Comment puis-je supprimer des règles spécifiques d'iptables?

334

J'héberge des services HTTP et HTTPS spéciaux sur les ports 8006 et 8007 respectivement. J'utilise iptables pour "activer" le serveur; c'est-à-dire pour router les ports HTTP et HTTPS entrants:

iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 8006 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 8007 -j ACCEPT
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8006 
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8007  
iptables -A OUTPUT -t nat -d 127.0.0.1 -p tcp --dport 80 -j REDIRECT --to-ports 8006
iptables -A OUTPUT -t nat -d 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to-ports 8007 

Cela fonctionne comme un charme. Cependant, je voudrais créer un autre script qui désactive à nouveau mon serveur; c'est-à-dire restaurer iptables à l'état dans lequel il se trouvait avant d'exécuter les lignes ci-dessus. Cependant, j'ai du mal à trouver la syntaxe pour supprimer ces règles. La seule chose qui semble fonctionner est une chasse d'eau complète:

iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

Mais cela supprimera également d'autres règles iptables, ce qui n'est pas souhaité.

Jeroen
la source
2
J'ai trouvé qu'il vaut mieux utiliser -Iau lieu de -Apour les ACCEPTlignes. C'est parce que généralement, la dernière ligne (pour la INPUTchaîne par exemple) est un DROPou REJECTet vous voulez que votre règle vienne avant cela. -Amet la nouvelle règle après la dernière règle, tout en la -Imettant au début.
Mark Lakata

Réponses:

471

Exécutez les mêmes commandes mais remplacez le "-A" par "-D". Par exemple:

iptables -A ...

devient

iptables -D ...
Eli Rosencruft
la source
7
Si vous avez plusieurs règles d'un même genre, cela ne les supprimera pas toutes.
ETech
4
essayez d'exécuter cette commande -D plusieurs fois et elle les supprimera toutes.
Zhenyu Li
4
j'ai exécuté la même commande, mais avec -D au lieu de -I. Mais je reçois une mauvaise règle (existe-t-il une règle de correspondance) ...
Ben
4
Si vous avez ajouté une règle avec -Iou -R, vous pouvez toujours la supprimer avec -D.
David Xia
Juste une note. Je crée une règle avec 'iptables -A ...' et la règle est apparue mais n'était pas efficace. Lors de l'utilisation de «iptables -D ...», la réponse était une règle incorrecte . Même ainsi, la règle a été supprimée. La règle était visible avec 'sudo iptables -nvL'. La chaîne que j'ai utilisée était «INPUT».
Ben Paz
446

Vous pouvez également utiliser le numéro de la règle ( --line-numéros ):

iptables -L INPUT --line-numbers

Exemple de sortie:

Chain INPUT (policy ACCEPT) 
    num  target prot opt source destination
    1    ACCEPT     udp  --  anywhere  anywhere             udp dpt:domain 
    2    ACCEPT     tcp  --  anywhere  anywhere             tcp dpt:domain 
    3    ACCEPT     udp  --  anywhere  anywhere             udp dpt:bootps 
    4    ACCEPT     tcp  --  anywhere  anywhere             tcp dpt:bootps

Donc, si vous souhaitez supprimer la deuxième règle:

iptables -D INPUT 2

Mettre à jour

Si vous utilisez (d) une table spécifique (par exemple nat), vous devez l'ajouter à la commande delete (merci à @ThorSummoner pour le commentaire)

sudo iptables -t nat -D PREROUTING 1
domi27
la source
4
Les deux solutions sont agréables, mais celle-ci ne fonctionnera pas dans un paramètre de script lorsque le numéro de ligne est inconnu. Donc, l'autre solution est plus générale et donc plus correcte, l'OMI.
Jeroen
2
Eh bien, si vous ne connaissez pas la ligne, vous pouvez utiliser un commentaire (comme réponse parmi) ou faire un grep pour votre règle:iptables -L INPUT --line-numbers | grep -oP "([0-9]{1,3}).*tcp.*domain" | cut -d" " -f1
domi27
6
Cela ne convient que si la table ne peut pas avoir de règles insérées à un moment donné. Sinon, les numéros de ligne pourraient changer entre les observer et exécuter la règle de suppression. Dans un tel cas, il n'est pas sûr de supposer que la fenêtre temporelle est si courte "qu'il est peu probable qu'elle se produise".
Nick
14
N'oubliez pas que si vous supprimez une règle, les numéros de ligne du reste changent. Donc, si vous devez supprimer les règles 5, 10 et 12 ... supprimez-les 12, 10, puis 5.
TomOnTime
2
En essayant de supprimer les règles de PREROUTING, j'ai dû spécifier -t nat, par exemple :, sudo iptables -t nat --line-numbers -Let les supprimer avec -t nataussi, par exemple: sudo iptables -t nat -D PREROUTING 1(Peut-être utile d'ajouter à la réponse?)
ThorSummoner
31

La meilleure solution qui fonctionne pour moi sans aucun problème ressemble à ceci:
1. Ajoutez une règle temporaire avec un commentaire:

