Configurar IPTables

16 02 2010

Qué es un firewall

Un firewall es un dispositivo que filtra el tráfico entre redes, como mínimo dos. El firewall puede ser un dispositivo físico o un software sobre un sistema operativo. En general debemos verlo como una caja con DOS o mas interfaces de red en la que se establecen una reglas de filtrado con las que se decide si una conexión determinada puede establecerse o no. Incluso puede ir más allá y realizar modificaciones sobre las comunicaciones, como el NAT.

Esa sería la definición genérica, hoy en dia un firewall es un hardware especifico con un sistema operativo o una IOS que filtra el tráfico TCP/UDP/ICMP/../IP y decide si un paquete pasa, se modifica, se convierte o se descarta. Para que un firewall entre redes funcione como tal debe tener al menos dos tarjetas de red. Esta sería la tipología clásica de un firewall:

Sea el tipo de firewall que sea, generalmente no tendrá mas que un conjunto de reglas en las que se examina el origen y destino de los paquetes del protocolo tcp/ip. En cuanto a protocolos es probable que sean capaces de filtrar muchos tipos de ellos, no solo los tcp, también los udp, los icmp, los gre y otros protocolos vinculados a vpns.

Hay dos maneras de implementar un firewall:

1.Política por defecto ACEPTAR: en principio todo lo que entra y sale por el firewall se acepta y solo se denegará lo que se diga explícitamente.

2. Política por defecto DENEGAR: todo esta denegado, y solo se permitirá pasar por el firewall aquellos que se permita explícitamente.

Como es obvio imaginar, la primera política facilita mucho la gestión del firewall, ya que simplemente nos tenemos que preocupar de proteger aquellos puertos o direcciones que sabemos que nos interesan; el resto no importa tanto y se deja pasar. Por ejemplo, si queremos proteger una máquina linux, podemos hacer un netstat -ln (o netstat -an, o netstat -loquesea | grep LISTEN), saber que puertos están abiertos, poner reglas para proteger esos puertos y ya está. ¿Para qué vamos a proteger un puerto que realmente nunca se va a abrir?

El único problema que podemos tener es que NO CONTROLEMOS LOS PUERTOS ABIERTOS, o que en un momento dado se instale un software nuevo que abra un puerto determinado, o que no sepamos que determinados paquetes ICMP son peligrosos. Si la política por defecto es ACEPTAR y no se protege explícitamente, nos la estamos jugando.

En cambio, si la política por defecto es DENEGAR, a no ser que lo permitamos explícitamente, el firewall se convierte en una barrera. El problema es que es mucho más difícil configurar un firewall de éste tipo, y hay que tener muy claro como funciona el sistema (sea iptables o el que sea) y que es lo que se tiene que abrir sin caer en la tentación de empezar a meter reglas permisivas. Esta configuración de firewall es la recomendada

IMPORTANTE

El orden en el que se ponen las reglas de firewall es determinante. Normalmente cuando hay que decidir que se hace con un paquete se va comparando con cada regla del firewall hasta que se encuentra una que le afecta (match), y se hace lo que dicte esta regla (aceptar o denegar); después de eso NO SE MIRARÁN MÁS REGLAS para ese paquete. ¿Cuál es el peligro? Si ponemos reglas muy permisivas entre las primeras del firewall, puede que las siguientes no se apliquen y no sirvan de nada.

Qué es iptables

IPTables es un sistema de firewall vinculado al kernel de linux que se ha extendido enormemente a partir del kernel 2.4 de éste sistema operativo.

Vale, tenemos una máquina linux con soporte para iptables, tiene reglas aplicadas y empiezan a llegar/salir/pasar paquetes. No nos liemos: olvidemos cuantas tarjetas de red hay, que direcciones ip tiene la máquina y olvidemos si el paquete entra o sale. Las reglas de firewall están a nivel de kernel, y al kernel lo que le llega es un paquete y tiene que decidir que hacer con él. El kernel lo que hace es, dependiendo de si el paquete es para la propia maquina o para otra maquina, consultar las reglas de firewall y decidir que hacer con el paquete según mande el firewall. Este es el camino que seguiría un paquete en el kernel:

Como se ve en el gráfico, básicamente se mira si el paquete esta destinado a la propia maquina o si va a otra. Para los paquetes (o datagramas, según el protocolo) que van a la propia maquina se aplican las reglas INPUT y OUTPUT, y para filtrar paquetes que van a otras redes o maquinas se aplican simplemente reglas FORWARD.

INPUT,OUTPUT y FORWARD son los tres tipos de reglas de filtrado. Pero antes de aplicar esas reglas es posible aplicar reglas de NAT: estas se usan para hacer redirecciones de puertos o cambios en las IPs de origen y destino. Veremos ejemplos.

E incluso antes de las reglas de NAT se pueden meter reglas de tipo MANGLE, destinadas a modificar los paquetes; son reglas poco conocidas y es probable que no las usen.

Por tanto tenemos tres tipos tablas con sus respectivas reglas (o cadenas/chains) en iptables:

- MANGLE

- NAT: reglas (o cadenas/chains) PREROUTING, POSTROUTING

- FILTER: reglas (o cadenas/chains) INPUT, OUTPUT, FORWARD.

Tablas

Hay tres tablas ya incorporadas, cada una de las cuales contiene ciertas cadenas o reglas predefinidas. Es posible crear nuevas tablas mediante módulos de extensión. El administrador puede crear y eliminar cadenas definidas por usuarios dentro de cualquier tabla. Inicialmente, todas las cadenas están vacías y tienen una política de destino que permite que todos los paquetes pasen sin ser bloqueados o alterados.

