iptables não pode NAT múltiplos endereços IP

1

Eu tenho um servidor com dois adaptadores de rede: eth0 e eth1. Este servidor está executando dois webservers https distintos: Um está escutando em eth0 (172.29.49.112:8443) O outro está escutando na eth1 (172.29.49.113: 4443)

Eu tenho regras NAT para iptables que redirecionam com sucesso a porta https padrão (443) para ambas as aplicações, mas as regras iptables só funcionam para ONE das regras de cada vez (qual delas ele ativa parece ser aleatório através de reinicializações).

Aqui estão as regras carregadas no tempo de inicialização do rc.local (sim, eu sei que executar minhas regras de firewall do rc.local não é recomendado):

#!/bin/sh -e

# setup port forwarding for gerrit and jenkins instances
su root -c "/sbin/iptables -t nat -A PREROUTING -i eth1 -d 172.29.49.113 -p tcp --dport 443 -j REDIRECT --to-port 4443"
su root -c "/sbin/iptables -t nat -A PREROUTING -i eth0 -d 172.29.49.112 -p tcp --dport 443 -j REDIRECT --to-port 8443"

# start gerrit (jenkins should auto-start as a service)
su gerrit2 -c "/home/gerrit2/gerrit/bin/gerrit.sh start"

exit 0

E aqui está a saída de "iptables -t nat -L -n -v":

Chain PREROUTING (policy ACCEPT 14458 packets, 1446K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    6   360 REDIRECT   tcp  --  eth0   *       0.0.0.0/0            172.29.49.112        tcp dpt:443 redir ports 8443
    0     0 REDIRECT   tcp  --  eth1   *       0.0.0.0/0            172.29.49.113        tcp dpt:443 redir ports 4443

Chain INPUT (policy ACCEPT 7436 packets, 874K bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 94 packets, 7050 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 94 packets, 7050 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Como você pode ver, não há outras regras sendo carregadas.

Quando eu executo apenas uma das duas regras, tudo funciona corretamente (para essa regra), mas mesmo que eu limpe as regras com "iptables -t nat -F" não consigo ativar o outro regra (a menos que eu reinicie - que parece limpar as coisas corretamente).

Por que estou tentando fazer isso? Eu quero que meus usuários possam acessar jenkins.servername.localnet e gerrit.servername.localnet em vez de jenkins.servername.localnet: 4443 etc. (Obviamente jenkins.servername.localnet resolve para 172.29.49.113 e .112 para gerrit).

Em um ponto, achei que os webservers jenkins / gerrit estavam ouvindo todos os IPs que causavam o problema. Mas ambos estão preparados para escutar apenas um único IP (jenkins - 172.29.49.113, gerrit - 172.29.49.112).

Provavelmente não é necessário, mas apenas no caso de ajuda - aqui está a saída do ifconfig:

eth0      Link encap:Ethernet  HWaddr 00:0c:29:99:52:e8  
          inet addr:172.29.49.112  Bcast:172.29.63.255  Mask:255.255.240.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:78588 errors:0 dropped:0 overruns:0 frame:0
          TX packets:27399 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:16180230 (15.4 MiB)  TX bytes:6329245 (6.0 MiB)

eth1      Link encap:Ethernet  HWaddr 00:0c:29:99:52:f2  
          inet addr:172.29.49.113  Bcast:172.29.63.255  Mask:255.255.240.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:45058 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:3496805 (3.3 MiB)  TX bytes:378 (378.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:1090 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1090 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:268078 (261.7 KiB)  TX bytes:268078 (261.7 KiB)

Isso tem sido incrivelmente frustrante, já que ALMOST funciona.

Estou executando o Debian Wheezy, Gerrit 2.10 e Jenkins 1.604.

Coisas que eu já vi: CAP_NET_BIND_SERVICE não é uma solução fácil porque gerrit é inicializado através de um script. O authbind é uma ferramenta que provavelmente fará o que eu quero, mas prefiro evitar mais uma camada.

    
por Kirin 02.04.2015 / 06:32

1 resposta

1

Tero Kilkanen apontou-me na direção certa sobre isso, embora tenha demorado um pouco para eu elaborar a sintaxe. Parece que o iptables estava confuso em relação a qual IP os dados recém-redirecionados deveriam ir.

O DNAT especifica a porta de destino AND do IP de destino, para que funcione corretamente agora. Os comandos finais que usei foram os seguintes:

su root -c "/sbin/iptables -t nat -A PREROUTING -p tcp -m tcp -d 172.29.49.113 --dport 443 -j DNAT --to 172.29.49.113:4443"
su root -c "/sbin/iptables -t nat -A PREROUTING -p tcp -m tcp -d 172.29.49.112 --dport 443 -j DNAT --to 172.29.49.112:8443"

Nota para wurtel e user1036745: Configurar a entrada nic com um curinga não faz diferença. (especialmente porque por padrão o iptables define uma entrada curinga para a entrada nic mesmo assim, então não é necessário especificar "eth +") Mas obrigado por tomar o tempo para responder de qualquer maneira.

    
por 08.04.2015 / 07:48