Lynis Ansible : automatiser l’audit de sécurité de vos serveurs Linux

Lynis + Ansible : automatiser l’audit de sécurité de vos serveurs Linux

Auditer un serveur Linux à la main, ça marche – une fois. Mais quand on gère 5, 10 ou 30 machines, il faut automatiser. Je vous montre comment j’utilise Lynis, inxi et un script de collecte maison, le tout orchestré par Ansible, pour produire des rapports de sécurité complets en quelques minutes.

Lynis et Ansible : automatiser l'audit de securite des serveurs Linux
Automatisation de l’audit de securite Linux avec Lynis et Ansible : scan, rapport et remediation.

⚡ En résumé

Lynis est un outil open source qui scanne la sécurité d’un système Linux (SSH, permissions, firewall, kernel). Combiné à inxi pour l’inventaire matériel et à un script de collecte système, le tout orchestré par un playbook Ansible, il permet d’auditer automatiquement un parc de serveurs et de récupérer 3 rapports exploitables en quelques minutes, sans intervention manuelle sur chaque machine.

Pourquoi automatiser l’audit de sécurité Linux

Quand un client me demande un audit de sécurité sur un serveur, la procédure manuelle fonctionne : je me connecte en SSH, je lance Lynis, je note les résultats, je vérifie la configuration SSH, les ports ouverts, les comptes utilisateurs, le firewall, les backups… C’est fastidieux mais faisable.

Le problème arrive quand je dois auditer une infrastructure complète : 5 serveurs de production, 2 serveurs de staging, un bastion, un serveur de monitoring. Refaire la même procédure serveur par serveur, c’est une perte de temps considérable et une source d’erreurs (oublier une vérification, mélanger les résultats).

Ma solution : un playbook Ansible qui se connecte à chaque serveur, lance 3 outils d’audit complémentaires, récupère les rapports en local et nettoie derrière lui. Un ansible-playbook audit.yml et 10 minutes plus tard, j’ai tous mes rapports prêts à analyser.

💡 Bon à savoir

Cette approche fonctionne aussi bien pour un audit ponctuel (prestation client) que pour un audit régulier de votre propre infrastructure. J’utilise le même playbook pour mes serveurs d’infogérance et pour les audits ponctuels de mes clients.

Lynis : le scanner de sécurité open source de référence

Lynis est un outil d’audit de sécurité développé par CISOfy. Il analyse en profondeur un système Linux (ou macOS/Unix) et produit un score de durcissement (hardening index) avec des recommandations concrètes. C’est le standard de facto pour l’audit de sécurité sur Linux.

Ce que Lynis vérifie

Lynis passe en revue plus de 300 points de contrôle, répartis en catégories :

Installation et lancement manuel

La méthode la plus propre est de cloner le dépôt officiel directement sur le serveur cible :

git clone https://github.com/CISOfy/lynis.git
cd lynis
sudo ./lynis audit system

L’audit dure entre 2 et 5 minutes selon la complexité du serveur. Le rapport s’affiche dans le terminal et se trouve aussi dans /var/log/lynis-report.dat.

⚠️ Attention

Lynis nécessite les droits root pour un audit complet. Sans sudo, certains tests seront ignorés (vérification du firewall, lecture de /etc/shadow, inspection des fichiers sécurisés). Le rapport sera partiel.

inxi : l’inventaire système complet en une commande

Lynis se concentre sur la sécurité, mais ne collecte pas les informations matérielles et système. Pour compléter l’audit, j’utilise inxi, un outil de diagnostic système qui produit un inventaire complet en une seule commande :

git clone https://github.com/smxi/inxi.git
cd inxi
./inxi -Fazy

Le flag -Fazy donne :

Le résultat est un snapshot complet du serveur : modèle CPU, quantité de RAM, layout disques, interfaces réseau, version du kernel, état des services. C’est exactement ce qu’il faut pour la partie « inventaire » d’un rapport d’audit.

Script de collecte complémentaire : ce que Lynis ne couvre pas

