<
>

De Zéro à l’Infra Multi-Site : Retour d’expérience sur mon projet TSSR (Aura)

Linux OPNsense Proxmox VLANs [02/07/2026]

L’objectif de mon dernier projet en date était d’une envergure particulièrement stimulante : concevoir, automatiser et sécuriser de bout en bout l’infrastructure de l’entreprise fictive « Aura ». Cette société compte 80 collaborateurs répartis sur un siège principal à Paris et une nouvelle agence à Villepinte.

L’intégralité de cette architecture a été maquettée au sein de mon propre Homelab, en exploitant un cluster de virtualisation Proxmox. Voici le détail technique des solutions déployées.

1. Réseau et Sécurité : Routage Proxmox, OPNsense et Tunnels VPN

Le fondement de l’infrastructure repose sur un plan d’adressage global en 10.0.0.0/8, offrant une grande flexibilité.
Ce réseau a été découpé par code postal géographique : 10.75.0.0/16 pour le site de Paris et 10.93.0.0/16 pour l’agence de Villepinte.

Segmentation des VLANs

La séparation logique des départements a été orchestrée via des VLANs identiques sur les deux sites.

ID VLAN
Nom du VLAN
Sous-réseau Paris
Sous-réseau Villepinte
Usage
10VLAN_SERVERS10.75.10.0/2410.93.10.0/24Serveurs
20 VLAN_IT10.75.20.0/2410.93.20.0/24Service IT
25VLAN_DIRECTION_RH10.75.25.0/2410.93.25.0/24Direction et RH
30VLAN_USERS10.75.30.0/2410.93.30.0/24Utilisateurs standards
35VLAN_COMPTA10.75.35.0/2410.93.35.0/24Comptabilité
40VLAN_PRINTERS10.75.40.0/2410.93.40.0/24Imprimantes
50VLAN_WIFI_PRIVE10.75.50.0/2410.93.50.0/24Réseau Wi-Fi interne
60VLAN_WIFI_PUBLIC10.75.60.0/2410.93.60.0/24Réseau Wi-Fi visiteurs
70VLAN_VPN10.75.70.0/2410.93.70.0/24Accès Télétravail
Représentation graphique de l’infrastructure informatique Aura

Bridge Proxmox et Isolation OPNsense

Pour simuler les commutateurs physiques, j’ai exploité le routage interne de Proxmox. L’interface vmbr1 agit comme le lien WAN. Les interfaces vmbr2 et vmbr3 gèrent respectivement les réseaux locaux de Paris et de Villepinte, et la fonction vlan aware y a été activée pour supporter le routage inter-VLAN. Le pare-feu et le routage sont assurés par deux machines virtuelles OPNsense, une pour chaque site géographique.

Dans OPNsense, j’ai optimisé la gestion du pare-feu en créant des alias et des règles flottantes (Floating Rules) pour autoriser massivement les ports essentiels comme le 53 (DNS), le 80 (HTTP) et le 443 (HTTPS) à travers tous les VLANs internes.

Pour sécuriser le Wi-Fi public (VLAN 60), j’ai créé un alias spécifique contenant les adresses privées standards (RFC1918). Une règle de pare-feu bloque toute communication vers cet alias, ce qui garantit qu’un visiteur dispose d’Internet sans jamais pouvoir joindre une ressource interne de l’entreprise, même si de nouveaux VLANs voient le jour par la suite.

Tunnels VPN

  • Interconnexion des sites : Les réseaux de Paris et Villepinte communiquent de manière transparente grâce à un tunnel VPN IPsec Site-à-Site. L’authentification repose sur une Pre-Shared Key (Clé pré-partagée) configurée sur les deux routeurs OPNsense.
  • Accès Télétravail : J’ai écarté OpenVPN et IPsec côté client pour privilégier le protocole WireGuard, réputé pour sa légèreté. Une règle NAT a été implémentée sur OPNsense pour rediriger le trafic entrant directement vers l’interface virtuelle wg0 de WireGuard.

2. Services Systèmes : L’écosystème Windows Server 2025

Bien que des solutions open source comme OpenLDAP ou Samba4 existent, la gestion d’un parc de postes de travail Windows justifie pleinement le déploiement d’un annuaire Active Directory complet, intégrant nativement la gestion des sessions, le DNS et les fameuses GPO (Stratégies de groupe).

