Δύο εικονικές μηχανές στον ίδιο κεντρικό υπολογιστή φτάνουν στο LAN μέσω γέφυρας, και ένας κανόνας στην αλυσίδα ip forward δείχνει μετρητή που δεν κινείται ποτέ. Τα πλαίσια είναι πραγματικά, η κίνηση περνά, και ο κανόνας απλώς δεν βρίσκεται στη διαδρομή της. Η σύγκριση των δύο τρόπων με τους οποίους το Linux εκθέτει την κίνηση μέσω γέφυρας εξηγεί αυτή τη σιωπή, και εξηγεί επίσης γιατί η φόρτωση ενός παλιού module είναι χειρότερη απάντηση απ' ό,τι φαίνεται.

Δύο διαδρομές μέσα από έναν κεντρικό υπολογιστή

Ένα πακέτο μπορεί να εγκαταλείψει αυτόν τον κεντρικό υπολογιστή με δύο πολύ διαφορετικούς τρόπους, και η διαφορά καθορίζει ποια hooks θα το δουν. Αν ο προορισμός βρίσκεται πέρα από μια φυσική θύρα και το πλαίσιο μεταγωγίζεται ανάμεσα σε δύο θύρες της γέφυρας, ο κεντρικός υπολογιστής προωθεί ένα πλαίσιο Ethernet· ο κώδικας δρομολόγησης δεν ερωτάται, και δεν συμβαίνει κανένα δρομολογημένο άλμα. Αν ο προορισμός είναι ο ίδιος ο κεντρικός υπολογιστής, ή ένα δίκτυο που φτάνει μέσω διεπαφής σήραγγας, το πακέτο δρομολογείται και τα hooks του επιπέδου IP εφαρμόζονται πράγματι. Κρατήστε αυτό το δίχασμα στο μυαλό σας, γιατί κάθε επόμενη ερώτηση για αλυσίδες και οικογένειες προκύπτει από το ποια από τις δύο διαδρομές ακολουθεί ένα πλαίσιο.

Αυτή η διάκριση είναι όλη η ιστορία πίσω από έναν κανόνα που δεν μετρά τίποτα. Ένα πλαίσιο μέσω γέφυρας από veth9a1 προς enp3s0 διασχίζει τη γέφυρα, όχι τη στοίβα IP, οπότε μια αλυσίδα ip forward δεν βλέπει τίποτα για αντιστοίχιση. Τα ονόματα διεπαφών σε ένα παλαιότερο παράδειγμα δεν καθορίζουν ποια διαδρομή έχετε, και γι' αυτό το πρώτο βήμα είναι να κοιτάξετε την τοπολογία και όχι το σύνολο κανόνων.

Μια σήραγγα προσθέτει μια τρίτη περίπτωση που αξίζει όνομα. Μια συσκευή TUN παραδίδει πακέτα IP στον κεντρικό υπολογιστή, οπότε αυτά δρομολογούνται και διασχίζουν πράγματι αλυσίδες IP, ενώ μια συσκευή TAP συνδεδεμένη σε γέφυρα παραδίδει πλαίσια και συμπεριφέρεται όπως η περίπτωση της γέφυρας. Ο τύπος της συσκευής, όχι το όνομα του προϊόντος, αποφασίζει.

Συγκρίνετε τις δύο οικογένειες που μπορούν να δουν ένα πλαίσιο μέσω γέφυρας

Το Linux υποστηρίζει εγγενές φιλτράρισμα γέφυρας μέσω της οικογένειας bridge του nftables, και δεν χρειάζεται κανένα παλιό module για να εξετάζει και να απορρίπτει πλαίσια εν κινήσει. Η ίδια η τεκμηρίωση της γέφυρας του πυρήνα δίνει αυτή τη σύσταση απευθείας, κάτι που αξίζει να το γνωρίζετε πριν ένα αποτέλεσμα αναζήτησης σας πει να φορτώσετε ένα module.

Observation pointWhat it seesWhat it costs
nftables bridge family chainsEthernet frames forwarded between bridge ports, in both directionsRules must be written in bridge syntax with link-layer matches
Legacy br_netfilter plus an ip chainBridged IPv4 and IPv6 packets, re-exposed through IP-layer hooksExisting host rules may begin matching traffic they never saw before
inet chain for routed trafficPackets the host routes, including traffic arriving from a TUN deviceNo visibility into purely switched frames

Η χρήση της εντολής nft αντί του iptables δεν τοποθετεί από μόνη της έναν κανόνα στη σωστή οικογένεια. Μια αλυσίδα που δηλώνεται στην οικογένεια bridge βλέπει πλαίσια· μια αλυσίδα που δηλώνεται σε ip, ip6 ή inet δεν βλέπει, ανεξάρτητα από το ποιο δυαδικό την έφτιαξε. Η οικογένεια είναι ιδιότητα της αλυσίδας, όχι του εργαλείου που την πληκτρολόγησε.

Η παλιά διαδρομή λειτουργεί διαφορετικά, και γι' αυτό αξίζει να συγκρίνετε αντί να διαλέγετε πλευρά από συνήθεια. Η φόρτωση του br_netfilter και η ενεργοποίηση των ρυθμίσεων bridge-nf-call εκθέτει ξανά την κίνηση IPv4 και IPv6 μέσω γέφυρας στα hooks του επιπέδου IP, ώστε ένας συνηθισμένος κανόνας iptables να μπορεί επιτέλους να την αντιστοιχίσει. Τα πλαίσια δεν αλλάζουν· αλλάζει το σύνολο των hooks που διασχίζουν, πράγμα που σημαίνει ότι κάθε υπάρχων κανόνας του κεντρικού υπολογιστή έχει τώρα νέο κοινό.

