Калі вы дадаяце прэфікс IPv6 у тунель паміж пляцоўкамі, пакет падарожнічае не так, як падказвае схема. Лакальны шлюз бярэ ўвесь пакет IPv6, шыфруе яго і ставіць перад ім знешні загаловак IP, сямейства адрасоў якога вызначаюць адрасы канчатковых кропак, а не тое, што ўнутры. Аддалены шлюз здымае гэты знешні загаловак і перасылае зыходны пакет у сваю лакальную сетку, дзе ён зноў звычайны пакет IPv6. Знешні тунель і ўнутраны трафік — дзве асобныя размовы, якія маюць агульны ключ, пару канчатковых кропак і болей нічога.

Два загалоўкі, два сямействы адрасоў

У рэжыме тунеля IPsec унутраны пакет IPv6 становіцца карыснай нагрузкай за загалоўкам ESP. Знешні загаловак, што нясе гэты пакет ESP, можа быць IPv4 або IPv6 і прытрымліваецца local_addrs і remote_addrs. WireGuard робіць тое ж з меншай цырымоніяй: унутраны пакет — карысная нагрузка дэйтаграмы UDP да канчатковай кропкі партнёра. Абодва пакідаюць унутраны загаловак некранутым, таму аддалены бок можа маршрутызаваць яго пасля дэкапсуляцыі.

Шлях паміж пляцоўкамі бачыць толькі UDP 4500, калі IPsec выкарыстоўвае праходжанне NAT, або UDP 51820 для слухача WireGuard па змаўчанні. Любы маршрутызатар на шляху можа быць толькі IPv4, і трафік IPv6 усё роўна праходзіць, бо на гэтым шляху ён ніколі не з'яўляецца як пакет IPv6. Гэта дае чыстае першае размежаванне: tcpdump -ni eth0 udp port 51820 паказвае зашыфраваны шлях, tcpdump -ni wg0 ip6 паказвае ўнутраны трафік. Заняты знешні запіс з маўклівым унутраным азначае, што ядро не змяшчае IPv6 у тунель; гэта маршрутызацыя або палітыка, а не стан канала.

Шлюз таксама змяншае ўнутраны Hop Limit падчас перасылання, таму канчатковыя кропкі лічацца маршрутызатарамі на шляху IPv6. Знешняя колькасць скачкоў і ўнутраны Hop Limit рухаюцца незалежна, і пакет, што гіне на аддаленым шлюзе, загінуў у перасыланні, а не ў шыфраванні.

Селектары і AllowedIPs — гэта спіс дазволаў

IKEv2 узгадняе, якія ўнутраныя прэфіксы можа несці child SA. На strongSwan 5.9 і навейшых іх явісты запіс у swanctl.conf выглядае так:

children {
  net6 {
    local_ts  = 2001:db8:aa::/48
    remote_ts = 2001:db8:bb::/48
    mode = tunnel
    esp_proposals = aes256gcm16-prfsha384-ecp384
    start_action = trap
  }
}

Калі апубсціць local_ts і remote_ts, strongSwan выводзіць іх з падсетак выбранага інтэрфейса. На вузле з dual-stack гэты кароткі шлях часта дае пару толькі IPv4: SA падымаецца, а IPv6 адхіляецца, не даходзячы да кода ESP. Явісты запіс абодвух прэфіксаў робіць SA здольным іх несці, і start_action = trap падымае яго на першым адпаведным пакеце.

У WireGuard адзін спіс выконвае дзве задачы. У блоку партнёра AllowedIPs = 2001:db8:bb::/48, fd00:bb::/48 — гэта і маршрут, што ўсталёўваецца пры адпраўленні, і фільтр, што ўжываецца пры прыёме: расшыфраваны пакет, унутраная крыніца якога выходзіць за межы спіса гэтага партнёра, ціха адкідваецца. wg-quick дадае маршрут для кожнага запісу, таму блоку партнёра ніжэй не патрэбная асобная каманда ip -6 route.

[Interface]
Address = 2001:db8:aa:ff::1/64, fd00:aa:ff::1/64
ListenPort = 51820

[Peer]
PublicKey = <site-b-public-key>
Endpoint = 203.0.113.20:51820
AllowedIPs = 2001:db8:bb::/48, fd00:bb::/48

Абодва спісы мусяць быць люстэркавымі: пляцоўка B прымае прэфікс пляцоўкі A як аддалены селектар і маршрутызуе яго назад, і тунель працуе толькі тады, калі абодва напрамкі супадаюць. Асіметрычны спіс дае сімптом, што з'ядае найбольш часу, — здаровы рукапаціск, лічыльнікі рухаюцца з аднаго боку, і ping з A у B, які праходзіць, тады як нішто з B не дасягае A.

Перасыланне, маршруты і зваротны прэфікс

Linux не перасылае IPv6, пакуль вы не скажаце, і налада дзейнічае на прастору імёнаў, а не на інтэрфейс:

