Agora já sabemos como selecionar os pacotes que queremos alterar. Para completar nossa regra, precisamos dizer ao kernel exatamente o que queremos fazer com os pacotes.
Você quer fazer Source NAT; mudar o endereço origem das conexões para algo diferente. Isto é feito na cadeia POSTROUTING, logo antes do pacote ser despachado. Este é um detalhe importante, uma vez que significa que qualquer coisa no próprio computador Linux (roteamento, filtro de pacotes) verá o pacote inalterado. Isto também significa que a opção `-o' (interface de saída) pode ser usada.
O Source NAT é especificado usando `-j SNAT', e a opção `--to-source' especifica um endereço IP, um intervalo de endereços IP, e uma porta ou intervalo de portas opcionais (somente para os protocolos TCP e UDP).
## Change source addresses to 1.2.3.4.
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4
## Change source addresses to 1.2.3.4, 1.2.3.5 or 1.2.3.6
## Change source addresses to 1.2.3.4, ports 1-1024
# iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023
Existe uma forma especializada de Source NAT chamada mascaramento: deve ser usada apenas para endereços IP dinâmicos, como linhas discadas padrão (para endereços Ip estáticos, use o SNAT acima).
Você não precisa colocar o endereço de origem explicitamente com o mascaramento: ele irá usar o endereço de origem da interface do qual o pacote está vindo. Mas, mais importente, se o link cair, a conexão (que é perdida) é esquecida, o que significa menos problemas quando a conexão retorna com um novo endereço IP.
## Masquerade everything out ppp0.
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
Isto é feito na cadeia PREROUTING, assim que o pacote chega. Isto significa que tudo o mais no seu computador Linux (roteamento, filtro de pacotes) irá ver o pacote indo para seu destino `real'. Isto também significa que a opção `-i' (interface de entrada) pode ser usada.
O Destination NAT é especificado usando `-j DNAT', e a opção `--to-destination' especifica um endereço IP, um intervalo de endereços IP e uma porta ou intervalo de portas opcionais (somente para protocolos TCP e UDP).
## Change destination addresses to 5.6.7.8
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8
## Change destination addresses to 5.6.7.8, 5.6.7.9 or 5.6.7.10.
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8-5.6.7.10
## Change destination addresses of web traffic to 5.6.7.8, port 8080.
# iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 \
-j DNAT --to 5.6.7.8:8080
Existe uma forma especializada de Destination NAT chamada redireção: é uma conveniência simples que é exatamente equivalente a fazer DNAT ao endereço da interface de entrada.
## Send incoming port-80 web traffic to our squid (transparent) proxy
# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 \
-j REDIRECT --to-port 3128
Note que o Squid precisa ser configurado para saber que é um proxy transparente!
Existem algumas sutilezas em relação ao NAT que a maioria das pessoas não precisa tratar. Elas estão documentadas aqui para os curiosos.
Se for dado um intervalo de endereços IP, o endereço IP a usar é escolhido baseado no endereço IP menos usado para conexões que a máquina conhece. Com isto se consegue um balanço de carga primitivo.
Você pode usar o destino `-j ACCEPT' para permitir uma conexão passar sem nenhum NAT acontecendo.
O comportamento padrão é alterar a conexão o mínimo possível, dentro das limitações da regra dada pelo usuário. Isto significa que não serão feitos remapeamentos de portas a menos que seja necessário.
Mesmo quando não é requisitado um NAT para uma conexão, a tradução porta de origem pode ocorrer implicitamente, se outra conexão tiver sido mapeada sobre a nova. Considere o caso de mascaramento, que é bastante comum:
Quando este mapeamento de porta de origem implícito ocorrer, as portas são dividias em três classes:
Uma porta nunca será mapeada implicitamente para uma classe diferente.
Se não hovuer uma forma de mapear de forma unívoca uma conexão solicitada por um usuário, ela será descartada. Isto também aplica-se a pacotes que não podem ser classificados como parte de nenhuma conexão, por que são malformados, ou o computador está sem memória livre, etc.
Você pode ter regras NAT que mapeiam pacotes no mesmo intervalo, o código do NAT é esperto o suficiente para evitar colisões. Portanto, ter duas regras que mapeiam os endereços de origem 192.168.1.1 e 192.168.1.2 para 1.2.3.4 está OK.
Além disto, você pode fazer mapeamento em endereços IP reais e usados, desde que estes endereços passem pelo computador que faz o mapeamento também. Assim, se você tem um endereço de rede atribuído (1.2.3.0/24), mas tem uma rede interna usando aqueles endereços e uma usando os Endereços de Internet Privada 192.168.1.0/24, você pode simplesmente fazer o NAT ods endereços de origem 192.168.1.0/24 para a rede 1.2.3.0, sem receio de colisões:
# iptables t nat -A POSTROUTING -s 192.158.1.0/24 -o eth1 \
-j SNAT --to 1.2.3.0/24
A mesma lógica aplica-se a endereços usados pela própria máquina que faz o NAT: é assim que o mascaramento funciona (compartilhando o endereço da interface entre pacotes mascarados e pacotes `reais' vindo da própria máquina).
Mais, você pode mapear os mesmos pacotse em vários destinos diferentes, e eles serão compartilhados. Por exemplo, se você não quer mapear qualquer coisa sobre 1.2.3.5, pode fazer:
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 \
-j SNAT --to 1.2.3.0-1.2.3.4 --to 1.2.3.6-1.2.3.254
O código do NAT permite que você insira regras DNAT na cadeia OUTPUT, mas isto não tem suporte completo no 2.4 (pode ser feito, mas exige uma nova opção de configuração, alguns tesets, e alguma codificiação, de forma que, a menos que alguém contrate Rusty para escrever isto, eu não espero isto tão cedo).
A limitação atual é que você somente opde alterar o destino para a máquina local (por exemplo, `-j DNAT --to 127.0.0.1'), e não para qualquer outra máquina, caso contrário as respostas não serão traduzidas corretamente.