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.
Dans l'interface web Proxmox (https://IP-proxmox:8006) :
# 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 vmbr2Info : 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.
Maintenant que le bridge existe dans Proxmox, il faut ajouter une carte réseau virtuelle sur chaque VM PFSense, connectee a ce bridge.
Dans Proxmox, sélectionner la VM PFSense 1 :
Note : Ne pas démarrer les VMs tout de suite. Configurer les deux PFSense d'abord, puis démarrer.
Démarrer PFSense 1 et se connecter a son interface web :
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.
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.
Se connecter a l'interface web de PFSense 1 :
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.
Pour que la configuration DMZ soit automatiquement synchronisée vers PFSense 2 :
Info : Apres la synchronisation, les règles firewall créées sur PFSense 1 seront automatiquement répliquées sur PFSense 2.
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.
| 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 |
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.
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 |
| 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 |
| 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.
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.
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
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
http://192.168.0.1:81admin@example.com / changeme
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.
Dans NPM > SSL Certificates > Add SSL Certificate > Custom :
Info : Un certificat wildcard (*.ton-domaine.local) signé par l'AD CS couvre tous tes sous-domaines en une seule entrée.
Aller dans hôtes > Proxy host puis ajouter un hôte proxy
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 |
sysctl net.ipv4.ip_forward
nano /usr/lib/sysctl.d/50-default.conf
net.ipv4.ip_forward=1
sysctl -p /usr/lib/sysctl.d/50-default.conf
sysctl net.ipv4.ip_forward
apt install iptables iptables-persistent -y
ip addr show
iptables -F
iptables -t nat -F
iptables -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
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
netfilter-persistent save
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.
ping 192.168.1.11 # Nextcloud — doit répondre
ping 192.168.1.12 # Portfolio — doit répondre
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)
ping 192.168.0.10 # NPM — NE DOIT PAS répondre depuis 10.0.20.x
ping 172.30.10.16 # ERP — NE DOIT PAS répondre
nc -zv 192.168.0.10 80
nc -zv 192.168.0.10 443
nslookup nextcloud.ton-domaine.local
curl -k https://nextcloud.cbaudiment.fr
curl -k https://portfolio.cbaudiment.fr
docker logs nginx-proxy-manager