Automatisation & Hardening – Rapport explicatif

12 min read Page Views

1. Automatisation de l’installation Debian (Preseed)

J’avais pour mission principale de poursuivre le projet d’hardening et d’automatisation des postes à l’aide d’un fichier preseed.
Pour commencer, j’ai pris connaissance de l’environnement existant, des outils utilisés et des contraintes techniques du projet.

Ma première idée a été de construire une image ISO Debian complète, dans laquelle le fichier preseed serait directement intégré.
J’ai donc suivi la procédure officielle de reconstruction d’ISO Debian.
Cette approche fonctionnait correctement pour intégrer le fichier preseed, mais je n’arrivais pas à inclure en même temps le fichier contenant les variables nécessaires à l’installation automatisée.

Première méthode : création d’une ISO complète

J’ai d’abord préparé un espace de travail pour extraire le contenu de l’ISO Debian.
Ensuite, j’ai modifié les fichiers nécessaires et injecté le preseed ainsi que les variables dans l’initrd.
Après chaque modification, il fallait régénérer les fichiers d’intégrité pour que l’ISO soit reconnue comme valide.
Une fois l’ISO reconstruite et convertie en ISO hybride, je pouvais la réécrire sur une clé USB pour la tester.

mkdir isofile
/usr/bin/udevil mount Téléchargements/debian-12.12.0-amd64-netinst.iso
sudo cp -rT /media/user/debian-12.12.0-amd64-netinst.iso/ isofile

sudo chmod +w -R isofile/install.amd/
sudo gunzip isofile/install.amd/initrd.gz
ls Documents/preseed.cfg Documents/variables1.cfg | cpio -H newc -o -A -F isofile/install.amd/initrd
gzip isofile/install.amd/initrd

chmod +w md5sum.txt
find -type f ! -name md5sum.txt -print0 | xargs -0 md5sum > md5sum.txt
chmod -w md5sum.txt

genisoimage -r -J -b isolinux/isolinux.bin -c isolinux/boot.cat \
-no-emul-boot -boot-load-size 4 -boot-info-table \
-o preseed-debian-12.12.0-amd64-netinst.iso isofile

isohybrid preseed-debian-12.12.0-amd64-netinst.iso

dd if=preseed-debian-12.12.0-amd64-netinst.iso of=/dev/sda bs=16M status=progress oflag=sync

Limites rencontrées

Même si l’intégration du preseed fonctionnait, l’intégration simultanée du fichier de variables posait problème.
C’est ce qui m’a amenée à tester une seconde méthode.

Deuxième méthode : utilisation de deux clés USB

Pour contourner la limitation précédente, j’ai testé une approche avec deux clés USB distinctes :

  • une contenant l’ISO Debian standard,
  • une contenant le fichier preseed et le fichier de variables.

Cette méthode permettait de charger les fichiers séparément au moment de l’installation, ce qui contournait les contraintes rencontrées avec l’ISO modifiée.

Rédaction de la procédure

Une fois les difficultés initiales résolues, j’ai rédigé une procédure complète afin de faciliter les futures installations.
Elle décrit l’ensemble des étapes nécessaires, depuis la préparation des supports jusqu’au lancement de l’installation automatisée.

* PREPARATION EN AMONT

L'installation du poste s'effectue avec 2 clés usb, aucune des clés usb ne doit être retirée pendant l'installation.

-1 clé bootable Debian,

-1 clé contenant le fichier preseed en racine ainsi que le fichier variable.

Bien vérifier le chemin indiqué du fichier variable dans le preseed.
Bien vérifier la syntaxe des noms dans chaques fichiers pour éviter toute erreur de lecture.

* INSTALLATION

Modifier les lignes de boot avec la clé usb bootable Debian en tête suivis de la deuxième clé.

Sauvegarder puis retourner au choix du mode d'installation.
Positionner le curseur sur l'entrée "Install" puis appuyer sur la touche #tabulation# (ne pas appuyer sur entrer), ajouter ensuite le paramètre #auto=true# avant l'option vga= dans la ligne de commande du bootloader.

