IPTABLES desde cero. 2
Aprendiendo iptables desde cero.
By Jos? Roberto Negreira a.k.a Xous
Version 2005-MAR-09
Disclaimer
Este art?culo se provee absolutamente sin garant?a de NINGUN TIPO. (De hecho, dif?cilmente encuentren documentaci?n en la cual los autores se hagan cargo de las cosas que puedan salir mal). El eventual lector es responsable de las acciones y consecuencias que ?ste realice y produzca. Espero que esta aclaraci?n no haya herido la susceptibilidad de nadie, pero la considero muy pero muy oportuna, para evitar cualquier tipo de problemas…porque a alguien se le haya ocurrido toquetear/desconfigurar/reventar el firewall de su empresa, siguiendo las indicaciones de este articulo. Pod?s distribuir este documento siempre y cuando mantengas la info de copyright, y el link a www.iptableslinux.com
Historial
2005-ABR-08: publicado la versi?n en español en iptableslinux.com
2005-MAR-08: published on iptableslinux.com
2005-MAR-08: 3 years after! translated to english
2002-MAR-02: Published on XousLAB (Thanks to myself
)
2002-MAR-02: Publicado en XousLab (Grax XouS
)
2002-FEB-27: Se corrigi? un error de una regla (Gracias Kremar)
2002-FEB-24: Publicado en PsicoFXP - Seguridad
2002-FEB-16: Publicado en el bolet?n de HTeam (Gracias CyRaNo)
Introducci?n
Al conectarnos a internet en nuestras casas, de forma expl?cita nos estamos conectando, en AMBOS sentidos: directamente a la red, "desnudos" si se me permite la analog?a. El objetivo de este art?culo es, medinte iptables, lograr cierta protecci?n y seguridad. N?tese que un firewall no garantiza 100% de seguridad.
Para este art?culo, se requieren conocimientos b?sicos/intermedios acerca de linux y TCP/IP, obviamente implementado bajo dicho sistema operativo.
Cabe destacar que para utilizar iptables, es necesario tener un kernel preparado para ?ste, y el m?dulo ip_tables cargado. Del mismo modo, si estas utilizando ipchains, se deben descargar sus m?dulos antes de cargar los de iptables.
Iptables es una utilidad de linux que se encarga de darle directivas al kernel, acerca del filtrado de paquetes TCP/IP. Un paquete TCP/IP consta de varios campos, con informaci?n adicional a los datos que se transmiten en s?. No viene al caso describir cada uno de ellos, sino los que consideraremos mas relevantes, es decir, aquellos campos que mediante iptables, empezaremos a "vigilar". Ejemplo: direccion origen, direccion destino, puerto origen, puerto de destino, etc.
C?mo funciona?
El kernel de linux posee (predefinidas "de f?brica"
3 cadenas (chains) de reglas: INPUT, FORWARD y OUTPUT. Cada paquete TCP/IP que ingresa/atraviesa/sale desde/hacia una maquina con iptables funcionando, pasar? por la cadena INPUT, FORWARD o OUTPUT respectivamente. Las cadenas, no son mas que un listado de reglas, con las cuales controlamos cada uno de los paquetes que pasan. Ahora se preguntaran, que es una regla?. Para evitar las confusiones, vamos a simplificar su definici?n al m?ximo, y luego mostrarles algunos ejemplos. Una regla consta de 2 partes, y no es mas que una condici?n y una acci?n. Si se cumple la condici?n se ejecuta la acci?n. Simple, verdad?
Algo para tener en cuenta mas adelante: si un paquete atraves? todas las reglas de una cadena, sin hallar coincidencia, iptables se fijar? en la politica por defecto de esa cadena(default policy).
Kernel? forward? paquetes? cadenas? chains? reglas? Me siento un poco mareado…
A no perder la calma…Resumiendo lo anteriormente dicho:
1) Lo mas importante: tener conocimientos previos en linux y TCP/IP !!!
2) El kernel de linux trae 3 cadenas primarias de reglas (INPUT, FORWARD y OUTPUT)
3) Con iptables se pueden agregar/eliminar reglas (entre otras cosas).
Y este es el momento ideal para teclear "man iptables", si no lo hiciste antes, para tener una idea del funcionamiento de esta utilidad. No obstante, esto no es requisito obligatorio para continuar leyendo.. =)
Supongamos la siguiente situaci?n…Hab?a una vez, una red local (192.168.1.0), con 50 PC’s, de las cuales destacaremos:
1) intruso.mired.lan (192.168.1.15) <— rebautizada para la ocasion =)
2) neutral.mired.lan (192.168.1.18) <— alguien que no corta ni pincha.
3) jose.mired.lan (192.168.1.20) <— nuestra adorable Linux Box
Nosotros somos los operadores de "jose.mired.lan", estamos corriendo un servicio ftp (wu-ftpd*), y estamos enterados de que el muchacho que usa "intruso", es alguien muy curioso, que le gusta investigar en m?quinas ajenas, utilizando su interfaz de red.
* NOTA: No es objetivo del presente art?culo discutir vulnerabilidades de servicios.
Experimentando con paquetes icmp
Este es nuestro primer objetivo real con iptables. Veamos el estado actual de nuestras 3 cadenas, listando su contenido, ejecutaremos este comando:
[root@jose /]# /sbin/iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Si la salida obtenida no se parece a lo que ven aqui arriba, significa que no tienen instalados los m?dulos correspondientes en el kernel, o que ya hay un firewall funcionando, o para confundirlos m?s: significa que ya se ejecut? un script (probablemente en el inicio del sistema) donde se cargan las reglas del firewall. Consulten la documentaci?n de la distribuci?n que instalaron ![]()
Suponiendo que la salida que obtuvieron es igual a la escrita aqui arriba, su situaci?n es la siguiente: quiere decir que el firewall esta aceptando todos los paquetes, o lo que es lo mismo, no filtra absolutamente nada. Esto nos indica 2 cosas:
- Las 3 cadenas (INPUT/FORWARD/OUTPUT) estan vac?as
- Las 3 cadenas tienen como politica default "ACCEPT".
Es normal que al hacer un ping a localhost (nosotros mismos) recibamos respuesta:
[root@jose /]# ping localhost
PING localhost.localdomain (127.0.0.1) from 127.0.0.1 : 56(84) bytes of data.
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=0 ttl=255 time=0.3 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=1 ttl=255 time=0.1 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=2 ttl=255 time=0.1 ms
(and so forth…)
Vamos a agregar una regla, para entender el funcionamiento:
[root@jose /]# /sbin/iptables –append INPUT –protocol icmp –source 127.0.0.1 –jump DROP
Qu? es esto? Simple: Agregar (append) la siguiente regla a la cadena INPUT: al recibir un paquete del tipo icmp (–protocol) con origen (–source) "127.0.0.1" y con cualquier destino (ya que no lo especificamos), enviamos ese paquete (–jump) a DROP, que por cierto es lo mismo que dejarlo tirado =).
Que? No pas? nada, verdad? Seguro? Entonces listemos otra vez las reglas que tenemos cargadas (te olvidaste como se hacia??)
[root@jose /]# /sbin/iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP icmp — 127.0.0.1 0.0.0.0/0
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Notamos que en la cadena INPUT, se nos agreg? una regla, cuya funci?n es impedir que se haga ping desde nuestra propia m?quina. Podr?n notar que esta regla no es demasiado ?til a los fines pr?cticos, pero si lo es para ejemplificar el uso. Y que es lo que faltar?a? Comprobar su funcionamiento!! por supuesto!!
[root@jose /]# ping localhost
PING localhost.localdomain (127.0.0.1) from 127.0.0.1 : 56(84) bytes of data.
(y se quedar? esperando una respuesta que nunca llegar?…)
Nuestro firewall est? invisible? Claro que no. De hecho, veremos que desde la pc "intruso", hacemos ping sin problemas, y nuestra maquina le responde.
[root@intruso /]# ping jose.iptableslinux.lan
PING jose.iptableslinux.lan (192.168.1.20) from 192.168.1.15 : 56(84) bytes of data.
64 bytes from 192.168.1.20: icmp_seq=0 ttl=255 time=2.524 msec
64 bytes from 192.168.1.20: icmp_seq=1 ttl=255 time=1.319 msec
Con lo cual, con un simple ping, nuestro amigo operador de "intruso" puede notar la presencia de nuestra PC. A no desesperar que esto recien comienza.
C?mo funciona?
Puesto que nuestro firewall est? filtrando los paquetes ICMP locales, y deja pasar los remotos. Vamos a cambiar un poco las reglas "del juego". Borramos la regla que anteriormente agregamos![]()
Esto se logra con la opci?n "–delete", y el resto, es la transcripci?n EXACTA de la regla que queremos borrar.
[root@jose /]# /sbin/iptables –delete INPUT –protocol icmp –source 127.0.0.1 –jump DROP
NOTA: conociendo que era la ?nica regla, hubieramos logrado el mismo resultado escribiendo:
[root@jose /]# /sbin/iptables –delete INPUT 1
Ahora lo que importa: Restringir el acceso a paquetes icmp desde la red!!!
[root@jose /]# /sbin/iptables -A INPUT -p icmp -s 192.168.1.15 -j DROP
Notese que es indistinto escribir -A o –append, -D o –delete, -p o –protocol, etc. Ahora, listamos nuestra cadena INPUT:
[root@jose /]# /sbin/iptables -nL INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP icmp — 192.168.1.15 0.0.0.0/0
Listo, ahora cualquier paquete icmp con origen en 192.168.1.15 ser? "DROPeado". Por ello, cuando nuestro amigo curioso hace ping desde su m?quina a la nuestra, jam?s tendr? respuesta..
[root@intruso /]# ping jose.mired.lan
PING jose.mired.lan (192.168.1.20) from 192.168.1.15 : 56(84) bytes of data.
Fant?stico. Para nuestro amigo, nuestra m?quina est? invisible, por consiguiente, logramos nuestro objetivo de asegurarla. Cierto? NOOO!! Sacrilegio!! NO no no y nooooO!?
No! NO NO NO!!
Nuestro amigo, extrañado por que el comando ping no respondi?, en un principio pens? que tendr?amos la PC apagada, pero luego ejecut?…
[root@intruso /]# ftp jose.mired.lan
Connected to jose.mired.lan.
220 jose FTP server (Version wu-2.6.1-16) ready.
Name (jose:root):
Oh Oh! Nos hemos olvidado que ten?amos un FTP server corriendo… Y corriendo apurados agregamos la siguiente regla:
[root@jose /]# /sbin/iptables -A INPUT -p tcp -s 192.168.1.15 –dport 21 -j DROP
Listamos la cadena INPUT y obtenemos
[root@jose /]# /sbin/iptables -nL INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP icmp — 192.168.1.15 0.0.0.0/0
DROP tcp — 192.168.1.15 0.0.0.0/0 tcp dpt:21
Por su parte, nuestro "amigo" se aburrir? de esperar hasta que nuestro FTP le responda (cosa que no suceder?). Interesante, verdad?
Ahora: pensemos lo siguiente, que pasa si en nuestra red, de las 50 PC’s que la conforman, la mayor?a son "amigos curiosos" ??. Agregaremos una regla para cada uno de ellos? Ser?a un trabajo bastante tedioso, y poco eficiente. Adem?s, un detalle realmente importante: si bien todas estas reglas, se aplicar?an sin problemas, y son correctas sint?cticamente, es MUY ACONSEJABLE seguir la filosof?a de "Todo lo que no est? EXPLICITAMENTE permitido, entonces est? prohibido".
Como logramos esto? Como primer paso, setearemos la politica por defecto en DROP (descartar). Cualquier paquete que circula por la cadena INPUT es DROPeado si no coincide con ninguna regla.
En caso de que est?n editando el iptables desde una consola local, pueden ignorar el parrafo siguiente:
NOTA IMPORTANTE: para aquellos que estan toqueteando el iptables remotamente (ya sea por telnet o ssh), si setean como pol?tica DROP para la cadena INPUT se les caer? la conexi?n. De hecho me pas? a mi, es por eso que previamente deberan agregar la siguiente regla:
[root@jose /]# /sbin/iptables -A INPUT -p tcp -s #ORIGEN# –dport #PUERTO# -j DROP Donde #ORIGEN# es el IP desde donde se est?n conectando al linux con iptables y #PUERTO# debe ser el 22 (si es conexion ssh) o 23 (si usan telnet)
Ahora, como dec?amos, continuaremos seteando la pol?tica de INPUT en DROP (con la opci?n -P):
[root@jose /]# /sbin/iptables -P INPUT -j DROP
Vaciamos todas las cadenas con la opci?n -F (flush)
[root@jose /]# /sbin/iptables -F
Listamos lo que tenemos
[root@jose /root]# /sbin/iptables -nL INPUT
Chain INPUT (policy DROP)
target prot opt source destination
Aunque no tengamos ninguna regla, nadie va a poder acceder a nuestra PC por ningun motivo. Justamente, cualquier paquete que entra, es expuesto a cada regla de la cadena (en nuestro caso nuestra cadena esta vac?a), al no encontrar coincidencias, el destino del paquete, lo decide la pol?tica de la cadena, osea DROP. El problema aqu? es que aunque nosotros podamos realizar conexiones salientes, las respuestas de los servidores ser?n descartadas. Para solucionar esto, agregamos la siguiente regla:
[root@jose /root]# /sbin/iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
Por la cual dejamos pasar cualquier paquete cuya conexi?n ya se ha establecido (ESTABLISHED), o cuya conexi?n es nueva, pero est? relacionada a una conexi?n ya establecida (RELATED), seg?n las man pages del iptables. (les dije que las lean, no?)
Por en?sima vez, listamos nuestra cadena INPUT:
[root@jose /root]# /sbin/iptables -nL INPUT
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all — 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
Con lo cual, nadie podr? iniciar una conexion a nuestra maquina, salvo que especifiquemos… Como ver?n, por defecto tenemos un DROP. Ahora podemos empezar a permitir conexiones.
Acceso Local:
[root@jose /root]# /sbin/iptables -A INPUT -i lo -s 127.0.0.1 -j ACCEPT
-i lo : Con esto especifico como interfaz de red a localhost (lo)
[root@jose /root]# /sbin/iptables -nL INPUT
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all — 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
ACCEPT all — 127.0.0.1 0.0.0.0/0
Le permito a "neutral", el acceso ftp (puerto 21)
[root@jose /root]# /sbin/iptables -A INPUT -p tcp -s 192.168.1.18 –dport 21 -j ACCEPT
[root@jose /root]# /sbin/iptables -nL INPUT
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all — 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
ACCEPT all — 127.0.0.1 0.0.0.0/0
ACCEPT tcp — 192.168.1.18 0.0.0.0/0 tcp dpt:21
Consejos ?tiles y comentarios finales
=================================
A medida que vayan interioriz?ndose en la utilidad iptables, podr?n ir permitiendo (o no) el acceso a sus m?quinas, redes, servicios, seg?n el puerto origen o destino, host (o red) de origen, etc. Esta es solo una ?nfima parte de lo que pueden realizar con la herramienta iptables.
Por ?ltimo, a?n no apaguen su m?quina. Los cambios realizados ‘on-the-fly’ a iptables, no quedan guardados en ning?n archivo, sino que se almacenan en memoria, y como sabr?n, al reiniciar, los cambios se borrar?n. Tengan en cuenta los siguientes consejos:
1) Guarden todas sus reglas en un script prolijo, y con comentarios explicando cada regla o grupo de reglas aplicadas
2) En caso de ejecutar el script autom?ticamente al iniciar la m?quina, consideren hacerlo antes de levantar ning?n servicio, o mejor a?n, antes de levantar ninguna interfaz de red. No se preocupen por las reglas que hacen referencia a interfaces no levantadas, igualmente son aceptadas por iptables.
3) Contin?en leyendo la documentaci?n que viene con iptables. Ojo que esto *no es* un consejo tipo ‘RTFM’ usual, porque las man pages de iptables constituye una real fuente y bien completa de informaci?n, y por supuesto tambi?n, la infinita documentaci?n que encontrar?n en internet
Y finalmente, espero que hayan disfrutado la lectura de estas lineas tanto como yo lo he hecho al escribirlas ![]()
Me gustar?a mucho recibir alg?n tipo de feedback (no puteadas, por favor), solo para saber si este documento le result? util a alguien o si lo desean linkear o subir a alg?n sitio. Y por supuesto, sugerencias, correcciones, etc.
direcci?n: feedback at iptableslinux.com
Consegu? la ?ltima versi?n de este documento en:
http://www.iptableslinux.com
NOTA
Cabe destacar que el servicio FTP es at?pico, o al menos diferente a otros protocolos (TELNET, SSH, etc), el cual posee 2 modos de conexi?n: activo y pasivo. El modo "activo" que es soportado por cualquier cliente FTP, adem?s de la conexi?n hecha desde el cliente al servidor, el servidor abre otra conexi?n auxiliar al cliente (desde y hacia cualquier puerto, salvo que el servidor permita especificar un rango). Por el contrario, con el modo "pasivo", ambas conexiones son abiertas desde el cliente al servidor (puertos 21 y 20, por defecto). Esto deber?an tenerlo en cuenta cuando uds., siendo los clientes y estando detr?s de un firewall, en una red "protegida", desean conectarse a alg?n FTP "del otro lado" del firewall.




























Paulo Cesar Alvarado