Come avvicinarsi alla creazione di un'app Linux che richiede i privilegi di root?

10

Sto lavorando su un indicatore per Ubuntu, e uno dei compiti che dovrebbe svolgere è chmod -x e chmod +x uno specifico binario di proprietà della radice ( /usr/lib/x86_64-linux-gnu/notify-osd per essere precisi). Per quanto ho capito, le mie opzioni sono:

  • esegui il comando con pkexec ogni volta (cosa che voglio evitare per amore dell'esperienza utente);
  • poiché l'indicatore è in python, potrei avere un binario con setuid bit set scritto in C. Tuttavia, mi è stato detto che questo approccio è disapprovato;
  • avvia un "proxy" che verrà eseguito come root e eseguirà solo quella specifica attività e l'indicatore comunicherà con quel "proxy"

La mia domanda è davvero, quale approccio sarebbe il migliore in termini di sicurezza e esperienza utente? Come dovrei approcciare all'implementazione di un'app che richiede un compito specifico da eseguire come root e il resto da utente normale.

    
posta Sergiy Kolodyazhnyy 29.10.2016 - 07:55
fonte

2 risposte

2

Non c'è davvero una risposta corretta a questa domanda. È un compromesso tra sicurezza e usabilità.

run command with pkexec each time ( which I kind of want to avoid for the sake of user experience );

Se il pubblico previsto non ha "CLIphobia", sudo potrebbe essere davvero fantastico qui se "ogni volta" è entro 15 minuti.

Ma da un punto di vista della sicurezza, raccomanderei pkexec. Presumo che possa essere considerato attendibile poiché viene preinstallato con la distro, a differenza di alcuni wrapper o demoni setuid rapidamente hackerati.

since the indicator is in python, I could have a binary with setuid bit set written in C. However, I've been told this approach is frowned upon;

L'unico problema di cui ho sentito parlare con setuid wrappers è che possono sovrascrivere se stessi con un trojan se sfruttato, ma questo non è rilevante per setuid-to- / root / binari come qualsiasi altro exploit su un processo in esecuzione come root significa che sei avvitato comunque.

L'unico problema che ho riscontrato non si applica a setuid-to- / root / binari, è stato così che non ho capito tutti gli ID utente unix e ho dimenticato di impostare l'utente reale ID, ID utente salvato e equivalenti ID gruppo, ciò significa che un programma che / drops / privilegi può ancora ottenerli indietro.

Potrebbero esserci altri motivi per cui i wrapper setuid sono disapprovati, ma non ne ho mai sentito parlare. Se nessun altro può trovare ragioni per cui i wrapper setuid sono disapprovati, un wrapper setuid sarà un'ottima scelta.

start a "proxy" which will run as root and only perform that one specific task , and the indicator will communicate with that "proxy"

Se crei un demone per eseguire l'operazione, tienilo il più semplice possibile e assicurati che gli utenti non autorizzati non riescano a comunicare con esso.

Posso pensare a due opzioni: (1) usare una password che un client autorizzato dovrebbe conoscere, il daemon lo sa e un client non autorizzato non lo sa. La password dovrebbe essere archiviata in un file chmoded 400 e di proprietà di root.

(2) usa le autorizzazioni unix sul socket per impedire a qualsiasi altro utente locale di provare anche a (ab) usare il demone. link

L'opzione due può essere considerata meno sicura e più incoerente in UX. L'utente potrebbe non capire il motivo per cui non funzionerà quando è connesso come un altro utente, il che è veramente brutto quando accade.

    
risposta data 29.10.2016 - 09:04
fonte
2

In primo luogo, vorrei rispondere alla domanda nel titolo:

How to approach creating a Linux app that requires root privilege?

Non richiedere o ottenere privilegi di root completi a meno che tu non li richieda assolutamente, in modo positivo. Piuttosto, come sottolineato da utente2313067 in un commento, utilizzare le capacità . Da man 7 capabilities :

Starting with kernel 2.2, Linux divides the privileges traditionally associated with superuser into distinct units, known as capabilities, which can be independently enabled and disabled. Capabilities are a per-thread attribute.

Linux 2.2 è stato rilasciato all'inizio del 1999 e, di conseguenza, ha più di 17 anni al mio scrivendo questo Rifiutarsi di girare su kernel che non supportano le funzionalità non è certo fuori dal regno di oggi ragionevole anche per software ampiamente distribuiti.

Specificamente, in questo caso, il tuo processo richiederebbe la capacità CAP_FOWNER , che tra le altre cose dice al kernel:

Bypass permission checks on operations that normally require the file system UID of the process to match the UID of the file (e.g., chmod(2), utime(2)), excluding those operations covered by CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH

Secondo, in generale l'approccio migliore consiste nel limitare le autorizzazioni estese il più possibile in ambito. Nel tuo caso, questo probabilmente significa un piccolo programma progettato per solo attivare o disattivare il bit eseguibile sul file in questione, e niente di più. Creare un piccolo programma, forse con il nome del file rilevante codificato (suggerisco una macro #define se usi C, o qualche meccanismo simile se usi un'altra lingua), che prende come input un singolo parametro a singolo carattere che dice se il bit eseguibile deve essere acceso o spento. Fai un sacco di controlli di sanità mentale e poi chiama stat () e chmod () ( non / usr / bin / stat e / bin / chmod) direttamente con i parametri appropriati. In questo modo, anche se c'è un bug nel tuo piccolo programma, diventa molto difficile approfittarne per fare qualcosa di diverso da ciò che era inteso. Chiama questo programma con un percorso completo e assicurati che non possa essere utilizzato da alcun utente non autorizzato (e certamente non modificato da nessuno). Prendi in considerazione la possibilità di compilarlo staticamente per ridurre il rischio di attacchi al preloader della libreria.

Terzo, considera perché è necessario modificare il bit eseguibile in primo luogo. Sei forse utilizzando lo stato globale per gestire un problema locale ? Potrebbe esserci un modo per realizzare ciò che si sta tentando di fare senza dover ricorrere alle modifiche ai permessi dei file in primo luogo. Assicurati di aver esaurito tutte le altre opzioni ragionevoli prima di ricorrere alla modifica dello stato del sistema globale persistente.

    
risposta data 29.10.2016 - 13:42
fonte

Leggi altre domande sui tag