Die neue -C
Option ist nicht zufriedenstellend, da sie für eine TOCTTOU-Rennbedingung (Time-of-Check-to-Time-of-Use) offen ist. Wenn zwei Prozesse versuchen, dieselbe Regel ungefähr zur selben Zeit hinzuzufügen, -C
werden sie nicht davor geschützt, sie zweimal hinzuzufügen.
Es ist also wirklich nicht besser als die grep
Lösung. Ein genauer Textverarbeitungsjob über die Ausgabe von iptables-save
kann genauso zuverlässig arbeiten -C
, da diese Ausgabe eine zuverlässige Momentaufnahme des Status der Tabellen ist.
Was benötigt wird, ist eine --ensure
Option, die eine Regel atomar prüft und nur hinzufügt, wenn sie noch nicht existiert. Außerdem wäre es schön, wenn die Regel an die richtige Position verschoben würde, an der eine neue Regel eingefügt würde, wenn sie noch nicht vorhanden wäre ( --ensure-move
). Wenn beispielsweise iptables -I 1
zum Erstellen einer Regel am Anfang einer Kette verwendet wird, diese Regel jedoch bereits an der siebten Position vorhanden ist, sollte die vorhandene Regel an die erste Position verschoben werden.
Ohne diese Funktionen besteht meiner Meinung nach eine praktikable Problemumgehung darin, eine Shell-Skriptschleife zu schreiben, die auf diesem Pseudocode basiert:
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
Dieser Code könnte sich drehen; Dies garantiert nicht, dass zwei oder mehr Fahrer innerhalb einer festgelegten Anzahl von Iterationen ausfallen. Einige randomisierte exponentielle Backoff-Schlafzustände könnten hinzugefügt werden, um dies zu unterstützen.