- filter table (Tabla de filtros) — Esta tabla es la responsable del filtrado (es decir, de bloquear o permitir que un paquete continúe su camino). Todos los paquetes pasan a través de la tabla de filtros. Contiene las siguientes cadenas predefinidas y cualquier paquete pasará por una de ellas:

- INPUT chain (Cadena de ENTRADA) — Todos los paquetes destinados a este sistema atraviesan esta cadena (y por esto se la llama algunas veces LOCAL_INPUT o ENTRADA_LOCAL)

- OUTPUT chain (Cadena de SALIDA) — Todos los paquetes creados por este sistema atraviesan esta cadena (a la que también se la conoce como LOCAL_OUTPUT o SALIDA_LOCAL)

- FORWARD chain (Cadena de REDIRECCIÓN) — Todos los paquetes que meramente pasan por este sistema para ser encaminados a su destino recorren esta cadena

- nat table (Tabla de traducción de direcciones de red) — Esta tabla es la responsable de configurar las reglas de reescritura de direcciones o de puertos de los paquetes. El primer paquete en cualquier conexión pasa a través de esta tabla; los veredictos determinan como van a reescribirse todos los paquetes de esa conexión. Contiene las siguientes cadenas redefinidas:

- PREROUTING chain (Cadena de PRERUTEO) — Los paquetes entrantes pasan a través de esta cadena antes de que se consulte la tabla de ruteo local, principalmente para DNAT (destination-NAT o traducción de direcciones de red de destino)

- POSTROUTING chain (Cadena de POSRUTEO) — Los paquetes salientes pasan por esta cadena después de haberse tomado la decisión del ruteo, principalmente para SNAT (source-NAT o traducción de direcciones de red de origen)

- OUTPUT chain (Cadena de SALIDA) — Permite hacer un DNAT limitado en paquetes generados localmente

mangle table (Tabla de destrozo) — Esta tabla es la responsable de ajustar las opciones de los paquetes, como por ejemplo la calidad de servicio (QoS) Todos los paquetes pasan por esta tabla. Debido a que está diseñada para efectos avanzados, contiene todas las cadenas predefinidas posibles:

- PREROUTING chain (Cadena de PRERUTEO) — Todos los paquetes que logran entrar a este sistema, antes de que el ruteo decida si el paquete debe ser reenviado (cadena de REENVÍO) o si tiene destino local (cadena de ENTRADA)

- POSTROUTING chain (Cadena de POSRUTEO) — Todos los paquetes que abandonan este sistema pasan a través de esta cadena

Además de las cadenas ya incorporadas, el usuario puede crear todas las cadenas definidas por el usuario que quiera dentro de cada tabla, las cuales permiten agrupar las reglas en forma lógica.

Cada cadena contiene una lista de reglas. Cuando un paquete se envía a una cadena, se lo compara, en orden, contra cada regla en la cadena. La regla especifica qué propiedades debe tener el paquete para que la regla lo matchee, como número de puerto o dirección IP. Si la regla no lo matchea, el procesamiento continúa con la regla siguiente. Si la regla, por el contrario, matchea el paquete, las instrucciones de destino de las reglas se siguen (y cualquier otro procesamiento de la cadena normalmente se aborta). Algunas propiedades de los paquetes solo pueden examinarse en ciertas cadenas (por ejemplo, la interfaz de red de salida no es válida en la cadena de ENTRADA). Algunos destinos solo pueden usarse en ciertas cadenas y/o en ciertas tablas (por ejemplo, el destino SNAT solo puede usarse en la cadena de POSTRUTEO de la tabla de traducción de direcciones de red).

Destinos de reglas

El destino de una regla puede ser el nombre de una cadena definida por el usuario o uno de los destinos ya incorporados ACCEPT, DROP, QUEUE, o RETURN (aceptar, descartar, encolar o retornar, respectivamente). Cuando un destino es el nombre de una cadena definida por el usuario, al paquete se lo dirige a esa cadena para que sea procesado (tal como ocurre con una llamada a una subrutina o en un lenguaje de programación). Si el paquete consigue atravesar la cadena definida por el usuario sin que ninguna de las reglas de esa cadena actúe sobre él, el procesamiento del paquete continúa donde había quedado en la cadena actual. Estos llamados entre cadenas se pueden anidar hasta cualquier nivel deseado.

Existen los siguientes destinos ya incorporados:

- ACCEPT (aceptar): Éste destino hace que netfilter acepte el paquete. El significado de esto depende de cuál sea la cadena realizando esta aceptación. De hecho, a un paquete que se lo acepta en la cadena de ENTRADA se le permite ser recibido por la terminal (host), a un paquete que se lo acepta en la cadena de SALIDA se le permite abandonar la terminal y a un paquete que se lo acepta en la cadena de REDIRECCIÓN se le permite ser ruteado a través de la terminal.

- DROP (descartar): Éste destino hace que netfilter descarte el paquete sin ningún otro tipo de procesamiento. El paquete simplemente desaparece sin indicación de que fue descartado al ser entregado a la terminal de envio o a una aplicación. Esto se le refleja al que envía, a menudo, como un communication timeout (alcance del máximo tiempo de espera en la comunicación), lo que puede causar confusión (aunque el descarte de paquetes entrantes no deseados se considera a veces una buena política de seguridad, pues no da ni siquiera el indicio a un posible atacante de que la terminal existe).

- QUEUE (encolar): Éste destino hace que el paquete sea enviado a una cola en el espacio de usuario. Una aplicación puede usar la biblioteca libipq. también parte del proyecto netfilter/iptables, para alterar el paquete. Si no hay ninguna aplicación que lea la cola, este destino es equivalente a DROP.

