Como posso verificar se uma regra iptables já existe?

35

Eu preciso adicionar uma regra ao iptables para bloquear conexões com uma porta tcp da Internet.

Como meu script pode ser chamado várias vezes e não há um script para excluir a regra, quero verificar se uma regra iptables já existe antes de inseri-la. Caso contrário, haverá muitas regras dup na cadeia INPUT.

Como posso verificar se uma regra iptables já existe?

    
por sevenever 22.11.2011 / 04:04

4 respostas

39

Existe uma nova opção -C --check nas versões recentes do iptables.

# iptables -C INPUT -p tcp --dport 8080 --jump ACCEPT
iptables: Bad rule (does a matching rule exist in that chain?).
# echo $?
1

# iptables -A INPUT -p tcp --dport 8080 --jump ACCEPT

# iptables -C INPUT -p tcp --dport 8080 --jump ACCEPT
# echo $?
0

Para versões mais antigas do iptables, eu usaria a sugestão de Garrett:

# iptables-save | grep -- "-A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT"
    
por 20.09.2012 / 10:33
9

A nova opção -C não é satisfatória, pois está aberta a uma condição de corrida de tempo de verificação de tempo de uso (TOCTTOU). Se dois processos tentarem adicionar a mesma regra aproximadamente ao mesmo tempo, -C não os protegerá de adicioná-la duas vezes.

Portanto, realmente não é melhor que a solução grep . Um trabalho de processamento de texto preciso sobre a saída de iptables-save pode funcionar de forma confiável como -C , pois essa saída é um instantâneo confiável do estado das tabelas.

O que é necessário é uma opção --ensure , que verifica e adiciona atomicamente uma regra somente 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 já não existisse ( --ensure-move ). Por exemplo, se iptables -I 1 for usado para criar uma regra na cabeça de uma cadeia, mas essa regra já existir na sétima posição, a regra existente deverá ser movida para a primeira posição.

Sem esses recursos, acho que uma solução viável é escrever um loop de script de shell com base nesse 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 ao redor; não garante que dois ou mais pilotos estarão fora dentro de um número fixo de iterações. Alguns backoffs aleatórios exponenciais poderiam ser adicionados para ajudar com isso.

    
por 02.07.2014 / 21:26
5

Isso pode parecer um pouco atrasado, mas funciona para mim: tente excluir a regra primeiro.

iptables -D INPUT -s xxx.xxx.xxx.xxx -j DROP;

Você deve receber uma mensagem semelhante a:

iptables: Má regra (existe uma regra correspondente nessa cadeia?)

Em seguida, basta adicionar sua regra como normal:

iptables -A INPUT -s xxx.xxx.xxx.xxx -j DROP;

    
por 27.11.2015 / 16:21
3

Basta listar e pesquisar por ele?

iptables --list | grep $ip

... ou como você tem a regra especificada. Se você usar grep -q , não produzirá nada, e você pode apenas verificar o valor de retorno com $?

    
por 22.11.2011 / 04:06

Tags