La enésima receta de iptables

Esta receta explica los usos más habituales de iptables. No trata de ser un manual de uso, sólo son unos cuantos comandos que solucionan problemas frecuentes.

Introducción

Lo más normal para un usuario medio es utilizar iptables para definir reglas de firewall en su router. Para simplificar la explicación de los ejemplos que aparecen en la receta voy a suponer una configuración concreta. Es importante tenerla en cuenta cuando tengas que hacer los cambios pertinentes para aplicarla a tu configuración concreta. Es ésta:

  • Una conexión a Internet (eth0). Debe ser algún tipo de conexión a Internet, que puede ser RTC, ADSL, cable-modem, etc. Supondremos para esta receta que usas un modem ADSL con conexión Ethernet.
  • Una conexión a tu red local (eth1): Será una tarjeta de red Ethernet 10/100. Esto permitirá que puedas enchufarle un conmutador y conectar “cienes y cienes” de ordenadores si quieres. Esta interfaz debes configurarla de forma estática, con una dirección IP privada, por ejemplo 192.168.0.1.

Esta configuración se corresponde con nuestra otra receta sobre compartir la conexión, de modo que es más sencillo seguir aquí desde aquella.

Tablas y reglas

Hay 3 tablas (o cadenas), que indican qué tipo de operación puede hacer el router con los paquetes.

  • FILTER: En esta tabla hay reglas que dicen qué hacer con los paquetes, pero sin modificarlos. Esta es la tabla por defecto, si no se indica otra.
    Se puede definir 3 tipos de reglas:
    • INPUT: Para paquetes cuyo destino es un socket de la propia máquina.
    • OUTPUT: Para paquetes generados por la propia máquina.
    • FORWARD: Para paquetes que llegan a la máquina, pero cuyo destino es una máquina distinta.
  • NAT: Implica a los paquetes que requieren crear nuevas conexiones. Normalmente implica algún tipo de traducción de dirección, ya sea dirección o puerto (modifican el paquete). También se puede definir 3 tipos de reglas:
    • PREROUTING: El paquete se modifica en cuanto llega a la máquina.
    • POSTROUTING: El paquete se modifica después de decidir su destino (una vez rutado).
    • OUTPUT: El paquete se ha generado en la propia máquina y se modifica antes de decidir su destino.
  • MANGLE: Implica modificaciones más sofisticadas del paquete, que van más allá de su dirección. Excede el alcance de esta receta.

Además de éstas que vienen de serie, el usuario puede crear otras.

Políticas

Existen dos políticas básicas para administrar un firewall.

  • Restrictiva(DROP). Todo lo que no está explícitamente permitido, está prohibido.
  • Permisiva(ACCEPT). Todo lo que no está explícitamente prohibido, está permitido. Es la política por defecto en iptables.

La política se determina para cada tipo de regla por separado. Por ejemplo, para establecer una política restrictiva para FORWARD sería:

# iptables -P FORWARD DROP

Evidentemente, iptables tienes muchas opciones que dan mucho juego, mucho más de lo que cualquier mortal pueda imaginar, no es tan complejo y sofisticado como CISCO IOS pero tampoco le falta tanto. Por eso vamos a acotar un poco el asunto y vamos a hablar sólo de 3 “esquemas” que se suelen usar para configuraciones sencillas:

  1. Utilizar política por defecto (permisiva) y denegar explícitamente cada servicio que NO se desea.
  2. Utilizar política restrictiva y aceptar explícitamente cada servicio que se desea.
  3. Utilizar política por defecto, indicar qué servicios se desean explícitamente y POR ÚLTIMO denegar todo lo demás. Este esquema, a pesar de usar una política permisiva, prohibe todo lo que no esté explícitamente aceptado.

Lógicamente los esquemas 1 y 3 son iguales salvo porque en el 3 no tienen sentido reglas de denegación específicas.

Es importante tener en cuenta que las reglas se aplican secuencialmente. Una vez que el paquete coincide con una regla de la lista ya no se le aplica ninguna más. Eso significa que si se prohibe un servicio, después el inútil permitir un subconjunto de lo prohibido.

Comandos básicos

Este es un resumen de comandos habituales simplificados.

Ver la configuración

# iptables -L [-t tabla] [-v]