#Exemple : kernel debian-installer/i386/linux
append vga=normal initrd=debian-installer/i386/initrd.gz#

Valider les fonctionnalitées souhaitées jusqu'à
arriver à l'étape de téléchargement du fichier de configuration.

Pour que le fichier preseed soit correctement pris en charge, il est nécessaire de spécifier explicitement son chemin. La clé USB contenant le preseed doit donc être montée manuellement. Pour ce faire, accède au minimal shell disponible dans la liste des étapes d’installation, puis exécute les commandes suivantes :

#blkid# Permet d’identifier les périphériques de stockage.
Utiliser cette commande pour confirmer que la clé USB contenant le preseed est bien reconnue et pour repérer son chemin 

#mkdir -p /media# Afin de pouvoir crée un point de montage à l'interieur de l'installateur.

#mount -t vfat /dev/sdXX /media# Monte la clé USB manuellement. Préciser le type.

#ls /media# Permet de vérifier que le contenu de la clé USB est correctement monté


Il est également nécessaire de s’assurer que l’image ISO utilisée pour l’installation est toujours montée :
Avec la commande #ls cdrom# par exemple.
	
Si ce n'est pas le cas, l’installation échouera car les fichiers sources ne seront plus disponibles.

Une fois les vérifications et montages effectués, quitter le minimal shell pour revenir au processus d’installation et poursuivre le chargement du fichier preseed.
	
le chemin sera donc *file:///media/(nom fichier preseed).cfg*

L'installation ne doit en aucun cas être interrompue, toute interruption du processus peut entraîner l'échec de l'installation.

2. Déploiement d’applications et de configurations (Ansible + Bash)

Après avoir finalisé la documentation sur Preseed, j’ai pu me concentrer sur la deuxième partie de ma mission : le déploiement d’applications et de configurations via Ansible et Bash.

Lorsque certains besoins n’étaient pas couverts par les modules Ansible existants, j’ai complété les playbooks avec des scripts Bash personnalisés.
Ces scripts me permettaient d’exécuter des actions spécifiques ou non prises en charge nativement par Ansible, tout en gardant une logique d’automatisation cohérente.


3. Phase de tests et stabilisation

Après avoir mis en place les premières versions de mes scripts et playbooks, j’ai procédé à une phase de tests.

Chaque script était exécuté dans un environnement de test afin d’identifier :

  • les erreurs,
  • les dépendances manquantes,
  • les comportements inattendus.

Lorsque les résultats n’étaient pas conformes, j’analysais les messages d’erreur, ajustais le script ou le playbook, puis relançais une nouvelle série de tests.
Ce processus s’est répété autant de fois que nécessaire jusqu’à obtenir un fonctionnement stable et reproductible.


4. Automatisation des applications via Ansible ou script bash

Objectif

Automatiser l’installation et la configuration d’applications sur les postes Linux via Ansible, tout en respectant les contraintes de sécurité.

Mise en place de l’environnement Ansible

J’ai installé Ansible sur la machine de test afin de disposer d’un environnement fonctionnel pour créer et exécuter mes playbooks.
J’ai également tenté d’utiliser ansible-lint pour vérifier la qualité de mes playbooks.
L’installation via pip n’ayant pas fonctionné, j’ai utilisé pipx, plus adapté pour installer des outils isolés.

sudo apt update
sudo apt upgrade
sudo apt install ansible
ansible --version

sudo apt install pipx
pipx install ansible-lint
pipx ensurepath

Vérification et tests des playbooks

Une fois mes premiers playbooks rédigés, je les ai testés avec ansible-lint.
Les fichiers étaient valides, mais l’exécution restait bloquée : certains modules nécessitaient une validation manuelle, ce qui empêchait l’automatisation complète.

