17 min read

Docker, GVM CE et Traefik : la combinaison gagnante pour une sécurité accrue de vos outils de détection de vulnérabilités

La cybersécurité est plus cruciale que jamais et les outils de sécurité open-source sont de plus en plus populaires pour protéger les entreprises contre les menaces en ligne.

#docker

#GVM CE

#traefik

Article publié le 16 janv. 2022

·

17 min de lecture

La cybersécurité est plus cruciale que jamais et les outils de sécurité open-source sont de plus en plus populaires pour protéger les entreprises contre les menaces en ligne. L’outil Greenbone Vulnerability Manager Community Edition (anciennement OpenVAS) est un système de détection de vulnérabilités open source qui peut aider les entreprises à identifier les faiblesses de sécurité dans leurs systèmes.

En étant open source, GVM est soumis à une inspection et à une vérification constantes par une communauté de Dev et d’Ops, ce qui permet de détecter les failles de sécurité plus rapidement et aussi d’avoir une base de donnée des dernières CVE (Common Vulnerabilty Exposure) et NVT (Network Vulnerability Test) à jour.

Dans cet article, nous allons vous montrer comment déployer GVM 22.4 de manière simple, sécurisé, sur un serveur public cloud OVH et le rendre accessible via une URL sécurisée avec SSL/TLS grâce à Traefik.

1. Le serveur et l’entrée DNS

1.1. Choix et configuration du serveur

Dans ce tutoriel, nous utiliserons une machine avec 2 vCore, 4 Go de RAM, 50 Go de SSD ainsi que la distribution Debian 11. Cela est correct pour lancer un scan d’une seule machine cible. Pour avoir un scan plus rapide et avoir la possibilité defaire plus de scans en parallèles, il faudra redimensionner le serveur. Pour cela, OVH fourni également une documentation.

Une fois la machine créer, on peut donc se connecter :

https://media.kanops.io/blog/img/docker_gvm_traefik/docker_gvm_traefik_display_debian_version.png

Nous pouvons par la suite installer les paquets Docker, Python 3 ainsi que la librairie python docker-compose pour déployer nos applications. Pour cela, nous devons installer ces paquets :

  • Docker :

    sudo apt update && sudo apt install -y docker.io
    

    💡 Tips pour être en sécurité avec Docker :

    • Utiliser toujours la dernière version à jour
    • Ne déployer sur la machine uniquement les conteneurs de GVM 22.4
    • Utilisez des volumes sécurisés pour stocker les données sensibles
  • Python 3:

    sudo apt install -y python3 python3-pip
    
  • La librairie docker-compose:

    python3 -m pip install --user docker-compose
    

Une fois les installations terminées, nous devons donner les droits à l’utilisateur actuel (ici ‘debian’) de pouvoir lancer la commande docker et ainsi pouvoir démarrer/stopper les conteneurs :

sudo usermod -aG docker $USER

⭐️ Il faudra se reconnecter à la machine ou relancer un shell pour pouvoir utiliser les commandes docker et docker-compose par la suite

💡 Cette partie de l’installation peut être automatisée avec des outils IaC, comme: Ansible, Chef ou Puppet. Ici un équivalent pour Ansible :

---
- name: Install GVM 22.4 dependencies
  hosts: all
  vars:
    instance_user: debian

  tasks:
    - name: Install openstack packages
      become: yes
      apt:
        name: "{{ gvm_packages }}"
        force_apt_get: yes
        state: present
        update_cache: yes
        vars:
          gvm_packages:
            - docker.io
            - python3
            - python3-pip
            - vim

    - name: Install docker-compose pip package
      pip:
        name: docker-compose
        executable: pip3

    - name: Add instance user to docker group
      become: true
      user:
        name: "{{ instance_user }}"
        groups: docker
        append: yes

Nous pouvons lancer le playbook et laisser les paquets s’installés sur la machine distante grâce à Ansible (nécessite Ansible 2.9) :

