iptables NAT e rede de máquinas virtuais

1

Atualmente, estou usando o seguinte script para fazer com que várias máquinas virtuais acessem a Internet e permitam que algumas portas sejam encaminhadas por meio do NAT do host dentro de uma rede somente de host.

host_interface=eth0 # name of host machine interface connected to the Internet
vnet_interface=vboxnet0 # name of host machine's local network interface
host_ip[0]=... # array contains external IP addresses for every guest
guest_ip[0]=... # array contains internal IP addresses for every guest
guest_ports[0]=21,22,80,443 # array of port lists for every guest

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD ACCEPT
iptables -F FORWARD
iptables -t nat -F

echo "1" > /proc/sys/net/ipv4/ip_forward

for i in ${!host_ip[*]}
do
        iptables -t nat -A PREROUTING -i $host_interface -d ${host_ip[$i]} -p tcp -m multiport ! --dports "${guest_ports[$i]}" -j ACCEPT
        iptables -t nat -A PREROUTING -i $host_interface -d ${host_ip[$i]} -j DNAT -p tcp -m multiport --dports "${guest_ports[$i]}" --to-destination ${guest_ip[$i]}
done

# forward all packets from already established connections
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

for i in ${!guest_ip[*]}
do
        # allow forwarding new connections from host to guest
        iptables -A FORWARD -i $host_interface -o $vnet_interface -d ${guest_ip[$i]} -m state --state NEW -j ACCEPT

        # allow forwarding new connections from guest to host
        iptables -A FORWARD -i $vnet_interface -o $host_interface -s ${guest_ip[$i]} -m state --state NEW -j ACCEPT

        iptables -t nat -A POSTROUTING -o $host_interface -s ${guest_ip[$i]} -j SNAT --to-source ${host_ip[$i]}
done

A única coisa que falta aqui é a capacidade de acessar qualquer máquina convidada pelo seu endereço IP EXTERNO (dentro da rede local, é claro). Estou recebendo a mensagem "Conexão recusada" toda vez que tento conectar-me à porta aberta da mesma máquina ou a outro convidado (mas é possível conectar-me ao host de qualquer convidado). IPs internos (privados) funcionam bem, sou capaz de me conectar a qualquer convidado e host de qualquer lugar dentro da rede local. Tentei adicionar algo como

iptables -t nat -A PREROUTING -i $vnet_interface -d ${host_ip[$i]} -j DNAT --to-destination ${guest_ip[$i]}

mas parece que é insuficiente.

    
por Lux In Tenebris 01.11.2010 / 00:23

2 respostas

2

Se eu entendi corretamente, seu problema é que os convidados da VM não podem acessar a si mesmos ou aos outros convidados pelos endereços IP externos. O problema que você está tendo é claramente ilustrado em esta página (imagine que o roteador é o host da VM, e o servidor da Web é um de seus convidados da VM). Você precisa configurar "Hairpin NAT".

A solução, para citar a mesma página, é que

an additional NAT rule needs to be introduced on the [VM host] to enforce that all reply traffic flows through the [VM host], despite the client and server being on the same subnet.

No seu caso, essas regras podem ser assim:

iptables -t nat -A PREROUTING -s $host_only_network -d ${guest_ip[$i]} -o $vnet_interface -p tcp -m multiport --dports "${guest_ports[$i]}" -j MASQUERADE

onde:

host_only_network=192.168.1.0/24  # replace with whatever applies to your guest network

Deixarei isso para você depurar completamente isso, já que configurações complicadas de NAT tendem a me causar dores de cabeça sérias.

    
por 01.11.2010 / 06:24
0

configurar sua política de entrada para aceitar por padrão é uma idéia muito ruim, você deve usar

iptables -P INPUT DROP

também o encaminhamento por padrão é ruim. Você sempre pode definir uma regra de permissão para todo o tráfego de interfaces específicas para sempre ser permitida na entrada ou no encaminhamento, o que é OK.

    
por 17.07.2012 / 11:23