comment=$(cat /proc/sys/kernel/random/uuid | sed 's/\-//g')
iptables -A ..... -m comment --comment "${comment}" -j REQUIRED_ACTION

2. Lorsque la règle a été ajoutée et que vous souhaitez la supprimer (ou tout ce qui contient ce commentaire), procédez comme suit:

iptables-save | grep -v "${comment}" | iptables-restore

Ainsi, vous supprimez à 100% toutes les règles qui correspondent au commentaire $ et laissez les autres lignes intactes. Cette solution fonctionne depuis 2 mois avec environ 100 changements de règles par jour - aucun problème.

ETech
la source
2
Dans le cas où vous ne disposez pas d'iptables-save / restore:iptables -S | grep "${comment}" | sed 's/^-A //' | while read rule; do iptables -D $rule; done
Mansour
Pour une utilisation réelle: CRON 1) supprimer les anciennes spamhausinterdictions iptables, 2) saisir spamhaus.org/drop , 3) grep pour les IP CIDR etiptables -A INPUT -s $ip_cidr -j -m comment --comment "spamhaus"
Xeoncross
2
@Mansour Or iptables -S | sed "/$comment/s/-A/iptables -D/e";) comme ça
hek2mgl
@ hek2mgl sed n'abandonne pas, n'est-ce pas? =] Merci, je garderai cette capacité à l'esprit (j'oublierai la syntaxe dans un jour).
Mansour
sed est utilisé uniquement pour supprimer "-" de uuid. En tout cas, une fois que vous aurez obtenu la syntaxe sed - elle ne sera jamais oubliée. ))
ETech
11

Liste d'abord toutes les règles iptables avec cette commande:

iptables -S

il répertorie comme:

-A XYZ -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT

Copiez ensuite la ligne souhaitée et remplacez-la -Apar -Dpour la supprimer:

iptables -D XYZ -p ...
Wladdy Lopez
la source
2
Être conscient! Ceci est une réponse incomplète. Du manuel sur "-S": "Comme toute autre commande iptables, elle s'applique à la table spécifiée (le filtre est la valeur par défaut).". Donc, en cas d'utilisation de ce commutateur - doit être répété pour toutes les tables: nat, mangle, etc.
pmod
1
Dans mon cas, je reçois iptables: Bad rule (does a matching rule exist in that chain?).quoi maintenant?
Abdull
Ah, compris - ma commande de suppression manquait les spécifications de la table. Donc, si vous répertoriez toutes les règles de la table natavec sudo iptables -S -t natet que vous souhaitez supprimer l'une des règles renvoyées, la copie ne suffit pas. Vous devez ajouter -t nat, par exemple sudo iptables -D ... -t nat.
Abdull
Facile à comprendre!
Sknight
5

Utilisez la -Dcommande, voici comment la manpage l'explique:

-D, --delete chain rule-specification
-D, --delete chain rulenum
    Delete  one  or more rules from the selected chain.  
    There are two versions of this command: 
    the rule can be specified as a number in the chain (starting at 1 for the first rule) or a rule to match.

Réalisez cette commande, comme toutes les autres commandes ( -A, -I) qui fonctionnent sur certaines tables. Si vous ne travaillez pas sur la table par défaut ( filtertable), utilisez-t TABLENAME pour spécifier cette table cible.

Supprimer une règle pour correspondre

iptables -D INPUT -i eth0 -p tcp --dport 443 -j ACCEPT

Remarque: Cela supprime uniquement la première règle correspondante. Si plusieurs règles correspondent (cela peut se produire dans iptables), exécutez-le plusieurs fois.

Supprimer une règle spécifiée sous forme de nombre

iptables -D INPUT 2

Outre le comptage du nombre, vous pouvez répertorier le numéro de ligne avec --line-numberparamètre, par exemple:

iptables -t nat -nL --line-number
cizixs
la source
J'ai trouvé celui-ci avec --line-number est le meilleur
Davuz
Oui! Superbe! Je ne veux pas toutiptables -F
Dev Anand Sadasivam
2

Supposons que, si vous souhaitez supprimer des règles NAT,

Listez les IPtables ajoutés à l'aide de la commande ci-dessous,

# sudo iptables -L -t nat -v

Chain PREROUTING (policy ACCEPT 18 packets, 1382 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    7   420 DNAT       tcp  --  any    any     anywhere             saltmaster           tcp dpt:http to:172.31.5.207:80
    0     0 DNAT       tcp  --  eth0   any     anywhere             anywhere             tcp dpt:http to:172.31.5.207:8080

Si vous souhaitez supprimer la règle nat des IPtables, exécutez simplement la commande,

# sudo iptables -F -t nat -v

Flushing chain `PREROUTING'
Flushing chain `INPUT'
Flushing chain `OUTPUT'
Flushing chain `POSTROUTING'

Ensuite, vous pouvez vérifier que,

# sudo iptables -L -t nat -v
lakshmikandan
la source