[Dica] Problema Comum no Redirecionando com Iptables (NAT & SNAT) - Parte 1/2
por
em 27-11-2008 às 12:27 (79941 Visualizações)
Recentemente eu tenho visto muitos posts no Forum de proxy/nat/firewall de pessoas que estão passando pela mesma dificuldade ao tentar realizar um redirecionamento para um servidor. Esse problema é muito comum porque muitas vezes agente não pensa no funcionamento detalhado do roteamento nem do que pode ocorrer ao alterar o destino de um pacote com o DNAT. Não entrarei muito a fundo no lógica de como realizar o redirecionamento, deixo isso pra outro post, mas aqui mostrarei como resolver o problema utilizando algumas regras de iptables.
Muitas pessoas quando projetam (ou não) a rede de uma empresa colocam os servidores web, ftp e arquivos (entre outros) na mesma rede dos clientes. Seja por não saber como criar uma rede segmentada, por não querer gastar dinheiro com mais um switch (o que não é exatamente necessário) e placa de rede ou por simplesmente achar que assim é mais cômodo. A verdade é que esse tipo de ambiente não só dificulta, e muito, a implementação de algumas funcionalidades mas também imposibilita a segmentação do trafego e a realização de bloqueios, implicando em brexas de segurança.
Nessa primeira parte vamos trabalhar com um workaround. Na segunda parte dessa série de post irei mostrar um ambiente "ideal".
Cenário 1
Primeiro temos que entender o cenário utilizado. Como dito anteriormente, muitas pessoas colocam um servidor web dentro da rede interna. Nessa caso trataremos a rede interna como sendo a rede 192.168.1.0/24. Mais especificamente, nesse exemplo, nossos hosts da rede interna são o 192.168.1.1 a 192.168.1.9 e nosso servidor web é o 192.168.1.10.
O que muitas pessoas tentam fazer é redirecionar um acesso ao gateway 192.168.1.254 para o servidor web 192.168.1.10. Como os estes estão na mesma rede lógica ocorre um problema curioso. Fiz essa animação em GIF para que as pessoas possam visualizar melhor o que ocorre:
Aposto que ninguém entendeu!! Vamos explicar:
Passo 1
O host deseja se comunicar com o domínio (digamos www.dominio.com.br). O host realiza a consulta DNS e descobri que www.dominio.com.br está vinculado ao IP 192.168.1.254. Com isso o host preenche os campos do pacote e o envia da seguinte forma:
IP de Origem: 192.168.1.1
IP de Destino: 192.168.1.254
Passo 2
O firewall (192.168.1.254) recebe o pacote do host 192.168.1.1 e consulta suas regras de iptables. Lá ele encontra a seguinte regra:
iptables -t nat -A PREROUTING -s 192.168.1.0/24 -i eth0 -d 192.168.1.254 -p tcp --dport 80 -j DNAT --to 192.168.1.10
Como o tráfego bate com a regra (IP de origem, interface de entrada, IP de destino e porta de destino) o firewall faz o que é mandado DNAT para 192.168.1.10, na animação ele pinta o pacote de azul. Para os que não sabem, o DNAT altera o IP de destino no pacote, ficando da seguinte forma:
IP de Origem: 192.168.1.1
IP de Destino: 192.168.1.10 (DNAT)
Enquanto isso o host 192.168.1.1 tá pensando: "Cade a resposta desse 192.168.1.254??"
Passo 3
O servidor web (192.168.1.10) recebe o pacote do host 192.168.1.1 (que na verdade foi encaminhado pelo Firewall) e processa a requisição HTTP. Ao terminar o procesamento ele devolve o pacote. Mas pra quem que ele devolve?? Pra Origem. E quem é a origem? É só consultar o pacote! De acordo com o que vimos, a origem é 192.168.1.1 (veja o fim do passo 2)! Então o servidor WEB, inocentemente envia o pacote diretamente para o host 192.168.1.1 sem que o DNAT fosse desfeito!
Vamos dar uma olhada no pacote de resposta:
IP de Origem: 192.168.1.10
IP de Destino: 192.168.1.1
Agora o desastre final! O host 192.168.1.1 recebe o pacote do servidor web (192.168.1.10) sendo que ele esperava uma resposta do firewall 192.168.1.254. Ao ver essa resposta HTTP do host pensa: "Mas que p***a é essa?! Eu não pedi nada pra esse cara! Ele tá doido?!". Ao ver que a resposta está direcionada a ele mas ele não requisitou nada daquilo ele simplesmente descarta o pacote.
Imagine que você ta em casa e pediu um sanduiche do Bobs mas chega na sua casa o entregador do McDonalds e toca seu interfone, você receberia o sanduíche?!
Enquanto isso o host 192.168.1.1 vai ficar esperando a resposta do 192.168.1.254 que nunca irá chegar. Depois de um timeout ele tentará novamente a conexão e o processo se repetirá.
Pois é! Então esse é o problema do redirecionamento com DNAT dentro de um mesma rede. Agora como contornar...
Cenário 2
Inicialmente esse cenário é exatamente igual ao anterior...
http://img355.imageshack.us/img355/2932/cenario2zu1.gifhttp://under-linux.org/wiki/images/d/d7/Cenario2zu1.gif
Passo 1
O host deseja se comunicar com o domínio (digamos www.dominio.com.br). O host realiza a consulta DNS e descobri que www.dominio.com.br está vinculado ao IP 192.168.1.254. Com isso o host preenche os campos do pacote e o envia da seguinte forma:
IP de Origem: 192.168.1.1
IP de Destino: 192.168.1.254
Passo 2
O firewall (192.168.1.254) recebe o pacote do host 192.168.1.1 e consulta suas regras de iptables. Lá ele encontra as seguintes regras:
iptables -t nat -A PREROUTING -s 192.168.1.0/24 -i eth0 -d 192.168.1.254 -p tcp --dport 80 -j DNAT --to 192.168.1.10
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -d 192.168.1.254 -p tcp --dport 80 -j SNAT --to 192.168.1.254
Como o tráfego bate com as regra (IP de origem, interface de entrada, IP de destino e porta de destino) o firewall faz o que é mandado DNAT para 192.168.1.10 e SNAT para 192.168.1.254, na animação ele pinta o pacote de azul e verde, uma vez que foram realizadas duas alterações no pacote. Para os que não sabem, o SNAT altera o IP de origem no pacote fazendo parecer que a conexão foi iniciada por outro host. Fica da seguinte forma:
IP de Origem: 192.168.1.254 (SNAT)
IP de Destino: 192.168.1.10 (DNAT)
Passo 3
O servidor web (192.168.1.10) recebe o pacote do host 192.168.1.254 (que na verdade foi encaminhado veio do 192.168.1.1) e processa a requisição HTTP. Ao terminar o processamento ele devolve o pacote pra Origem. E quem é a origem? consultando o pacote vemos que temos que devolver para 192.168.1.254 da seguinte forma:
IP de Origem: 192.168.1.10
IP de Destino: 192.168.1.254
Passo 4
O firewall (192.168.1.254) recebe o pacote do servidor web 192.168.1.10. Como ele possui uma tabela de NAT's realizados ele sabe que esse pacote ele precisa ser alterado. Dessa forma ele nem consulta a tabela de regras NAT do iptables, ele simplesmente restaura a origem/destino do pacote e encaminha. O pacote vai ficar da seguinte forma:
IP de Origem: 192.168.1.254
IP de Destino: 192.168.1.1
O host 192.168.1.1 recebe o pacote do firewall 192.168.1.254. Dessa vez ele recebe o que esperava e a conexão é fechada.
Bem, esse é o problema e o workaround. Com certeza muita gente vai criticar essas regras porque existem diversas formas de se fazer isso. Eu mesmo pensei em pelo menos 3, mas achei essa a mais simples para o entendimento de todos.
Assim que possível estarei postando a segunda parte dessa dica que irá apresentar a solução ideal para um ambiente simples com servidores como esse. Assim que eu tiver ânimo de criar outros GIFs desse...
Enquanto isso, dúvidas, reclamações, sugestões, críticas, agradecimentos ou xingamentos... Utilizem os comentários!!
Até mais...
Comentários
+ Enviar Comentário