Tolérance aux pannes AD et Troubleshooting RPC

J’ai déployé deux contrôleurs de domaine (DC) sous Windows Server 2025 : le principal à Paris (10.75.10.240) et le secondaire à Villepinte (10.93.10.240). Grâce à la configuration des Sites & Services Active Directory, les utilisateurs s’authentifient automatiquement sur le serveur le plus proche de leur position géographique géographique, ce qui élimine les problèmes de latence et apporte une forte redondance.

Lors de la promotion du DC de Villepinte, un défi technique de taille est apparu. La réplication inter-sites échouait avec une erreur bloquante : RPC server is unavailable. Le diagnostic a permis de comprendre que l’alias de mon pare-feu OPNsense ne couvrait pas la totalité des ports requis pour Active Directory. J’ai dû modifier la configuration pour autoriser explicitement les flux LDAP (389), Kerberos (88), DNS (53) et surtout la plage dynamique RPC (49152-65535). Une fois l’alias complété, un test via la commande dcdiag /test:replications a validé le succès de la synchronisation entre les deux sites.

Stockage Centralisé : DFS et AGDLP

La structure des partages de fichiers a été sécurisée en appliquant rigoureusement la méthodologie des droits NTFS nommée AGDLP. Pour unifier l’expérience utilisateur, j’ai configuré un Espace de noms DFS (DFS-N) fournissant un point d’entrée unique et transparent : \\aura.lan\Partages. Les dossiers partagés essentiels sont répliqués en continu entre Paris et Villepinte via le composant de Réplication DFS (DFS-R).

3. Outils et Support : GLPI via Docker et LDAPS

Afin d’abandonner la gestion artisanale du support par e-mails pour 80 personnes, j’ai déployé l’application de ticketing GLPI.

Pour garantir la portabilité et la facilité de maintenance, GLPI tourne via Docker Compose sur une machine virtuelle Debian 13. Le fichier docker-compose.yml orchestre l’image officielle de GLPI et une base de données MariaDB. Le conteneur GLPI expose le port 8080 sur la machine hôte.

Pour chiffrer les flux web, un serveur web Nginx est installé directement sur l’hôte Debian et agit en tant que Reverse Proxy. Il écoute sur le port 443 (HTTPS) et redirige les requêtes de manière transparente vers le port 8080 du conteneur. Enfin, pour que les collaborateurs puissent se connecter avec leur session Windows habituelle, j’ai généré un certificat SSL auto-signé avec OpenSSL, ce qui a permis d’activer et de sécuriser l’interconnexion LDAPS entre GLPI et l’Active Directory.

4. L’Automatisation avec PowerShell, FOG Project et Ansible

L’industrialisation des processus a permis d’optimiser drastiquement le travail du service IT.

L’Intégration Active Directory (PowerShell)

Créer manuellement 80 comptes utilisateurs dans l’annuaire représentait une perte de temps doublée d’un risque majeur d’erreurs de frappe. J’ai donc développé le script PowerShell complet import_users_csv.ps1. Ce script accomplit les tâches suivantes lors de l’importation d’un fichier CSV fourni par les Ressources Humaines :

  • Il vérifie la date de fin de contrat et ignore automatiquement les profils arrivés à expiration.
  • Il génère de manière dynamique un identifiant de connexion unique (SAMAccountName).
  • Il cible l’Unité d’Organisation (OU) exacte et intègre l’utilisateur au Groupe de Sécurité correspondant (par exemple, GS_IT_PARIS) selon son site et son département.
# filename: import_users_csv.ps1
# --- Configuration ---
$CSVPath = "C:\utilisateurs_aura.csv"
$Domain  = "@aura.lan"	
$BaseDN  = "OU=AURA,DC=aura,DC=lan"
$Aujourdhui = Get-Date

# Importation des données
$Users = Import-Csv -Path $CSVPath -Delimiter ";" -Encoding UTF8