ansible-playbok -u <instance_user> --private-key /path/to/id_rsa -i "<ip_instance>,"<fichier_ansible>.yml

Nous vérifions donc que les paquets sont bien installés et que les versions sont à jour :

https://media.kanops.io/blog/img/docker_gvm_traefik/docker_gvm_traefik_display_libraries_versions.png

1.2. Configuration de l’entrée DNS

Il sera nécessaire de créer une entrée DNS de type A pour pouvoir générer le certificat par la suite. Pour cela, chez OVH il faudra se rendre dans l’onglet ‘Web Cloud’, puis dans l’onglet de gauche, choisir le domaine principale pour lequel le sous-domaine sera créer.

⭐️ Ici la documentation officielle d’OVH sur les domaines.

💡 Pour récupérer l’IP publique de la machine directement avec un shell sur le serveur, on peut utiliser la commande :

hostname -I

La configuration doit être similaire à la capture ci-dessous :

https://media.kanops.io/blog/img/docker_gvm_traefik/docker_gvm_traefik_display_add_dns.png

Une fois l’entrée configurée, dans l’interface de la zone DNS nous devons avoir une entrée qui devrait ressembler à ceci:

https://media.kanops.io/blog/img/docker_gvm_traefik/docker_gvm_traefik_display_dns_ok.png

2. Installation de GVM 22.4

Il existe plusieurs manières d’installer GVM 22.4 depuis les sources en standalone ou avec Docker. Ici, nous utiliserons docker-compose pour déployer tous les outils nécessaires. Nous utiliserons celui mis à disposition sur le site de Greenbone pour déployer notre stack :

