Κάθε γραμμή στο αρχείο καταγραφής πρόσβασης δείχνει την ίδια διεύθυνση loopback, ενώ η σελίδα φορτώνει και το πιστοποιητικό επαληθεύεται σωστά. Τίποτα δεν είναι χαλασμένο με την έννοια ότι είναι απρόσιτο, και γι' αυτό αυτό επιβιώνει για μήνες. Αυτό που έσπασε είναι η απόδοση: το web backend καταγράφει τη διεύθυνση του hop που προώθησε τη σύνδεση, και κάθε επόμενη απόφαση που εμπιστεύτηκε το αρχείο κληρονόμησε την ίδια λανθασμένη απάντηση.

Οι έλεγχοι παρακάτω πηγαίνουν από το καλώδιο προς τα μέσα. Σταματήστε στον πρώτο που εξηγεί την τιμή που βλέπετε, γιατί κάθε επόμενο βήμα υποθέτει ότι τα προηγούμενα ισχύουν ήδη. Κανένας τους δεν απαιτεί να μαντέψετε τη διαμόρφωση του front-end.

Ακολουθήστε τις δύο συνδέσεις, όχι τη γραμμή του αρχείου

Το Port-Share πολυπλέκει δύο πρωτόκολλα σε έναν ακροατή TCP. Το OpenVPN εξετάζει τα πρώτα byte μιας εισερχόμενης σύνδεσης, την κρατά όταν μοιάζει με το δικό του πρωτόκολλο, και παραδίδει οτιδήποτε άλλο σε δεύτερο προορισμό. Αυτός ο προορισμός είναι συνήθως ένας διακομιστής web στον ίδιο κεντρικό υπολογιστή, οπότε ο αποδεκτός υποδοχέας του διακομιστή web έχει ως ομότιμο τη διεργασία OpenVPN.

ss -ltnp 'sport = :443'
ss -tnp 'dport = :8080'

Η πρώτη εντολή δείχνει ποιος κατέχει τον δημόσιο ακροατή. Η δεύτερη δείχνει τις συνδέσεις που φτάνουν στη θύρα του backend, και η διεύθυνση του ομοτίμου τους είναι αυτή που θα εκτυπώσει το αρχείο καταγραφής πρόσβασης. Αν αυτό το ομότιμο είναι loopback, το αρχείο είναι ακριβές και η πληροφορία χάθηκε ένα επίπεδο νωρίτερα. Η μετονομασία του πεδίου ή η ενεργοποίηση ενότητας IP πελάτη δεν θα ανακτήσει μια διεύθυνση που η σύνδεση δεν μετέφερε ποτέ.

Αυτός είναι ο έλεγχος που καθορίζει όλα τα υπόλοιπα. Αν το ομότιμο του backend είναι η διεύθυνση του προγράμματος περιήγησης, η κοινή χρήση θύρας δεν είναι το πρόβλημά σας και είναι η μορφή του αρχείου.

Η προώθηση μεταφοράς δεν είναι έγχυση κεφαλίδας

Ο προωθητής μετακινεί byte. Δεν αναλύει HTTP, οπότε δεν μπορεί να εισαγάγει κεφαλίδα σε αίτημα που δεν διαβάζει ποτέ ως αίτημα, και δεν μπορεί να προσθέσει τίποτα σε ροή TLS που περνά ανέπαφη. Μια ενότητα που περιμένει κεφαλίδα διαμεσολαβητή θα περιμένει μια που κανένα στοιχείο δεν παράγει.

Δύο μηχανισμοί μπορούν να μεταφέρουν την αρχική διεύθυνση, και οι δύο απαιτούν συμφωνία στα δύο άκρα. Το πρωτόκολλο PROXY προσθέτει μια μικρή κεφαλίδα στην αρχή της σύνδεσης, και το backend πρέπει να έχει διαμορφωθεί ώστε να την περιμένει· ένα backend που δεν την περιμένει θα θεωρήσει αυτά τα byte ως την αρχή του αιτήματος και θα αποτύχει με μπερδεμένο τρόπο. Αξιόπιστες κεφαλίδες διαμεσολαβητή όπως X-Forwarded-For λειτουργούν όταν ένας διαμεσολαβητής που καταλαβαίνει HTTP τις θέτει και το backend ενημερώνεται ποια ομότιμα επιτρέπεται να τις βεβαιώσουν.

