
Container Snitch esamina i processi in esecuzione sotto Docker Engine e segnala se vengono trovati in esecuzione come root.
cnitch (snitch o container snitch) è un semplice framework e strumento a riga di comando per monitorare i container Docker e identificare eventuali processi in esecuzione come root.
Perché è una cosa negativa? Se non sei ancora stato su can I haz non-privileged containers? di mhausenblas ti consiglio di andarci subito per avere tutte le informazioni.
Quando stavo sviluppando cnitch mi sono imbattuto in quello che pensavo fosse un bug dell'applicazione: cnitch segnalava sé stesso come processo root all'interno di un container Docker. Non capivo come fosse possibile, dato che il Dockerfile dichiarava esplicitamente che stavo creando un utente e non eseguendo come root. Dopo molto debug e verifica, ho deciso di ricontrollare il Dockerfile e ho trovato questo:
FROM alpine
RUN adduser -h /home/cnitch -D cnitch cnitch
COPY ./cmd/cnitch /home/cnitch/
RUN chmod +x /home/cnitch/cnitch
#USER cnitch
ENTRYPOINT ["/home/cnitch/cnitch"]
Quando stavo testando il container dell'applicazione per risolvere un problema di permessi sul socket Docker, devo aver commentato il comando USER. Piuttosto meta: cnitch ha aiutato a trovare un problema in cnitch. Questo andrà sicuramente nei test di integrazione.
cnitch si connette al motore Docker tramite API e interroga i container attualmente in esecuzione, quindi ispeziona i processi in esecuzione all'interno del container e identifica quelli che girano come utente root.
Quando viene trovato un processo root, queste informazioni vengono inviate ai moduli di reporting configurabili, permettendoti di eseguire audit o azioni su di esse.
2017/07/29 16:04:27 Starting Cnitch: Monitoring Docker Processes at: tcp://172.16.255.128:2376
2017/07/29 16:04:27 Checking for root processes every: 10s
2017/07/29 16:05:08 Checking image: ubuntu, id: 7bd489560a310343c39186500daa680290289c27f7a730524a31355a3aaf0430
2017/07/29 16:05:08 >> WARNING: found process running as root: tail -f /dev/null pid: 365
Attualmente cnitch è in grado di inviare report a StatsD e StdOut. I backend di reporting sono estensibili per supportare facilmente qualsiasi backend; ad esempio, sarebbe un processo abbastanza banale creare un backend per supportare Logstash o un altro strumento di aggregazione di file di log.
Le eccezioni vengono inviate all'endpoint StatsD come conteggio utilizzando la metrica cnitch.exception.root_process. Le metriche sono anche taggate con il nome host dell'istanza cnitch e con il nome del container.
Il logger StdOut è un semplice logger di output che invia le eccezioni rilevate a StdOut.
Sia che tu esegua cnitch in un container Docker o come binario, necessita di accesso all'API Docker impostando l'URL del server o il percorso del socket tramite la variabile d'ambiente DOCKER_HOST
--hostname=[hostname] il nome o l'indirizzo IP da utilizzare per l'aggregazione delle metriche--statsd-server=[hostname:port] l'URI del collector statsd; se omesso, il reporting statsd sarà disabilitato--check=[durata es. 10s (10 secondi), 1m (1 minuto)], la frequenza con cui snitch scansionerà i processi rootImposta la variabile d'ambiente DOCKER_HOST con l'API del tuo motore Docker, quindi esegui snitch con i flag necessari.
$ cnitch --hostname=myhost --statsd-server=127.0.0.1:8125 --check=10s
cnitch viene eseguito in un container non privilegiato e, se desideri utilizzare il socket Docker per accedere all'API, devi aggiungere l'utente cnitch al gruppo docker. Questo può essere ottenuto tramite il flag --group-add, impostandolo con il gid del gruppo utente docker.
Ad esempio:
--group-add=$(stat -f "%g" /var/run/docker.sock
Esempio di utilizzo del file socket Docker per l'accesso API
$ docker run -i -t --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
--group-add=$(stat -f "%g" /var/run/docker.sock) \
-e "DOCKER_HOST:unix:///var/run/docker.sock" \
quay.io/nicholasjackson/cnitch [options]
Se stai utilizzando un Mac e Docker Machine, il socket Docker si trova all'interno della VM, quindi non puoi usare il comando stat per scoprire il gid.
C'è uno stack di esempio con Docker Compose nella cartella ./example che mostra come cnitch esporta i dati verso statsd. Per eseguire questo esempio:
$ cd ./example
$ docker-compose up
Una volta avviato tutto, apri http://[indirizzo IP host Docker]:3000 nel tuo browser web e dovresti vedere la schermata di login di Grafana.

Accedi a Grafana con le seguenti credenziali:
Quindi seleziona la dashboard cnitch. Questa dashboard mostra i processi root attualmente in esecuzione.

Se non stai utilizzando /var/run/docker.sock per comunicare con il tuo host Docker, dovrai modificare alcune impostazioni nel file ./example/docker-compose.yml per adattarle alla tua configurazione.
Implementare le funzionalità da Docker Bench Security Script https://github.com/docker/docker-bench-security
[ ] 1.1 Assicurarsi che sia stata creata una partizione separata per i container
[ ] 1.2 Assicurarsi che l'host del container sia stato indurito
[ ] 1.3 Assicurarsi che Docker sia aggiornato
[ ] 1.4 Assicurarsi che solo utenti fidati siano autorizzati a controllare il demone Docker
[ ] 1.5 Assicurarsi che il logging di audit sia configurato per il demone Docker
[ ] 1.6 Assicurarsi che il logging di audit sia configurato per i file e le directory Docker - /var/lib/docker
[ ] 1.7 Assicurarsi che il logging di audit sia configurato per i file e le directory Docker - /etc/docker
[ ] 1.8 Assicurarsi che il logging di audit sia configurato per i file e le directory Docker - docker.service
[ ] 1.9 Assicurarsi che il logging di audit sia configurato per i file e le directory Docker - docker.socket
[ ] 1.10 Assicurarsi che il logging di audit sia configurato per i file e le directory Docker - /etc/default/docker
[ ] 1.11 Assicurarsi che il logging di audit sia configurato per i file e le directory Docker - /etc/docker/daemon.json
[ ] 1.12 Assicurarsi che il logging di audit sia configurato per i file e le directory Docker - /usr/bin/docker-containerd
[ ] 1.13 Assicurarsi che il logging di audit sia configurato per i file e le directory Docker - /usr/bin/docker-runc
[ ] 2.1 Assicurarsi che il traffico di rete sia limitato tra i container sul bridge predefinito
[ ] 2.2 Assicurarsi che il livello di logging sia impostato su 'info'
[ ] 2.3 Assicurarsi che Docker possa apportare modifiche a iptables
[ ] 2.4 Assicurarsi che non vengano utilizzati registri insicuri
[ ] 2.5 Assicurarsi che il driver di storage aufs non sia utilizzato
[ ] 2.6 Assicurarsi che l'autenticazione TLS per il demone Docker sia configurata
[ ] 2.7 Assicurarsi che l'ulimit predefinito sia configurato appropriatamente
[ ] 2.8 Abilitare il supporto dei namespace utente
[ ] 2.9 Assicurarsi che l'utilizzo predefinito del cgroup sia stato confermato
[ ] 2.10 Assicurarsi che la dimensione del dispositivo di base non venga modificata finché non è necessario
[ ] 2.11 Assicurarsi che l'autorizzazione per i comandi client Docker sia abilitata
[ ] 2.12 Assicurarsi che il logging centralizzato e remoto sia configurato
[ ] 2.13 Assicurarsi che le operazioni sul registro legacy (v1) siano disabilitate
[ ] 2.14 Assicurarsi che il ripristino live sia abilitato
[ ] 2.15 Assicurarsi che il proxy Userland sia disabilitato
[ ] 2.16 Assicurarsi che il profilo seccomp personalizzato a livello di demone sia applicato, se necessario
[ ] 2.17 Assicurarsi che le funzionalità sperimentali siano evitate in produzione
[ ] 2.18 Assicurarsi che ai container sia impedito di acquisire nuovi privilegi
[ ] 3.x ...
[x] 4.1 Assicurarsi che sia stato creato un utente per il container
[ ] 4.2 Assicurarsi che i container utilizzino immagini di base attendibili
[ ] 4.3 Assicurarsi che i pacchetti non necessari non siano installati nel container
[ ] 4.4 Assicurarsi che le immagini siano scansionate e ricostruite per includere le patch di sicurezza
[ ] 4.5 Assicurarsi che Content trust per Docker sia abilitato
[ ] 4.6 Assicurarsi che le istruzioni HEALTHCHECK siano state aggiunte all'immagine del container
[ ] 4.7 Assicurarsi che le istruzioni di aggiornamento non siano usate da sole nel Dockerfile
[ ] 4.8 Assicurarsi che i permessi setuid e setgid siano rimossi nelle immagini
[ ] 4.9 Assicurarsi che COPY sia usato invece di ADD nel Dockerfile
[ ] 4.10 Assicurarsi che i segreti non siano memorizzati nei Dockerfile
[ ] 4.11 Assicurarsi che siano installati solo pacchetti verificati
[ ] 5.x ...
[ ] 6.x ...
[ ] 7.x ...