Nowa -C
opcja nie jest satysfakcjonująca, ponieważ jest otwarta na warunki wyścigu od momentu sprawdzenia do czasu użycia (TOCTTOU). Jeśli dwa procesy spróbują dodać tę samą regułę mniej więcej w tym samym czasie, -C
nie ochronią ich przed dwukrotnym dodaniem.
Tak więc to naprawdę nie jest lepsze niż grep
rozwiązanie. Dokładne zadanie przetwarzania tekstu na wyjściu iptables-save
może działać równie niezawodnie -C
, ponieważ dane wyjściowe są wiarygodną migawką stanu tabel.
Potrzebna jest --ensure
opcja, która atomowo sprawdza i dodaje regułę tylko wtedy, gdy jeszcze nie istnieje. Ponadto byłoby miło, gdyby reguła została przeniesiona do prawidłowej pozycji, do której wstawiono by nową regułę, gdyby jeszcze nie istniała ( --ensure-move
). Na przykład, jeśli iptables -I 1
zostanie użyty do stworzenia reguły na szczycie łańcucha, ale reguła ta istnieje już na siódmej pozycji, wówczas istniejąca reguła powinna przejść na pierwszą pozycję.
Myślę, że bez tych funkcji możliwe jest obejście pętli skryptu powłoki w oparciu o ten pseudo kod:
while true ; do
# delete all copies of the rule first
while copies_of_rule_exist ; do
iptables -D $RULE
done
# now try to add the rule
iptables -A $RULE # or -I
# At this point there may be duplicates due to races.
# Bail out of loop if there is exactly one, otherwise
# start again.
if exactly_one_copy_of_rule_exists ; then
break;
fi
done
Ten kod może się kręcić; nie gwarantuje to, że dwóch lub więcej zawodników wyląduje w określonej liczbie iteracji. Aby to zrobić, można dodać kilka losowych snów wykładniczych.