Οι κανόνες για τις θύρες 80 και 443 δεν στέλνουν το πρόγραμμα περιήγησης μέσα από VPN
Μια αντιστοίχιση θύρας επιλέγει ροές TCP, όχι ένα πρόγραμμα περιήγησης. Το HTTP/3 τρέχει πάνω σε UDP, το DNS μπορεί να πάρει άλλη διαδρομή και ένα πρόγραμμα ενημέρωσης ταιριάζει στον ίδιο κανόνα που γράψατε.
Κάποιος ζητά το πρόγραμμα περιήγησης να χρησιμοποιεί τη σήραγγα, και το αίτημα επιστρέφει ως κανόνας τείχους προστασίας που αντιστοιχεί στις θύρες προορισμού 80 και 443. Φαίνεται ακριβής και δεν είναι. Μια αντιστοίχιση θύρας επιλέγει πακέτα από την κεφαλίδα μεταφοράς τους, όχι από το ποιο πρόγραμμα άνοιξε την υποδοχή, και η σύγχρονη περιήγηση δεν περιορίζεται σε αυτές τις δύο θύρες στο TCP. Ο κανόνας θα χάσει κίνηση που θέλατε να συμπεριλάβετε και θα πιάσει κίνηση που δεν σκοπεύατε ποτέ να αγγίξετε. Πριν τον γράψετε, αποφασίστε ποιο από τα τρία διαφορετικά όρια θέλετε πραγματικά.
Ο κανόνας περιγράφει μια κλάση μεταφοράς, όχι μια εφαρμογή
Στο Linux, μια αντιστοίχιση θύρας προορισμού εξετάζει την κεφαλίδα TCP και τίποτα πάνω από αυτήν. Η σήμανση αυτών των πακέτων και η καθοδήγησή τους με διαδρομή πολιτικής λειτουργεί ακριβώς όπως τεκμηριώνεται, και κανένας από αυτούς τους μηχανισμούς δεν γνωρίζει τι σημαίνει το ωφέλιμο φορτίο ή ποια διεργασία το έστειλε. Η σήμανση είναι ένας αριθμός προσκολλημένος σε ένα πακέτο, όχι μια ταυτότητα προσκολλημένη σε μια εφαρμογή.
nft add rule inet mangle output tcp dport { 80, 443 } meta mark set 0x1
ip rule add fwmark 0x1 table 100
ip route add default dev wg0 table 100
Δύο συνέπειες ακολουθούν αμέσως. Ένα πρόγραμμα ενημέρωσης λογισμικού που επικοινωνεί με TCP 443 δέχεται την ίδια μεταχείριση με το πρόγραμμα περιήγησης, κάτι που μπορεί να είναι εντάξει ή μπορεί να είναι μια διακοπή που περιμένει τον επόμενο κύκλο ενημέρωσης. Και μια υπηρεσία ιστού που δημοσιεύεται σκόπιμα σε άλλη θύρα, ας πούμε 8443, πέφτει εντελώς έξω από τον κανόνα, ενώ παραμένει η κίνηση ιστού που απασχολούσε τον χρήστη.
Οι αριθμοί είναι νόμιμοι επιλογείς όταν η απαίτηση αφορά πραγματικά αυτές τις θύρες. Γίνονται μυθοπλασία όταν στο αίτημα γράφεται «πρόγραμμα περιήγησης» και στο σύνολο κανόνων υλοποιείται ένα εύρος θυρών. Αυτό το χάσμα δεν είναι λεπτομέρεια τεκμηρίωσης. Είναι η διαφορά ανάμεσα σε έναν κανόνα που μπορείτε να υπερασπιστείτε σε μια ανασκόπηση και σε έναν που κανείς δεν μπορεί να δοκιμάσει.
Το HTTP/3 αφήνει ήσυχα πίσω τον κανόνα σας για TCP
Το HTTP/3 τρέχει πάνω σε QUIC, και το QUIC μεταφέρεται σε UDP. Ένας κανόνας που αντιστοιχεί μόνο σε TCP δεν μπορεί να το δει, οπότε το ίδιο πρόγραμμα περιήγησης που ικανοποιεί τη σελίδα δοκιμής σας μπορεί να στείλει μεταγενέστερο αίτημα μέσω UDP και να παρακάμψει τη σήραγγα, χωρίς κανείς να αλλάξει ρύθμιση. Το RFC 9114 περιγράφει το HTTP/3 ως πρωτόκολλο βασισμένο στο QUIC, και το QUIC χρησιμοποιεί UDP με προεπιλεγμένη θύρα 443 στην κοινή ανάπτυξη.
Το αν ένα δεδομένο πρόγραμμα περιήγησης θα δοκιμάσει HTTP/3 εξαρτάται από τη διαμόρφωσή του, από τον ιστότοπο και από το αν μια προηγούμενη προσπάθεια πέτυχε. Αυτό το κάνει κακό πράγμα για συλλογισμό από μνήμης. Ρωτήστε το εργαλείο αντ' αυτού:
curl --http3 -sS -o /dev/null -w '%{http_version} %{time_total}\n' https://example.com
ss -tunp | grep -E ':443\b'
Η γραμμή curl εκτυπώνει την έκδοση που διαπραγματεύτηκε, οπότε ένα 3 επιβεβαιώνει ότι χρησιμοποιήθηκε η διαδρομή UDP. Η λίστα υποδοχών δείχνει έπειτα αν αυτή η σύνδεση είναι δεσμευμένη στη διεπαφή της σήραγγας ή στη φυσική. Αν το HTTP/3 δεν είναι διαθέσιμο στην κατασκευή curl σας, η σημαία αποτυγχάνει ηχηρά αντί να υποχωρήσει σιωπηλά, που είναι η δική της μικρή χάρη.
Το DNS είναι μια ξεχωριστή απόφαση που πρέπει να πάρετε
Ένας κανόνας θύρας για κίνηση ιστού δεν λέει τίποτα για την επίλυση ονομάτων. Το πρόγραμμα περιήγησης μπορεί να χρησιμοποιήσει τον επιλυτή του συστήματος, έναν επιλυτή ρυθμισμένο μέσα στο πρόγραμμα περιήγησης ή έναν που έσπρωξε η τελευταία σύνδεση. Καθένας από αυτούς μπορεί να στέλνει ερωτήματα από διαφορετική διαδρομή από αυτήν που επιλέγει ο κανόνας σας, κάτι που παράγει τον κλασικό διχασμό: η σελίδα φορτώνει, το όνομα επιλύεται κάπου που δεν περιμένατε, και ο εσωτερικός ιστότοπος επιλύεται σε δημόσια διεύθυνση ή καθόλου.
Αποφασίστε το ρητά. Αν τα εσωτερικά ονόματα πρέπει να επιλύονται μέσω της σήραγγας, ο επιλυτής πρέπει να είναι μέσα σε αυτήν, και το σύνολο κανόνων πρέπει να επιτρέπει DNS προς αυτόν τον επιλυτή κρατώντας έξω τα άλλα ερωτήματα. Αν το πρόγραμμα περιήγησης χρησιμοποιεί DNS over HTTPS προς δημόσιο πάροχο, το ερώτημα παρακάμπτει εντελώς τον επιλυτή σας και ο κανόνας θύρας δεν μπορεί να βοηθήσει. Γράψτε την επιλογή στο ίδιο αρχείο αλλαγής με τον κανόνα δρομολόγησης, γιατί και τα δύο τα διαβάζει μαζί όποιος αποσφαλματώσει την επόμενη αποτυχία.
Έπειτα επαληθεύστε με τον επιλυτή και όχι με τη σελίδα:
resolvectl query intranet.example.internal
resolvectl status | grep -A3 'Current DNS Server'
Μια απούσα απάντηση είναι πρόβλημα επίλυσης ακόμη και όταν το μήνυμα σφάλματος του προγράμματος περιήγησης κατηγορεί το δίκτυο. Αυτές οι δύο αποτυχίες φαίνονται ίδιες στον χρήστη και είναι εντελώς διαφορετικά εισιτήρια.
Τρία όρια, τρεις διαφορετικοί μηχανισμοί
Η περισσότερη σύγχυση εξαφανίζεται μόλις ονομάσετε το όριο που θέλετε. Δεν είναι εναλλάξιμα, και το καθένα έχει διαφορετικό τρόπο αποτυχίας κατά τη διάρκεια διακοπής της σήραγγας.
| What you actually want | Mechanism that fits | What it does not cover |
|---|---|---|
| These transport ports use this exit | Firewall mark plus policy route | Applications, HTTP/3 over UDP, DNS |
| This browsing session stays separate | Application-aware VPN, or a separate network namespace plus a proxy | Other applications in the same session |
| Only these private sites are reachable | Destination-based routes with private DNS | Public sites on the same address family |
Ένα ξεχωριστό προφίλ προγράμματος περιήγησης είναι η παγίδα στη μεσαία γραμμή. Χωρίζει cookies και ιστορικό και δεν αλλάζει τίποτα στον πίνακα δρομολόγησης του κεντρικού υπολογιστή, οπότε και τα δύο προφίλ ακολουθούν την ίδια διαδρομή. Η απομόνωση απαιτεί κάτι που επιβάλλει ο πυρήνας, δηλαδή έναν χώρο ονομάτων, ένα container ή μια εφαρμογή που κατέχει τη δική της διεπαφή σήραγγας.
Όποια γραμμή κι αν ισχύει, γράψτε τι πρέπει να συμβεί όταν πέσει η σήραγγα. Μια διαδρομή βασισμένη σε σήμανση που εξαφανίζεται με τη διεπαφή συνήθως πέφτει πίσω στην φυσική προεπιλεγμένη διαδρομή, που είναι συμπεριφορά fail-open. Αυτό μπορεί να είναι αποδεκτό για περιήγηση και απαράδεκτο για οτιδήποτε άλλο, και είναι απόφαση, όχι λεπτομέρεια υλοποίησης.
Δοκιμάστε τις ροές που ισχυρίζεστε ότι καλύπτετε
Η δοκιμή αποδοχής πρέπει να ακολουθεί το όριο που γράψατε, όχι τους αριθμούς θυρών που ήταν βολικοί. Διαλέξτε μία ροή που πρέπει να περάσει από τη σήραγγα, μία που δεν πρέπει, και μία που χρησιμοποιεί μεταφορά που δεν σκεφτήκατε:
ip route get 203.0.113.40
curl -sS -o /dev/null -w 'v4 %{http_version} %{remote_ip}\n' https://example.com
nft list ruleset | grep -A2 'dport'
Η αναζήτηση διαδρομής σας λέει ποια διεπαφή χρησιμοποιεί πραγματικά ένας προορισμός, και αυτό είναι το γεγονός που οι περισσότερες αναφορές το κάνουν λάθος. Η γραμμή curl επιβεβαιώνει την έκδοση που διαπραγματεύτηκε και την οικογένεια διευθύνσεων. Η αποτύπωση του συνόλου κανόνων πιάνει τον κανόνα που προσθέσατε κατά τη δοκιμή και ξεχάσατε να περιορίσετε, και έτσι μια προσωρινή σήμανση γίνεται μόνιμη δρομολόγηση fail-open.
Καταγράψτε και τις τρεις εξόδους με χρονοσφραγίδα και κρατήστε τις μαζί με την αλλαγή. Όταν αργότερα κάποιος αναφέρει ότι «το VPN χάλασε το intranet», η διαφορά ανάμεσα στο προβλεπόμενο και το υλοποιημένο όριο θα είναι ορατή σε αυτό το αρχείο, και η διόρθωση θα είναι αλλαγή κανόνα και όχι διαφωνία.