services:
  vulnerability-tests:
    image: greenbone/vulnerability-tests
    environment:
      STORAGE_PATH: /var/lib/openvas/22.04/vt-data/nasl
    volumes:
      - vt_data_vol:/mnt

  notus-data:
    image: greenbone/notus-data
    volumes:
      - notus_data_vol:/mnt

  scap-data:
    image: greenbone/scap-data
    volumes:
      - scap_data_vol:/mnt

  cert-bund-data:
    image: greenbone/cert-bund-data
    volumes:
      - cert_data_vol:/mnt

  dfn-cert-data:
    image: greenbone/dfn-cert-data
    volumes:
      - cert_data_vol:/mnt
    depends_on:
      - cert-bund-data

  data-objects:
    image: greenbone/data-objects
    volumes:
      - data_objects_vol:/mnt

  report-formats:
    image: greenbone/report-formats
    volumes:
      - data_objects_vol:/mnt
    depends_on:
      - data-objects

  gpg-data:
    image: greenbone/gpg-data
    volumes:
      - gpg_data_vol:/mnt

  redis-server:
    image: greenbone/redis-server
    restart: on-failure
    volumes:
      - redis_socket_vol:/run/redis/

  pg-gvm:
    image: greenbone/pg-gvm:stable
    restart: on-failure
    volumes:
      - psql_data_vol:/var/lib/postgresql
      - psql_socket_vol:/var/run/postgresql

  gvmd:
    image: greenbone/gvmd:stable
    restart: on-failure
    volumes:
      - gvmd_data_vol:/var/lib/gvm
      - scap_data_vol:/var/lib/gvm/scap-data/
      - cert_data_vol:/var/lib/gvm/cert-data
      - data_objects_vol:/var/lib/gvm/data-objects/gvmd
      - vt_data_vol:/var/lib/openvas/plugins
      - psql_data_vol:/var/lib/postgresql
      - gvmd_socket_vol:/run/gvmd
      - ospd_openvas_socket_vol:/run/ospd
      - psql_socket_vol:/var/run/postgresql
    depends_on:
      pg-gvm:
        condition: service_started
      scap-data:
        condition: service_completed_successfully
      cert-bund-data:
        condition: service_completed_successfully
      dfn-cert-data:
        condition: service_completed_successfully
      data-objects:
        condition: service_completed_successfully
      report-formats:
        condition: service_completed_successfully

  gsa:
    image: greenbone/gsa:stable
    restart: on-failure
    ports:
      - 9392:80
    volumes:
      - gvmd_socket_vol:/run/gvmd
    depends_on:
      - gvmd
    labels:
      - traefik.enable=true
      - traefik.http.routers.greenbone-http.entryPoints=http
      - traefik.http.routers.greenbone-http.rule=Host(`scanner.kanops.io`)
      - traefik.http.routers.greenbone-http.service=greenbone-kanops@docker
      - traefik.http.routers.greenbone-https.tls.certresolver=letsencrypt
      - traefik.http.routers.greenbone-https.tls=true
      - traefik.http.routers.greenbone-https.entryPoints=https
      - traefik.http.routers.greenbone-https.rule=Host(`scanner.kanops.io`)
      - traefik.http.routers.greenbone-https.service=greenbone-kanops@docker
      - traefik.http.services.greenbone-kanops.loadbalancer.server.port=80

  ospd-openvas:
    image: greenbone/ospd-openvas:stable
    restart: on-failure
    init: true
    hostname: ospd-openvas.local
    cap_add:
      - NET_ADMIN # for capturing packages in promiscuous mode
      - NET_RAW # for raw sockets e.g. used for the boreas alive detection
    security_opt:
      - seccomp=unconfined
      - apparmor=unconfined
    command:
      [
        "ospd-openvas",
        "-f",
        "--config",
        "/etc/gvm/ospd-openvas.conf",
        "--mqtt-broker-address",
        "mqtt-broker",
        "--notus-feed-dir",
        "/var/lib/notus/advisories",
        "-m",
        "666",
      ]
    volumes:
      - gpg_data_vol:/etc/openvas/gnupg
      - vt_data_vol:/var/lib/openvas/plugins
      - notus_data_vol:/var/lib/notus
      - ospd_openvas_socket_vol:/run/ospd
      - redis_socket_vol:/run/redis/
    depends_on:
      redis-server:
        condition: service_started
      gpg-data:
        condition: service_completed_successfully
      vulnerability-tests:
        condition: service_completed_successfully

  mqtt-broker:
    restart: on-failure
    image: greenbone/mqtt-broker
    ports:
      - 1883:1883
    networks:
      default:
        aliases:
          - mqtt-broker
          - broker

  notus-scanner:
    restart: on-failure
    image: greenbone/notus-scanner:stable
    volumes:
      - notus_data_vol:/var/lib/notus
      - gpg_data_vol:/etc/openvas/gnupg
    environment:
      NOTUS_SCANNER_MQTT_BROKER_ADDRESS: mqtt-broker
      NOTUS_SCANNER_PRODUCTS_DIRECTORY: /var/lib/notus/products
    depends_on:
      - mqtt-broker
      - gpg-data
      - vulnerability-tests

  gvm-tools:
    image: greenbone/gvm-tools
    volumes:
      - gvmd_socket_vol:/run/gvmd
      - ospd_openvas_socket_vol:/run/ospd
    depends_on:
      - gvmd
      - ospd-openvas

volumes:
  gpg_data_vol:
  scap_data_vol:
  cert_data_vol:
  data_objects_vol:
  gvmd_data_vol:
  psql_data_vol:
  vt_data_vol:
  notus_data_vol:
  psql_socket_vol:
  gvmd_socket_vol:
  ospd_openvas_socket_vol:
  redis_socket_vol:

Ce docker-compose va créer des volumes et exécuter certains nombres de services, certains services vont s’exécuter uniquement pour copier dans les volumes les binaires nécessaires. Une fois les exécutions terminées, les conteneurs contenant les outils (voir l’architecture sur le site de Greenbone) seront déployés.

  • Pour lancer les services, nous allons d’abord créer un répertoire et y stocker le code ci-dessus dans un fichier docker-compose.yml ci-dessus avec l’éditeur de texte de votre choix (ici vim) :
