Pobieranie Squid i TPROXY z IPv6 na CentOS 7

18

Mam problem z uruchomieniem TPROXY z Squid i IPv6 na serwerze CentOS 7. Wcześniej korzystałem z ogólnej konfiguracji przechwytywania z NAT, ale było to ograniczone tylko do IPv4. Teraz rozszerzam konfigurację, aby uwzględnić IPv6 z TPROXY.

Korzystam z oficjalnego artykułu wiki Squid na ten temat, aby skonfigurować wszystko:

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

Jak dotąd konfiguracja TPROXY wydaje się działać dla IPv4 bez żadnych problemów. Jednak w przypadku IPv6 połączenia wygasają i nie działają poprawnie. Rozłożę konfigurację dla lepszego zrozumienia.

Uwaga wszystkie zapory i zasady routingu są dokładnie takie same dla IPv4, jedyną różnicą jest to, inet6i ip6tablesdo konfigurowania reguł opartych na IPv6 w poniższych przykładach.

  • System operacyjny i jądro: CentOS 7 (3.10.0-229.14.1.el7.x86_64)
  • Wszystkie pakiety są aktualne zgodnie z yum
  • Wersja Squid: 3.3.8 (Wypróbowano również 3.5.9)
  • Firewall: iptables / ip6tables 1.4.21
  • libcap-2.22-8.el7.x86_64

Łączność IPv6 odbywa się obecnie przez tunel 6w4 za pośrednictwem Hurricane Electric, jest to konfigurowane na routerze DD-WRT, a następnie przypisany prefiks przekazywany klientom przez radvd. Pole Squid ma skonfigurowanych kilka statycznych adresów IPv6.

Pudełko Squid znajduje się w głównej sieci LAN, którą obsługuje. Klienci przechwytujący ruch na porcie 80 (głównie klienci bezprzewodowi) są wypychani do skrzynki Squid za pośrednictwem mojego routera DD-WRT z następującymi regułami zapory i routingu, zaadaptowanymi z artykułu wiki Policy Routing i DD-WRT wiki

Wydaje się, że działa OK, jeśli chodzi o przekazywanie ruchu do skrzynki Squid. Jedną dodatkową regułą, którą musiałem dodać na routerze DD-WRT, oprócz powyższej, była reguła wyjątkowa dla skonfigurowanych wychodzących adresów IPv4 i IPv6 w skrzynce Squid, w przeciwnym razie mam problem z szaloną pętlą i ruch jest przerywany dla wszystkich klientów, w tym główna sieć LAN korzystająca z Squid 3128.

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

W polu Squid używam następujących reguł routingu i łańcucha DIVERT, aby odpowiednio obsłużyć ruch. Musiałem dodać dodatkowe reguły, aby uniknąć błędów w łańcuchu już istniejącym podczas testowania. Moja zapora jest CSF, dodałem następujące elementycsfpre.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 jest skonfigurowany dla dwóch portów:

http_proxy 3128
http_proxy 3129 tproxy

Ponadto używam również Privoxy i musiałem dodać no-tproxydo mojej linii cache_peer, w przeciwnym razie cały ruch nie byłby możliwy do przekazania dla obu protokołów.

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

Nie używam żadnych tcp_outgoing_addressdyrektyw z powodu Privoxy, zamiast tego kontroluję adresy wychodzące za pośrednictwem CentOS i kolejności łączenia.

wartości 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

Nie jestem pewien, czy rp_filterpotrzebne są modyfikacje, ponieważ instalacja działa na IPv4 z nimi lub bez nich i daje taki sam wynik dla IPv6.

SELINUX

SELINUX jest włączony w polu Squid, ale zasady zostały skonfigurowane tak, aby umożliwić konfigurację TPROXY, więc nie jest blokowana (i tak pokazuje to praca IPv4). Sprawdziłem grep squid /var/log/audit/audit.log | audit2allow -ai otrzymałem<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;

Ustawiłem również następujące wartości logiczne:

setsebool squid_connect_any 1
setsebool squid_use_tproxy 1

Zerwana łączność IPv6

Ostatecznie łączność IPv6 jest całkowicie zerwana dla klientów TPROXY (klienci LAN na porcie 3128używający pliku WPAD / PAC mają w pełni działający protokół IPv6). Chociaż wydaje się, że ruch jest w jakiś sposób kierowany do skrzynki Squid, żadne żądania przez IPv6 za pośrednictwem TPROXY nie pojawiają się w access.log. Wszystkie żądania IPv6 dotyczą zarówno literalnego adresu IPv6, jak i DNS, limit czasu. Mogę uzyskać dostęp do wewnętrznych klientów IPv6, ale znowu ten ruch również nie jest rejestrowany.

Zrobiłem kilka testów przy użyciu test-ipv6.com i odkryłem, że wykryło mój wychodzący adres Squid IPv6, ale testy IPv6 wykazały albo zły / wolny albo przekroczenie limitu czasu. Tymczasowo włączyłem nagłówek via i stwierdziłem, że nagłówek HTTP Squid jest widoczny, więc ruch co najmniej dociera do pola Squid, ale nie jest odpowiednio kierowany, gdy już tam jest.

