Получение Squid и TPROXY с IPv6, работающим на CentOS 7

18

У меня проблемы с тем, чтобы TPROXY работал со Squid и IPv6 на сервере CentOS 7. Ранее я использовал общую настройку перехвата с NAT, но она была ограничена только IPv4. Сейчас я расширяю настройку, чтобы включить IPv6 с TPROXY.

Я использовал официальную статью Squid wiki на эту тему, чтобы настроить все:

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

Пока что конфигурация TPROXY работает для IPv4 без проблем. С IPv6, однако, соединения истекают и не работают должным образом. Я сломаю настройку для лучшего понимания.

Обратите внимание , весь брандмауэр и правила маршрутизации точно так же для IPv4, с той лишь разницей , inet6и ip6tablesдля настройки правил на основе IPv6 в приведенных ниже примерах.

  • ОС и ядро: CentOS 7 (3.10.0-229.14.1.el7.x86_64)
  • Все пакеты обновлены в соответствии с ням
  • Версия Squid: 3.3.8 (также пробовал 3.5.9)
  • Брандмауэр: iptables / ip6tables 1.4.21
  • libcap-2.22-8.el7.x86_64

Подключение IPv6 в настоящее время осуществляется через туннель 6in4 через Hurricane Electric, это настраивается на маршрутизаторе DD-WRT, а затем назначенный префикс передается клиентам через radvd. В окне Squid настроено несколько статических IPv6-адресов.

Коробка Squid находится в основной локальной сети, которую она обслуживает. Клиенты, у которых перехватывается трафик через порт 80 (главным образом, беспроводные клиенты), отправляются в Squid через мой маршрутизатор DD-WRT со следующими правилами брандмауэра и маршрутизации, адаптированными из статьи википедии о политике и вики DD-WRT

Похоже, что он работает нормально с точки зрения передачи трафика в окно Squid. Одно дополнительное правило, которое я должен был добавить на маршрутизаторе DD-WRT, в дополнение к вышеприведенному, было правилом исключения для настроенных исходящих адресов IPv4 и IPv6 на коробке Squid, в противном случае я получаю сумасшедшую проблему петли, и трафик прерывается для всех клиентов, включая основная сеть, в которой используется Squid 3128.

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

Затем в окне Squid я использую следующие правила маршрутизации и цепочку DIVERT для соответствующей обработки трафика. Мне нужно было добавить дополнительные правила, чтобы избежать ошибок в цепочке, уже существующей во время тестирования. Мой брандмауэр CSF, я добавил следующее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 настроен на два порта:

http_proxy 3128
http_proxy 3129 tproxy

Кроме того, я также использую Privoxy и должен был добавить no-tproxyв мою строку cache_peer, иначе весь трафик не мог быть перенаправлен для обоих протоколов.

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

Я не использую никаких tcp_outgoing_addressдиректив из-за Privoxy, вместо этого я контролирую исходящие адреса через CentOS и порядок связывания.

значения 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

Я не уверен rp_filter, нужны ли изменения, так как программа установки работает на IPv4 с ними или без них и дает тот же результат для IPv6.

SELINUX

SELINUX включен на коробке Squid, но политики настроены так, чтобы разрешить настройку TPROXY, поэтому он не блокируется (работа IPv4 показывает это в любом случае). Я проверил с grep squid /var/log/audit/audit.log | audit2allow -aи получить<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;

Я также установил следующие логические значения:

setsebool squid_connect_any 1
setsebool squid_use_tproxy 1

Сломанная связь IPv6

В конечном счете, подключение клиентов IPv6 полностью нарушено для клиентов TPROXY (клиенты LAN на порту, 3128которые используют файл WPAD / PAC, имеют полностью рабочий IPv6). Хотя кажется, что трафик каким-то образом направляется на Squid, никаких запросов через IPv6 через TPROXY в access.log. Все IPv6-запросы запрашивают как буквальный IPv6, так и DNS, время ожидания. Я могу получить доступ к внутренним клиентам IPv6, но опять же, этот трафик также не регистрируется.

Я провел некоторое тестирование с использованием test-ipv6.com и обнаружил, что он обнаружил мой исходящий IPv6-адрес Squid, но тесты IPv6 показывали либо плохой / медленный, либо тайм-аут. Я временно включил заголовок via и обнаружил, что HTTP-заголовок Squid был виден, поэтому трафик, по крайней мере, попадает в окно Squid, но не маршрутизируется должным образом, как только он там появляется.

