Colocando o Squid e o TPROXY com IPv6 trabalhando no CentOS 7

18

Estou tendo problemas para que o TPROXY funcione com o Squid e o IPv6 em um servidor CentOS 7. Anteriormente, eu estava usando uma configuração de interceptação genérica com o NAT, mas estava limitada apenas ao IPv4. Agora estou expandindo a instalação para incluir o IPv6 com o TPROXY.

Eu tenho usado o artigo oficial do Squid wiki sobre o assunto para configurar tudo:

http://wiki.squid-cache.org/Features/Tproxy4

Até agora, a configuração do TPROXY parece estar funcionando para o IPv4 sem problemas. Com o IPv6, no entanto, as conexões atingem o tempo limite e não estão funcionando corretamente. Vou dividir a configuração para entender melhor.

Observe que todas as regras de firewall e roteamento são exatamente iguais para IPv4, a única diferença é inet6e ip6tablespara configurar regras baseadas em IPv6 nos exemplos abaixo.

  • SO e Kernel: CentOS 7 (3.10.0-229.14.1.el7.x86_64)
  • Todos os pacotes estão atualizados de acordo com o yum
  • Versão do Squid: 3.3.8 (Também tentei 3.5.9)
  • Firewall: iptables / ip6tables 1.4.21
  • libcap-2.22-8.el7.x86_64

Atualmente, a conectividade IPv6 é realizada através de um túnel 6in4 via Hurricane Electric; isso é configurado no roteador DD-WRT e, em seguida, o prefixo atribuído é delegado aos clientes via radvd. A caixa Squid tem vários endereços IPv6 estáticos configurados.

A caixa do Squid fica na LAN principal que está sendo usada. Os clientes que estão tendo tráfego na porta 80 interceptados (principalmente clientes sem fio) estão sendo enviados para a caixa Squid por meio do meu roteador DD-WRT com as seguintes regras de firewall e roteamento, adaptadas dos artigos wiki Policy Routing e DD-WRT

Isso parece estar funcionando bem em termos de passar o tráfego para a caixa Squid. Uma regra adicional que precisei adicionar ao roteador DD-WRT, além das opções acima, foi uma regra de exceção para os endereços IPv4 e IPv6 de saída configurados na caixa Squid, caso contrário, eu tenho um problema de loop louco e o tráfego é interrompido para todos os clientes, incluindo a LAN principal que usa o Squid 3128.

ip6tables -t mangle -I PREROUTING -p tcp --dport 80 -s "$OUTGOING_PROXY_IPV6" -j ACCEPT

Na caixa do Squid, estou usando as seguintes regras de roteamento e a cadeia DIVERT para lidar com o tráfego adequadamente. Eu precisava adicionar regras adicionais para evitar erros com a cadeia já existente durante o teste. Meu firewall é CSF: eu adicionei o seguinte aocsfpre.sh

ip -f inet6 route flush table 100
ip -f inet6 rule del fwmark 1 lookup 100

ip -f inet6 rule add fwmark 1 lookup 100
ip -f inet6 route add local default dev eno1 table 100

ip6tables -t mangle -F
ip6tables -t mangle -X
ip6tables -t mangle -N DIVERT

ip6tables -t mangle -A DIVERT -j MARK --set-mark 1
ip6tables -t mangle -A DIVERT -j ACCEPT
ip6tables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
ip6tables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 3129

squid.conf está configurado para duas portas:

http_proxy 3128
http_proxy 3129 tproxy

Além disso, também estou usando o Privoxy e tive que adicionar no-tproxyà minha linha cache_peer, caso contrário, todo o tráfego não pôde ser encaminhado para os dois protocolos.

cache_peer localhost parent 8118 7 no-tproxy no-query no-digest

Não estou usando nenhuma tcp_outgoing_addressdiretiva por causa do Privoxy. Em vez disso, estou controlando os endereços de saída por meio do CentOS e da ordem de ligação.

valores sysctl:

net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.eno1.rp_filter = 0

