La nueva -C
opción no es satisfactoria, porque está abierta a una condición de carrera de tiempo de verificación a tiempo de uso (TOCTTOU). Si dos procesos intentan agregar la misma regla aproximadamente al mismo tiempo, -C
no los protegerá de agregarla dos veces.
Entonces, realmente no es mejor que la grep
solución. Un trabajo de procesamiento de texto preciso sobre la salida de iptables-save
puede funcionar de manera tan confiable -C
, ya que esa salida es una instantánea confiable del estado de las tablas.
Lo que se necesita es una --ensure
opción que compruebe atómicamente y agregue una regla solo si aún no existe. Además, sería bueno si la regla se mueve a la posición correcta donde se insertaría una nueva regla si aún no existiera ( --ensure-move
). Por ejemplo, si iptables -I 1
se usa para crear una regla en la cabeza de una cadena, pero esa regla ya existe en la séptima posición, entonces la regla existente debería moverse a la primera posición.
Sin estas características, creo que una solución viable es escribir un bucle de script de shell basado en este pseudocódigo:
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
Este código podría girar; no garantiza que dos o más corredores salgan dentro de un número fijo de iteraciones. Se podrían agregar algunos retrasos exponenciales aleatorios para ayudar con eso.