- RETURN (retorno): Hace que el paquete en cuestión deje de circular por la cadena en cuya regla se ejecutó el destino RETURN. Si dicha cadena es una subcadena de otra, el paquete continuará por la cadena superior como si nada hubiera pasado. Si por el contrario la cadena es una cadena principal (por ejemplo la cadena INPUT), al paquete se le aplicará la política por defecto de la cadena en cuestión (ACCEPT, DROP o similar).

Hay muchos destinos de extensión disponibles. Algunos de los más comunes son:

- REJECT (rechazo): Este destino tiene el mismo efecto que ‘DROP’, salvo que envía un paquete de error a quien envió originalmente. Se usa principalmente en las cadenas de ENTRADA y de REDIRECCIÓN de la tabla de filtrado. El tipo de paquete se puede controlar a través del parámetro ‘–reject-with’. Un paquete de rechazo puede indicar explícitamente que la conexión ha sido filtrada (un paquete ICMP filtrado administrativamente por conexión), aunque la mayoría de los usuarios prefieren que el paquete indique simplemente que la computadora no acepta ese tipo de conexión (tal paquete será un paquete tcp-reset para conexiones TCP denegadas, un icmp-port-unreachable para sesiones UDP denegadas o un icmp-protocol-unreachable para paquetes no TCP y no UDP). Si el parámetro ‘–reject-with’ no se especifica, el paquete de rechazo por defecto es siempre icmp-port-unreachable.

- LOG (bitácora): Éste destino lleva un log o bitácora del paquete. Puede usarse en cualquier cadena en cualquier tabla, y muchas veces se usa para debuggear (análisis de fallos, como ser la verificación de qué paquetes están siendo descartados).

- ULOG: Éste destino lleva un log o bitácora del paquete, pero no de la misma manera que el destino LOG. El destino LOG le envía información al log del nucleo, pero ULOG hace multidifusión de los paquetes que matchean esta regla a través de un socket netlink, de manera que programas del espacio de usuario puedan recibir este paquete conectándose al socket.

- DNAT: Éste destino hace que la dirección (y opcionalmente el puerto) de destino del paquete sean reescritos para la traducción de dirección de red. Mediante la opción ‘–to-destination’ debe indicarse el destino a usar. Esto es válido solamente en las cadenas de SALIDA y PRERUTEO dentro de la tabla de nat. Esta decisión se recuerda para todos los paquetes futuros que pertenecen a la misma conexión y las respuestas tendrán su dirección y puerto de origen cambiados al original (es decir, la inversa de este paquete).

- SNAT: Éste destino hace que la dirección (y opcionalmente el puerto) de origen del paquete sean reescritos para traducción de dirección de red. Mediante la opción ‘–to-source’ debe indicarse el origen a usar. Esto es válido solamente en la cadena de POSRUTEO dentro de la tabla de nat y, como DNAT, se recuerda para todos los paquetes que pertenecen a la misma conexión.

- MASQUERADE: Ésta es una forma especial, restringida de SNAT para direcciones IP dinámicas, como las que proveen la mayoría de los proveedored de servicios de internet (ISPs) para modems o liena de abonado digital (DSL). En vez de cambiar la regla de SNAT cada vez que la dirección IP cambia, se calcula la dirección IP de origen a la cual hacer NAT fijándose en la dirección IP de la interfaz de salida cuando un paquete coincide con esta esta regla. Adicionalmente, recuerda cuales conexiones usan MASQUERADE y si la dirección de la interfaz cambia (por ejemplo, por reconectarse al ISP), todas las conexiones que hacen NAT a la dirección vieja se olvidan.

Seguimiento de conexiones

Una de las características de importancia que está construída por encima del framework de netfilter es el seguimiento de conexiones (connection tracking). El seguimento de conexiones le permite al núcleo llevar cuenta de todas las conexiones o sesiones lógicas de red y de este modo relacionar todos los paquetes que pueden llegar a formar parte de esa conexión. La traducción de red (NAT) depende de esta información para traducir todos los paquetes relacionados de la misma manera y iptables puede usar esta información para actuar como un cortafuegos de estado o como dicen los hijos de la gran bretaña State full inspection, es una técnica o tipo de cortafuego que trabaja en 3 de las capas del modelo OSI para el TCP/IP:

- Capa 3 (Capa de red – Internet Protocol)

- Capa 4 (Capa de Transporte –TCP)

- Capa 5 (Capa de Aplicación).

El seguimiento de conexiones clasifica cada paquete en uno de cuatro estados:

- NEW (nuevo): Intentando crear una conexión nueva.

- ESTABLISHED (establecido): Parte de una conexión ya existente.

- RELATED (relacionado): Relacionada, aunque no realmente parte de una conexión existente.

- INVALID (inválido): No es parte de una conexión existente e incapaz de crear una conexión nueva.

Un caso común sería que el primer paquete que el cortafuegos ve se clasificará como NEW, la respuesta se clasificará como ESTABLISHED y un error ICMP sería RELATED. Un paquete de error ICMP que no matchee una conexión conocida será INVALID.

El estado de la conexión es completamente independiente de cualquier estado de TCP. Si la terminal (host) responde con un paquete SYN ACK para señalar una conexión TCP entrante nueva, la conexión TCP misma no se establece, pero la conexión a la que se le hace el seguimiento sí se establece. Este paquete matcheará el estado ESTABLISHED.