Я пытался заставить это работать в течение некоторого времени и не могу найти, в чем проблема, я даже спросил в списке рассылки Squid, но не смог диагностировать реальную проблему или решить ее. Основываясь на моем тестировании, я почти уверен, что проблема заключается в одной из следующих областей и Squid:

  • Маршрутизация
  • ядро
  • Межсетевой экран

Будем весьма благодарны за любые идеи и дополнительные шаги, которые можно предпринять для работы TPROXY и IPv6!

Дополнительная информация

Правила 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

Таблица маршрутизации IPv6 (префикс скрыт)

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
Джеймс Уайт
источник
Я попытался обновить до более поздней версии Squid (3.5), чтобы исключить любые ошибки / проблемы с выпуском, но проблема остается.
Джеймс Уайт
1
Просто комментируя, чтобы сказать, у меня это работало около года назад на коробке CentOS 6. Однако однажды он внезапно перестал работать (после обновления ядра, я думаю), и с тех пор мне так и не удалось заставить его работать. Если я включаю настройку IPv6 TPROXY, он в основном прерывает весь трафик порта 80 и ничего не достигает squid. Я отказался от этого на данный момент. Ядро, которое я сейчас использую, - это 2.6.32 - я отмечаю, что на wiki.squid-cache.org/Features/Tproxy4 они перечисляют минимальную версию ядра 2.6.37, так что мне уже не хватает этого. Если я когда-нибудь разберусь с этим, я обновлю здесь свои выводы.
parkamark
Так что я наконец-то заработал. Проблема была в том, что порт «перехват» IPv4 был равен порту «tproxy» IPv6 в squid.conf - это подробно описано в документации, но я подумал, что смогу не делать этого, потому что эти порты прослушиваются конкретные адреса / стеки вместе с портом, поэтому нет конкретной причины, по которой они должны конфликтовать, верно? Ну, это похоже на ложную презумпцию.
Продолжайте
Я определил «http_port 192.168.0.1:3128 перехват» и «http_port [fd00 :: 2]: 3128 tproxy» в squid.conf - не делайте этого! Это должны быть просто «http_port 3128 intercept» и «http_port 3129 tproxy». Вы не можете привязать порт tproxy IPv6 к определенному IPv6-адресу, а затем ожидать, что все магии брандмауэра / маршрутизации будут работать. Вы можете указать только порты, то есть squid будет связываться со всеми адресами / интерфейсами на этих портах. Я добавлю правила брандмауэра для блокировки этих открытых портов по мере необходимости.
parkamark

Ответы:

1

Я понимаю, что это старо, и у меня нет полного ответа на это, но я делаю что-то очень похожее на вас, и у меня почти идентичные симптомы.

Во-первых: test-ipv6.com, по-видимому, несколько обновился, чтобы справиться с новым типом ошибки (она была сломана ранее в этом году). Пройдите тест снова.

В моем случае он отправил мне URL-адрес, описывающий проблему, которая у меня возникла: FAQ по определению MTU пути . Они предоставляют URL-адрес, который вы можете использовать с cURL для проведения теста PMTUD, а затем вы можете проверить свой трафик с помощью tpcdumpили wireshark.

Когда трафик передается через Squid через TPROXY, определение MTU пути IPv6 не работает полностью на вашем хосте. (Я все еще работаю над тем, почему это не работает на моем хосте, поэтому у меня нет окончательного решения).

Краткое описание:

  • ICMP чрезвычайно важен в IPv6. Многие люди хотят заблокировать ICMP и в конечном итоге причиняют больше вреда, чем пользы.
  • Если пакет «слишком большой» для вашего соединения, пакет отбрасывается, и предполагается, что сообщение ICMP типа 2 («Пакет слишком большой») отправляется исходному серверу с просьбой уменьшить размер пакета и повторно отправить его.
  • Если сообщение ICMP не попадает на сервер, сервер продолжает повторную отправку большого пакета, который немедленно отбрасывается, потому что он слишком большой.
  • Это было описано как «черная дыра», потому что пакеты никогда не достигают своего места назначения.

Поэтому вы можете убедиться, что правила брандмауэра настроены на прием сообщений ICMPv6 (список «необходимых» типов ICMP см. В RFC4890).

В моем случае я разрешаю сообщения ICMP, но проблема все еще остается. Я не совсем готов бросить полотенце и просто уменьшить MTU моей сети (это ядерный вариант).

Пария ноль
источник