Je kunt Jenkins via de VPN openen en toch zien dat GitHub een mislukte webhook meldt, want dat zijn twee verschillende verbindingen met twee verschillende eigenaren. De browser rijdt op een tunnel die je laptop heeft onderhandeld; GitHubs bezorgdienst begint op het openbare internet en heeft geen route naar het privénetwerk. Toegang tot de repository verandert dat niet, ook al kan Jenkins zelf zonder problemen uit dezelfde repository putten. Kies een ingang, een relay of polling, en test dan het pad dat de gebeurtenis werkelijk aflegt.

Een browsersessie bewijst maar één richting

Een VPN-verbinding beantwoordt één vraag: kan deze laptop de interne host bereiken. De bezorging van webhooks vraagt iets anders: kan een externe dienst een verbinding naar die host openen. Dat Jenkins uit een repository put, is uitgaand verkeer en zegt niets over inkomende bereikbaarheid. Houd beide richtingen op aparte lijnen in je diagram, inclusief welke kant elk ervan begint.

Lees het bezorgrecord voordat je iets wijzigt. Een time-out, een verbindingsreset en een geaccepteerd verzoek dat bij geen enkele taak paste, hebben drie verschillende eigenaren: netwerk, proxy en triggerconfiguratie.

Optie A: een smal eindpunt blootleggen

Als de organisatie al een goedgekeurde ingang publiceert, leg dan het webhookpad bloot in plaats van het dashboard. Dat betekent meestal een regel voor een omgekeerde proxy die POST's op de hook-URL accepteert en doorstuurt naar Jenkins, terwijl de beheerinterface van buiten onbereikbaar blijft.

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

Voer die test uit vanaf een netwerk zonder VPN-toegang, want een succes van binnen de tunnel bewijst niets. Het eindpunt hoort verzoeken zonder het gedeelde geheim te weigeren, dat GitHub als handtekeningheader stuurt, en alleen het ene pad en de ene methode te accepteren die je hebt gepubliceerd. Een openbare Jenkins-console is geen webhook-oplossing; het is een incident dat wacht op de volgende scanner. Beperk de regel streng genoeg zodat de rest van de applicatie de toegangscontroles houdt die zij had.

Optie B: de richting omkeren met een relay

Waar inkomende blootstelling niet wordt goedgekeurd, kan een kleine client binnen het netwerk een uitgaande verbinding naar een relay vasthouden en doorgestuurde gebeurtenissen ontvangen. De relay wordt dan deel van het bezorgpad, dus de beschikbaarheid en authenticatie ervan zijn even belangrijk als de buildtaak.

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

Jenkins’ richtlijnen over webhooks achter firewalls beschrijven deze vorm, en het loont ze te lezen voordat je een eigen doorgever schrijft. Beëindig TLS bij de relay, verifieer de handtekening voordat de gebeurtenis de taak bereikt, en houd de uitgaande koppeling in de gaten, want een weggevallen tunnel ziet er precies uit als een gebeurtenis die nooit is verzonden. Bevestig ook dat de relay de verzoekbody byte voor byte bewaart, omdat handtekeningcontroles mislukken op JSON die onderweg is geparseerd en opnieuw gecodeerd.

Optie C: de repository pollen

Polling ruilt latentie voor eenvoud en heeft helemaal geen inkomend pad nodig. Jenkins kan volgens een schema pollen, of een kleine taak kan de API bevragen en een build starten wanneer die een onbekende revisie ziet.

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

Elke polling kost API-aanroepen en voegt vertraging toe tussen push en build, wat zichtbaar wordt op drukke repositories en gedeelde snelheidslimieten. Het vereist ook inloggegevens die worden opgeslagen waar de poller draait, dus beperk het token tot alleen-lezen toegang tot de repository en roteer het zoals elk ander geheim. Kies dit wanneer het gebeurtenisvolume laag is of wanneer er nooit een ingang wordt goedgekeurd, en zeg dat in de taakbeschrijving zodat niemand zich later afvraagt waarom builds achterblijven.

Accepteer een echte bezorging, geen paginalading

Welke optie je ook koos, de acceptatietest is een gebeurtenis die het bronplatform stuurt, niet een browsertab die vanaf een bevoorrechte laptop is geopend. Push een lege commit naar een krab-tak en lees de responscode van de bezorging, het log van de relay of de uitvoer van de polling-taak, in die volgorde. Een 200 van het eindpunt zonder build betekent dat het triggerfilter verkeerd is; een time-out betekent dat het pad nog dicht is. Noteer welk van de drie ontwerpen in gebruik is, want anders herhaalt de volgende persoon die debugt de browsertest en komt bij dezelfde doodlopende weg uit.

Pas dezelfde redenering toe op betaal-callbacks en andere meldingen van buiten: elk heeft zijn eigen route naar de privé-applicatie nodig, zelfs wanneer iedereen al een VPN-sessie heeft. Het bezorgpad hoort bij het ontwerp van de applicatie, niet bij een voetnoot over netwerken.

Gerelateerde artikelen