Sin embargo, una conexión a la que se le hace el seguimiento de un protocolo sin estado como UDP tiene un estado de conexión.

Es más, mediante el uso de módulo que pueden agregarse, al seguimiento de conexión se le puede dar conocimiento de los protocolos de la capa de aplicación y así que entienda que dos o más conexiones distintas están “relacionadas”. Por ejemplo, considérese el protocolo FTP. Se establece una conexión de control, pero cada vez que se transfiere información, se establece otra conexión para que la transfiera. Si se carga el módulo nf_conntrack_ftp, el primer paquete de una conexión de datos FTP se clasificará como RELATED en lugar de NEW, ya que lógicamente es parte de una conexión existente.

iptables puede usar la información del seguimiento de conexiones para conseguir hacer reglas de filtrado de paquetes más potentes y más fáciles de manejar. La extensión de “estado” le permite a las reglas de iptables que examinen la clasificación de seguimiento de conexión para un paquete. Por ejemplo, una regla puede permitir el paso solo a paquetes NEW desde dentro del cortafuegos hacia afuera, pero permitir paquetes RELATED y ESTABLISHED en ambas direcciones. Esto permite el paso de paquetes de respuesta normales desde el exterior (ESTABLISHED), pero no permite que lleguen conexiones nuevas desde el exterior al interior. Sin embargo, si una conexión de datos FTP necesita llegar desde el exterior del cortafuegos hacia el interior, será permitido, porque el paquete se clasificará correctamente como RELATED para la conexión de control FTP, en vez de NEW.

iptables

iptables es un aplicativo del espacio de usuario que le permite a un administrador de sistema configurar las tablas, cadenas y reglas de netfilter (descritas más arriba). Debido a que iptables requiere privilegios elevados para operar, el único que puede ejecutarlo es el superusuario. En la mayoría de los sistemas Linux, iptables está instalado como /sbin/iptables. La sintaxis detallada del comando iptables está documentada en su pagina de man, la cual puede verse tipeando el comando “man iptables” desde la línea de comandos.

Opciones comunes

En cada una de las formas de invocación de iptables que se muestra a continuación, las siguientes opciones comunes están disponibles:

-t tabla :Hace que el comando se aplique a la tabla especificada. Si esta opción se omite, el comando se aplica a la tabla filter por defecto.

-v :Produce una salida con detalles (del inglés, verbose).

-n :Produce una salida numérica (es decir, números de puerto en lugar de nombres de servicio y direcciones IP en lugar de nombres de dominio).

–line-numbers :Cuando se listan reglas, agrega números de línea al comienzo de cada regla, correspondientes a la posición de esa regla en su cadena.

Especificaciones de las reglas

La mayoría de las formas de comandos de iptables requieren que se les indiquen una especificación de reglas, que es usada para matchear un subconjunto particular del tráfico de paquetes de red procesados por una cadena. La especificación de regla incluye también un destino que especifica qué hacer con paquetes que son matcheados por la regla. Las siguientes opciones se usan (frecuentemente combinadas unas con otras) para crear especificaciones de reglas.

