Modos de funcionamento do Squid

Considerando forward proxies, temos:

Não transparente

http_port 3128

Modo tradicional. Os clientes precisam ser configurados para usarem o proxy. NAT não é requerida no servidor — é desaconselhável inclusive[1]. Tráfego HTTP é filtrado e cacheado. Tráfego HTTPS é tunelado sem modificações; portanto, não é cacheado. Domínios HTTPS podem ser filtrados; URLs HTTPS (que incluem a parte interna dos endereços) não são visíveis, pois, após a conexão TLS[2] ser estabelecida, o proxy nada mais sabe a respeito.

Transparente HTTP

# sysctl -w net.ipv4.ip_forward=1
# iptables -t mangle -A PREROUTING -i int_interna -p tcp -m tcp --dport 3129 -j DROP
# iptables -t nat -A PREROUTING -i int_interna -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3129
# iptables -t nat -A POSTROUTING -o int_externa -j MASQUERADE

http_port 3128
http_port 3129 intercept

Dispensa configuração nos clientes. NAT é requerida. Tráfego da porta 80, proveniente da rede interna, é redirecionado para o próprio servidor, sendo interceptado pelo Squid. Tráfego HTTP é filtrado e cacheado. Tráfego HTTPS é tunelado e domínios e URLs HTTPS não podem ser filtrados — mesmo que o usuário tente acessar sem https://, HSTS[3], cada vez mais popular, efetivamente impede qualquer tipo de controle.

Transparente HTTP + HTTPS

# sysctl -w net.ipv4.ip_forward=1
# iptables -t mangle -A PREROUTING -i int_interna -p tcp -m tcp --dport 3129:3130 -j DROP
# iptables -t nat -A PREROUTING -i int_interna -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3129
# iptables -t nat -A PREROUTING -i int_interna -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 3130
# iptables -t nat -A POSTROUTING -o int_externa -j MASQUERADE

http_port 3128 ssl-bump tls-cert=/caminho/ca.pem tls-key=/caminho/ca.key
http_port 3129 intercept
https_port 3130 intercept ssl-bump tls-cert=/caminho/ca.pem tls-key=/caminho/ca.key
acl etapa1 at_step SslBump1
ssl_bump peek etapa1
ssl_bump bump all

Mais problemático de todos. Dispensa configuração nos clientes. NAT é requerida. Squid 4+ altamente recomendável[4]. A parte HTTP continua como antes. Contudo, com ssl-bump, o Squid torna-se MITM[5]: estabelece a conexão com o servidor HTTPS (via TLS como de costume), inspeciona o que está sendo acessado e por fim assina o site novamente com um certificado próprio[6], gerado sob medida para aquele domínio e entrega-o ao cliente. Pelo fato de decriptar a conexão TLS, é possível filtrar URLs, bem como armazenar os dados transferidos no cache.

Tais vantagens não vêm sem contraindicações: não funciona em todos os sites, requer a autoridade certificadora (CA) instalada nos clientes e levanta uma grande questão de privacidade. Afinal, você está xeretando dentro de conexões que eram para ser privativas. E a segurança da chave privada passa a ser sua responsabilidade!

Para tentar lidar com a quebradeira, dá para recorrer a listas de domínios que devem (ou não) sofrer bump[7]. Algo a destacar é que as ACLs ssl::server_name e ssl::server_name_regex devem ser usadas nesse processo.

Lista negra:

http_port 3128 ssl-bump tls-cert=/caminho/ca.pem tls-key=/caminho/ca.key
http_port 3129 intercept
https_port 3130 intercept ssl-bump tls-cert=/caminho/ca.pem tls-key=/caminho/ca.key
acl sem_bump ssl::server_name_regex -i bradesco
acl etapa1 at_step SslBump1
ssl_bump peek etapa1
ssl_bump splice sem_bump
ssl_bump bump all

Configuração menos encrenqueira:

http_port 3128 ssl-bump tls-cert=/caminho/ca.pem tls-key=/caminho/ca.key
http_port 3129 intercept
https_port 3130 intercept ssl-bump tls-cert=/caminho/ca.pem tls-key=/caminho/ca.key
acl etapa1 at_step SslBump1
ssl_bump peek etapa1
ssl_bump splice all

splice all não faz bump (nada de cache). peek etapa1 dá acesso a SNI[8], que torna as ACLs dstdomain e dstdom_regex funcionais. Nos clientes, a CA serve apenas para exibir a página de erro do Squid. Ou seja, não é estritamente requerida.

Note que é possível manter o proxy normal, sem ssl-bump, na porta 3128:

http_port 3128
http_port 3129 intercept
https_port 3130 intercept ssl-bump tls-cert=/caminho/ca.pem tls-key=/caminho/ca.key
...

É uma saída para situações em que ssl-bump é problemático: configure manualmente no navegador para evitá-lo.

Fique de olho na lista de discussão squid-users e pendure uma ferradura na parede se for usar o recurso.

No modo transparente, é importante bloquear[9] acessos vindos da rede interna às portas 3129 e 3130, caso o usuário invente de configurar manualmente. Se chegarem ao Squid, serão bloqueados e cache.log será inundado com avisos Host header forgery detected.

Na minha opinião, o modo tradicional, não transparente, sem ssl-bump, é a melhor escolha, pois permite filtrar domínios e não abre a Caixa de Pandora que é mexer com TLS. Além de possibilitar uso de autenticação, recurso do contrário perdido. Dependendo do ambiente, autoconfiguração ajuda, principalmente com clientes Windows.

Com a indústria descontinuando HTTP, cada vez menos coisa é cacheada com HTTPS, mas pelo menos controle sobre o que é acessado continua viável.

Relacionado:
Squid + ssl-bump e as hierarquias tupiniquins


[1] Servidor DNS local é necessário nesse caso.
[2] Transport Layer Security.
[3] HTTP Strict Transport Security.
[4] Precisa ser compilado com --with-openssl. A partir da versão 4.0.24, GnuTLS é suportado também (--with-gnutls), porém é considerado experimental.
[5] Man-in-the-middle attack.
[6] Intercept HTTPS CONNECT messages with SSL-Bump.
[7] Feature: SslBump Peek and Splice.
[8] Server Name Indication.
[9] Os comandos iptables deste post são mínimos, apenas para fazer o Squid funcionar. Em produção, proteção de um firewall é recomendada.

Comentários