Οι επισκέπτες στο προεπιλεγμένο δίκτυο libvirt επιλύουν ονόματα τέλεια μέχρι να ανέβει η διεπαφή WireGuard, και τότε κάθε αναζήτηση κολλάει στο ίδιο σημείο. Το dnsmasq ακούει ακόμη στο 192.168.122.1:53, ο επισκέπτης έχει ακόμη αυτή τη διεύθυνση ως resolver του, και το ερώτημα φτάνει ακόμη. Αυτό που άλλαξε είναι ότι το δικό του upstream ερώτημα του host, ή η απάντηση σε αυτό, τώρα απορρίπτεται από έναν κανόνα που αξιολογείται πριν από οποιαδήποτε αλυσίδα φίλτρων θα σκεφτόσασταν να επεξεργαστείτε. Η διέξοδος είναι μια σήμανση που εφαρμόζεται αρκετά νωρίς, σε μια σύνδεση που κληρονομεί η απάντηση.

Οι επισκέπτες χάνουν το DNS τη στιγμή που ανεβαίνει το τούνελ

Επιβεβαιώστε το σχήμα πριν αλλάξετε οτιδήποτε. Κατεβάστε το τούνελ, εκτελέστε το dig @192.168.122.1 example.com από έναν επισκέπτη και δείτε το να απαντά. Ανέβαστε το τούνελ, επαναλάβετε και δείτε το να λήγει. Αυτό το ζεύγος αποτελεσμάτων αποκλείει ένα χαλασμένο δίκτυο libvirt, μια λάθος διεύθυνση resolver και ένα νεκρό dnsmasq σε ένα βήμα.

Στη συνέχεια κοιτάξτε την πλευρά του host. Αν το dnsmasq καταγράφει το ερώτημα και την upstream προώθησή του, το πακέτο έφτασε και η αποτυχία είναι στην έξοδο. Αν το dnsmasq δεν καταγράφει τίποτα, το ερώτημα του επισκέπτη απορρίπτεται στην είσοδο και η εξαίρεση ανήκει σε άλλο hook από αυτό που σημαίνει αυτό το άρθρο.

Γιατί ένας κανόνας accept σε μεταγενέστερη αλυσίδα δεν ενεργοποιείται ποτέ

Ένα τείχος προστασίας VPN βασισμένο σε σημάνσεις αποφασίζει κοιτάζοντας τη σήμανση του πακέτου ή τη σήμανση της σύνδεσης, όχι τη διεύθυνση προέλευσής σας. Οτιδήποτε φτάνει στη φυσική διεπαφή χωρίς την αναμενόμενη σήμανση απορρίπτεται, και αυτή η απόρριψη συμβαίνει στο σύνολο κανόνων που κατέχει τον έλεγχο σήμανσης. Μια γραμμή ip saddr 192.168.122.0/24 accept που προστίθεται σε κάποια μεταγενέστερη αλυσίδα απλώς δεν εξετάζεται ποτέ για αυτό το πακέτο, γι' αυτό ο προφανής κανόνας φαίνεται σωστός και δεν αλλάζει τίποτα.

Το να το διευρύνετε μέχρι να δουλέψει κάτι είναι η δεύτερη παγίδα. Η αποδοχή ολόκληρου του υποδικτύου libvirt στη διαδρομή εισόδου του host ανοίγει κάθε υπηρεσία του host στους επισκέπτες, ενώ η πραγματική ανάγκη είναι μία θύρα.

Ο μηχανισμός που κάνει δυνατή μια στενή εξαίρεση είναι η παρακολούθηση συνδέσεων. Όταν ορίζετε ct mark σε ένα πακέτο, η τιμή αποθηκεύεται στην καταχώριση conntrack και όχι μόνο στο πακέτο, ώστε κάθε πακέτο σε αυτή τη σύνδεση να τη φέρει στη συνέχεια, συμπεριλαμβανομένης της απάντησης από τον host πίσω στον επισκέπτη. Αυτό είναι όλο το κόλπο: σημάνετε το αίτημα μία φορά και η διαδρομή επιστροφής είναι ήδη σημασμένη.

Σημάνετε το ερώτημα πριν το δει ο πίνακας VPN

Βάλτε την εξαίρεση στον δικό της πίνακα ώστε ένας μεταγενέστερος αναγνώστης να τη βρει χωρίς να αναλύσει τους κανόνες VPN:

table inet allowedLocal {
  chain guest_dns {
    type filter hook input priority mangle; policy accept;
    ip saddr 192.168.122.0/24 meta l4proto { tcp, udp } \
      th dport 53 ct mark set 0x00000f41
  }
}

