IP allow list e raggiungibilità delle risorse aziendali
Quando un’enterprise attiva Enable IP allow list in Enterprise settings, sezione Authentication security, sta dichiarando che ogni accesso alle risorse protette deve arrivare da un intervallo elencato in notazione CIDR. Come amministratore devi ricordare che quella regola non riguarda solo le persone: vale anche per i token e per le macchine che eseguono i workflow. La conseguenza pratica è il punto più importante di questa unità: con una IP allow list attiva i runner ospitati standard non sono utilizzabili. La documentazione richiede self-hosted runners oppure larger runners configurati con intervalli di IP statici, i cui indirizzi vanno poi aggiunti all’elenco.
Due dettagli operativi risparmiano ore di indagine. Il primo: l’opzione Enable IP allow list configuration for installed GitHub Apps popola automaticamente l’elenco con gli intervalli dichiarati dalle app installate; quelle voci compaiono con una descrizione del tipo “Managed by the … GitHub App” e non sono modificabili né eliminabili a mano. Il secondo: le modifiche non sono immediate perché il controllo è servito da cache, quindi concedi qualche minuto prima di dichiarare fallito un intervallo appena aggiunto.
Lo scenario di deployment cambia le opzioni disponibili. Enable IP allow list user-level enforcement, che estende la restrizione ai repository di proprietà degli utenti, esiste solo con Enterprise Managed Users. E sempre con EMU, se l’autenticazione passa da Entra ID con OIDC, puoi far valere l’elenco di GitHub oppure quello dell’identity provider: sono alternativi, non cumulabili. Con GHEC e account personali quella scelta non si pone.
Portare i runner dentro la rete: Azure private networking e le alternative
Azure private networking for GitHub-hosted runners fa girare runner gestiti da GitHub dentro una tua virtual network Azure: GitHub distribuisce le schede di rete nella subnet che indichi, mentre tu mantieni network security groups e routing. È la strada per far raggiungere a un runner ospitato un database o un registry che non affaccia su Internet.
I vincoli sono la parte che l’esame ama chiedere. Vale solo per i larger runners: i runner ospitati standard non sono supportati. I runner nascono nella stessa region Azure della subnet, e le region supportate sono un sottoinsieme, ancora più ristretto per le immagini GPU e arm64. Gli indirizzi sono dinamici, cioè la configurazione predefinita: non è il meccanismo con cui ottieni IP statici. Puoi predisporre una subnet di failover, ma il passaggio è manuale. La confusione tipica da evitare: gli static IP address ranges dei larger runners, che si attivano con la casella “Assign unique & static public IP address ranges for this runner”, e Azure private networking sono funzionalità distinte con scopi diversi; se usi la VNET, gli indirizzi da mettere in allow list sono quelli della tua subnet.
Se non vuoi una virtual network restano due approcci applicativi. Un API gateway con OIDC collocato al bordo della rete valida il token OpenID Connect emesso per il workflow, usa le claim per accettare solo le esecuzioni attese e poi effettua le chiamate per conto del workflow; è stateless e scala orizzontalmente, ma l’infrastruttura la gestisci tu. Oppure WireGuard, che costruisce una network overlay fra runner e servizio privato senza infrastruttura di gateway separata.
Perché la coda non si smaltisce
Un job fermo in coda è quasi sempre uno di quattro problemi. Concorrenza esaurita: per i runner ospitati, da Settings > Actions > Runners > GitHub-hosted runners la sezione All jobs usage mostra i job attivi e il massimo consentito, mentre Active jobs elenca quelli in esecuzione; superato il massimo i nuovi job entrano in coda. Sui larger runners il campo Maximum concurrency svolge lo stesso ruolo sul singolo runner, e alzarlo evita che i workflow restino bloccati per parallelismo.
Label che non combaciano: GitHub cerca un runner che corrisponda alle label e al gruppo indicati nel job. Attenzione, le label di sistema operativo e architettura sono dichiarate, non verificate: la documentazione dice esplicitamente che GitHub le accetta così come sono, senza controllare che il runner usi davvero quel sistema operativo. Inoltre lo script config non assegna label a un runner già configurato.
Visibilità del gruppo: un runner perfettamente sano ma collocato in un runner group che non concede accesso a quel repository o a quel workflow è, dal punto di vista del job, inesistente. Verifica Repository access e Workflow access nell’organizzazione e Organization access nell’enterprise; le impostazioni imposte da un gruppo condiviso dall’enterprise non sono sovrascrivibili a valle.
Capacità della flotta self-hosted: nella lista dei runner lo stato è Idle, Active oppure Offline. Se un runner riceve l’assegnazione ma non la prende in carico entro un minuto il job torna in coda, e se resta in coda oltre un giorno fallisce.
Dove stanno i log e come si isola un problema di rete
Sui self-hosted runner tutto parte dalla cartella _diag nella directory di installazione: i file che iniziano con Runner_ sono il log dell’applicazione, uno per ogni avvio, quelli che iniziano con Worker_ contengono l’esecuzione dei singoli job e i file SelfUpdate documentano gli aggiornamenti automatici. Il servizio si osserva con gli strumenti del sistema operativo: journalctl -u actions.runner.<org>-<repo>.<runner>.service su Linux, launchctl su macOS, Get-Service e il log applicativo con origine ActionsRunnerService su Windows.
Per la rete, ./config.sh --check con URL e token restituisce PASS o FAIL per ciascun servizio e scrive il dettaglio in _diag. Ricorda i requisiti: il runner apre solo connessioni in uscita HTTPS sulla porta 443 e riceve i job in long polling, quindi nessuna regola in ingresso è necessaria; devono però essere raggiungibili github.com, api.github.com e i domini *.actions.githubusercontent.com, oltre a codeload.github.com per le action, agli endpoint di storage per artifact, log e cache e a ghcr.io per i package. Dietro proxy si impostano https_proxy, http_proxy e no_proxy, anche tramite il file .env nella directory del runner: vanno definite prima di configurare o avviare l’applicazione, e ogni modifica richiede un riavvio.
Su GHES il quadro è diverso perché l’infrastruttura è tua: il Management Console espone la scheda Monitor con le dashboard Operational Health e System & Application Insights, che includono una sezione Actions. Qui il comportamento può dipendere dalla versione dell’istanza: il riferimento usato in questa unità è la 3.21.