Protezione dei container con AppArmor

AppArmor è un servizio di sicurezza del kernel Linux che puoi utilizzare per limitare le capacità dei processi in esecuzione del tuo sistema operativo host. Ogni processo può avere il proprio profilo di sicurezza. La il profilo di sicurezza consente o meno funzionalità specifiche, come l'accesso alla rete o autorizzazioni di lettura, scrittura ed esecuzione dei file.

Puoi utilizzare AppArmor con i container Docker in esecuzione Istanze di Container-Optimized OS. Per ogni contenitore, puoi applicare il profilo di sicurezza predefinito di AppArmor fornito con Docker oppure una configurazione profilo che fornisci.

Utilizzo del profilo di sicurezza AppArmor di Docker predefinito

Quando avvii un container sull'istanza di Container-Optimized OS, il sistema applica automaticamente il profilo di sicurezza AppArmor di docker-default. Le seguenti Il comando di esempio esegue un container con il profilo di sicurezza docker-default:

docker run --rm -it debian:jessie bash -i

Per testare il profilo di sicurezza docker-default, puoi provare a leggere /proc/sysrq-trigger con il comando cat, come segue:

root@88cef496c1a5:/# cat /proc/sysrq-trigger

L'output deve contenere un'"Autorizzazione negata" simile al seguente:

cat: /proc/sysrq-trigger: Permission denied

Applicazione di un profilo di sicurezza personalizzato

Per applicare un profilo di sicurezza diverso, usa apparmor=<profile-name> a riga di comando quando esegui il container. Il seguente comando di esempio esegue un container con un profilo di sicurezza denominato no-ping:

docker run --rm -i --security-opt apparmor=no-ping debian:jessie bash -i

Consulta la sezione Creare un profilo di sicurezza personalizzato più avanti in questo argomento per ulteriori informazioni sulla creazione del profilo no-ping specificato nell'esempio.

Puoi anche specificare unconfined con l'opzione apparmor per indicare che il container deve essere eseguito senza nessun profilo di sicurezza, come nell'esempio seguente esempio:

docker run --rm -it --security-opt apparmor=unconfined debian:jessie bash -i

Visualizzazione dei profili di sicurezza AppArmor attivi

Puoi vedere quale profilo AppArmor, se presente, si applica ai processi sul tuo Istanza Container-Optimized OS ispezionando /proc/<pid>/attr/current dove <pid> è l'ID di processo.

Supponiamo che nella tua istanza siano in esecuzione i seguenti processi (mostrati dal comando ps -ef | grep '[b]ash -i'):

root      1903  1897  0 21:58 pts/3    00:00:00 docker run --rm -it debian:jessie bash -i
root      1927  1913  0 21:58 pts/4    00:00:00 bash -i
root      1978  1001  0 22:01 pts/0    00:00:00 docker run --rm -it --security-opt apparmor=unconfined debian:jessie bash -i
root      2001  1988  0 22:01 pts/2    00:00:00 bash -i

Se controlli /proc/1927/attr/current, dovresti vedere il seguente output che indica che il processo (pid 1927) è stato eseguito con la sicurezza Docker predefinita profilo:

# cat /proc/1927/attr/current
docker-default (enforce)

Se esamini /proc/2001/attr/current, dovresti vedere il seguente output che indica che il processo (pid 2001) è stato eseguito con nessun profilo di sicurezza (ovvero con l'opzione apparmor=unconfined):

# cat /proc/2001/attr/current
unconfined

Creazione di un profilo di sicurezza personalizzato

Se il processo richiede un profilo di sicurezza diverso da docker-default, puoi scrivere il tuo profilo personalizzato. Per utilizzare un profilo personalizzato, devi creare il file del profilo e caricarlo in AppArmor.

Ad esempio, supponiamo che tu voglia un profilo di sicurezza che non consenta le reti non elaborate per via del traffico. Il seguente script crea un file per un profilo di sicurezza chiamato no-ping in /etc/apparmor.d/no_raw_net:

cat > /etc/apparmor.d/no_raw_net <<EOF
#include <tunables/global>

profile no-ping flags=(attach_disconnected,mediate_deleted) {
  #include <abstractions/base>

  network inet tcp,
  network inet udp,
  network inet icmp,

  deny network raw,
  deny network packet,
  file,
  mount,
}
EOF

Dopo aver creato il file del profilo di sicurezza, puoi utilizzare apparmor_parser per caricare il profilo in AppArmor:

/sbin/apparmor_parser --replace --write-cache /etc/apparmor.d/no_raw_net

Una volta caricato, puoi testare il profilo no-ping nel seguente modo:

$ docker run --rm -i --security-opt apparmor=no-ping debian:jessie ping -c3 8.8.8.8

Il comando crea un contenitore con il profilo di sicurezza no-ping e tenta di eseguire ping all'interno del contenitore. Il profilo di sicurezza non deve consentire del traffico, generando un errore come il seguente:

ping: Lacking privilege for raw socket.

Per assicurarti che il tuo profilo di sicurezza personalizzato sia presente quando L'istanza Container-Optimized OS si avvia e rimane permanente tra i riavvii, puoi utilizzare cloud-init per installare il profilo in /etc/apparmor.d. Per farlo, aggiungi uno script cloud-config ai metadati dell'istanza come valore dello script Chiave user-data.

Il seguente script cloud-config aggiunge il profilo no-ping a /etc/apparmor.d:

#cloud-configs

write_files:
- path: /etc/apparmor.d/no_raw_net
  permissions: 0644
  owner: root
  content: |
    #include <tunables/global>

    profile no-ping flags=(attach_disconnected,mediate_deleted) {
      #include <abstractions/base>

      network inet tcp,
      network inet udp,
      network inet icmp,

      deny network raw,
      deny network packet,
      file,
      mount,
    }

Per assicurarti che il file di servizio carichi il tuo profilo personalizzato in AppArmor e dice a Docker di utilizzarlo, esegui questi comandi sull'istanza:

ExecStartPre=/sbin/apparmor_parser -r -W /etc/apparmor.d/no_raw_net
ExecStart=/usr/bin/docker run --security-opt apparmor=no-ping ...

Dopo aver eseguito i comandi, riavvia l'istanza in modo da poter eseguire container limitato dal tuo profilo AppArmor personalizzato.