Πώς ένας πελάτης OpenVPN πίσω από NAT γίνεται έξοδος στο διαδίκτυο
Η έξοδος καλεί η ίδια προς τα έξω, οπότε ο δρομολογητής της δεν χρειάζεται θύρα εισόδου. Παρακολουθήστε τι δρομολογεί ο κόμβος, τι προωθεί η έξοδος και από πού έρχεται η διαδρομή επιστροφής.
Τρεις υπολογιστές Linux, ένας σχεδιασμός: ένας δημόσια προσβάσιμος κόμβος OpenVPN, ένας φορητός υπολογιστής καταναλωτή και ένα μηχάνημα εξόδου πίσω από έναν συνηθισμένο οικιακό δρομολογητή που δεν προωθεί τίποτα προς τα μέσα. Η έξοδος καλεί η ίδια τον κόμβο. Στη συνέχεια η κίνηση του καταναλωτή προς το διαδίκτυο μπαίνει στη σήραγγα στον φορητό και βγαίνει από το δικό της ανάντη κανάλι. Ό,τι εκπλήσσει σε αυτή τη διάταξη προκύπτει από μία λεπτομέρεια: η έξοδος ξεκίνησε τη σύνδεση, άρα η διαδρομή προς τα μέσα υπάρχει ήδη και δεν χρειάζεται προώθηση θύρας για να δημιουργηθεί.
Αυτό που ακολουθεί παρακολουθεί τη διαδρομή του πακέτου και όχι τη σειρά της διαμόρφωσης, γιατί η διαμόρφωση αποκτά νόημα μόνο όταν ξέρεις ποιο συστατικό παίρνει ποια απόφαση. Κάθε επίπεδο παίρνει ακριβώς μία απόφαση, και τα λάθη συγκεντρώνονται εκεί όπου δύο επίπεδα θεωρούνται ένα.
Δύο συνεδρίες μεταφοράς, μία εσωτερική διαδρομή
Κάθε υπολογιστής κρατά τη δική του εξωτερική σύνδεση προς τον κόμβο, και καμία από αυτές δεν γνωρίζει την άλλη. Η κίνηση του καταναλωτή προς το διαδίκτυο είναι μια ξεχωριστή εσωτερική ροή που μεταφέρεται μέσα στη σήραγγα του καταναλωτή και μετά εκπέμπεται ξανά από τη σήραγγα της εξόδου. Αυτή η εσωτερική ροή πρέπει να δρομολογήσει ο κόμβος και αυτή πρέπει να προωθήσει η έξοδος.
outer: consumer --TLS--> hub
outer: exit --TLS--> hub
inner: consumer --tun--> hub --internal--> exit --tun--> uplink
Επειδή και οι δύο εξωτερικές συνδέσεις είναι εξερχόμενες από την πλευρά του πελάτη, ο δρομολογητής της εξόδου δεν βλέπει ποτέ εισερχόμενο SYN και δεν χρειάζεται ποτέ κανόνα NAT προορισμού. Πρέπει μόνο να κρατά ζωντανή την εγκατεστημένη μεταφορά, κάτι που ήδη κάνει για κάθε μακρόβια σύνδεση. Τίποτα στο δημόσιο διαδίκτυο δεν χρειάζεται να φτάσει πρώτα στην έξοδο, γι' αυτό μια δυναμική διεύθυνση σε αυτό το ανάντη κανάλι δεν είναι πρόβλημα. Ο δρομολογητής πρέπει ακόμη να επιτρέπει την εξερχόμενη συνεδρία, αλλά αυτή είναι η ίδια άδεια που χρησιμοποιεί ήδη ένα πρόγραμμα περιήγησης.
Τι εγκαθιστά στην πραγματικότητα το iroute μέσα στον διακομιστή
Ο κόμβος είναι η μόνη συσκευή που αποφασίζει ποιος ομότιμος κατέχει ποιον προορισμό, και παίρνει αυτή την απόφαση στον δικό του πίνακα δρομολόγησης χώρου χρήστη, όχι του πυρήνα. Μια καταχώριση client-config-dir για την έξοδο με όνομα exit-node μπορεί να διεκδικήσει εκεί το προεπιλεγμένο πρόθεμα:
# /etc/openvpn/server/ccd/exit-node
iroute 0.0.0.0 0.0.0.0
Αυτή η γραμμή λέει στη διεργασία του διακομιστή "εσωτερικά πακέτα με οποιονδήποτε προορισμό ανήκουν σε αυτόν τον πελάτη". Δεν προσθέτει προεπιλεγμένη διαδρομή στο λειτουργικό σύστημα του κόμβου και δεν κάνει τον κόμβο πύλη διαδικτύου. Αναφορά OpenVPN 2.6 κρατά τη δρομολόγηση εσωτερικά ειδική για τον πελάτη και τη δρομολόγηση του πυρήνα ως ξεχωριστούς μηχανισμούς, και αυτός ο διαχωρισμός είναι ο λόγος που ο σχεδιασμός λειτουργεί χωρίς να αγγίξει την προεπιλεγμένη διαδρομή του κόμβου.
Ο καταναλωτής χρειάζεται την κατοπτρική οδηγία, που παραδίδεται ως push, ώστε η δική του κίνηση να μπει στη σήραγγα αντί να βγει από την τοπική πύλη. Με τοπολογία υποδικτύου η δεξαμενή είναι συνδεδεμένη διαδρομή στη συσκευή tun της εξόδου, άρα η κατεύθυνση επιστροφής δεν χρειάζεται επιπλέον push· αυτό που δεν πρέπει να λάβει η έξοδος είναι η ανακατεύθυνση παρακάτω, που θα έστελνε την ανάντη κίνησή της πίσω στη σήραγγα που προσπαθεί να χρησιμοποιήσει. Στείλτε την μόνο στον καταναλωτή και διαβάστε τις εφαρμοσμένες διαδρομές στον πελάτη αντί να πιστεύετε ότι επιλέχθηκε το αρχείο CCD.
# /etc/openvpn/server/ccd/consumer-01
push "redirect-gateway def1"
Ο πυρήνας της εξόδου κάνει την προώθηση
Μέσα στην έξοδο, ένα πακέτο από τον καταναλωτή φτάνει στη διεπαφή tun με προορισμό κάποιον υπολογιστή του διαδικτύου. Ο πυρήνας συμβουλεύεται τον πίνακα δρομολόγησης, βρίσκει το πραγματικό ανάντη κανάλι ως την καλύτερη αντιστοίχιση και μετά εφαρμόζει δύο ανεξάρτητες πολιτικές: αν επιτρέπεται να προωθηθεί καθόλου το πακέτο και αν επιτρέπεται να φύγει από αυτή τη διεπαφή με αυτή τη διεύθυνση πηγής. Η προώθηση είναι sysctl και είναι απενεργοποιημένη από προεπιλογή σε πολλές διανομές.
Έτσι η έξοδος χρειάζεται μόνιμα ενεργή προώθηση IPv4, έναν κανόνα προώθησης που δέχεται τις πηγές της σήραγγας του καταναλωτή προς το ανάντη κανάλι, και τη διαδρομή απάντησης πίσω από το tun. Η ενεργοποίηση της προώθησης για όλο τον υπολογιστή αλλάζει και τη συμπεριφορά κάθε άλλου που δρομολογείται μέσω αυτού, γι' αυτό ο κανόνας πρέπει να ονομάζει πηγές και διεπαφές αντί να δέχεται τα πάντα.
Η μετάφραση πηγής είναι αυτό που αγοράζει τη διαδρομή επιστροφής
Ένας υπολογιστής του διαδικτύου δεν έχει διαδρομή προς μια διεύθυνση 10.90.0.x, άρα οι απαντήσεις θα απορρίπτονταν πριν φτάσουν ποτέ στην έξοδο. Η επανεγγραφή της πηγής καθώς το πακέτο φεύγει από το ανάντη κανάλι το λύνει, και η παρακολούθηση συνδέσεων αντιστρέφει την επανεγγραφή στην επιστροφή.
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 10.90.0.0/24 -o enp1s0 -j MASQUERADE
ip -4 route get 10.90.0.9 # run on the exit: must point at the tun
Ο κανόνας παραπάνω είναι σημείο εκκίνησης για μία διεπαφή ανάντη, όχι πολιτική τείχους προστασίας. Περιορίστε την πηγή στις εκχωρήσεις που πραγματικά εξουσιοδοτήσατε, και κρατήστε την πολιτική εισόδου της εξόδου ξεχωριστή ώστε η συγκάλυψη για την κίνηση της σήραγγας να μην εκθέτει σιωπηρά τοπικές υπηρεσίες. Σε υπολογιστή με δυναμική διεύθυνση ανάντη, η συγκάλυψη σας γλιτώνει και από την χειροκίνητη παρακολούθηση της διεύθυνσης.
Πού μπορεί ο κόμβος να επιβάλει και πού όχι
Με το client-to-client και την παραδοσιακή διαδρομή δεδομένων χώρου χρήστη, ο κόμβος παραδίδει εσωτερικά πακέτα μεταξύ ομοτίμων μέσα στη διεργασία του διακομιστή. Δεν διασχίζουν ποτέ την αλυσίδα FORWARD του πυρήνα του κόμβου, άρα ένας κανόνας πυρήνα εκεί δεν μπορεί να περιορίσει τη διέλευση μεταξύ ομοτίμων, όσο προσεκτικά κι αν γραφτεί. Η επιβολή πρέπει να ζει στην πολιτική του ίδιου του διακομιστή: ποιος επιτρέπεται να συνδεθεί, ποιο αρχείο CCD παίρνει και αν χορηγείται καθόλου η προεπιλεγμένη κυριότητα της εξόδου.
Γι' αυτό επίσης ένα προεπιλεγμένο iroute είναι μια ευρεία απόφαση εμπιστοσύνης. Η έξοδος πρέπει νόμιμα να δέχεται κίνηση επιστροφής από αυθαίρετες διευθύνσεις διαδικτύου, και πρέπει να είναι μηχάνημα που ελέγχετε, ενημερώνετε και παρακολουθείτε. Το να δώσετε την ίδια κυριότητα σε έναν ομότιμο στον οποίο δεν θα δίνατε δρομολογητή είναι το λάθος στο οποίο αυτός ο σχεδιασμός καλεί.
Η συμμετοχή είναι ο πραγματικός έλεγχος. Κάθε πελάτης που μπορεί να ρυθμίσει τις δικές του διαδρομές μπορεί να δοκιμάσει να χρησιμοποιήσει την έξοδο, άρα ο περιορισμός του ποιος επιτρέπεται να συνδεθεί, ή ποιους ομοτίμους θα εξυπηρετεί η έξοδος, είναι μέρος του σχεδιασμού και όχι ύστερη σκέψη.
Ασφαλής αποτυχία όταν η έξοδος εξαφανιστεί
Βγάλτε την έξοδο εκτός λειτουργίας και η εσωτερική προεπιλεγμένη κυριότητα εξαφανίζεται μαζί με τη συνεδρία της. Αυτό που δεν πρέπει να συμβεί είναι ο κόμβος να γίνει σιωπηρά η αναπληρωματική έξοδος: καμία προεπιλεγμένη διαδρομή από τη δεξαμενή VPN προς το ανάντη κανάλι του κόμβου και κανένας ευρύς κανόνας συγκάλυψης στον κόμβο που θα προωθούσε πρόθυμα την ίδια κίνηση. Δοκιμάστε αυτή την αποτυχία σκόπιμα και μετά δοκιμάστε την ανάκτηση με νέα ροή και όχι με σελίδα που ήταν ήδη ανοιχτή.
# on the consumer, with the exit up and then down
ip -4 route get 1.1.1.1
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com
Αν η κίνηση του καταναλωτή φτάνει ακόμη στο διαδίκτυο αφού η έξοδος έχει φύγει, κάτι άλλο τη μεταφέρει και το όριο που σκοπεύατε δεν υπάρχει. Αντιμετωπίστε το DNS και το IPv6 επίσης ως ξεχωριστές αποφάσεις: μια διαδρομή IPv4 με συγκάλυψη δεν λέει τίποτα για κίνηση AAAA, και ένας resolver που σπρώχνει ο κόμβος θα απαντά από όπου βγαίνει πραγματικά το ερώτημα.