Aller au contenu

🚀 Installation de CISO Assistant

Installation basique

L'installation de base fournie par la documentation permet de se faire une idée de l'application. Il faut au préalable avoir installé Docker et Docker compose.

Installation de base
olivier@ws01:~$ git clone https://github.com/intuitem/ciso-assistant-community.git
olivier@ws01:~$ cd ciso-assistant-community
olivier@ws01:~/ciso-assistant-community$ ./docker-compose.sh

Vous trouverez le docker-compose.yml fourni par Intuitem sur leur dépôt Github (ou dans le dépôt cloné). Vous constaterez alors l'utilisation de Caddy comme reverse-proxy.

Lors de l'initialisation des conteneurs, il vous sera demandé de saisir un super utilisateur avec son mot de passe.

Ensuite il vous suffira de vous connecter sur https://localhost:8443 et vous authentifier avec les creds précédemment renseignés.

ciso-welcome

Cette installation est très bien pour prendre en main le logiciel mais l'accès est limité à nous-même. Voyons maintenant comment l'intégrer avec Nginx et Traefik à la place de Caddy pour le rendre accessible aux collaborateurs.

Installation avec Docker et Nginx

Il n'y a pas encore de documentation officielle concernant cette configuration. J'ai donc recherché une façon de faire à m'appyant sur les "issues" du dépôt Github de l'application.

Dans tous les cas, l'application se veut collaborative et il faut donc la rendre accessible à minima sur le réseau.

Pour ce mode d'installation, vous devez au préalable :

  • Avoir installé Docker et Docker compose
  • Avoir installé Nginx (façon "old-school" 😄)
  • Avoir (créé) un nom de domaine de porté locale
  • Avoir préparé le certificat pour le ndd (dans notre exemple cela sera "ciso.domain.lan")
  • Préparer un compte mail qui servira pour les notifications et lors de l'ajout d'un utilisateur supplémentaire.
  • Générer une clé secrète pour Django avec par exemple la commande openssl rand -base64 50
Installation avec Nginx en reverse-proxy
olivier@srv01:~$ sudo mkdir /srv/ciso-assistant && sudo chown olivier: /srv/ciso-assistant
olivier@srv01:~$ cd /srv/ciso-assistant
olivier@srv01:/srv/ciso-assistant$ mkdir data
olivier@srv01:/srv/ciso-assistant$ vim docker-compose.yml

services:
  ciso_backend:
    image: ghcr.io/intuitem/ciso-assistant-community/backend:latest
    container_name: ciso_backend
    hostname: backend
    restart: unless-stopped
    environment:
      - ALLOWED_HOSTS=backend
      - CISO_ASSISTANT_URL=https://ciso.domain.lan
      - DJANGO_DEBUG=False
      - DJANGO_SECRET_KEY=<DJANGO_KEY>
      # DB
      - POSTGRES_NAME=ciso
      - POSTGRES_USER=<USER_PGSQL>
      - POSTGRES_PASSWORD=<MOT_DE_PASSE_PGSQL>
      - DB_HOST=ciso_db
      - DB_PORT=5432
      # Email
      - DEFAULT_FROM_EMAIL=<EMAIL>
      - EMAIL_HOST=<SERVEUR_MAIL>
      - EMAIL_PORT=<PORT>
      - EMAIL_HOST_USER=<USER>
      - EMAIL_HOST_PASSWORD=<PASSWORD>
      - EMAIL_USE_TLS=True # Si utilisation du chiffrement

  ciso_frontend:
    image: ghcr.io/intuitem/ciso-assistant-community/frontend:latest
    container_name: ciso_frontend
    hostname: frontend
    restart: unless-stopped
    environment:
      - PUBLIC_BACKEND_API_URL=http://backend:8000/api
      - ORIGIN=https://ciso.domain.lan
      - PROTOCOL_HEADER=x-forwarded-proto
      - HOST_HEADER=x-forwarded-host
    depends_on:
      - ciso_backend
    ports:
      - 127.0.0.1:3000:3000

  ciso_db:
    image: docker.io/postgres:latest
    container_name: ciso_frontend
    hostname: ciso_db
    environment:
      - POSTGRES_USER=<USER_PGSQL>
      - POSTGRES_PASSWORD=<MOT_DE_PASSE_PGSQL>
      - POSTGRES_DB=ciso
      - PGDATA=/var/lib/postgres/data
    volumes:
      - ./data:/var/lib/postgres/data

