Como posso verificar se já existe uma regra do iptables?


41

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

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

Como posso verificar se já existe uma regra do iptables?


Alternativamente, usar este invólucro, o qual fornece idempotente interacção iptables: xyne.archlinux.ca/projects/idemptables
sampablokuper

Respostas:


44

Há uma nova -C --checkopção 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"

12

A nova -Copçã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, -Cnão os protegerá de adicioná-la duas vezes.

Portanto, não é realmente melhor que a grepsolução. Um trabalho preciso de processamento de texto na saída de iptables-savepode 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 --ensureopçã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 1for 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.


11
Posso acrescentar que esse comando não é satisfatório pelo simples motivo de que você precisa identificar exatamente como sua regra foi adicionada. Eu fiz o teste com a minha configuração, e não poderia encontrar uma regra porque eu não especificou as palavras exatas e valores ...
Fabien Haddadi

Se você remover temporariamente uma regra, poderá quebrar alguma coisa ...
Mehrdad 27/04

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: Regra incorreta (existe uma regra correspondente nessa cadeia?)

Em seguida, basta adicionar sua regra normalmente:

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


11
Abrir um buraco indesejado no firewall, apenas para simular um comando idempotente, provavelmente não é uma boa ideia. Claro, o buraco deve ser temporário, mas ainda melhora as chances de um atacante. E se algo interromper a adição da regra de substituição, o buraco poderá persistir indefinidamente.
precisa saber é o seguinte

Bom ponto @sampablokuper: esta estratégia é provavelmente apenas adequado para ACEITAR regras e não deixar cair queridos, por razões de segurança
lucaferrario

Acabei fazendo a mesma coisa!
warhansen

4

Basta listar e procurar por ele?

iptables --list | grep $ip

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


3
Em iptables-save|grep $ipvez disso, sugiro que seja um formato mais facilmente analisável, especialmente em um script. Você também pode verificar a sintaxe exata do comando, se desejar.
22411 Garrett #

11
Nenhum deles realmente responde à pergunta, porque iptables-save|grep $ippoderia muito bem corresponder a várias regras. Possivelmente iptables-savepoderia ser usado para verificar a especificação completa da regra, mas isso ainda é um pouco complicado: o formato retornado por iptables-savepode não corresponder exatamente à regra no script. iptables-savepode gerar as opções em uma ordem diferente, adicionar coisas (como -m tcp) e assim por diante.
larsks

Lembre-se de que iptables --listtentará resolver portas conhecidas. Portanto, certifique-se disso antes de grep para uma porta.
Fabien Haddadi


0

Para evitar regras duplicadas do seu script, adicione a linha abaixo.

iptables -C -INPUT -p tcp --dport 8080 --jump ACCEPT || iptables -A -INPUT -p tcp --dport 8080 --jump ACCEPT

Na primeira vez em que o comando acima é executado, observaremos a mensagem abaixo

iptables: Regra incorreta (existe uma regra correspondente nessa cadeia?).

Isto é apenas para informação. Mas a segunda metade do comando garantiria a adição da regra.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.