IPTABLES es el firewall incluido a nivel de kernel en las distribuciones Linux, es muy potente (una vez comprendido su funcionamiento), muy útil y flexible. Este post se ha hecho sobre un CentOS 6 (clon de Red Hat), prácticamente todo se debería poder aplicar a cualquier distribución.
Mucho cuidado con los — y los -, wordpress hace conversiones, el largo son en realidad 2 cortos. En los ejemplos no existe esa conversión.
El funcionamiento básico de iptables es el siguiente:
- Existen chains (cadenas) de reglas. Basicamente 3: INPUT, OUTPUT y FORWARD.
- Las reglas dentro de una cadena se evaluan por orden. Es aquí donde hay multitud de opciones de filtrado.
- Cuando una regla se evalua de forma positiva, es dirigida a un TARGET. Puede ser aceptada, denegada, eliminada, logada u otras muchas consas más (ver man iptables TARGET EXTENSIONS).
Podemos listar las reglas actuales con:
/sbin/iptables -LLa relación de puertos y servicios se puede ver en:
/etc/servicesiptables trabaja con el concepto cadenas (chains), 3 tipos:
- INPUT, tráfico entrante.
- OUTPUT, tráfico saliente.
- FORWARD, tráfico a través de la máquina.
Sintaxis IPTABLES (muy resumido, para más detalles ver man):
iptables [-t tabletype] COMMAND [-m MATCH_EXTENSION] -j TARGETtabletype=>
- filter, filtrado de paquetes (por defecto)
- nat, configuración NAT o enmascaramiento
<COMMAND>=>
- -A, –append chain rule-specification, añadir una regla al final de la cadeana
- -D –delete chain [rulenum|rule-specification] , elimina una regla. Si se especifica mediante rulenum, la primera regla es 1.
- -I, –insert chain [rulenum] rule-specification, inserta una regla antes de la numrule (por defecto 1, la primera)
- -R, –replace chain rulenum rule-specification, reemplaza una regla en una chain (numrule=1 es la primera)
- -L, –list [chain], listado reglas
- -F, –flush [chain], flush de reglas en chains actuales (las borra todas)
<rule-specification>=>
- [!] -s –source address[/mask], origen del paquete, puede ser una ip con o sin máscara o el nombre de un host
- [!] -d –destination address[/mask], destino del paquete, puede ser una ip con o sin máscara o el nombre de un host(ojo que el nombre solo se resuelve una sola vez antes de enviar las reglas al kernel).
- [!] -p –protocol, protocolo usado en la cominicación: tcp, udp, udplite, icmp, esp, ah, sctp o all
- [!] –source-port,–sport port[:port], puerto o rango de puertos de origen de la comunicación
- [!] –destination-port,–dport port[:port], puerto o rango de puertos de destino de la comunicación
- [!] -i –in-interface name, nombre del interfaz de entrada de la comunicación. Por defecto todos los interfaces.
- [!] -o –out-interface name, nombre del interfaz de salida de la comunicación. Por defecto todos los interfaces.
Si se antepone una !, esto quiere decir que estamos negando la condicion.
<MATCH_EXTENSION>, puede especificarse con -m o –match
- state, permite filtrar por estado de conexion. Opciones:
- [!] –state estado, se pueden especificar varios estados separados por ,. Los estados pueden ser:
- INVALID, paquete no identificado.
- NEW, nueva conexión
- ESTABLISHED, conexión existente.
- RELATED, relativa a otra conexión.
- [!] –state estado, se pueden especificar varios estados separados por ,. Los estados pueden ser:
Ejemplo, aceptar todas las conexiones relativas o establecidas(es mejor aplicar filtrado solo a conexiones NEW):
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
- comment, aplicar comentarios a una regla. Opciones:
- –comment comentario
Ejemplo:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -m comment --comment "Permitir conexiones existentes" -j ACCEPT
- mac, aplicar filtrado por MAC, no es aplicable para el chain OUTPUT. Opciones:
- [!] –mac-source address, el formato de MAC es XX:XX:XX:XX:XX:XX
Ejemplo:
iptables -A INPUT -p TCP --dport 80 -m mac --mac-source FE:54:00:FC:4F:CC -j ACCEPT
- limit, aplicación de limites promedios y ráfagas. Opciones:
- –limit rate[/second|/minute|/hour|/day], especifica una frecuencia media por unidad de tiempo.
- –limit-burst number, especifica una cantidad de peticiones a las que no se aplicará el limit. Una vez superado se ceñirá a la especimicación de limit.
Ejemplo, aceptar una media de 1 conexión por segundo con ráfagas de 2:
iptables -A INPUT -m state --state NEW -p tcp --dport 25 -m limit --limit 1/second --limit-burst 2 -j ACCEPT
<TARGET>=>
- DROP, eliminar paquete sin informar al remitente
- REJECT, eliminar paquete informado error al remitente por defecto port-unreachable. El error informado se puede definir con: –reject-with [icmp-net-unreachable, icmp-host-unreachable, icmp-port-unreachable, icmp-proto-unreachable, icmp-net-prohibited, icmp-host-prohibited, icmp-admin-prohibited]
- ACCEPT, paquete aceptado
- LOG, es un TARGET EXTENSIONS. Escribe algo en el log, podemos configurar el prefijo con –log-prefix «texto_prefijo». Por defecto escribe en /var/log/messages
Ejemplo para permitir icmp, puerto 22, aceptar puerto 80 por una MAC específica, denegar todas las conexiones puerto 80 y logar, limitar tráfico puerto 22 y logar, permitir conexiones salientes puerto 22, eliminar demás conexiones salientes y permitir comunicación a través de la máquina:
#!/bin/bash
#flush de todas las reglas y todos los chains
iptables -F
#trafico entrante
iptables -A INPUT -m state --state ESTABLISHED,RELATED -m comment --comment "Aceptar conexiones existentes" -j ACCEPT
iptables -A INPUT -p icmp -m comment --comment "Aceptar ping" -j ACCEPT
iptables -A INPUT -i lo -m comment --comment "Aceptar conexiones internas" -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 22 -m comment --comment "Aceptar puerto 22" -j ACCEPT
iptables -A INPUT -p TCP --dport 80 -m mac --mac-source FE:54:00:FC:4F:CC -m comment --comment "Aceptar peticiones al puerto 80 por una MAC" -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 80 -m comment --comment "Logar intentos accesos puerto 80" -j LOG --log-prefix "denegado_puerto_80"
iptables -A INPUT -m state --state NEW -p tcp --dport 80 -m comment --comment "Eliminar accesos puerto 80" -j DROP
iptables -A INPUT -m state --state NEW -p tcp --dport 25 -m limit --limit 1/second --limit-burst 2 -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 25 -j LOG --log-prefix "Ataque DOS puerto 25"
iptables -A INPUT -m comment --comment "Eliminar todo lo demás" -j DROP
#trafico saliente
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -m comment --comment "Aceptar conexiones salientes existentes" -j ACCEPT
iptables -A OUTPUT -m state --state NEW -p tcp --dport 22 -m comment --comment "Aceptar puerto 22 saliente" -j ACCEPT
iptables -A OUTPUT -m comment --comment "Eliminar todas las demás salientes" -j DROP
#trafico interno
iptables -A FORWARD -m comment --comment "Aceptar todo el tráfico interno" -j ACCEPTLos comentarios ayudan mucho a identificar el cometido de cada una de las reglas:
[root@tester1 ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED /* Aceptar conexiones existentes */
ACCEPT icmp -- anywhere anywhere /* Aceptar ping */
ACCEPT all -- anywhere anywhere /* Aceptar conexiones internas */
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh /* Aceptar puerto 22 */
ACCEPT tcp -- anywhere anywhere tcp dpt:http MAC FE:54:00:FC:4F:CC /* Aceptar peticiones al puerto 80 por una MAC */
LOG tcp -- anywhere anywhere state NEW tcp dpt:http /* Logar intentos accesos puerto 80 */ LOG level warning prefix `denegado_puerto_80'
DROP tcp -- anywhere anywhere state NEW tcp dpt:http /* Eliminar accesos puerto 80 */
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:smtp limit: avg 1/sec burst 2
LOG tcp -- anywhere anywhere state NEW tcp dpt:smtp LOG level warning prefix `Ataque DOS puerto 25'
DROP all -- anywhere anywhere /* Eliminar todo lo demás */
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere /* Aceptar todo el tráfico interno */
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED /* Aceptar conexiones salientes existentes */
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh /* Aceptar puerto 22 saliente */
DROP all -- anywhere anywhere /* Eliminar todas las demás salientes */Ahora desde fuera de la máquina podemos intentar (4 veces en menos de 2 segundos) un:
[jcmolinos@ppcjuancmolinos ~]$ telnet 192.168.122.150 25
Trying 192.168.122.150...
telnet: connect to address 192.168.122.150: Connection refusedY veremos en el log /var/log/messages:
8.122.150 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=1351 DF PROTO=TCP SPT=46644 DPT=25 WINDOW=14600 RES=0x00 SYN URGP=0
Mar 7 20:38:03 tester1 yum: Installed: wget-1.12-1.4.el6.i686Aplicación de reglas de forma automática
Si tenemos activado en el arranque el servicio iptables:
[root@tester1 ~]# chkconfig --list iptables
iptables 0:desactivado 1:desactivado 2:activo 3:activo 4:activo 5:activo 6:desactivadoPara que las reglas sean permanentes se han de incluir en el fichero:
/etc/sysconfig/iptablesContenido ejemplo:
[root@tester1 sysconfig]# cat iptables
# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMITSu edición manual no es recomendada se debería usar system-config-firewall, o directamente no usarlo nunca y de esa forma no sobreescribe nuestras reglas.
Lo que se puede hacer es realizar todos los cambios en iptables como hemos visto arriba y luego directamente hacer:
/etc/init.d/iptables saveEsto actualizará el fichero:
/etc/sysconfig/iptablesCon las reglas que teníamos en memoria hasta ahora, nos asegurarnos que el servicio de iptables esté con arranque automático para que se apliquen las reglas en el siguiente arranque.
[root@tester1 ~]# chkconfig iptables onHay que tener en cuenta que las utilidades system-config-firewall-tui y system-config-firewall sobreescriben todas estas configuraciones, yo prefiero no usarlas.



muy buen material se agradece muxo
excelente’ lei varios ejemplos en otras paginas y tu explicacion me parece la mas clara de todas, muchas gracias por compartir tu conocimiento.
Gracias a ti…
le falto decir que se configura en el archivo /etc/sysconfig/iptables
Esa información ya aparecía al final de la entrada…
Lo voy a poner en practica.
Mil gracias, buen post.
BV.
Pingback: Configuración iptables para conexiones salientes, en Red Hat/CentOS 6 o Ubuntu | Administrando Sistemas
Pingback: JBoss en servidor externo RHEL 7 y Eclipse Kepler con Spring MVC - elConspirador
Disculpa tengo un error precisamente con el puerto 25 y no lo puedo resolver me sale el mismo error que te sale a ti y ya agregue los iptables correspondientes
Hola, ¿de que error estás hablando exáctamente?
Pingback: iptables output, configuración iptables para conexiones salientes, en Red Hat/CentOS 6 o Ubuntu - Administrando Sistemas