Obteniendo Squid y TPROXY con IPv6 trabajando en CentOS 7

18

Tengo problemas para que TPROXY funcione con Squid e IPv6 en un servidor CentOS 7. Anteriormente estaba usando una configuración de intercepción genérica con NAT, pero estaba limitada solo a IPv4. Ahora estoy ampliando la configuración para incluir IPv6 con TPROXY.

He estado usando el artículo wiki oficial de Squid sobre el tema para configurar todo:

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

Hasta ahora, la configuración de TPROXY parece estar funcionando para IPv4 sin problemas. Con IPv6, sin embargo, las conexiones se están agotando y no funcionan correctamente. Desglosaré la configuración para una mejor comprensión.

Tenga en cuenta que todas las reglas de firewall y enrutamiento son exactamente las mismas para IPv4, la única diferencia es inet6y ip6tablespara configurar las reglas basadas en IPv6 en los ejemplos a continuación.

  • SO y kernel: CentOS 7 (3.10.0-229.14.1.el7.x86_64)
  • Todos los paquetes están actualizados según yum
  • Versión de Squid: 3.3.8 (También probé 3.5.9)
  • Cortafuegos: iptables / ip6tables 1.4.21
  • libcap-2.22-8.el7.x86_64

La conectividad IPv6 se realiza actualmente a través de un túnel 6in4 a través de Hurricane Electric, esto se configura en el enrutador DD-WRT y luego el prefijo asignado se delega a los clientes a través de radvd. El cuadro Squid tiene varias direcciones IPv6 estáticas configuradas.

El cuadro Squid se encuentra dentro de la LAN principal a la que sirve. Los clientes que tienen tráfico en el puerto 80 interceptado (principalmente clientes inalámbricos) son enviados a la caja Squid a través de mi enrutador DD-WRT con el siguiente firewall y reglas de enrutamiento, adaptados del artículo wiki Policy Routing y el wiki DD-WRT

Esto parece estar funcionando bien en términos de pasar el tráfico al cuadro Squid. Una regla adicional que tuve que agregar en el enrutador DD-WRT además de la anterior fue una regla de excepción para las direcciones IPv4 e IPv6 salientes configuradas en el cuadro Squid; de lo contrario, tengo un problema de bucle loco y el tráfico se interrumpe para todos los clientes, incluido la LAN principal que usa Squid 3128.

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

En el cuadro Squid, estoy usando las siguientes reglas de enrutamiento y la cadena DIVERT para manejar el tráfico en consecuencia. Necesitaba agregar reglas adicionales para evitar cualquier error con la cadena ya existente durante las pruebas. Mi firewall es CSF, he agregado lo siguiente acsfpre.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 dos puertos:

http_proxy 3128
http_proxy 3129 tproxy

Además, también estoy usando Privoxy y tuve que agregar no-tproxya mi línea cache_peer, de lo contrario no se pudo reenviar todo el tráfico para ambos protocolos.

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

No estoy usando ninguna tcp_outgoing_addressdirectiva debido a Privoxy, sino que estoy controlando las direcciones salientes a través de CentOS y el orden de enlace.

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

No estoy seguro de si las rp_filtermodificaciones son necesarias ya que la configuración funciona en IPv4 con o sin ellas y produce el mismo resultado para IPv6.

SELINUX

SELINUX está habilitado en el cuadro Squid, pero las políticas se han configurado para permitir la configuración de TPROXY, por lo que no está bloqueado (el funcionamiento de IPv4 lo muestra de todos modos). He consultado grep squid /var/log/audit/audit.log | audit2allow -ay obtengo<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;

También he configurado los siguientes booleanos:

setsebool squid_connect_any 1
setsebool squid_use_tproxy 1

Conectividad IPv6 rota

En última instancia, la conectividad IPv6 está completamente rota para los clientes TPROXY (los clientes LAN en el puerto 3128que usan un archivo WPAD / PAC tienen IPv6 completamente funcional). Si bien parece que el tráfico se está enrutando a la casilla Squid de alguna manera, no aparecen solicitudes a través de IPv6 a través de TPROXY access.log. Todo IPv6 solicita tanto IPv6 literal como DNS, tiempo de espera. Puedo acceder a clientes internos de IPv6 pero, nuevamente, este tráfico tampoco está registrado.

Hice algunas pruebas usando test-ipv6.com y descubrí que detectó mi dirección IPv6 de Squid saliente, pero las pruebas de IPv6 se mostraron como malas / lentas o de tiempo de espera. Temporalmente habilité el encabezado via y encontré que el encabezado HTTP Squid estaba visible, por lo que el tráfico al menos llega al cuadro Squid pero no se enruta correctamente una vez que está allí.