Même avec Lynis et inxi, certaines informations manquent : l’état des services systemd, les processus gourmands, la configuration SSH détaillée, les comptes sudoers, l’état de fail2ban, l’état d’auditd. J’ai donc écrit un script de collecte en Bash qui complète les lacunes :

#!/usr/bin/env bash
# audit_collect.sh - Collecte d'infos d'audit (lecture seule)
set -uo pipefail

timestamp="$(date -Is)"
echo "# Audit système - $(hostname) - $timestamp"

# 1. Ressources système
echo "## Ressources système"
echo "CPU:"
lscpu | egrep 'Model name|Socket|Thread|Core|CPU\(s\)'
echo "RAM:"
free -h
echo "Disques:"
lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT,LABEL
df -hT

# 2. Services et processus
echo "## Services et processus"
echo "Services actifs:"
systemctl list-units --type=service --state=running | head -n 200
echo "Services en échec:"
systemctl --failed
echo "Processus CPU élevés:"
ps axo pid,ppid,cmd,%cpu,%mem --sort=-%cpu | head -n 15
echo "Processus RAM élevés:"
ps axo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head -n 15

# 3. Sécurité système
echo "## Sécurité système"
echo "SSH config:"
sshd_cfg="/etc/ssh/sshd_config"
[ -f "$sshd_cfg" ] && egrep -i \
  'PermitRootLogin|PasswordAuthentication|PubkeyAuthentication' "$sshd_cfg"
echo "Comptes utilisateurs (UID>=1000):"
getent passwd | awk -F: '$3>=1000 {print $1":"$3":"$6":"$7}'
echo "Sudoers:"
sudo -n cat /etc/sudoers 2>/dev/null | egrep -v '^#' || echo "Accès sudoers non disponible"
echo "Fail2ban:"
systemctl status fail2ban 2>/dev/null | head -n 15 || echo "fail2ban absent"
echo "auditd:"
systemctl status auditd 2>/dev/null | head -n 15 || echo "auditd absent"

Le script est en lecture seule : aucune modification, aucune écriture sur le serveur. Il ne fait que lire des informations système et les afficher sur la sortie standard.

Le playbook Ansible qui orchestre tout

Voici le cœur du dispositif : un playbook Ansible qui se connecte au serveur cible, lance les 3 outils d’audit, rapatrie les rapports en local, puis nettoie le serveur.

