Linux-ზე გადამისამართების ჩართვის შემდეგ IPv6-ის ნაგულისხმევი მარშრუტი გაქრა
როცა IPv6 გადამისამართება ჩართულია, ბირთვი უგულებელყოფს router advertisements-ებს uplink-ზე და ნასწავლი ნაგულისხმევი მარშრუტი ვადას ამოწურავს. გამოასწორეთ accept_ra-ით.
Debian-ის კარიბჭეზე დავაყენე net.ipv6.conf.all.forwarding=1, რათა მას VPN კლიენტების ტრაფიკი გადაეცა, და დაახლოებით ნახევარი საათის შემდეგ მანქანას IPv6-ის ნაგულისხმევი მარშრუტი აღარ ჰქონდა. ზედა მარშრუტიზატორი მუშაობდა, link-local მეზობელი კვლავ პასუხობდა და uplink კვლავ თავის გლობალურ მისამართს ინახავდა. შეწყდა ბირთვის სურვილი, კვლავ მიეღო router advertisements ამ ინტერფეისზე. მარშრუტი მაშინ არ გაქრა, როცა sysctl ჩავწერე; ის გაქრა მაშინ, როცა RA-დან ნასწავლი ნაგულისხმევი მარშრუტის ვადა ამოიწურა და ვერაფერმა არ განაახლა.
ერთი შეხედვით არაფერი ჩანდა გატეხილი. გადამისამართება მუშაობდა, კლიენტები გადიოდნენ, სანამ ძველი მარშრუტი ჯერ კიდევ ქეშში იყო, ხოლო ხარვეზი მოვიდა უფრო გვიან, ვიდრე ის ცვლილება, რომელმაც ის გამოიწვია. სწორედ ამ შეყოვნების გამო ამას ზედა მხარეს ან firewall-ის წესს მიაწერენ, რომელიც არასდროს ყოფილა ჩართული.
წაიკითხეთ მარშრუტების ცხრილი, სანამ რომელიმე sysctl-ს შეეხებით
დაიწყეთ ip -6 route show default-ით და წაიკითხეთ ატრიბუტები და არა მხოლოდ კარიბჭე. RA-დან ნასწავლი ნაგულისხმევი მარშრუტი აღნიშნულია proto ra-ით, ატარებს უპირატესობას და აჩვენებს expires-ის უკუთვლას. ხელით დამატებულ მარშრუტს არც ერთი აქვს და ეს განსხვავება გეუბნებათ, რომელი მექანიზმი ფლობს მარშრუტს.
$ ip -6 route show default
default via fe80::1 dev eth0 proto ra metric 1024 expires 1432sec hoplimit 64 pref mediumშემდეგ შეხედეთ მისამართს: ip -6 addr show dev eth0. გლობალური მისამართი საათებში გაზომილი სასურველი და ძალაში მყოფი ვადებით გადააჭარბებს ნაგულისხმევ მარშრუტს, რომლის მარშრუტიზატორის ვადა წუთებში იზომება. მისამართი არის, ნაგულისხმევი მარშრუტი კი არა, ეს გამოცხადებების პრობლემის ნიშანია. თუ მისამართიც არ არის, პირველ რიგში უნდა მოეკიდოთ ბმას, პრეფიქსის ინფორმაციას ან დუბლირებული მისამართების გამოვლენას.
რატომ თიშავს გადამისამართება RA-ს დამუშავებას
RA არის 134 ტიპის ICMPv6 პაკეტი, გაგზავნილი link-local წყაროდან 255 ჰოპის ზღვრით. სანამ ბირთვი მას გამოიყენებს, ამოწმებს ინტერფეისის accept_ra-ს. ნაგულისხმევი მნიშვნელობა არის 1 და 1 არ ნიშნავს დიახ-ს. ის ნიშნავს: მიიღე მხოლოდ მაშინ, სანამ ეს ჰოსტი არ გადასცემს. დააყენეთ forwarding=1 და ეს პირობა ვეღარ სრულდება, ამიტომ გამოცხადება იხურება მანამ, სანამ მასში რომელიმე პრეფიქსი ან ნაგულისხმევი მარშრუტიზატორი განიხილება.
არსებობს სამი მნიშვნელობა და გადამისამართებას მხოლოდ მესამე გადაურჩება:
accept_ra | forwarding=0 | forwarding=1 |
|---|---|---|
| 0 | ignored | ignored |
| 1 (default) | accepted | ignored |
| 2 | accepted | accepted |
კიდევ ორი დროშა წყვეტს, რა დამონტაჟდება სინამდვილეში. accept_ra_defrtr აკონტროლებს, გახდება თუ არა გამოცხადებაში მოცემული ნაგულისხმევი მარშრუტიზატორი მარშრუტად, ხოლო accept_ra_pinfo აკონტროლებს, გამოყენებული იქნება თუ არა პრეფიქსის ინფორმაცია მისამართის კონფიგურაციისთვის. accept_ra_defrtr-ის გამორთვა ჩვეულებრივი გზაა, რომ გადამცემ ჰოსტზე SLAAC მისამართები შეინარჩუნოთ ნაგულისხმევი მარშრუტის სწავლის გარეშე. ეს სხვა ბერკეტია, ვიდრე accept_ra, და მას მიმართავთ მაშინ, როცა მისამართები გინდათ, მარშრუტი კი არა. ბირთვის IP sysctl-ის საცნობარი სამივეს ჩამოთვლის.
დაადასტურეთ სამი ბრძანებით
ჯერ წაიკითხეთ ცოცხალი მნიშვნელობები და არა ის ფაილი, რომელიც გგონიათ, რომ ჩატვირთულია:
sysctl net.ipv6.conf.eth0.forwarding net.ipv6.conf.all.forwarding \
net.ipv6.conf.eth0.accept_ra net.ipv6.conf.eth0.accept_ra_defrtrმეორეც, დაამტკიცეთ, რომ გამოცხადებები კვლავ მოდის. ICMPv6-ის ტიპის ბაიტით ფილტრაცია საკმარისია და გიხსნით მეზობლების აღმოჩენის ტრაფიკის კედლის კითხვისგან:
tcpdump -ni eth0 'icmp6 and ip6[40] == 134'თუ რამდენიმე წუთში არაფერი გამოჩნდა, accept_ra თქვენი პრობლემა არ არის. ზედა მხარემ გამოცხადება შეწყვიტა, გზაზე რაღაც ICMPv6-ს ფილტრავს, ან ეს ინტერფეისი ნამდვილად არ არის იმ სეგმენტში, რომელზეც ფიქრობთ. მესამეც, თავად მოითხოვეთ გამოცხადება და წაიკითხეთ მისი ველები:
rdisc6 eth0rdisc6 Debian-სა და Ubuntu-ზე ndisc6 პაკეტში მოდის. გამოსავალში შეხედეთ მარშრუტიზატორის ვადას და უპირატესობას, სანამ სხვა რამეს შეცვლით. გამოცხადება მარშრუტიზატორის ვადით 0 არის ბრძანება ნაგულისხმევი მარშრუტიზატორის მოცილების შესახებ და არც ერთი accept_ra-ის მნიშვნელობა არ აქცევს მას გამოსადეგ მარშრუტად. ასევე დაიჭერთ ხიდის რეჟიმში მყოფ ზედა CPE-ს, რომელიც პრეფიქსებს არიგებს, მაგრამ თავს მარშრუტიზატორად არასდროს გვთავაზობს.
აქციეთ uplink ერთადერთ დამთმენ ინტერფეისად
თუ ზედა მხარე ნაგულისხმევი მარშრუტიზატორი უნდა იყოს, მიიღეთ გამოცხადებები იქ, გადამისამართების მიუხედავად, და სხვაგან არსად:
# /etc/sysctl.d/60-ipv6-router.conf
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.eth0.accept_ra = 2
net.ipv6.conf.eth0.accept_ra_defrtr = 1შეზღუდვა მნიშვნელოვანია, რადგან Linux-ში IPv6 გადამისამართება ერთი გლობალური გადამრთველია და არა ერთი თითო ბმაზე. ჩაწერეთ 1 net.ipv6.conf.wg0.forwarding-ში და შემდეგ წაიკითხეთ net.ipv6.conf.all.forwarding: გლობალური მნიშვნელობა იბრუნებს და ყველა ინტერფეისი იწყებს გადაცემას. თქვენ არ შეგიძლიათ იყოთ მარშრუტიზატორი გვირაბში და ჩვეულებრივი ჰოსტი LAN-ში. შეზღუდვა შეგიძლიათ მხოლოდ მიღებას. დაიტოვეთ accept_ra=2 uplink-ზე, ხოლო გვირაბისა და LAN-ის ინტერფეისები დატოვეთ 1 ან 0-ზე, რათა გვირაბიდან მოსულმა დაკარგულმა გამოცხადებამ ვერ დააყენოს მასში მიმართული ნაგულისხმევი მარშრუტი.
დროებითი sysctl -w გადატვირთვას ვერ გადაურჩება, ხოლო systemd-networkd და NetworkManager ორივე ამ მნიშვნელობებს საკუთარი კონფიგურაციიდან წერენ. networkd-ში დააყენეთ IPv6Forwarding=yes და IPv6AcceptRA=yes uplink-ის .network ფაილში; networkd IPv6Forwarding-ს გლობალურად აღწერს ბირთვში იმავე მიზეზით. NetworkManager-ის შემთხვევაში სწორედ uplink-ზე ipv6.method=auto მართავს accept_ra-ს მნიშვნელობას, ამიტომ nmcli connection up-ის შემდეგ ხელახლა წაიკითხეთ sysctl და ნუ დაეყრდნობით პირველ შემოწმებას.
სტატიკური ალტერნატივა, ip -6 route add default via fe80::1 dev eth0, ნამდვილად მუშაობს და გონივრული პასუხია, როცა ზედა მარშრუტიზატორს სტაბილური link-local მისამართი აქვს. ნათლად იცოდეთ, რას თმობთ. სტატიკური ნაგულისხმევი მარშრუტი არასდროს განახლდება და არასდროს უქმდება, ამიტომ ზედა მხარის შეცვლის შემდეგაც მკვდარ მეზობელზე მიუთითებს. RA-ს მარშრუტი უსაფრთხოდ ფუჭდება; სტატიკური კი ჩუმად ფუჭდება.
შეამოწმეთ გადაცემული პაკეტი და არა თავად კარიბჭის პაკეტი
კარიბჭის საკუთარი პინგები შეიძლება წარმატებით გაიაროს მარშრუტზე, რომელსაც ვერც ერთი კლიენტი ვერ გამოიყენებს, და ასევე იმიტომაც წარმატდება, რომ კარიბჭე წყაროა. შეამოწმეთ დაკავშირებული კლიენტიდან და შემდეგ ჰკითხეთ კარიბჭეს, რას გააკეთებდა იმ კლიენტის მისამართისთვის:
# on the VPN client
ping -6 -c 3 2001:4860:4860::8888
# on the gateway, using a client address
ip -6 route get 2001:4860:4860::8888 from fd42:20::2შემდეგ დაელოდეთ ერთ მარშრუტიზატორის ვადას და კვლავ შეხედეთ. სტაბილური მდგომარეობა, რომელიც გსურთ, არის proto ra-ით აღნიშნული ნაგულისხმევი მარშრუტი, რომლის expires მნიშვნელობა მუდამ ახლდება, პლუს all.forwarding=1. თუ expires მხოლოდ ითვლის უკუსვლით, გამოცხადებები კვლავ სადღაც იხურება და ჩვეულებრივი დამნაშავე ქსელის მენეჯერია, რომელიც accept_ra-ს გადაწერს მას შემდეგ, რაც ჩატვირთვისას sysctl უკვე შესრულდა.
სანამ ამას დახურავთ, დაადასტურეთ ოთხი რამ: ნაგულისხმევი მარშრუტი არის proto ra და ახლდება, accept_ra=2 მხოლოდ uplink-ს ეხება, გადამისამართება ჯერ კიდევ 1-ია გადატვირთვის შემდეგ და მენეჯერის გადატვირთვის შემდეგ, და IPv6-ის პინგს კლიენტი ასრულებს და არა კარიბჭე. თუ კლიენტი ჯანსაღი მარშრუტით მაინც ვერ ახერხებს, შემდეგი ეჭვმიტანილი უკუგზა ან ზედა firewall-ია, და არა გამოცხადება.