mkdir -p $HOME/greenbone-community-edition
cd $HOME/greenbone-community-edition && vim docker-compose.yml
  • Ensuite, pour créer les volumes et lancer les services, on devra exécuter cette commande :
docker-compose -f docker-compose.yml -p greenbone-community-edition up -d

Une fois les services lancés, nous pouvons donc accéder à l’interface de Greenbone Security Assistant (GSA) avec l’adresse IP de la machine sur le port 9392 :

https://media.kanops.io/blog/img/docker_gvm_traefik/docker_gvm_traefik_display_gvm_screen.png

⚠️ Vérifier uniquement que le service est accessible, car :

  • Les accès par défaut sont admin/admin
  • Le SSL n’est pas en place, les communications ne sont donc pas chiffrées

Une fois les conteneurs lancés, pour modifier le mot de passe du compte ‘admin’, il faudra exécuter cette commande :

docker-compose -f docker-compose.yml -p greenbone-community-edition exec -u gvmd gvmd gvmd --user=admin --new-password=<password>

⭐️ Nous conseillons de générer un mot de passe qui n’a jamais était utilisée, d’au moins 8 caractères et n’ayant jamais était leak. Ici quelques sites utiles :

⭐️ Nous pouvons stopper tous les services avec cette commande :

docker-compose -f docker-compose.yml down

3. Mise en place de Traefik et du SSL

Traefik est un serveur reverse proxy et un load balancer open-source. Il permet de facilement gérer les redirections de trafic HTTP et HTTPS vers nos applications en utilisant les labels directement lié aux conteneurs ou avec des fichiers de configuration.

Une fois GVM 22.4 installé et configuré, nous devons installer et configurer Traefik pour gérer les connexions entrantes et rediriger les requêtes HTTP/HTTPS vers le conteneur GSA (Greenbone Security Assistant).

⭐️ Nous pourrions également utiliser Nginx comme serveur reverse proxy, mais ici le choix de Traefik repose principalement sur le fait qu’il communique avec le socket Docker nativement. Et donc les configurations de redirections et SSL seront dynamiques grâce aux labels des conteneurs Docker.

3.1. Mise en place de Traefik

Pour implémenter Traefik ici, il faudra modifier le fichier docker-compose.yml. Traefik sera ajouté en tant que service, nous prenons la dernière version stable de l’image disponible actuellement et nous exposons respectivement les ports :

  • 80 pour le HTTP
  • 443 pour le HTTPS
  • 8080 pour le dashboard de Traefik, très utile pour debugger. ⚠️ Dans un environnement de production, il n’est pas conseillé de laisser le dashboard accessible. Dans ce tutoriel, nous le laisserons volontairement accessible, mais protéger par un htaccess. ⚠️

Pour les volumes :

  • /var/run/docker.sock : Traefik aura besoin d’accéder au socket du processus Docker pour pouvoir récupérer les informations des autres conteneurs, notamment les labels. Ce qui lui permet de prendre en considération chaque fois qu’un conteneur est ajouté.
  • /etc/traefik/traefik.toml : Le fichier de configuration statique. Ici, nous configurerons les entrypoints, les providers (on déclare qui va fournir des données à Traefik, ici les fichiers et Docker), le chemin vers un fichier de configuration dynamique ainsi que les informations concernant la génération de certificat avec Let’s Encrypt.
  • /configuration : Dossier où plusieurs fichiers de configurations (extension .toml) peuvent être ajoutés en complément du fichier de configuration dynamique. Les fichiers ajoutés dans ce répertoire seront automatiquement pris en compte par le conteneur Traefik sans avoir à redémarrer celui-ci.
  • /etc/traefik/ssl: Dossier contenant le/les certificats SSL.
