Чаму webhook-і GitHub атрымліваюць тайм-аўт супраць Jenkins за VPN
GitHub адпраўляе webhook-і ўваходным кірункам, таму VPN, які абараняе Jenkins, іх адхіляе. Перадайце дастаўку вонкава праз relay або заменіце webhook агентам, які апытвае.
Старонка дастаўкі паказвае тайм-аўт, а Jenkins нічога не запісвае ў журнал — гэта прыкмета злучэння, якое так і не прыйшло. GitHub адпраўляе webhook як зыходны HTTP POST са сваёй інфраструктуры на адрас payload URL, які вы наладзілі. VPN абараняе Jenkins, адхіляючы менавіта такое злучэнне. Ні на адным баку нічога не зламана. Праблема ў кірунку запыту.
Што дастаўка насамрэч спрабуе зрабіць
GitHub разрознівае імя хоста ў payload URL і злучаецца з ім з публічнага інтэрнэту. Калі гэты адрас паказвае на прыватны адрас або на імя, якое разрозніваецца толькі ўнутры вашай сеткі, спроба правальваецца яшчэ да таго, як будзе адпраўлены запыт. Калі ён паказвае на публічнае імя, якое скідвае ваш край, спроба замест гэтага сканчаецца тайм-аўтам.
Гэта розніца важная для дыягностыкі. Збой DNS і адфільтраваны порт выглядаюць гэтак жа, нібы на баку Jenkins нічога не адбылося, і абодва паказваюцца на GitHub як няўдалая дастаўка з іншай прычынай. Прачытайце гэтую прычыну, перш чым мяняць адрас.
Тунэль, які злучаецца вонкава, не стварае слухача. Менавіта гэтую частку людзі чакаюць пабачыць іншай.
Тры спосабы выправіць кірунак злучэння
Кожнае рашэнне мяняе таго, хто пачынае злучэнне, і існуюць толькі тры формы.
| 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 |
Апытанне — найменш элегантнае і самае простае ў кіраванні. Relay забяспечвае амаль імгненную зваротную сувязь, не адкрываючы порт. Runner звычайна правільны адказ, калі канфідэнцыйнасць payload выключае ўдзел трэцяга боку, бо задача можа выконвацца на машыне, якая ўжо знаходзіцца ўнутры сеткі.
Выбірайце па тым, што можаце абслугоўваць, а не па тым, што гучыць сучасна.
Перадайце дастаўку вонкава з дапамогай smee
Стварыце канал на службе relay і захавайце яго адрас. Унутры сеткі ўсталюйце кліент і перасылайце дастаўкі на шлях, якога чакае Jenkins. Адрас payload URL у наладах рэпазіторыя становіцца адрасам канала, а тып змесціва выстаўляецца як application/json.
sudo npm install --global smee-client
smee -u CHANNEL_URL --path /github-webhook/ --port 8080Тры дэталі вызначаюць, ці будзе гэта працаваць. Шлях мусіць супадаць з тым, чаго Jenkins чакае для падзей GitHub, — па змаўчанні гэта /github-webhook/. Jenkins мусіць слухаць порт, які вы далі кліенту. І наладжаны ў задачы Jenkins URL мусіць узгадняцца з гэтым шляхам, інакш падзея прыйдзе і потым будзе адкінута.
Няўзгодненасць з завяртальным слэшам дае 404, які чытаецца як збой дастаўкі, хоць ім не з’яўляецца.
Запусціць так, каб яно перажыло тыдзень
Кліент у пярэднім плане памірае разам з тэрміналам, і webhook-і працуюць дзень, а потым спыняюцца. Дайце яму unit з Restart=always, запусціце яго ад імя карыстальніка Jenkins і прачытайце журнал пасля першай сапраўднай дастаўкі. Менавіта апошні крок аддзяляе працоўны relay ад наладжанага.
[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Тэстуйце сапраўдным push, а не кнопкай паўтору. Паўтор праганяе захаваны payload relay, а не шлях ад GitHub да вашага канала, таму ён можа прайсці, пакуль жывая дастаўка ўсё яшчэ збоіць.
Атрымлівайце апавяшчэнне, калі unit спыняецца. Relay, які не працуе, маўчыць па сваёй прыродзе, а маўчанне — гэта тое, што вы ўжо дыягнастуеце.
Што relay можа бачыць і калі яго лепш не выкарыстоўваць
Relay тэрмінуе payload, таму бачыць назвы рэпазіторыяў, даныя commit і ўсё астатняе, што нясе падзея. Стаўцеся да адрасу канала як да публічнай канцавой кропкі. Трымайце сакрэтны token Jenkins наладжаным, каб падробленыя дастаўкі адхіляліся, і абмяжуйце token, які выкарыстоўвае Jenkins, неабходным мінімумам.
Калі канфідэнцыйнасць payload гэта выключае, runner на ўласным хостынгу або аўтэнтыфікаваны зваротны тунэль — гэта адказ.
Relay цяпер — гэта інфраструктура, і ён заслугоўвае такога ж агляду, як і зборка, якую ён запускае. Змяніце канал, калі ён працячэ, і запішыце дату, калі вы апошні раз правяралі жывую дастаўку. Пастаўце гэтую дату ў runbook побач з адрасам канала. Relay, які ніхто не аглядаў год, — гэта публічная канцавая кропка, якой ніхто не валодае.