C’est à ce moment-là que j’ai découvert le module ansible.builtin.script, qui permet d’exécuter un script local sur un nœud distant.
La documentation recommande cependant de privilégier les modules Ansible natifs plutôt que de pousser des scripts, car cela garantit une meilleure idempotence et une gestion plus propre des erreurs.


5. Choix technique : modules Ansible + scripts Bash

Après analyse, j’ai décidé de :

  • utiliser les modules Ansible dès qu’ils existent (firewall, USBGuard, installation de paquets…),
  • compléter avec des scripts Bash uniquement lorsque :
    • aucun module n’existe,
    • ou que le module ne couvre pas le besoin exact.

6. Approche de travail

Pour avancer sur l’automatisation, j’ai travaillé de manière simple et efficace :
j’écrivais un playbook, je le testais, je regardais ce qui cassait, et je recommençais jusqu’à ce que ça fonctionne correctement.

En pratique :

  • je rédigeais le playbook,
  • je vérifiais la qualité avec ansible-lint,
  • je lançais l’exécution sur la machine de test,
  • j’analysais les erreurs et les dépendances manquantes,
  • je corrigeais,
  • je retestais,
  • et je répétais ce cycle autant de fois que nécessaire.

Une fois une version stable obtenue, je documentais la procédure pour qu’elle soit claire et réutilisable.


7. Automatisation des applications et outils de pentest

Dans la continuité du projet, j’ai travaillé sur l’installation et la configuration d’un ensemble d’applications nécessaires aux postes utilisateurs et aux postes orientés pentest.

J’ai commencé par les applications classiques : VSCode, Thunderbird, Element Nightly, Bitwarden, USBGuard…
Pour chacune, j’ai vérifié la méthode d’installation la plus propre, puis j’ai créé un playbook dédié.

---
- name: Install basic apps
  hosts: all
  become: true

  tasks:
    - name: Install base utilities
      apt:
        name:
          - curl
          - wget
          - gnupg
          - ca-certificates
          - git
          - thunderbird
          - usbguard
        state: present
        update_cache: yes

    - name: Ensure keyrings directory exists
      file:
        path: /usr/share/keyrings
        state: directory
        mode: '0755'

    
    - name: Add Microsoft GPG key
      shell: |
        curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | \
        gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg
      args:
        creates: /usr/share/keyrings/microsoft-prod.gpg

    - name: Add VS Code repository
      ansible.builtin.apt_repository:
        repo: >-
          deb [arch=amd64,arm64,armhf signed-by=/usr/share/keyrings/microsoft-prod.gpg]
          https://packages.microsoft.com/repos/code stable main
        state: present
        filename: vscode
        update_cache: yes

    
    - name: Add Element Nightly GPG key
      get_url:
        url: https://packages.element.io/debian/element-io-archive-keyring.gpg
        dest: /usr/share/keyrings/element-io-archive-keyring.gpg
        mode: '0644'

    - name: Add Element Nightly repository
      ansible.builtin.apt_repository:
        repo: deb [signed-by=/usr/share/keyrings/element-io-archive-keyring.gpg] https://packages.element.io/debian/ default main
        state: present
        filename: element-nightly
        update_cache: yes

    - name: Install main applications
      apt:
        name:
          - code
          - element-nightly
        state: present
        update_cache: yes

Installation sécurisée de VeraCrypt

Finalement, le playbook Ansible pour VeraCrypt ne fonctionnait pas comme prévu.
J’ai donc réalisé l’installation de VeraCrypt via un script Bash.

Pour VeraCrypt, j’ai étudié plusieurs méthodes : PPA, PGP, paquet officiel…
La solution la plus fiable reste de télécharger le .deb officiel, vérifier la signature PGP, puis lancer l’installation de manière automatisée.

J’ai donc conservé l’approche automatisée, mais en m’appuyant sur un script Bash plutôt que sur un module Ansible.

#!/bin/sh

echo "Download veracrypt package"
wget https://launchpad.net/veracrypt/trunk/1.26.24/+download/veracrypt-console-1.26.24-Debian-12-amd64.deb

