Sudo (Italiano)
Sudo permette a un amministratore di sistema di delegare l'autorità, a determinati utenti o gruppi di utenti, di esecuzione di comandi come root o come un altro utente, fornendo al contempo una traccia di controllo dei comandi e dei loro argomenti.
Sudo è un'alternativa a su (Italiano) per l'esecuzione di comandi come root. A differenza di su (Italiano), che avvia una shell root che consente l'accesso root a tutti i comandi successivi, sudo concede invece un innalzamento temporaneo dei privilegi per un singolo comando. Consentendo i privilegi di root solo quando necessario, l'uso di sudo riduce la probabilità che un errore di battitura o un bug in un comando invocato rovini il sistema.
Sudo può anche essere usato per eseguire comandi come altri utenti; in aggiunta, sudo registra nel journal tutti i comandi e i tentativi di accesso falliti ai fini dell'audit di sicurezza.
Installazione
Installare il pacchetto sudo.
In alternativa, installare il pacchetto sudo-rs, che è un'implementazione di sudo sicura per la memoria, sebbene con alcune limitazioni.
Uso
sudo deve essere configurato correttamente per poterlo usare come utente non privilegiato. Consultare la sezione #Configurazione.
Per usare sudo basta anteporre sudo e uno spazio a un comando e ai suoi argomenti:
$ sudo comando
Ad esempio, per usare pacman:
$ sudo pacman -Syu
Consultare sudo(8) per ulteriori informazioni.
Shell di login
Non è possibile eseguire ogni comando come un altro utente semplicemente anteponendo sudo. In particolare, quando si usa una redirezione e una sostituzione di comando, è necessario utilizzare una shell di login, alla quale si può accedere facilmente con sudo -iu utente (si può omettere -u utente se l'utente desiderato è root).
Nel seguente esempio, la sostituzione di comando funzionerebbe in una shell completa, ma fallisce anteponendo sudo:
$ sudo wpa_supplicant -B -i interfaccia -c <(wpa_passphrase MioSSID passphrase)
Successfully initialized wpa_supplicant Failed to open config file '/dev/fd/63', error: No such file or directory Failed to read or parse configuration '/dev/fd/63'
Configurazione
Il file di configurazione principale per sudo è /etc/sudoers. Deve essere sempre modificato con il comando visudo(8). Può essere usato per impostare alias (cioè delle variabili, in sostanza), cambiare i comportamenti predefiniti e specificare cosa possono eseguire determinati utenti. Consultare sudoers(5) per ulteriori informazioni.
sudo analizza anche i file contenuti nella directory /etc/sudoers.d/. Ciò significa che invece di modificare /etc/sudoers è possibile cambiare le impostazioni in file separati e inserirli in quella directory. Questa possibilità presenta due vantaggi:
- Non è necessario unire il file
sudoers.pacnew; - Se c'è un problema con una nuova voce, è possibile rimuovere il file incriminato invece di modificare
/etc/sudoers(ma vedere l'avviso sotto).
Il formato per le voci in questi file "drop-in" è lo stesso di /etc/sudoers. Per modificarli direttamente, usare visudo /etc/sudoers.d/nomefile. Per i dettagli consultare sudoers(5) § Including other files from within sudoers.
I file nella directory /etc/sudoers.d/ vengono analizzati in ordine lessicografico; i nomi dei file che contengono . o ~ vengono saltati. Per evitare problemi di ordinamento, i nomi dei file dovrebbero iniziare con due cifre, ad esempio 10-foo.
/etc/sudoers.d/ sono fragili tanto quanto /etc/sudoers stesso: qualsiasi file formattato in modo errato impedirà a sudo di funzionare. Pertanto, per lo stesso motivo, si consiglia vivamente di utilizzare visudo.Struttura delle opzioni predefinite
Come spiegato in sudoers(5) § Defaults, molte "opzioni di configurazione del comportamento possono essere modificate rispetto ai loro valori predefiniti al momento dell'esecuzione tramite una o più linee Default_Entry". sudoers(5) § SUDOERS OPTIONS elenca tutte le opzioni che possono essere utilizzate con il comando Defaults nella configurazione.
Visualizzare le impostazioni correnti
Eseguire sudo -ll per stampare la configurazione corrente di sudo, oppure sudo -lU utente per un utente specifico.
Usare visudo
visudo blocca il file specificato (/etc/sudoers per impostazione predefinita), salva le modifiche in un file temporaneo e ne controlla la sintassi prima di scriverlo.
- È imperativo che
sudoerssia privo di errori di sintassi! Qualsiasi errore rende sudo inutilizzabile. Modificarlo sempre con visudo per prevenire errori. - visudo(8) avverte che configurare visudo per onorare le variabili d'ambiente dell'utente per il proprio editor preferito può rappresentare un buco di sicurezza, poiché consente all'utente con privilegi di visudo di eseguire comandi arbitrari come root senza registrazione, semplicemente impostando quella variabile su qualcos'altro.
L'editor predefinito per visudo è vi. Il pacchetto sudo è compilato con --with-env-editor e onora l'uso delle variabili SUDO_EDITOR, VISUAL e EDITOR. EDITOR non viene utilizzato quando VISUAL è impostato.
Per stabilire nano come editor di visudo per la durata della sessione corrente della shell, esportare EDITOR=nano; per usare un editor diverso solo una volta, basta impostare la variabile prima di chiamare visudo:
# EDITOR=nano visudo /etc/sudoers.d/10-editor
Per cambiare l'editor in modo permanente, vedere Environment variables#Per user.
Per cambiare l'editor in modo permanente a livello di sistema solo per visudo (ad esempio con rnano(1), la modalità ristretta di nano):
/etc/sudoers.d/10-editor
# Set default EDITOR to restricted version of nano, and do not allow visudo to use EDITOR/VISUAL. Defaults editor=/usr/bin/rnano, !env_editor
In alternativa, è possibile modificare una copia del file e controllarla successivamente utilizzando visudo -c /copia/del/file. Questa operazione potrebbe tornare utile nel caso in cui si voglia evitare di bloccare il file con visudo.
Esempi di voci
Per consentire all'utente archie, quando antepone sudo a un comando, di eseguire tutti i comandi su una precisa macchina (hostname) come qualsiasi utente e gruppo, creare il file:
/etc/sudoers.d/90-archie
archie hostname=(ALL:ALL) ALL
Per consentire ai membri del gruppo wheel ogni accesso:
/etc/sudoers.d/10-wheel
%wheel ALL=(ALL:ALL) ALL
wheel e aggiungervi l'utente, poiché per impostazione predefinita Polkit tratta i membri del gruppo wheel come amministratori. Se l'utente non è un membro di wheel, il software che utilizza Polkit potrebbe chiedere di autenticarsi utilizzando la password di root invece della password dell'utente.Per disabilitare la richiesta della password per l'utente archie:
/etc/sudoers.d/90-archie_nopasswd
Defaults:archie !authenticate
Abilitare solo comandi esplicitamente definiti per l'utente archie su hostname senza password:
/etc/sudoers.d/90-archie_commands
archie hostname= NOPASSWD: /usr/bin/halt,/usr/bin/poweroff,/usr/bin/reboot,/usr/bin/pacman -Syu
%wheel se il proprio utente fa parte di questo gruppo.Un esempio dettagliato di sudoers è disponibile in /usr/share/doc/sudo/examples/sudoers. Altrimenti, consultare sudoers(5) per informazioni dettagliate.
Permessi predefiniti del file Sudoers
Il proprietario e il gruppo per il file sudoers devono essere entrambi 0 (root). I permessi del file devono essere impostati a 0440. Questi permessi sono impostati di default, ma se vengono modificati accidentalmente, dovrebbero essere ripristinati immediatamente, altrimenti sudo fallirà.
# chown -c root:root /etc/sudoers # chmod -c 0440 /etc/sudoers
Eseguire un comando via SSH
SSH non alloca un tty per impostazione predefinita quando si esegue un comando remoto. Senza un tty allocato, sudo non può impedire che la password venga visualizzata. Si dovrebbe usare l'opzione -t di ssh per forzare l'allocazione di un tty e impostare l'opzione Defaults requiretty per consentire all'utente di eseguire sudo solo se ha un tty.
/etc/sudoers.d/10-requiretty
# Disable "ssh hostname sudo <cmd>", because it will show the password in clear text. You have to run "ssh -t hostname sudo <cmd>". # Defaults requiretty Defaults cmddenial_message="Usage without a TTY is not allowed: run 'ssh -t'!"
Umask permissiva
Sudo unirà il valore della umask dell'utente con la propria umask (che di default è 0022). Ciò impedisce a sudo di creare file con permessi più aperti di quanto consentito dalla umask dell'utente. Sebbene questo sia un comportamento predefinito sensato se non si utilizza una umask personalizzata, può portare a situazioni in cui un'utilità eseguita da sudo può creare file con permessi diversi rispetto a quelli che avrebbe se fosse eseguita direttamente da root. Se si verificano errori a causa di ciò, sudo fornisce un modo per correggere la umask, anche se la umask desiderata è più permissiva di quella specificata dall'utente:
/etc/sudoers.d/10-umask_override (Italiano)
Defaults umask = 0022 Defaults umask_override
Questo imposta la umask di sudo sulla umask predefinita di root (0022) e sovrascrive il comportamento predefinito, utilizzando sempre la umask indicata indipendentemente da quella impostata dall'utente.
Suggerimenti e trucchi
Ridurre il numero di volte in cui è necessario digitare la password
Se risulta fastidioso dover reinserire la password ogni 5 minuti (valore predefinito), è possibile cambiarlo impostando un valore più lungo per timestamp_timeout (in minuti):
/etc/sudoers.d/10-timestamp_timeout
Defaults timestamp_timeout=10
Se si stanno usando comandi sudo in uno script lungo e non si vuole attendere l'input dell'utente quando il timeout scade, è possibile aggiornare il timeout eseguendo separatamente sudo -v in un ciclo (mentre sudo -K lo revoca immediatamente).
Disabilitare il timeout della richiesta password
Un fastidio comune è un processo a lunga esecuzione che gira in un terminale in background con permessi normali ed eleva i privilegi solo quando necessario. Ciò porta a una richiesta di password di sudo che passa inosservata e va in timeout, a quel punto il processo muore e il lavoro svolto viene perso o, nel migliore dei casi, memorizzato nella cache. Il consiglio comune è di abilitare sudo senza password o estendere il timeout della memorizzazione della password di sudo. Entrambe le soluzioni hanno implicazioni negative per la sicurezza. Il timeout della richiesta può invece essere disabilitato e, poiché ciò non serve a alcuno scopo di sicurezza ragionevole, dovrebbe essere la soluzione ideale in questo caso:
/etc/sudoers.d/10-passwd_timeout
Defaults passwd_timeout=0
Passare gli alias
Quanto segue è rilevante solo se il completamento bash non è disponibile (sia completo che ridotto come descritto sopra): gli alias in Zsh e Bash vengono normalmente espansi solo per la prima parola di un comando. Ciò significa che i propri alias normalmente non verranno espansi quando si esegue il comando sudo. Un modo per far espandere la parola successiva è creare un alias per sudo che termini con uno spazio. Aggiungere quanto segue al file di configurazione della propria shell:
alias sudo='sudo '
zshmisc(1) § ALIASING descrive come funziona:
- Se il testo di sostituzione termina con uno spazio, la parola successiva nell'input della shell è sempre idonea ai fini dell'espansione degli alias.
Allo stesso modo bash(1) § ALIASES:
- Se l'ultimo carattere del valore dell'alias è uno spazio, allora anche la parola del comando successiva all'alias viene controllata per l'espansione dell'alias.
Aggiungere il segnale acustico del terminale alla richiesta password
Per attirare l'attenzione su una richiesta di sudo in un terminale in background, gli utenti possono semplicemente fargli emettere un carattere bell:
/etc/sudoers.d/10-passprompt
Defaults passprompt="^G[sudo] password for %p: "
Si noti che ^G è un carattere bell letterale. Ad esempio, in vim, inserirlo usando la sequenza Ctrl+v Ctrl+g. Se Ctrl+v è già mappato (ad es. per l'operazione di incolla), si può di solito usare Ctrl+q. In nano, Alt+v Ctrl+g.
Un'altra opzione è impostare la variabile d'ambiente SUDO_PROMPT. Ad esempio, aggiungere quanto segue al file di configurazione della propria shell:
export SUDO_PROMPT=$'\a[sudo] password per %p: '
Disabilitare sudo per terminale
Se risultano fastidiose le impostazioni predefinite di sudo che richiedono di inserire la password ogni volta che si apre un nuovo terminale, cambiare il timestamp_type (che è tty per impostazione predefinita) in ppid, in modo che tutti i processi con lo stesso ID del processo padre condividano il timeout di 5 minuti. Ciò risulta particolarmente utile con un terminal multiplexer o emulatori di terminale grafici a schede. Un'altra opzione è impostarlo su global.
global permetterà a qualsiasi processo di usare la propria sessione sudo./etc/sudoers.d/10-timestamp_type
Defaults timestamp_type=ppid
Variabili d'ambiente
Se si hanno molte variabili d'ambiente o se si esportano le impostazioni del proxy tramite export http_proxy="...", quando si usa sudo queste variabili non vengono passate all'account root a meno che non si esegua sudo con l'opzione -E/--preserve-env.
$ sudo -E pacman -Syu
Il modo raccomandato per preservare le variabili d'ambiente è aggiungerle a env_keep:
/etc/sudoers.d/10-env_keep
Defaults env_keep += "ftp_proxy http_proxy https_proxy no_proxy"
Password di root
Gli utenti possono configurare sudo per chiedere la password di root invece della password dell'utente aggiungendo targetpw (utente di destinazione, predefinito root) o rootpw alla riga Defaults in /etc/sudoers:
/etc/sudoers.d/10-targetpw
Defaults targetpw
Per evitare di esporre la password di root agli utenti, è possibile limitare questo comportamento a un gruppo specifico:
/etc/sudoers.d/10-targetpw
Defaults:%wheel targetpw %wheel ALL=(ALL) ALL
Disabilitare il login di root
Gli utenti potrebbero voler disabilitare il login di root. Senza root, gli attaccanti devono prima indovinare un nome utente configurato come sudoer e la relativa password utente. Consultare ad esempio OpenSSH#Deny.
- Si faccia attenzione: si potrebbe rimanere chiusi fuori dal sistema disabilitando il login di root. Sudo non è installato automaticamente e la sua configurazione predefinita non consente né l'accesso root senza password né l'accesso root con la propria password. Assicurarsi che un utente sia correttamente configurato come sudoer prima di disabilitare l'account root!
- Se è stato cambiato il file sudoers per usare rootpw come predefinito, allora non bisogna disabilitare il login di root con nessuno dei seguenti comandi!
- Se si è già rimasti chiusi fuori, consultare Password recovery per un aiuto.
L'account può essere bloccato tramite passwd:
# passwd -l root
Un comando simile sblocca root.
$ sudo passwd -u root
In alternativa, si può usare il seguente comando per eliminare la password e quindi bloccare l'account root:
$ sudo passwd -dl root
Per abilitare nuovamente il login di root:
$ sudo passwd root
Si noti che questo comando disabilita semplicemente il login basato su password. L'utente potrebbe essere ancora in grado di accedere utilizzando un altro token di autenticazione (ad esempio una chiave SSH). Per disabilitare l'account usare:
$ usermod --expiredate 1 root
In caso di emergenza del sistema, il prompt di ripristino chiederà la password di root, rendendo impossibile l'accesso alla shell di ripristino. Per sbloccare automaticamente l'account root in caso di emergenza, aggiungere la variabile d'ambiente SYSTEMD_SULOGIN_FORCE=1 a rescue.service utilizzando un drop-in file:
/etc/systemd/system/rescue.service.d/SYSTEMD_SULOGIN_FORCE.conf
[Service] Environment=SYSTEMD_SULOGIN_FORCE=1
sudo -i.kdesu
kdesu può essere usato sotto KDE per avviare applicazioni GUI con privilegi di root. È possibile che per impostazione predefinita kdesu provi a usare su anche se l'account root è disabilitato. È però possibile dire a kdesu di usare sudo invece di su. Creare o modificare il file ~/.config/kdesurc:
[super-user-command] super-user-command=sudo
oppure usare il seguente comando:
$ kwriteconfig6 --file kdesurc --group super-user-command --key super-user-command sudo
Esempio di hardening con sudo
Supponiamo di creare 3 utenti: admin, devel e archie. L'utente "admin" viene usato per journalctl, systemctl, mount, kill e iptables; "devel" viene usato per installare pacchetti e modificare i file di configurazione; "archie" è l'utente con cui si effettua l'accesso. Per permettere ad "archie" di riavviare, spegnere e usare netctl, faremmo quanto segue:
Modificare /etc/pam.d/su e /etc/pam.d/su-l. Richiedere che l'utente sia nel gruppo wheel, ma non metterci nessuno.
#%PAM-1.0 auth sufficient pam_rootok.so # Uncomment the following line to implicitly trust users in the "wheel" group. #auth sufficient pam_wheel.so trust use_uid # Uncomment the following line to require a user to be in the "wheel" group. auth required pam_wheel.so use_uid auth required pam_unix.so account required pam_unix.so session required pam_unix.so
Limitare l'accesso SSH al gruppo "ssh". Solo archie farà parte di questo gruppo.
# groupadd -r ssh # gpasswd -a archie ssh # echo 'AllowGroups ssh' >> /etc/ssh/sshd_config
Riavviare sshd.service. Aggiungere gli utenti agli altri gruppi.
# for g in power network ;do ;gpasswd -a archie $g ;done # for g in network power storage ;do ;gpasswd -a admin $g ;done
Impostare i permessi sui file di configurazione in modo che devel possa modificarli.
# chown -R devel:root /etc/{http,openvpn,cups,zsh,vim,screenrc}
/etc/sudoers.d/80-hardened
Cmnd_Alias POWER = /usr/bin/shutdown -h now, /usr/bin/halt, /usr/bin/poweroff, /usr/bin/reboot Cmnd_Alias STORAGE = /usr/bin/mount -o nosuid\,nodev\,noexec, /usr/bin/umount Cmnd_Alias SYSTEMD = /usr/bin/journalctl, /usr/bin/systemctl Cmnd_Alias KILL = /usr/bin/kill, /usr/bin/killall Cmnd_Alias PKGMAN = /usr/bin/pacman Cmnd_Alias NETWORK = /usr/bin/netctl Cmnd_Alias FIREWALL = /usr/bin/iptables, /usr/bin/ip6tables Cmnd_Alias SHELL = /usr/bin/zsh, /usr/bin/bash %power ALL = (root) NOPASSWD: POWER %network ALL = (root) NETWORK %storage ALL = (root) STORAGE root ALL = (ALL) ALL admin ALL = (root) SYSTEMD, KILL, FIREWALL devel ALL = (root) PKGMAN archie ALL = (devel) SHELL, (admin) SHELL
Con questa configurazione, non si avrà quasi mai bisogno di accedere come utente root. archie può connettersi al Wi-Fi di casa.
$ sudo netctl start home $ sudo poweroff
archie non può usare netctl come nessun altro utente.
$ sudo -u admin -- netctl start home
Quando archie ha bisogno di usare journalctl o terminare un processo fuori controllo, può passare a quell'utente.
$ sudo -i -u devel $ sudo -i -u admin
Ma archie non può passare all'utente root.
$ sudo -i -u root
Se archie vuole avviare una sessione GNU Screen come admin, può farlo così:
$ sudo -i -u admin [admin]$ chown admin:tty `echo $TTY` [admin]$ screen
Modificare i file
sudo fornisce il comando sudoedit (equivalente a sudo -e). Questo comando è utile per modificare file che possono essere modificati solo da root mentre si esegue l'editor come utente normale, utilizzando la configurazione di quell'utente.
Per modificare un file, impostare SUDO_EDITOR sul nome dell'editor e passare il nome del file a sudoedit. Per esempio:
$ SUDO_EDITOR=vim sudoedit /etc/file
Consultare #Usare visudo e sudo(8) § e per i modi di impostare l'editor, ma attenzione ai possibili problemi di sicurezza.
Se vengono passati più nomi a sudo, tutti i file vengono aperti nell'editor in una singola invocazione. Una funzione utile per unire file:
$ SUDO_EDITOR=vimdiff sudoedit /etc/file /etc/file.pacnew
Abilitare insults
Gli utenti possono abilitare l'easter egg degli insulti in sudo aggiungendo la seguente riga nel file sudoers con visudo.
/etc/sudoers.d/10-insults
Defaults insults
Quando si inserirà una password errata, il messaggio Riprovare. verrà sostituito con insulti umoristici.
Abilitare il feedback visivo della password
Per impostazione predefinita, non c'è alcun feedback visivo quando si inserisce una password. Questo è fatto apposta per una maggiore sicurezza. Tuttavia, se si desidera avere un feedback visivo, è possibile abilitarlo aggiungendo questa riga:
/etc/sudoers.d/10-pwfeedback
Defaults pwfeedback
Prompt della password colorato
Per personalizzare il prompt della password con colori e caratteri in grassetto, impostare la variabile d'ambiente SUDO_PROMPT nel file di inizializzazione della shell e usare tput(1). Ad esempio, per impostare il prompt della password in rosso grassetto, usa questo:
export SUDO_PROMPT="$(tput setaf 1 bold)Password:$(tput sgr0) "
Oppure usare colori diversi con il messaggio predefinito in questo modo:
export SUDO_PROMPT="$(tput setab 1 setaf 7 bold)[sudo]$(tput sgr0) $(tput setaf 6)password per$(tput sgr0) $(tput setaf 5)%p$(tput sgr0): "
Consultare di più su Color output in console e Bash/Prompt customization.
Usare U2F
U2F funziona bene con sudo, perché può eliminare efficacemente il rischio di shoulder surfing in aree pubbliche, pur offrendo un controllo consapevole per approvare la richiesta con un semplice tocco fisico. Consultare Universal 2nd Factor#Passwordless sudo.
Scrivere su file protetti
Quando si usa sudo, si potrebbe voler scrivere su file protetti. L'uso di tee permette tale separazione:
$ input stream | sudo tee --option file_protetto_1 file_protetto_2...
quando una semplice redirezione >/>> non avrebbe funzionato.
In Vim
Un concetto simile è utile quando ci si è dimenticati di avviare Vim con sudo durante la modifica di un file di proprietà di un altro utente. In questo caso si può fare quanto segue all'interno di Vim per salvare il file:
:w !sudo tee %
Si può aggiungere questa riga al proprio ~/.vimrc per rendere questo trucco facile da usare con la mappatura :w!! in modalità comando:
~/.vimrc
" Permette il salvataggio dei file come sudo quando ci si dimentica di avviare vim con sudo cmap w!! w !sudo tee > /dev/null %
La parte > /dev/null scarta esplicitamente lo standard output poiché non abbiamo bisogno di passare nulla a un altro comando in pipe.
Una spiegazione più dettagliata di come e perché funziona si può trovare nell'articolo How does the vim “write with sudo” trick work? su StackOverflow.
Usare sudo-rs senza il pacchetto sudo
È possibile utilizzare sudo-rs come sostituto autonomo per sudo, senza richiedere il pacchetto sudo.
Creare /etc/pam.d/sudo seguendo la configurazione predefinita di sudo. Creare anche /etc/pam.d/sudo-i per sudo -i:
# ln -s /etc/pam.d/sudo /etc/pam.d/sudo-i
Creare o modificare /etc/sudo-rs/config.toml:
/etc/sudo-rs/config.toml
[defaults] askpass = false timeout = 15
sudo-rs supporta sia /etc/sudoers che /etc/sudoers-rs e utilizza quest'ultimo se esiste. In opzione è possibile sostituire sudo con sudo-rs creando un collegamento simbolico (symlink) da una directory del PATH a priorità più alta:
# ln -s /usr/bin/sudo-rs /usr/local/bin/sudo