Stránka doručení zobrazuje vypršení a Jenkins nic nezaznamená, což je podpis spojení, které nikdy nedorazilo. GitHub posílá webhook jako odchozí HTTP POST ze své vlastní infrastruktury na payload URL, které jste nastavili. VPN chrání Jenkins tím, že přesně takové spojení odmítá. Na žádné straně není nic rozbité. Problém je ve směru požadavku.

Co doručení vlastně zkouší

GitHub přeloží název hostitele v payload URL a připojí se k němu z veřejného internetu. Pokud toto URL ukazuje na soukromou adresu nebo na jméno, které se přeloží jen uvnitř vaší sítě, pokus selže dřív, než se odešle jakýkoli požadavek. Pokud ukazuje na veřejné jméno, které vaše hrana zahodí, pokus místo toho vyprší.

Ten rozdíl je důležitý pro diagnostiku. Selhání DNS i filtrovaný port vypadají, jako by se na straně Jenkinsu nic nestalo, a obojí se v GitHubu zobrazí jako neúspěšné doručení s jiným důvodem. Přečtěte si ten důvod, než změníte URL.

Tunel, který vytáčí spojení ven, nevytváří posluchače. Právě to lidé čekají, že bude fungovat jinak.

Tři způsoby, jak opravit směr spojení

Každé řešení mění, kdo spojení zahajuje, a existují jen tři podoby.

ApproachWho initiatesWhat you give up
Relay serviceAn outbound client inside the networkA third party sees every payload
Reverse tunnel or ingressThe public edge, into a controlled listenerAn inbound surface you must secure
Runner or pollingThe agent, outbound to GitHubInstant delivery, replaced by a schedule

Dotazování je nejméně elegantní a nejsnáze provozovatelné. Relay udržuje téměř okamžitou zpětnou vazbu, aniž by otevíral port. Runner je obvykle správná odpověď, když důvěrnost payloadu vylučuje třetí stranu, protože úloha může běžet na stroji, který už je uvnitř sítě.

Vybírejte podle toho, co umíte provozovat, ne podle toho, co zní moderně.

Předejte doručení ven pomocí smee

Vytvořte kanál ve službě relay a jeho URL si uložte. Uvnitř sítě nainstalujte klienta a přeposílejte doručení na cestu, kterou Jenkins očekává. Payload URL v nastavení repozitáře se stane URL kanálu a typ obsahu se nastaví na application/json.

sudo npm install --global smee-client
smee -u CHANNEL_URL --path /github-webhook/ --port 8080

O úspěchu rozhodují tři detaily. Cesta musí odpovídat tomu, co Jenkins očekává pro události GitHubu, což je standardně /github-webhook/. Jenkins musí naslouchat na portu, který jste klientovi předali. A Jenkins URL nastavené v úloze musí s touto cestou souhlasit, jinak událost dorazí a pak je zahozena.

Neshoda na koncová lomítka vytvoří 404, které se čte jako selhání doručení, ale není jím.

Provozování tak, aby přežilo týden

Klient v popředí umírá s terminálem a webhooky fungují den, a pak se zastaví. Dejte mu unit s Restart=always, spusťte ho jako uživatele Jenkins a po prvním skutečném doručení si přečtěte journal. Právě ten poslední krok odděluje funkční relay od nastaveného.

[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.target

Testujte skutečným push, ne tlačítkem přehrání. Přehrání spouští uložený payload relay, ne cestu z GitHubu do vašeho kanálu, takže může projít, i když živé doručení stále selhává.

Nastavte upozornění, když se unit zastaví. Relay, který je mimo provoz, je tiše podle konstrukce a ticho je přesně to, co už ladíte.

Co relay vidí a kdy ho nepoužívat

Relay ukončuje payload, takže vidí názvy repozitářů, data o commitu a vše ostatní, co událost nese. Chovejte se k URL kanálu jako k veřejnému koncovému bodu. Udržujte tajný token Jenkinsu nastavený, aby se padělaná doručení odmítala, a rozsah tokenu, který Jenkins používá, omezte na nutné minimum.

Pokud to důvěrnost payloadu vylučuje, runner hostovaný u vás nebo ověřený reverzní tunel je odpověď.

Relay je teď infrastruktura a zaslouží stejnou revizi jako build, který spouští. Pokud unikne, rotujte kanál, a poznamenejte si datum, kdy jste naposledy ověřili živé doručení. To datum dejte do runbooku vedle URL kanálu. Relay, který nikdo rok nezkontroloval, je veřejný koncový bod, který nikomu nepatří.

Související články