-j destino/–jump destino : Especifica el destino de una regla. El destino es el nombre de una cadena definida por el usuario (creada usando la opción -N, uno de los destinos ya incorporados, ACCEPT, DROP, QUEUE, o RETURN, o un destino de extensión, como REJECT, LOG, DNAT, o SNAT. Si esta opción es omitida en una regla, entonces el matcheo de la regla no tendrá efecto en el destino de un paquete, pero los contadores en la regla se incrementarán.

-i [!] in-interface/–in-interface [!] in-interface : Nombre de una interfaz a través de la cual un paquete va a ser recibido (solo para paquetes entrando en las cadenas de INPUT, FORWARD y PREROUTING). Cuando se usa el argumento ‘!’ antes del nombre de la interfaz, el significado se invierte. Si el nombre de la interfaz termina con ‘+’, entonces cualquier interfaz que comience con este nombre será matcheada. Si esta opción se omite, se matcheará todo nombre de interfaz.

-o [!] out-interface/–out-interface [!] out-interface : Nombre de una interfaz a través de la cual un paquete va a ser enviado (para paquetes entrando en las cadenas de FORWARD, OUTPUT y POSTROUTING). Cuando se usa el argumento ‘!’ antes del nombre de la interfaz, el significado se invierte. Si el nombre de la interfaz termina con ‘+’, entonces cualquier interfaz que comience con este nombre será matcheada. Si esta opción se omite, se matcheará todo nombre de interfaz.

-p [!] protocol/–protocol [!] protocol : Matchea paquetes del nombre de protocolo especificado. Si ‘!’ precede el nombre de protocolo, se matchean todos los paquetes que no son el protocolo especificado. Nombres de protocolo válidos son icmp, udp, tcp … . Una lista de todos los protocolos válidos puede encontrarse en el archivo /etc/protocols.

-s [!] origen[/prefijo]/–source [!] origen[/prefijo] :Matchea paquetes IP vieniendo de la dirección de origen especificada. La dirección de origen puede ser una dirección IP, una dirección IP con un prefijo de red asociado, o un nombre de terminal (hostname). Si ‘!’ precede al origen, se matchean todos los paquetes que no vienen del origen especificado.

-d [!] destino[/prefijo]/–destination [!] destino[/prefijo] : Matchea paquetes IP yendo a la dirección de destino especificada. La dirección de destino puede ser una dirección IP, una dirección IP con un prefijo de red asociado, o un nombre de terminal (hostname). Si ‘!’ precede al origen, se matchean todos los paquetes que no van al destino especificado.

–destination-port [!] [puerto[[:puerto]]/–dport [!] [puerto[[:puerto]] : Matchea paquetes TCP o UDP (dependiendo del argumento a la opción -p) destinados a los puertos o rango de puertos (cuando se usa la forma puerto:puerto) especificados. Si ‘!’ precede la especificación de puertos, se matchean todos los paquetes TCP o UDP que no están destinados a los puertos o rango de puertos especificados.

–source-port [!] [puerto[[:puerto]]/–sport [!] [puerto[[:puerto]] : Matchea paquetes TCP o UDP (dependiendo del argumento a la opción -p) que vienen de los puertos o rango de puertos (cuando se usa la forma puerto:puerto) especificados. Si ‘!’ precede la especificación de puertos, se matchean todos los paquetes TCP o UDP que no vienen de los puertos o rango de puertos especificados.

–tcp-flags [!] mask comp : Matchea paquetes TCP que tienen marcadas o desmarcadas ciertas banderas del protocolo TCP. El primer argumento especifica las banderas a examinar en cada paquete TCP, escritas en una lista separada por comas (no se permiten espacios). El segundo argumento es otra lista separada por comas de banderas que deben estar marcadas dentro de las que se debe examinar. Estas banderas son: SYN, ACK, FIN, RST, URG, PSH, ALL, y NONE. Por lo tanto, la opción “–tcp-flags SYN,ACK,FIN,RST SYN” solo va a matchear paquetes con la bandera SYN marcada y las banderas ACK, FIN y RST desmarcadas.

[!] –syn : Matchea paquetes TCP que tienen la bandera SYN marcada y las banderas ACK, FIN y RST desmarcadas. Estos paquetes son los que se usan para iniciar conexiones TCP. Al bloquear tales paquetes en la cadena de INPUT, se previenen conexiones TCP entrantes, pero conexiones TCP salientes no serán afectadas. Esta opción puede combinarse con otras, como –source, para bloquear o dejar pasar conexiones TCP entrantes solo de ciertas terminales o redes. Esta opción es equivalente a “–tcp-flags SYN,RST,ACK SYN”. Si ‘!’ precede a –syn, el significado de la opción se invierte.

Invocación

El comando iptables tiene las siguientes formas de invocación. Ítems entre llaves, {…|…|…}, son requeridos, pero solo se puede indicar uno de los ítems separados por ‘|’. Ítems entre corchetes, [...], son opcionales.

iptables { -A | –append | -D | –delete } cadena especificación-de-regla [ opciones ] : Esta forma de invocación del comando agrega (-A o –append) o elimina (-D o –delete) una regla de la cadena especificada. Por ejemplo, para agregar una regla a la cadena de INPUT en la tabla filter (la tabla por defecto cuando la opción -t no se especifica) que descarte todos los paquetes UDP, usamos este comando:
iptables -A INPUT -p udp -j DROP

Para borrar la regla agregada por el comando anterior, usamos este comando:
iptables -D INPUT -p udp -j DROP

El comando anterior borra en verdad la primera regla de la cadena de INPUT que matchea la especificación de regla “-p udp -j DROP”. Si hay varias reglas idénticas en la cadena, solo se borra la primera regla que matchee.

iptables { -R | –replace | -I | –insert } cadena numregla especificación-de-regla [ opciones ] : Esta forma de invocación del comando reemplaza (-R o –replace) una regla existente o inserta (-I o –insert) una regla nueva en la cadena especificada. De hecho, para reemplazar la cuarta regla en la cadena de INPUT por una regla que descarte todos los paquetes ICMP, usamos este comando:

iptables -R INPUT 4 -p icmp -j DROP

Para inserta una regla nueva en el segundo lugar de la cadena de OUTPUT que descarte todo el tráfico TCP dirigido al puerto 80 en cualquier terminal, usamos este comando:

iptables -I OUTPUT 2 -p tcp --dport 80 -j DROP

iptables { -D | –delete } cadena numregla [ opciones ] : Esta forma de invocación del comando elimina una regla del índice numérico especificado en la cadena especificada. Las reglas se numeran comenzando desde 1. Por ejemplo, para eliminar la tercer regla de la cadena FORWARD, usamos este comando:
iptables -D FORWARD 3

iptables { -L | –list | -F | –flush | -Z | –zero } [ cadena ] [ opciones ] : Esta forma de invocación del comando se usa para listar las reglas en una cadena (-L o –list), tirar (es decir, eliminar) todas las reglas de una cadena (-F o –flush), o para poner en cero el byte y los contadores de paquetes de una cadena (-Z o –zero). Si no se especifica ninguna cadena, la operación se realiza para todas las cadenas. Por ejemplo, para listar las reglas en la cadena de OUTPUT, usamos este comando:
iptables -L OUTPUT

Para tirar todas las cadenas, usamos este comando:
iptables -F

Para poner en cero el byte y los contadores de paquetes de la cadena de PREROUTING en la tabla nat, usamos este comando:
iptables -t nat -Z PREROUTING

iptables { -N | –new-chain } cadena / iptables { -X | –delete-chain } [ cadena ] : Esta forma de invocación del comando se usa para crear (-N o –new-chain) una cadena definida por el usuario nueva o para eliminar (-X o –delete-chain) una cadena definida por el usuario existente. Si no se especifica ninguna cadena con las opciones -X o –delete-chain, se eliminan todas las cadenas definidas por el usuario. No es posible eliminar cadenas ya incorporadas, como ser las cadenas de INPUT o OUTPUT en la tabla filter.

iptables { -P | –policy } cadena destino : Esta forma de invocación del comando se usa para especificar la política de destino para una cadena. De hecho, para especificar la política de destino para la cadena de INPUT en DROP, usamos este comando:

iptables -P INPUT DROP

iptables { -E | –rename-chain } nombre-de-cadena-viejo nombre-de-cadena-nuevo :Esta forma de invocación del comando se usa para renombrar una cadena definida por el usuario.

Ejemplos

Estos son ejemplos de uso cotidiano en algún Firewall o cortafuegos.

Firewall con iptables

Para generar este script con iptables, se deben seguir los siguientes pasos:

1. Se crea un archivo de texto con un editor de texto plano cualquiera, como ser vi, emacs o nano, entre muchísimos otros. A este archivo se lo llama, por ejemplo, iptables_ipt

2. Se le da permiso de ejecución mediante el comando chmod u+x o también chmod 777 iptables_ipt.

3. Se ejecuta desde la línea de comandos ./iptables_ipt

#!/bin/bash
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate NEW ! -i eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -A FORWARD -i eth1 -o eth1 -j REJECT
iptables -P INPUT DROP
iptables -P FORWARD DROP
echo "Firewall Activado"

Para este ejemplo, eth0 es la puerta local, y eth1 es la puerta de enlace a Internet. Puede además agregarse bloqueo de puertos específicos, como por ejemplo:

iptables -A INPUT -p tcp --dport 25 -j DROP # smtp filtrado

# Corroboramos con nmap los puertos y nos dirá algo parecido

$ sudo nmap -sT "nuestra IP"
* 22/tcp filtered ssh *
* 25/tcp filtered smtp *

Filtrado de puertos

Para filtrar un puerto específico, como el 22 ó 443, el código recomendable sería el siguiente:

$ sudo iptables -t filter -I INPUT -p tcp --dport 22 -j DROP
$ sudo iptables -t filter -I INPUT -p tcp --dport 443 -j DROP

Si se desea cerrar el puerto SSH completamente y que no sea filtrado:

$ sudo /etc/init.d/sshd stop

Si se desea acitvar de nuevo el puerto SSH para conexiones remotas:

$ sudo /etc/init.d/sshd start


Ejemplo de IPTables:

#!/bin/bash
WAN_INTERFAZ="eth1"
LAN_INTERFAZ="eth0"
IP_EXTERNA="laquesea"
IP_INTERNA="laquesea"
echo 1 > /proc/sys/net/ipv4/ip_forward
case "$1" in  
   start)
   #=====================================================   N A T ==================================================
   #Politicas por defecto en ACCEPT
   iptables -t nat -P PREROUTING ACCEPT 
   iptables -t nat -P POSTROUTING ACCEPT 
   iptables -t nat -P OUTPUT ACCEPT 

   #Hace la función de NAT, permite el acceso de los pcs de la red a inet sin tener IP real
   iptables -t nat -A POSTROUTING -o $LAN_INTERFAZ -j MASQUERADE   
    
   iptables -t nat -A POSTROUTING -s ! IP_EXTERNA -o $WAN_INTERFAZ -j SNAT --to-source IP_EXTERNA

    #====================================================  M A N G L E  ==============================================
    #Politicas por defecto
    #iptables -t mangle -P PREROUTING ACCEPT
    #iptables -t mangle -P POSTROUTING ACCEPT 
    #iptables -t mangle -P INPUT ACCEPT
    #iptables -t mangle -P FORWARD ACCEPT 
    #iptables -t mangle -P OUTPUT ACCEPT

    #iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark 
    #iptables -t mangle -A PREROUTING -m mark --mark 0x0/0xff -m mac --mac-source 00:02:CF:6E:4C:54 -j MARK --set-mark 0x1 
    #iptables -t mangle -A PREROUTING -m mark --mark 0x0/0xff -j MARK --set-mark 0x1 
    #iptables -t mangle -A PREROUTING -j CONNMARK --save-mark 
    #iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark 
    #iptables -t mangle -A OUTPUT -m mark --mark 0x0/0xff -j MARK --set-mark 0x1 
    #=====================================================  F I L T E R  ===============================================
    #Politicas por defecto en DROP
    iptables -P INPUT DROP
    iptables -P OUTPUT DROP
    iptables -P FORWARD DROP
    
    #-------- I N P U T -------    
    #Aceptamos aquellos paquetes de entrada cuya conexión ya haya sido establecida o esté relacionada
    iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
    #Aceptamos aquellos paquetes entrantes cuyo puerto destino sea el 53 (DNS)
    iptables -A INPUT -p udp -m udp --dport 53 -m state --state NEW -j ACCEPT
    #Aceptamos TODOS los paquetes que vengan de la red interna
    iptables -A INPUT -s 127.0.0.1 -j ACCEPT
    iptables -A INPUT -i $LAN_INTERFAZ -j ACCEPT

    #Aceptamos los paquetes de entrada cuyo protocolo sea icmp (pings por ejemplo) 
    iptables -A INPUT -p icmp -j ACCEPT   

    #ssh 
    iptables -A INPUT -i $WAN_INTERFAZ -p tcp -m tcp --dport 22 -j ACCEPT   
    #ssh 
    iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT    

    iptables -A INPUT -i $WAN_INTERFAZ -p tcp -m tcp --dport 4559 -j ACCEPT
    iptables -A INPUT -p tcp -m tcp --dport 4559 -m state --state NEW -j ACCEPT     

    #Aceptamos aquellos paquetes entrantes cuyo puerto destino sea el 80 (Apache)
    iptables -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT 
    #Aceptamos aquellos paquetes entrantes cuyo puerto destino sea el 443 (HTTPS)
    iptables -A INPUT -p tcp -m tcp --dport 443 -m state --state NEW -j ACCEPT 

    #SAMBA
    iptables -A INPUT -p tcp -m tcp -m multiport --dports 137,138,139,445 -m state --state NEW -j ACCEPT 
    iptables -A INPUT -p udp -m udp -m multiport --dports 137,138,139,445 -j ACCEPT
    iptables -A INPUT -p tcp -m tcp --dport 901 -m state --state NEW -j ACCEPT

    #Aceptamos aquellos paquetes entrantes cuyo puerto destino sea el 67 (DHCP)
    iptables -A INPUT -p udp -m udp --dport 67 -m state --state NEW -j ACCEPT

    #Aceptamos aquellos paquetes entrantes cuyo puerto destino sea el 9100 (Impresora)
    iptables -A INPUT -p tcp -m tcp --dport 9100 -m state --state NEW -j ACCEPT
    iptables -A INPUT -p udp -m udp --dport 9100 -m state --state NEW -j ACCEPT
    #Aceptamos aquellos paquetes entrantes cuyo puerto destino sea el 631 (CUPS)    
    iptables -A INPUT -p tcp -m tcp --dport 631 -m state --state NEW -j ACCEPT

    #Aceptamos aquellos paquetes entrantes cuyo estado sea nuevo  y el puerto sea el 8001 (peticiones de xchat)
    iptables -A INPUT -p tcp -m tcp --dport 8001 -m state --state NEW -j ACCEPT 
    #Aceptamos aquellos paquetes entrantes cuyo puerto destino sea el 25 (SSL-IMAP4)
    iptables -A INPUT -p tcp -m tcp --dport 25 -m state --state NEW -j ACCEPT      
    #Aceptamos aquellos paquetes entrantes cuyo puerto destino sea el 995 (Pop3-SSL)
    iptables -A INPUT -p tcp -m tcp --dport 995 -m state --state NEW -j ACCEPT 
    #Aceptamos aquellos paquetes entrantes cuyo puerto destino sea el 110 (Pop3)
    iptables -A INPUT -p tcp -m tcp --dport 110 -m state --state NEW -j ACCEPT 
    #Aceptamos aquellos paquetes entrantes cuyo puerto destino sea el 465 (Gmail)
    iptables -A INPUT -p tcp -m tcp --dport 465 -m state --state NEW -j ACCEPT   
    #Aceptamos aquellos paquetes entrantes cuyo puerto destino sea el 123 (NTP (obtener la hora)
    iptables -A INPUT -p udp -m udp --dport 123 -m state --state NEW -j ACCEPT 
    #Aceptamos aquellos paquetes entrantes cuyo puerto destino sea el 389 (LDAP)
    iptables -A INPUT -p tcp -m tcp --dport 389 -m state --state NEW -j ACCEPT    
    #Aceptamos aquellos paquetes entrantes cuyo puerto destino sea el 69 (TFTP)
    iptables -A INPUT -p udp -m udp --dport 69 -m state --state NEW -j ACCEPT   
    #Aceptamos aquellos paquetes entrantes cuyo puerto destino sea el 143 (Microsoft-Server)
    #iptables -A INPUT -p tcp -m tcp --dport 143 -m state --state NEW -j ACCEPT    
    
    #Aquellos paquetes entrantes cuyo estado sea nuevo los rechazamos (Nuevos solo queremos de salida)
    iptables -A INPUT -i $WAN_INTERFAZ -m state --state NEW -j DROP

    #Sacamos un log de entradas
    #iptables -A INPUT -j LOG
    
    #Todos los paquetes de entrada restantes los descartamos
    iptables -A INPUT -j DROP

    
    #-------- F O R W A R D --------  
    #Aceptamos aquellos paquetes de redirección cuya conexión ya haya sido establecida o esté relacionada
    iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
    #Redirigimos a las ips de los DNS externos a las peticiones con estado nuevo que nos lleguen al puerto 53
    iptables -A FORWARD -d 80.58.61.250/32 -p udp -m udp --dport 53 -m state --state NEW -j ACCEPT 
    iptables -A FORWARD -d 80.58.61.254/32 -p udp -m udp --dport 53 -m state --state NEW -j ACCEPT
    #Damos salida a aquellos paquetes cuya puerto sea el 53 (DNS) Creo que esto sobra...
    iptables -A FORWARD -i $LAN_INTERFAZ -p udp -m state --state NEW -m udp --dport 53 -j ACCEPT 
    iptables -A FORWARD -i $LAN_INTERFAZ -p tcp -m state --state NEW -m tcp --dport 53 -j ACCEPT
    #Damos salida a aquellos paquetes cuya puerto sea el 67 (DHCP)
    iptables -A FORWARD -i $LAN_INTERFAZ -p udp -m udp --dport 67 -m state --state NEW -j ACCEPT

    #Aceptamos la redirección de todos los paquetes cuyo protocolo sea icmp (pings, ...)
    iptables -A FORWARD -p icmp -j ACCEPT 
    #Aceptamos redirigir TODOS los paquetes que vayan/vengan a/de la red interna
    iptables -A FORWARD -i $LAN_INTERFAZ -j ACCEPT    

    #Forward PREROUTING
    iptables -A FORWARD -d IP_INTERNA/32 -i $WAN_INTERFAZ -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
    iptables -A FORWARD -d IP_INTERNA/32 -i $LAN_INTERFAZ -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT

    #Damos salida a aquellos paquetes cuya puerto sea el 9100 (Impresora)
    iptables -A FORWARD -i $LAN_INTERFAZ -p tcp -m tcp --dport 9100 -j ACCEPT
    iptables -A FORWARD -i $LAN_INTERFAZ -p udp -m udp --dport 9100 -j ACCEPT
     
    #Redirigimos aquellos paquetes cuyo paquete destino sea el 80
    iptables -A FORWARD -p tcp -m tcp --dport 80 -j ACCEPT            

    #Redirigimos aquellos paquetes cuyo paquete destino sea el 4559
    iptables -A FORWARD -p tcp -m tcp --dport 4559 -j ACCEPT

    #Aceptamos redirigir todos los paquetes cuyo destino sea el puerto 8001 (xchat)
    iptables -A FORWARD -p tcp -m tcp --dport 8001 -m state --state NEW -j ACCEPT    
    
    #Redirigimos aquellos paquetes que quieran salir a internet
    iptables -A FORWARD -o $WAN_INTERFAZ -j ACCEPT

    #Redirigimos aquellos paquetes cuyo protocolo sea TCP
    iptables -A FORWARD -p tcp -j ACCEPT
    
    #Todo lo que venga de internet y el estado sea nuevo lo rechazamos (solo aceptamos de la red interna)
    iptables -A FORWARD -i $WAN_INTERFAZ -m state --state NEW -j DROP 

    #Sacamos un log de redirecciones
    #iptables -A FORWARD -j LOG
    
    #Todos los paquetes de redirección restantes los descartamos
    iptables -A FORWARD -j DROP


    #-------- O U T P U T --------
    #Aceptamos dar salida a aquellos paquetes cuya conexión ya haya sido establecida o esté relacionada
    iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    #Aceptamos TODOS los paquetes que vengan de la red interna
    iptables -A OUTPUT -s 127.0.0.1 -j ACCEPT
    #Aceptamos dar salida a TODOS los paquetes que vengan de la red interna
    iptables -A OUTPUT -o $LAN_INTERFAZ -j ACCEPT
    iptables -A OUTPUT -o $WAN_INTERFAZ -j ACCEPT

    #Aceptamos dar salida a aquellos paquetes cuyo destino sea la ip indicada y el puerto el 53 (DNS)
    iptables -A OUTPUT -d 80.58.61.250/32 -p udp -m state --state NEW -m udp --dport 53 -j ACCEPT 
    iptables -A OUTPUT -d 80.58.61.254/32 -p udp -m state --state NEW -m udp --dport 53 -j ACCEPT
    #Damos salida a aquellos paquetes cuya puerto sea el 53 (DNS) Creo que esto sobra...
    iptables -A OUTPUT -p udp -m state --state NEW -m udp --dport 53 -j ACCEPT 
    iptables -A OUTPUT -p tcp -m state --state NEW -m tcp --dport 53 -j ACCEPT
    #Damos salida a aquellos paquetes cuya puerto sea el 67 (DHCP) Creo que esto sobra...
    iptables -A OUTPUT -p udp -m state --state NEW -m udp --dport 67 -j ACCEPT
    iptables -A OUTPUT -p tcp -m state --state NEW -m tcp --dport 67 -j ACCEPT

    #Aceptamos dar salida a todos los paquetes cuyo protocolo sea icmp (pings, ...)
    iptables -A OUTPUT -p icmp -j ACCEPT     
    
     #SAMBA
    iptables -A OUTPUT -d 192.168.1.152 -p tcp -m tcp -m multiport --dports 137,138,139,445 -m state --state NEW -j ACCEPT
    iptables -A OUTPUT -d 192.168.1.152 -p udp -m udp -m multiport --dports 137,138,139,445 -j ACCEPT
    iptables -A OUTPUT -d 192.168.1.152 -p tcp -m tcp --dport 901 -m state --state NEW -j ACCEPT

    #Aceptamos dar salida a aquellos paquetes cuyo puerto destino sea el 22 (SSH)
    iptables -A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT    

    #Aceptamos dar salida a aquellos paquetes cuyo puerto destino sea el 21 (SSH)
    iptables -A OUTPUT -p tcp -m tcp --dport 21 -m state --state NEW -j ACCEPT

    #Aceptamos dar salida a aquellos paquetes cuyo puerto destino es el 80 (Apache/Web)
    iptables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT   
    #Aceptamos dar salida a aquellos paquetes cuyo puerto destino sea el 443 (HTTPS)
    iptables -A OUTPUT -p tcp -m tcp --dport 443 -m state --state NEW -j ACCEPT 

    #Aceptamos dar salida a aquellos paquetes cuyo puerto destino es el 9100 (Impresora)
    iptables -A OUTPUT -p tcp -m tcp --dport 9100 -j ACCEPT  
    iptables -A OUTPUT -p udp -m udp --dport 9100 -j ACCEPT 
    #Aceptamos dar salida a aquellos paquetes cuyo puerto destino sea el 8001 (xchat) 
    iptables -A OUTPUT -p tcp -m tcp --dport 8001 -m state --state NEW -j ACCEPT

    #Sacamos un log de salidas
    #iptables -A OUTPUT -j LOG
             
    #El resto de paquetes de salida los rechazamos
    iptables -A OUTPUT -j DROP 
   ;;
   stop)
   iptables -F
   iptables -t nat -F
   iptables -t mangle -F
   iptables -t filter -F
   iptables -X 
   iptables -P INPUT ACCEPT
   iptables -P OUTPUT ACCEPT
   iptables -P FORWARD ACCEPT 
   ;;
esac 
exit 0
About these ads

Acciones

Información

Deja un comentario

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s




Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

%d personas les gusta esto: