risposta-alla-domanda-sullo-sviluppo-web-bd.com

Comprensione della proprietà dei file utente nella finestra mobile: come evitare di modificare le autorizzazioni dei volumi collegati

Considera il seguente file Docker banale:

FROM debian:testing
RUN  adduser --disabled-password --gecos '' docker
RUN  adduser --disabled-password --gecos '' bob 

in una directory di lavoro con nient'altro. Costruisci l'immagine docker:

docker build -t test .

e quindi eseguire uno script bash sul contenitore, collegando la directory di lavoro in un nuovo sottodir nella directory home di bob:

docker run --rm -it -v $(pwd):/home/bob/subdir test 

Chi possiede il contenuto di subdir sul contenitore? Sul contenitore, eseguire:

cd /home/bob/subdir
ls -l

annuncio che vediamo:

-rw-rw-r-- 1 docker docker 120 Oct 22 03:47 Dockerfile

Sacri fumi! docker possiede i contenuti! Di nuovo sul computer Host all'esterno del contenitore, vediamo che il nostro utente originale possiede ancora Dockerfile. Proviamo a correggere la proprietà della home directory di bob. Sul contenitore, eseguire:

chown -R bob:bob /home/bob
ls -l 

e vediamo:

-rw-rw-r-- 1 bob bob 120 Oct 22 03:47 Dockerfile

Ma aspetta! all'esterno del contenitore, ora eseguiamo ls -l

-rw-rw-r-- 1 1001 1001 120 Oct 21 20:47 Dockerfile

non possediamo più il nostro file. Notizie terribili!


Se nell'esempio sopra avessimo aggiunto un solo utente, tutto sarebbe andato per il meglio. Per qualche motivo, Docker sembra rendere qualsiasi home directory di proprietà del primo primo utente non root che incontra (anche se quell'utente è dichiarato su un precedente Immagine). Allo stesso modo, questo primo utente è quello che corrisponde alle stesse autorizzazioni di proprietà del mio utente di casa.

Domanda 1 È corretto? Qualcuno può indicarmi la documentazione di questo, sto solo congetturando basato sull'esperimento di cui sopra.

Domanda 2: Forse questo è solo perché entrambi hanno lo stesso valore numerico sul kernel, e se ho provato su un sistema in cui il mio utente di casa non era id 1000 allora le autorizzazioni sarebbero cambiate in ogni caso?

Domanda: La vera domanda è, ovviamente, 'cosa devo fare al riguardo?' Se bob è connesso come bob sul computer host specificato, dovrebbe essere in grado di eseguire il contenitore come bob e non avere le autorizzazioni dei file modificate nel suo account Host. Allo stato attuale, deve effettivamente eseguire il contenitore come utente docker per evitare che il suo account venga modificato.

Ti sento chiedere Perché ho comunque un file Docker così strano? . Mi chiedo troppo a volte. Sto scrivendo un contenitore per una webapp (RStudio-server) che consente a diversi utenti di accedere, che utilizza semplicemente i nomi utente e le credenziali della macchina Linux come nomi utente validi. Questo mi porta la motivazione forse insolita di voler creare più utenti. Posso aggirare il problema creando l'utente solo in fase di esecuzione e tutto va bene. Tuttavia, utilizzo un'immagine di base che ha aggiunto un singolo utente docker in modo che possa essere utilizzata in modo interattivo senza essere eseguita come root (come da best practice). Ciò rovina tutto poiché quell'utente diventa il primo utente e finisce per possedere tutto, quindi tenta di accedere poiché altri utenti non riescono (l'app non può avviarsi perché manca di permessi di scrittura). La prima esecuzione dello script di avvio chown risolve questo problema, ma a costo di modifica dei permessi dei volumi collegati (ovviamente solo un problema se si collegano i volumi).

63
cboettig

È corretto? Qualcuno può indicarmi la documentazione di questo, sto solo congetturando basato sull'esperimento di cui sopra.

Forse questo è solo perché entrambi hanno lo stesso valore numerico sul kernel, e se testassi su un sistema in cui il mio utente di casa non era ID 1000, le autorizzazioni sarebbero cambiate in ogni caso?

Leggi info coreutils 'chown invocation', potrebbe darti un'idea migliore di come funzionano le autorizzazioni/proprietà dei file.

Fondamentalmente, tuttavia, ogni file sul tuo computer ha una serie di bit attaccati ad esso che ne definisce le autorizzazioni e la proprietà. Quando chown un file, stai semplicemente impostando questi bit.

Quando chown un file per un determinato utente/gruppo utilizzando il nome utente o il nome del gruppo, chown verrà visualizzato in /etc/passwd per il nome utente e /etc/group affinché il gruppo tenti di associare il nome a un ID. Se il nome utente/gruppo non esiste in quei file, chown fallirà.

[email protected]:/test# touch test
[email protected]:/test# ll
total 8
drwxr-xr-x  2 root root 4096 Oct 22 18:15 ./
drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../
-rw-r--r--  1 root root    0 Oct 22 18:15 test
[email protected]:/test# chown test:test test
chown: invalid user: 'test:test'