foreach ($User in $Users) {
    # 1. Filtrage par date de fin de contrat (Exclut les contrats expirés)
    $ExpiryDate = $null
    if ($User.Fin_Contrat) {
        $ExpiryDate = [DateTime]::ParseExact($User.Fin_Contrat, "dd/MM/yyyy", $null)
        if ($ExpiryDate -lt $Aujourdhui) { 
            Write-Host "Ignoré : Contrat terminé pour $($User.Nom)" -ForegroundColor Gray
            continue 
        }
    }

    # 2. Génération de l'identifiant unique (SAMAccountName)
    $BaseSAM = ($User.Prenom.Substring(0,1) + $User.Nom).ToLower().Replace(" ", "")
    $SAM = $BaseSAM
    $i = 1
    while (Get-ADUser -Filter "SamAccountName -eq '$SAM'" -ErrorAction SilentlyContinue) {
        $SAM = "$BaseSAM$i"
        $i++
    }

    # 3. Préparation du chemin OU et du Groupe de Sécurité
    $LieuUpper = $User.Lieu.ToUpper()
    $GroupName = "GS_$($User.Service)_$LieuUpper"
    $TargetOU  = "OU=$($User.Service),OU=Utilisateurs,OU=$($User.Lieu),$BaseDN"

    # 4. Préparation des paramètres de l'utilisateur
    $UserParams = @{
        Name                  = "$($User.Prenom) $($User.Nom)"
        GivenName             = $User.Prenom
        Surname               = $User.Nom
        SamAccountName        = $SAM
        UserPrincipalName     = "$SAM$Domain"
        Path                  = $TargetOU
        AccountExpirationDate = $ExpiryDate
        Enabled               = $true
        ChangePasswordAtLogon = $true
        AccountPassword       = (ConvertTo-SecureString "Aura2025!" -AsPlainText -Force)
        OfficePhone           = $User.Telephone
        StreetAddress         = $User.Adresse
        City                  = $User.Ville
        PostalCode            = $User.CP
        Department            = $User.Service
        Office                = $User.Bureau
    }

    try {
        # Création du compte dans l'Active Directory
        New-ADUser @UserParams
        Write-Host "SUCCÈS : Compte créé pour $($User.Nom) $($User.Prenom) > $SAM" -ForegroundColor Green

        # 5. Ajout automatique au Groupe de Sécurité correspondant
        if (Get-ADGroup -Filter "Name -eq '$GroupName'") {
            Add-ADGroupMember -Identity $GroupName -Members $SAM
            Write-Host "  -> Utilisateur ajouté au groupe : $GroupName" -ForegroundColor Cyan
        } else {
            Write-Host "  -> ALERTE : Groupe [$GroupName] introuvable." -ForegroundColor Yellow
        }
    } catch {
        Write-Host "ERREUR : Impossible de créer $($User.Nom) $($User.Prenom) ($($_.Exception.Message))" -ForegroundColor Red
    }
} 

Le Déploiement Zero-Touch (FOG + Ansible)

Le déploiement manuel de Windows 11 et des logiciels requis monopolisait plusieures heures par poste. L’association de FOG Project et d’Ansible a permis de réduire cette intervention à 15 minutes, et ce, de manière totalement autonome.

  1. Boot Réseau (PXE) : Le service DHCP dnsmasq d’OPNsense oriente la machine vers le serveur FOG via le réseau. Une subtilité technique importante sur Proxmox : pour permettre le démarrage PXE en environnement UEFI, j’ai dû ajouter un périphérique matériel spécifique VirtIO RNG aux paramètres de la machine virtuelle.
  2. Déploiement de l’Image : FOG déploie un master Windows 11 préalablement généralisé par l’utilitaire sysprep. En amont de la capture, le service WinRM a été activé en PowerShell pour autoriser les futures requêtes entrantes d’Ansible.
  3. Le Cerveau Bash : À la fin du déploiement de l’image, le script post_deploy.sh s’exécute automatiquement. Il analyse l’adresse IP reçue par le poste : le troisième octet détermine le département de l’employé (par exemple, « 20 » correspond à l’IT), et la plage IP détermine le site géographique. Il rédige ensuite à la volée le fichier d’inventaire dynamique inventory.ini pour Ansible.
  4. Configuration Ansible : Le playbook final s’exécute sans intervention humaine. Il force la machine à changer de nom (par exemple, PC-IT-PAR-20), l’intègre au domaine Active Directory dans la bonne OU, puis déploie l’ensemble des paquets logiciels métiers en mode silencieux via le gestionnaire Chocolatey.
