Το OpenVPN δεν βρίσκει το ca.crt παρόλο που το προφίλ φορτώνεται
Η διαδρομή του προφίλ δεν είναι η βάση για τα αρχεία μέσα του. Δείτε γιατί ένα απόλυτο --config αποτυγχάνει ακόμη στο ca.crt και πώς η εκκίνηση αποφασίζει την απάντηση.
Η υπηρεσία ξεκινά, διαβάζει το προφίλ χωρίς παράπονο και μετά πεθαίνει σε μια γραμμή που μοιάζει άσχετη: δεν μπορεί να ανοίξει το ca.crt. Τίποτα στο πιστοποιητικό δεν άλλαξε, και η διαδρομή του προφίλ στο αρχείο unit είναι απόλυτη. Αυτός ο συνδυασμός είναι το σημάδι. Η διαδρομή που δώσατε εντοπίζει ένα αρχείο, και τα ονόματα μέσα σε εκείνο το αρχείο επιλύονται κάπου αλλού εντελώς, οπότε μια εκκίνηση που φαίνεται πλήρως προσδιορισμένη μπορεί ακόμη να διαβάζει τα κλειδιά της από κατάλογο που κανείς δεν είχε σκοπό.
Η αποτυχία έχει λίγες αιτίες, και αξίζει να τις ξεχωρίσουμε με σειρά: τον βασικό κατάλογο που είχε στην πραγματικότητα η διεργασία, το πλαίσιο εκκίνησης της υπηρεσίας και τα δικαιώματα ή το sandbox γύρω από το αρχείο όταν η διαδρομή είναι σωστή. Καθένα αφήνει διαφορετικό ίχνος — στο unit, στη διεργασία και στο σύστημα αρχείων.
Η διαδρομή του προφίλ δεν είναι βασικός κατάλογος
Φανταστείτε μια διεργασία που ξεκινά στο /tmp και της δίνεται το /etc/vpn/prod/tenant-a.ovpn. Μέσα σε αυτό το προφίλ, η γραμμή ca ca.crt ονομάζει σχετική διαδρομή. Τίποτα στο όρισμα που εντόπισε το προφίλ δεν ξαναγράφει αυτό το όνομα, οπότε η διεργασία ψάχνει το /tmp/ca.crt και αναφέρει αρχείο που λείπει.
Το μπερδεμένο είναι η σειρά των σφαλμάτων. Το OpenVPN αναλύει πρώτα τη διαμόρφωση και ανοίγει τα αρχεία αναφοράς καθώς τα φτάνει, οπότε ένα τυπογραφικό στο προφίλ αναφέρεται πριν αγγιχτεί οποιοδήποτε κλειδί, ενώ ένα πιστοποιητικό που λείπει εμφανίζεται μόνο όταν η ανάλυση φτάσει ως εκεί. Ένα προφίλ που φορτώνεται είναι επομένως απόδειξη ότι η σύνταξη είναι εντάξει, όχι ότι βρέθηκαν τα αρχεία που ονομάζει.
Τι ξεχωρίζει το εγχειρίδιο: --config και --cd
Το εγχειρίδιο του OpenVPN 2.6 περιγράφει δύο διακριτές επιλογές. Η μία φορτώνει αρχείο διαμόρφωσης. Η άλλη αλλάζει τον κατάλογο της διεργασίας πριν διαβαστούν η διαμόρφωση, το κλειδί, το script και άλλα αρχεία, και απαιτεί απόλυτο κατάλογο χωρίς αναφορά στον τρέχοντα.
openvpn --cd /etc/vpn/prod --config tenant-a.ovpn
Αυτή η κλήση είναι σχήμα, όχι οδηγία να εκκινήσετε το προφίλ κάποιου άλλου. Αυτό που σας δίνει είναι ντετερμινισμός: η βάση για κάθε σχετικό όνομα στην αλυσίδα δηλώνεται στην εντολή αντί να κληρονομείται από όποιο κέλυφος ή διαχειριστή ξεκίνησε τη διεργασία. Η εναλλακτική είναι εξίσου έγκυρη και συχνά καλύτερη για μια υπηρεσία: αφήστε τον κατάλογο εργασίας ήσυχο και κάντε κάθε αρχείο αναφοράς απόλυτο μέσα στο προφίλ.
Ό,τι κι αν διαλέξετε, ελέγξτε όλη την αλυσίδα και όχι την πρώτη αποτυχία. Ένα προφίλ μπορεί να τραβήξει άλλο αρχείο διαμόρφωσης, και τα σχετικά ονόματα του αρχείου που περιλήφθηκε επιλύονται ως προς τον ίδιο κατάλογο διεργασίας, όχι ως προς τον κατάλογο του αρχείου που τα περιέλαβε. Οι διαδρομές καταγραφής, τα αρχεία ταυτοποίησης και τα βοηθητικά script ακολουθούν τον ίδιο κανόνα.
Η υπηρεσία ξεκινά αλλού
Ένα διαδραστικό κέλυφος στον κατάλογο του προφίλ δεν αποδεικνύει τίποτα για ένα συσκευασμένο unit. Οι διαχειριστές ορίζουν τον δικό τους κατάλογο εργασίας, και ένα script περιτυλίγματος μπορεί να τον αλλάξει ξανά πριν τρέξει το εκτελέσιμο. Το unit που αποτυγχάνει είναι η μόνη εκκίνηση για την οποία αξίζει να συλλογιστούμε.
systemctl show -p WorkingDirectory -p ExecStart --value openvpn@tenant-a
ls -l /proc/$(pgrep -n openvpn)/cwd
Η δεύτερη εντολή δείχνει τον κατάλογο που κρατά στην πραγματικότητα η ζωντανή διεργασία, και αυτό είναι πιο αξιόπιστο από το αρχείο unit όταν εμπλέκεται περιτύλιγμα. Αν τα δύο διαφωνούν, το περιτύλιγμα είναι η απάντησή σας και το unit είναι ψευδές ίχνος.
Μετά την αναζήτηση: δικαιώματα, chroot και sandbox
Ένας σωστός βασικός κατάλογος μπορεί ακόμη να δώσει το ίδιο μήνυμα, γιατί η επίλυση και η πρόσβαση είναι ξεχωριστά βήματα. Η διεργασία χρειάζεται δικαίωμα εκτέλεσης σε κάθε γονικό κατάλογο και δικαίωμα ανάγνωσης στο αρχείο, και ένα unit υπηρεσίας που κρύβει μέρος του συστήματος αρχείων αλλάζει το τι μπορεί να δει καθόλου η διεργασία.
Τρεις συνήθεις παραλλαγές παράγουν το ίδιο σφάλμα. Το αρχείο είναι αναγνώσιμο μόνο από το root ενώ η υπηρεσία αποβάλλει προνόμια πριν το ανοίξει. Το unit ορίζει μια προστατευτική όψη του συστήματος αρχείων που δεν περιλαμβάνει τον κατάλογο του προφίλ. Ο δαίμονας τρέχει με chroot, οπότε η διαδρομή που υπάρχει στον κεντρικό υπολογιστή δεν υπάρχει μέσα σε αυτή την όψη.
Διαγνώστε με την ιδιοκτησία του αρχείου και την ταυτότητα της διεργασίας, όχι χαλαρώνοντας τα δικαιώματα. Το να κάνετε ένα ιδιωτικό κλειδί αναγνώσιμο από όλους για να σιγήσετε αυτό το σφάλμα ανταλλάσσει μια ηχηρή αποτυχία με μια ήσυχη, και το κλειδί είναι το κομμάτι του καταλόγου που θέλετε λιγότερο να εκτεθεί.
Αποδείξτε τη διόρθωση με τη δική σας εκκίνηση
Επανεκκινήστε το πραγματικό unit από κατάλογο άσχετο με το προφίλ και παρατηρήστε την ίδια γραμμή εκκίνησης. Έπειτα επιβεβαιώστε ότι η διεργασία κρατά τον επιδιωκόμενο κατάλογο όσο τρέχει και ότι το πιστοποιητικό που φόρτωσε είναι αυτό που περιμένετε.
systemctl restart openvpn@tenant-a
systemctl status openvpn@tenant-a --no-pager
journalctl -u openvpn@tenant-a -n 20 --no-pager
Όταν η φόρτωση των διαδρομών πετύχει, η ταυτοποίηση και η δρομολόγηση παραμένουν ξεχωριστά στάδια με τις δικές τους αποτυχίες, και μια σύνδεση που ανεβαίνει αλλά δεν περνά κίνηση είναι άλλη έρευνα. Η διόρθωση εδώ αφορά μόνο από ποιον κατάλογο ήρθαν τα αρχεία, και θα πρέπει να φαίνεται στην κλήση αντί να τη θυμάται όποιος την έτρεξε τελευταία φορά με το χέρι.
Αν το προφίλ αναπτύσσεται από διαχειριστή διαμόρφωσης, βάλτε εκεί και τον βασικό κατάλογο ή τα απόλυτα ονόματα αρχείων. Μια χειροκίνητη διόρθωση σε έναν κεντρικό υπολογιστή είναι η εκδοχή αυτού του προβλήματος που επιστρέφει μετά την επόμενη ανακατασκευή.