sysctl -w net.ipv6.conf.all.forwarding=1
ip -6 route add 2001:db8:bb::/48 dev wg0
ip -6 route get 2001:db8:bb::10 from 2001:db8:aa::10

Другі радок — той, які забываюць у схемах на аснове маршрутаў. IPsec на аснове палітык усталёўвае палітыку XFRM, што адпавядае прэфіксам, але канфігурацыя на аснове маршрутаў з vti6 або WireGuard патрабуе сапраўднага маршруту IPv6, што ўказвае на гэты прыбор. Захавайце sysctl у /etc/sysctl.d/; інакш перазагрузка ціха верне перасыланне ў выключаны стан.

Перасыланне мае пабочны эфект, які варта ведаць: ядро тады ігнаруе аб'явы маршрутызатараў, калі net.ipv6.conf.<wan>.accept_ra не роўны 2, таму шлюз, чый адрас WAN прыходзіць праз SLAAC, можа страціць маршрут па змаўчанні ў тую хвіліну, калі вы ўключаеце перасыланне. Задайце accept_ra = 2 на гэтым інтэрфейсе ў тым самым файле, і маршрут выжыве. Ядро пляцоўкі B таксама мусяць навучыцца 2001:db8:aa::/48 ад шлюза тунеля — статычным маршрутам або пратаколам маршрутызацыі паверх тунеля, інакш адказ гіне ўнутры ўласнай сеткі B.

Праверка на чатыры крокі, якая лакалізуе паломку

Працуйце ў гэтым парадку і спыніцеся на першым кроку, які не ўдаўся, бо кожны наступны крок залежыць ад папярэдніх.

  1. Селектары: swanctl --list-sas павінен паказаць пару прэфіксаў IPv6 на child SA, або wg show wg0 allowed-ips аддалены прэфікс са свежым latest-handshakes.
  2. Маршрут ядра: ip -6 route get 2001:db8:bb::10 павінен адказаць прыборам тунеля, а не інтэрфейсам WAN.
  3. Унутраны запіс: tcpdump -ni wg0 ip6 падчас ping паміж сапраўднымі хостамі лакальнай сеткі. Пакеты, што выходзяць, але ніводзін не вяртаецца, указваюць на маршрут або брандмаўэр B; цалкам адсутнасць пакетаў указвае назад на крок 1 або 2.
  4. Прызначэнне: на хосце B ss -6 -ltn пацвярджае, што служба слухае на IPv6, а лакальныя лічыльнікі брандмаўэра паказваюць, ці пакет быў прыняты або адкінуты.

MTU належыць да таго самага праходу. Маршрутызатары IPv6 не фрагментуюць, таму завялікі пакет адкідваецца і Packet Too Big вяртаецца адпраўніку. Калі рукапаціскі і малыя ping працуюць, а перадача файла застравае, паменшыце карысную нагрузку, пакуль яна не пройдзе: ping -6 -s 1400 -c 3 2001:db8:bb::10. Інтэрфейсы WireGuard па змаўчанні маюць MTU 1420 байтаў, а IPsec паверх IPv4 аднімае болей, таму задаць унутраны MTU лепш, чым спадзявацца на выяўленне MTU шляху праз брандмаўэр, які адкідвае ICMPv6.

Рэжымы адмовы, падобныя да праблем з брандмаўэрам

Самы часты — зусім не брандмаўэр: служба прывязваецца да 0.0.0.0 замест ::, запіс AAAA існуе, і кліент атрымлівае хуткі адказ адмовы праз IPv6, які браўзер з dual-stack хавае, адкатваючыся на IPv4. Калі адмаўляюць толькі некаторыя праграмы, праверце сямейства слухання, перш чым кранаць набор правілаў.

Другі — фільтраванне ICMPv6. Neighbor Discovery і Packet Too Big — частка нармальнай працы, а не дыягностыкі, і палітыка, што адкідвае ўвесь ICMPv6, стварае тунель, які злучаецца, аўтэнтыфікуецца і потым застравае на ўсім, большым за маленькі пакет. Дазвольце тыпы, ад якіх залежыць шлях, і пакіньце лічыльнікі ўключанымі, каб адкідванне было бачна.

Трэці — прэфікс, даданы ў тунель, але ніколі — у план адрасоў пляцоўкі, якой ён належыць, таму ніводзін маршрутызатар яго не абвяшчае і ніводзін хост не можа адказаць з яго. Пачніце з аднаго прэфікса і адной пары хостаў, давядзіце абодва напрамкі чатырма крокамі, потым дадайце астатняе; зламаны прэфікс застаецца адным радком у канфігурацыі замест пераробкі. Адзіная афіцыйная спасылка, якую варта трымаць адкрытай, — RFC 8200, якая вызначае загаловак, што нясе тунель.

Падобныя артыкулы