Este é um assunto que, a princípio, é simples, mas pode causar muita confusão. Apesar da teoria parecer “simples” e de fácil compreensão, existem particularidades e pegadinhas que influenciarão diretamente na eficiência da solução adotada. Sem o entendimento correto, suas regras serão facilmente burladas e seu ambiente estará sujeito a falhas de conexão, devido a má utilização dos recursos.

proxytransparente

A imagem acima foi extraída do blog obtudo.blogspot.com.br, que explica conceitos básicos sobre servidores proxy.

Não demonstrarei exemplos avançados de configuração, pois o meu objetivo, neste instante, é auxiliar no entendimento dos principais conceitos e como aplicá-los da melhor maneira. É possível, por exemplo, adotar uma configuração de proxy manual/tradicional e transparente ao mesmo tempo e ainda simular um controle totalmente transparente ao incluir uma configuração prevendo a detecção automática de proxy (WPAD) – formato concebido originalmente pela Netscape em 1996.

O ideal é trabalhar com a combinação adequada destes recursos.

Partindo do começo…

Em termos de configuração, o entendimento comum de proxy transparente HTTP consiste, basicamente, em interceptar o tráfego HTTP e redirecionar à um servidor proxy compatível, de forma automática e “obrigatória”. Mas, a complexidade envolvida é um pouco maior do que aparenta e demonstrarei as razões.

A princípio, a implementação é relativamente simples. Em soluções Linux, basta redirecionar requisições TCP/80 para uma porta HTTP específica do Squid (configurada para trabalhar em modo acelerado/transparente). Este redirecionamento pode ser feito por meio de regras de firewall (iptables), através dos alvos DNAT ou REDIRECT. Para simplificar, em redes de pequeno e médio porte, é comum configurar o firewall/proxy como gateway padrão.

Em roteadores Cisco também é possível interceptar o tráfego através do protocolo WCCP2. É um método considerado bastante eficiente, porém mais trabalhoso e menos implementado. Até hoje não implementei nenhuma solução baseada neste protocolo“.

Até aqui não há mistério e é fácil encontrar “receita de bolo” ensinando como fazer. No entanto, existem particularidades importantes que são pouco documentadas e você precisa dominar.

Ao optar por este tipo de configuração, o servidor proxy responderá as requisições de web “se passando” pelo “servidor real” de destino. Na prática, para viabilizar este acesso, também ocorre um ip-spoofing antes de entregar a resposta aos clientes. Ou seja, o cliente solicita conexão à um endereço remoto, o Squid intercepta, processa e forja a resposta. Mas, não é um simples Spoof – o Squid intermedeia a conexão entre cliente e servidor real. Obviamente, a conexão com o endereço remoto é estabelecida pelo proxy. Porém, na visão do cliente, a conexão estará estabelecida com o endereço remoto, não com o servidor proxy. Tudo isto acontece automaticamente e sem intervenção manual. Daí o nome proxy transparente.

Vale ressaltar que o tratamento, descrito acima, está presente apenas no socket configurado para trabalhar em modo transparente (ou acelerado) e utilizará informações do cabeçalho HTTP para identificar o destino de conexão real. Logo, os clientes não poderão definir tal porta em “configuração manual de proxy“. Esta compreensão é importante porque, caso você inclua a possibilidade de “detecção automática (WPAD)”, deverá configurar e selecionar outro socket sem este recurso ativo.

Também é possível forjar os pacotes encaminhados aos servidores reais (destino), habilitando um recurso conhecido como TPROXY (referenciado, algumas vezes, como full transparent proxy). Com o TPROXY ativo, ambos os sentidos de conexão são forjados, mas não é uma implementação muito comum. É útil quando o administrador deseja identificar, no fluxo entre proxy e “servidor real”, qual estação da rede é responsável por determinado acesso (para aplicar limites de conexão ou QoS, por exemplo) ou evitar que todas as requisições de Internet sejam feitas a partir de uma única origem (IP do proxy).

Confiram um exemplo básico (sem TPROXY):

Rede 10.0.0.0/24, com interface WAN eth1 e LAN eth0

1. Configuração do Squid (/etc/squid/squid.conf)

# Proxy manual: Socket para conexões destinadas manualmente ao proxy (C/S clássico)
http_port 8080

# Proxy transparente: Socket para conexões redirecionadas ao proxy
http_port 3128 intercept

2. Configuração do firewall/proxy (gateway padrão da rede)

iptables -t nat -A POSTROUTING -o eth1 -s 10.0.0.0/24 -j MASQUERADE
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128
iptables -A INPUT -i eth0 -s 10.0.0.0/8 -m multiport -p tcp --dport 3128,8080 -j ACCEPT

À primeira vista, é simples. Todas as requisições HTTP (porta 80) serão redirecionadas ao servidor Squid (porta 3128), permitindo ainda a utilização manual (porta 8080). Porém, o tratamento para requisições HTTPS (porta 443) é mais complexo e merece atenção especial.

Ao configurar uma porta em modo “transparente” duas limitações serão impostas logo de imediato: “não permitirá sua utilização em configurações manuais e será incompatível com os mecanismos de autenticação suportados nativamente“.

Neste modo de operação, as características de comunicação, descritas anteriormente, impõem limites para tratar ou identificar quando o responsável pelo questionamento da credencial de usuário é o servidor real ou o próprio Squid. Portanto, perde-se o suporte para autenticação de usuários. Este problema pode ser contornado com a inclusão de um serviço de captive portal (redirecionando ao proxy, após a autorização do usuário) – acredito que não é uma solução adequada para aplicar no segmento principal da rede, mas pode ser uma alternativa interessante em um segmento de rede WI-FI aberto e isolado.