# filename:post_deploy.yml
- name: Configuration post-deploiement Windows 11
  hosts: nouveau_poste
  gather_facts: no

  vars_files:
    - vars/commun.yml
    - "vars/{{ service }}.yml"

  tasks:
    - name: Tester la connexion WinRM
      ansible.windows.win_ping:

    - name: Quitter le domaine si nécessaire
      microsoft.ad.membership:
        state: workgroup
        workgroup_name: WORKGROUP
        domain_admin_user: "aura\\Administrateur"
        domain_admin_password: "P@SSW0RD!"
      register: leave_result
      ignore_errors: yes

    - name: Redemarrer apres quitter domaine
      ansible.windows.win_reboot:
      when: leave_result.reboot_required is defined and leave_result.reboot_required

    - name: Renommer le poste
      ansible.windows.win_hostname:
        name: "{{ hostname }}"
      register: rename_result

    - name: Redemarrer apres renommage
      ansible.windows.win_reboot:
      when: rename_result.reboot_required

    - name: Joindre le domaine dans la bonne OU
      microsoft.ad.membership:
        dns_domain_name: aura.lan
        domain_admin_user: "aura\\Administrateur"
        domain_admin_password: "P@SSW0RD!"
        domain_ou_path: "{{ ou }}"
        state: domain
      register: domain_result

    - name: Redemarrer apres jonction domaine
      ansible.windows.win_reboot:
      when: domain_result.reboot_required

    - name: Installer logiciels communs
      chocolatey.chocolatey.win_chocolatey:
        name: "{{ logiciels_communs }}"
        state: present

    - name: Installer logiciels specifiques au service
      chocolatey.chocolatey.win_chocolatey:
        name: "{{ logiciels_service }}"
        state: present
      when: logiciels_service is defined
# filename:post_deploy.sh
#!/bin/bash

IP_POSTE="$1"
NOM_POSTE="$2"

# Détecter le site selon la plage IP
if [[ "$IP_POSTE" == 10.75.* ]]; then
    SITE="Paris"
    OU_BASE="OU=Ordinateurs,OU=Paris,OU=AURA,DC=aura,DC=lan"
elif [[ "$IP_POSTE" == 10.93.* ]]; then
    SITE="Villepinte"
    OU_BASE="OU=Ordinateurs,OU=Villepinte,OU=AURA,DC=aura,DC=lan"
else
    echo "[$(date)] Site inconnu pour $IP_POSTE = abandon" >> /var/log/fog_ansible.log
    exit 1
fi

# Détecter le service selon la vlan
TROISIEME_OCTET=$(echo $IP_POSTE | cut -d. -f3)
NUMERO=$(echo $IP_POSTE | cut -d. -f4)

case $TROISIEME_OCTET in
    20)
        SERVICE="IT"
        HOSTNAME="PC-IT-${SITE:0:3}-$NUMERO"
        ;;
    30)
        SERVICE="USERS"
        HOSTNAME="PC-USERS-${SITE:0:3}-$NUMERO"
        ;;
    35)
        SERVICE="COMPTA"
        HOSTNAME="PC-COMPTA-${SITE:0:3}-$NUMERO"
        ;;
    25)
        SERVICE="RH"
        HOSTNAME="PC-RH-${SITE:0:3}-$NUMERO"
        ;;
    *)
        echo "[$(date)] VLAN inconnu : $IP_POSTE — abandon" >> /var/log/fog_ansible.log
        exit 1
        ;;
esac

echo "[$(date)] Déploiement $HOSTNAME ($SERVICE - $SITE) détecté" >> /var/log/fog_ansible.log

# Générer l'inventaire dynamique
cat > /opt/fog/ansible/inventory.ini << EOF
[nouveau_poste]
$IP_POSTE

[nouveau_poste:vars]
ansible_user=Admin
ansible_password=NouveauMotDePasse!
ansible_connection=winrm
ansible_winrm_transport=basic
ansible_winrm_server_cert_validation=ignore
ansible_winrm_port=5985
ansible_winrm_scheme=http