He estado tratando de hacer que esto funcione por algún tiempo y no puedo encontrar cuál es el problema, incluso he preguntado en la lista de correo de Squid, pero no he podido diagnosticar el problema real o resolverlo. Según mis pruebas, estoy bastante seguro de que es una de las siguientes áreas y el problema de la caja de Calamar:

  • Enrutamiento
  • Núcleo
  • Cortafuegos

¡Cualquier idea y pasos adicionales que pueda tomar para que TPROXY e IPv6 funcionen serán muy apreciados!

Información Adicional

reglas de 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

Tabla de enrutamiento IPv6 (prefijo oculto)

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
fuente
Intenté actualizar a una versión posterior de Squid (3.5), para descartar cualquier error / problema de lanzamiento, pero el problema persiste.
James White
1
Solo comento para decir que tuve esto funcionando hace aproximadamente un año en una caja CentOS 6. Sin embargo, de repente dejó de funcionar un día (después de una actualización del kernel, creo) y no he logrado hacerlo funcionar desde entonces. Si habilito la configuración IPv6 TPROXY, básicamente rompe todo el tráfico del puerto 80 y nada llega al calamar. He renunciado por el momento. El kernel que estoy ejecutando actualmente es 2.6.32. Observo que en wiki.squid-cache.org/Features/Tproxy4 , enumeran una versión mínima de kernel de 2.6.37, así que ya me falta eso. Si alguna vez lo descubro, actualizaré aquí con mis hallazgos.
parkamark
Así que finalmente conseguí que esto funcionara. El problema era que el puerto de "intercepción" de IPv4 fuera igual al puerto de "tproxy" de IPv6 en squid.conf: esto se detalla en la documentación, pero pensé que podría evitarlo porque tenía estos puertos escuchando direcciones / pilas específicas junto con el puerto, por lo que no hay una razón específica por la que deberían entrar en conflicto, ¿verdad? Bueno, esto parece ser una presunción falsa.
Sigue
Había definido "http_port 192.168.0.1:3128 intercept" y "http_port [fd00 :: 2]: 3128 tproxy" en squid.conf - ¡no hagas esto! Debe ser simplemente "http_port 3128 intercept" y "http_port 3129 tproxy". No puede hacer que el puerto tvproxy IPv6 se una a una dirección IPv6 específica y luego esperar que funcione toda la magia del firewall / enrutamiento. Solo puede especificar los puertos solo, lo que significa que squid se unirá a todas las direcciones / interfaces en estos puertos. Agregaré reglas de firewall para bloquear estos puertos abiertos, según sea necesario.
parkamark

Respuestas:

1

Me doy cuenta de que esto es viejo y no tengo una respuesta completa para esto, pero estoy haciendo algo muy similar a usted y tengo síntomas casi idénticos.

Primero: test-ipv6.com parece haberse actualizado un poco recientemente para poder manejar un nuevo tipo de error (se rompió a principios de este año). Pruébalo de nuevo.

En mi caso, me envió a una URL que describe un problema que parece tener: Preguntas frecuentes sobre la detección de MTU de ruta . Proporcionan una URL que puede usar con cURL para hacer una prueba PMTUD, y luego puede verificar su tráfico usando tpcdumpo wireshark.

Cuando el tráfico se TPROXY sobre Squid, la detección de MTU de ruta IPv6 no funciona por completo en su host. (Todavía estoy trabajando en por qué no funciona en mi host, por lo que no tengo una solución definitiva).

Una breve descripción:

  • ICMP es extremadamente importante en IPv6. Mucha gente quiere bloquear ICMP y terminar causando más daño que bien.
  • Si un paquete es "demasiado grande" para su conexión, el paquete se descarta y se supone que se debe enviar un mensaje ICMP tipo 2 ("Paquete demasiado grande") al servidor de origen, pidiéndole que reduzca el tamaño del paquete y lo reenvíe.
  • Si el mensaje ICMP no llega al servidor, el servidor sigue reenviando el paquete grande, que se descarta inmediatamente porque es demasiado grande.
  • Esto se ha descrito como un "agujero negro" porque los paquetes nunca llegan a su destino.

Por lo tanto, puede asegurarse de que las reglas de su firewall estén configuradas para aceptar mensajes ICMPv6 (consulte RFC4890 para obtener una lista de los tipos de ICMP "necesarios").

En mi caso, estoy permitiendo mensajes ICMP y todavía tengo el problema. No estoy listo para tirar la toalla y simplemente reducir la MTU de mi red (que es la opción nuclear).

Paria Cero
fuente