Μπορείτε να ανοίξετε το Jenkins μέσω VPN και παρόλα αυτά να βλέπετε το GitHub να αναφέρει αποτυχημένο webhook, γιατί πρόκειται για δύο διαφορετικές συνδέσεις με δύο διαφορετικούς ιδιοκτήτες. Το πρόγραμμα περιήγησης κινείται σε ένα τούνελ που διαπραγματεύτηκε ο φορητός σας, ενώ η υπηρεσία παράδοσης του GitHub ξεκινά από το δημόσιο διαδίκτυο και δεν έχει διαδρομή προς το ιδιωτικό δίκτυο. Η πρόσβαση στο αποθετήριο δεν το αλλάζει, ακόμη και αν το ίδιο το Jenkins μπορεί να αντλεί από το ίδιο αποθετήριο χωρίς πρόβλημα. Διαλέξτε ένα σημείο εισόδου, έναν αναμεταδότη ή polling, και μετά δοκιμάστε τη διαδρομή που ακολουθεί στην πραγματικότητα το συμβάν.

Μια συνεδρία περιήγησης αποδεικνύει μόνο μία κατεύθυνση

Μια σύνδεση VPN απαντά σε ένα ερώτημα: μπορεί αυτός ο φορητός να φτάσει τον εσωτερικό host. Η παράδοση webhook ρωτά κάτι άλλο: μπορεί μια εξωτερική υπηρεσία να ανοίξει σύνδεση προς αυτόν τον host. Το ότι το Jenkins αντλεί από ένα αποθετήριο είναι εξερχόμενη κίνηση και δεν λέει τίποτα για την εισερχόμενη προσβασιμότητα. Κρατήστε τις δύο κατευθύνσεις σε ξεχωριστές γραμμές του διαγράμματός σας, μαζί με το ποια πλευρά ξεκινά καθεμία.

Διαβάστε την εγγραφή παράδοσης πριν αλλάξετε οτιδήποτε. Ένα timeout, μια επαναφορά σύνδεσης και ένα αίτημα που έγινε δεκτό χωρίς να ταιριάξει με καμία εργασία έχουν τρεις διαφορετικούς ιδιοκτήτες: δίκτυο, proxy και διαμόρφωση σκανδάλης.

Επιλογή A: εκθέστε ένα στενό endpoint

Αν ο οργανισμός δημοσιεύει ήδη εγκεκριμένο σημείο εισόδου, εκθέστε τη διαδρομή του webhook αντί για τον πίνακα ελέγχου. Αυτό συνήθως σημαίνει έναν κανόνα αντίστροφου proxy που δέχεται POST στη διεύθυνση URL του hook και τα προωθεί στο Jenkins, ενώ η διεπαφή διαχείρισης παραμένει απρόσιτη από έξω.

curl -sS -o /dev/null -w "%{http_code}\n" -X POST https://jenkins.example.com/github-webhook/

Εκτελέστε αυτή τη δοκιμή από δίκτυο χωρίς πρόσβαση VPN, γιατί μια επιτυχία μέσα από το τούνελ δεν αποδεικνύει τίποτα. Το endpoint πρέπει να απορρίπτει αιτήματα χωρίς το κοινό μυστικό, το οποίο στέλνει το GitHub ως κεφαλίδα υπογραφής, και να δέχεται μόνο τη μία διαδρομή και μέθοδο που δημοσιεύσατε. Μια δημόσια κονσόλα Jenkins δεν είναι διόρθωση webhook, είναι συμβάν που περιμένει τον επόμενο σαρωτή. Περιορίστε τον κανόνα αρκετά ώστε η υπόλοιπη εφαρμογή να διατηρήσει τους ελέγχους πρόσβασης που είχε.

Επιλογή B: αντιστρέψτε την κατεύθυνση με αναμεταδότη