traefik:
  image: traefik:2.9
  ports:
    - 80:80
    - 443:443
    - 8080:8080
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - $HOME/greenbone-community-edition/traefik/traefik.toml:/etc/traefik/traefik.toml
    - $HOME/greenbone-community-edition/traefik/configuration:/configuration
    - $HOME/greenbone-community-edition/traefik/ssl:/etc/traefik/ssl

💡 La variable $HOME devra être modifié par sa valeur dans le fichier docker-compose.yml.

Le bloc sera ajouter dans le fichier docker-compose.yml. Ici, il sera ajouté juste au-dessous du service gsa. Les labels de configuration pour Traefik, spécifique au service gsa seront ajoutés également pour que Trafik puisse créer les configurations de redirections :

gsa:
  image: greenbone/gsa:stable
  restart: on-failure
  expose:
    - 80
  volumes:
    - gvmd_socket_vol:/run/gvmd
  depends_on:
    - gvmd
  labels:
    - traefik.enable=true
    - traefik.http.routers.gsa-http.entryPoints=http
    - traefik.http.routers.gsa-http.rule=Host(`scanner-tuto.kanops.io`)
    - traefik.http.routers.gsa-http.middlewares=redirect-https@file
    - traefik.http.routers.gsa-https.tls.certresolver=letsencrypt
    - traefik.http.routers.gsa-https.tls=true
    - traefik.http.routers.gsa-https.entryPoints=https
    - traefik.http.routers.gsa-https.rule=Host(`scanner-tuto.kanops.io`)
    - traefik.http.routers.gsa-https.service=gsa-kanops@docker
    - traefik.http.services.gsa-kanops.loadbalancer.server.port=80

traefik:
  image: traefik:2.9
  ports:
    - 80:80
    - 443:443
    - 8080:8080
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - $HOME/greenbone-community-edition/traefik/traefik.toml:/etc/traefik/traefik.toml
    - $HOME/greenbone-community-edition/traefik/configuration:/configuration
    - $HOME/debian/greenbone-community-edition/traefik/ssl:/etc/traefik/ssl

Il faudra également créer les répertoires nécessaires pour Traefik:

mkdir -p $HOME/greenbone-community-edition/traefik/configuration
mkdir -p $HOME/greenbone-community-edition/traefik/ssl
touch $HOME/greenbone-community-edition/traefik/traefik.toml
touch $HOME/greenbone-community-edition/traefik/configuration/dynamic.toml

3.2. Le fichier de configuration statique

Une fois le service traefik ajouté et les labels pour le service gsa dans le fichier docker-compose.yml, on passe donc aux fichiers de configuration. Dans un premier temps, nous allons créer le fichier de configuration statique, nommée traefik.toml. On définira dans celui-ci les entrypoints nécessaires (HTTP, HTTPS et le dashboard), les configurations nécessaires pour la génération d’un certificat Let’s Encrypt, la configuration des logs ainsi que l’activation des providers qui fourniront des nouvelles configurations dynamiquement à Traefik.

Ci-dessous le fichier de configuration complet à copier dans le fichier traefik.toml:

[entryPoints]
  [entryPoints.http]
  address = ":80"

  [entryPoints.https]
  address = ":443"

  [entryPoints.traefik]
  address = ":8080"

[certificatesResolvers.letsencrypt.acme]
  email = "your@email.com"
  storage = "/etc/traefik/ssl/acme.json"
  caserver = "https://acme-v02.api.letsencrypt.org/directory"
  [certificatesResolvers.letsencrypt.acme.tlsChallenge]

[log]
  filePath = "/var/log/traefik/traefik.log"
  level = "ERROR"

[accessLog]
  filePath = "/var/log/traefik/access.log"
  format = "json"
  [accessLog.fields]
    defaultMode = "keep"
    [accessLog.fields.headers]
      defaultMode = "keep"

