iptables não permite conexões mysql para ips alias?

10

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

Curtis
fonte
1
Os .184 or .196 hostshosts clientes também têm endereços IP adicionais na sua outra sub-rede? Se você faz tcpdump -qn port 3306e tenta se conectar a partir de um desses sistemas, o que vê? Você vê o endereço de origem que você espera?
precisa
1
Obrigado, Zordache! Isso resolveu. O host .251 não tinha nenhum IP atribuído da outra sub-rede. Os outros dois hosts fazem (.184 e .196) e, portanto, quando se conectam a um IP na outra sub-rede, o IP de origem nesses hosts alterna para um IP na mesma sub-rede. Eu pensava que o IP de saída / origem seria sempre o padrão atribuído. Mas, tcpdump mostra claramente que o IP de origem muda para a sub-rede 209.xxx.xxx.xxx sempre que se conectar a um IP nessa mesma sub-rede. (No entanto, foi necessário executar o tcpdump a partir do host físico do Proxmox.) Você é um gênio. Obrigado!
Curtis

Respostas:

8

Os hosts .184 ou .196 hosts também possuem endereços IP adicionais na outra sub-rede?

Se você faz tcpdump -qn port 3306e tenta se conectar a partir de um desses sistemas, o que vê? Você vê o endereço de origem que você espera? Provavelmente, esse é um problema de roteamento simples.

Quando um sistema está tomando a decisão de rota, ele consulta a tabela de rotas. As tabelas de rotas são uma lista sempre consultada em uma ordem específica. As rotas de link para redes locais são quase sempre as rotas mais preferidas e serão usadas antes de uma rota que use um gateway (roteador). O gateway padrão é sempre a rota usada quando nenhuma outra rota se aplica. Se uma rota srcdefinida por uma determinada rota , esse endereço será preferido e provavelmente usado quando essa rota estiver sendo usada.

10.2.13.0/24 dev eth1  proto kernel  scope link  src 10.2.13.1 
10.2.4.0/23 dev eth0  proto kernel  scope link  src 10.2.4.245 
default via 10.2.4.1 dev eth0 

Portanto, dado este exemplo de tabela de rotas para um sistema de hospedagem múltipla, tudo o que for destinado 10.2.13.0/24virá 10.2.13.1e tudo o que for destinado 10.2.4.0/23será 10.2.4.245.

Zoredache
fonte