Συμβάντα hook του OpenVPN: γιατί το όνομα και η χρονική σφραγίδα δεν είναι κλειδί
Ένα hook αποσύνδεσης αναφέρει τον χρόνο σύνδεσης, όχι τον χρόνο αποσύνδεσης. Σε ζεύγος με το όνομα χρήστη μπορεί να τερματίσει τη λάθος συνεδρία· αποκτήστε ταυτότητα αντ’ αυτού.
Μια εγγραφή αποσύνδεσης φτάνει αφού έχει ήδη ξεκινήσει μια δεύτερη σύνδεση με το ίδιο όνομα, και ένας χειριστής που ενημερώνει τη νεότερη γραμμή για αυτόν τον χρήστη κλείνει τη λάθος συνεδρία. Το λάθος δεν είναι η σύγκριση των χρονικών σφραγίδων. Είναι η παραδοχή ότι ένα όνομα μαζί με ένα ολόκληρο δευτερόλεπτο προσδιορίζουν μία συνεδρία. Τα συμβάντα hook περιγράφουν συνδέσεις, και μια σύνδεση χρειάζεται ένα κλειδί που ανήκει μόνο σε αυτήν.
Ξεκινήστε με το τι σημαίνουν πραγματικά οι μεταβλητές αποσύνδεσης. Μόνο τότε έχει νόημα η επιλογή αναγνωριστικού.
Τι πραγματικά μεταφέρει το hook αποσύνδεσης
Στο Community OpenVPN 2.6, η αναφορά hook time_unix ορίζει τη στιγμή που συνδέθηκε ο πελάτης· ορίζεται πριν εκτελεστεί το hook σύνδεσης και δεν επαναπροσδιορίζεται όταν το hook αποσύνδεσης ενεργοποιηθεί αργότερα. time_duration δίνει τη διάρκεια αυτής της συνεδρίας σε δευτερόλεπτα, άρα το τέλος είναι περίπου ο χρόνος σύνδεσης συν η διάρκεια. Και τα δύο είναι ακέραια δευτερόλεπτα, και κανένα δεν είναι η στιγμή που η βάση δεδομένων σας επεξεργάστηκε το συμβάν. Το να κρατάτε αυτούς τους τρεις χρόνους χωριστούς είναι αυτό που κάνει μια συσχέτιση να αντέχει αντί να φαίνεται απλώς σωστή κατά τη δοκιμή.
Αυτή η αριθμητική αξίζει να καταγραφεί, γιατί είναι ο μόνος χρόνος λήξης που προσφέρει το ίδιο το hook. Η καθυστέρηση επεξεργασίας και οι διαφορές ρολογιών μεταξύ διακομιστών παραμένουν ακόμη έξω από αυτήν.
Γιατί το προφανές ζεύγος δεν είναι μοναδικό
Το ζεύγος του ονόματος με τον χρόνο σύνδεσης περιορίζει την αναζήτηση και ακόμη δεν προσδιορίζει συνεδρία. Ένας πελάτης μπορεί να επανασυνδεθεί μέσα στο ίδιο δευτερόλεπτο, άρα δύο συνεδρίες μπορούν να μοιράζονται και τις δύο τιμές. Δύο στιγμιότυπα δαίμονα, ή μια αντικατάσταση διακομιστή που διατηρεί την ίδια διαμόρφωση, μπορούν να παράγουν αυτό το ζεύγος από διαφορετικές διεργασίες. Οι διευθύνσεις τούνελ ανακυκλώνονται για τον ίδιο λόγο, γεγονός που τις καθιστά γνωρίσματα μιας συνεδρίας και όχι αναγνωριστικά της.
Ο τρόπος αποτυχίας είναι ήσυχος. Μια καθυστερημένη αποσύνδεση για την πρώτη συνεδρία ταιριάζει με τη νεότερη γραμμή και τερματίζει μια κατανομή που η δεύτερη συνεδρία χρησιμοποιεί ακόμη, οπότε ο χρήστης βιώνει μια τυχαία απώλεια πρόσβασης που δεν προκάλεσε. Ένας αριθμός γραμμών που φαίνεται σωστός στη συνέχεια κάνει το πρόβλημα δυσκολότερο να εντοπιστεί.
Από πού προέρχεται μια σταθερή ταυτότητα
Η διεπαφή διαχείρισης αποδίδει σε κάθε πελάτη ένα αναγνωριστικό στιγμιότυπου πελάτη, και αυτό το αναγνωριστικό περιορίζεται στο στιγμιότυπο δαίμονα που το εξέδωσε. Ένα εφαρμόσιμο εξωτερικό κλειδί συνδυάζει ένα σταθερό αναγνωριστικό διακομιστή, μια εποχή που αλλάζει όταν ξεκινά ο δαίμονας, και αυτό το ID πελάτη. Η εποχή έχει σημασία γιατί τα αναγνωριστικά επανεκκινούν με τη διεργασία, και ένα γυμνό ID διεργασίας μπορεί αργότερα να επαναχρησιμοποιηθεί από κάτι άσχετο.
Οι μεταβλητές περιβάλλοντος που ορίζονται μέσα σε ένα θυγατρικό σενάριο σύνδεσης δεν ταξιδεύουν στο μεταγενέστερο σενάριο αποσύνδεσης του γονικού δαίμονα, γιατί αυτά τα σενάρια εκτελούνται ως ξεχωριστές διεργασίες με δικά τους περιβάλλοντα. Επομένως η δημιουργία ενός UUID κατά τη σύνδεση είναι μισή λύση. Η πλευρά της αποσύνδεσης πρέπει να μπορεί να ονομάσει το ίδιο UUID, που σημαίνει ότι η ταυτότητα πρέπει να ζει κάπου όπου μπορούν να φτάσουν και τα δύο συμβάντα.
Κάντε την απόσυρση υπό όρους και idempotent
Αποσύρετε κατά κάτοχο συνεδρίας, όχι κατά χρήστη. Ένας χειριστής που διαγράφει οποιαδήποτε κατανομή ανήκει αυτή τη στιγμή σε ένα όνομα θα διαγράψει τελικά τη λάθος, και η μόνη άμυνα είναι να ελέγξετε ότι η εγγραφή που αφαιρείται είναι η εγγραφή που περιγράφει αυτό το συμβάν.
Η διεπαφή διαχείρισης δέχεται έναν συνδεδεμένο πελάτη διαχείρισης κάθε φορά, γι’ αυτό ενσωματωθείτε με όποιον την κατέχει ήδη αντί να προσαρτήσετε έναν δεύτερο παρατηρητή που ανταγωνίζεται για το ίδιο socket.
Χειριστείτε επαναλαμβανόμενα συμβάντα χωρίς να αλλάξετε το αποτέλεσμα δύο φορές, και κρατήστε τα ασύζευκτα συμβάντα για συμφωνία αντί να τα απορρίπτετε. Μια επιστροφή κλήσης αποσύνδεσης έχει τεκμηριωμένες συνθήκες κύκλου ζωής και μπορεί να μην φτάσει ποτέ μετά από κατάρρευση ή σκληρή διακοπή, οπότε ο σχεδιασμός χρειάζεται τρόπο να αναπαραστήσει μια συνεδρία της οποίας το συμβάν τέλους λείπει.
Δοκιμάστε σκόπιμα τις δύσκολες περιπτώσεις: δύο επανασυνδέσεις μέσα σε ένα δευτερόλεπτο, δύο στιγμιότυπα δαίμονα, μια σύνδεση της οποίας η επεξεργασία απέτυχε και μια επανεκκίνηση δαίμονα στη μέση μιας συνεδρίας. Ένα κλειδί που αντέχει και στις τέσσερις αξίζει εμπιστοσύνη.