In molti ambienti serverizzati capita di dover permettere a una VM Ubuntu di eseguire operazioni remote su un’altra macchina, ad esempio per riavviare servizi applicativi, eseguire manutenzioni pianificate o lanciare script di deploy. Uno scenario classico è quello di una VM Jenkins che deve collegarsi via SSH a una seconda VM Ubuntu e lanciare uno o più script con privilegi elevati.
In questo articolo vediamo una procedura semplice e sicura per:
jenkins, sulla macchina remota;sudo senza richiesta password;Supponiamo di avere:
| Macchina | Ruolo | Esempio |
|---|---|---|
| VM 1 | Server Jenkins che avvia la pipeline | utente locale di servizio jenkins |
| VM 2 | Server remoto su cui riavviare servizi | IP 10.90.0.23 |
Obiettivo finale: Jenkins deve poter eseguire in SSH un comando del tipo:
ssh jenkins@10.90.0.23 "sudo /home/syna/xcore-restarts.sh"
Sulla macchina remota è buona pratica creare un utente dedicato alle operazioni automatizzate, invece di riutilizzare utenti personali o amministrativi.
sudo adduser jenkins
In alternativa:
sudo useradd -m -s /bin/bash jenkins
sudo passwd jenkins
jenkins sulla macchina remota non deve essere necessariamente
un amministratore completo. L’idea è concedergli solo i privilegi minimi necessari.
Sul server dove gira Jenkins bisogna generare una coppia di chiavi SSH per l’utente che eseguirà
i job. Spesso il servizio Jenkins gira proprio con l’utente jenkins.
Per generare la chiave:
sudo -u jenkins ssh-keygen -t ed25519 -C "jenkins-deploy"
Quando viene chiesto dove salvare la chiave, si può lasciare il percorso predefinito. Se l’uso è interamente automatizzato, in genere la passphrase viene lasciata vuota.
I file generati saranno tipicamente:
/var/lib/jenkins/.ssh/id_ed25519
/var/lib/jenkins/.ssh/id_ed25519.pub
ed25519 è in genere preferibile rispetto a rsa:
è moderno, leggero e molto adatto agli ambienti Linux attuali.
Una volta generata la chiave, bisogna autorizzare la VM Jenkins ad accedere alla VM remota.
Il metodo più comodo è ssh-copy-id.
sudo -u jenkins ssh-copy-id jenkins@10.90.0.23
Alla prima esecuzione verrà richiesta la password dell’utente jenkins della macchina remota.
Dopo la copia della chiave, l’accesso SSH potrà avvenire senza password.
Se ssh-copy-id non fosse disponibile, si può procedere manualmente.
Sulla VM remota:
sudo mkdir -p /home/jenkins/.ssh
sudo nano /home/jenkins/.ssh/authorized_keys
All’interno del file authorized_keys va incollato il contenuto di
/var/lib/jenkins/.ssh/id_ed25519.pub generato sulla macchina Jenkins.
Poi bisogna impostare i permessi corretti:
sudo chown -R jenkins:jenkins /home/jenkins/.ssh
sudo chmod 700 /home/jenkins/.ssh
sudo chmod 600 /home/jenkins/.ssh/authorized_keys
Prima di integrare tutto in Jenkins conviene eseguire un test manuale dal server Jenkins:
sudo -u jenkins ssh jenkins@10.90.0.23
Se la connessione va a buon fine senza richiedere password, la parte SSH è configurata correttamente.
yes, la chiave host verrà salvata
nel file known_hosts dell’utente jenkins.
A questo punto resta il passaggio più delicato: permettere all’utente remoto di eseguire
uno o più script come root senza digitare la password. La configurazione va fatta tramite
sudoers.
È importante non dare privilegi troppo ampi, ad esempio evitare regole come:
jenkins ALL=(ALL) NOPASSWD: ALL
Questa configurazione renderebbe l’utente di fatto amministratore completo della macchina. Molto meglio autorizzare solo i comandi necessari.
Il metodo corretto è usare visudo, che controlla anche la sintassi.
Se si preferisce nano come editor:
sudo EDITOR=nano visudo
Ancora meglio, per mantenere la configurazione ordinata, si può creare un file dedicato
in /etc/sudoers.d/:
sudo nano /etc/sudoers.d/jenkins
All’interno si può inserire, ad esempio:
jenkins ALL=(root) NOPASSWD: /home/syna/xcore-restarts.sh
In questo modo l’utente jenkins può eseguire solo quello specifico script con sudo:
sudo /home/syna/xcore-restarts.sh
e non altri comandi privilegiati.
Se servono più script, si possono elencare sulla stessa riga, separati da virgola:
jenkins ALL=(root) NOPASSWD: /home/syna/xcore-restarts.sh, /home/syna/altro-script.sh
In alternativa si possono usare più righe separate:
jenkins ALL=(root) NOPASSWD: /home/syna/xcore-restarts.sh
jenkins ALL=(root) NOPASSWD: /home/syna/altro-script.sh
Dopo aver creato o modificato il file in /etc/sudoers.d/, conviene validare tutto:
sudo visudo -c
Se la sintassi è corretta, verrà restituito un messaggio di conferma. In caso contrario è bene correggere subito il file, perché una configurazione errata in sudoers può creare problemi seri nella gestione amministrativa del sistema.
Una volta sistemati SSH e sudo, il test completo può essere fatto direttamente dalla VM Jenkins:
sudo -u jenkins ssh jenkins@10.30.0.23 "sudo /home/syna/xcore-restarts.sh"
Se lo script viene eseguito senza richiesta di password, la configurazione è pronta per essere usata in una pipeline.
Una pipeline minimale per riavviare i servizi sulla macchina remota può essere:
pipeline {
agent any
stages {
stage('Restart servizi remoti') {
steps {
sh '''
ssh -o StrictHostKeyChecking=no jenkins@10.30.0.23 \
"sudo /home/syna/xcore-restarts.sh"
'''
}
}
}
}
In questo caso Jenkins si collega alla macchina remota come utente jenkins e lancia
lo script autorizzato via sudo.
Anche se la procedura descritta è già abbastanza pulita, ci sono alcuni accorgimenti ulteriori che migliorano la sicurezza generale.
Invece di lasciare gli script in home directory di utenti applicativi, è spesso preferibile spostarli in una posizione amministrata, ad esempio:
sudo mkdir -p /usr/local/jenkins-scripts
sudo mv /home/syna/xcore-restarts.sh /usr/local/jenkins-scripts/
sudo mv /home/syna/altro-script.sh /usr/local/jenkins-scripts/
Poi impostare proprietà e permessi:
sudo chown root:root /usr/local/jenkins-scripts/*
sudo chmod 750 /usr/local/jenkins-scripts/*
e aggiornare il sudoers:
jenkins ALL=(root) NOPASSWD: /usr/local/jenkins-scripts/xcore-restarts.sh, /usr/local/jenkins-scripts/altro-script.sh
In questo modo l’utente jenkins può eseguire gli script, ma non modificarli.
Per vedere l’elenco dei comandi autorizzati a un utente:
sudo -l -U jenkins
È un comando molto utile per verificare rapidamente se il profilo di autorizzazione corrisponde a quanto previsto.
NOPASSWD: ALL senza reale necessità;/etc/sudoers con un editor normale anziché tramite visudo;.ssh o su authorized_keys;La combinazione di accesso SSH tramite chiave e autorizzazioni sudo limitate a script specifici rappresenta una soluzione molto efficace per automatizzare operazioni remote tra due VM Ubuntu. Nel caso di Jenkins, questo approccio consente di costruire pipeline semplici, ripetibili e relativamente sicure, evitando l’uso di password interattive e riducendo al minimo i privilegi concessi.
Il principio guida dovrebbe essere sempre lo stesso: creare un utente tecnico dedicato,
autenticarsi con chiavi SSH e concedere solo i privilegi strettamente necessari tramite
regole sudoers mirate.