iptables não permitindo conexões mysql para aliased ips?

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

Eu posso tornar o MySQL público com a seguinte regra:

iptables -A INPUT -p tcp --dport 3306 -j ACCEPT

Com essa regra, posso conectar-me ao MySQL de qualquer IP de origem para qualquer IP de destino no servidor sem nenhum problema. No entanto, quando tento restringir o acesso a apenas três IPs, substituindo a linha acima pela seguinte, me deparo com problemas (xxx = mascaramento de octeto):

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 

Quando as regras acima estiverem em vigor, acontece o seguinte:

  • Eu posso me conectar ao servidor MySQL dos hosts .184, .196 e .251 bem enquanto estou me conectando ao servidor MySQL usando seu endereço IP padrão ou um alias de IP na mesma sub-rede que o endereço IP padrão.

  • Eu sou incapaz de me conectar ao MySQL usando aliases de IP que são atribuídos ao servidor de uma sub-rede diferente do IP padrão do servidor quando estou vindo dos hosts .184 ou .196, 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 (fazendo com que .196 a última regra seja 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 inconsistente comportamento). Eu sei, este teste em particular foi bobo, já que não deveria importar em que ordem essas três regras são adicionadas, mas eu imaginei que alguém poderia perguntar.

  • Se eu voltar para a regra "pública", todos os hosts podem se conectar ao servidor MySQL usando os IPs padrão ou com alias (em qualquer 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 = octeto mascarado):

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

    
por Curtis 26.06.2012 / 01:06

1 resposta

8

Os hosts clientes dos hosts .184 ou .196 também têm endereços IP adicionais em sua outra sub-rede?

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

Quando um sistema está tomando a decisão de rota, ele consulta a tabela de rotas. 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 será aplicada. Se uma rota de uma determinada rota tiver um src definido, 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 rota para um sistema multi-homed, qualquer coisa destinada a 10.2.13.0/24 virá de 10.2.13.1 , e qualquer coisa destinada a 10.2.4.0/23 virá de 10.2.4.245 .

    
por 26.06.2012 / 02:27