OpenVPN auth-user-pass: αρχείο, stdin ή προτροπή; Πώς να επιλέξετε
Διαλέξτε ανάμεσα στην προτροπή της κονσόλας, ένα αρχείο διαπιστευτηρίων, μια ροή και τη διεπαφή διαχείρισης, και μετά διορθώστε τα σφάλματα που μοιάζουν μόνο με λάθος κωδικό.
Τρία πράγματα καθορίζουν ποια πηγή διαπιστευτηρίων πρέπει να χρησιμοποιήσετε: αν κάποιος κάθεται στην κονσόλα, αν το μυστικό επιτρέπεται να ζει στον δίσκο και αν κάποια άλλη διεργασία πρέπει να απαντήσει στην προτροπή. Αν κάνετε λάθος επιλογή, ο πελάτης αναφέρει πρόβλημα stdin ενώ ο κωδικός είναι απολύτως έγκυρος, και αυτό στέλνει τους περισσότερους στον διακομιστή χωρίς λόγο. Επιλέξτε πρώτα τη διαδρομή και τα μηνύματα σφάλματος βγάζουν νόημα μόνο όταν ξέρετε ποια διαδρομή τα παρήγαγε.
Οι τρεις συνθήκες που το καθορίζουν
Η προτροπή της κονσόλας είναι η μόνη διαδρομή που χρειάζεται άνθρωπο, άρα η μόνη που αποτυγχάνει σιωπηλά σε μια μονάδα systemd ή σε ένα container. Αν ένας άνθρωπος ξεκινήσει τον πελάτη και πληκτρολογήσει τον κωδικό, κανένα αρχείο δεν εμπλέκεται και τίποτα ευαίσθητο δεν φτάνει στον δίσκο. Αν ο πελάτης ξεκινήσει κατά την εκκίνηση, η ίδια προτροπή γίνεται κόλλημα και το timeout εμφανίζεται συνήθως ως γενική αποτυχία σύνδεσης και όχι ως σφάλμα διαπιστευτηρίων.
Ένα αρχείο διαπιστευτηρίων είναι η σωστή απάντηση όταν η διεργασία ξεκινά χωρίς επίβλεψη και το μυστικό επιτρέπεται να επιβιώσει στον δίσκο υπό ελεγχόμενο σύνολο δικαιωμάτων. Όταν το μυστικό δεν επιτρέπεται να γραφτεί καθόλου - πολιτική μόνο θησαυροφυλακίου, βραχύβιο token - χρειάζεστε μια ροή που ο πελάτης μπορεί να ανοίξει, που στην πράξη σημαίνει υποκατάσταση διεργασίας ή βοηθό που γράφει σε περιγραφέα αρχείου. Η διεπαφή διαχείρισης καλύπτει την τέταρτη περίπτωση: έναν ελεγκτή που ήδη διαχειρίζεται τον κύκλο ζωής της σήραγγας και μπορεί να απαντά σε ερωτήσεις μέσω socket.
- Άνθρωπος στην κονσόλα, χωρίς αυτοματισμό: διαδραστική προτροπή.
- Εκκίνηση χωρίς επίβλεψη, το μυστικό μπορεί να αποθηκευτεί: αρχείο διαπιστευτηρίων με mode 0600.
- Εκκίνηση χωρίς επίβλεψη, το μυστικό δεν μπορεί να αποθηκευτεί: υποκατάσταση διεργασίας ή fd όπου γράφει ένας πράκτορας μυστικών.
- Μια άλλη διεργασία κατέχει τον πελάτη: διεπαφή διαχείρισης.
Όταν ταιριάζουν δύο απαντήσεις, προτιμήστε αυτή που κρατά το μυστικό έξω από το argv και έξω από το ιστορικό του shell. Ένας κωδικός που περνά ως όρισμα προγράμματος είναι αναγνώσιμος από κάθε τοπικό χρήστη μέσω της λίστας διεργασιών, και αυτή η έκθεση δύσκολα αναιρείται.
Τι κάνει στην πραγματικότητα κάθε διαδρομή εισόδου
Το --auth-user-pass από μόνο του ζητά όνομα χρήστη και κωδικό στην κονσόλα. Με όνομα αρχείου, ο πελάτης παίρνει την πρώτη γραμμή ως όνομα χρήστη και τη δεύτερη ως κωδικό. Τίποτα δεν υποστηρίζει εισαγωγικά, σχόλια ή σύνταξη κλειδί-τιμή. Αυτή είναι όλη η μορφή, οπότε όποιος το επεξεργάζεται περιμένοντας αρχείο INI το χαλάει. Ένα ενσωματωμένο μπλοκ <auth-user-pass> κρατά τις ίδιες δύο γραμμές μέσα στο προφίλ, κάτι που κάνει το ίδιο το προφίλ μυστικό και το βάζει στην ίδια κατηγορία χειρισμού με ένα ιδιωτικό κλειδί.
Οι άλλες δύο διαδρομές είναι μια ροή και ένα socket. Το OpenVPN χρειάζεται μόνο έναν αναγνώσιμο περιγραφέα αρχείου, άρα δέχεται υποκατάσταση διεργασίας, μια καταχώρηση /dev/fd με σωλήνα ή ένα όνομα αρχείου που είναι στην πραγματικότητα FIFO. Η διεπαφή διαχείρισης είναι διαφορετική στη φύση της: ο πελάτης ζητά τις τιμές από μια εποπτεύουσα διεργασία αντί να τις διαβάζει μόνος του. Αυτή η διαφορά μετρά στην επανασύνδεση: ένα αρχείο διαπιστευτηρίων, ένα FIFO όπου ένας βοηθός μυστικών μπορεί να ξαναγράψει και η διεπαφή διαχείρισης μπορούν να τροφοδοτήσουν ξανά χωρίς άνθρωπο. Η υποκατάσταση διεργασίας δεν μπορεί, γιατί ο περιγραφέας καταναλώνεται στην πρώτη ανάγνωση.
Το αρχείο πρέπει να είναι ακριβώς δύο γραμμές
Δύο τρόποι αποτυχίας καλύπτουν τα περισσότερα χαλασμένα αρχεία διαπιστευτηρίων. Ένας επεξεργαστής των Windows αφήνει καταλήξεις CRLF, η επιστροφή μεταφοράς γίνεται μέρος του κωδικού και ο διακομιστής απορρίπτει μια τιμή που φαίνεται σωστή στην οθόνη. Μια κενή δεύτερη γραμμή - μια άδεια γραμμή εκεί όπου ανήκει ο κωδικός - αφήνει τον πελάτη με κενό κωδικό, τον οποίο ο διακομιστής απορρίπτει παρόλο που η τιμή στην οθόνη φαίνεται σωστή. Μια επιπλέον αλλαγή γραμμής μετά τον κωδικό είναι ακίνδυνη. Γράψτε το αρχείο από το shell, όχι από επεξεργαστή, και ελέγξτε τα byte:
install -m 600 /dev/null /etc/openvpn/client.creds
printf '%s\n%s\n' "$VPN_USER" "$VPN_PASS" > /etc/openvpn/client.creds
od -c /etc/openvpn/client.creds | head -3Η διαδρομή έχει τόση σημασία όσο το περιεχόμενο. Μια σχετική διαδρομή επιλύεται ως προς τον κατάλογο εργασίας της διεργασίας, που για μια υπηρεσία σπάνια είναι ο κατάλογος όπου δοκιμάσατε. Χρησιμοποιήστε απόλυτη διαδρομή, κάντε το αρχείο ιδιοκτησία του λογαριασμού που εκτελεί τον πελάτη και κρατήστε mode 0600 ώστε η ομάδα και οι άλλοι να μην μπορούν να το διαβάσουν. Το εγχειρίδιο του OpenVPN 2.6 απαριθμεί τις αποδεκτές μορφές της οδηγίας. Ελέγξτε το πριν εφεύρετε μια τρίτη.
Δοκιμάστε το αρχείο πριν κατηγορήσετε τον διακομιστή. Η εκτέλεση του openvpn --config client.ovpn --auth-user-pass /etc/openvpn/client.creds --verb 4 τυπώνει αν άνοιξε το αρχείο και, αργότερα, αν έγιναν δεκτά τα διαπιστευτήρια, κάτι που σας λέει ποιο επίπεδο να αλλάξετε μετά.
Ροές, stdin και τα σφάλματα που παράγουν
Το πέρασμα του κωδικού μέσω σωλήνα είναι το πρώτο που δοκιμάζουν οι περισσότεροι και η διαδρομή με τις περισσότερες εκπλήξεις. Η υποκατάσταση διεργασίας δουλεύει γιατί ο πελάτης χρειάζεται μόνο έναν αναγνώσιμο περιγραφέα: openvpn --config client.ovpn --verb 3 --auth-user-pass <(printf '%s\n%s\n' "$VPN_USER" "$VPN_PASS"). Το πέρασμα /dev/stdin δουλεύει μόνο όταν το stdin είναι ακόμη ανοιχτό και αναγνώσιμο τη στιγμή που ρωτά ο πελάτης, κάτι που δεν ισχύει σε ένα pipeline που το έχει ήδη καταναλώσει.
Το ERROR: could not read Auth username from stdin έχει δύο διαφορετικές αιτίες. Σε ορισμένους πελάτες 2.3.x το μήνυμα προερχόταν από ελάττωμα χειρισμού stdin που διόρθωσαν μεταγενέστερες εκδόσεις 2.3, άρα ένας τόσο παλιός πελάτης βελτιώνεται μόνο με αναβάθμιση. Σε σύγχρονο πελάτη η ίδια διατύπωση σημαίνει ότι ο πελάτης ζήτησε είσοδο κονσόλας και το stdin δεν ήταν τερματικό - ακριβώς η κατάσταση σε μονάδα systemd, εργασία cron ή container που ξεκίνησε χωρίς -t.
Το auth-nocache προσθέτει έναν τρίτο βρόχο που μοιάζει με χαλασμένο κωδικό. Απορρίπτει τα διαπιστευτήρια από τη μνήμη μετά τη χρήση, οπότε μια επανασύνδεση που προκλήθηκε από αλλαγή δικτύου δεν έχει τι να επαναλάβει και η προτροπή επιστρέφει. Αυτή είναι η οδηγία που λειτουργεί όπως σχεδιάστηκε. Το auth-nocache αλλάζει τι κρατά ο πελάτης στη μνήμη, όχι τι πιστεύει ο διακομιστής ή ο πάροχος ταυτότητας για τον λογαριασμό, άρα όλη η διόρθωση είναι να ξαναδοθεί το ίδιο αρχείο, ξαναδιαβασμένο στην επανεκκίνηση - και για διαχειριζόμενη σύνδεση αυτή η παροχή πρέπει να έρχεται από το εγκεκριμένο θησαυροφυλάκιο μυστικών, όχι από κωδικό σε σενάριο.
Η διεπαφή διαχείρισης όταν μια άλλη διεργασία κατέχει την προτροπή
Ένας ελεγκτής που ήδη εποπτεύει τη σήραγγα μπορεί να απαντά και στις ερωτήσεις της. Ξεκινήστε τον πελάτη με --management 127.0.0.1 7505, διαβάστε τις γραμμές κατάστασης και προσέξτε το >PASSWORD:Need 'Auth' username/password. Ο ελεγκτής απαντά με username "Auth" alice ακολουθούμενο από password "Auth" ... σε ξεχωριστές γραμμές εντολών. Το token 'Auth' αντηχεί το αναγνωριστικό του αιτήματος και πρέπει να ταιριάζει, αλλιώς η απάντηση αγνοείται και ο πελάτης περιμένει.
Το κόστος είναι μια μηχανή καταστάσεων που τώρα κατέχετε: σειρά συνδέσεων, επανεκκινήσεις πελάτη και ένα τοπικό socket που άλλοι χρήστες στον κεντρικό υπολογιστή δεν πρέπει να φτάνουν. Αυτό που αγοράζετε είναι διαπιστευτήρια που παρέχονται κατά την εκτέλεση, χωρίς αρχείο στον δίσκο και χωρίς προτροπή που μπορεί να κολλήσει. Αν τίποτα άλλο στη στοίβα σας δεν μιλά ήδη το πρωτόκολλο, αυτή η διαδρομή προσθέτει ένα στοιχείο προς συντήρηση.
Αποτυχίες που μοιάζουν με προβλήματα διαπιστευτηρίων
Μια χειραψία TLS που δεν ολοκληρώνεται ποτέ, ή ένα VERIFY ERROR: depth=0, error=certificate signature failure, είναι πρόβλημα εμπιστοσύνης και συμβαίνει πριν διαβαστεί οποιοδήποτε όνομα χρήστη. Ένας πελάτης proto tcp στραμμένος σε ακροατή UDP αποτυγχάνει στο ίδιο σημείο: τα πακέτα δεν φτάνουν ποτέ στο στάδιο ελέγχου ταυτότητας, άρα κάθε κωδικός φαίνεται λάθος κατ' συσχέτιση. Κρατήστε την επαλήθευση πιστοποιητικών ενεργή πριν σταλούν τα διαπιστευτήρια. Μια οικεία προτροπή δεν λέει τίποτα για το ποιος λαμβάνει τον κωδικό. Ελέγξτε την αλυσίδα πιστοποιητικών, το κοινό όνομα και τη μεταφορά πριν αγγίξετε τα διαπιστευτήρια.
Τα σφάλματα shell στο σενάριο που συναρμολογεί το προφίλ είναι το άλλο ψεύτικο ίχνος. Ένα κενό που λείπει μέσα στο [ ! -f "$file" ] παράγει command not found, το σενάριο σταματά νωρίς, το προφίλ δεν ξαναχτίζεται ποτέ και ο πελάτης ξεκινά με το προηγούμενο. Αυτό το σφάλμα ανήκει στο shell, όχι στον έλεγχο ταυτότητας, και κανένα ξαναγράψιμο του κωδικού δεν θα το σβήσει.
Δεν είναι κάθε προτροπή σε αυτή τη ροή αυτό το διαπιστευτήριο. Μια φράση πρόσβασης ιδιωτικού κλειδιού, μια σύνδεση διαμεσολαβητή HTTP και ο κωδικός της υπηρεσίας είναι τρία διαφορετικά μυστικά που ζητούνται σε διαφορετικές φάσεις, και μια φράση πρόσβασης κλειδιού συνήθως τη χειρίζεται ο πελάτης ή ένας πράκτορας και όχι το auth-user-pass. Αν η προτροπή εμφανιστεί πριν στηθεί η συνεδρία TLS, απαντάτε σε λάθος ερώτηση και καμία επαναφορά λογαριασμού δεν βοηθά. Μόλις αποκλειστεί η λάθος προτροπή, οι υπόλοιποι έλεγχοι ξεκινούν από το πρώιμο επίπεδο:
- Διαβάστε το πρώτο σφάλμα πρωτοκόλλου, όχι την τελευταία γραμμή διαπιστευτηρίων: TLS, μετά έλεγχος ταυτότητας, μετά push.
- Επιβεβαιώστε ότι το αρχείο είναι δύο γραμμές, δεν έχει επιστροφές μεταφοράς και αναφέρεται με απόλυτη διαδρομή.
- Επιβεβαιώστε ότι το προφίλ και η γραμμή εντολών δεν διαφωνούν για την οδηγία.
- Ξεχωρίστε το "τα διαπιστευτήρια έγιναν δεκτά" από το "η κίνηση ρέει" - η δρομολόγηση και το DNS είναι μεταγενέστερο επίπεδο.
Όταν ο πελάτης φτάσει στη φάση push, σταματήστε να κοιτάτε τα διαπιστευτήρια και αρχίστε να διαβάζετε τις διαδρομές και τους διακομιστές DNS που έστειλε ο διακομιστής. Αυτό είναι το επόμενο πρόβλημα, και δεν έχει καμία σχέση με τον κωδικό που μόλις διορθώσατε.