Borrar todas las reglas de una tabla

# iptables -F [-t tabla]

Configuración de un router (con esquema 3)

Esta es una configuración sencilla pero completa de un router, utilizando el esquema 3.

Enrutar tráfico de la red local a Internet aplicando NAT. Recuerda activar también el forwarding.

# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Aceptar todo el tráfico ICMP.

# iptables -A INPUT -p ICMP -j ACCEPT

Aceptar todo el tráfico de conexiones ya establecidas (ESTABLISHED) o relacionado con otras conexiones (RELATED).

# iptables -A INPUT -m state —state ESTABLISHED,RELATED -j ACCEPT

Aceptar cualquier conexión que proceda de la red interna:

# iptables -A INPUT -p tcp -i eth1 -j ACCEPT

Aceptar conexiones web (80) desde cualquier origen:

# iptables -A INPUT -p tcp —dport 80 -j ACCEPT

Aceptar todo el tráfico desde el loopback:

# iptables -A INPUT -i lo -j ACCEPT

Descartar el resto:

# iptables -A INPUT -j DROP

Si quieres permitir algo más debes insertar la nueva regla antes del DROP. Por ejemplo: Aceptar conexiones HTTPS desde cualquier sitio:

# iptables -I INPUT 7 -p tcp —dport https -j ACCEPT

Por supuesto también puedes editar directamente el fichero en el que guardes la configuración de iptables (ver guardar configuración). El contenido de dicho fichero para la configuración fijada con estos comandos sería (no se muestran las tablas vacías):

*filter
:INPUT ACCEPT [696743:123302283]
:FORWARD ACCEPT [591745:477869546]
:OUTPUT ACCEPT [801266:279702677]
-A INPUT -p ICMP -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i eth1 -j ACCEPT
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp --dport https -j ACCEPT
-A INPUT -j DROP
COMMIT
*nat
:PREROUTING ACCEPT [64615:3723067]
:POSTROUTING ACCEPT [101:14282]
:OUTPUT ACCEPT [10260:530443]
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT

Bloquear un puerto (en esquema 1)

Esto es útil si el router da un servicio a la red local que no quieres que se vea desde Internet, por ejemplo, el servidor FTP.

# iptables -A INPUT -i eth0 -p tcp --dport 20:21 -j DROP

Redireccionar un puerto del router hacia otro host (interno o externo)

Esto se conoce comúnmente como Port forwarding. Por ejemplo, al conectar al puerto 80 del router, se accederá realmente al servidor web de una máquina de la red interna:

# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80  -j DNAT --to-destination 192.168.0.15:80

Guardar la configuración de iptables

Para guardar las reglas activas (las que has ido poniendo hasta ahora) ejecuta:

Router:~# iptables-save > /etc/iptables.up.rules

Y ahora hay que hacer que esa configuración se cargue automáticamente al levantar la interfaz de red principal (la externa). Para ello, edita de nuevo el fichero /etc/network/interfaces para que la entrada de eth0 quede así:

auto eth0
iface eth0 inet dhcp
      pre-up iptables-restore < /etc/iptables.up.rules

Referencias

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Ayuda

hola sabes me gusta mucho como explicas y das ejemplo me gustaría saber si me puedes ayudar con mi pregunta.

¿Qué regla de iptables permite bloquear cualquier tipo de conexión que se inicie y llegue desde una maquina externa?
Teniendo en cuenta que solo queremos filtrar los intentos de conexión externos hacia nosotros, tenemos que mantener las conexiones que
salen de nuestra máquina y vayan al exterior. Por lo tanto, las respuestas a nuestras peticiones sí que se han de procesa.

si me puede ayudar te lo agradecería mucho

saludos

Imagen de oscarah

Interesante.

La oraciones primera y última no usan mayúsculas, comas o puntos. Sin embargo, a excepción de la última palabra del tercer párrafo, el resto está bastante bien redactado. Esta incoherencia me da que pensar. Por ejemplo, que es una pregunta copiada textualmente de algún otro sitio. Me pica la curiosidad, ¿quién pregunta eso realmente? No será algún examen on-line, ¿verdad? Sticking out tongue

PD: Que mal pensado soy. No me lo tengas en cuenta Smiling

