Kodėl GitHub webhook’ai pasibaigia laiku prieš Jenkins už VPN
GitHub siunčia webhook’us į vidų, todėl juos atmeta VPN, saugantis Jenkins. Perduokite pristatymą į išorę per relay arba pakeiskite webhook’ą agentu, kuris apklausinėja.
Pristatymo puslapyje rodomas laiko limitas, o Jenkins nieko neįrašo, tai yra požymis ryšio, kuris taip ir neatėjo. GitHub siunčia webhook’ą kaip išeinantį HTTP POST iš savo infrastruktūros į jūsų sukonfigūruotą payload URL. VPN apsaugo Jenkins atmesdamas būtent tokio tipo ryšį. Nė vienoje pusėje niekas nesugedę. Problema yra užklausos kryptis.
Ką pristatymas iš tikrųjų bando
GitHub išsprendžia payload URL esantį prieglobos vardą ir prisijungia prie jo iš viešo interneto. Jei tas URL nurodo privatų adresą arba vardą, kuris sprendžiamas tik jūsų tinkle, bandymas nepavyksta prieš išsiunčiant bet kokią užklausą. Jei jis nurodo viešą vardą, kurį jūsų kraštas numeta, bandymas vietoj to pasibaigia laiku.
Šis skirtumas svarbus diagnostikai. DNS gedimas ir filtruojamas prievadas abu atrodo taip, lyg Jenkins pusėje nieko neįvyko, ir abu GitHub rodomi kaip nepavykęs pristatymas su kita pridėta priežastimi. Perskaitykite tą priežastį prieš keisdami URL.
Tunelis, kuris skambina į išorę, nesukuria klausytojo. Būtent šios dalies žmonės tikisi veikiančios kitaip.
Trys būdai ištaisyti ryšio kryptį
Kiekvienas sprendimas keičia, kas pradeda ryšį, ir yra tik trys formos.
| Approach | Who initiates | What you give up |
|---|---|---|
| Relay service | An outbound client inside the network | A third party sees every payload |
| Reverse tunnel or ingress | The public edge, into a controlled listener | An inbound surface you must secure |
| Runner or polling | The agent, outbound to GitHub | Instant delivery, replaced by a schedule |
Apklausa yra mažiausiai elegantiška ir lengviausia eksploatuoti. Relay palaiko beveik momentinį grįžtamąjį ryšį neatidarydamas prievado. Runner paprastai yra teisingas atsakymas, kai payload konfidencialumas atmeta trečiąją šalį, nes darbas gali veikti mašinoje, kuri jau yra tinklo viduje.
Rinkitės pagal tai, ką galite eksploatuoti, o ne pagal tai, kas skamba moderniai.
Perduokite pristatymą į išorę su smee
Sukurkite kanalą relay paslaugoje ir išsaugokite jo URL. Tinklo viduje įdiekite klientą ir persiųskite pristatymus į kelią, kurio tikisi Jenkins. Payload URL saugyklos nustatymuose tampa kanalo URL, o turinio tipas nustatytas kaip application/json.
sudo npm install --global smee-client
smee -u CHANNEL_URL --path /github-webhook/ --port 8080Trys detalės lemia, ar tai veiks. Kelias turi atitikti tai, ko Jenkins tikisi GitHub įvykiams, o tai pagal nutylėjimą yra /github-webhook/. Jenkins turi klausytis prievado, kurį davėte klientui. Ir darbe sukonfigūruotas Jenkins URL turi sutapti su tuo keliu, kitaip įvykis atvyks ir tada bus išmestas.
Pabaigos brūkšnio neatitikimas sukuria 404, kuris skaitomas kaip nepavykęs pristatymas, bet juo nėra.
Vykdyti taip, kad atlaikytų savaitę
Priekinio plano klientas miršta kartu su terminalu, o webhook’ai veikia dieną ir tada sustoja. Duokite jam unit su Restart=always, vykdykite jį kaip Jenkins naudotoją ir perskaitykite journal po pirmo tikro pristatymo. Būtent šis paskutinis žingsnis atskiria veikiantį relay nuo sukonfigūruoto.
[Unit]
Description=smee webhook relay
After=network.target
[Service]
Type=simple
Restart=always
RestartSec=2
User=jenkins
ExecStart=/usr/bin/smee -u CHANNEL_URL --path /github-webhook/ --port 8080
[Install]
WantedBy=multi-user.targetTestuokite tikru push, o ne kartojimo mygtuku. Kartojimas atlieka išsaugotą relay payload, o ne kelią nuo GitHub iki jūsų kanalo, todėl jis gali praeiti, nors tiesioginis pristatymas vis dar nepavyksta.
Įspėkite, kai unit sustoja. Sustabdytas relay yra tylus iš prigimties, o tyla yra būtent tai, ką jau derinate.
Ką relay gali matyti, ir kada jo nenaudoti
Relay užbaigia payload, todėl mato saugyklų pavadinimus, commit duomenis ir visa kita, ką neša įvykis. Traktuokite kanalo URL kaip viešą galinį tašką. Laikykite Jenkins slaptą token sukonfigūruotą, kad suklastoti pristatymai būtų atmetami, ir apribokite Jenkins naudojamą token iki būtino minimumo.
Jei payload konfidencialumas to neleidžia, savarankiškai talpinamas runner arba autentifikuotas atvirkštinis tunelis yra atsakymas.
Relay dabar yra infrastruktūra ir nusipelno tokios pačios peržiūros kaip build, kurį jis paleidžia. Rotuokite kanalą, jei jis nuteka, ir užsirašykite datą, kada paskutinį kartą patikrinote tiesioginį pristatymą. Įrašykite tą datą į runbook šalia kanalo URL. Relay, kurio niekas metus neperžiūrėjo, yra viešas galinis taškas, kuriam niekas nepriklauso.