Κανένα από τα δύο δεν είναι αυτόματο, και κανένα δεν είναι ασφαλές από προεπιλογή. Ένα backend που πιστεύει κάθε εισερχόμενη προωθημένη κεφαλίδα επιτρέπει σε έναν πελάτη να επιλέξει τη δική του διεύθυνση, κάτι που μετατρέπει μια ανακρίβεια στο αρχείο σε παράκαμψη του ελέγχου πρόσβασης. Εκτελέστε την επίδειξη μία φορά σε κεντρικό υπολογιστή δοκιμών πριν εμπιστευτείτε οποιαδήποτε κεφαλίδα σε διαδρομή παραγωγής.

curl -sS -H 'X-Forwarded-For: 127.0.0.1' https://site.example.com/health
grep -F '127.0.0.1' /var/log/nginx/access.log | tail -n 3

Ο προαιρετικός κατάλογος αντιστοίχισης προέλευσης

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

Αξίζει να γνωρίζετε αυτόν τον σχεδιασμό, γιατί εξηγεί γιατί ορισμένες εγκαταστάσεις αναφέρουν πραγματικές διευθύνσεις και άλλες όχι, με φαινομενικά ίδια διαμόρφωση front-end. Η διαφορά είναι στην πλευρά λήψης και συνήθως ζει σε μια ενότητα ή ένα patch που οι περισσότεροι συσκευασμένοι διακομιστές web δεν ενεργοποιούν από προεπιλογή. Διαβάστε την τεκμηρίωση του διακομιστή σας για το ακριβές hook που προσφέρει, και επιβεβαιώστε ότι η ενότητα φορτώνεται αντί να το υποθέσετε.

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

Αποφασίστε ποιο στοιχείο εγγυάται τη διεύθυνση

Πριν αλλάξετε τη διαμόρφωση, ονομάστε το στοιχείο που επιτρέπεται να βεβαιώσει διεύθυνση πελάτη και τα στοιχεία που επιτρέπεται να το πιστέψουν. Μια μόνο γραπτή απάντηση αποτρέπει τη συνήθη απόκλιση, όπου τρία διαφορετικά επίπεδα εμπιστεύονται το καθένα διαφορετική πηγή.

Τρεις σχεδιασμοί καλύπτουν τις περισσότερες ανάγκες. Κρατήστε τον δημόσιο ακροατή και τον ακροατή web χωριστά, ώστε ο διακομιστής web να βλέπει πραγματικά ομότιμα και να μην υπάρχει πρόβλημα απόδοσης. Βάλτε μπροστά έναν αντίστροφο διαμεσολαβητή που καταλαβαίνει HTTP, τερματίστε ή αναλύστε το αίτημα εκεί, και αφήστε τον να θέσει μια προωθημένη κεφαλίδα για ένα backend που εμπιστεύεται μόνο αυτόν τον διαμεσολαβητή. Ή κρατήστε την κοινή χρήση θύρας και δεχτείτε ότι τα αρχεία δείχνουν το hop, με κανόνες πρόσβασης γραμμένους με βάση την ταυτότητα της εφαρμογής και όχι μια διεύθυνση.

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

Δοκιμάστε τον κανόνα, όχι τη σελίδα

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

curl -sS -o /dev/null -w '%{http_code}\n' https://site.example.com/
tail -n 5 /var/log/nginx/access.log
grep -c '' /var/log/nginx/access.log

Συγκρίνετε ένα εξουσιοδοτημένο εξωτερικό αίτημα με τις εγγραφές τόσο του front-end όσο και του backend, και επιβεβαιώστε ότι ένας κανόνας που θα έπρεπε να απορρίπτει εξακολουθεί να απορρίπτει και ένας που θα έπρεπε να επιτρέπει εξακολουθεί να επιτρέπει. Αν η γραμμή του αρχείου είναι σωστή αλλά ο κανόνας συμπεριφέρεται ακόμη σαν όλοι να είναι τοπικοί, ο κανόνας διαβάζει διαφορετικό πεδίο από αυτό που διορθώσατε.

Ολοκληρώστε γράφοντας την αλυσίδα απόδοσης στις σημειώσεις ανάπτυξης: ποιος ακροατής, ποιος προωθητής, ποια κεφαλίδα ή αντιστοίχιση και ποιο backend έχει διαμορφωθεί να την εμπιστεύεται. Το επόμενο άτομο που θα διαβάσει μια γραμμή αρχείου θα χρειαστεί και τα τέσσερα, και η απουσία αυτής της σημείωσης είναι ο τρόπος με τον οποίο το ίδιο ticket ανοίγει ξανά ένα χρόνο αργότερα. Κρατήστε την δίπλα στη διαμόρφωση και όχι σε νήμα συνομιλίας.

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