"aviso: la dereferencia de punteros de tipo castigado romperá las reglas de alias estricto" --GCC 4.3.1

Imagen de david.villa

Redirección sencillita de puertos TCP

Easily forwarding arbitrary TCP connections with rinetd

No soy portavoz de ningún colectivo, grupo o facción. Mi opinión es personal e intransferible.

Imagen de david.villa

Impedir el uso de la red a un usuario concreto

iptables -A OUTPUT -p tcp -m owner —uid-owner username -j DROP

visto en: Disable internet access for particular user in Ubuntu

No soy portavoz de ningún colectivo, grupo o facción. Mi opinión es personal e intransferible.

No puedo usar dnsmasq cuando agrego -A INPUT -j DROP

He seguido todas las recetas de este sitio, y me ha funciondo todo muy bien, a excepción de que el DHCP del dnsmasq deja de funcionar cuando agrego -A INPUT -j DROP a iptables, cuando se lo quito todo funciona correctamente, cuando se lo coloco ya el dnsmasq no asigna direcciones ip a los clientes.

Cual puede ser el problema?

Imagen de david.villa

Pues

seguramente es porque el firewall está descartando el tráfico DHCP. Tienes varias opciones:

Aplicar esa regla sólo al tráfico procedente del exterior, algo como:

# iptables -A INPUT -i eth0 -j DROP

Permitir todo el tráfico procedente de la red interna. Es lo más cómodo si no necesitas restringir lo que hacen los usuarios de la red privada.

# iptables -A INPUT -i eth1 -j ACCEPT

O bien permitir expresamente el tráfico DHCP antes de hacer el DROP a todo:

# iptables -A INPUT -p udp —dport 67 -i eth1 -J ACCEPT
# iptables -A INPUT -j DROP

Esto último no lo he probado, quizá haya que abrir algún puerto más porque dnsmasq escucha en algunos otros. En estos comandos he usado el convenio de la receta, es decir, eth0 es el interfaz con la red pública y eth1 es el interfaz con la red privada.

Saludos

No soy portavoz de ningún colectivo, grupo o facción. Mi opinión es personal e intransferible.

Gracias!

Hola David...

La primera solución me funcionó perfecto!

Usar..
# iptables -A INPUT -i eth0 -j DROP

en vez de...

# iptables -A INPUT -j DROP

La última solución me pareció la más adecuada, sin embargo no me funcionó, investigue un poquito a ver si encontraba que otros puertos debía habilitar, pero no encontré nada, quizas con más tiempo luego.

La segunda no me pareció adecuada para mi caso, así que no la probé.

Te estoy muy agradecido!

Saludos!

Imagen de david.villa

La segunda igual que la primera

Supongo que eres consciente de que si no descartas el resto del tráfico de la red privada, la primera y la segunda opción que yo te daba son equivalentes; por eso no entiendo porqué dices que no es adecuada para tu caso.

No soy portavoz de ningún colectivo, grupo o facción. Mi opinión es personal e intransferible.

Ultima solución

Hola David.

Después que escribí la respuesta anterior caí en cuenta de que la segunda era lo mismo que la primera... Sin embargo volví a intentar con la última solución que pusiste y ahora si todo funciona perfecto, solo faltaba agregar el puerto 53 que es el de DNS.

La solución entonces fué:

# iptables -A INPUT -i eth1 -p udp --sport 67:68 --dport 67:68 -j ACCEPT
# iptables -A INPUT -p udp --dport 53 -i eth1 -J ACCEPT
# iptables -A INPUT -j DROP

Muchas gracias por la ayuda prestada! la próxima semana voy por la VPN, saludos!

Imagen de brue

Seguramente...

... me equivoque, porque no he dormido nada, pero... ¿y el puerto 68?

--
PPC: int main(){long foo=1649571173;puts(&foo);}
x86: int main(){long foo=1702187618;puts(&foo);}

brue

Imagen de david.villa

Seguramente no te equivocas

ya decía que no lo he probado. Supongo que debería permitirse tanto el 67 como el 68 como origen y como destino, es decir:

# iptables -A INPUT -i eth1 -p udp --sport 67:68 --dport 67:68 -j ACCEPT

No soy portavoz de ningún colectivo, grupo o facción. Mi opinión es personal e intransferible.