Πώς να εκτελέσετε μία διεργασία Linux έξω από ένα τούνελ WireGuard
Δώστε σε ένα πρόγραμμα το δικό του πλαίσιο δικτύου ώστε να εξέλθει από έναν κεντρικό υπολογιστή WireGuard με πλήρες τούνελ και μετά διορθώστε τους κανόνες προώθησης και σήμανσης που το μπλοκάρουν.
Δεν μπορείτε να εξαιρέσετε ένα πρόγραμμα από έναν κεντρικό υπολογιστή WireGuard με πλήρες τούνελ επεξεργάζοντας διαδρομές. Οι διαδρομές επιλέγουν μονοπάτι βάσει προορισμού, και αυτό που θέλετε να εξαιρέσετε είναι μια διεργασία, οπότε ο πυρήνας δεν έχει τίποτα να αντιστοιχίσει. Η εφαρμόσιμη προσέγγιση είναι να δώσετε σε αυτή τη διεργασία το δικό της πλαίσιο δικτύου: έναν χώρο ονομάτων με τη δική του διεπαφή, τις δικές του διευθύνσεις και την προεπιλεγμένη του διαδρομή, συνδεδεμένο με τον κεντρικό υπολογιστή μέσω ζεύγους veth. Το έτρεξα σε Ubuntu 24.04 με wireguard-tools 1.0.20210914, και ο χώρος ονομάτων δεν ήταν ποτέ το πρόβλημα — η πολιτική προώθησης του κεντρικού υπολογιστή και οι κανόνες σήμανσης του τούνελ ήταν.
Επιλέξτε πρώτα το είδος πλαισίου που χρειάζεστε
Στην πράξη εμφανίζονται δύο μορφές. Αν ο κεντρικός υπολογιστής τρέχει πλήρες τούνελ και ένα πρόγραμμα πρέπει να βγει από τη διαδρομή του ISP, χτίζετε έναν δεύτερο χώρο ονομάτων, τον συνδέετε με τον κεντρικό υπολογιστή και αφήνετε τον κεντρικό υπολογιστή να προωθεί και να μεταφράζει την κίνηση γι' αυτό. Αν ένας χώρος ονομάτων φέρνει ήδη διεπαφή VPN και χρειάζεστε μόνο μια εντολή που ξεκινά μέσα του, αυτή είναι η συνηθισμένη περίπτωση ip netns exec και το μεγαλύτερο μέρος της δουλειάς δρομολόγησης έχει ήδη γίνει.
Καμία από τις δύο μορφές δεν σας δίνει κανόνα περιορισμένο σε ένα αναγνωριστικό διεργασίας. Το Netfilter αντιστοιχίζει διευθύνσεις, θύρες, σημάνσεις και διεπαφές· δεν υπάρχει πίνακας δρομολόγησης ανά διεργασία. Η σήμανση μπορεί να κατευθύνει την κίνηση, αλλά η σήμανση πρέπει να εφαρμοστεί σε πακέτα που έχετε ήδη αναγνωρίσει, και αυτό είναι το ίδιο πρόβλημα ένα επίπεδο πιο κάτω. Ένας χώρος ονομάτων διαχωρίζει ολόκληρη τη στοίβα για εκείνο το δέντρο διεργασιών, και γι' αυτό είναι η συνηθισμένη απάντηση.
Αν η απαίτηση είναι πραγματικά να μη βγαίνει τίποτα από το τούνελ, σταματήστε το τούνελ. Ο χώρος ονομάτων υπάρχει για τη μικτή περίπτωση: ένα πρόγραμμα έξω, όλα τα άλλα μέσα, στο ίδιο μηχάνημα, την ίδια στιγμή.
Χτίστε το δεύτερο πλαίσιο και συνδέστε το με τον κεντρικό υπολογιστή
Μια ενδεικτική διάταξη: ο κεντρικός υπολογιστής έχει διεπαφή WireGuard που μεταφέρει την προεπιλεγμένη διαδρομή και έναν χώρο ονομάτων δικτύου που ονομάζεται clearnet συνδεδεμένο με τον κεντρικό υπολογιστή μέσω ζεύγους veth. Οι παρακάτω διευθύνσεις είναι παραδείγματα.
ip netns add clearnet
ip link add veth-clear-out type veth peer name veth-clear-in
ip addr add 192.168.100.1/24 dev veth-clear-out
ip link set veth-clear-out up
ip link set veth-clear-in netns clearnet
ip netns exec clearnet ip addr add 192.168.100.2/24 dev veth-clear-in
ip netns exec clearnet ip link set veth-clear-in up
ip netns exec clearnet ip route add default via 192.168.100.1
Αυτός ο χώρος ονομάτων μπορεί τώρα να φτάσει τον κεντρικό υπολογιστή και τίποτα άλλο. Ο κεντρικός υπολογιστής πρέπει να προωθεί την κίνηση και να ξαναγράφει τη διεύθυνση προέλευσης, γιατί το 192.168.100.0/24 είναι ιδιωτικό και ο ανάντη δρομολογητής δεν έχει διαδρομή πίσω σε αυτό:
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o <wan-interface> -j MASQUERADE
Επιβεβαιώστε την πλευρά του χώρου ονομάτων πριν προχωρήσετε.ip netns exec clearnet ip route θα πρέπει να δείχνει τη διαδρομή veth και την προεπιλεγμένη διαδρομή μέσω 192.168.100.1, και ένα ping σε αυτή τη διεύθυνση θα πρέπει να απαντήσει. Αν το ping στη διεύθυνση του κεντρικού υπολογιστή αποτύχει, οι διευθύνσεις ή η κατάσταση του συνδέσμου είναι λάθος και κανένας κανόνας τείχους προστασίας δεν θα βοηθήσει.
Όταν τα ονόματα επιλύονται αλλά τίποτα δεν επιστρέφει, διαβάστε το FORWARD
Η κλασική αποτυχία μοιάζει με σφάλμα δρομολόγησης: ο χώρος ονομάτων επιλύει ένα όνομα, το πακέτο φεύγει και δεν φτάνει ποτέ απάντηση. Σε κεντρικούς υπολογιστές με πολιτική FORWARD DROP — έτσι κάνουν αρκετές διανομές και τα περισσότερα σκληρυμένα images — το πακέτο απορρίπτεται στην πορεία, και το σφάλμα που τυπώνει η εφαρμογή δεν λέει τίποτα για φιλτράρισμα.
Διαβάστε την αλυσίδα πριν προσθέσετε οτιδήποτε:
iptables -S FORWARD
nft list chain inet filter forward
Έπειτα επιτρέψτε την κίνηση και προς τις δύο κατευθύνσεις, με μετρητές, ώστε να καταλάβετε αν ο κανόνας ταίριαξε ποτέ:
iptables -A FORWARD -i veth-clear-out -o <wan-interface> -j ACCEPT
iptables -A FORWARD -i <wan-interface> -o veth-clear-out -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
watch -n1 'iptables -L FORWARD -v -n'
Ένας κανόνας με μηδενικό μετρητή πακέτων δεν βρίσκεται στη διαδρομή. Είτε τα ονόματα των διεπαφών διαφέρουν από ό,τι υποθέσατε, είτε ένας προηγούμενος κανόνας στην αλυσίδα αποδέχτηκε, απέρριψε ή επέστρεψε πρώτος το πακέτο. Διορθώστε τη σειρά, όχι το κείμενο του κανόνα.
Η κίνηση απάντησης είναι το μισό που ξεχνούν οι άνθρωποι. Ο κανόνας επιστροφής χρειάζεται το ίδιο όνομα veth συν αντιστοίχιση κατάστασης σύνδεσης, ή απλή αποδοχή διεπαφής αν κρατάτε την πολιτική ανοιχτή. Προσθέστε μόνο τον κανόνα εξόδου και το αρχικό σύμπτωμα επιστρέφει, με τον νέο σας κανόνα να στέκεται εκεί και να φαίνεται σωστός.
Κρατήστε τους κανόνες σήμανσης του τούνελ μακριά από τη νέα διαδρομή
Αυτό το βήμα μετατρέπει έναν λειτουργικό χώρο ονομάτων σε διαρρέοντα. Οι ρυθμίσεις WireGuard εγκαθιστούν συνήθως πολιτική σήμανσης τείχους προστασίας μαζί με δικούς τους κανόνες δρομολόγησης και ειδικό πίνακα, ώστε τα ασήμαντα πακέτα να πέφτουν στον κύριο πίνακα ενώ τα σημασμένα χρησιμοποιούν τον πίνακα του τούνελ. Η προωθημένη κίνηση από τον χώρο ονομάτων αξιολογείται κατά της δρομολόγησης πολιτικής στην έξοδο, και ανάλογα με το πώς γράφτηκαν αυτοί οι κανόνες μπορεί να καταλήξει στον πίνακα του τούνελ.
Δύο προσθήκες χωρίζουν τις διαδρομές. Επιστρέψτε νωρίς στην αλυσίδα mangle για το υποδίκτυο του χώρου ονομάτων και προσθέστε έναν κανόνα βάσει προέλευσης που βάζει αυτό το υποδίκτυο στον κύριο πίνακα:
iptables -t mangle -I PREROUTING -s 192.168.100.0/24 -j RETURN
ip rule add from 192.168.100.0/24 lookup main priority 100
Η προτεραιότητα 100 ταξινομείται μπροστά από τους κανόνες του τούνελ στον δικό μου κεντρικό υπολογιστή, οπότε αποφασίζει ο συνηθισμένος πίνακας για αυτή την προέλευση. Μην αντιγράψετε τον αριθμό στα τυφλά: οι προτεραιότητες που wg-quick εγκαθιστά διαφέρουν μεταξύ εκδόσεων και μεταξύ των ρυθμίσεων IPv4 και IPv6, οπότε εκτελέστε ip rule show και επιλέξτε προτεραιότητα που πέφτει μπροστά από τους κανόνες του τούνελ στο μηχάνημά σας.
Επαληθεύστε με αναζήτηση ειδική για την προέλευση αντί να εμπιστεύεστε τη λίστα κανόνων:
ip route get 1.1.1.1 from 192.168.100.2
ip netns exec clearnet ip route get 1.1.1.1
Αν η πρώτη εντολή αναφέρει τη διεπαφή WireGuard, ο νέος κανόνας δεν είναι ακόμα μπροστά από την πολιτική του τούνελ. Αν αναφέρει τη διεπαφή WAN ενώ η δεύτερη δείχνει ακόμα την προεπιλεγμένη διαδρομή veth, ο κεντρικός υπολογιστής και ο χώρος ονομάτων διαφωνούν και θα πρέπει να ξαναδιαβάσετε και τους δύο πίνακες δρομολόγησης.
Ξεκινήστε τη διεργασία που ανοίγει τη σύνδεση
Το να ξεκινήσετε την εντολή είναι μία γραμμή, αλλά ξεκινήστε τη διεργασία που δημιουργεί πραγματικά το socket.ip netns exec clearnet curl -s https://ifconfig.me είναι το μικρότερο ειλικρινές τεστ: δείχνει τη διεύθυνση που παρουσιάζει ο χώρος ονομάτων στον κόσμο, όχι αυτή που θα χρησιμοποιούσε ο κεντρικός υπολογιστής.
Για μια υπηρεσία, προσδέστε τον χώρο ονομάτων μέσω διαδρομής ώστε η διεργασία να μένει μέσα του σε όλη της τη ζωή:
[Service]
NetworkNamespacePath=/run/netns/clearnet
Οι γραφικές εφαρμογές είναι εκεί όπου η προσέγγιση της μίας γραμμής αποτυγχάνει σιωπηλά. Ένας περιηγητής που ξεκινά από μενού συχνά παραδίδει το αίτημα σε ένα στιγμιότυπο που ήδη τρέχει έξω από τον χώρο ονομάτων, οπότε το νέο παράθυρο εμφανίζεται και η κίνηση φεύγει ακόμα από το τούνελ. Δώστε του ξεχωριστό προφίλ ώστε να δημιουργηθεί πραγματικά νέο στιγμιότυπο, και μετά ελέγξτε το πλαίσιο της διεργασίας αντί να μαντεύετε:
readlink /proc/$(pgrep -f clearnet-profile | head -1)/ns/net
readlink /run/netns/clearnet
Οι δύο έξοδοι πρέπει να ταιριάζουν. Ο ίδιος έλεγχος δουλεύει για κάθε μακρόχρονο πρόγραμμα, και αξίζει να γίνεται μία φορά ανά εφαρμογή αντί να υποθέτετε ότι ο εκκινητής έκανε αυτό που εννοούσατε.
Η επίλυση ονομάτων χρειάζεται τη δική της απόφαση. Η δημιουργία χώρου ονομάτων δεν του δίνει ρύθμιση resolver· αρχεία ανά χώρο ονομάτων υποστηρίζονται μέσω /etc/netns/<name>/resolv.conf και χωρίς ένα κληρονομείτε συμπεριφορά που διαβάζεται εύκολα λάθος. Το IPv6 χρειάζεται την ίδια μεταχείριση: αν ο χώρος ονομάτων δεν έχει προεπιλεγμένη διαδρομή v6 ενώ η εφαρμογή προτιμά v6, τα αιτήματα μπορεί να κολλήσουν πριν υποχωρήσουν, κάτι που μοιάζει με χαλασμένο τούνελ.
Ελέγξτε το πλαίσιο, όχι μόνο τη διεύθυνση εξόδου
Μια λειτουργική δημόσια διεύθυνση αποδεικνύει τη διαδρομή, όχι ολόκληρη την απαίτηση. Διαβείτε τα υπόλοιπα με αυτή τη σειρά:
ip netns exec clearnet ip route get 1.1.1.1δείχνει την προεπιλεγμένη διαδρομή veth, όχι τη διεπαφή WireGuard.- Οι μετρητές FORWARD και στους δύο κανόνες αυξάνονται όσο εκτελείται ένα αίτημα.
- Η διεργασία της εφαρμογής αναφέρει το inode του χώρου ονομάτων που περιμένετε.
- Μετά από επανεκκίνηση ο χώρος ονομάτων υπάρχει πριν ξεκινήσει η υπηρεσία· μια μονάδα που τρέχει νωρίτερα αποτυγχάνει ή, χειρότερα, τρέχει έξω από τον χώρο ονομάτων.
Έπειτα αποφασίστε τι πρέπει να συμβεί όταν πέσει το τούνελ. Ο χώρος ονομάτων συνεχίζει να λειτουργεί, που είναι το νόημα της άσκησης και ταυτόχρονα ο κίνδυνος: το εξαιρεμένο πρόγραμμα μένει συνδεδεμένο ενώ όλα τα άλλα σταματούν. Καταγράψτε το ως επιλογή πολιτικής και να είστε σαφείς για το τι δεν καλύπτει η εξαίρεση — η ταυτότητα λογαριασμού, η αποθηκευμένη κατάσταση του περιηγητή και ο πάροχος DNS σας βρίσκονται όλα εκτός του πεδίου ενός χώρου ονομάτων δικτύου, και το να αντιμετωπίζετε την εξαίρεση ως ανωνυμία είναι το λάθος που επιβιώνει της διαμόρφωσης.