Όπου η εισερχόμενη έκθεση δεν θα εγκριθεί, ένας μικρός client μέσα στο δίκτυο μπορεί να κρατά εξερχόμενη σύνδεση προς αναμεταδότη και να λαμβάνει προωθημένα συμβάντα. Ο αναμεταδότης γίνεται τότε μέρος της διαδρομής παράδοσης, οπότε η διαθεσιμότητα και η αυθεντικοποίησή του έχουν την ίδια σημασία με την εργασία build.

ssh -N -R 9000:localhost:8080 relay.example.net

Οι οδηγίες του Jenkins για webhooks πίσω από τείχη προστασίας περιγράφουν αυτό το σχήμα, και αξίζει να τις διαβάσετε πριν γράψετε δικό σας προωθητή. Τερματίστε το TLS στον αναμεταδότη, επαληθεύστε την υπογραφή πριν το συμβάν φτάσει στην εργασία και παρακολουθείτε τον εξερχόμενο σύνδεσμο, γιατί ένα τούνελ που πέφτει μοιάζει ακριβώς με συμβάν που δεν στάλθηκε ποτέ. Επιβεβαιώστε επίσης ότι ο αναμεταδότης διατηρεί το σώμα του αιτήματος byte προς byte, αφού οι έλεγχοι υπογραφής αποτυγχάνουν σε JSON που έχει αναλυθεί και κωδικοποιηθεί ξανά στην πορεία.

Επιλογή C: κάντε polling στο αποθετήριο

Το polling ανταλλάσσει καθυστέρηση με απλότητα και δεν χρειάζεται καθόλου εισερχόμενη διαδρομή. Το Jenkins μπορεί να κάνει polling με χρονοδιάγραμμα, ή μια μικρή εργασία μπορεί να ρωτήσει το API και να ξεκινήσει build όταν δει μια άγνωστη αναθεώρηση.

curl -sS -u "$USER:$TOKEN" "https://api.github.com/repos/OWNER/REPO/commits?per_page=1"

Κάθε polling ξοδεύει κλήσεις API και προσθέτει καθυστέρηση ανάμεσα στο push και στο build, κάτι που φαίνεται σε πολυσύχναστα αποθετήρια και σε κοινά όρια ρυθμού. Χρειάζεται επίσης διαπιστευτήρια αποθηκευμένα όπου κι αν εκτελείται ο poller, οπότε περιορίστε το token σε πρόσβαση μόνο για ανάγνωση στο αποθετήριο και περιστρέψτε το όπως κάθε άλλο μυστικό. Διαλέξτε το όταν ο όγκος συμβάντων είναι χαμηλός ή όταν δεν πρόκειται να εγκριθεί ποτέ σημείο εισόδου, και πείτε το στην περιγραφή της εργασίας ώστε να μη αναρωτιέται κανείς αργότερα γιατί τα build καθυστερούν.

Δεχτείτε πραγματική παράδοση, όχι φόρτωση σελίδας

Όποια επιλογή κι αν διαλέξατε, η δοκιμή αποδοχής είναι ένα συμβάν που στέλνει η πλατφόρμα προέλευσης, όχι μια καρτέλα περιήγησης από προνομιούχο φορητό. Κάντε push ενός κενού commit σε πρόχειρο κλάδο και διαβάστε τον κωδικό απόκρισης της παράδοσης, το αρχείο καταγραφής του αναμεταδότη ή την έξοδο της εργασίας polling, με αυτή τη σειρά. Ένα 200 από το endpoint χωρίς build σημαίνει ότι το φίλτρο σκανδάλης είναι λάθος, ενώ ένα timeout σημαίνει ότι η διαδρομή παραμένει κλειστή. Καταγράψτε ποιο από τα τρία σχέδια χρησιμοποιείται, γιατί αλλιώς το επόμενο άτομο που θα κάνει debugging θα επαναλάβει τη δοκιμή στον browser και θα φτάσει στο ίδιο αδιέξοδο.

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

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