echo "Installing VeraCrypt"
sudo apt install ./veracrypt-console-1.26.24-Debian-12-amd64.deb

echo "Installing pmount utility"
sudo apt install pmount

chmod +x veracrypt.sh

Automatisation des outils de pentest

Beaucoup d’outils reposent sur Go, donc j’ai installé Go proprement avant d’automatiser l’installation de :

  • ffuf,
  • gowitness,
  • dnsx,
  • amass,
  • subfinder,
  • gau,
  • Bypass URL Parser, etc.

Pour éviter de polluer le système, j’ai créé un espace dédié aux outils Go, ce qui permet de garder un environnement propre et maintenable.

Gestion des outils Python

Installer des outils Python dans le système global crée des conflits.
La bonne pratique est de les isoler dans un virtualenv.
J’ai donc prévu un répertoire dédié pour les outils Python, même si cette partie sera finalisée plus tard.

---
- name: Go install
  hosts: localhost
  become: yes

  tasks:
    - name: Variables
      ansible.builtin.include_vars: versions.yml

    - name: Download go
      ansible.builtin.get_url:
        url: "https://go.dev/dl/go{{go_version}}.linux-amd64.tar.gz"
        dest: /tmp/go.tar.gz

    - name: Download and insall Go
      ansible.builtin.unarchive:
        src: "https://go.dev/dl/go{{go_version}}.linux-amd64.tar.gz"
        dest: /usr/local
        remote_src: yes
        creates: /usr/local/go

    - name: Create GOPATH directory
      ansible.builtin.file:
        path: /opt/go
        state: directory
        mode: '0755'

    - name: Add go PATH
      ansible.builtin.lineinfile:
        path: /opt/.bashrc
        line: 'export PATH=$PATH:/usr/local/go/bin:/opt/go/bin'
        create: yes

    - name: Install Go tools
      ansible.builtin.command: >
        /usr/local/go/bin/go install {{ item.repo }}@{{ item.version}}
      loop:
        - { repo: "github.com/projectdiscovery/subfinder/v2/cmd/subfinder", version: "{{ subfinder }}" }
        - { repo: "github.com/lc/gau/v2/cmd/gau",                           version: "latest"}
        - { repo: "github.com/sensepost/gowitness",                    version: "{{ gowitness }}" }
        - { repo: "github.com/projectdiscovery/dnsx/cmd/dnsx",         version: "{{ dnsx }}" }
        - { repo: "github.com/ffuf/ffuf/v2",                           version: "{{ ffuf }}" }
      environment:
        GOPATH: /opt/go

8. Avancement global

Au fur et à mesure, j’ai avancé sur plusieurs playbooks :

  • celui des applications est terminé,
  • celui de VeraCrypt fonctionne mais doit être amélioré côté versioning,
  • celui des outils Go est opérationnel,
  • j’ai créé un fichier version.yml pour gérer les versions des outils.
go_version: "1.25.5"
ffuf: "v2.1.0"
subfinder: "v2.6.7"
gau: "latest"
gowitness: "latest"
dnsx: "v1.2.2"
bypass_url_parser: "0.4.4"
droopescan: "1.45.1"

Playbook d’installation des outils de pentest

J’ai créé un playbook dédié à l’installation des outils de pentest. Le playbook installe ensuite un ensemble de paquets de base nécessaires au fonctionnement des outils, comme nmap, docker, wget ou encore Java.

Pour gérer les outils Python, j’ai mis en place plusieurs environnements virtuels (venv).
Chaque outil Python est installé dans son propre venv afin d’éviter les conflits de dépendances et de garder un système propre.

J’ai notamment installé :

  • Bypass URL Parser, dans un venv dédié
  • Droopescan, également dans un venv séparé

Enfin, j’ai intégré l’installation de SecLists via un clonage Git, ce qui permet d’avoir une version complète et à jour de la collection de wordlists utilisée dans de nombreux outils de pentest.

