A nova -C
opção não é satisfatória, pois está aberta a uma condição de corrida de tempo de verificação até o tempo de uso (TOCTTOU). Se dois processos tentarem adicionar a mesma regra ao mesmo tempo, -C
não os protegerá de adicioná-la duas vezes.
Portanto, não é realmente melhor que a grep
solução. Um trabalho preciso de processamento de texto na saída de iptables-save
pode funcionar com a maior confiabilidade possível -C
, pois essa saída é uma captura instantânea confiável do estado das tabelas.
O que é necessário é uma --ensure
opção que verifique e adicione atomicamente uma regra apenas se ela ainda não existir. Além disso, seria bom se a regra fosse movida para a posição correta, onde uma nova regra seria inserida se ela já não existisse ( --ensure-move
). Por exemplo, se iptables -I 1
for usada para criar uma regra no início de uma cadeia, mas essa regra já existir na sétima posição, a regra existente deverá passar para a primeira posição.
Sem esses recursos, acho que uma solução possível é escrever um loop de script de shell com base neste pseudo-có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
Esse código pode girar; não garante que dois ou mais corredores saiam dentro de um número fixo de iterações. Alguns adormecimentos exponenciais aleatórios podem ser adicionados para ajudar nisso.