---
- name: Audit Lynis + audit système inxi
  hosts: "{{ target | default('debian13-test') }}"
  become: true
  gather_facts: true

  vars:
    lynis_repo: "https://github.com/CISOfy/lynis.git"
    lynis_dir: "{{ ansible_env.HOME }}/lynis"
    inxi_repo: "https://github.com/smxi/inxi.git"
    inxi_dir: "{{ ansible_env.HOME }}/inxi"
    audit_collect_script_local: "./audit_collect.sh"
    audit_collect_script_remote: "{{ ansible_env.HOME }}/audit_collect.sh"
    local_report_dir: "./rapports_lynis_inxi"

  tasks:
    # Créer le répertoire local pour les rapports
    - name: Créer le répertoire local pour stocker les rapports
      delegate_to: localhost
      become: false
      ansible.builtin.file:
        path: "{{ local_report_dir }}"
        state: directory
        mode: "0755"

    # --- Lynis (sécurité) ---
    - name: Cloner Lynis dans le home
      ansible.builtin.git:
        repo: "{{ lynis_repo }}"
        dest: "{{ lynis_dir }}"
        version: "master"
        update: false

    - name: Exécuter un audit Lynis
      ansible.builtin.command: >
        ./lynis audit system --cronjob --report-file /dev/null
      args:
        chdir: "{{ lynis_dir }}"
      register: lynis_output

    - name: Écrire le rapport Lynis sur le contrôleur
      delegate_to: localhost
      become: false
      ansible.builtin.copy:
        dest: "{{ local_report_dir }}/{{ inventory_hostname }}-rapport-lynis.txt"
        content: "{{ lynis_output.stdout }}"
        mode: "0644"

    # --- inxi (inventaire système) ---
    - name: Cloner inxi dans le home
      ansible.builtin.git:
        repo: "{{ inxi_repo }}"
        dest: "{{ inxi_dir }}"
        version: "master"
        update: false

    - name: Exécuter inxi (inventaire complet anonymisé)
      ansible.builtin.shell: ./inxi -Fazy
      args:
        chdir: "{{ inxi_dir }}"
      register: inxi_output

    - name: Écrire le rapport inxi sur le contrôleur
      delegate_to: localhost
      become: false
      ansible.builtin.copy:
        dest: "{{ local_report_dir }}/{{ inventory_hostname }}-rapport-systeme-inxi.txt"
        content: "{{ inxi_output.stdout }}"
        mode: "0644"

    # --- Script de collecte complémentaire ---
    - name: Copier audit_collect.sh sur la cible
      ansible.builtin.copy:
        src: "{{ audit_collect_script_local }}"
        dest: "{{ audit_collect_script_remote }}"
        mode: "0755"

    - name: Exécuter audit_collect.sh
      ansible.builtin.command: "{{ audit_collect_script_remote }}"
      register: audit_collect_output

    - name: Écrire le rapport audit_collect sur le contrôleur
      delegate_to: localhost
      become: false
      ansible.builtin.copy:
        dest: "{{ local_report_dir }}/{{ inventory_hostname }}-audit-collect.txt"
        content: "{{ audit_collect_output.stdout }}"
        mode: "0644"

    # --- Nettoyage ---
    - name: Supprimer les fichiers d'audit sur la cible
      ansible.builtin.file:
        path: "{{ item }}"
        state: absent
      loop:
        - "{{ inxi_dir }}"
        - "{{ lynis_dir }}"
        - "{{ audit_collect_script_remote }}"

Points clés de ce playbook

Lancer l’audit en pratique

Prérequis

Auditer un seul serveur

# Auditer un serveur spécifique de votre inventaire
ansible-playbook audit.yml -e target=mon-serveur-prod

# Auditer avec un inventaire ad hoc
ansible-playbook audit.yml -i "192.168.1.50," -e target=all

Auditer toute une infrastructure

# Auditer tous les serveurs d'un groupe
ansible-playbook audit.yml -e target=production

# Auditer avec un parallélisme limité (éviter la surcharge)
ansible-playbook audit.yml -e target=all --forks 3

À la fin de l’exécution, vous retrouvez un répertoire rapports_lynis_inxi/ contenant 3 fichiers par serveur :

rapports_lynis_inxi/
├── srv-prod-01-rapport-lynis.txt
├── srv-prod-01-rapport-systeme-inxi.txt
├── srv-prod-01-audit-collect.txt
├── srv-prod-02-rapport-lynis.txt
├── srv-prod-02-rapport-systeme-inxi.txt
└── srv-prod-02-audit-collect.txt

Lire et exploiter les rapports

Rapport Lynis : le hardening index

La partie la plus utile du rapport Lynis se trouve à la fin : le hardening index. C’est un score sur 100 qui donne une vision immédiate de l’état de sécurité du serveur :

