¿Cómo puedo eliminar reglas específicas de iptables?

334

Estoy alojando servicios especiales HTTP y HTTPS en los puertos 8006 y 8007 respectivamente. Yo uso iptables para "activar" el servidor; es decir, para enrutar los puertos HTTP y HTTPS entrantes:

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 

Esto funciona como un encanto. Sin embargo, me gustaría crear otro script que vuelva a deshabilitar mi servidor; es decir, restaurar iptables al estado en que estaba antes de ejecutar las líneas anteriores. Sin embargo, estoy teniendo dificultades para descubrir la sintaxis para eliminar estas reglas. Lo único que parece funcionar es una descarga completa:

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

Pero eso también eliminará otras reglas de iptables que no son deseadas.

Jeroen
fuente
2
He descubierto que es mejor usarlo en -Ilugar de -Apara ACCEPTlíneas. Esto se debe a que, por lo general, la última línea (por INPUTejemplo, la cadena) es una DROPo REJECTy desea que su regla aparezca antes. -Acoloca la nueva regla después de la última regla, mientras que la -Icoloca al comienzo.
Mark Lakata

Respuestas:

471

Ejecute los mismos comandos pero reemplace "-A" con "-D". Por ejemplo:

iptables -A ...

se convierte

iptables -D ...
Eli Rosencruft
fuente
77
Si tiene varias reglas de un tipo, no las eliminará todas.
ETech
44
intente ejecutar este comando -D varias veces, y los eliminará a todos.
Zhenyu Li
44
Ejecuté el mismo comando, pero con -D en lugar de -I. Pero obtengo MALA REGLA (existe una regla de coincidencia) ...
Ben
44
Si agregó una regla con -Io -R, aún puede eliminarla con -D.
David Xia
Solo una nota. Creo una regla con 'iptables -A ...' y la regla apareció pero no fue efectiva. Al usar 'iptables -D ...' la respuesta fue una regla incorrecta . Aun así, la regla fue eliminada. La regla era visible con 'sudo iptables -nvL'. La cadena que utilicé fue 'INPUT'.
Ben Paz
446

También puede usar el número de la regla ( --line-numbers ):

iptables -L INPUT --line-numbers

Salida de ejemplo:

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

Entonces, si desea eliminar la segunda regla:

iptables -D INPUT 2

Actualizar

Si usa (d) una tabla específica (por ejemplo, nat), debe agregarla al comando de eliminación (gracias a @ThorSummoner para el comentario)

sudo iptables -t nat -D PREROUTING 1
domi27
fuente
44
Ambas soluciones son buenas, pero esta no funcionará en una configuración con script cuando se desconoce el número de línea. Entonces, la otra solución es más general y, por lo tanto, más correcta, la OMI.
Jeroen
2
Bueno, si no conoce la línea, puede usar un comentario (como respuesta entre) o hacer un grep para su regla:iptables -L INPUT --line-numbers | grep -oP "([0-9]{1,3}).*tcp.*domain" | cut -d" " -f1
domi27
66
Esto está bien solo si la tabla no puede tener reglas insertadas en cualquier momento. De lo contrario, los números de línea podrían cambiar entre observarlos y ejecutar la regla de eliminación. En tal caso, no es seguro suponer que el intervalo de tiempo es tan corto que "es poco probable que suceda".
Nick
14
Recuerde que si elimina una regla, los números de línea del resto cambian. Entonces, si necesita eliminar la regla 5, 10 y 12 ... elimínelas 12, 10 y luego 5.
TomOnTime
2
Al intentar eliminar las reglas de PREROUTING, tuve que especificar -t nat, por ejemplo: sudo iptables -t nat --line-numbers -Ly eliminarlas -t nattambién, por ejemplo: sudo iptables -t nat -D PREROUTING 1(¿Puede valer la pena agregar a la respuesta?)
ThorSummoner
31

La mejor solución que funciona para mí sin ningún problema se ve de esta manera:
1. Agregue una regla temporal con algún comentario:

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

2. Cuando se agregue la regla y desee eliminarla (o todo lo que contenga este comentario), haga lo siguiente:

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

Por lo tanto, eliminará al 100% todas las reglas que coinciden con el comentario $ y dejará sin tocar otras líneas. Esta solución funciona durante los últimos 2 meses con aproximadamente 100 cambios de reglas por día, sin problemas. Espero que ayude

ETech
fuente
2
En caso de que no tenga iptables-save / restore:iptables -S | grep "${comment}" | sed 's/^-A //' | while read rule; do iptables -D $rule; done
Mansour
Para un uso en la vida real: CRON 1) elimine las antiguas spamhausprohibiciones de iptables, 2) tome spamhaus.org/drop , 3) grep para IP de CIDR yiptables -A INPUT -s $ip_cidr -j -m comment --comment "spamhaus"
Xeoncross
2
@Mansour O iptables -S | sed "/$comment/s/-A/iptables -D/e";) como este
hek2mgl
@ hek2mgl sed no se rinde, ¿verdad? =] Gracias, tendré en cuenta esta capacidad (olvidaré la sintaxis en un día).
Mansour
sed se usa solo para eliminar "-" de uuid. En cualquier caso, una vez que tenga la sintaxis sed, nunca se olvidará. ))
ETech
11

Primero enumere todas las reglas de iptables con este comando:

iptables -S

enumera como:

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

Luego copie la línea deseada y simplemente reemplace -Acon -Dpara eliminar eso:

iptables -D XYZ -p ...
Wladdy Lopez
fuente
2
¡Ten cuidado! Esta es una respuesta incompleta. Del manual sobre "-S": "Al igual que cualquier otro comando de iptables, se aplica a la tabla especificada (el filtro es el predeterminado)". Por lo tanto, en caso de usar este interruptor, debe repetirse para todas las tablas: nat, mangle, etc.
pmod
1
En mi caso, me sale iptables: Bad rule (does a matching rule exist in that chain?).¿Qué pasa ahora?
Abdull
Ah, lo descubrí: a mi comando de eliminación le faltaba la especificación de la tabla. Entonces, en caso de que enumere todas las reglas de la tabla natcon sudo iptables -S -t naty desee eliminar una de las reglas devueltas, la copia no es suficiente. Tienes que agregar -t nat, por ejemplo sudo iptables -D ... -t nat.
Abdull
¡Fácil de comprender!
Sknight
5

Use el -Dcomando, así es como la manpágina lo explica:

-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.

Tenga en cuenta que este comando, como todos los demás comandos ( -A, -I) funciona en cierta tabla. Si no está trabajando en la tabla predeterminada ( filtertabla), use -t TABLENAMEpara especificar esa tabla de destino.

Eliminar una regla para que coincida

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

Nota: Esto solo elimina la primera regla coincidente. Si tiene muchas reglas coincidentes (esto puede suceder en iptables), ejecútelo varias veces.

Eliminar una regla especificada como un número

iptables -D INPUT 2

Además de contar el número, puede enumerar el número de línea con el --line-numberparámetro, por ejemplo:

iptables -t nat -nL --line-number
cizixs
fuente
Encontré este con --line-number es el mejor
Davuz
¡Si! ¡Magnífico! No quiero todoiptables -F
Dev Anand Sadasivam
2

Suponga que, si desea eliminar las reglas NAT,

Enumere las tablas de IP adjuntas utilizando el siguiente comando,

# 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 desea eliminar la regla nat de las tablas IP, simplemente ejecute el comando,

# sudo iptables -F -t nat -v

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

Entonces, puedes verificar que,

# sudo iptables -L -t nat -v
lakshmikandan
fuente