¿Cómo puedo verificar si ya existe una regla de iptables?

41

Necesito agregar una regla a iptables para bloquear las conexiones a un puerto TCP desde Internet.

Como mi secuencia de comandos se puede llamar varias veces y no hay una secuencia de comandos para eliminar la regla, quiero verificar si ya existe una regla de iptables antes de insertarla; de lo contrario, habrá muchas reglas duplicadas en la cadena INPUT.

¿Cómo puedo verificar si ya existe una regla de iptables?

sevenever
fuente
Alternativamente, use este contenedor, que proporciona interacción idempotente de iptables: xyne.archlinux.ca/projects/idemptables
sampablokuper

Respuestas:

44

Hay una nueva -C --checkopción en las versiones recientes de 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

Para versiones anteriores de iptables, usaría la sugerencia de Garrett:

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

La nueva -Copción no es satisfactoria, porque está abierta a una condición de carrera de tiempo de verificación a tiempo de uso (TOCTTOU). Si dos procesos intentan agregar la misma regla aproximadamente al mismo tiempo, -Cno los protegerá de agregarla dos veces.

Entonces, realmente no es mejor que la grepsolución. Un trabajo de procesamiento de texto preciso sobre la salida de iptables-savepuede funcionar de manera tan confiable -C, ya que esa salida es una instantánea confiable del estado de las tablas.

Lo que se necesita es una --ensureopción que compruebe atómicamente y agregue una regla solo si aún no existe. Además, sería bueno si la regla se mueve a la posición correcta donde se insertaría una nueva regla si aún no existiera ( --ensure-move). Por ejemplo, si iptables -I 1se usa para crear una regla en la cabeza de una cadena, pero esa regla ya existe en la séptima posición, entonces la regla existente debería moverse a la primera posición.

Sin estas características, creo que una solución viable es escribir un bucle de script de shell basado en este pseudocódigo:

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

Este código podría girar; no garantiza que dos o más corredores salgan dentro de un número fijo de iteraciones. Se podrían agregar algunos retrasos exponenciales aleatorios para ayudar con eso.

Kaz
fuente
1
¿Puedo agregar que este comando no es satisfactorio por la simple razón de que tiene que determinar la forma exacta en que se agregó su regla? Hice la prueba con mi configuración, y no pude encontrar una regla porque no especifiqué las palabras clave y los valores exactos ...
Fabien Haddadi
Si elimina temporalmente una regla, entonces podría romper algo ...
Mehrdad
5

Esto puede parecer un poco al revés, pero funciona para mí: intente eliminar la regla primero.

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

Debería recibir un mensaje similar a:

iptables: regla incorrecta (¿existe una regla coincidente en esa cadena?)

Luego simplemente agregue su regla como de costumbre:

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

recurse
fuente
1
Abrir un agujero no deseado en su firewall, solo para simular un comando idempotente, probablemente no sea una gran idea. Claro, el hoyo está destinado a ser temporal, pero aún mejora las posibilidades de un atacante. Y si algo interrumpe la adición de la regla de reemplazo, entonces el agujero podría persistir indefinidamente.
sampablokuper
Buen punto @sampablokuper: esta estrategia probablemente solo sea adecuada para ACEPTAR reglas y no DROP, por razones de seguridad
lucaferrario
¡Terminé haciendo lo mismo!
warhansen
4

¿Solo listar y buscarlo?

iptables --list | grep $ip

... o como quiera que tenga la regla especificada. Si lo usa, grep -qno generará nada, y puede verificar el valor de retorno con$?

Jonathon Reinhart
fuente
3
En iptables-save|grep $ipcambio, sugeriría que es un formato más fácil de analizar, especialmente en un script. También puede verificar la sintaxis exacta del comando si lo desea.
Garrett
1
Ninguno de estos responde realmente la pregunta, porque iptables-save|grep $ippodría muy bien coincidir con múltiples reglas. Posiblemente iptables-savepodría usarse para verificar la especificación de la regla completa , pero eso sigue siendo un poco complicado: el formato devuelto por iptables-savepuede no coincidir exactamente con la regla en el script. iptables-savepuede generar las opciones en un orden diferente, agregar elementos (como -m tcp), etc.
Larsks
Tenga en cuenta que iptables --listintentará resolver los puertos conocidos. Así que asegúrese de eso antes de buscar un puerto.
Fabien Haddadi
0

Para evitar reglas duplicadas de su script, agregue la siguiente línea.

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

La primera vez que se ejecuta el comando anterior, observaríamos el siguiente mensaje

iptables: regla incorrecta (¿existe una regla coincidente en esa cadena?).

Esto es solo para información. Pero la segunda mitad del comando se aseguraría de agregar la regla.

laxman vallandas
fuente