Διαβάστε την πραγματική διαδρομή πριν προσθέσετε κανόνα

Τρεις εντολές καθορίζουν πού βρίσκεστε: σε τι είναι συνδεδεμένη η γέφυρα, αν το παλιό module είναι ενεργό, και ποιες αλυσίδες υπάρχουν ήδη στην οικογένεια bridge. Εκτελέστε τις πριν γράψετε οτιδήποτε, γιατί η απάντηση καθορίζει ποιο από τα δύο σχέδια επεκτείνετε. Το να παραλείψετε αυτό το βήμα είναι ο τρόπος με τον οποίο ένας σωστός κανόνας καταλήγει σε μια αλυσίδα που τίποτα δεν διασχίζει.

bridge link show
lsmod | grep br_netfilter
nft list ruleset | grep -A4 "chain forward"

Η έξοδος χωρίζει τις περιπτώσεις καθαρά. Οι θύρες που εμφανίζονται κάτω από τη γέφυρα σας λένε ποιες διεπαφές μεταγωγίζονται· ένα κενό αποτέλεσμα lsmod σημαίνει καμία ορατότητα στο επίπεδο IP των πλαισίων μέσω γέφυρας· μια υπάρχουσα αλυσίδα forward της οικογένειας bridge σημαίνει ότι υπάρχει ήδη κάτοχος πολιτικής και ο κανόνας σας ανήκει εκεί και όχι σε μια νέα δική του αλυσίδα.

Στη συνέχεια προσθέστε έναν κανόνα που διαβάζεται εύκολα πίσω, με μετρητή και χωρίς αλλαγή της ετυμηγορίας, και στείλτε μία αντιπροσωπευτική ροή μέσα από τη γέφυρα. Ένας μετρητής που κινείται αποδεικνύει ότι το πλαίσιο έφτασε στον κανόνα. Αυτό είναι το μόνο που αποδεικνύει, γι' αυτό συνεχίστε και με τη διαδρομή απόρριψης, αφού μια πολιτική που δέχεται τα πάντα παράγει επίσης κινούμενο μετρητή.

nft add rule bridge filter forward iifname "veth9a1" oifname "enp3s0" counter accept

Πού το παλιό module αλλάζει συμπεριφορά

Η ενεργοποίηση της παλιάς διαδρομής σε μια γέφυρα που λειτουργεί δεν είναι ουδέτερη πράξη προσθήκης ορατότητας. Κανόνες που ήταν προηγουμένως απρόσιτοι για κίνηση μέσω γέφυρας γίνονται προσβάσιμοι, μαζί με κανόνες του κεντρικού υπολογιστή που γράφτηκαν για άλλη διεπαφή, και μια προεπιλεγμένη πολιτική drop στην αλυσίδα ip forward μπορεί ξαφνικά να εφαρμοστεί σε πλαίσια που περνούσαν ανέγγιχτα. Σε έναν κεντρικό υπολογιστή που διαχειρίζεστε μέσω αυτής της γέφυρας, το αποτέλεσμα είναι αποκλεισμός χωρίς κονσόλα. Δεν είναι υποθετικός τρόπος αποτυχίας· είναι η συνηθισμένη συνέπεια του να διευρύνετε ένα σύνολο hooks σε ένα μηχάνημα που προσεγγίζετε μέσω της διαδρομής που μόλις διευρύνατε.

Η ασφαλέστερη σειρά είναι να αποφασίσετε ποια οικογένεια κατέχει την πολιτική, να γράψετε εκεί τους κανόνες, και να κρατήσετε μια ανεξάρτητη διαδρομή ανάκτησης πριν αλλάξετε οποιοδήποτε sysctl. Αν δύο οικογένειες κρατούν κανόνες, τεκμηριώστε ποια είναι η αυθεντία· δύο επικαλυπτόμενες πολιτικές είναι ο τρόπος με τον οποίο ένα πακέτο γίνεται δεκτό σε ένα σημείο και απορρίπτεται σε άλλο χωρίς ένα αρχείο να διαβάσετε.

Η απομόνωση από μόνη της χρειάζεται ακόμη πλήρη σχεδιασμό. Το να επιτρέπεται μία πηγή προς έναν προορισμό αποδεικνύει μόνο ότι μία ροή λειτουργεί, ενώ η απαίτηση συνήθως είναι μια VM να μην μπορεί να φτάσει τους γείτονές της ή τον κεντρικό υπολογιστή. Οι μετρητές στους κανόνες άρνησης έχουν μεγαλύτερη σημασία από τον μετρητή στον κανόνα αποδοχής, γιατί ο μετρητής αποδοχής είναι αυτός που περιμένατε ήδη να κινηθεί.

Τέλος, κρατήστε την περίπτωση εισόδου του κεντρικού υπολογιστή ξεχωριστά. Η κίνηση που απευθύνεται στη δική του IP της γέφυρας φτάνει στο input, όχι στο forward, και ένας κανόνας στο forward δεν θα τη δει ποτέ, όποια οικογένεια κι αν επιλέξετε. Τρεις περιπτώσεις, δύο οικογένειες, ένα δίδαγμα: η διαδρομή καθορίζει το hook, και το hook καθορίζει αν ο κανόνας σας υπάρχει καθόλου.

Σχετικά άρθρα