Não tenho certeza se as rp_filtermodificações são necessárias, pois a instalação funciona no IPv4 com ou sem elas e produz o mesmo resultado para o IPv6.

SELINUX

O SELINUX está ativado na caixa Squid, mas as políticas foram configuradas para permitir a configuração do TPROXY, para que não seja bloqueado (o funcionamento do IPv4 mostra isso de qualquer maneira). Eu verifiquei com grep squid /var/log/audit/audit.log | audit2allow -ae recebo<no matches>

#============= squid_t ==============

#!!!! This avc is allowed in the current policy
allow squid_t self:capability net_admin;

#!!!! This avc is allowed in the current policy
allow squid_t self:capability2 block_suspend;

#!!!! This avc is allowed in the current policy
allow squid_t unreserved_port_t:tcp_socket name_connect;

Também defini os seguintes booleanos:

setsebool squid_connect_any 1
setsebool squid_use_tproxy 1

Conectividade IPv6 interrompida

Por fim, a conectividade IPv6 é completamente interrompida para clientes TPROXY (os clientes LAN na porta 3128que usam um arquivo WPAD / PAC têm o IPv6 totalmente funcional). Embora pareça que o tráfego esteja sendo roteado para a caixa Squid de alguma forma, nenhuma solicitação sobre IPv6 via TPROXY está aparecendo no access.log. Todo IPv6 solicita tempo limite literal de IPv6 e DNS. Posso acessar clientes IPv6 internos, mas novamente, esse tráfego também não é registrado.

Fiz alguns testes usando test-ipv6.com e descobri que ele detectou meu endereço IPv6 do Squid de saída, mas os testes IPv6 mostraram-se ruins / lentos ou com tempo limite esgotado. Eu habilitei temporariamente o cabeçalho via e descobri que o cabeçalho HTTP do Squid estava visível; portanto, o tráfego está chegando pelo menos à caixa do Squid, mas não está sendo roteado corretamente quando estiver lá.

Estou tentando fazer isso funcionar há algum tempo e não consigo encontrar qual é o problema, até perguntei na lista de emails do Squid, mas não consegui diagnosticar o problema real ou resolvê-lo. Com base nos meus testes, tenho certeza de que é uma das seguintes áreas e o Squid apresenta o problema:

  • Encaminhamento
  • Núcleo
  • Firewall

Todas as idéias e etapas adicionais que eu possa tomar para que o TPROXY e o IPv6 funcionem serão muito apreciadas!

Informação adicional

Regras do ip6tables:

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
DIVERT     tcp      ::/0                 ::/0                 socket
TPROXY     tcp      ::/0                 ::/0                 tcp dpt:80 TPROXY redirect :::3129 mark 0x1/0x1

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

Chain DIVERT (1 references)
target     prot opt source               destination
MARK       all      ::/0                 ::/0                 MARK set 0x1
ACCEPT     all      ::/0                 ::/0

Tabela de roteamento IPv6 (prefixo obscurecido)

unreachable ::/96 dev lo  metric 1024  error -101
unreachable ::ffff:0.0.0.0/96 dev lo  metric 1024  error -101
2001:470:xxxx:xxx::5 dev eno1  metric 0
    cache  mtu 1480
2001:470:xxxx:xxx:b451:9577:fb7d:6f2d dev eno1  metric 0
    cache
