Configuración firewall iptables Red Hat/CentOS 6, desde linea de comandos

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:

  1. Existen chains (cadenas) de reglas. Basicamente 3: INPUT, OUTPUT y FORWARD.
  2. Las reglas dentro de una cadena se evaluan por orden. Es aquí donde hay multitud de opciones de filtrado.
  3. 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:

Código   
/sbin/iptables -L

La relación de puertos y servicios se puede ver en:

Código   
/etc/services

iptables 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):

Código   
iptables [-t tabletype] COMMAND  [-m MATCH_EXTENSION] -j TARGET

tabletype=>

  • 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 destino 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.

Ejemplo, aceptar todas las conexiones relativas o establecidas(es mejor aplicar filtrado solo a conexiones NEW):

Código   
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
  • comment, aplicar comentarios a una regla. Opciones:
    • –comment comentario

Ejemplo:

Código   
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:

Código   
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:

Código   
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:

Código   
#!/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 ACCEPT

Los comentarios ayudan mucho a identificar el cometido de cada una de las reglas:

Código   
[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:

Código   
[jcmolinos@ppcjuancmolinos ~]$ telnet 192.168.122.150 25
Trying 192.168.122.150...
telnet: connect to address 192.168.122.150: Connection refused

Y veremos en el log /var/log/messages:

Código   
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.i686

Aplicación de reglas de forma automática

Si tenemos activado en el arranque el servicio iptables:

Código   
[root@tester1 ~]# chkconfig --list iptables
iptables 0:desactivado 1:desactivado 2:activo 3:activo 4:activo 5:activo 6:desactivado

Para que las reglas sean permanentes se han de incluir en el fichero:

Código   
/etc/sysconfig/iptables

Contenido ejemplo:

Código   
[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
COMMIT

Su 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:

Código   
/etc/init.d/iptables save

Esto actualizará el fichero:

Código   
/etc/sysconfig/iptables

Con 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.

Código   
[root@tester1 ~]# chkconfig iptables on

Hay que tener en cuenta que las utilidades system-config-firewall-tui y system-config-firewall sobreescriben todas estas configuraciones, yo prefiero no usarlas.

8 thoughts on “Configuración firewall iptables Red Hat/CentOS 6, desde linea de comandos

  1. excelente’ lei varios ejemplos en otras paginas y tu explicacion me parece la mas clara de todas, muchas gracias por compartir tu conocimiento.

  2. Pingback: Configuración iptables para conexiones salientes, en Red Hat/CentOS 6 o Ubuntu | Administrando Sistemas

  3. Pingback: JBoss en servidor externo RHEL 7 y Eclipse Kepler con Spring MVC - elConspirador

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

20 + cuatro =

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>