Jak mogę sprawdzić, czy reguła iptables już istnieje?

41

Muszę dodać regułę do iptables, aby blokować połączenia z portem TCP z Internetu.

Ponieważ mój skrypt może być wywoływany wiele razy i nie ma skryptu, który mógłby usunąć regułę, chcę sprawdzić, czy reguła iptables już istnieje przed wstawieniem - w przeciwnym razie w łańcuchu INPUT będzie wiele reguł dup.

Jak mogę sprawdzić, czy reguła iptables już istnieje?

Sevever
źródło
Ewentualnie użyj tego opakowania, które zapewnia idempotentną interakcję iptables: xyne.archlinux.ca/projects/idemptables
sampablokuper

Odpowiedzi:

44

W -C --checknajnowszych wersjach iptables pojawiła się nowa opcja.

# 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

W przypadku starszych wersji iptables skorzystałbym z sugestii Garretta:

# iptables-save | grep -- "-A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT"
Marc MAURICE
źródło
12

Nowa -Copcja nie jest satysfakcjonująca, ponieważ jest otwarta na warunki wyścigu od momentu sprawdzenia do czasu użycia (TOCTTOU). Jeśli dwa procesy spróbują dodać tę samą regułę mniej więcej w tym samym czasie, -Cnie ochronią ich przed dwukrotnym dodaniem.

Tak więc to naprawdę nie jest lepsze niż greprozwiązanie. Dokładne zadanie przetwarzania tekstu na wyjściu iptables-savemoże działać równie niezawodnie -C, ponieważ dane wyjściowe są wiarygodną migawką stanu tabel.

Potrzebna jest --ensureopcja, która atomowo sprawdza i dodaje regułę tylko wtedy, gdy jeszcze nie istnieje. Ponadto byłoby miło, gdyby reguła została przeniesiona do prawidłowej pozycji, do której wstawiono by nową regułę, gdyby jeszcze nie istniała ( --ensure-move). Na przykład, jeśli iptables -I 1zostanie użyty do stworzenia reguły na szczycie łańcucha, ale reguła ta istnieje już na siódmej pozycji, wówczas istniejąca reguła powinna przejść na pierwszą pozycję.

Myślę, że bez tych funkcji możliwe jest obejście pętli skryptu powłoki w oparciu o ten pseudo kod:

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

Ten kod może się kręcić; nie gwarantuje to, że dwóch lub więcej zawodników wyląduje w określonej liczbie iteracji. Aby to zrobić, można dodać kilka losowych snów wykładniczych.

Kaz
źródło
1
Chciałbym dodać, że to polecenie jest raczej niezadowalające z tego prostego powodu, że musisz wskazać dokładny sposób dodania reguły. Zrobiłem test z moją konfiguracją i nie mogłem znaleźć reguły, ponieważ nie podałem dokładnych słów kluczowych i wartości ...
Fabien Haddadi
Jeśli tymczasowo usuniesz regułę, możesz coś złamać ...
Mehrdad
5

Może się to wydawać nieco wstecz, ale działa dla mnie - najpierw spróbuj usunąć regułę.

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

Powinieneś otrzymać wiadomość podobną do:

iptables: Zła reguła (czy istnieje pasująca reguła w tym łańcuchu?)

Następnie po prostu dodaj swoją regułę jak zwykle:

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

powrócić
źródło
1
Otwarcie niechcianej dziury w zaporze ogniowej, aby symulować idempotentne polecenie, prawdopodobnie nie jest dobrym pomysłem. Jasne, dziura ma być tymczasowa, ale wciąż zwiększa szanse atakującego. A jeśli coś zakłóci dodanie reguły zastępowania, dziura może trwać w nieskończoność.
sampablokuper
Dobra uwaga @sampablokuper: ta strategia jest prawdopodobnie odpowiednia tylko dla reguł ACCEPT, a nie DROP, ze względów bezpieczeństwa
lucaferrario
Skończyło się na tym samym!
warhansen
4

Po prostu wymień i wyszukaj?

iptables --list | grep $ip

... lub jednak masz określoną regułę. Jeśli grep -qgo użyjesz, nic nie wyświetli i możesz po prostu sprawdzić wartość zwracaną za pomocą$?

Jonathon Reinhart
źródło
3
Sugerowałbym iptables-save|grep $ipzamiast tego, ponieważ jest to łatwiejszy do przeanalizowania format, szczególnie w skrypcie. Jeśli chcesz, możesz również sprawdzić dokładną składnię polecenia.
Garrett,
1
Żadne z nich tak naprawdę nie odpowiada na pytanie, ponieważ iptables-save|grep $ipmoże bardzo dobrze pasować do wielu reguł. Możliwe, że iptables-savemożna go użyć do sprawdzenia pełnej specyfikacji reguły, ale wciąż jest to trochę kłopot: zwrócony format iptables-savemoże nie pasować dokładnie do reguły w skrypcie. iptables-savemoże generować opcje w innej kolejności, dodawać rzeczy (jak -m tcp) i tak dalej.
larsks
Pamiętaj, że iptables --listspróbujesz rozwiązać znane porty. Upewnij się więc o tym, zanim zaczniesz szukać portu.
Fabien Haddadi
0

Aby uniknąć powielania reguł ze skryptu, dodaj poniższy wiersz.

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

Pierwszy raz, gdy uruchomione zostanie powyższe polecenie, obserwujemy poniższy komunikat

iptables: Zła reguła (czy istnieje pasująca reguła w tym łańcuchu?).

To jest tylko informacja. Ale druga połowa polecenia zapewni dodanie reguły.

Laxman Vallandas
źródło