O GNU/Linux é um sistema operacional tão poderoso que nos permite interferir no tráfego da interface de rede de forma simplesmente mágica através de ferramentas de rede como iptables.
O iptables é muito conhecido na implementação de firewalls no Linux. Todavia, ele oferece muitos outros recursos, e dentre eles o redirecionamento de pacotes.
Para demonstrar esse potencial, ilustraremos duas situações interessantes:
- redirecionar a porta TCP 81 para a 80 na mesma máquina
- redirecionar a porta TCP 5436 local para a 5432 de máquina em outra rede
Serão considerados 10.220.10.62/16 como endereço IP local e 10.1.2.71/16 como endereço IP remoto. Atenção: a maioria das instruções citadas neste artigo deve ser executada pelo "root" ou outro usuário com poderes de super-vaca!
Antes de qualquer coisa, devemos nos certificar de que as regras existentes do NAT no iptables tenham sido reinicializadas. Para limpar as tabelas e cadeias (chains) e zerar os respectivos contadores, executamos as instruções a seguir:
iptables -t nat -F iptables -t nat -X iptables -t nat -Z
O redirecionamento de portas locais pode ser feito com o alvo (target) REDIRECT.
O REDIRECT redireciona o pacote para a própria máquina alterando o IP de destino para o endereço primário da interface de entrada (pacotes gerados localmente são mapeados para o endereço 127.0.0.1).
Assim, afim de redirecionar a porta TCP 81 para a 80 na mesma máquina, executamos:
iptables -t nat -A PREROUTING -p tcp --dport 81 -j REDIRECT --to-port 80
É interessante analisar se o tráfego está chegando à essa porta 81. Para isso, podemos usar o alvo LOG, o qual provocará a inclusão de uma entrada no /var/log/syslog a cada requisição.
O alvo LOG liga o registro dos pacotes que se encaixam em determinado critério pelo log do kernel (o qual pode ser lido com dmesg ou syslogd). É extremamente útil para ser usado em conjunto com regras que descartam o pacote (i.e., alvos DROP ou REJECT).
Para o nosso caso, basta executar a instrução a seguir para habilitar o log:
iptables -t nat -A PREROUTING -p tcp --dport 81 -j LOG --log-prefix "[Porta 81] "
Executamos o comando abaixo para verificar as regras aplicadas à tabela NAT do iptables:
iptables -t nat -L -n -v
Para testar se o redirecionamento está acontecendo como esperado, abra um novo terminal e execute a instrução a seguir para acompanhar no log do Linux as requisições que chegam à porta 81:
tail -f /var/log/syslog | grep 'Porta 81'
Para este caso, o teste deve ser disparado de uma máquina externa, digamos, do endereço 10.220.8.250/16. Podemos usar o telnet executando essa instrução:
telnet 10.220.10.62 81
Como se trata de um serviço Web, outra opção é usar o próprio protocolo HTTP, através da ferramenta curl. Eis um exemplo:
curl -v http://10.220.10.62:81/
Fácil, não?! Vejamos agora a segunda situação, um pouco mais complicada.
O redirecionamento de IPs precisa ser habilitado no kernel do Linux. Para fazer isso, basta executar esse comando:
echo 1 > /proc/sys/net/ipv4/ip_forward
Para garantir que esse parâmetro do kernel esteja ligado durante uma possível reinicialização da máquina, uma sugestão é adicionar tal configuração no sysctl.conf:
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
Voltando ao iptables, usaremos um outro alvo, o DNAT.
O DNAT determina que o endereço de destino deve ser modificado (assim como todos os demais pacotes da respectiva conexão) e as regras devem parar de ser examinadas.
Assim, para redirecionar a porta 5436 local (10.220.10.62) para a 5432 de outra máquina (10.1.2.71), executamos:
iptables -t nat -A PREROUTING -s 10.220.0.0/16 -p tcp --dport 5436 -j DNAT --to-destination 10.1.2.71:5432
A opção "-s" restringe a origem dos pacotes à subrede da máquina local. Como estamos redirecionando o pacote para uma máquina em outra subrede, precisamos usar o alvo MASQUERADE.
iptables -t nat -A POSTROUTING -j MASQUERADE
Da mesma forma que no caso anterior, podemos ligar o log do Linux para capturar as requisições nessa porta TCP:
iptables -t nat -A PREROUTING -p tcp --dport 5436 -j LOG --log-prefix "[Porta 5436] "
E em seguida acompanhar as mudanças através desse comando:
tail -f /var/log/syslog | grep 'Porta 5436'
Para testar essa nova regra, abra um terminal em outra máquina na mesma subrede e use o telnet:
telnet 10.220.10.62 5436
Como trata-se de um serviço do SGBD PostgreSQL, podemos testar definitivamente usando o cliente psql:
psql -h 10.220.10.62 -p 5436 -U usuario banco
Uma alternativa para acompanhar o tráfego de rede nessas regras de NAT no iptables é a ferramenta tcpdump. Através dela podemos visualizar os IPs com setas mostrando a direção do tráfego, e com isso verificar se as requisições estão chegando e se as respectivas respostas estão voltando.
Por exemplo, para analisar o tráfego que chega à porta 5436 local, podemos usar:
tcpdump -n -i eth0 port 5436
Já para verificar as requisições entre a máquina local e a máquina remota, uma opção seria:
tcpdump -n -i eth0 host 10.1.2.71
Muito simples e prático!