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

41

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 überprü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?

siebenmal
quelle
Alternativ können Sie diesen Wrapper verwenden, der eine idempotente iptables-Interaktion bietet: xyne.archlinux.ca/projects/idemptables
sampablokuper

Antworten:

44

-C --checkIn den letzten iptables-Versionen gibt es eine neue 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"
Marc MAURICE
quelle
12

Die neue -COption 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, -Cwerden sie nicht davor geschützt, sie zweimal hinzuzufügen.

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

Was benötigt wird, ist eine --ensureOption, 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 1zum 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 besteht meiner Meinung nach eine praktikable Problemumgehung darin, 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.

Kaz
quelle
1
Darf ich hinzufügen, dass dieser Befehl aus dem einfachen Grund, dass Sie genau bestimmen müssen, wie Ihre Regel hinzugefügt wurde, eher nicht zufriedenstellend ist. Ich habe den Test mit meinem Setup durchgeführt und konnte keine Regel finden, da ich die genauen Schlüsselwörter und Werte nicht angegeben habe ...
Fabien Haddadi
Wenn Sie vorübergehend eine Regel entfernen, brechen Sie möglicherweise etwas ...
Mehrdad
5

Dies mag ein bisschen rückwärts erscheinen, 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;

rekursieren
quelle
1
Das Öffnen einer unerwünschten Lücke in Ihrer Firewall, um einen idempotenten Befehl zu simulieren, ist wahrscheinlich keine gute Idee. Sicher, das Loch soll nur vorübergehend sein, aber es verbessert trotzdem die Chancen eines Angreifers. Und wenn etwas die Hinzufügung der Ersetzungsregel unterbricht, könnte die Lücke auf unbestimmte Zeit bestehen bleiben.
sampablokuper
Guter Punkt @sampablokuper: Diese Strategie ist aus Sicherheitsgründen wahrscheinlich nur für ACCEPT-Regeln und nicht für DROP-Regeln geeignet
lucaferrario
Am Ende habe ich das Gleiche getan!
Warhansen
4

Einfach auflisten und danach suchen?

iptables --list | grep $ip

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

Jonathon Reinhart
quelle
3
Ich würde iptables-save|grep $ipstattdessen vorschlagen, da es ein einfacher zu analysierendes Format ist, insbesondere in einem Skript. Sie können auch die genaue Syntax des Befehls überprüfen, wenn Sie möchten.
Garrett,
1
Keiner von beiden beantwortet tatsächlich die Frage, da iptables-save|grep $ipsehr gut mehrere Regeln übereinstimmen könnten . Möglicherweise iptables-savekönnte die vollständige Regelspezifikation überprüft werden , aber das ist immer noch ein bisschen hackig: Das von zurückgegebene Format stimmt iptables-savemöglicherweise nicht genau mit der Regel im Skript überein. iptables-savekann die Optionen in einer anderen Reihenfolge generieren, Dinge (wie -m tcp) hinzufügen und so weiter.
Larsks
Denken Sie daran, dass iptables --listversucht wird, bekannte Ports aufzulösen. Stellen Sie dies sicher, bevor Sie nach einem Port suchen.
Fabien Haddadi
0

Fügen Sie die folgende Zeile hinzu, um doppelte Regeln aus Ihrem Skript zu vermeiden.

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

Wenn der obige Befehl zum ersten Mal ausgeführt wird, wird die folgende Meldung angezeigt

iptables: Ungültige Regel (existiert in dieser Kette eine übereinstimmende Regel?).

Dies ist nur zur Information. Die zweite Hälfte des Befehls würde jedoch sicherstellen, dass die Regel hinzugefügt wird.

laxman vallandas
quelle