Hardening index : 67 [#############       ]
Tests performed     : 281
Plugins enabled     : 0

Un score en dessous de 70 mérite attention. En dessous de 50, c’est une urgence. Au-dessus de 80, le serveur est bien durci.

Juste avant le score, Lynis liste les suggestions et warnings classés par catégorie. Ce sont les actions concrètes à mettre en place :

Suggestions (42):
  * Set a password on GRUB boot loader [BOOT-5122]
  * Install libpam-tmpdir to set $TMP and $TMPDIR [CUST-0280]
  * Install apt-listchanges [PKGS-7394]
  * Configure minimum password age in /etc/login.defs [AUTH-9286]
  * Configure maximum password age in /etc/login.defs [AUTH-9286]
  * Default umask in /etc/login.defs should be 027 [AUTH-9328]

Warnings (2):
  * Found some information disclosure in SMTP banner [MAIL-8818]
  * iptables module(s) loaded, but no rules active [FIRE-4512]

Rapport inxi : contexte matériel

Le rapport inxi permet de contextualiser les résultats de Lynis. Un serveur avec 1 Go de RAM et un disque presque plein n’aura pas les mêmes priorités qu’un serveur bien dimensionné. Informations utiles :

Rapport audit_collect : vue opérationnelle

Ce troisième rapport complète les deux premiers avec les informations opérationnelles que Lynis ne couvre pas :

💡 Conseil pratique

Pour chaque serveur audité, je commence par lire le rapport inxi (contexte), puis le hardening index de Lynis (score global), puis les warnings Lynis (urgences), et enfin le rapport audit_collect (détails opérationnels). Cette lecture en 4 étapes permet d’identifier rapidement les priorités.

Checklist post-audit : les actions à prioriser

✅ Checklist de remédiation post-audit

  • SSH : PermitRootLogin no et PasswordAuthentication no dans /etc/ssh/sshd_config
  • Firewall : règles iptables/nftables/UFW actives et restrictives (pas de ACCEPT global)
  • Mises à jour : paquets à jour, unattended-upgrades configuré pour les correctifs de sécurité
  • Comptes : supprimer ou verrouiller les comptes inutilisés, vérifier les sudoers
  • Services : désactiver les services inutiles, corriger les services en échec
  • Fail2ban : installé et actif sur SSH au minimum
  • Permissions : corriger les fichiers SUID/SGID inutiles, vérifier les permissions sur /etc/shadow
  • Logs : rotation configurée, journald persistant activé
  • Backups : vérifier qu’un backup récent existe et qu’il est testé
  • Kernel : paramètres sysctl de sécurité appliqués (net.ipv4.conf.all.rp_filter, kernel.randomize_va_space)
  • Monitoring : un agent de supervision est installé et envoie des données (node_exporter, Netdata, etc.)

Erreurs courantes à éviter

🔴 Lancer Lynis sans sudo

Sans les droits root, Lynis ignore les tests sur le firewall, les permissions sensibles, /etc/shadow et de nombreux points de contrôle système. Le rapport sera incomplet et le score artificiellement bas. Utilisez toujours become: true dans le playbook.

🔴 Ne pas nettoyer après l’audit

Laisser Lynis et inxi clonés sur un serveur de production est une mauvaise pratique. Ces outils révèlent des informations sensibles. Le playbook inclut une étape de nettoyage automatique : les dépôts clonés et le script sont supprimés à la fin de l’exécution.

🔴 Auditer sans inventaire Ansible

Utiliser un inventaire ad hoc (-i "IP,") pour un audit ponctuel fonctionne, mais sur une infrastructure entière, maintenir un inventaire structuré (groupes, variables) est indispensable pour que l’audit soit reproductible et que les rapports soient nommés correctement.

🔴 Ignorer le score Lynis inférieur à 50

Un hardening index en dessous de 50 indique des failles critiques : root SSH autorisé, pas de firewall, paquets obsolètes avec CVE connues. Ce n’est pas un score « moyen », c’est un serveur vulnérable. Traitez les warnings Lynis en priorité avant les suggestions.

Aller plus loin : le guide d’audit terrain

Les 3 rapports automatisés couvrent 80 % du travail. Pour les 20 % restants – la partie qui nécessite du jugement humain – j’ai documenté un guide opérationnel complet avec les commandes à lancer pour chaque section du rapport final :

Réseau et firewall

# Interfaces réseau et configuration IP
ip a

# Routes
ip r

# Ports ouverts (la commande la plus utile)
sudo ss -tulpen

# Firewall : vérifier ce qui est actif
sudo ufw status verbose         # si UFW
sudo nft list ruleset            # si nftables
sudo iptables -L -n -v          # si iptables legacy

Base de données

# Version PostgreSQL
sudo -u postgres psql -c "SELECT version();"

# Nombre de connexions actives
sudo -u postgres psql -c "SELECT count(*) FROM pg_stat_activity;"

# Dernier backup visible
sudo find / -name "*.sql" -o -name "*.dump" 2>/dev/null

Backups

# Backups présents sur le serveur
sudo find / -name "*backup*" 2>/dev/null

# Crontabs (backups automatisés)
crontab -l
sudo ls /etc/cron.d/

# Recherche de scripts de backup S3
sudo grep -R "s3" /etc /usr/local /opt 2>/dev/null

Priorisation des risques

Après avoir collecté toutes les informations, je classe les observations en 3 niveaux de priorité :

🚨 Point critique

Un audit n’a de valeur que s’il est suivi d’actions correctives. Produire un rapport Lynis avec un score de 55 et ne rien faire, c’est pire que de ne pas auditer du tout : vous savez que le serveur est vulnérable et vous ne corrigez pas. Chaque audit doit déboucher sur un plan d’action avec des échéances.

FAQ

Lynis est-il gratuit ?

Oui, Lynis Community Edition est open source et gratuit (licence GPLv3). CISOfy propose aussi une version Enterprise avec des fonctionnalités supplémentaires (compliance, rapports centralisés), mais la version communautaire est largement suffisante pour auditer des serveurs Linux.

Lynis modifie-t-il la configuration du serveur ?

Non. Lynis fonctionne en lecture seule. Il ne modifie aucun fichier, ne change aucune configuration et ne redémarre aucun service. C’est un scanner d’audit, pas un outil de remédiation automatique. Toute correction doit être faite manuellement ou via un outil de gestion de configuration comme Ansible.

Peut-on planifier l’audit en cron ?

Absolument. Le flag --cronjob de Lynis est conçu pour ça : il supprime les couleurs et les questions interactives. Vous pouvez créer un cron Ansible ou un job cron classique qui lance ansible-playbook audit.yml de façon hebdomadaire ou mensuelle. Les rapports s’accumuleront dans le répertoire local avec un nom incluant la date.

Quelle différence entre Lynis et OpenSCAP ?

Lynis est un scanner de durcissement généraliste, léger et sans dépendances. OpenSCAP est un framework de conformité basé sur des profils SCAP/STIG/CIS, plus lourd mais plus adapté aux environnements réglementés (PCI-DSS, SOC 2). Pour un audit de sécurité général sur des serveurs Linux d’entreprise, Lynis est plus rapide à mettre en place et ses recommandations sont plus directement actionnables.

Faut-il installer Lynis sur chaque serveur ?

Non, c’est justement l’avantage de l’approche Ansible. Le playbook clone Lynis depuis GitHub directement sur la cible, lance l’audit, récupère le rapport et supprime Lynis. Rien n’est installé de façon permanente. C’est l’approche « agent-less » d’Ansible appliquée à l’audit de sécurité.

Comment améliorer le score Lynis rapidement ?

Les quick wins les plus courants : désactiver root SSH (PermitRootLogin no), activer le firewall avec des règles restrictives, installer et configurer fail2ban, appliquer les mises à jour de sécurité en attente, configurer unattended-upgrades, et corriger les paramètres sysctl de sécurité réseau. Ces 6 actions font souvent gagner 15 à 20 points sur le hardening index.

L’audit fonctionne-t-il sur des conteneurs Docker ?

Lynis peut tourner dans un conteneur, mais les résultats seront limités : pas d’accès au kernel, pas de vision sur le firewall de l’hôte, pas de services systemd. Pour auditer un environnement Docker, mieux vaut auditer l’hôte Docker avec Lynis et utiliser des outils spécifiques comme docker bench security ou Trivy pour scanner les images et la configuration du daemon Docker.

Besoin d’un audit de sécurité sur votre infrastructure Linux ?

J’accompagne les entreprises dans l’audit, le durcissement et l’infogérance de leurs serveurs Linux. Un audit complet avec rapport détaillé et plan d’action, c’est la première étape pour sécuriser votre infrastructure.

Demander un audit →

Quitter la version mobile