Bonnes pratiques & Securité

Sécurité

Docker propose un outil de détection de vulnérabilité (Common Vulnerabilities and Exposures -CVEs ) des images. C’est aussi simple que de lancer :

docker scout cves <nom_de_l_image>

Essayez par exemple en créant une image basée sur nginx:1.18.0 :

FROM nginx:1.18.0

RUN apt update
RUN apt install -y vim

puis en faisant un build :

docker build -t essai_scan .

puis le scan :

docker scout cves essai_scan

Suivez les recommendations pour améliorer la sécurité de votre image.

.dockerignore

Ca ne vous a peut être pas échappé, au moment de lancer un build docker affiche « Uploading build context » . Le client docker à ce moment envoie l’intégralité du répertoire courant au serveur docker. Si ce répertoire est volumineux, cela peut prendre du temps.

Une bonne pratique consiste à écrire un fichier .dockerignore contenant des expressions régulières de fichiers à exclure du contexte de build.

Essayez !

Bonnes pratiques diverses

Ces bonnes pratiques sont tirées de la documentation : https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

  • Each container should have only one responsibility.

  • Containers should be immutable, lightweight, and fast.

  • Don’t store data in your container. Use a shared data store instead.

  • Containers should be easy to destroy and rebuild.

  • Use a small base image (such as Linux Alpine). Smaller images are easier to distribute.

  • Avoid installing unnecessary packages. This keeps the image clean and safe.

  • Avoid cache hits when building.

  • Auto-scan your image before deploying to avoid pushing vulnerable containers to production.

  • Scan your images daily both during development and production for vulnerabilities Based on that, automate the rebuild of images if necessary.

  • apt-get : privilégiez l’installation de paquets sous la forme suivante :

RUN apt-get update && apt-get install -y \
package-bar \
package-baz \
package-foo  \
&& rm -rf /var/lib/apt/lists/*

Isolation des réseaux

Dans le docker compose suivant, on crée 3 services et 2 réseaux. Lancez ce docker compose et vérifiez la communication depuis chaque conteneur :

  • service1 peut-il communiquer (ping) avec service2 ? avec service3 ? avec yahoo.fr ?

  • Idem avec service2 et service3

services:
service1:
    image: alpine
    command: tail -f /dev/null
    networks:
    - internal_net
    - isolated_net

service2:
    image: alpine
    command: tail -f /dev/null
    networks:
    - internal_net

service3:
    image: alpine
    command: tail -f /dev/null
    networks:
    - isolated_net

networks:
internal_net:
    driver: bridge
isolated_net:
    driver: bridge
    internal: true

Exercice

Dans l’exemple suivant la personne qui fournit le Dockerfile a pour intention de créer une application qui qui exécute un serveur web Nginx et un serveur SSH pour qu’un utilisateur “user” puisse se connecter en SSH et modifier le contenu du serveur web. Cependant, ce qu’il propose ne respecte pas les bonnes pratiques énoncées ci-dessus.

Essayez de proposer des améliorations.

.
├── Dockerfile
└── index.html
FROM ubuntu:latest
MAINTAINER John Doe <ohn.doe@example.com>
RUN apt-get update
RUN apt-get install -y nginx vim git openssh-server
COPY index.html /var/www/html/index.html
RUN mkdir /run/sshd
RUN useradd -m -s /bin/bash user
RUN echo 'user:password' | chpasswd
EXPOSE 80
EXPOSE 22
ENTRYPOINT ["bash", "-c"]
CMD ["/sbin/sshd && nginx && tail -f /var/log/nginx/access.log"]
version: '3'
services:
  web:
    build: .
    ports:
      - "80:80"
      - "22:22"
    volumes:
      - ./index.html:/var/www/html/index.html