Δρομολόγηση της κίνησης του οικοδεσπότη μέσω VPN σε VM: έξι έλεγχοι
Έξι διαδοχικοί έλεγχοι για να μετατρέψετε μια VM σε πύλη VPN από την οποία δρομολογεί την κίνησή του ο δικός της οικοδεσπότης: λειτουργία προσαρμογέα, προώθηση, NAT, διαδρομές οικοδεσπότη, DNS, MTU.
Έξι έλεγχοι, εκτελεσμένοι με σειρά, αποφασίζουν αν μια VM μπορεί να λειτουργήσει ως πύλη VPN για τον δικό της οικοδεσπότη. Ο hypervisor δεν κάνει τίποτα από αυτά για εσάς: ο φιλοξενούμενος κατέχει τη σήραγγα, ο οικοδεσπότης κατέχει μια διαδρομή, και το δίκτυο ανάμεσά τους είναι συνηθισμένη δρομολόγηση. Κρατώ τη λίστα γιατί η παράλειψη ενός βήματος δίνει πάντα το ίδιο σύμπτωμα, σιωπή, όπου ο οικοδεσπότης κάνει ping στον φιλοξενούμενο με χαρά και δεν φτάνει σε τίποτα εσωτερικό.
Ξεκινήστε από τον λόγο. Είτε ο εταιρικός πελάτης εγκαθίσταται μόνο μέσα στον φιλοξενούμενο, είτε η πολιτική τον κρατά εκεί, και εξακολουθείτε να χρειάζεστε τον εσωτερικό διακομιστή build από τον οικοδεσπότη. Αν επιτρέπεται στον οικοδεσπότη δικός του πελάτης, κάντε το αντ' αυτού: μία σήραγγα στον οικοδεσπότη κερδίζει κάθε φορά δύο δίκτυα συν ένα NAT.
Έλεγχος 1: ο οικοδεσπότης χρειάζεται ζεύξη στην οποία μπορεί να δώσει διεύθυνση
Ο οικοδεσπότης πρέπει να έχει διεπαφή στο ίδιο πρόθεμα με τον δεύτερο προσαρμογέα του φιλοξενούμενου. Host-only στο VirtualBox, host-only ή προσαρμοσμένο VMnet στο VMware Workstation, εσωτερική γέφυρα ή συσκευή tap στο QEMU/KVM και διακόπτης Internal στο Hyper-V πληρούν όλα την προϋπόθεση. Φιλοξενούμενος 192.168.56.2, οικοδεσπότης 192.168.56.1, πρόθεμα 192.168.56.0/24 είναι η διάταξη που χρησιμοποιώ σε εργαστήρια.
Το δίκτυο QEMU σε λειτουργία χρήστη (-netdev user, το προεπιλεγμένο backend SLIRP) και το NAT του VirtualBox αποτυγχάνουν εντελώς σε αυτόν τον έλεγχο. Τα πακέτα του φιλοξενούμενου φτάνουν σε μια διεργασία διαμεσολαβητή στον οικοδεσπότη, οπότε ο οικοδεσπότης δεν βλέπει ποτέ συσκευή που να φέρει τις διευθύνσεις του φιλοξενούμενου και δεν έχει πού να δείξει μια διαδρομή. Το Default Switch του Hyper-V είναι η ίδια ιστορία. Αν το ping 192.168.56.2 από τον οικοδεσπότη αποτύχει, σταματήστε: καμία διαδρομή που θα προστεθεί αργότερα δεν θα το διορθώσει.
Έλεγχος 2: ο φιλοξενούμενος προωθεί και μεταφράζει
Τα πακέτα από τον οικοδεσπότη φτάνουν με διεύθυνση πηγής από το host-only δίκτυο και εσωτερικό προορισμό, οπότε ο φιλοξενούμενος πρέπει να τα προωθήσει και μετά να τα κρύψει πίσω από τη διεύθυνση της σήραγγάς του. Σε φιλοξενούμενο Linux αυτό σημαίνει προώθηση, ένα ζεύγος FORWARD accept και source NAT προς τη σήραγγα:
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -A FORWARD -i eth1 -o tun0 -j ACCEPT
sudo iptables -A FORWARD -i tun0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -t nat -A POSTROUTING -s 192.168.56.0/24 -o tun0 -j MASQUERADE
Ο κανόνας MASQUERADE είναι το κομμάτι που οι άνθρωποι παραλείπουν. Οι εταιρικοί δρομολογητές σπάνια γνωρίζουν ότι υπάρχει το 192.168.56.0/24, με τον κανόνα οι εσωτερικοί διακομιστές βλέπουν τη διεύθυνση σήραγγας του φιλοξενούμενου και απαντούν σε αυτήν, και η απάντηση βρίσκει τον δρόμο της επιστροφής στον φιλοξενούμενο.
Ένας φιλοξενούμενος Windows είναι πιο αδέξιος. Το IPEnableRouter=1 κάτω από το SYSTEM\CurrentControlSet\Services\Tcpip\Parameters ενεργοποιεί την προώθηση χωρίς μετάφραση, οπότε λειτουργεί μόνο εκεί όπου η εταιρική δρομολόγηση δείχνει ήδη πίσω στο host-only πρόθεμά σας. Το Internet Connection Sharing μεταφράζει, αλλά επαναριθμεί τον κοινόχρηστο προσαρμογέα σε 192.168.137.1, οπότε διαβάστε τη διεύθυνση που πήρε πραγματικά πριν γράψετε διαδρομές οικοδεσπότη.
Έλεγχος 3: οι διαδρομές του οικοδεσπότη ονομάζουν τον φιλοξενούμενο, όχι τη σήραγγα
Στείλτε μέσω του φιλοξενούμενου μόνο τα προθέματα που χρειάζεται ο οικοδεσπότης. Στο Linux μία διαδρομή ανά πρόθεμα αρκεί και αντιστρέφεται καθαρά:
sudo ip route add 10.20.0.0/16 via 192.168.56.2
ip route get 10.20.30.40
Στα Windows το αντίστοιχο είναι το route add 10.20.0.0 mask 255.255.0.0 192.168.56.2. Αφήστε έξω το -p όσο δοκιμάζετε ακόμη, ώστε μια κακή διαδρομή να πεθαίνει στην επανεκκίνηση, και προσθέστε το μόλις δουλέψει η διαδρομή. Μην αφαιρέσετε την προεπιλεγμένη διαδρομή του οικοδεσπότη εκτός αν κάθε εφαρμογή στον οικοδεσπότη πρέπει να χρησιμοποιεί τη σήραγγα, αν πραγματικά απαιτείται πλήρης σήραγγα, προσθέστε τις δύο διαδρομές /1 και κρατήστε την απευθείας διαδρομή προς το δίκτυο του hypervisor:
sudo ip route add 0.0.0.0/1 via 192.168.56.2
sudo ip route add 128.0.0.0/1 via 192.168.56.2
Σε οικοδεσπότη Windows ελέγξτε και τη μετρική της διεπαφής. Μια διαδρομή που προστέθηκε όσο ο host-only προσαρμογέας ήταν απενεργοποιημένος μένει στον πίνακα αλλά δεν μεταφέρει ποτέ κίνηση, και ένας δεύτερος προσαρμογέας με χαμηλότερη μετρική μπορεί να κερδίσει την αναζήτηση για το ίδιο πρόθεμα.
Έλεγχος 4: το DNS ακολουθεί τη διαδρομή, όχι την προεπιλογή της σήραγγας
Οι διαδρομές μετακινούν πακέτα, ο resolver αποφασίζει ποια ονόματα παράγουν πακέτα. Περιορίστε τον εταιρικό resolver στην εταιρική ζώνη αντί να αντικαταστήσετε τον resolver του οικοδεσπότη, και δείξτε τον σε έναν διακομιστή DNS που η νέα διαδρομή ήδη φτάνει. Με systemd-resolved στον οικοδεσπότη:
resolvectl dns eth1 10.20.0.53
resolvectl domain eth1 '~corp.example.com'
Στα Windows μια καταχώριση στον πίνακα πολιτικής επίλυσης ονομάτων κάνει την ίδια δουλειά: Add-DnsClientNrptRule -Namespace ".corp.example.com" -NameServers 10.20.0.53. Αν ο φιλοξενούμενος τρέχει δικό του resolver στη host-only διεύθυνση, χρησιμοποιήστε αυτή τη διεύθυνση, αλλά μόνο αφού επιβεβαιώσετε ότι απαντά στο 192.168.56.2 και όχι στο loopback.
Έπειτα ελέγξτε το MTU πριν κατηγορήσετε το DNS για αργές σελίδες. Η διεπαφή της σήραγγας είναι μικρότερη από τη διεπαφή 1500 byte του οικοδεσπότη, οπότε ένας οικοδεσπότης που στέλνει τμήματα πλήρους μεγέθους με το bit DF ενεργό τα βλέπει να πέφτουν κάπου μέσα στον φιλοξενούμενο. Το κλασικό σύμπτωμα είναι ένα ping που δουλεύει και μια εσωτερική διαδικτυακή εφαρμογή που κολλάει μετά τη χειραψία TLS. Σφίξτε το MSS στη διαδρομή προώθησης του φιλοξενούμενου:
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
Έλεγχος 5: επαληθεύστε από τα δύο άκρα
Από τον οικοδεσπότη, το traceroute ή το tracert προς μια εσωτερική διεύθυνση θα πρέπει να δείχνει το 192.168.56.2 ως πρώτο άλμα, όχι τη φυσική πύλη. Στον φιλοξενούμενο, παρακολουθήστε την ίδια απόπειρα να φεύγει: το tcpdump -ni any host 10.20.30.40 δείχνει το προωθημένο αίτημα στην πλευρά host-only και το μεταφρασμένο στη σήραγγα. Ένα αίτημα που βγαίνει, επιστρέφει και αφήνει τον οικοδεσπότη ακόμη σιωπηλό δείχνει προς τη διαδρομή επιστροφής.
Δύο αστοχίες εξηγούν το μεγαλύτερο μέρος αυτού. Είτε η σήραγγα του φιλοξενούμενου δεν φέρει διαδρομή επιστροφής για το host-only πρόθεμα επειδή λείπει ο κανόνας NAT, είτε η διαδρομή του οικοδεσπότη δείχνει σε διεύθυνση που ο φιλοξενούμενος δεν έχει πια μετά από επανεκκίνηση. Διαβάστε ξανά τις διευθύνσεις με το ip -br addr και το ip route get αντί να εμπιστεύεστε σημειώσεις από την προηγούμενη συνεδρία.
Έλεγχος 6: κάντε το να επιβιώνει από επανεκκίνηση και αναβάθμιση του hypervisor
Διατηρήστε και τα δύο μισά: ρύθμιση διαδρομών με netplan ή NetworkManager στον οικοδεσπότη, route add ... -p στα Windows, και net.ipv4.ip_forward=1 στο /etc/sysctl.d/ συν ένα σύνολο κανόνων τείχους προστασίας που επαναφορτώνεται στον φιλοξενούμενο. Πάρτε snapshot του φιλοξενούμενου μόλις επαληθευτεί η ρύθμιση, πριν φτάσει η επόμενη ενημέρωση του εταιρικού πελάτη.
Τα host-only δίκτυα επαναριθμούνται όταν ένας hypervisor δημιουργεί ξανά τους προσαρμογείς του, κάτι που ακυρώνει σιωπηλά κάθε διαδρομή και κανόνα NAT που χτίστηκε πάνω στο 192.168.56.0/24. Μετά από αναβάθμιση, επαναλάβετε τους τρεις πρώτους ελέγχους με σειρά, αυτό κοστίζει ένα λεπτό και πιάνει την περίπτωση όπου ο οικοδεσπότης έχει ακόμη τη διαδρομή του ενώ ο φιλοξενούμενος μετακινήθηκε σε νέο υποδίκτυο.
Το IPv6 χρειάζεται δικό του πέρασμα. Κανόνες ip6tables, εγγραφές AAAA και μια δεύτερη οικογένεια διαδρομών οικοδεσπότη δεν ακολουθούν τη ρύθμιση IPv4, και μια εταιρική υπηρεσία προσβάσιμη μέσω IPv6 θα φαίνεται μόνιμα χαλασμένη όσο το IPv4 δουλεύει.
Επιτυχία ή αποτυχία, με σειρά: ο οικοδεσπότης μπορεί να κάνει ping στη host-only διεύθυνση του φιλοξενούμενου, ο φιλοξενούμενος προωθεί και κάνει MASQUERADE προς τη σήραγγα, το ip route get επιστρέφει τον φιλοξενούμενο ως πύλη για το εσωτερικό πρόθεμα, τα εταιρικά ονόματα επιλύονται μέσω του περιορισμένου resolver, το traceroute δείχνει πρώτα τον φιλοξενούμενο, και οι ίδιες έξι απαντήσεις επιβιώνουν από επανεκκίνηση.