web-dev-qa-db-fra.com

Comment puis-je vérifier si une règle iptables existe déjà?

J'ai besoin d'ajouter une règle à iptables pour bloquer les connexions à un port TCP depuis Internet.

Étant donné que mon script peut être appelé plusieurs fois et qu'il n'y a pas de script pour supprimer la règle, je souhaite vérifier si une règle iptables existe déjà avant de l'insérer - sinon, il y aura beaucoup de règles dup dans la chaîne INPUT.

Comment puis-je vérifier si une règle iptables existe déjà?

37
sevenever

Il y a une nouvelle option -C --check dans les versions récentes d'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

Pour les anciennes versions d'iptables, j'utiliserais la suggestion de Garrett:

# iptables-save | grep -- "-A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT"
42
Marc MAURICE

La nouvelle option -C n'est pas satisfaisante car elle est ouverte à une condition de concurrence selon l'heure de la vérification (TOCTTOU). Si deux processus tentent d'ajouter la même règle à peu près au même moment, -C ne les empêchera pas de l'ajouter deux fois.

Donc, ce n’est vraiment pas mieux que la solution grep. Un travail de traitement de texte précis sur la sortie de iptables-save peut fonctionner de manière aussi fiable que -C, car cette sortie est un instantané fiable de l'état des tables.

Ce qu'il faut, c'est une option --ensure qui vérifie et ajoute une règle de manière atomique uniquement si elle n'existe pas déjà. De plus, ce serait bien si la règle est déplacée à la position correcte où une nouvelle règle serait insérée si elle n'existait pas déjà (--ensure-move). Par exemple, si iptables -I 1 est utilisé pour créer une règle en tête d'une chaîne, mais que cette règle existe déjà à la septième position, la règle existante doit passer à la première position.

Sans ces fonctionnalités, je pense qu'une solution de contournement possible consiste à écrire une boucle de script Shell basée sur ce pseudo-code:

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

Ce code pourrait tourner autour; cela ne garantit pas que deux coureurs ou plus seront absents dans un nombre déterminé d'itérations. Des périodes de repos exponentielles aléatoires pourraient être ajoutées pour y remédier.

10
Kaz

Cela peut sembler un peu en arrière, mais cela fonctionne pour moi - Essayez d’abord de supprimer la règle.

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

Vous devriez recevoir un message similaire à:

iptables: Bad rule (une règle de correspondance existe-t-elle dans cette chaîne?)

Ensuite, ajoutez simplement votre règle comme d'habitude:

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

5
recurse

Juste la liste et la recherche?

iptables --list | grep $ip

... ou peu importe la règle spécifiée. Si vous utilisez grep -q, rien ne sera généré et vous pourrez simplement vérifier la valeur de retour avec $?.

4
Jonathon Reinhart