[providers]
  [providers.docker]
    watch = true
    exposedbydefault = false
  [providers.file]
    watch = true
    directory = "/configuration"

[api]
dashboard = true

Ce fichier de configuration nous permettra de mettre en place:

  • La configuration nos entrypoints:

    Ici la documentation de Traefik sur les entrypoints.

    [entryPoints]
      [entryPoints.http]
      address = ":80"
    
      [entryPoints.https]
      address = ":443"
    
      [entryPoints.traefik]
      address = ":8080"
    
    • [entryPoints.http] : Permet de rendre disponible le serveur web sur le port 80 (HTTP) pour toutes les interfaces.
    • [entryPoints.https] : Permet de rendre disponible le serveur web sur le port 443 (HTTPS) pour toutes les interfaces.
    • [entryPoints.traefik] : Permet de rendre disponible le dashboard Traefik sur le port 8080.
  • La configuration de la communication avec les serveurs de Let’s Encrypt

    [certificatesResolvers.letsencrypt.acme]
      email = "your@email.com"
      storage = "/etc/traefik/ssl/acme.json"
      caserver = "https://acme-v02.api.letsencrypt.org/directory"
      [certificatesResolvers.letsencrypt.acme.tlsChallenge]
    
    • email: renseigner votre adresse email
    • storage: là où le contenu du certificat sera stocké. Ici, comme le serveur Traefik se trouve dans un conteneur ce chemin est en réalité un chemin dans le conteneur.
    • caserver: l’url de l’API de Let’s Encrypt où il va faire la demande de génération de certificat.
    • [certificatesResolvers.letsencrypt.acme.tlsChallenge]: permet de définir quel challenge à utiliser pour créer ou renouveler le certificat selon la norme ACME.
  • La configuration des logs :

    💡 Ici; on va configurer les logs du Traefik ainsi que les logs d’accès du serveur web. Les logs d’accès nous donnent différentes informations très utiles sur les requêtes http entrantes, grâce à ces logs, nous pourrons par exemple récupérer l’adresse IP et ainsi mettre en place un système de filtrage d’IP grâce à un outil comme fail2ban.

    Ici, les logs de Traefik :

    [log]
      filePath = "/var/log/traefik/traefik.log"
      level = "ERROR"
    
    • filePath : Le chemin vers le fichier de log.
    • level : Les différents niveaux de logs à afficher. Les niveaux sont: DEBUG, PANIC, FATAL, ERROR, WARN et INFO.

    Ici, les logs d’accès :

    [accessLog]
      filePath = "/path/to/access.log"
      format = "json"
      [accessLog.fields]
        defaultMode = "keep"
        [accessLog.fields.headers]
          defaultMode = "keep"
    
    • filePath : Le chemin vers le fichier de log.
    • format : Le format de sortie des logs, si on ne précise pas le format par défaut décrit ici, sera utilisé.
    • [accessLog.fields] : Permet de garder certaines informations dans nos logs, notamment les headers HTTP qui peut permettre de voir si des bots se connectent ou cherchent à se connecter.
  • La configuration des providers :

    Un provider va permettre à Traefik d’aller récupérer des informations de configurations dans des fichiers supplémentaires et dans le socket Docker.

    [providers]
      [providers.docker]
        watch = true
        exposedbydefault = false
      [providers.file]
        watch = true
        directory = "/configuration"
    
    • [providers.docker]: Permet d’aller récupérer des informations dans le socket de Docker.
    • [providers.file]: Permet d’aller récupérer des informations dans des fichiers au format .toml dans le dossier /configuration.
  • L’activation du dashboard Traefik :

    [api]
        dashboard = true
    

3.3. Le fichier de configuration dynamique

