NET_ADMIN είναι η δυνατότητα του Linux που επιτρέπει σε μια διεργασία να εκτελεί διαχείριση δικτύου, και σε ένα container κάνει ακριβώς αυτό μέσα στον χώρο ονομάτων δικτύου όπου εκτελείται η διεργασία. Δεν είναι άδεια για άνοιγμα socket και δεν είναι υποκατάστατο συσκευής ή διαδρομής. Το ενδιαφέρον ερώτημα δεν είναι ποτέ αν η δυνατότητα έχει δοθεί, αλλά ποιος χώρος ονομάτων δέχεται την αλλαγή.

Τι καλύπτει η δυνατότητα

Μέσα στον χώρο ονομάτων του, μια διεργασία που κρατά NET_ADMIN μπορεί να ανεβάζει και να κατεβάζει διεπαφές, να εκχωρεί διευθύνσεις, να προσθέτει και να αφαιρεί διαδρομές και να γράφει κανόνες firewall, δηλαδή την ομάδα πράξεων που συγκεντρώνει το capabilities(7) κάτω από αυτή τη δυνατότητα. Μπορεί επίσης να ρυθμίζει παραμέτρους σε επίπεδο διεπαφής που ελέγχουν πώς ο πυρήνας βάζει σε ουρά και φιλτράρει την κίνηση. Ένας πελάτης VPN χρειάζεται συνήθως μερικές από αυτές κατά την εκκίνηση και τίποτε άλλο μετά. Γι' αυτό τα περισσότερα images ζητούν μεγαλύτερη εμβέλεια από όση χρησιμοποιούν.

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

Ο χώρος ονομάτων καθορίζει την ακτίνα

Ένα container στο δικό του δίκτυο γέφυρας φτάνει το δικό του loopback, τις δικές του διεπαφές και τον δικό του πίνακα δρομολόγησης. Η χορήγηση NET_ADMIN εκεί αφήνει τον πελάτη VPN να χτίσει σήραγγα χωρίς να αγγίξει τις αποφάσεις δρομολόγησης του υποδοχέα, που είναι η διάταξη που υποθέτουν τα περισσότερα images container.

Αλλάξτε αυτό το container σε δίκτυο υποδοχέα και η ίδια χορήγηση τώρα επεξεργάζεται τις διαδρομές και το firewall του υποδοχέα, επειδή δεν έχει μείνει ξεχωριστός χώρος ονομάτων. Ο πελάτης που έπρεπε να διαχειρίζεται μία σήραγγα μπορεί τότε να ανακατευθύνει την κίνηση ολόκληρου του μηχανήματος, και ένα λάθος στο script αποδόμησης αφήνει στον υποδοχέα κανόνες που δεν έγραψε κανείς. Τίποτε στη δυνατότητα δεν άλλαξε· άλλαξε το πλαίσιο. Γι' αυτό το ίδιο αρχείο compose συμπεριφέρεται διαφορετικά σε δύο υποδοχείς.

Τρεις προϋποθέσεις που συγχωνεύονται σε μία

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

services:
  vpn:
    image: example/vpn-client:latest
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1

Διαβάστε την τεκμηρίωση του ίδιου του image για το ποια sysctl χρειάζεται, επειδή ένα sysctl μέσα σε container μπορεί να απαιτεί πρόσθετο προνόμιο ή ρύθμιση σε επίπεδο υποδοχέα. Όπου το image υποστηρίζει λειτουργία μόνο χώρου χρήστη, δεν χρειάζεται καθόλου συσκευή και η λίστα δυνατοτήτων μικραίνει ανάλογα.

Δώστε τη στενή πράξη, όχι τη λειτουργία

Η προνομιούχος λειτουργία παραδίδει κάθε δυνατότητα και ταυτόχρονα διευρύνει την πρόσβαση σε συσκευές, ώστε να κρύβει ποια από τις τρεις προϋποθέσεις έλειπε. Κάνει επίσης τις αστοχίες του container δυσδιάκριτες από αλλαγές του υποδοχέα. Προτιμήστε ρητή λίστα ακόμη και όταν είναι μακρύτερη.

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

Τα μυστικά ανήκουν σε ξεχωριστή απόφαση. Η κατοχή NET_ADMIN δεν λέει τίποτε για την ταυτότητα ομοτίμου που παρουσιάζει ο πελάτης, τα διαπιστευτήρια που φορτώνει ή το πώς περιστρέφονται. Η διαχείριση δικτύου δεν παρέχει εμπιστοσύνη.

Επαληθεύστε την αλλαγή και καταγράψτε γιατί υπάρχει η χορήγηση

Επιβεβαιώστε τι έλαβε πραγματικά το container πριν αποσφαλματώσετε τη σήραγγα. Η επιθεώρηση παρακάτω αναφέρει τις προστιθέμενες δυνατότητες και τη λειτουργία δικτύου και έπειτα δείχνει πώς φαίνεται η λίστα διεπαφών από μέσα:

docker inspect --format '{{.HostConfig.CapAdd}} {{.HostConfig.NetworkMode}} {{.HostConfig.Privileged}}' vpn
docker exec vpn sh -c 'grep CapEff /proc/self/status'
docker exec vpn ip -br addr
docker exec vpn ip route

Αν η δυνατότητα υπάρχει και η λίστα διεπαφών είναι ακόμη κενή, ο πελάτης απέτυχε πριν μπορέσει να δημιουργήσει οτιδήποτε, και τα logs του container είναι το επόμενο σημείο. Αν η σήραγγα υπάρχει αλλά η κίνηση δεν ρέει, ο πίνακας δρομολόγησης μέσα στο container απαντά στο επόμενο ερώτημα.

Δοκιμάστε και τη διαδρομή αποδόμησης, επειδή ένας πελάτης που γράφει κανόνες firewall μπορεί να τους αφήσει πίσω. Σταματήστε το container και ελέγξτε ξανά το σύνολο κανόνων του υποδοχέα αν χρησιμοποιείται δίκτυο υποδοχέα. Μια χορήγηση που χρειάζεται μόνο δύο δευτερόλεπτα στην εκκίνηση δεν θα έπρεπε να περιγράφεται στο αρχείο compose ως μόνιμη απαίτηση χωρίς σημείωση που το εξηγεί.

Γράψτε τον λόγο δίπλα σε κάθε δυνατότητα: ποια πράξη τη χρειάστηκε και τι αποτυγχάνει χωρίς αυτή. Αυτή η σημείωση επιβιώνει από ενημερώσεις image, και είναι η διαφορά ανάμεσα σε μια ελεγμένη λίστα προνομίων και σε μια που μεγάλωσε με αντιγραφή και επικόλληση.

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