Отримання кальмарів та TPROXY за допомогою IPv6, що працює над CentOS 7


18

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

Я використовую офіційну статтю у вікі Squid з цього питання, щоб налаштувати все:

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)
  • Усі пакети оновлені відповідно до yum
  • Версія кальмарів: 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. У полі «Кальмари» налаштовано кілька статичних IPv6-адрес.

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

Здається, це працює нормально з точки зору передачі трафіку в поле "Кальмари". Ще одне додаткове правило, яке мені довелося додати на маршрутизаторі DD-WRT, крім вищезазначеного, - це правило виключення для налаштованих вихідних IPv4 та IPv6 адрес у полі Squid, інакше я отримую шалену проблему циклу і трафік порушується для всіх клієнтів, у тому числі основна локальна мережа, в якій використовується Squid 3128.

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

У полі «Кальмари» я використовую наступні правила маршрутизації та ланцюжок 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 (клієнти локальної мережі на порту, 3128які використовують файл WPAD / PAC, повністю працюють з IPv6). Незважаючи на те, що трафік якимось чином перенаправляється до вікна Squid, жодні запити через IPv6 через TPROXY не з'являються у access.log. Усі IPv6 запитують як буквальний IPv6, так і DNS, тайм-аут. Я можу отримати доступ до внутрішніх клієнтів IPv6, але знову ж таки, цей трафік також не реєструється.

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

Я деякий час намагаюся змусити це працювати, і не можу знайти проблему, я навіть запитав у списку розсилки кальмарів, але не зміг діагностувати фактичну проблему або вирішити її. На основі мого тестування я впевнений, що це одна з наступних областей і проблема кальмарів:

  • Маршрутизація
  • Ядро
  • Брандмауер

Будемо дуже вдячні за будь-які ідеї та додаткові кроки, які я можу зробити для роботи 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 портів і нічого не досягає кальмарів. Я на даний момент відмовився від цього. Ядро, на якому я зараз працюю, - 2.6.32 - зауважу, що на wiki.squid-cache.org/Features/Tproxy4 вони містять список мінімальної кількості ядер 2.6.37, тому мені цього вже не вистачає. Якщо я коли-небудь висуну його, я поінформую тут свої висновки.
parkamark

Тому я, нарешті, почав це працювати. Проблема полягала в тому, щоб порт "перехоплення" IPv4 був рівним порту IPv6 "tproxy" в squid.conf - це детально описано в документації, але я подумав, що міг би піти, не роблячи цього, тому що ці порти слухали конкретні адреси / стеки разом з портом, тому немає конкретної причини, чому вони повинні конфліктувати, правда? Ну, це здається помилковою презумпцією. Читати далі ...
parkamark

Я визначав "http_port 192.168.0.1:3128 перехоплення" та "http_port [fd00 :: 2]: 3128 tproxy" в squid.conf - не робіть цього! Це повинні бути просто "перехват http_port 3128" та "http_port 3129 tproxy". Ви не можете примусити IPv6 порт tproxy прив’язати до певної адреси IPv6, і тоді очікуйте, що вся магія брандмауера / маршрутизації спрацює. Ви можете вказати лише порти окремо, тобто кальмар буде прив'язуватися до всіх адрес / інтерфейсів цих портів. Я додам правила брандмауера, щоб зафіксувати ці відкриті порти в міру необхідності.
parkamark

Відповіді:


1

Я усвідомлюю, що це по-старому, і я не маю повної відповіді на це, але я роблю щось дуже схоже на вас і має майже однакові симптоми.

По-перше: тест -ipv6.com, здається, нещодавно оновився, щоб мати змогу впоратися з новим типом помилок (він був зламаний на початку цього року). Повторіть тест.

У моєму випадку він надіслав мені URL-адресу, яка описує проблему, яку я, здається, маю: FAQ FAQ про виявлення MTU . Вони надають URL-адресу, яку ви можете використовувати за допомогою CURL, щоб зробити тест PMTUD, а потім ви можете перевірити свій трафік за допомогою tpcdumpабо за допомогою проводки.

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

Короткий опис:

  • ICMP надзвичайно важливий у IPv6. Дуже багато людей хочуть заблокувати ICMP і врешті-решт заподіяти більше шкоди, ніж користі.
  • Якщо пакет "занадто великий" для вашого з'єднання, пакет відміняється, і повідомлення ICMP типу 2 ("Пакет занадто великий") повинен бути відправлений на вихідний сервер із проханням зменшити розмір пакета та повторно надіслати.
  • Якщо повідомлення ICMP не переносить його на сервер, сервер продовжує повторно надсилати великий пакет - який негайно відкидається, оскільки він занадто великий.
  • Це було описано як "чорну діру", тому що пакети ніколи не досягають свого призначення.

Таким чином, ви можете переконатися, що ваші правила брандмауера встановлені для прийому повідомлень ICMPv6 (див. RFC4890 для переліку "необхідних" типів ICMP).

У моєму випадку я дозволяю ICMP-повідомлення, і все ще є проблема. Я не зовсім готовий кинути рушник і просто зменшити MTU моєї мережі (що є ядерним варіантом).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.