Come posso verificare se esiste già una regola iptables?


41

Devo aggiungere una regola a iptables per bloccare le connessioni a una porta tcp da Internet.

Poiché il mio script può essere chiamato più volte e non esiste uno script per eliminare la regola, voglio verificare se esiste già una regola iptables prima di inserirla, altrimenti ci saranno molte regole dup nella catena INPUT.

Come posso verificare se esiste già una regola iptables?


In alternativa, utilizzare questo wrapper, che fornisce l'interazione idempotente di iptables: xyne.archlinux.ca/projects/idemptables
sampablokuper

Risposte:


44

C'è una nuova -C --checkopzione nelle recenti versioni di 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

Per le versioni precedenti di iptables, userei il suggerimento di Garrett:

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

12

La nuova -Copzione non è soddisfacente, perché è aperta a una condizione di gara TOCTTOU (time-of-check-to-time-of-use). Se due processi tentano di aggiungere la stessa regola nello stesso momento, -Cnon li proteggeranno dall'aggiunta due volte.

Quindi, non è davvero meglio della grepsoluzione. Un accurato processo di elaborazione del testo sull'output di iptables-savepuò funzionare in modo affidabile come -C, poiché quell'output è un'istantanea affidabile dello stato delle tabelle.

Ciò che è necessario è --ensureun'opzione che controlla atomicamente e aggiunge una regola solo se non esiste già. Inoltre, sarebbe bello se la regola fosse spostata nella posizione corretta in cui una nuova regola sarebbe inserita se non esistesse già ( --ensure-move). Ad esempio, se iptables -I 1viene utilizzato per creare una regola all'inizio di una catena, ma tale regola esiste già nella settima posizione, la regola esistente dovrebbe spostarsi nella prima posizione.

Senza queste funzionalità, penso che una soluzione alternativa possibile sia scrivere un loop di script di shell basato su questo pseudo codice:

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

Questo codice potrebbe girare; non garantisce che due o più corridori saranno fuori entro un numero fisso di iterazioni. Alcuni sleeps esponenziali randomizzati potrebbero essere aggiunti per aiutare in questo.


1
Posso aggiungere che questo comando non è abbastanza soddisfacente per la semplice ragione che devi individuare esattamente come è stata aggiunta la tua regola. Ho fatto il test con la mia configurazione e non sono riuscito a trovare una regola perché non ho specificato le parole chiave e i valori esatti ...
Fabien Haddadi,

Se rimuovi temporaneamente una regola, potresti infrangere qualcosa ...
Mehrdad,

5

Questo può sembrare un po 'arretrato, ma funziona per me. Prova prima a eliminare la regola.

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

Dovresti ricevere un messaggio simile a:

iptables: regola errata (esiste una regola corrispondente in quella catena?)

Quindi aggiungi semplicemente la tua regola normalmente:

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


1
L'apertura di un buco indesiderato nel firewall, solo per simulare un comando idempotente, probabilmente non è una grande idea. Certo, il buco è destinato a essere temporaneo, ma migliora ancora le possibilità di un attaccante. E se qualcosa interrompe l'aggiunta della regola di sostituzione, il buco potrebbe persistere indefinitamente.
sampablokuper,

Buon punto @sampablokuper: questa strategia è probabilmente adatta solo alle regole ACCEPT e non a DROP, per motivi di sicurezza
lucaferrario

Ho finito per fare la stessa cosa!
Warhansen,

4

Basta elencarlo e cercarlo?

iptables --list | grep $ip

... o comunque hai specificato la regola. Se lo usi grep -qnon genererà nulla e puoi semplicemente controllare il valore di ritorno con$?


3
Suggerirei iptables-save|grep $ipinvece in quanto è un formato più facilmente analizzabile, specialmente in uno script. Puoi anche verificare l'esatta sintassi del comando, se lo desideri.
Garrett,

1
Nessuno di questi in realtà risponde alla domanda, perché iptables-save|grep $ippotrebbe benissimo abbinare più regole. Probabilmente iptables-savepotrebbe essere usato per verificare la specifica completa della regola, ma è ancora un po 'un trucco: il formato restituito iptables-savepotrebbe non corrispondere esattamente alla regola nello script. iptables-savepuò generare le opzioni in un ordine diverso, aggiungere cose (come -m tcp) e così via.
Larsks,

Tieni presente che iptables --listproverà a risolvere porte note. Quindi assicurati di farlo prima di richiedere una porta.
Fabien Haddadi,


0

Per evitare regole duplicate dal tuo script, aggiungi sotto la riga.

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

La prima volta che viene eseguito il comando precedente, osserveremo il messaggio seguente

iptables: regola non valida (esiste una regola corrispondente in quella catena?).

Questo è solo per informazione. Ma la seconda metà del comando assicurerebbe di aggiungere la regola.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.