Ici le fichier de configuration est dit dynamique, car dès qu’on modifiera le fichier $HOME/debian/greenbone-community-edition/traefik/configuration/dynamic.toml, Traefik le prendra dynamiquement en considération sans avoir à redémarrer le conteneur Traefik. Dans ce fichier, nous allons configurer :

  • Un router pour le dashboard de Traefik, se router utilisera des middlewares, ainsi que la configuration sur la négociation d’algorithme de chiffrement TLS.
  • Des middlewares qui seront utilisés par nos routers, ainsi que quelques configurations sur la négociation d’algorithme de chiffrement TLS.
    Ci-desssous le contenu de notre fichier :
[http.routers.traefik]
  entryPoints = ["traefik"]
  rule = "PathPrefix(`/dashboard`) || PathPrefix(`/api`)"
  service = "api@internal"
  middlewares = ["auth"]

[http.middlewares.auth.basicAuth]
  users = [
    "kanops-tuto:$2y$10$335FTc4tVmwll4a4zsxKXOhlYTpXjW8AoC9FcG9avZeWgEE8hMPqm"
  ]

[http.middlewares.redirect-https.redirectscheme]
  scheme = "https"

[tls]
  [tls.options]
    [tls.options.default]
      minVersion = "VersionTLS12"
      sniStrict = true
      cipherSuites = [
        "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
        "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
      ]
      curvePreferences = ["CurveP521","CurveP384"]

Ce fichier de configuration va nous permettre de mettre en place :

  • La configuration du router du dashboard : Le router est le point central de liaison entre les entrypoints, les middlewares et les services. On va protéger notre router par un htaccess [http.middlewares.auth.basicAuth]. Le mot de passe doit être hashé au préalable dans un de ses formats : MD5, SHA1 ou BCrypt.

    [http.routers.traefik]
      entryPoints = ["traefik"]
      rule = "PathPrefix(`/dashboard`) || PathPrefix(`/api`)"
      service = "api@internal"
      middlewares = ["auth"]
    
    [http.middlewares.auth.basicAuth]
      users = [
        "kanops-tuto:$2y$10$335FTc4tVmwll4a4zsxKXOhlYTpXjW8AoC9FcG9avZeWgEE8hMPqm"
      ]
    
    • [http.routers.traefik] : Le router sera nommé traefik.
    • entryPoints : Définit par quel entrypoint présent dans le fichier de configuration statique ce router pourra être accessible.
    • rule : Ici, permet de définir PathPrefix qui va nous permettre d’accéder au dashboard grâce à l’url avec /dashboard/# ou avec /api/#.
    • service : Définit vers quel service doit être redirigé le client lorsqu’il arrive par l’entrypoint "traefik".
    • [http.middlewares.auth.basicAuth] : Ici, on crée un middlware nommée auth qui sera appliqué avant que les requêtes arrivent au service.
  • La configuration d’un middleware permettant de rediriger les connections HTTP vers du HTTPS :

    [http.middlewares.redirect-https.redirectscheme]
      scheme = "https"
    
    • scheme : Permet de rediriger vers de l’HTTPS. Ici plus d’informations sur le scheme.
  • La configuration des options de chiffrement TLS :

    [tls]
      [tls.options]
        [tls.options.default]
          minVersion = "VersionTLS12"
          sniStrict = true
          cipherSuites = [
            "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
            "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
          ]
          curvePreferences = ["CurveP521","CurveP384"]
    
    • minVersion : La version minimum de TLS que le serveur pourra négocier avec le client.
    • sniStrict : S’il est activé, Traefik n’autorisera pas les connexions des clients qui ne spécifie pas le header server_name. Plus d’informations ici.
    • cipherSuites : Les différents algorithmes de chiffrement (cipher) que Traefik autorise.
    • curvePreferences : Les courbes ellyptiques préférer dans un ordre précis. Plus d’informations ici.

3.4. La configuration avec les labels Docker

Certaines configurations peuvent aussi être mises en places grâce aux labels que portent les conteneurs Docker. Ci-dessous une explication détaillée de ces labels qui ont été mis en place pour notre conteneur gsa :

