sudo-rs su Ubuntu: cosa cambia nelle regole sudoers
Ubuntu 26.04 usa sudo-rs come predefinito: i caratteri jolly negli argomenti non corrispondono più. Ecco la sintassi sudoers da usare al loro posto.
Cosa cambia con sudo-rs su Ubuntu
Ubuntu 26.04 LTS include sudo-rs come sudo predefinito. Di conseguenza, su un server appena installato, il comando sudo esegue la reimplementazione in Rust invece del programma originale in C. La maggior parte dei file sudoers continua a funzionare esattamente come prima. La regola che causa problemi è quella che contiene un carattere jolly negli argomenti di un comando, perché sudo-rs non confronta i pattern glob con il testo degli argomenti.
Ubuntu 25.10 ha introdotto per prima questa modifica e Ubuntu 26.04 LTS l'ha mantenuta. Ubuntu 24.04 LTS non è interessata, perché continua a usare sudo originale, a meno che non si installi sudo-rs manualmente. La modifica diventa rilevante quando si esegue l'upgrade da Ubuntu 24.04 a 26.04, oppure quando si configura un nuovo server con la versione più recente. Se si usano anche le versioni intermedie, le differenze tra le versioni LTS e intermedie di Ubuntu su un server spiegano quale macchina riceve per prima una modifica di questo tipo.
Verifica quale implementazione di sudo è effettivamente in esecuzione sul server
Non dedurlo dal numero di release. Interroga direttamente la macchina.
sudo --version
update-alternatives --config sudo
dpkg -l 'sudo*'Considera sudo --version sul tuo server più affidabile di qualsiasi tabella delle versioni disponibile su Internet, inclusa questa pagina. update-alternatives --config sudo completa la verifica: elenca tutti i provider installati di /usr/bin/sudo e indica quello selezionato. Un pacchetto installato non è necessariamente selezionato, quindi devi controllare la selezione, non l’elenco dei pacchetti.
Durante la transizione, entrambe le implementazioni sono disponibili come pacchetti. Quella in Rust è sudo-rs, alla versione 0.2.13 in 26.04 ad agosto 2026. L’implementazione originale, mantenuta da Todd C. Miller, è disponibile come sudo.ws e i relativi programmi hanno il suffisso .ws: sudo.ws e visudo.ws.
Perché Ubuntu è passata a sudo-rs
sudo usa il bit setuid per l'account root. Qualsiasi utente del sistema può avviarlo e il programma parte con privilegi completi. Di conseguenza, un bug di memoria al suo interno può diventare un exploit locale per ottenere root. CVE-2021-3156 era esattamente questo: un overflow del buffer nell'heap raggiungibile da qualsiasi utente locale. Il bug era presente nel codice rilasciato da circa dieci anni. Rust rileva questa classe di bug in fase di compilazione. Questo è il motivo principale della riscrittura.
Il secondo motivo riguarda l'ambito delle funzionalità, ed è quello che interessa la configurazione. Il sudo originale ha accumulato un insieme ampio di funzionalità in tre decenni. Ogni funzionalità aggiunge altro codice eseguito come root. sudo-rs implementa intenzionalmente solo un sottoinsieme. Gli autori hanno escluso tutto ciò che consideravano di nicchia o potenzialmente dannoso. Di conseguenza, una direttiva sudoers rimasta funzionante per anni può semplicemente non essere disponibile. La regola con caratteri jolly è uno di questi casi.
La sicurezza della memoria elimina una classe di bug. Non rende però il programma privo di bug. Da quando è diventato l'implementazione predefinita, anche sudo-rs ha ricevuto correzioni di sicurezza. Va aggiornato come qualsiasi altro software.
Quali regole sudoers continuano a funzionare
Il file è lo stesso. sudo-rs legge /etc/sudoers e i file drop-in in /etc/sudoers.d/. Sono supportate le direttive normalmente utilizzate dagli amministratori di sistema:
deploy ALL=(ALL:ALL) ALLe le forme per i gruppi, come%sudo ALL=(ALL:ALL) ALL- i tag
NOPASSWD:ePASSWD: User_Alias,Runas_Alias,Host_AliaseCmnd_Alias- un comando con un elenco esatto di argomenti, ad esempio
/usr/bin/systemctl restart app-api - un comando seguito da
"", che consente il comando soltanto senza argomenti - un comando seguito da
*come argomento finale, che consente qualsiasi argomento aggiuntivo - un percorso di directory che termina con
/, che consente qualsiasi comando in quella directory !per escludere un comando da un elenco- un sottoinsieme utile di
Defaults, inclusosecure_path,env_keep,env_check,timestamp_timeout,passwd_tries,editor,umask,targetpw,rootpweuse_pty
Due direttive Defaults si comportano in modo diverso e possono causare problemi. env_reset non può essere disattivata in sudo-rs: è sempre attiva. use_pty è attiva per impostazione predefinita, quindi il comando viene eseguito nel proprio pseudo-terminale.
Perché la regola wildcard di sudoers ha smesso di corrispondere
I wildcard sono ancora consentiti in un solo punto: il nome file del comando. Una regola con %ops ALL = /sbin/fsck* consente ancora sudo fsck e sudo fsck_exfat, perché * fa parte del percorso confrontato con il filesystem.
All'interno dell'elenco degli argomenti, sudo-rs accetta soltanto due forme speciali, e nessuna delle due è un pattern. "" indica l'assenza di argomenti. Un * finale indica qualsiasi argomento aggiuntivo. Ogni altro argomento viene confrontato come testo letterale. Perciò %ops ALL = /sbin/service ntp * è valido, perché ntp è letterale e * è l'ultimo elemento. Una regola come questa, invece, non concede nulla di ciò che si intendeva concedere:
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart app-*app-* è un pattern all'interno di un argomento. sudo-rs non lo espande, quindi la regola non copre systemctl restart app-api e sudo rifiuta il comando. Due comandi mostrano il comportamento effettivo di qualsiasi regola sul proprio server: sudo -l -U deploy, eseguito come root, stampa i comandi che quell'account può realmente eseguire, mentre sudo visudo -c indica se il file viene analizzato correttamente. Eseguirli prima di iniziare a modificare il file senza una verifica precisa.
La regola con carattere jolly era sempre una falla
Nel sudo originale, gli argomenti digitati vengono concatenati in un'unica stringa e confrontati con la stringa degli argomenti della regola tramite un glob. Un glob corrisponde anche agli spazi bianchi. È questo il dettaglio che quasi tutti trascurano.
La documentazione di sudo-rs fornisce la dimostrazione più chiara. Una regola come /bin/rm *.txt autorizza anche sudo rm -rf /home .txt, perché l'unico * assorbe -rf /home e la stringa concatenata termina comunque con .txt. La regola sembra significare «solo file di testo». In realtà significa «qualsiasi argomento, purché la riga termini con .txt».
Lo stesso vale per l'esempio con systemctl. Poiché gli argomenti vengono confrontati come un'unica stringa concatenata, anche un pattern finale corrisponde a tutto ciò che viene aggiunto dopo. Di conseguenza, restart app-* autorizza restart app-api e qualsiasi altro argomento aggiunto dal chiamante. Un pattern all'interno di un argomento espone anche gli argomenti circostanti, ma è negli argomenti che risiede la capacità operativa di un comando. sudo-rs rifiuta questa costruzione invece di tentare di renderla sicura, perché non esiste una forma generica e sicura per usarla.
Sostituire il wildcard con un elenco esplicito di comandi
Molte regole con wildcard esistono perché qualcuno non voleva scrivere quattro righe. Scrivi le quattro righe.
Cmnd_Alias APP_RESTART = /usr/bin/systemctl restart app-api, /usr/bin/systemctl restart app-worker
Cmnd_Alias APP_STATUS = /usr/bin/systemctl status app-api, /usr/bin/systemctl status app-worker
deploy ALL=(root) NOPASSWD: APP_RESTART, APP_STATUSIndica il percorso corretto. Una regola che specifica /bin/systemctl su un sistema in cui il binario si trova in /usr/bin/systemctl non viene mai applicata, e il problema appare identico a un errore di autorizzazioni. Verifica con command -v systemctl e incolla l'output.
Inserisci la regola in un file drop-in dedicato invece che in /etc/sudoers, così un aggiornamento del pacchetto non sovrascrive le modifiche:
sudo visudo -f /etc/sudoers.d/90-deploy
sudo visudo -c
sudo -l -U deployAssegna al file un nome senza punto e senza tilde finale. La versione originale di sudo ignora in sudoers.d i file i cui nomi contengono un punto, quindi 90-deploy.conf è un classico caso di mancata applicazione silenziosa. Rispettare questa convenzione non comporta alcun costo.
Usa un wrapper di proprietà di root quando l'elenco diventa lungo
Quando l'insieme di elementi consentiti è troppo ampio da elencare, sposta la decisione fuori da sudoers e affidala a un piccolo programma di proprietà di root.
sudo tee /usr/local/sbin/app-restart >/dev/null <<'EOF'
#!/bin/sh
set -eu
case "${1:-}" in
app-api|app-worker) ;;
*) echo "app-restart: not allowed: ${1:-}" >&2; exit 1 ;;
esac
exec /usr/bin/systemctl restart "$1"
EOF
sudo chown root:root /usr/local/sbin/app-restart
sudo chmod 0755 /usr/local/sbin/app-restart
ls -l /usr/local/sbin/app-restartLa configurazione di sudoers deve quindi indicare un solo comando:
deploy ALL=(root) NOPASSWD: /usr/local/sbin/app-restart *Il * finale è accettabile in questo caso perché è lo script, non sudo, a decidere cosa è consentito. Questo vale solo finché lo script è di proprietà di root e nessun altro può modificarlo. Se deploy può scrivere nel file, deploy può sostituirne il contenuto ed eseguire qualsiasi comando come root. È una situazione peggiore della regola con wildcard che hai rimosso. Controlla i permessi con ls -l. Se l'output non ti è chiaro, imparare a leggere la stringa di permessi drwxr-xr-x richiede cinque minuti. La stessa regola vale per la directory: anche /usr/local/sbin non deve essere scrivibile dall'account, perché una directory scrivibile consente di sostituire completamente il file.
Assegna al job un account dedicato invece di una regola sudo
La domanda corretta è spesso perché il comando richieda affatto root. Un servizio eseguito con un utente dedicato può essere gestito da quell'utente, senza coinvolgere alcuna voce di sudoers. Per le unità di sistema, systemd delega già questa decisione a polkit, quindi una regola può specificare una sola unità e un solo operatore:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" &&
action.lookup("unit") == "app-api.service" &&
subject.user == "deploy") {
return polkit.Result.YES;
}
});Salva la regola come /etc/polkit-1/rules.d/50-app-api.rules: deploy può eseguire systemctl restart app-api senza usare sudo. Verificala esattamente dal contesto che la utilizzerà, perché una regola che funziona nella sessione SSH deve essere verificata anche da cron prima di farvi affidamento. In ogni caso, l'account che esegue l'attività dovrebbe esistere esclusivamente per quello scopo. È lo stesso principio alla base degli account utente con privilegi minimi su un VPS.
Cosa non include sudo-rs
sudo -E non è implementato. Indicare invece le variabili necessarie con Defaults env_keep += "HTTP_PROXY HTTPS_PROXY NO_PROXY" e ricordare che env_reset è sempre attivo: tutto ciò che non viene mantenuto viene eliminato.
L'archiviazione centralizzata di sudoers in LDAP non è disponibile. sudoers.ldap e cvtsudoers non sono implementati e il pacchetto sudo-ldap è stato rimosso in 26.04. L'autenticazione LDAP tramite PAM o SSSD continua a funzionare. Non rientra nell'ambito, invece, la gestione delle policy in una directory.
INTERCEPT, che tentava di impedire le escape dalla shell in un comando autorizzato, non è implementato. In ogni caso, non avrebbe protetto da un utente determinato. Se una regola consente di eseguire un editor o un interprete come root, l'utente dispone di fatto dei privilegi root e nessuna opzione di sudo può modificare questo risultato.
La registrazione delle sessioni non è implementata. Non sono quindi disponibili log I/O né sudoreplay. La registrazione viene inviata solo a syslog e non esiste alcuna opzione logfile per reindirizzarla altrove. I messaggi di sudo vengono quindi scritti nella destinazione a cui il sistema invia già syslog.
È opportuno tornare a sudo.ws?
È possibile farlo e, durante il ciclo 26.04, il pacchetto originale rimane disponibile esattamente per questo motivo.
sudo apt install sudo.ws
update-alternatives --config sudo
sudo update-alternatives --set sudo /usr/bin/sudo.wsCopia i percorsi esatti dall’output di --config invece di copiarli da questa pagina, perché quello è l’elenco accettato dal sistema in uso. Per tornare in seguito a sudo-rs, imposta l’alternativa sul percorso del binario sudo-rs indicato nello stesso elenco.
Prima di modificare qualsiasi elemento che influisce su sudo, mantieni aperta una seconda sessione SSH, con accesso effettuato e sessione inattiva. Un file sudoers che non può essere analizzato oppure un’alternativa che punta a un binario non installato può impedirti di ottenere root su un server remoto. Questa precauzione rientra nelle attività da eseguire nei primi dieci minuti su un nuovo VPS.
Considera il ritorno alla versione precedente come una scadenza, non come una correzione. Ti concede una settimana per riscrivere correttamente le regole. La riscrittura è comunque utile, perché ogni regola con caratteri jolly che elimini concedeva più autorizzazioni di quanto il suo autore avesse previsto.
FAQ
Perché la regola wildcard di sudoers ha smesso di funzionare su Ubuntu 26.04?
Ubuntu 26.04 LTS seleziona sudo-rs come implementazione predefinita di sudo e sudo-rs non verifica i pattern wildcard all'interno degli argomenti di un comando. Consente una wildcard nel nome file del comando, "" per indicare l'assenza di argomenti e un singolo * come argomento finale. Una regola come /usr/bin/systemctl restart app-* inserisce un pattern al centro di un argomento, quindi non concede alcuna autorizzazione e il comando viene rifiutato. Esegui sudo -l -U deploy come root per verificare le autorizzazioni effettive dell'account, quindi sostituisci la regola con i comandi esatti oppure con uno script wrapper di proprietà di root.
Come posso tornare al sudo originale su Ubuntu 26.04?
L'implementazione originale è distribuita nel pacchetto sudo.ws. Installala con sudo apt install sudo.ws, quindi imposta l'alternativa in modo che punti a essa con sudo update-alternatives --set sudo /usr/bin/sudo.ws. Esegui prima update-alternatives --config sudo per leggere i percorsi esatti disponibili sul sistema e mantieni aperta una seconda sessione SSH mentre apporti la modifica. Questo non ripristina sudo-ldap, che è stato rimosso da 26.04 indipendentemente dall'implementazione selezionata.
sudo-rs legge lo stesso file /etc/sudoers?
Sì. sudo-rs legge /etc/sudoers e i file drop-in nella directory /etc/sudoers.d/, con la stessa sintassi per utenti, gruppi, alias, specifiche run-as e il tag NOPASSWD. Implementa un sottoinsieme del linguaggio sudoers, quindi le differenze riguardano costrutti mancanti, non costrutti con comportamento diverso. Modifica il file con sudo visudo, quindi verifica la configurazione con sudo visudo -c prima di chiudere la sessione.
Che cosa sostituisce sudo -E in sudo-rs?
sudo -E non è implementato ed era già sconsigliato nel sudo originale, perché fornire a un processo root un ambiente controllato dal chiamante è un modo noto per modificarne il comportamento. In sudoers indica invece le variabili effettivamente necessarie, con una riga come Defaults env_keep += "HTTP_PROXY HTTPS_PROXY NO_PROXY". env_reset è sempre attivo in sudo-rs e non può essere disabilitato, quindi tutte le variabili non mantenute vengono eliminate.