it-swarm.com.de

Wie kann ich überprüfen, ob bereits eine iptables-Regel existiert?

Ich muss iptables eine Regel hinzufügen, um Verbindungen zu einem TCP-Port aus dem Internet zu blockieren.

Da mein Skript möglicherweise mehrmals aufgerufen wird und es kein Skript zum Löschen der Regel gibt, möchte ich vor dem Einfügen prüfen, ob bereits eine iptables-Regel vorhanden ist. Andernfalls enthält die INPUT-Kette viele Dup-Regeln.

Wie kann ich überprüfen, ob bereits eine iptables-Regel existiert?

37
sevenever

In den letzten iptables-Versionen gibt es eine neue -C --check-Option.

# 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

Für ältere iptables-Versionen würde ich den Garrett-Vorschlag verwenden:

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

Die neue Option -C ist nicht zufriedenstellend, da sie für eine TOCTTOU-Rennbedingung (Time-of-Check-to-Time-of-Use) offen ist. Wenn zwei Prozesse versuchen, dieselbe Regel ungefähr zur selben Zeit hinzuzufügen, schützt -C sie nicht davor, sie zweimal hinzuzufügen.

Es ist also wirklich nicht besser als die grep Lösung. Ein genauer Textverarbeitungsjob über die Ausgabe von iptables-save kann genauso zuverlässig arbeiten wie -C, da diese Ausgabe eine zuverlässige Momentaufnahme des Status der Tabellen ist.

Was benötigt wird, ist eine --ensure-Option, die eine Regel atomar prüft und nur hinzufügt, wenn sie noch nicht existiert. Außerdem wäre es schön, wenn die Regel an die richtige Position verschoben würde, an der eine neue Regel eingefügt würde, wenn sie noch nicht vorhanden wäre (--ensure-move). Wenn beispielsweise iptables -I 1 zum Erstellen einer Regel am Anfang einer Kette verwendet wird, diese Regel jedoch bereits an der siebten Position vorhanden ist, sollte die vorhandene Regel an die erste Position verschoben werden.

Ohne diese Funktionen ist es meiner Meinung nach eine praktikable Lösung, eine Shell-Skriptschleife zu schreiben, die auf diesem Pseudocode basiert:

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

Dieser Code könnte sich drehen; Dies garantiert nicht, dass zwei oder mehr Fahrer innerhalb einer festgelegten Anzahl von Iterationen ausfallen. Einige randomisierte exponentielle Backoff-Schlafzustände könnten hinzugefügt werden, um dies zu unterstützen.

10
Kaz

Dies mag ein bisschen rückwärts scheinen, aber es funktioniert bei mir. Versuchen Sie zuerst, die Regel zu löschen.

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

Sie sollten eine Nachricht erhalten, die der folgenden ähnelt:

iptables: Bad rule (Gibt es in dieser Kette eine passende Regel?)

Dann fügen Sie einfach Ihre Regel wie gewohnt hinzu:

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

5
recurse

Einfach auflisten und danach suchen?

iptables --list | grep $ip

... oder aber Sie haben die Regel angegeben. Wenn Sie grep -q verwenden, wird nichts ausgegeben, und Sie können den Rückgabewert einfach mit $? überprüfen.

4