Para tornar as coisas mais interessantes… vejamos como “controlar” requisições HTTPS! 😉

Neste caso, além da configuração exibida, alguns administradores autorizam o “roteamento direto” (via filtro de pacotes), permitindo que os pacotes sejam encaminhados diretamente, sem que o proxy intercepte. Ou seja, seguindo à risca o modelo hop-by-hop. Com este tipo de configuração você será capaz de bloquear facilmente “http://www.facebook.com“, nãohttps://www.facebook.com“. Por esta razão, alguns administradores afirmam, erroneamente, que não é possível controlar requisições HTTPS.

Não tente contornar a “falha” escrevendo regras de filtragem de pacotes (via iptables) para controlar este tipo de acesso. Pode ser “fácil” lidar com meia dúzia de sites, mas será inviável – para não dizer impossível – controlar milhares de endereços desta maneira. O fato é: “Ou você adota um mecanismo de filtragem eficiente, ou será facilmente burlado“.

Por incrível que pareça, muitas empresas mantém o acesso a porta TCP/443 liberado e sem nenhuma inspeção de aplicação. Esta medida impossibilita o controle de inúmeras aplicações (como Skype ou Ultrasurf, por exemplo), permite acesso privilegiado a URLs https e abre uma brecha enorme para o tunelamento de conexões (VPNs).

# - Liberação *não recomendada* (torna vulnerável)
iptables -A FORWARD -s 10.0.0.0/24 -p tcp --dport 443 --syn -j ACCEPT

Existem, basicamente, duas alternativas eficientes… Particularmente, só considero uma.

Seja qual for a solução, certifique-se de ter bloqueado o encaminhamento de pacotes pela porta TCP/443 diretamente. Na maioria das vezes, o tratamento das exceções é simples e menos trabalhoso. Nada impede autorizar um endereço específico ou bloco de rede. O bloco 170.66.0.0/16 é do Banco do Brasil e podemos considerá-lo confiável. Neste caso, basta autorizá-lo na cadeia FORWARD.

Em caso de dúvidas, é possível utilizar a ferramenta whois do registro.br para auxiliar na identificação do bloco de rede“.

Em relação a configuração do proxy

Quando encaminhamos requisições HTTPS à um socket HTTP (proxy manual, por exemplo), o Squid processa as requisições através do método CONNECT, ignorando características específicas do protocolo (como se estivesse tunelando). Desta maneira, a capacidade filtro fica reduzida. Ainda assim, trabalhar com um socket HTTPS nem sempre será vantajoso.

Não podemos redirecionar requisições HTTPS para uma porta HTTP comum, pois o cliente “entende”, desde o início da conexão, que precisa negociar uma sessão encriptada (não é opcional). Logo, o servidor Proxy precisa negociar o processo de encriptação e isto requer, obrigatoriamente, a utilização de um socket HTTPS. Neste caso, o Squid precisa desenvolver um ataque de man-in-the-middle mais sofisticado, negociando também a troca de chaves com o cliente – é necessário se desejarmos interceptar o tráfego ou filtrar URL e conteúdo de sites HTTPS.

Nada impede configurar uma porta HTTPS, em modo transparente, trabalhando com um certificado auto-assinado (técnica comumente empregada em setups de proxy reverso). O primeiro obstáculo é evitar que os navegadores considerem o certificado inválido. Para resolver este problema, basta importar o certificado (como confiável) em todas as estações da rede. Dependendo da complexidade da rede, esta etapa será trabalhosa. O próximo obstáculo será tratar cada exceção manualmente, pois nenhum administrador, em sã consciência, se responsabilizará por um man-in-the-middle em sites de Bancos ou serviços de webmail pessoal, por exemplo. Do contrário, os usuários poderão alegar invasão de privacidade, com grave violação de segurança.

Na minha opinião, as desvantagens desta solução superam as vantagens. Então, prefiro não implementar uma configuração de proxy transparente para conexões HTTPS. Por isto comentei que considero apenas uma alternativa (risos).

Prefiro configurar os servidores de DNS e DHCP para identificar e entregar o “script de detecção automática de proxy (WPAD)” e, no controlador de domínio, forçar a configuração da URL de detecção de proxy via GPO (http://webserver.sufixo.de.pesquisa/wpad.dat). É uma combinação que costuma funcionar muito bem e é extremamente estável.

Com WPAD podemos instruir, ao navegador, todas as regras de utilização do proxy (quando utilizar ou não) a partir de um ponto central. O efeito prático é de um proxy transparente, apesar de lidar com um método de conexão manual (não submeta a uma porta configurada com opção “intercept“).

Conforme o exemplo demonstrado inicialmente, podemos manter o redirecionamento para a porta 3128 e ainda selecionar a 8080 no WPAD. Desta forma seremos capazes de controlar requisições HTTP e HTTPS, sem a necessidade de configurar um socket HTTPS. E qualquer aplicação web (na porta 80), que não suportar configuração de proxy, será interceptada.

Por padrão, no caso de requisições HTTPS, a capacidade de inspeção estará limitada apenas ao domínio – em função da criptografia aplicada, não será possível analisar uma URL completa. Para elevar o nível de inspeção, basta configurar o recurso ssl_bump (no socket HTTP mesmo). A flexibilidade é grande o suficiente para lhe permitir selecionar, por ACLs, quais domínios serão inspecionados.

O meu objetivo foi dar uma visão geral sobre o assunto. Acabei estendendo um pouco mais.

Com o tempo compartilharei informações mais detalhadas e exemplos práticos.