Od jakiegoś czasu staram się, aby to zadziałało i nie mogę znaleźć problemu. Zapytałem nawet o listę dyskusyjną Squid, ale nie byłem w stanie zdiagnozować ani rozwiązać problemu. Na podstawie moich testów jestem prawie pewien, że jest to jeden z następujących obszarów, a problem Squid zawiera:

  • Wytyczanie
  • Jądro
  • Zapora ogniowa

Będziemy wdzięczni za wszelkie pomysły i dodatkowe kroki, które mogę podjąć, aby TPROXY i IPv6 działały!

Dodatkowe informacje

Zasady 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 routingu IPv6 (ukryty prefiks)

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
źródło
Próbowałem zaktualizować do późniejszej wersji Squid (3.5), aby wykluczyć wszelkie błędy / problemy z wydaniem, ale problem pozostaje.
James White
1
Tylko komentując, powiedziałem, że działałem to około rok temu na pudełku CentOS 6. Jednak nagle przestał działać (myślę, że po aktualizacji jądra) i od tego czasu nie udało mi się go uruchomić. Jeśli włączę konfigurację IPRO6 TPROXY, to zasadniczo psuje cały ruch na porcie 80 i nic nie dociera do kałamarnicy. Na razie się poddałem. Jądro, na którym aktualnie pracuję, to 2.6.32 - zauważam, że na wiki.squid-cache.org/Features/Tproxy4 podają minimalną wersję jądra 2.6.37, więc już mi tego brakuje. Jeśli kiedykolwiek to przekopię, zaktualizuję tutaj swoje ustalenia.
parkamark
Więc w końcu to działa. Problem polegał na tym, że port „przechwytujący” IPv4 był równy portowi „tproxy” IPv6 w pliku squid.conf - jest to szczegółowo opisane w dokumentacji, ale pomyślałem, że nie mogę tego zrobić, ponieważ te porty nasłuchują konkretne adresy / stosy wraz z portem, więc nie ma konkretnego powodu, dla którego powinny one powodować konflikty, prawda? Cóż, wydaje się to fałszywym domniemaniem. Czytaj dalej ...
parkamark,
Zdefiniowałem „http_port 192.168.0.1:3128 przechwytywanie” i „http_port [fd00 :: 2]: 3128 tproxy” w squid.conf - nie rób tego! Musi to być po prostu „http_port 3128 intercept” i „http_port 3129 tproxy”. Nie można powiązać portu tproxy IPv6 z określonym adresem IPv6, a następnie oczekiwać, że cała magia zapory / routingu będzie działać. Można określić tylko same porty, co oznacza, że ​​squid będzie się wiązał ze wszystkimi adresami / interfejsami na tych portach. Dodam reguły zapory, aby zablokować te otwarte porty w dół, zgodnie z wymaganiami.
parkamark

Odpowiedzi:

1

Zdaję sobie sprawę, że to jest stare i nie mam na to pełnej odpowiedzi, ale robię coś bardzo podobnego do ciebie i mam prawie identyczne objawy.

Po pierwsze: wydaje się, że test-ipv6.com zaktualizował się nieco niedawno, aby móc obsłużyć nowy rodzaj błędu (został zepsuty na początku tego roku). Ponownie przetestuj.

W moim przypadku wysłano mnie do adresu URL opisującego problem, który prawdopodobnie mam: Często zadawane pytania dotyczące wykrywania MTU ścieżki . Podają adres URL, którego można użyć z cURL do przeprowadzenia testu PMTUD, a następnie można sprawdzić ruch za pomocą tpcdumplub wireshark.

Gdy ruch jest TPROXY przez Squid, wykrywanie MTU ścieżki IPv6 nie działa w pełni na twoim hoście. (Nadal pracuję nad tym, dlaczego nie działa na moim hoście, więc nie mam ostatecznego rozwiązania).

Krótki opis:

  • ICMP jest niezwykle ważny w IPv6. Wiele osób chce zablokować ICMP i ostatecznie wyrządzić więcej szkody niż pożytku.
  • Jeśli pakiet jest „zbyt duży” dla twojego połączenia, pakiet jest odrzucany, a wiadomość ICMP typu 2 („Pakiet zbyt duży”) powinna zostać wysłana do serwera źródłowego, prosząc go o zmniejszenie rozmiaru pakietu i ponowne wysłanie.
  • Jeśli komunikat ICMP nie dotrze do serwera, serwer ponownie wysyła duży pakiet - który jest natychmiast odrzucany, ponieważ jest zbyt duży.
  • Zostało to opisane jako „czarna dziura”, ponieważ pakiety nigdy nie docierają do miejsca docelowego.

Możesz więc upewnić się, że reguły zapory są ustawione na akceptowanie wiadomości ICMPv6 (zobacz RFC4890, aby uzyskać listę „potrzebnych” typów ICMP).

W moim przypadku zezwalam na komunikaty ICMP i nadal mam problem. Nie jestem jeszcze gotowy, aby rzucić ręcznik i po prostu zmniejszyć MTU mojej sieci (która jest opcją nuklearną).

Pariah Zero
źródło