L'uso di CmndAlias ALL
non sarà mai sicuro
Ci sono 1000 modi per correre service network restart
senza farlo sudo service network restart
. Ecco un esempio di cosa potrebbe provare un utente cattivo:
$ echo "service network restart" > /tmp/hax
$ chmod a+x /tmp/hax
$ sudo /tmp/hax
Se fornisci agli utenti l' ALL
alias di comando e quindi provi a creare una lista nera, saranno sempre in grado di trovare un modo per aggirarlo. Blacklist bash, e useranno Python. Blacklist python, e useranno Perl. Blacklist Perl, e useranno PHP. Nessuno lo vuole!
Se davvero non si vuole qualcuno a fare qualcosa, si dovrebbe fare come dice Thomas, e creare una whitelist di cose che sono autorizzati a fare.
Impostazione di una whitelist con un'eccezione
Un esempio di una piccola lista bianca con un'esclusione è disponibile nella parte inferiore di man sudoers
:
pete HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
The user pete is allowed to change anyone's password except for root on the HPPA
machines. Note that this assumes passwd(1) does not take multiple user names
on the command line.
(In realtà questo esempio dalla manpage non è sicuro e può essere sfruttato per cambiare la password di root! Vedi i commenti qui sotto per come.)
Possiamo provare ad adattarlo al tuo caso, per offrire tutti i service
comandi al gruppo di staff, ma escludiamo i service network
comandi che ti riguardano:
%staff ALL = /usr/sbin/service *, \
! /usr/sbin/service *network*, \
! /usr/sbin/service *NetworkManager*
(La ALL
posizione in quella posizione si riferisce a Host_Alias, non a Cmnd_Alias - confondere non è vero?)
L'utente non sarà in grado di eseguire sudo bash
o sudo tee
o sudo wget
o sudo /path/to/malicious_script
. Puoi mettere in whitelist più comandi di amministrazione per i tuoi utenti se stai attento. Sii specifico!
Nota: ho aggiunto la *
parola network
precedente prima , nel caso in cui una bandiera innocua venga mai aggiunta allo service
strumento in futuro. Immaginiamo che --verbose
in futuro sia stato aggiunto un flag, quindi gli utenti sarebbero in grado di eseguire quanto segue:
$ sudo service --verbose network restart
Quindi abbiamo bisogno *
di consumare tutte le bandiere prima del nome del servizio. L'unico svantaggio è che questo potrebbe bloccare altri servizi che non ti dispiace effettivamente far funzionare gli utenti, ad esempio un servizio chiamato safe-network
o che network-monitor
verrebbero rifiutati.
Consenti agli utenti di modificare un file utilizzando le autorizzazioni di gruppo
Di seguito puoi trovare vari tentativi che utilizzano rnano
through sudo
per consentire agli utenti di modificare uno o più file. Ma in realtà sono più complessi e più pericolosi di quanto dovrebbero essere.
Una soluzione molto più semplice e sicura è quella di modificare le autorizzazioni di gruppo sui file specifici per i quali si desidera aprire i diritti di modifica. Qui ci sono un paio di esempi:
### Give steve the ability to edit his nginx config:
$ chgrp steve /etc/nginx/sites-available/steves_dodgy_project
$ chmod g+rw /etc/nginx/sites-available/steves_dodgy_project
### Let all members of the staff group edit the group_website config:
$ chgrp staff /etc/nginx/sites-available/group_website
$ chmod g+rw /etc/nginx/sites-available/group_website
Se hai bisogno di un controllo più approfondito (ad esempio: accesso per soli 3 utenti, ma non per tutti i membri dello staff) puoi creare un nuovo gruppo usando il addgroup
comando e aggiungere solo pochi utenti.
Consenti agli utenti di modificare un file tramite sudo
Il resto di questa risposta è diventato un'indagine su quanto sia facile lasciare buchi nella sudo
configurazione quando si cerca di offrire flessibilità agli utenti. Non consiglierei di effettuare nessuna delle seguenti operazioni!
Se desideri concedere ai tuoi utenti l'accesso per modificare un file specifico, puoi provare a utilizzare rnano
:
%staff ALL = /bin/rnano /etc/nginx/sites-available/host
rnano
consentirà solo loro di modificare il file specificato. Ciò è importante per impedire a un utente malintenzionato di modificare un servizio di avvio diverso (ad esempio /etc/init.d/urandom
) e di aggiungere una linea che verrebbe eseguita service network restart
.
Sfortunatamente non ho trovato un modo per limitare rvim
sufficientemente (l'utente può ancora aprire qualsiasi file utilizzando :e
), quindi siamo bloccati nano
.
Sfortunatamente consentire agli utenti di modificare più file è molto più difficile ...
Consenti agli utenti di modificare più file (molto più difficile di quanto dovrebbe essere)
1. Approcci non sicuri
Fai attenzione ai caratteri jolly! Se offri troppa flessibilità (o flessibilità), puoi sfruttarla:
%staff ALL = /bin/rnano /etc/nginx/sites-available/* # UNSAFE!
In questo caso, un utente malintenzionato potrebbe modificare qualsiasi altro script del servizio di avvio e quindi eseguirlo:
$ sudo rnano /etc/nginx/sites-available/../../../any/file/on/the/system
(Il Sudo in realtà impedisce .
ed ..
espande il comando, ma sfortunatamente non sugli argomenti.)
Speravo che qualcosa del genere potesse funzionare, ma è ancora insicuro:
%staff ALL = /bin/rnano /etc/nginx/sites-available/[A-Za-z0-9_-]* # UNSAFE!
Dal sudo
momento che attualmente offre solo modelli glob , che *
corrisponderanno a tutto - non è una regexp!
(Modifica: ho preso in considerazione la possibilità di cavartela con quanto sopra nella tua situazione, perché non ci sono sottocartelle sottostanti sites-available
. Abbiamo richiesto che un carattere fosse associato dopo la cartella e che /..
dovesse fallire dopo un nome file. Tuttavia, questo non è un soluzione praticabile, perché rnano
accetta più argomenti. E comunque in generale questo non sarebbe ancora sicuro su una cartella con sottocartelle!)
Anche se non abbiamo sottocartelle ed escludiamo qualsiasi riga contenente /../
, la regola che offre un *
glob potrebbe essere comunque sfruttata, perché rnano
accetta più argomenti (scorrendoli sopra <C-X>
e lo spazio è felicemente accettato dal *
glob.
$ rnano /etc/nginx/sites-available/legal_file /then/any/file/on/the/system
2. Spingendo la busta (anche alla fine non sicura)
E se rifiutassimo qualsiasi linea contenente spazi o tentando di raggiungere /..
? Quindi una soluzione praticabile finale potrebbe essere questa:
# I tried hard to make this safe, but in the end I failed again.
# Please don't use this unless you are really smart or really stupid.
%staff ALL = /bin/rnano /etc/nginx/sites-available/*, \
! /bin/rnano */..*, \
! /bin/rnano /etc/nginx/sites-available/, \
! /bin/rnano */., \
! /bin/rnano * *
# CONCLUSION: It is still NOT SAFE if there are any subfolders, due to
# the bug in rnano described below.
Accettiamo qualsiasi cosa "sotto" la cartella ma rifiutiamo anche qualsiasi chiamata a rnano
se /..
o /.
o
sono passati, o se la cartella è indirizzata direttamente. (Tecnicamente l' /.
esclusione rende /..
superflua l' esclusione, ma ho lasciato entrambi per chiarezza.)
Ho trovato la cartella e le /.
esclusioni erano necessarie perché altrimenti l'utente poteva scegliere come target la cartella stessa. Ora potresti pensare che rnano
si bloccherebbe se puntato su una cartella, ma ti sbaglieresti. In realtà la mia versione (2.2.6-1ubuntu1) si avvia con un lieve avvertimento e un file vuoto, quindi <C-X>
mi chiede di inserire qualsiasi nome di file che mi piace salvare, aprendo un nuovo vettore di attacco! Beh, almeno si è rifiutato di sovrascrivere un file esistente (nel test che ho fatto). Comunque, dato che non c'è modo di inserire nella blacklist le sottocartelle con sudo, dobbiamo concludere che questo approccio non è ancora sicuro. Spiacente utenti!
Questa scoperta mi ha fatto dubitare della completezza della nano
modalità "limitata". Dicono che una catena è forte quanto il suo anello più debole. Sto cominciando a sentire la combinazione della sudo
blacklist black-magic e rnano
potrebbe non essere più sicuro di una catena di margherite.
3. Approcci sicuri ma limitati
I globi sono molto limitati: non ci permettono di abbinare più volte una classe di personaggi. Si potrebbe offrire più modifiche di file, se tutti i nomi dei file hanno la stessa lunghezza (in questo caso host
seguita da una sola cifra):
%staff ALL = /bin/rnano /etc/nginx/sites-available/host[0-9] # SAFE
Ma se si desidera consentire all'utente di modificare vari file, potrebbe essere necessario specificare esplicitamente ogni singolo file:
%staff ALL = /bin/rnano /etc/nginx/sites-available/hothost \
/bin/rnano /etc/nginx/sites-available/coldhost \ # SAFE
/bin/rnano /etc/nginx/sites-available/wethost \
/bin/rnano /etc/nginx/sites-available/steves_dodgy_project
Non essere tentato di utilizzare a*
in qualsiasi momento. Vedi le sezioni 1. e 2. sopra per perché! Ricorda: un piccolo errore può compromettere l'intero account del superutente e l'intero sistema.
4. Scrivi il tuo controllo argomento (la sicurezza è ora tua responsabilità)
Spero che aggiungeranno il supporto regexp sudo
in futuro; potrebbe risolvere molti problemi se usato correttamente. Ma potremmo anche aver bisogno della possibilità di controllare le proprietà degli argomenti (per consentire solo file, solo cartelle o solo determinati flag).
Ma c'è un'alternativa per creare flessibilità in sudo. Passa il dollaro:
%staff ALL = /root/bin/staffedit *
Quindi scrivi il tuo staffedit
script o eseguibile per verificare se gli argomenti passati dall'utente sono legali e, se lo sono, esegui la loro richiesta.
networking
enetwork-manager
? Inoltre, perché i tuoi utenti hannosudo
accesso? Non dovrebbero a meno che tu non voglia che abbiano i privilegi di root completi.