Tengo un firewall de iptables bastante simple en un servidor que proporciona servicios MySQL, pero parece que iptables me está dando resultados muy inconsistentes.
La política predeterminada en el script es la siguiente:
iptables -P INPUT DROP
Entonces puedo hacer público MySQL con la siguiente regla:
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
Con esta regla, puedo conectarme a MySQL desde cualquier IP de origen a cualquier IP de destino en el servidor sin ningún problema. Sin embargo, cuando trato de restringir el acceso a solo tres IP reemplazando la línea anterior con la siguiente, me encuentro con problemas (xxx = octeto enmascarado):
iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.XXX.XXX.184 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.XXX.XXX.196 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.XXX.XXX.251 -j ACCEPT
Una vez que las reglas anteriores están en su lugar, sucede lo siguiente:
Me puedo conectar con el servidor MySQL desde los 0.184, .196 y .251 anfitriones muy bien, siempre y cuando estoy conectando con el servidor MySQL utilizando su dirección IP por defecto o un alias IP en la misma subred que la dirección IP por defecto.
Soy incapaz de conectar a MySQL usando alias IP asignadas al servidor desde una subred diferente de IP por defecto del servidor cuando estoy procedentes de los .184 o .196 .251 anfitriones, pero funciona muy bien. Desde los hosts .184 o .196, un intento de telnet simplemente se cuelga ...
# telnet 209.xxx.xxx.22 3306 Trying 209.xxx.xxx.22...
Si elimino la línea .251 (convirtiendo a .196 en la última regla agregada), el host .196 aún no puede conectarse a MySQL usando alias de IP (por lo que no es el orden de las reglas lo que está causando el comportamiento inconsistente). Lo sé, esta prueba en particular fue tonta ya que no debería importar en qué orden se agregan estas tres reglas, pero pensé que alguien podría preguntar.
Si vuelvo a la regla "pública", todos los hosts pueden conectarse al servidor MySQL utilizando las direcciones IP predeterminadas o con alias (en cualquiera de las subredes):
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
El servidor se ejecuta en un contenedor CentOS 5.4 OpenVZ / Proxmox (2.6.32-4-pve).
Y, en caso de que prefiera ver las reglas del problema en el contexto de la secuencia de comandos de iptables, aquí está (xxx = octeto enmascarado):
# Flush old rules, old custom tables
/sbin/iptables --flush
/sbin/iptables --delete-chain
# Set default policies for all three default chains
/sbin/iptables -P INPUT DROP
/sbin/iptables -P FORWARD DROP
/sbin/iptables -P OUTPUT ACCEPT
# Enable free use of loopback interfaces
/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A OUTPUT -o lo -j ACCEPT
# All TCP sessions should begin with SYN
/sbin/iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
# Accept inbound TCP packets (Do this *before* adding the 'blocked' chain)
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow the server's own IP to connect to itself
/sbin/iptables -A INPUT -i eth0 -s 208.xxx.xxx.178 -j ACCEPT
# Add the 'blocked' chain *after* we've accepted established/related connections
# so we remain efficient and only evaluate new/inbound connections
/sbin/iptables -N BLOCKED
/sbin/iptables -A INPUT -j BLOCKED
# Accept inbound ICMP messages
/sbin/iptables -A INPUT -p ICMP --icmp-type 8 -j ACCEPT
/sbin/iptables -A INPUT -p ICMP --icmp-type 11 -j ACCEPT
# ssh (private)
/sbin/iptables -A INPUT -p tcp --dport 22 -m state --state NEW -s xxx.xxx.xxx.xxx -j ACCEPT
# ftp (private)
/sbin/iptables -A INPUT -p tcp --dport 21 -m state --state NEW -s xxx.xxx.xxx.xxx -j ACCEPT
# www (public)
/sbin/iptables -A INPUT -p tcp --dport 80 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# smtp (public)
/sbin/iptables -A INPUT -p tcp --dport 25 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 2525 -j ACCEPT
# pop (public)
/sbin/iptables -A INPUT -p tcp --dport 110 -j ACCEPT
# mysql (private)
/sbin/iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.xxx.xxx.184 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.xxx.xxx.196 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.xxx.xxx.251 -j ACCEPT
¿Algunas ideas? Gracias por adelantado. :-)
.184 or .196 hosts
hosts del cliente también tienen direcciones IP adicionales en la otra subred? Si haces unatcpdump -qn port 3306
e intentas conectarte desde uno de esos sistemas, ¿qué ves? ¿Ves la dirección de origen que esperas?