Tuttavia, puoi chown un file usando gli ID per quello che vuoi (all'interno di alcuni limiti interi positivi superiori, ovviamente), indipendentemente dal fatto che esista un utente/gruppo con tali ID sul tuo computer.

[email protected]:/test# chown 5000:5000 test
[email protected]:/test# ll
total 8
drwxr-xr-x  2 root root 4096 Oct 22 18:15 ./
drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../
-rw-r--r--  1 5000 5000    0 Oct 22 18:15 test

I bit UID e GID sono impostati sul file stesso, quindi quando si montano quei file all'interno del contenitore della finestra mobile, il file ha lo stesso UID proprietario/gruppo dell'host, ma ora è mappato su /etc/passwd nel contenitore, che probabilmente sarà un utente diverso a meno che non sia di proprietà di root (UID 0).

La vera domanda è, ovviamente, "cosa devo fare al riguardo?" Se bob ha effettuato l'accesso come bob sul computer Host specificato, dovrebbe essere in grado di eseguire il contenitore come bob e non avere le autorizzazioni dei file modificate nel suo account Host. Allo stato attuale, deve effettivamente eseguire il contenitore come docker utente per evitare che il suo account venga modificato.

Sembra che, con la tua configurazione attuale, dovrai assicurarti che i tuoi UID> nomi utente in /etc/passwd sul tuo host corrispondono ai tuoi UID> nomi utente nei tuoi contenitori /etc/passwd se desideri interagire con la tua directory degli utenti montati come lo stesso utente che ha effettuato l'accesso sull'host.

Puoi creare un utente con un ID utente specifico con useradd -u xxxx. Buuuut, sembra una soluzione disordinata ...

Potrebbe essere necessario trovare una soluzione che non monti una home directory degli utenti Host.

25
Chris McKinnel

Ho trovato due opzioni:

CHOWN tutte le cose (dopo aver fatto il tuo lavoro)

Ho fatto docker run -v `pwd`/shared:/shared image e il contenitore ha creato file all'interno di pwd/shared che appartengono al processo docker. Tuttavia, /shared è ancora di mia proprietà. Quindi, all'interno del processo docker, lo faccio

chown -R `stat -c "%u:%g" /shared` /shared

stat -c "%u:%g" /shared ritorna 1000:1000 nel mio caso, essendo il uid:gid del mio utente. Anche se non c'è nessun utente 1000 all'interno della finestra mobile conatainer, l'id è presente (e stat /shared dice "sconosciuto" se chiedi il nome utente).

Ad ogni modo, chown trasferisce obbedientemente la proprietà dei contenuti di /shared a 1000:1000 (che, per quanto riguarda, non esiste, ma fuori dal contenitore, sono io). Quindi ora possiedo tutti i file. Il contenitore può comunque modificare le cose se lo desidera, poiché dal suo punto di vista è root.

E tutto va bene per il mondo.

docker run -u quindi tutti i file creati avranno automaticamente il proprietario giusto

Un altro modo per farlo è il -u flag on docker run.

docker run -v `pwd`/shared:/shared -u `stat -c "%u:%g" /shared` ubuntu bash

In questo modo, l'utente finestra mobile all'interno del contenitore è youruid:yourgid.

Tuttavia: questo significa rinunciare all'autorità di root all'interno del contenitore (apt-get install, eccetera.). A meno che non si crei un utente con quel nuovo uid e lo si aggiunga al gruppo root.

54
Jared Forsyth

Quindi, ho finito in questo post cercando come ripristinare la proprietà di tutti i file (di proprietà di root) che sono usciti da un contenitore docker in esecuzione come root, al mio utente non privilegiato nell'host .

Avevo bisogno che il processo all'interno del contenitore fosse eseguito come root, quindi non posso usare -u su docker run.

Non sono orgoglioso di quello che ho fatto, ma alla fine del mio script bash, ho aggiunto questo:

docker run --rm -it \
    --entrypoint /bin/sh \
    -e Host_UID=`id -u` \
    -v ${Host_FOLDER_OWNED_BY_ROOT}:/tmp \
    Alpine:latest \
    -c 'chown -R ${Host_UID}:${Host_UID} /tmp/'

Rompiamo alcune delle righe:

  • Esegui/bin/sh all'interno del contenitore:

--entrypoint/bin/sh

  • Passa l'utente uid come variabile di ambiente al contenitore:

-e Host_UID = `id -u`

  • Montare qualsiasi cartella che si desidera ri-possedere al proprio utente ( riempito con file di proprietà di root, prodotti in uscita dal contenitore precedente eseguito come root ), sotto questo nuovo contenitore /tmp:

-v $ {Host_FOLDER_OWNED_BY_ROOT}:/tmp

  • Esegui chown in modo ricorsivo con l'utente dell'utente Host sulla directory di destinazione (montata all'interno del contenitore in /tmp):

-c 'chown -R $ {Host_UID}: $ {Host_UID}/tmp /'

Quindi, con questo, ho ripristinato i file al mio attuale utente senza "intensificare" i privilegi su root o su Sudo.

È sporco, ma ha funzionato. Spero di averti aiutato.

2
BBerastegui