Mais um mistério do Port Forwarding: Um cache no meio do caminho.
“Houston, we have another problem!”
Lembra daquele mistério “fantasmagórico” envolvendo o port forwarding quando acessado da rede interna? Pois bem, aquele mesmo cliente andou navegando por aí e no meio do caminho acabou caindo no artigo do Rodrigo Ribeiro que fala do Lusca Cache + Thunder Cache. De imediato, seu telefone toca e vem a solicitação para instalá-lo no servidor que hospeda o firewall.
Após tudo instalado, todo mundo navegando, relatório de economia sendo gerado e etc, você recebe outra ligação: Quando alguém da rede interna tenta acessar o servidor web da empresa (é, aquele do outro post), simplesmente não vai.
Causa:
Mais uma vez, a causa deste mistério pode ser descoberta analisando o caminho que o pacote percorre fora e dentro do servidor.
Veja a figura abaixo:
Figura 1
Percebam que a conexão é feita diretamente no proxy, porta 8888 neste caso, pois o browser está configurado para utilizar proxy ao invés de fazer a conexão direta. O browser faz a solicitação da página e o processo do proxy irá resolver o nome do site se necessário e, após isto, abrir conexão para o IP. Neste momento o proxy retorna que não conseguiu conectar no site. A mensagem pode variar de acordo com a política de firewall adotada.
Vamos analisar novamente o diagrama da travessia dos pacotes pelas tabelas e chains do ipfilter:

Figura 2
Temos um port forwarding que está sendo feito na tabela chain prerouting da tabela nat, mas este nosso pacote não passa por lá. Temos que observar que ele vem de um processo local, e só passa pela chain prerouting os pacotes que vêm da rede externa ao host. Logo, quando o pacote chega ao ip real do servidor web (que é um ip local), ele não é redirecionado e o proxy estará tentando conectar no próprio host.
Resolução:
Vejo duas soluções que podem ser utilizadas. A primeira, bem simples, é adicionar o ip real na lista de exclusão do browser. No caso de utilizar-se browsers ou aplicações que não possuam esta opção, aí não terá jeito.
A segunda, basicamente, resolvemos o problema repetindo o dnat feito na chain prerouting na chain output. Desta forma, os pacotes locais também serão redirecionados para o servidor web que está na rede interna. Veja o exemplo:
iptables -p tcp -t nat -A OUTPUT -d 200.254.225.31 –dport 80 -j DNAT –to-destination 172.15.25.3:80
Para incrementar mais esta solução (que eu acho até mais elegante e menos despendiosa), dei uma analisada com mais calma no manual do iptables, e verifiquei a existência do módulo owner, que identifica os pacotes vindos de um processo que tenha um uid e gid específicos. Com isto, podemos restringir a nossa solução apenas aos pacotes gerados pelo processo do Proxy. Podemos modificar nossa regra anterior para:
iptables -p tcp -t nat -A OUTPUT -d 200.254.225.31 –dport 80 -m owner –owner-uid squid –owner-gid squid -j DNAT –to-destination 172.15.25.3:80
É importante observar que no manual do iptables indica a possibilidade de se utilizar os parâmetros –pid-owner, –sid-owner e –cmd-owner. Porém, há também a seguinte observação: “NOTE: pid, sid and command matching are broken on SMP”. Por este motivo, não utilizei nenhuma destas opções. Para o nosso caso, o ideal mesmo seria o –cmd-owner, mas ele foi removido a partir do kernel 2.6.15. É uma pena!
Conclusão
Uma solução foi formada pela análise do cenário e estruturas internas do servidor relacionadas com filtro de pacotes (ipfilter), bem como da ferramenta utilizada para gerar as regras, no caso o iptables. Tenha sempre em mente que conhecer o ambiente entendendo como ele funciona é o que construirá seu sucesso ou fracasso em uma situação.
“Conheça a si e ao inimigo, e não temerás 100 batalhas” – A arte da guerra, Sun Tzu
Artigo também publicado em Zé Bob na Itália



Figura 4
Últimos comentários