Το πλήρες τούνελ του OpenVPN κόβει τη συνεδρία SSH: διορθώστε τη διαδρομή επιστροφής
Η προεπιλεγμένη διαδρομή στέλνει τις απαντήσεις SSH μέσα στο τούνελ. Καρφιτσώστε το peer, φιλτράρετε το redirect-gateway ή δρομολογήστε κατά πηγή πριν χάσετε το μηχάνημα.
Το να ενεργοποιήσετε έναν πελάτη OpenVPN με πλήρες τούνελ σε μηχάνημα που προσεγγίζετε μέσω SSH μπορεί να κόψει τη συνεδρία μέσα σε ένα δευτερόλεπτο, και το μηχάνημα δεν κάνει τίποτα λάθος. Το τούνελ δεν αλλάζει πώς τα πακέτα φτάνουν στον διακομιστή· αλλάζει πώς φεύγουν οι απαντήσεις. Μόλις η προεπιλεγμένη διαδρομή δείξει στο tun0, μια απάντηση στον πελάτη SSH σας πηγαίνει στο δίκτυο του παρόχου, το οποίο δεν έχει διαδρομή πίσω στη διεύθυνσή σας. Η σύνδεση κολλάει, η επόμενη προσπάθεια λήγει, και ο δαίμονας ακούει όλη την ώρα στη θύρα 22.
Διαβάστε τον πίνακα δρομολόγησης πριν διαβάσετε το αρχείο καταγραφής του VPN. Το αρχείο θα πει ότι το τούνελ ανέβηκε, και έχει δίκιο. Το ερώτημα είναι σε ποια διεπαφή παραδίδεται κάθε απάντηση, και αυτό είναι αναζήτηση ανά πακέτο σε έναν πίνακα που το τούνελ μόλις ξαναέγραψε.
Γιατί η απάντηση βγαίνει από τη λάθος πόρτα
Τα εισερχόμενα πακέτα εξακολουθούν να φτάνουν στη φυσική διεπαφή, γιατί ένας πελάτης VPN δεν μπορεί να αλλάξει πώς το διαδίκτυο φτάνει στη δημόσια διεύθυνση του διακομιστή σας. Οι απαντήσεις είναι ξεχωριστή απόφαση: για κάθε πακέτο ο πυρήνας αναζητά τον προορισμό, και μετά το --redirect-gateway η προεπιλεγμένη εγγραφή λέει τούνελ. Η έξοδος του παρόχου βλέπει έναν προορισμό που δεν εξυπηρετεί και απορρίπτει το πακέτο.
Η δική του προστασία του OpenVPN καλύπτει ακριβώς έναν προορισμό. Το εγχειρίδιο της 2.6 περιγράφει το --redirect-gateway ως ακολουθία: προσθέτει μια διαδρομή κεντρικού υπολογιστή για το peer VPN μέσω της πύλης που χρησιμοποιούνταν πριν από το τούνελ, ώστε η κρυπτογραφημένη κίνηση να μην μπορεί να επιστρέψει στον εαυτό της, και μετά αντικαθιστά την προεπιλεγμένη διαδρομή. Αυτή η διαδρομή αφορά μόνο το peer. Ο πελάτης SSH σας είναι απλώς μια άλλη διεύθυνση διαδικτύου και δεν παίρνει καμία εξαίρεση.
Αξίζει να αποκλείσετε νωρίς ένα λάθος προθέματος. Το ip route add -net 0.0.0.0 gw 10.8.0.1 dev tun0 χωρίς μήκος ταιριάζει με τη μεμονωμένη διεύθυνση 0.0.0.0, όχι με το διαδίκτυο· πρέπει να είναι 0.0.0.0/0. Και αν η ανάληψη της προεπιλεγμένης διαδρομής σπάσει τη δική του μεταφορά του τούνελ, προσθέστε το τελικό σημείο ως διαδρομή κεντρικού υπολογιστή μέσω της φυσικής διεπαφής, χρησιμοποιώντας την πραγματική διεύθυνση του παρόχου.
Καρφιτσώστε τη διεύθυνση του πελάτη SSH για άμεση διόρθωση
Η γρηγορότερη διόρθωση είναι μια διαδρομή κεντρικού υπολογιστή για τη διεύθυνση του πελάτη σας μέσω της πύλης που χρησιμοποιούσε ο διακομιστής πριν υπάρξει το τούνελ. Από τη μεριά σας, βρείτε τη διεύθυνση που θα δει ο διακομιστής και μετά διαβάστε τον πίνακα του διακομιστή για να ξέρετε την παλιά πύλη:
curl -s https://ifconfig.co
ip route
Στον διακομιστή, προσθέστε την εξαίρεση πριν ξεκινήσει ο πελάτης. Οι διευθύνσεις εδώ είναι σύμβολα κράτησης θέσης· η μορφή είναι αυτό που μετράει:
sudo ip route add 80.128.240.55 via 192.168.178.1
Αυτή είναι η διόρθωση που χρησιμοποιήθηκε στην αναφερόμενη περίπτωση, και λειτουργεί αμέσως. Είναι επίσης εύθραυστη με δύο προβλέψιμους τρόπους: η διαδρομή εξαφανίζεται στην επανεκκίνηση, και γίνεται λανθασμένη τη στιγμή που ο πάροχός σας θα σας δώσει άλλη διεύθυνση. Αντιμετωπίστε την ως μέτρο ανάγκης και κάντε την διαρκώς σταθερή σκόπιμα, μέσω μιας μονάδας δικτύου ή ενός hook του dispatcher, ή δεχτείτε ότι είναι προσωρινή και γράψτε τη διαδρομή ανάκτησης.
Εμποδίστε τον πελάτη να πάρει την προεπιλεγμένη διαδρομή
Η πιο καθαρή επιλογή είναι να μην αφήσετε το τούνελ να αντικαταστήσει καθόλου την προεπιλεγμένη διαδρομή. Το route-nopull, με το --client ή το --pull, δέχεται τις επιλογές που αποστέλλονται εκτός από διαδρομές, το block-outside-dns και επιλογές τύπου DHCP όπως οι διακομιστές DNS, οπότε προσθέτετε μόνο τα προθέματα που χρειάζεστε. Πιο στενό εργαλείο είναι ένα φίλτρο έλξης, που απορρίπτει μία προβληματική οδηγία και κρατά τις υπόλοιπες:
route-nopull
pull-filter ignore "redirect-gateway"
Χρησιμοποιήστε το ένα ή το άλλο, όχι και τα δύο, και να έχετε σαφή εικόνα για το τι αλλάζει. Χωρίς προεπιλεγμένη διαδρομή μέσα από το τούνελ, ο διακομιστής δεν περιηγείται πλέον στο διαδίκτυο μέσω του παρόχου· φτάνει μόνο ό,τι δρομολογήσατε ρητά. Αν το πλήρες τούνελ ήταν όλο το νόημα της ρύθμισης, αυτό είναι το λάθος κουμπί και η διαδρομή κεντρικού υπολογιστή παραπάνω είναι η σωστή.
Χωρίστε τη διαδρομή επιστροφής κατά πηγή ή κατά σύνδεση
Όταν η εισερχόμενη διεύθυνση είναι σταθερή, ένας κανόνας πηγής κρατά τις απαντήσεις τοπικά χωρίς να αγγίζει τις δικές του διαδρομές του τούνελ. Δώστε στη διεύθυνση της φυσικής διεπαφής τον δικό της πίνακα με το πρόθεμα LAN και την φυσική προεπιλεγμένη διαδρομή, και μετά επιλέξτε αυτόν τον πίνακα για κίνηση που προέρχεται από αυτήν:
ip rule add from 192.168.1.11 table 128
ip route add table 128 to 192.168.1.0/24 dev eth0
ip route add table 128 default via 192.168.1.1
Αυτό λειτουργεί γιατί οι απαντήσεις σε μια εισερχόμενη σύνδεση SSH προέρχονται από τη διεύθυνση με την οποία συνδέθηκε ο πελάτης. Μια αναφερόμενη περίπτωση όπου κάθε εισερχόμενη υπηρεσία έπρεπε να συνεχίσει να λειτουργεί χρησιμοποίησε ακριβώς αυτή τη μορφή. Όταν η εισερχόμενη διεύθυνση μεταβάλλεται ή η διαδρομή είναι δυναμική, σημάνετε αντί αυτού τη σύνδεση: βάλτε ένα σημάδι conntrack στο πρώτο πακέτο που φτάνει από τη φυσική διεπαφή, αντιγράψτε το στα πακέτα απάντησης στο OUTPUT, και δρομολογήστε τα σημασμένα πακέτα μέσω ενός πίνακα που δείχνει στη φυσική πύλη.
iptables -t mangle -A PREROUTING -i eth0 -m conntrack --ctstate NEW -j CONNMARK --set-mark 1234
iptables -t mangle -A OUTPUT -m connmark --mark 1234 -j MARK --set-mark 4321
ip route add default via 192.168.1.1 dev eth0 table 3412
ip rule add fwmark 4321 table 3412
Κρατήστε το σημάδι σύνδεσης, το σημάδι τείχους προστασίας και τον αριθμό πίνακα ξεχωριστά κατά τη δοκιμή. Η επαναχρησιμοποίηση ενός αριθμού για δύο ρόλους παράγει έναν κανόνα που φαίνεται σωστός και ταιριάζει με τα λάθος πακέτα. Η προεπιλεγμένη εγγραφή του πίνακα χρειάζεται επίσης το via με την πύλη LAN σε ένα συνηθισμένο ζεύξιμο Ethernet· το γυμνό dev eth0 λειτουργεί μόνο όταν η διεπαφή είναι σημείο προς σημείο ή το επόμενο άλμα επιλύεται με άλλον τρόπο. Ο αναφερόμενος κεντρικός υπολογιστής Jessie βρέθηκε τυχαία σε ζεύξη όπου η γυμνή μορφή λειτούργησε, κάτι που δεν είναι κανόνας διανομής για αντιγραφή.
Επαληθεύστε χωρίς να κλειδωθείτε έξω
Μην δοκιμάζετε αποσυνδέοντας. Κρατήστε την πρώτη συνεδρία ανοιχτή, ανεβάστε το τούνελ, και ρωτήστε τον πυρήνα ποια διαδρομή θα ακολουθούσε η δική σας διεύθυνση:
ip route get 80.128.240.55
Η απάντηση πρέπει να ονομάζει τη φυσική διεπαφή και την παλιά πύλη, όχι το τούνελ. Μετά ανοίξτε μια δεύτερη σύνδεση SSH· αυτή είναι η πραγματική δοκιμή, γιατί η παλιά συνεδρία μπορεί να επιβιώσει σε κατάσταση που μια νέα σύνδεση δεν μπορεί να αναπαράγει. Αν η δεύτερη κολλήσει ενώ η πρώτη ακόμη απαντά, ο κανόνας δεν ταίριαξε ποτέ με την κίνηση που μετράει, και τα σημάδια ή η διεύθυνση πηγής είναι το σημείο που πρέπει να κοιτάξετε.
Κρατήστε μια κονσόλα εκτός ζώνης διαθέσιμη καθ’ όλη τη διάρκεια της άσκησης. Ένας διακομιστής του οποίου η μόνη οδός πρόσβασης είναι το τούνελ που μόλις σπάσατε δεν μπορεί να επισκευαστεί μέσω αυτού του τούνελ, και η επαναφορά είναι ευκολότερη όταν έχετε σημειώσει τους αριθμούς πίνακα και τα προθέματα που προσθέσατε.