Φράξτε ένα εύρος προορισμού για κάθε pool πελατών VPN
Ένας κανόνας nftables αρκεί για να αρνηθεί ένα πρόθεμα προορισμού σε έναν επιτρεπόμενο pool VPN χωρίς να αγγίξει την κίνηση της ίδιας της πύλης. Ταιριάξτε το hook και τη θέση.
Ένας κανόνας μπορεί να κρατήσει έναν επιτρεπόμενο pool VPN μακριά από ένα εύρος προορισμού χωρίς να διαταράξει τίποτε άλλο από όσα κάνει η πύλη. Ο κανόνας είναι σύντομος· αυτό που αποφασίζει αν θα δουλέψει είναι το hook στο οποίο ζει και η θέση του στην αλυσίδα. Αν κάνετε λάθος σε αυτά τα δύο, παίρνετε ένα firewall που φαίνεται σωστό και συμπεριφέρεται ασυνεπώς. Ξεκινήστε από το τι κάνει το πακέτο όταν το βλέπει ο κανόνας.
Τι αντιστοιχίζει πραγματικά ο κανόνας
Ο κανόνας αντιστοιχίζει τρία πράγματα ταυτόχρονα: μια διεπαφή εισόδου, ένα πρόθεμα πηγής και ένα πρόθεμα προορισμού. Και τα τρία πρέπει να ισχύουν πριν εφαρμοστεί το drop, και αυτό τον κρατά στενό. Το να τον διαβάζετε ως μία έκφραση είναι ευκολότερο από το να τον διαβάζετε ως τρεις ξεχωριστές πολιτικές.
Η αντιστοίχιση διεπαφής είναι αυτό που ξεχωρίζει την προωθημένη κίνηση πελατών από τις δικές της συνδέσεις της πύλης. Χωρίς αυτήν, ένας κανόνας που ονομάζει μόνο το pool πηγής θα επηρέαζε και πακέτα που παράγει η ίδια η πύλη από αυτή τη διεύθυνση, αν ποτέ το κάνει. Το πρόθεμα πηγής περιορίζει την πολιτική στους επιτρεπόμενους πελάτες και το πρόθεμα προορισμού σε ένα εύρος. Διαβάστε τον κανόνα ως τομή και όχι ως λίστα.
Γράψτε τις τρεις τιμές πριν αλλάξετε οτιδήποτε: το όνομα της διεπαφής του tunnel, το pool που μοιράζει ο διακομιστής και το πρόθεμα που σκοπεύετε να αρνηθείτε. Ένα τυπογραφικό λάθος σε οποιοδήποτε από αυτά παράγει κανόνα που αναλύεται καθαρά και δεν προστατεύει τίποτα. Κρατήστε αυτές τις τρεις τιμές στο αρχείο αλλαγών δίπλα στον κανόνα.
Το hook αποφασίζει σε ποιον εφαρμόζεται ο κανόνας
Μια αλυσίδα netfilter προσαρτάται σε ένα hook, και το hook αποφασίζει ποια πακέτα βλέπει ποτέ η αλυσίδα. Το hook forward βλέπει κίνηση που δρομολογείται μέσα από την πύλη, και αυτή είναι η κίνηση από πελάτη σε προορισμό. Ό,τι άλλο υπάρχει στην αλυσίδα απευθύνεται σε άλλο κοινό.
Το hook input βλέπει κίνηση που απευθύνεται στην ίδια την πύλη, οπότε ένας κανόνας εκεί ρυθμίζει την πρόσβαση στις δικές της υπηρεσίες και όχι τη διέλευση. Το hook output βλέπει κίνηση που παράγει η πύλη, δηλαδή το αντίθετο από αυτό που χρειάζεται μια πολιτική pool πελατών. Τα ονόματα αλυσίδων είναι αυθαίρετες ετικέτες που επιλέγει όποιος έγραψε το ruleset, οπότε μην συνάγετε το hook από το όνομα. Ελέγξτε πού προσαρτάται η αλυσίδα πριν υποθέσετε τι μπορεί να αντιστοιχίσει.
| Hook | Traffic it sees | Right for this policy |
|---|---|---|
| input | Addressed to the gateway | No, that is the host's own services |
| forward | Routed through the gateway | Yes, for client-to-destination traffic |
| output | Generated by the gateway | No, that is the opposite direction |
Η ανάγνωση της προσάρτησης είναι έλεγχος μιας γραμμής που εμποδίζει έναν κανόνα να προσγειωθεί σε αλυσίδα που δεν βλέπει ποτέ το πακέτο.
Τοποθετήστε τον κανόνα πριν από το ευρύ accept
Οι κανόνες αξιολογούνται με σειρά και η πρώτη ετυμηγορία κερδίζει. Ένα ευρύ accept νωρίτερα στην αλυσίδα τερματίζει την αξιολόγηση για τα πακέτα που αντιστοιχίζει, οπότε ένα drop που προστίθεται μετά δεν εκτελείται ποτέ γι' αυτά. Αυτός ο κανόνας σειράς είναι ο λόγος που ένας σωστός στην όψη κανόνας μπορεί να μην έχει κανένα αποτέλεσμα.
Εισαγάγετε τον κανόνα πριν από το accept και μην τον προσθέτετε στο τέλος. Αν η αλυσίδα περιέχει ήδη ένα γενικό accept για τη διεπαφή του tunnel, ο νέος κανόνας πρέπει να προηγείται, αλλιώς είναι διακοσμητικός. Ελέγξτε τη σειρά που προκύπτει και όχι το αρχείο που επεξεργαστήκατε, γιατί ένα ruleset που συναρμολογήθηκε από πολλά αρχεία μπορεί να μην ταιριάζει με κανένα από αυτά. Έπειτα επιβεβαιώστε με ένα δοκιμαστικό πακέτο από το pool.
sudo nft list chain inet filter forward
sudo nft insert rule inet filter forward iifname "tun0" ip saddr 10.90.0.0/24 ip daddr 198.51.100.0/24 drop
sudo nft -c -f /etc/nftables.conf
Η τρίτη εντολή αναλύει το αρχείο χωρίς να το εφαρμόζει, κάτι που πιάνει συντακτικά λάθη πριν γίνουν διακοπή. Εφαρμόστε με σχέδιο επαναφοράς, γιατί ένας λανθασμένος κανόνας σε αλυσίδα forward μπορεί να κόψει το tunnel πάνω από το οποίο εργάζεστε.
Οι υπάρχουσες ροές δεν νοιάζονται για τον νέο σας κανόνα
Μια εγγραφή conntrack που δημιουργήθηκε πριν υπάρξει ο κανόνας συνεχίζει να αντιστοιχίζει την προηγούμενη αποδοχή. Γι' αυτό ένα νέο drop μερικές φορές φαίνεται να δουλεύει για νέες συνδέσεις και να μην κάνει τίποτα για εκείνη που δοκιμάζεται.
Διαβάστε την αντιστοίχιση κατάστασης στην αρχή της αλυσίδας. Αν δέχεται κίνηση established και related πριν από τον κανόνα σας, κάθε ροή που ήδη εξελίσσεται συνεχίζει να ρέει μέχρι να κλείσει. Συνήθως αυτή είναι η συμπεριφορά που θέλετε για κανόνα έκτακτης ανάγκης, και είναι μπερδεμένη όταν περιμένετε άμεση διακοπή. Αποφασίστε ποιο αποτέλεσμα θέλετε πριν την ανάπτυξη. Ένα τεστ που επαναχρησιμοποιεί ανοιχτή σύνδεση θα σας πει λάθος ιστορία.
sudo conntrack -L -s 10.90.0.14 -d 198.51.100.20
sudo nft list ruleset | grep -n -A3 'ct state'
Η πρώτη εντολή δείχνει αν υπάρχει ροή και η δεύτερη αν ένας πρώιμος κανόνας κατάστασης συνεχίζει να τη δέχεται. Και οι δύο είναι μόνο για ανάγνωση και ασφαλείς κατά τη διάρκεια περιστατικού.
Τι δεν είναι αυτός ο κανόνας
Ο κανόνας δεν είναι μαύρη λίστα τομέων, πολιτική IPv6 ή περιορισμός σε μεμονωμένο λογαριασμό εφαρμογής.
Καθένα από αυτά χρειάζεται τον δικό του μηχανισμό. Ένα μπλοκ τομέα πρέπει να επιλύει ονόματα, κάτι που ένα φίλτρο πακέτων δεν κάνει. Η κίνηση IPv6 χρειάζεται δική της αντιστοίχιση, γιατί μια έκφραση ip δεν λέει τίποτα για πακέτα ip6. Ένας περιορισμός σε επίπεδο εφαρμογής ανήκει στην υπηρεσία ή σε πιστοποιημένο proxy και όχι σε αντιστοίχιση προθέματος. Το να κρατάτε αυτές τις απαιτήσεις χωριστά εμποδίζει έναν στενό κανόνα να κληθεί να κάνει τέσσερις δουλειές.
Το συμβόλαιο που παρέχει αυτός ο κανόνας είναι ακριβές: η κίνηση από επιτρεπόμενο pool προς ένα πρόθεμα προορισμού απορρίπτεται, ενώ η άσχετη κίνηση της πύλης διατηρεί την υπάρχουσα πολιτική της. Γράψτε αυτή την πρόταση δίπλα στον κανόνα και ο επόμενος θα ξέρει για τι ήταν.