Potete aprire Jenkins tramite la VPN e vedere comunque GitHub segnalare un webhook fallito, perché sono due connessioni diverse con due proprietari diversi. Il browser viaggia su un tunnel negoziato dal portatile; il servizio di consegna di GitHub parte da internet pubblico e non ha alcuna rotta verso la rete privata. L’accesso al repository non cambia la cosa, anche se Jenkins stesso può prelevare dallo stesso repository senza problemi. Scegliete un ingresso, un relè o il polling, poi provate il percorso che l’evento compie davvero.

Una sessione del browser dimostra solo una direzione

Una connessione VPN risponde a una domanda: questo portatile può raggiungere l’host interno. La consegna dei webhook ne chiede un’altra: un servizio esterno può aprire una connessione verso quell’host. Il fatto che Jenkins prelevi da un repository è traffico in uscita e non dice nulla sulla raggiungibilità in ingresso. Tenete entrambe le direzioni su righe separate del vostro diagramma, compreso quale lato avvia ciascuna.

Leggete il record di consegna prima di cambiare qualsiasi cosa. Un timeout, un reset della connessione e una richiesta accettata che non corrispondeva a nessun job hanno tre proprietari diversi: rete, proxy e configurazione del trigger.

Opzione A: esporre un endpoint ristretto

Se l’organizzazione pubblica già un ingresso approvato, esponete il percorso del webhook invece della dashboard. Di solito significa una regola di reverse proxy che accetta POST sull’URL del gancio e li inoltra a Jenkins, mentre l’interfaccia di amministrazione resta irraggiungibile dall’esterno.

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

Eseguite quel test da una rete senza accesso VPN, perché un successo dall’interno del tunnel non dimostra nulla. L’endpoint dovrebbe rifiutare le richieste prive del segreto condiviso, che GitHub invia come intestazione di firma, e accettare solo l’unico percorso e metodo che avete pubblicato. Una console Jenkins pubblica non è una correzione del webhook; è un incidente in attesa della prossima scansione. Limitate la regola abbastanza da far conservare al resto dell’applicazione i controlli di accesso che aveva.

Opzione B: invertire la direzione con un relè

Dove l’esposizione in ingresso non sarà approvata, un piccolo client dentro la rete può mantenere una connessione in uscita verso un relè e ricevere gli eventi inoltrati. Il relè diventa così parte del percorso di consegna, quindi la sua disponibilità e la sua autenticazione contano quanto il job di build.

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

Le indicazioni di Jenkins sui webhook dietro i firewall descrivono questa forma, e vale la pena leggerle prima di scrivere un inoltro personalizzato. Terminate TLS sul relè, verificate la firma prima che l’evento raggiunga il job e monitorate il collegamento in uscita, perché un tunnel caduto sembra esattamente un evento che non è mai stato inviato. Confermate anche che il relè conservi il corpo della richiesta byte per byte, dato che i controlli di firma falliscono su JSON che è stato analizzato e ricodificato lungo il percorso.

Opzione C: interrogare il repository

Il polling scambia latenza con semplicità e non richiede alcun percorso in ingresso. Jenkins può interrogare secondo una pianificazione, oppure un piccolo job può consultare l’API e avviare una build quando vede una revisione sconosciuta.

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

Ogni interrogazione consuma chiamate API e aggiunge un ritardo tra push e build, cosa che si nota su repository trafficati e su limiti di velocità condivisi. Richiede anche credenziali archiviate ovunque giri l’interrogatore, quindi limitate il token all’accesso in sola lettura al repository e ruotatelo come qualsiasi altro segreto. Sceglietelo quando il volume di eventi è basso o quando nessun ingresso verrà mai approvato, e ditelo nella descrizione del job così che nessuno si chieda poi perché le build sono in ritardo.

Accettate una consegna reale, non un caricamento di pagina

Qualunque opzione abbiate scelto, il test di accettazione è un evento inviato dalla piattaforma di origine, non una scheda del browser aperta da un portatile privilegiato. Fate push di un commit vuoto su un ramo temporaneo e leggete il codice di risposta della consegna, il log del relè o l’output del job di polling, in quest’ordine. Un 200 dall’endpoint senza build significa che il filtro del trigger è sbagliato; un timeout significa che il percorso è ancora chiuso. Annotate quale dei tre progetti è in uso, altrimenti la prossima persona che esegue il debug ripeterà il test del browser e arriverà allo stesso vicolo cieco.

Applicate lo stesso ragionamento ai callback di pagamento e alle altre notifiche esterne: ognuna ha bisogno della propria rotta verso l’applicazione privata, anche quando ogni persona possiede già una sessione VPN. Il percorso di consegna appartiene al progetto dell’applicazione, non a una nota a piè di pagina sulle reti.

Articoli correlati