Η προεπιλεγμένη διαδρομή IPv6 εξαφανίστηκε μετά την ενεργοποίηση της προώθησης στο Linux
Όταν ενεργοποιείται η προώθηση IPv6, ο πυρήνας αγνοεί τα router advertisements στο uplink και η προεπιλεγμένη διαδρομή που έμαθε λήγει. Διορθώστε το με accept_ra.
Έθεσα το net.ipv6.conf.all.forwarding=1 σε μια πύλη Debian ώστε να μπορεί να προωθεί την κίνηση των πελατών VPN, και περίπου μισή ώρα αργότερα το μηχάνημα δεν είχε πλέον καμία προεπιλεγμένη διαδρομή IPv6. Ο δρομολογητής ανάντη ήταν ζωντανός, ο γείτονας link-local απαντούσε ακόμη, και το uplink κρατούσε ακόμη τη γενική του διεύθυνση. Αυτό που είχε σταματήσει ήταν η προθυμία του πυρήνα να δέχεται ακόμη router advertisements σε εκείνη τη διεπαφή. Η διαδρομή δεν εξαφανίστηκε όταν πληκτρολόγησα το sysctl; εξαφανίστηκε όταν έληξε η διάρκεια ζωής της προεπιλεγμένης διαδρομής που είχε μάθει από το RA και τίποτα δεν την ανανέωσε.
Με την πρώτη ματιά τίποτα δεν φαινόταν χαλασμένο. Η προώθηση λειτουργούσε, οι πελάτες περνούσαν όσο η παλιά διαδρομή ήταν ακόμη στην προσωρινή μνήμη, και η αποτυχία ήρθε αργότερα από την αλλαγή που την προκάλεσε. Αυτή η καθυστέρηση είναι ο λόγος που το πρόβλημα χρεώνεται στην ανάντη πλευρά ή σε έναν κανόνα τείχους προστασίας που δεν είχε ποτέ εμπλακεί.
Διαβάστε τον πίνακα δρομολόγησης πριν αγγίξετε οποιοδήποτε 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 είναι πακέτο ICMPv6 τύπου 134, που αποστέλλεται από πηγή 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Δεύτερον, αποδείξτε ότι οι αναγγελίες φτάνουν ακόμη. Το φιλτράρισμα με βάση το byte τύπου ICMPv6 αρκεί, και σας γλιτώνει από το διάβασμα ενός τοίχου κίνησης ανακάλυψης γειτόνων:
tcpdump -ni eth0 'icmp6 and ip6[40] == 134'Αν δεν εμφανιστεί τίποτα για αρκετά λεπτά, το accept_ra δεν είναι το πρόβλημά σας. Η ανάντη πλευρά σταμάτησε να αναγγέλλει, κάτι στη διαδρομή φιλτράρει ICMPv6, ή αυτή η διεπαφή δεν είναι πραγματικά στο τμήμα που νομίζετε. Τρίτον, ζητήστε μόνοι σας μια αναγγελία και διαβάστε τα πεδία της:
rdisc6 eth0Το rdisc6 παρέχεται στο πακέτο ndisc6 σε Debian και Ubuntu. Στην έξοδο, κοιτάξτε τη διάρκεια ζωής δρομολογητή και την προτίμηση πριν αλλάξετε οτιδήποτε άλλο. Μια αναγγελία με διάρκεια ζωής δρομολογητή 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Η οριοθέτηση έχει σημασία γιατί η προώθηση IPv6 στο Linux είναι ένας γενικός διακόπτης, όχι ένας ανά σύνδεσμο. Γράψτε 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 στο αρχείο .network του uplink; το networkd τεκμηριώνει το IPv6Forwarding ως γενικό για τον ίδιο λόγο του πυρήνα. Με το NetworkManager, το ipv6.method=auto στο uplink είναι αυτό που οδηγεί την τιμή accept_ra, οπότε ξαναδιαβάστε το sysctl μετά το nmcli connection up αντί να εμπιστευτείτε τον πρώτο έλεγχο.
Η στατική εναλλακτική, το ip -6 route add default via fe80::1 dev eth0, λειτουργεί πράγματι, και είναι λογική απάντηση όταν ο ανάντη δρομολογητής έχει σταθερή διεύθυνση link-local. Να ξέρετε καθαρά τι παραχωρείτε. Μια στατική προεπιλεγμένη διαδρομή δεν ανανεώνεται ποτέ και δεν αποσύρεται ποτέ, άρα συνεχίζει να δείχνει σε νεκρό γείτονα αφού αντικατασταθεί η ανάντη πλευρά. Η διαδρομή από RA αποτυγχάνει με ασφάλεια; η στατική αποτυγχάνει σιωπηλά.
Δοκιμάστε ένα προωθημένο πακέτο, όχι αυτό της ίδιας της πύλης
Τα ping της ίδιας της πύλης μπορούν να πετύχουν σε μια διαδρομή που κανένας πελάτης δεν μπορεί να χρησιμοποιήσει, και μπορούν να πετύχουν και επειδή η πύλη είναι η πηγή. Δοκιμάστε από συνδεδεμένο πελάτη και μετά ρωτήστε την πύλη τι θα έκανε για τη διεύθυνση αυτού του πελάτη:
# 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 μετά από επανεκκίνηση και μετά από επανεκκίνηση του διαχειριστή, και ένας πελάτης, όχι η πύλη, ολοκληρώνει ένα ping IPv6. Αν ο πελάτης εξακολουθεί να αποτυγχάνει με υγιή διαδρομή, ο επόμενος ύποπτος είναι η διαδρομή επιστροφής ή ένα ανάντη τείχος προστασίας, όχι η αναγγελία.