Mengapa webhook GitHub kehabisan waktu terhadap Jenkins di balik VPN
GitHub mengirim webhook ke dalam, jadi VPN yang melindungi Jenkins menolaknya. Salurkan pengiriman ke luar lewat relay, atau ganti webhook dengan agen yang melakukan polling.
Halaman pengiriman menampilkan waktu habis dan Jenkins tidak mencatat apa pun, yang merupakan tanda koneksi yang tidak pernah tiba. GitHub mengirim webhook sebagai HTTP POST keluar dari infrastrukturnya sendiri ke payload URL yang Anda konfigurasikan. VPN melindungi Jenkins dengan menolak persis jenis koneksi itu. Tidak ada yang rusak di kedua sisi. Masalahnya adalah arah permintaan.
Apa yang sebenarnya dicoba oleh pengiriman
GitHub menyelesaikan nama host di payload URL dan terhubung ke sana dari internet publik. Jika URL itu menunjuk ke alamat privat, atau ke nama yang hanya diselesaikan di dalam jaringan Anda, percobaan gagal sebelum permintaan apa pun dibuat. Jika menunjuk ke nama publik yang dibuang tepi Anda, percobaan malah kehabisan waktu.
Perbedaan itu penting untuk diagnosis. Kegagalan DNS dan port yang tersaring sama-sama tampak seperti tidak terjadi apa-apa di sisi Jenkins, dan keduanya muncul di GitHub sebagai pengiriman gagal dengan alasan berbeda yang terlampir. Baca alasan itu sebelum Anda mengubah URL.
Tunnel yang menekan keluar tidak membuat pendengar. Itulah bagian yang orang harapkan bekerja secara berbeda.
Tiga cara memperbaiki arah koneksi
Setiap solusi mengubah siapa yang memulai koneksi, dan hanya ada tiga bentuk.
| 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 |
Polling adalah yang paling tidak elegan dan paling mudah dioperasikan. Relay menjaga umpan balik hampir instan tanpa membuka port. Runner biasanya jawaban yang tepat ketika kerahasiaan payload mengecualikan pihak ketiga, karena pekerjaan dapat berjalan di mesin yang sudah berada di dalam jaringan.
Pilih berdasarkan apa yang dapat Anda operasikan, bukan berdasarkan apa yang terdengar modern.
Salurkan pengiriman ke luar dengan smee
Buat kanal di layanan relay dan simpan URL-nya. Di dalam jaringan, pasang klien dan teruskan pengiriman ke jalur yang diharapkan Jenkins. Payload URL di pengaturan repositori menjadi URL kanal, dengan jenis konten disetel ke application/json.
sudo npm install --global smee-client
smee -u CHANNEL_URL --path /github-webhook/ --port 8080Tiga detail menentukan apakah ini berhasil. Jalur harus cocok dengan apa yang diharapkan Jenkins untuk peristiwa GitHub, yang secara default adalah /github-webhook/. Jenkins harus mendengarkan di port yang Anda berikan kepada klien. Dan Jenkins URL yang dikonfigurasikan di pekerjaan harus sesuai dengan jalur itu, jika tidak peristiwa tiba lalu dibuang.
Ketidakcocokan garis miring di akhir menghasilkan 404 yang terbaca seperti kegagalan pengiriman dan sebenarnya bukan.
Menjalankannya agar bertahan seminggu
Klien di depan mati bersama terminal, dan webhook berfungsi sehari lalu berhenti. Beri ia unit dengan Restart=always, jalankan sebagai pengguna Jenkins, dan baca journal setelah pengiriman nyata pertama. Langkah terakhir itulah yang membedakan relay yang berfungsi dari yang dikonfigurasikan.
[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.targetUji dengan push nyata alih-alih tombol pemutaran ulang. Pemutaran ulang melatih payload tersimpan relay, bukan jalur dari GitHub ke kanal Anda, sehingga bisa lolos sementara pengiriman langsung masih gagal.
Berikan peringatan saat unit berhenti. Relay yang mati itu senyap secara konstruksi, dan kesenyapan itulah yang sedang Anda debug.
Apa yang dapat dilihat relay, dan kapan tidak memakainya
Relay mengakhiri payload, jadi ia melihat nama repositori, data commit, dan apa pun yang dibawa peristiwa. Perlakukan URL kanal sebagai titik akhir publik. Biarkan secret token Jenkins tetap dikonfigurasikan agar pengiriman palsu ditolak, dan batasi token yang dipakai Jenkins pada minimum yang diperlukan.
Jika kerahasiaan payload mengecualikan itu, runner yang dihosting sendiri atau tunnel balik yang terautentikasi adalah jawabannya.
Relay kini menjadi infrastruktur, dan ia layak mendapat tinjauan yang sama seperti build yang ia picu. Putar kanal jika bocor, dan catat tanggal terakhir Anda memverifikasi pengiriman langsung. Letakkan tanggal itu di runbook di samping URL kanal. Relay yang tidak ditinjau siapa pun selama setahun adalah titik akhir publik yang tidak dimiliki siapa pun.