Da Docker a OpenShift
Sempre più aziende stanno migrando verso servizi di orchestrazione come Kubernetes e OpenShift; quest’ultimo ha aumentato le restrizioni alla sicurezza seguendo una strategia che non consente agli utenti di eseguire con privilegi di amministratore, quindi la maggior parte dei container che di solito vengono eseguiti correttamente su Docker e Kubernetes potrebbero non funzionare correttamente su OpenShift.
Versione corta
Passi principali:
- Impostare la proprietà del gruppo sul gruppo principale (0).
- Non utilizzare root come specifica per la direttiva USER in Dockerfile.
- I file eseguibili devono essere eseguiti dal gruppo radice (0) e dal proprietario.
- Non è possibile utilizzare porte inferiori a 1024.
L’uso dei ID assegnati in maniera arbitraria agli utenti fa parte della strategia di sicurezza multi-livello impiegata da OpenShift per ridurre i rischi di un’applicazione o del runtime del contenitore compromessi.
Versione lunga
Il presupposto di base è che i container vengano eseguiti utilizzando un ID utente assegnato in modo arbitrario: ciò significa che ogni container ha un ID utente assegnato che è univoco per il tuo progetto.
In effetti, al tuo progetto viene assegnato un ID utente che appartiene a un intervallo preciso con cui le applicazioni possono essere eseguite.
In questo modo, il range di ID utente utilizzato sarà univoco e non si sovrapporrà ad altri progetti. Per vedere quale intervallo è assegnato a un progetto eseguendo oc describe sul progetto.
openshift.io/sa.scc.uid-range=1008050000/10000
Al contrario di OpenShift, Docker e Kubernetes possono eseguire container che utilizzi un utente specifico definito tramite la direttiva USER nel Dockerfile, oppure andranno ad utilizzare l’utente root se non viene esplicitamente specificato.
Come fare
Il punto è: come fare a rendere un’immagine Docker che gira -magari- anche su Kubernetes pronta per essere eseguita su OpenShift?
Qui i passaggi da seguire:
Imposta il gruppo
Sebbene OpenShift esegua i container utilizzando un ID utente assegnato arbitrariamente, l’ID gruppo deve essere sempre impostato sul gruppo root (0).
Ciò significa che ogni directory e file devono essere accessibili dal gruppo root per funzionare.
Di solito, ciò comporta una modifica nel Dockerfile come nell’esempio seguente:
RUN chgrp -R 0 /mia/directory && \
chmod -R g=u /mia/directory
In questo caso, gli utenti del gruppo root possono accedere alle risorse specificate con gli stessi privilegi del proprietario.
User 1001
Le linee guida di RedHat suggeriscono di modificare il Dockerfile per utilizzare un utente casuale, per garantire piena compatibilità con OpenShift, ma anche retro-compatibilità con Kubernetes e Docker.
Questo si traduce in queste righe:
USER 1001
RUN chown -R 1001:0 /mia/directory
In questo caso, quando l’immagine finale verrà eseguita su OpenShift, l’utente specificato verrà ignorato poiché il cluster assegnerà a un utente un ID arbitrario. Questa modifica consente di eseguire la tua immagine sia su Kubernetes che su OpenShift, con un livello di sicurezza più elevato.
Tieni presente che il tentativo di risolvere i problemi relativi ai permessi nella proprietà initContainers impostando dei permessi superiori non funzionerà; il vantaggio offerto da Kubernetes per gestire i privilegi in questa fase si basa sul presupposto che sei root, ma in OpenShift anche gli initContainer verranno assegnati a un utente arbitrario.
Permessi
Per rendere i tuoi file eseguibili in grado di essere eseguiti da un ID utente arbitrario su OpenShift, le autorizzazioni dovrebbero essere modificate correttamente.
Ad esempio, uno script da eseguire dovrebbe avere i privilegi di esecuzione per il proprietario e il gruppo (ricordate? facciamo parte del gruppo root), ma nessuno -o pochi- per gli altri utenti.
RUN chmod 775 /my/directory/my-script
Porte chiuse
Ogni numero di porta inferiore a 1024 non può essere utilizzato poiché può essere bindata solo dall’utente root. Questo significa che qualsiasi tentativo di utilizzare una porta che va da 0 a 1023, sarà inutile.
Risorse utili
- Docker - per cominciare bene