Eu tenho um firewall iptables bastante simples em um servidor que fornece serviços MySQL, mas o iptables parece estar me dando resultados muito inconsistentes.
A política padrão no script é a seguinte:
iptables -P INPUT DROP
Posso então tornar o MySQL público com a seguinte regra:
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
Com essa regra, eu posso conectar ao MySQL de qualquer IP de origem para qualquer IP de destino no servidor sem problemas. No entanto, quando tento restringir o acesso a apenas três IPs, substituindo a linha acima pela seguinte, encontro um problema (xxx = oculto de máscara):
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
Depois que as regras acima estiverem em vigor, acontece o seguinte:
I pode se conectar ao servidor MySQL a partir dos 0,184, .196 e .251 anfitriões muito bem desde que estou conectando ao servidor MySQL usando seu endereço IP padrão ou um alias IP na mesma sub-rede que o endereço IP padrão.
Eu sou incapaz de se conectar ao MySQL usando aliases IP que são atribuídos ao servidor a partir de uma sub-rede diferente IP padrão do servidor quando eu venho das .184 ou .196 anfitriões, mas .251 funciona muito bem. Dos hosts .184 ou .196, uma tentativa de telnet simplesmente trava ...
# telnet 209.xxx.xxx.22 3306 Trying 209.xxx.xxx.22...
Se eu remover a linha .251 (tornando a .196 a última regra adicionada), o host .196 ainda não poderá se conectar ao MySQL usando aliases de IP (portanto, não é a ordem das regras que está causando o comportamento inconsistente). Eu sei, esse teste em particular foi bobo, pois não importa em que ordem essas três regras são adicionadas, mas achei que alguém poderia perguntar.
Se eu voltar para a regra "pública", todos os hosts poderão se conectar ao servidor MySQL usando os IPs padrão ou alias (na sub-rede):
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
O servidor está sendo executado em um contêiner do CentOS 5.4 OpenVZ / Proxmox (2.6.32-4-pve).
E, caso você prefira ver as regras do problema no contexto do script iptables, aqui está (xxx = oculto de máscara):
# 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
Alguma ideia? Desde já, obrigado. :-)
.184 or .196 hosts
hosts clientes também têm endereços IP adicionais na sua outra sub-rede? Se você faztcpdump -qn port 3306
e tenta se conectar a partir de um desses sistemas, o que vê? Você vê o endereço de origem que você espera?