Ce playbook permet donc d’automatiser l’installation d’un ensemble d’outils essentiels pour les postes orientés pentest, tout en respectant une logique de maintenabilité et d’isolation des environnements.

- name: Download and Install pentest tools
  hosts: localhost
  become: yes

  tasks:
    - name: Load the variables from the file
      ansible.builtin.include_vars: versions.yml
    
    - name: Install base packages
      apt:
        name:
          - nmap
          - docker.io
          - wget
          - openjdk-17-jre-headless
        state: present
        update_cache: yes

    - name: Install venv Python
      ansible.builtin.package:
        name: python3-venv
        state: present

    - name: Create venv
      ansible.builtin.command:
        cmd: python3 -m venv /opt/bup/mon_venv
      args:
        creates: /opt/mon_venv/bin/activate
    
    - name: Install Bypass Url Parser
      ansible.builtin.pip:
        virtualenv: /opt//bup/mon_venv
        name: "bypass_url_parser=={{ bypass_url_parser }}"

    - name: Create venv
      ansible.builtin.command:
        cmd: python3 -m venv /opt/droopescan/mon_venv
      args:
        creates: /opt/mon_venv/droopescan/activate    

    - name: Install droopescan
      ansible.builtin.pip:
        virtualenv: /opt/droopescan/mon_venv
        name: "droopescan=={{ droopescan }}"    

    - name: Install Seclists
      git:
        repo: "https://github.com/danielmiessler/SecLists.git"
        dest: /usr/local/share/seclists
        clone: yes
        update: yes

J’ai également rédigé une procédure complète pour documenter l’installation de ces outils.
Cette procédure facilite non seulement la reproduction du déploiement, mais elle permet aussi à l’équipe d’améliorer ou d’ajouter de nouveaux outils beaucoup plus facilement, grâce à une base claire et structurée.

Ce document comprend la Procedure d'installation des postes de travail ainsi que certains axes d'amélioration.
:

== Cette procédure intervient en complément de l'installation complète de l'OS Debian à l'aide du fichier preseed.

* Pour les postes de travail.

*Première étape : Installation d'ansible via un script.*

- Se rendre dans le répertoire contenant le script et l'exécuter. (le script est déjè executable)

#bash ansible.sh#

- Répéter la même procédure pour VeraCrypt.

#bash veracrypt.sh#

*Deuxième étape: Exécution des playbooks et du firewall.*

- Lancer le playbook des applications.

#ansible-playbook app.yml#


- script hardening

* Pour les postes de pentest.

*Première étape : Installation d'ansible via un script.*

- Se rendre dans le répertoire contenant le script et l'exécuter. (le script est déjè executable)

#bash ansible.sh#

- Répéter la même procédure pour VeraCrypt.

#bash veracrypt.sh#


*Deuxième étape: Exécution des playbooks.*

- Lancer le playbook des applications.

#ansible-playbook app.yml#

- Lancer le playbook des outils de pentest go et les autres outils.

Attention : les playbooks d'outils doivent être accompagnés par le playbooks #versions.yml#.

#ansible-playbook pentest_tools.yml#

#ansible-playbook go_tools.yml#

- Lancer le playbook du firewall, il doit être accompagé de son script.

#ansible-playbook firewall.yml#

* Bonne pratique/recommandations:


- Mettre à jour régulièrement les applications et outils installés, et effectuer des tests après installation, un playbook "versions.yml" est disponible pour une meilleur gestion.

- Pour vérifier les erreurs avant de lancer un playbook utiliser la commande #--check#, exemple : #ansible-playbook app.yml --check#.

- Définir les privilèges stricts dans les tâches Ansible.

- Versionner tous les playbooks sur le Gitlab.

- Prévoir un espace dédié pour les oulis qui ont les mêmes dépendances.

*Autres paramètrages manuels*

- Déposer script header check.

- Installer Burp Suite pro avec licence .

- Installer amass manuellement. (https://github.com/owasp-amass/amass).