Το priority mangle είναι αρνητικό, γεγονός που τοποθετεί αυτή την αλυσίδα μπροστά από τις συνηθισμένες αλυσίδες φίλτρων που εγκαθιστά το πακέτο VPN σε προτεραιότητα μηδέν. Η σειρά των hooks είναι αυτό που κάνει τον κανόνα αποτελεσματικό· ο ίδιος κανόνας σε μια αλυσίδα που ταξινομείται μετά την αλυσίδα VPN είναι διακόσμηση.

Ο ίδιος ο αριθμός σήμανσης δεν είναι μεταφέρσιμος. Πάρτε την τιμή που δέχονται οι εγκατεστημένοι κανόνες VPN για την δική τους κίνηση, διαβάστε την από το ζωντανό σύνολο κανόνων και χρησιμοποιήστε την. Μια λάθος σήμανση παράγει έναν κανόνα που φορτώνει καθαρά, ταιριάζει με κάθε ερώτημα και δεν επιτρέπει τίποτα.

Κρατήστε την τρύπα στο πλάτος της θύρας 53

Όπως είναι γραμμένο, αυτό επιτρέπει DNS από το υποδίκτυο libvirt προς τον host μέσω TCP ή UDP θύρας 53 και τίποτα άλλο. Δεν αφήνει τους επισκέπτες να φτάσουν στο διαδίκτυο έξω από το τούνελ και δεν αφήνει τον host να ανοίξει συνδέσεις προς τους επισκέπτες. Αν ένας επισκέπτης χρειαστεί αργότερα άλλη υπηρεσία του host, προσθέστε ξεχωριστό κανόνα που ονομάζει αυτή τη θύρα προορισμού αντί να χαλαρώσετε αυτόν.

Να είστε ειλικρινείς για το τι ανταλλάσσετε. Ένας επισκέπτης που μπορεί να φτάσει σε resolver μπορεί επίσης να περάσει αυθαίρετα δεδομένα μέσα από ερωτήματα DNS, και αυτή η εξαίρεση είναι ένα σκόπιμο κενό στο όριο του VPN και όχι μια δήλωση ότι το τοπικό δίκτυο είναι αξιόπιστο. Ο περιορισμός της πηγής στο 192.168.122.0/24 κρατά το κενό μακριά από κάθε άλλο τοπικό υποδίκτυο, και η μέτρηση ερωτημάτων από αυτή την πηγή είναι φθηνή αν η απειλή σας απασχολεί.

Κάντε το να επιβιώσει σε επανεκκίνηση και αποδείξτε και τα δύο μισά

Ένας κανόνας που πληκτρολογείται σε προτροπή κελύφους εξαφανίζεται στην επόμενη εκκίνηση, και ένας κανόνας που φορτώνεται αφού η διεπαφή VPN περνά ήδη κίνηση χάνει την κούρσα στην πρώτη σύνδεση. Βάλτε τον πίνακα στη μόνιμη διαμόρφωση nftables του host, ή σε μια unit που διατάσσεται πριν από την υπηρεσία VPN, και ελέγξτε τη σειρά αντί να την υποθέσετε.

Η επαλήθευση χρειάζεται τρεις ξεχωριστές απαντήσεις. Επιβεβαιώστε ότι η αλυσίδα είναι φορτωμένη και διατεταγμένη πρώτη, επιβεβαιώστε ότι η καταχώριση conntrack δείχνει τη σήμανση και προς τις δύο κατευθύνσεις, και επιβεβαιώστε ότι μια αναζήτηση επισκέπτη επιστρέφει διεύθυνση. Στη συνέχεια επιβεβαιώστε το άλλο μισό: η συνηθισμένη κίνηση ιστού του επισκέπτη προς δημόσιο host εξακολουθεί να αποτυγχάνει όσο το τούνελ είναι κάτω ή μπλοκάρει. Αν το DNS δουλεύει και όλα τα άλλα διαρρέουν, ο κανόνας σας είναι ευρύτερος από τον παραπάνω.

Αν οι αναζητήσεις εξακολουθούν να αποτυγχάνουν αφού μπει η σήμανση, αντισταθείτε στην παρόρμηση να διευρύνετε την πηγή. Ελέγξτε πού προωθεί το dnsmasq, αν ο resolver του επισκέπτη δείχνει στο 192.168.122.1 ή σε δημόσια διεύθυνση που πληκτρολόγησε κάποιος, και αν το ερώτημα φτάνει καθόλου στον host. Η σήμανση επιτρέπει το πακέτο και τίποτα άλλο, οπότε ένα κακό upstream ή ένα χαλασμένο εικονικό δίκτυο παραμένουν χαλασμένα όσα κανόνες κι αν προσθέσετε.

Σχετικά άρθρα