EOF
#filename: ansible_software.yml lang: bash
adam@SRV-FOG-PARIS:~$ cat /opt/fog/ansible/vars/commun.yml
logiciels_communs:
  - googlechrome
  - 7zip
  - vlc
  - libreoffice


adam@SRV-FOG-PARIS:~$ cat /opt/fog/ansible/vars/IT.yml
logiciels_service:
  - putty
  - wireshark
  - vscode

5. Résilience Extrême : Haute Disponibilité et Backups (Proxmox & PBS)

L’infrastructure d’Aura se devait de résister à la perte critique d’un site complet.

Le Cluster Proxmox et le QDevice

L’architecture de calcul repose sur un cluster Proxmox de 6 nœuds hébergés de manière équitable sur les deux sites. La règle de l’hyperviseur exige qu’un quorum de N/2 + 1 nœuds soit actif pour fonctionner, ce qui correspond ici à 4 nœuds. Par conséquent, si le site de Paris subit une coupure d’électricité majeure, il ne reste que 3 nœuds actifs à Villepinte, et le cluster bascule en read-only.

Pour parer à cette éventualité, j’ai déployé un composant de vote supplémentaire, le QDevice (Quorum Device), hébergé sur un Raspberry Pi indépendant via la commande pvecm qdevice setup. Ce dernier, hébergé dans un troisième domaine (un cloud public, un VPS tiers ou un troisième site physique) disposant de liaisons réseau indépendantes vers Paris et Villepinte.
Lors de mes tests simulant la coupure de 3 nœuds consécutifs, le cluster a maintenu sa pleine fonctionnalité grâce à ce vote additionnel. Des règles de priorité de Haute Disponibilité (HA) sont configurées : en cas de panne matérielle d’un hôte, le mécanisme de « Failback » redémarre automatiquement (Failover) les machines virtuelles vers un hôte sain.

Afin de garantir la haute disponibilité, le stockage des machines virtuelles est décorrélé des hyperviseurs. Les données sont mutualisées sur des baies TrueNAS physiques (ZFS RAIDZ1) et partagées au cluster via le protocole NFS.

La Règle du 3-2-1 avec Proxmox Backup Server (PBS)

Pour esquiver les coûts massifs de licence par processeur de certaines solutions propriétaires, la stratégie de sauvegarde s’articule autour de deux instances de Proxmox Backup Server (PBS), une pour Paris et une pour Villepinte.

La sécurité des données est assurée par un contrôle strict des accès. Les cibles de sauvegarde NFS sur TrueNAS sont restreintes pour n’accepter que les adresses IP spécifiques des serveurs PBS. Pour garantir la pérennité du système, ces montages réseau ont été inscrits en dur dans le fichier système /etc/fstab des serveurs Linux.

Enfin, des tâches de synchronisation automatisées (Sync Jobs) ont été configurées entre les instances Proxmox Backup Server (PBS). Le serveur PBS de Villepinte réplique de façon programmée les données critiques du site de Paris, et réciproquement. Cette architecture valide strictement la règle d’or du 3-2-1 en matière de sauvegarde :

  • 3 copies des données : La copie de production active, la sauvegarde locale et la copie répliquée hors-site.
  • 2 supports de stockage distincts : La production s’exécute sur le stockage centralisé TrueNAS, tandis que les sauvegardes exploitent les disques locaux dédiés et indépendants des serveurs PBS.
  • 1 copie hors-site : Assurée par la réplication croisée et l’externalisation géographique des données entre les sites physiques de Paris et de Villepinte.

Le mot de la fin

Si je devais retenir une chose de ce projet « Aura », c’est qu’aujourd’hui, l’administration système ne se résume plus à cliquer dans des interfaces. Entre le déploiement Zero-Touch via FOG/Ansible et la mise en place d’une résilience poussée sous Proxmox, j’ai pu expérimenter l’IT moderne : automatisée, scalable et hautement disponible.

Obtenir mon titre TSSR n’est que la première étape. Je suis maintenant à la recherche de mon prochain défi professionnel pour mettre ma passion de l’optimisation au service d’une vraie DSI. Prêt à échanger ? Ma messagerie est ouverte ! 🤝