2001:470:xxxx:xxx::/64 dev eno1  proto kernel  metric 256
unreachable 2002:a00::/24 dev lo  metric 1024  error -101
unreachable 2002:7f00::/24 dev lo  metric 1024  error -101
unreachable 2002:a9fe::/32 dev lo  metric 1024  error -101
unreachable 2002:ac10::/28 dev lo  metric 1024  error -101
unreachable 2002:c0a8::/32 dev lo  metric 1024  error -101
unreachable 2002:e000::/19 dev lo  metric 1024  error -101
unreachable 3ffe:ffff::/32 dev lo  metric 1024  error -101
fe80::/64 dev eno1  proto kernel  metric 256
default via 2001:470:xxxx:xxxx::1 dev eno1  metric 1
James White
fonte
Eu tentei atualizar para uma versão posterior do Squid (3.5), para descartar quaisquer problemas de bugs / versões, mas o problema permanece.
James White
11
Apenas comentando para dizer que eu tive isso trabalhando há um ano atrás em uma caixa do CentOS 6. No entanto, de repente parou de funcionar um dia (depois de uma atualização do kernel, eu acho) e não consegui fazê-lo funcionar desde então. Se eu ativar a configuração do IPv6 TPROXY, ele basicamente interromperá todo o tráfego da porta 80 e nada alcançará o squid. Eu desisti por um momento. O kernel em execução no momento é o 2.6.32 - observo que no wiki.squid-cache.org/Features/Tproxy4 , eles listam uma versão mínima do kernel de 2.6.37, portanto, já estou aquém disso. Se eu descobrir isso, vou atualizar aqui com minhas descobertas.
parkamark
Então eu finalmente consegui isso funcionando. O problema era ter a porta de "interceptação" do IPv4 igual à porta "tproxy" do IPv6 no squid.conf - isso é detalhado na documentação, mas achei que poderia me safar por não fazer isso, porque essas portas estavam escutando endereços / pilhas específicos junto com a porta; portanto, não há motivo específico para que eles entrem em conflito, certo? Bem, isso parece ser uma falsa presunção. Leia sobre ...
parkamark 5/08/16
Eu havia definido "http_port 192.168.0.1:3128 intercept" e "http_port [fd00 :: 2]: 3128 tproxy" no squid.conf - não faça isso! Deve ser simplesmente "interceptação http_port 3128" e "http_port 3129 tproxy". Você não pode ter a porta IPv6 tproxy vinculada a um endereço IPv6 específico e esperar que toda a mágica do firewall / roteamento funcione. Você pode especificar apenas as portas sozinhas, o que significa que o squid se ligará a todos os endereços / interfaces nessas portas. Vou adicionar regras de firewall para bloquear essas portas abertas, conforme necessário.
parkamark

Respostas:

1

Sei que é velho e não tenho uma resposta completa para isso, mas estou fazendo algo muito parecido com você e tenho sintomas quase idênticos.

Primeiro: o test-ipv6.com parece ter se atualizado um pouco recentemente para poder lidar com um novo tipo de erro (foi quebrado no início deste ano). Faça um teste novamente.

No meu caso, ele me enviou para uma URL que descreve um problema que parece ter: Perguntas freqüentes sobre a detecção de caminho no MTU . Eles fornecem uma URL que você pode usar com o cURL para fazer um teste de PMTUD e, em seguida, pode verificar seu tráfego usando tpcdumpou wireshark.

Quando o tráfego é TPROXY sobre o Squid, a detecção de caminho MTU do IPv6 não está funcionando totalmente em seu host. (Ainda estou trabalhando por que não está funcionando no meu host, portanto não tenho uma solução definitiva).

Uma descrição rápida:

  • O ICMP é extremamente importante no IPv6. Muitas pessoas querem bloquear o ICMP e acabam causando mais mal do que bem.
  • Se um pacote for "muito grande" para sua conexão, o pacote será descartado e uma mensagem do tipo ICMP tipo 2 ("Pacote muito grande") deve ser enviada ao servidor de origem, solicitando que ele reduza o tamanho do pacote e reenvie.
  • Se a mensagem ICMP não chegar ao servidor, o servidor continuará reenviando o pacote grande - que é descartado imediatamente por ser muito grande.
  • Isso foi descrito como um "buraco negro" porque os pacotes nunca chegam ao seu destino.

Portanto, convém verificar se suas regras de firewall estão definidas para aceitar mensagens ICMPv6 (consulte RFC4890 para obter uma lista dos tipos de ICMP "necessários").

No meu caso, estou permitindo mensagens ICMP e ainda tenho o problema. Não estou pronto para jogar a toalha e apenas reduzir o MTU da minha rede (que é a opção nuclear).

Pariah Zero
fonte