როდესაც საიტებს შორის გვირაბს IPv6 პრეფიქსს დაუმატებთ, პაკეტი ისე არ მოძრაობს, როგორც დიაგრამა მიუთითებს. ლოკალური გეიტვეი იღებს მთელ IPv6 პაკეტს, შიფრავს მას და წინ უდგამს გარეგან IP თავსართს, რომლის მისამართების ოჯახსაც არა შიგნით არსებული, არამედ საბოლოო წერტილების მისამართები განსაზღვრავს. დისტანციური გეიტვეი ამოიღებს ამ გარეგან თავსართს და ორიგინალურ პაკეტს თავის LAN-ზე გადაგზავნის, სადაც ის ისევ ჩვეულებრივი 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-ს არ გადაგზავნის, სანამ არ ეტყვით, და პარამეტრი interface-ს არა, namespace-ს ეხება:

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

მეორე სტრიქონი ისაა, რასაც route-ზე დაფუძნებულ დიზაინებში ხდება დავიწყებული. პოლიტიკაზე დაფუძნებული IPsec პრეფიქსებს შემეძრებული XFRM პოლიტიკს დამონტაჟებს, მაგრამ vti6 საან WireGuard-იან route-ზე დაფუძნებულ კონფიგურაციას რეალური IPv6 მარშრუტი სჭირდება მის მიმართ. sysctl /etc/sysctl.d/-ის ქვემოთ შეინახეთ; სხვა შემთხვევაში restart გადაგზავნას ჩუმად გამორთულ მდგომარეობას დაუბრუნებს.

გადაგზავნას აქვს გვარ-ეფექტი, რომელიც ღირს იცოდეთ: კერნელი მაშინ უგულვებელყოფს მარშრუტიზატორის განცხადებებს, თუ net.ipv6.conf.<wan>.accept_ra 2 არ არის, ამიტომ გეიტვეი, რომლის WAN მისამართი SLAAC-ით მოდის, შესაძლოა სტანდარტულ მარშრუტს დაკარგვის გადაგზავნის ჩართვის წამს. ამ ინტერფეისზე accept_ra = 2 იმავე ფაილში დააყენეთ და მარშრუტი გადაუვლის. B-ის საიტის კერნელმაც უნდა ისწავლოს 2001:db8:aa::/48 გვირაბის გეიტვეიდან — static route-ით ან გვირაბის ზემოთ მარშრუტიზაციის პროტოკოლით, სხვა შემთხვევაში პასუხი 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 ნამდვილ LAN ჰოსტებს შორის. პაკეტები, რომლებიც გადადიან, მაგრამ ვერც ერთი არ დაბრუნდა, 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 ინტერფეისებს სტანდარტულად 1420 ბაიტი MTU-ია, და IPv4-ის ზემოთ IPsec მეტს აკუჭებს, ამიტომ შიდა MTU-ის დაყენება ICMPv6-ის ჩამსრულებელ ფაიერვოლს გავლით MTU-ის აღმოჩენის იმედის უფრო ღირსეულია.

ფაიერვოლის პრობლემების მსგავსი ჩავარდნის რეჟიმები

ყველაზე გავრცელებული საერთოდ არა ფაიერვოლია: სერვისი 0.0.0.0-ს იკავებს ::-ის ნაცვლად, AAAA ჩანაწერი არსებობს, და კლიენტი IPv6-ზე სწრაფ უარყოფას იღებს, რომელსაც dual-stack ბრაუზერი IPv4-ზე დაბრუნებით ფართობს. თუ მხოლოდ ზოგიერთი აპლიკაცია ჩავარდა, მსმენ ოჯახი შეინარჩუნეთ რეგულების ნაკრების შეყლებამდე.

მეორე ICMPv6-ის ფილტრიზაციაა. Neighbor Discovery და Packet Too Big ნორმალური მუშაობის ნაწილია, არა დიაგნოსტიკისა, და პოლიტიკა, რომელიც ყველა ICMPv6-ს ჩამას, იძლევა გვირაბს, რომელიც ირთვება, ადასტურებდა და შემდეგ წყდება ყველაფერზე მსხვილზე. დაუშვათ ტიპები, რომლებზეც გზა არის დამოკიდებული, და მრაქოვიები მისთვის ჩართული დატოვეთ, რომ ჩაგდება შეინიშნოს.

მესამე არის პრეფიქსი, რომელიც გვირაბს ემატება, მაგრამ არასდროს — იმ საიტის მისამართების გეგმას, რომელსაც ეკუთვნის, ამიტომ არც ერთი მარშრუტიზატორი არ აცხადებს მას და არც ერთი ჰოსტი არ შეიტანს პასუხს მისგან. დაიწყეთ ერთი პრეფიქსით და ერთი ჰოსტების წყვილით, დაამტკიცეთ ორივე მიმდინარეობა ოთხი ეტაპით, შემდეგ დაამატეთ დარჩენილი; დაზიანებული პრეფიქსი რჩება კონფიგურაციის ერთ სტრიქონად, აღდგენის ნაცვლად. ერთადერთი ოფიციალური წყარო, რომელიც ღირს ღია შეიტანოს, არის RFC 8200, რომელიც განსაზღვრავს თავსართს, რომელსაც გვირაბი ატარებს.

დაკავშირებული სტატიები