gsa:
  image: greenbone/gsa:stable
  restart: on-failure
  exppose:
    - 80
  volumes:
    - gvmd_socket_vol:/run/gvmd
  depends_on:
    - gvmd
  labels:
    - traefik.enable=true
    - traefik.http.routers.gsa-http.entryPoints=http
    - traefik.http.routers.gsa-http.rule=Host(`scanner-tuto.kanops.io`)
    - traefik.http.routers.gsa-http.middlewares=redirect-https@file
    - traefik.http.routers.gsa-https.tls.certresolver=letsencrypt
    - traefik.http.routers.gsa-https.tls=true
    - traefik.http.routers.gsa-https.entryPoints=https
    - traefik.http.routers.gsa-https.rule=Host(`scanner-tuto.kanops.io`)
    - traefik.http.routers.gsa-https.service=gsa-kanops@docker
    - traefik.http.services.gsa-kanops.loadbalancer.server.port=80
  • Dans un premier temps, on active la prise en considération du conteneur par Traefik avec traefik.enable=true

  • - traefik.http.routers.gsa-http.entryPoints=http
    - traefik.http.routers.gsa-http.rule=Host(`scanner-tuto.kanops.io`)
    - traefik.http.router.gsa-http.middlewares=redirect-https@file
    

    On crée ensuite un premier router pour le HTTP nommé gsa-http. Son entrypoint sera http (le port 80), l’url permettant d’accéder à se router sera scanner-tuto.kanops.io et pour finir la requête arrivera dans le middleware redirect-https définit dans notre fichier de configuration dynamique.

  • - traefik.http.routers.gsa-https.entryPoints=https
    - traefik.http.routers.gsa-https.rule=Host(`scanner-tuto.kanops.io`)
    - traefik.http.routers.gsa-https.tls=true
    - traefik.http.routers.gsa-https.tls.certresolver=letsencrypt
    - traefik.http.routers.gsa-https.service=gsa-kanops@docker
    

    On crée par la suite un autre router dédié au HTTPS nommée gsa-https. Son entrypoints sera https (le port 443), l’url pour accéder à se router sera la même. Pour se router, on active le tls tls=true, on indique que notre fournisseur de certificat sera let’s encrypt certresolver=letsencrypt et pour finir se router rediregera les requêtes vers ce conteneur qui sera nommé gsa-kanops@docker comme service.

4. Déploiement de la stack avec TLS

Une fois notre fichier docker-compose.yml modifié pour prendre en compte Traefik, nos dossiers de configurations Traefik et fichiers des configurations prêts. Nous pouvons donc lancer les services avec les commandes docker-compose plus haut dans le tutoriel.

Une fois les services lancés, on peut maintenant accéder à GSA de manière sécurisée avec le TLS d’activée :

https://media.kanops.io/blog/img/docker_gvm_traefik/docker_gvm_traefik_display_gvm_tls.png https://media.kanops.io/blog/img/docker_gvm_traefik/docker_gvm_traefik_display_gvm_dashboard.png

Ici, en accédant au dashboard de Traefik, on s’aperçoit que le htaccess fonctionne correctement :

https://media.kanops.io/blog/img/docker_gvm_traefik/docker_gvm_traefik_display_traefik_dashboard.png https://media.kanops.io/blog/img/docker_gvm_traefik/docker_gvm_traefik_display_traefik_after_htaccess.png

Voilà ! Nous avons déployé GVM 22.4 et mis en place un certificat Let’s Encrypt!

Auteur Billy PAYET

Billy PAYET

Billy est un expert en DevOps qui a une solide expérience en automatisation et en intégration continue. Il utilise des outils tels que Ansible, Jenkins et Docker pour améliorer les processus de déploiement et de livraison des applications. Il est passionné par l'amélioration continue et aider les équipes à atteindre leurs objectifs de qualité et de performance.