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

18

Estou com problemas para fazer o TPROXY trabalhar com o Squid e o IPv6 em um servidor do CentOS 7. Eu estava usando anteriormente uma configuração genérica de interceptação com NAT, mas ela estava limitada apenas ao IPv4. Agora estou expandindo a configuração para incluir o IPv6 com o TPROXY.

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

link

Até agora, a configuração TPROXY parece estar funcionando para o IPv4 sem problemas. Com o IPv6, no entanto, as conexões estão expirando e não estão funcionando corretamente. Eu vou quebrar a configuração para melhor compreensão.

Observe que todas as regras de firewall e roteamento são exatamente as mesmas para o IPv4, a única diferença é inet6 e ip6tables para 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 testado 3.5.9)
  • Firewall: iptables / ip6tables 1.4.21
  • libcap-2.22-8.el7.x86_64

A conectividade IPv6 está atualmente em 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 do Squid tem vários endereços IPv6 estáticos configurados.

A caixa do Squid fica dentro da LAN principal que está sendo servida. Clientes que estão tendo tráfego na porta 80 interceptados (principalmente clientes sem fio) estão sendo enviados para a caixa do Squid através do meu roteador DD-WRT com as seguintes regras de firewall e roteamento, adaptadas do artigo wiki do Policy Routing e do wiki do DD-WRT

  • link
  • link

    ip6tables -t mangle -A PREROUTING -i "$CLIENTIFACE" -s "$PROXY_IPV6" -p tcp --dport 80 -j ACCEPT
    ip6tables -t mangle -A PREROUTING -i "$CLIENTIFACE" -p tcp --dport 80 -j MARK --set-mark $FWMARK
    ip6tables -t mangle -A PREROUTING -m mark --mark $FWMARK -j ACCEPT
    ip6tables -t filter -A FORWARD -i "$CLIENTIFACE" -o "$CLIENTIFACE" -p tcp --dport 80 -j ACCEPT
    
    ip -f inet6 rule add fwmark $FWMARK table 2
    ip -f inet6 route add default via "$PROXY_IPV6" dev "$CLIENTIFACE" table 2
    

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

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

Na caixa Squid, estou usando as seguintes regras de roteamento e a cadeia DIVERT para lidar com o tráfego de acordo. Eu precisava adicionar regras adicionais para evitar erros com a cadeia já existente durante o teste. Meu firewall é CSF , adicionei o seguinte a csfpre.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 Privoxy e tive que adicionar no-tproxy à minha linha cache_peer, caso contrário, não foi possível encaminhar todo o tráfego para os dois protocolos.

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

Eu não estou usando nenhuma diretiva tcp_outgoing_address por causa do Privoxy, em vez disso, estou controlando os endereços de saída por meio do CentOS e da ordem de vinculaçã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 modificações de rp_filter são necessárias, pois a configuração funciona no IPv4 com ou sem elas e produz o mesmo resultado para o IPv6.

SELINUX

O SELINUX está habilitado na caixa do Squid, mas as políticas foram configuradas para permitir a configuração do TPROXY, de modo que não seja bloqueado (o IPv4 funciona assim mesmo). Eu verifiquei com grep squid /var/log/audit/audit.log | audit2allow -a e 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 valores booleanos:

setsebool squid_connect_any 1
setsebool squid_use_tproxy 1

Conectividade IPv6 quebrada

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

Eu fiz alguns testes usando o test-ipv6.com e descobri que ele detectou meu endereço de saída IPv6 do Squid, mas os testes IPv6 mostraram-se como ruim / lento ou timeout. Eu habilitei temporariamente o cabeçalho via e descobri que o cabeçalho HTTP do Squid estava visível, então o tráfego está, pelo menos, chegando à caixa do Squid, mas não sendo roteado apropriadamente quando estiver lá.

Eu tenho tentado fazer isso funcionar por algum tempo e não consigo encontrar qual é o problema, eu até perguntei na lista de discussão do Squid, mas não consegui diagnosticar o problema ou resolvê-lo. Com base nos meus testes, tenho certeza que é uma das seguintes áreas e a caixa do Squid o problema:

  • Roteamento
  • Kernel
  • Firewall

Todas as ideias e passos adicionais que eu possa dar para que TPROXY e IPv6 funcionem, serão muito apreciados!

Informações adicionais

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
    
por James White 22.10.2015 / 00:07

1 resposta

1

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

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

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

Quando o tráfego é TPROXY sobre o Squid, a Detecção MTU do Caminho IPv6 não está totalmente funcionando no seu host. (Ainda estou trabalhando no porquê de não estar funcionando no meu host, então 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 ICMP tipo 2 ("Pacote muito grande") deverá ser enviada ao servidor de origem, solicitando que reduza o tamanho do pacote e reenvie.
  • Se a mensagem ICMP não chegar ao servidor, o servidor continuará reenviando o pacote grande - que é imediatamente descartado porque é muito grande.
  • Isso foi descrito como um "buraco negro" porque os pacotes nunca atingem seus limites destino.
Portanto, convém certificar-se de que suas regras de firewall estejam configuradas para aceitar mensagens ICMPv6 (consulte RFC4890 para obter uma lista de tipos ICMP "necessários").

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

    
por 28.09.2017 / 20:00