olivier@srv01:/srv/ciso-assistant$ vim /etc/nginx/sites-available/01-ciso.domain.lan :

server {
        listen 443 ssl;
        listen [::]:443 ssl;

        ssl_certificate /etc//nginx/ssl/ciso/ciso.domain.lan.crt;
        ssl_certificate_key /etc/nginx/ssl/ciso/ciso.domain.lan.pem;
        ssl_session_timeout 1d;
        ssl_session_cache shared:MozSSL:10m;
        ssl_session_tickets off;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
        ssl_prefer_server_ciphers off;

        add_header Strict-Transport-Security "max-age=63072000" always;

        server_name ciso.domain.lan;
        location / {
                proxy_pass      http://127.0.0.1:3000;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

Il ne vous reste plus qu'à relancer Nginx et lancer les conteneurs. Comptez une ou deux minutes voire plus pour le lancement du backend CISO.

Une fois les conteneurs lancés, il faut créer le super-utilisateur :

Création du super-utilisateur
olivier@srv01:~$ docker exec -it <ID_CT_BACKEND> python manage.py createsuperuser
# Vous renseignerez alors un email et un mot de passe.

source : Issue du dépôt Github de CISO Assistant

Installation avec Docker Swarm et Traefik

Étant donné que je travaille sur un projet perso qui est de se familiariser avec Docker Swarm, je me suis dit que c'était la bonne occasion de mettre à profit ma petite infra pour tester le déploiement de CISO Assistant exposé par Traefik.

Je ne vais reprendre que le fichier de configuration des services. Vous pouvez trouver la documentation sur Docker Swarm et Traefik ici

Fichier docker-stack.yml
services:
  ciso_backend:
    image: ghcr.io/intuitem/ciso-assistant-community/backend:latest
    hostname: backend
    networks:
      - ciso
    environment:
      - ALLOWED_HOSTS=backend
      - CISO_ASSISTANT_URL=https://ciso.domain.fr
      - DJANGO_DEBUG=False
      - DJANGO_SECRET_KEY=<DJANGO_KEY>
      # DB
      - POSTGRES_NAME=ciso
      - POSTGRES_USER=<USER_PGSQL>
      - POSTGRES_PASSWORD=<MOT_DE_PASSE_PGSQL>
      - DB_HOST=ciso_db
      - DB_PORT=5432
      # Email
      - DEFAULT_FROM_EMAIL=<EMAIL>
      - EMAIL_HOST=<SERVEUR_MAIL>
      - EMAIL_PORT=<PORT>
      - EMAIL_HOST_USER=<USER>
      - EMAIL_HOST_PASSWORD=<PASSWORD>
      - EMAIL_USE_TLS=True # Si utilisation du chiffrement
    deploy:
      placement:
        constraints:
          - node.role == worker
      restart_policy:
        condition: on-failure
      replicas: 1

  ciso_frontend:
    image: ghcr.io/intuitem/ciso-assistant-community/frontend:latest
    hostname: frontend
    networks:
      - ciso
      - web
    environment:
      - PUBLIC_BACKEND_API_URL=http://backend:8000/api
      - ORIGIN=https://ciso.domain.fr
      - PROTOCOL_HEADER=x-forwarded-proto
      - HOST_HEADER=x-forwarded-host
    depends_on:
      - ciso_backend
    deploy:
      placement:
        constraints:
          - node.role == worker
      restart_policy:
        condition: on-failure
      replicas: 1
      labels:
        - "traefik.enable=true"
        - "traefik.docker.network=web"
        - "traefik.http.routers.ciso-web.rule=Host(`ciso.domain.fr`)"
        - "traefik.http.routers.ciso-web.tls=true"
        - "traefik.http.routers.ciso-web.tls.certresolver=letsencrypt"
        - "traefik.http.services.ciso-web-service.loadbalancer.server.port=3000"

  ciso_db:
    image: docker.io/postgres:latest
    hostname: ciso_db
    networks:
      - ciso
    environment:
      - POSTGRES_USER=<USER_PGSQL>
      - POSTGRES_PASSWORD=<MOT_DE_PASSE_PGSQL>
      - POSTGRES_DB=ciso
      - PGDATA=/var/lib/postgres/data
    volumes:
      - ./data:/var/lib/postgres/data
    deploy:
      placement:
        constraints:
          - node.role == worker
      restart_policy:
        condition: on-failure
      replicas: 1

networks:
  ciso:
  web:
    external: true

Comme pour l'installation avec Docker et Nginx, il vous faudra créer manuellement un super-utilisateur avec la même commande.

Et ça fonctionne nickel. Bon par contre même avec le Raspberry Pi 4 venu en renfort, les performances sont pas top malgré un état des ressources (cpu, RAM...) non surchargé.

Utilisation de l'API

Pour ceux qui utilisent des process d'automatisation tels que l'intégration des informations issues de CISO Assistant dans une autre application par exemple, il est possible d'exposer l'API du backend.

En effet, si nous reprenons la stack technique de l'installation de base, il est techniquement possible de configurer le backend pour interroger l'API directement sans passer par le frontend.

ciso-stack

La documentation et les tests de l'API sont accessibles par le biais de Swagger.

Voici comment faire avec les différentes configurations vues plus haut.

Exposition de l'API sur l'installation basique

Une fois votre stack déployée, arrêtez-la et modifiez le service "backend" dans le fichier docker-compose.yml comme ci-dessous.

Publication de l'API dans le fichier docker-compose.yml
services:
  backend:
    container_name: backend
    image: ghcr.io/intuitem/ciso-assistant-community/backend:latest
    restart: always
    ports:
      - 127.0.0.1:8000:8000 # Publication du port
    environment:
      - ALLOWED_HOSTS=backend,localhost # Ajout de localhost. Sans cela vous aurez une erreur Django.
      - CISO_ASSISTANT_URL=https://localhost:8443
      - DJANGO_DEBUG=True
    volumes:
      - ./db:/code/db
(...)

Lancez la stack puis connectez-vous sur : http://localhost:8000/api/iam/login/

Vous arriverez alors sur cette page.

ciso-stack

Renseignez votre utilisateur et votre mot de passe ici :

ciso-stack

Puis cliquez sur "Post".

Vous obtiendrez alors juste au dessus un token qui sera utilisé avec Swagger.

ciso-stack

Copiez le token puis rendez-vous sur l'interface de Swagger http://localhost:8000/api/schema/swagger/

ciso-stack

Cliquez ensuite sur le bouton "Authorize" afin d'y renseigner votre token. VOus pouvez dès à présent interroger l'API.

Exposition de l'API sur l'installation avec Docker et Nginx

Ici je pars du principe que nous pourrions ouvrir l'accès à CISO Assistant sur le net. J'ai donc mis des restrcitions d'accès à l'API basées sur les IP. Cela n'empêche pas de configurer des accès restreints aux IP utiles dans le cas d'une portée locale uniquement du logiciel (Zero Trust ! 😉).

Configuration de l'accès à l'API avec Nginx
services:
  ciso_backend:
    image: ghcr.io/intuitem/ciso-assistant-community/backend:latest
    container_name: ciso_backend
    hostname: backend
    restart: unless-stopped
    environment:
      - ALLOWED_HOSTS=backend,ciso.domain.lan # Ajout de ciso.domain.lan sinon erreur dans Django
      - CISO_ASSISTANT_URL=https://ciso.domain.lan
      - DJANGO_DEBUG=False
      - DJANGO_SECRET_KEY=<DJANGO_KEY>
      # DB
      - POSTGRES_NAME=ciso
      - POSTGRES_USER=<USER_PGSQL>
      - POSTGRES_PASSWORD=<MOT_DE_PASSE_PGSQL>
      - DB_HOST=ciso_db
      - DB_PORT=5432
      # Email
      - DEFAULT_FROM_EMAIL=<EMAIL>
      - EMAIL_HOST=<SERVEUR_MAIL>
      - EMAIL_PORT=<PORT>
      - EMAIL_HOST_USER=<USER>
      - EMAIL_HOST_PASSWORD=<PASSWORD>
      - EMAIL_USE_TLS=True # Si utilisation du chiffrement
    ports:
      - 127.0.0.1:8000:8000

  ciso_frontend:
    image: ghcr.io/intuitem/ciso-assistant-community/frontend:latest
    container_name: ciso_frontend
    hostname: frontend
    restart: unless-stopped
    environment:
      - PUBLIC_BACKEND_API_URL=http://backend:8000/api
      - ORIGIN=https://ciso.domain.lan
      - PROTOCOL_HEADER=x-forwarded-proto
      - HOST_HEADER=x-forwarded-host
    depends_on:
      - ciso_backend
    ports:
      - 127.0.0.1:3000:3000

  ciso_db:
    image: docker.io/postgres:latest
    container_name: ciso_frontend
    hostname: ciso_db
    environment:
      - POSTGRES_USER=<USER_PGSQL>
      - POSTGRES_PASSWORD=<MOT_DE_PASSE_PGSQL>
      - POSTGRES_DB=ciso
      - PGDATA=/var/lib/postgres/data
    volumes:
      - ./data:/var/lib/postgres/data

olivier@srv01:/srv/ciso-assistant$ vim /etc/nginx/sites-available/01-ciso.domain.lan :

server {
        listen 443 ssl;
        listen [::]:443 ssl;

        ssl_certificate /etc//nginx/ssl/ciso/ciso.domain.lan.crt;
        ssl_certificate_key /etc/nginx/ssl/ciso/ciso.domain.lan.pem;
        ssl_session_timeout 1d;
        ssl_session_cache shared:MozSSL:10m;
        ssl_session_tickets off;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
        ssl_prefer_server_ciphers off;

        add_header Strict-Transport-Security "max-age=63072000" always;

        server_name ciso.domain.lan;
        location / {
                proxy_pass      http://127.0.0.1:3000;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        # Ajout de l'accès à l'API avec restriction sur les IP des clients
        location /api {
                allow 127.0.0.1;
                allow 192.168.1.0/24;
                deny all;
                proxy_pass      http://127.0.0.1:8000;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

Exposition de l'API sur l'installation avec Docker Swarm et Traefik

La mise est en place avec Traefik est plutôt triviale. Comme avec Nginx, on va limiter l'accès à l'API aux IP de notre LAN.

Configuration de l'accès à l'API avec Traefik
services:
  ciso_backend:
    image: ghcr.io/intuitem/ciso-assistant-community/backend:latest
    hostname: backend
    networks:
      - ciso
      - web # Ajout du réseau overley "web" pour la liaison avec Traefik
    environment:
      - ALLOWED_HOSTS=backend,ciso.domain.fr # On autorise ciso.domain.fr sinon erreur de Django
      - CISO_ASSISTANT_URL=https://ciso.domain.fr
      - DJANGO_DEBUG=False
      - DJANGO_SECRET_KEY=<DJANGO_KEY>
      # DB
      - POSTGRES_NAME=ciso
      - POSTGRES_USER=<USER_PGSQL>
      - POSTGRES_PASSWORD=<MOT_DE_PASSE_PGSQL>
      - DB_HOST=ciso_db
      - DB_PORT=5432
      # Email
      - DEFAULT_FROM_EMAIL=<EMAIL>
      - EMAIL_HOST=<SERVEUR_MAIL>
      - EMAIL_PORT=<PORT>
      - EMAIL_HOST_USER=<USER>
      - EMAIL_HOST_PASSWORD=<PASSWORD>
      - EMAIL_USE_TLS=True # Si utilisation du chiffrement
    deploy:
      placement:
        constraints:
          - node.role == worker
      restart_policy:
        condition: on-failure
      replicas: 1
      labels:
        - "traefik.enable=true"
        - "traefik.docker.network=web"
        - "traefik.http.routers.ciso-back-web.rule=Host(`ciso.dev.quercylibre.fr`) && PathPrefix(`/api`)" # Ajout du Prefix /api
        - "traefik.http.routers.ciso-back-web.tls=true"
        - "traefik.http.middlewares.ciso-back-web-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.0/24" # Déclaration du middleware permettant de limiter l'accès
        - "traefik.http.routers.ciso-back-web.middlewares=ciso-back-web-ipallowlist" # On référence le middleware déclaré ci-dessus.
        - "traefik.http.services.ciso-back-web-service.loadbalancer.server.port=8000"
(...)

La suite

Il ne vous reste plus qu'à commencer à jouer avec le logiciel. Pour une première prise en main, je vous recommande de commencer par l'approche par la conformité avec un audit basé sur le guide de l'hygiène informatique de l'ANSSI. D'autres référentiels sont disponibles dans l'application comme vous pourrez le constater sur la page d'accueil du dépôt Github

ciso-framework

Vous trouverez la documentation officielle du logiciel sur https://intuitem.gitbook.io/ciso-assistant.