MISE EN PLACE D'UNE DMZ
Préparation dans Proxmox — création du bridge DMZ

Toutes les interfaces réseau des VMs sur Proxmox passent par des bridges Linux (vmbr). Il faut créer un bridge dedie a la DMZ sur chaque noeud Proxmox.

Créer le bridge vmbr-dmz sur chaque noeud Proxmox

Dans l'interface web Proxmox (https://IP-proxmox:8006) :

  • Aller dans le noeud Proxmox > System > Network
  • Cliquer sur Create > Linux Bridge
  • Renseigner les paramètres suivants :
    • Name : vmbr2 (ou vmbr-dmz selon la convention)
    • IPv4/CIDR : Laisser vide (pas d'IP sur le bridge Proxmox lui-meme)
    • Bridge ports : Laisser vide (bridge interne, pas connecté à une carte physique)
    • VLAN aware : Non
    • Comment : DMZ Network 192.168.0.0/24
  • Cliquer sur 'Create' puis 'Apply Configuration'
Vérification depuis le shell Proxmox
  • # Vérifier que le bridge est bien créé
    ip link show vmbr2
    # Vérifier la configuration réseau complète
    cat /etc/network/interfaces | grep -A5 vmbr2
  • Info : Le bridge DMZ est purement interne a Proxmox. Il n'est pas connecté à une carte réseau physique — c'est intentionnel. Seuls les PFSense et les VMs DMZ y sont connectes.

Ajout de l'interface DMZ sur les deux PFSense

Maintenant que le bridge existe dans Proxmox, il faut ajouter une carte réseau virtuelle sur chaque VM PFSense, connectee a ce bridge.

Ajouter la carte reseau sur PFSense 1

    Dans Proxmox, sélectionner la VM PFSense 1 :

  • Aller dans l'onglet 'Hardware' de la VM PFSense 1
  • Cliquer sur 'Add' > 'Network Device'
  • Configurer comme suit :
    • Bridge : vmbr2 (le bridge DMZ crée précédemment)
    • Model : VirtIO (para-virtualized) — meilleures performances
    • VLAN Tag : Vide (pas de tag VLAN)
    • Firewall : Décocher (PFSense gère lui-même son firewall)
  • Cliquer sur 'Add'
  • Répéter exactement la même opération sur la VM PFSense 2
  • Note : Ne pas démarrer les VMs tout de suite. Configurer les deux PFSense d'abord, puis démarrer.

Assigner l'interface dans PFSense

Démarrer PFSense 1 et se connecter a son interface web :

  • Aller dans Interfaces > Assignments
  • Dans la liste des interfaces disponibles, la nouvelle carte (vtnet2 ou em2 selon le modele) doit apparaitre
  • Cliquer sur 'Add' pour l'assigner — elle s'appellera OPT1 par défaut
  • Cliquer sur OPT1 pour la configurer :
    • Enable : Cocher 'Enable interface'
    • Description : DMZ
    • IPv4 Configuration Type : Static IPv4
    • IPv4 Address : 192.168.0.252 / 24
    • IPv6 : None
    • Block private networks : Décocher (réseau privé intentionnel)
    • Block bogon networks : Décocher
  • Cliquer sur 'Save' puis 'Apply Changes'
  • Répéter sur PFSense 2 avec l'IP 192.168.0.253 / 24
  • Info : Sur PFSense 2, utiliser l'IP 192.168.0.253. L'IP virtuelle CARP 192.168.0.254 sera configurée a l'étape suivante.

Configuration CARP sur l'interface DMZ

Pour que la haute disponibilité fonctionne sur la DMZ comme sur le LAN et le WAN, il faut creer une IP virtuelle CARP sur l'interface DMZ. C'est cette IP (10.0.10.254) qui servira de passerelle par défaut pour toutes les VMs en DMZ.

Créer l'IP virtuelle CARP sur PFSense 1

Se connecter a l'interface web de PFSense 1 :

  • Aller dans Firewall > Virtual IPs
  • Cliquer sur 'Add'
  • Renseigner les parametres :
    • Type : CARP
    • Interface : DMZ
    • IP Address(es) : 192.168.0.254 / 24
    • Virtual IP Password : Choisir un mot de passe (identique sur les 2 PFSense)
    • VHID Group : Choisir un numero libre (ex: 3 si 1 et 2 sont pris par WAN et LAN)
    • Advertising Frequency : Base: 1 / Skew: 0 (PFSense 1 = maitre)
    • Description : CARP DMZ
  • Cliquer sur 'Save' puis 'Apply Changes'
Créer l'IP virtuelle CARP sur PFSense 2
  • Se connecter à l'interface web de PFSense 2 et créer la même IP virtuelle avec une différence :
    • Type : CARP
    • Interface : DMZ
    • IP Address(es) : 192.168.0.254 / 24
    • Virtual IP Password : Même mot de passe que PFSense 1
    • VHID Group : Même numéro que PFSense 1 (ex: 3)
    • Advertising Frequency : Base: 1 / Skew: 100 (PFSense 2 = esclave)
    • Description : CARP DMZ
  • Cliquer sur 'Save' puis 'Apply Changes'
Vérifier la configuration du CARP
  • Sur PFSense, aller dans Status > CARP (failover). on doit voir :
    • Interface DMZ — 192.168.0.254 — MASTER (sur PFSense 1)
    • Interface DMZ — 192.168.0.254 — BACKUP (sur PFSense 2)
  • Note : Si les deux PFSense affichent MASTER, c'est un problème de communication PFSync ou de mot de passe CARP différent. Vérifier que l'interface PFSync fonctionne bien.

Synchronisation de la configuration (XMLSync)

Pour que la configuration DMZ soit automatiquement synchronisée vers PFSense 2 :

  • Sur PFSense 1, aller dans System > High Availability Sync
  • Vérifier que 'Synchronize rules' et 'Synchronize Virtual IPs' sont bien coches
  • Cliquer sur 'Save' — PFSense 1 va pousser la config vers PFSense 2

Info : Apres la synchronisation, les règles firewall créées sur PFSense 1 seront automatiquement répliquées sur PFSense 2.

Configuration des règles firewall DMZ

Principe général : tout est bloqué par défaut, on n'ouvre que ce qui est strictement nécessaire. Les règles sont appliquées de haut en bas dans PFSense — la première règle qui correspond s'applique.

Interface WAN — accès entrant
Action Protocole Source Port Destination Port Description
Pass IPV4 TCP any any WAN Address 80 HTTP vers NGinx
Pass IPV4 TCP any any WAN Address 443 HTTPS vers NGinx
NAT Port Forward

Firewall > NAT > Port Forward — créer deux règles :

Action Interface Protocole Source Port Destination Port NAT IP NAT Port Description
Pass WAN TCP any any WAN Address 192.168.0.1 80 HTTP -> NGinx
Pass WAN TCP any any WAN Address 192.168.0.1 80 HTTP -> NGinx

Note : Cocher 'Add associated filter rule' lors de la creation — la regle WAN correspondante sera creee automatiquement.

Interface DMZ

Ces règles controlent tout ce qui sort de la DMZ (publique et privée) vers l'extérieur. PFSense voit les deux sous-réseaux sur cette interface.

Action Protocole Source Port Destination Port Description
Block IPV4 any any any This Firewall any Bloquer accès PFSense
Pass IPV4 TCP 192.168.0.1 any 182.168.1.11 443 NGinx -> Nextcloud
Pass IPV4 UDP 192.168.1.11 any 172.30.10.11 53 Nextcloud -> DNS
Pass IPV4 UDP 192.168.1.11 any 172.30.20.10 53 Nextcloud -> DNS
Block IPV4 any any any any any Bloquer tout le reste
Interface LAN/VLANs — acces internes
Action Protocole Source Port Destination Port Description
Pass IPV4 TCP VLANs any 192.168.0.1 443 Accès pages web DMZ
Block IPV4 any VLANs any DMZ net any Bloquer le reste
Interface VLAN Admin — administration SSH via Guacamole
Action Protocole Source Port Destination Port Description
Pass IPV4 TCP 172.30.99.2 any any 22 Accès SSH via Guacamole
Block IPV4 any VLAN 99 net any DMZ net any Bloquer le reste

Note : La règle de blocage doit être en dernière position. PFSense lit les règles de haut en bas — la première qui correspond s'applique.

Installation et configuration de Nginx Proxy Manager

NPM est déployé via Docker sur la VM 192.168.0.1. Il centralise toutes les entrées HTTPS et redistribue vers les serveurs de la DMZ privée selon le nom de domaine.

Installation de Docker sur la VM NPM
apt update && apt install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo 'deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable' | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
systemctl enable docker && systemctl start docker
docker --version && docker compose version
Déploiement de NPM
mkdir -p /opt/nginx-proxy-manager
cd /opt/nginx-proxy-manager
nano docker-compose.yml

Contenu du fichier docker-compose.yml :

services:
	app:
		image: jc21/nginx-proxy-manager:latest
		container_name: nginx-proxy-manager
		restart: unless-stopped
		ports:
			- '80:80'
			- '443:443'
			- '81:81'
		volumes:
			- ./data:/data
			- ./letsencrypt:/etc/letsencrypt
		environment:
			DB_SQLITE_FILE: /data/database.sqlite
docker compose up -d
docker ps
docker logs nginx-proxy-manager
Première connexion et sécurisation
  • Depuis un poste du VLAN Admin, accéder à http://192.168.0.1:81
  • Identifiants par défaut : admin@example.com / changeme
  • Changer immédiatement l'email et le mot de passe administrateur
  • Attention : Le port 81 (interface admin NPM) ne doit jamais être exposé sur Internet. La règle PFSense bloque déjà tout accès WAN vers ce port.

Importer le certificat AD CS

Dans NPM > SSL Certificates > Add SSL Certificate > Custom :

  • Certificate Key : Contenu de nextcloud.key (clé privée)
  • Certificate : Contenu du certificat signé par l'AD CS
  • CA Bundle : Contenu du certificat CA racine (ca.crt)
  • Info : Un certificat wildcard (*.ton-domaine.local) signé par l'AD CS couvre tous tes sous-domaines en une seule entrée.

Créer les Proxy Hosts

Nextcloud :

Aller dans hôtes > Proxy host puis ajouter un hôte proxy

  • Domain Names : nextcloud.ton-domaine.local
  • Scheme : https
  • Forward Hostname / IP : 192.168.1.11
  • Forward Port :443
  • Websockets Support : Activer (requis pour Nextcloud)
  • Block Common Exploits : Activer
  • SSL Certificate : Certificat AD CS importé
  • Force SSL : Activer
  • HTTP/2 Support : Activer

Serveur web :

  • Domain Names : portfolio.ton-domaine.local
  • Scheme : https
  • Forward Hostname / IP : 192.168.1.12
  • Forward Port :443
  • Websockets Support : Activer
  • Block Common Exploits : Activer
  • SSL Certificate : Certificat AD CS importé
  • Force SSL : Activer
  • HTTP/2 Support : Activer
Enregistrements DNS dans l'AD

Sur le serveur Windows AD (172.30.10.11), Gestionnaire DNS > Zones de recherche directe > cbaudiment.fr :

Nom Type IP Description
nextcloud A 192.168.0.1 Pointe vers NPM
portfolio A 192.168.0.1 Pointe vers NPM
nginx A 192.168.0.1 Pointe vers NPM
Activation du routage

Activation du routage IP :

  • Vérification de la ligne existante
    sysctl net.ipv4.ip_forward
  • i la le retour de commande est net.ipv4.ip_forward = 0, rajouter la ligne
    nano /usr/lib/sysctl.d/50-default.conf
  • Rajouter la ligne à la fin du fichier
    net.ipv4.ip_forward=1
  • Activer les changements :
    sysctl -p /usr/lib/sysctl.d/50-default.conf
  • Vérification :
    sysctl net.ipv4.ip_forward

Configuration d'iptables pour le NAT

  • Installation d'iptables
    apt install iptables iptables-persistent -y
  • Vérification de votre interface réseau LAN
    ip addr show
  • Note : Généralement ens33 ou eth0
  • Nettoyage des règles existantes pour éviter les conflits
    iptables -F
    iptables -t nat -F
    iptables -X
  • Configuration des politiques par défaut (tout accepter)
    iptables -P INPUT ACCEPT
    iptables -P FORWARD ACCEPT
    iptables -P OUTPUT ACCEPT
  • Ajout des règles NAT pour le VPN
  • IMPORTANT : Remplacez ens18 par le nom de l'interface si différente
    iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ens18 -j MASQUERADE
    iptables -A FORWARD -s 192.168.1.0/24 -j ACCEPT
    iptables -A FORWARD -d 192.168.1.0/24 -m state --state RELATED,ESTABLISHED -j ACCEPT
  • Sauvegarde des règles pour persistance au redémarrage
    netfilter-persistent save
  • Répondre "Yes" aux questions
  • Vérification des règles
    iptables -t nat -L -v -n
    iptables -L FORWARD -v -n
  • Erreur — Les ports 80/443/81 de NPM ne sont plus exposés après activation d'iptables
    Cause : conflit entre les règles iptables manuelles et celles de Docker au démarrage.

    Solution :

    cd /opt/nginx-proxy-manager
    docker compose down
    docker compose up -d

    Vérifier que les ports sont bien exposés :

    docker ps --format "table {{.Names}}\t{{.Ports}}\t{{.Status}}"
    ss -tlnp | grep -E '80|443|81'

    Erreur — Mauvaise interface dans la règle MASQUERADE
    Le MASQUERADE doit impérativement se faire sur ens18 (interface côté PFSense/DMZ publique) et non sur ens19 (interface côté DMZ privée). Une règle sur ens19 ne fonctionnera pas et Nextcloud restera inaccessible depuis les VLANs internes.

Tests et validation
Tests de connectivité réseau
  • Depuis NPM (192.168.0.1) — tester la DMZ privée
    ping 192.168.1.11   # Nextcloud — doit répondre
    ping 192.168.1.12   # Portfolio — doit répondre
  • Depuis Nextcloud (192.168.1.11) — tester les serveurs internes
    nc -zv 172.30.10.11 389   # LDAP vers AD — doit réussir
    nc -zv 172.30.10.13 445   # SMB vers fichiers — doit réussir
    ping 172.30.10.12          # GLPI — NE DOIT PAS répondre (isolation)
Test d'isolation DMZ
  • Depuis un serveur DMZ privée, tenter d'accéder à la DMZ publique directement
  • Ce flux doit être bloqué par PFSense (règle de blocage DMZ pub -> DMZ priv)
    ping 192.168.0.10   # NPM — NE DOIT PAS répondre depuis 10.0.20.x
  • Tenter d'accéder à un serveur interne non autorisé
    ping 172.30.10.16  # ERP — NE DOIT PAS répondre
Test NPM et accès HTTPS
  • Tester que NPM répond bien
    nc -zv 192.168.0.10 80
    nc -zv 192.168.0.10 443
  • Tester la résolution DNS depuis un poste du domaine
    nslookup nextcloud.ton-domaine.local
  • Doit retourner 192.168.0.10
  • Tester l'accès via NPM
    curl -k https://nextcloud.cbaudiment.fr
    curl -k https://portfolio.cbaudiment.fr
Test du basculement CARP
  • Lancer un ping continu depuis une VM DMZ : ping -c 100 8.8.8.8
  • Éteindre PFSense 1 (le maître)
  • PFSense 2 doit prendre le relais en 2-3 secondes (pertes minimales)
  • Rallumer PFSense 1 — il reprend le rôle MASTER automatiquement
Test de l'administration Guacamole
  • Se connecter à Guacamole depuis le PC Admin
  • Lancer une connexion SSH vers NPM (192.168.0.10)
  • Lancer une connexion SSH vers Nextcloud (192.168.1.11)
  • Vérifier que les connexions s'établissent correctement
  • Tenter une connexion SSH depuis un autre poste (non admin) — doit échouer
Test depuis Internet
  • Depuis un smartphone en 4G ou réseau externe
  • Accéder à https://nextcloud.cbaudiment.fr (si domaine public configuré)
  • Le certificat AD CS doit être reconnu sur les postes du domaine
  • Se connecter avec un compte AD — doit fonctionner
Vérification des logs
  • Logs NPM
    docker logs nginx-proxy-manager
  • Logs Apache PFSense
  • Status > System Logs > Firewall dans l'interface PFSense
  • Verifier que les regles bloquantes fonctionnent :
  • Les tentatives bloquees doivent apparaitre dans les logs firewall PFSense