Contexte : Une PME souhaite filtrer les flux inter-VLAN avec un firewall (pfSense / FortiGate / iptables).
enable configure terminal ! vlan 10 name ADMIN ! vlan 20 name USERS ! vlan 30 name GUEST ! vlan 40 name DMZ ! interface fastEthernet 0/1 switchport mode access switchport access vlan 10 ! interface fastEthernet 0/2 switchport mode access switchport access vlan 20 ! interface fastEthernet 0/3 switchport mode access switchport access vlan 30 ! interface fastEthernet 0/4 switchport mode access switchport access vlan 40 ! interface fastEthernet 0/24 switchport mode trunk switchport trunk allowed vlan 10,20,30,40 switchport trunk native vlan 99 ! show vlan brief show interfaces trunk exit
| Source | Destination | Port | Action | Justification |
|---|---|---|---|---|
| VLAN 10 (ADMIN) | ✅ AUTORISÉ | Admin peut superviser les postes | ||
| VLAN 10 (ADMIN) | VLAN 30 (GUEST) | any | ❌ BLOQUÉ | Sécurité : admin ne doit pas contacter invités |
| VLAN 20 (USERS) | VLAN 10 (ADMIN) | any | ❌ BLOQUÉ | Les users ne touchent pas à l'admin |
| VLAN 20 (USERS) | VLAN 30 (GUEST) | any | ❌ BLOQUÉ | Isolation users/guest |
| VLAN 20 (USERS) | Internet | any | ✅ AUTORISÉ | Accès Internet normal |
| VLAN 30 (GUEST) | Interne (10.0.0.0/8) | any | ❌ BLOQUÉ | Guest ne voit pas l'interne |
| VLAN 30 (GUEST) | DMZ (VLAN 40) | 80,443 | ✅ AUTORISÉ | Accès au serveur web DMZ |
| VLAN 30 (GUEST) | Internet | 80,443 | ✅ AUTORISÉ | Navigateurs uniquement |
| VLAN 40 (DMZ) | VLAN 10 (ADMIN) | 22,3389 | ❌ BLOQUÉ | Accès admin via saut obligatoire |
# Via l'interface web : # Interfaces → Assignments → VLANs → Add # Parent interface: LAN, VLAN tag: 10, Description: ADMIN # Même chose pour VLAN 20 (USERS), VLAN 30 (GUEST), VLAN 40 (DMZ) # Assigner les interfaces VLAN : # Interfaces → Assignments → Add (pour chaque VLAN) # Interface VLAN 10: IP 10.0.10.254/24, Enable interface # Interface VLAN 20: IP 10.0.20.254/24, Enable interface # Interface VLAN 30: IP 10.0.30.254/24, Enable interface # Interface VLAN 40: IP 10.0.40.254/24, Enable interface
# Firewall → Rules → VLAN10 (ADMIN) # Règle 1: Allow ADMIN to USERS # Action: Pass, Protocol: any, Source: VLAN10 net, Destination: VLAN20 net # Règle 2: Block ADMIN to GUEST # Action: Block, Protocol: any, Source: VLAN10 net, Destination: VLAN30 net # Firewall → Rules → VLAN20 (USERS) # Règle 1: Block USERS to ADMIN # Action: Block, Protocol: any, Source: VLAN20 net, Destination: VLAN10 net # Règle 2: Allow USERS to Internet # Action: Pass, Protocol: any, Source: VLAN20 net, Destination: !LAN net # Firewall → Rules → VLAN30 (GUEST) # Règle 1: Block GUEST to Internal # Action: Block, Protocol: any, Source: VLAN30 net, Destination: 10.0.0.0/8 # Règle 2: Allow GUEST to DMZ Web # Action: Pass, Protocol: TCP, Source: VLAN30 net, Destination: VLAN40 net, Port: 80,443 # Règle 3: Allow GUEST to Internet # Action: Pass, Protocol: any, Source: VLAN30 net, Destination: !LAN net
config system interface
edit "VLAN10_ADMIN"
set vdom "root"
set interface "internal"
set vlanid 10
set ip 10.0.10.254 255.255.255.0
set allowaccess ping https ssh
next
edit "VLAN20_USERS"
set interface "internal"
set vlanid 20
set ip 10.0.20.254 255.255.255.0
next
edit "VLAN30_GUEST"
set interface "internal"
set vlanid 30
set ip 10.0.30.254 255.255.255.0
next
end
# Politiques firewall
config firewall policy
edit 1
set name "ADMIN_TO_USERS"
set srcintf "VLAN10_ADMIN"
set dstintf "VLAN20_USERS"
set srcaddr "all"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
next
edit 2
set name "BLOCK_USERS_TO_ADMIN"
set srcintf "VLAN20_USERS"
set dstintf "VLAN10_ADMIN"
set action deny
next
edit 3
set name "BLOCK_GUEST_TO_INTERNAL"
set srcintf "VLAN30_GUEST"
set dstintf "VLAN10_ADMIN" "VLAN20_USERS"
set action deny
next
end
# Interfaces → Other Types → VLAN # Parent: LAN, VLAN tag: 10, Description: ADMIN # VLAN tag: 20, Description: USERS # VLAN tag: 30, Description: GUEST # VLAN tag: 40, Description: DMZ # Assigner les IPs # Firewall → Rules → VLAN10 # Allow: Source VLAN10 net, Destination VLAN20 net # Firewall → Rules → VLAN20 # Block: Source VLAN20 net, Destination VLAN10 net # Allow: Source VLAN20 net, Destination any (Internet) # Firewall → Rules → VLAN30 # Block: Source VLAN30 net, Destination LAN net # Allow: Source VLAN30 net, Destination any, Port 80,443 (TCP)
# Activer le routage IP echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf sysctl -p # Règles iptables # Autoriser ADMIN → USERS iptables -A FORWARD -i vlan10 -o vlan20 -j ACCEPT # Bloquer USERS → ADMIN iptables -A FORWARD -i vlan20 -o vlan10 -j DROP # Bloquer GUEST → ADMIN iptables -A FORWARD -i vlan30 -d 10.0.10.0/24 -j DROP # Autoriser GUEST → DMZ (HTTP/HTTPS) iptables -A FORWARD -i vlan30 -o vlan40 -p tcp -m multiport --dports 80,443 -j ACCEPT # Bloquer GUEST → Interne iptables -A FORWARD -i vlan30 -d 10.0.0.0/8 -j DROP # Sauvegarder les règles iptables-save > /etc/iptables/rules.v4
# Client ADMIN (VLAN 10) IP: 10.0.10.10/24 Passerelle: 10.0.10.254 DNS: 8.8.8.8 # Client USERS (VLAN 20) IP: 10.0.20.10/24 Passerelle: 10.0.20.254 DNS: 8.8.8.8 # Client GUEST (VLAN 30) IP: 10.0.30.10/24 Passerelle: 10.0.30.254 DNS: 8.8.8.8 # Serveur DMZ (VLAN 40) IP: 10.0.40.10/24 Passerelle: 10.0.40.254 # Installer un serveur web : sudo apt install apache2 -y
Ces livrables servent à valider et documenter une configuration exploitable en PME. Cliquez sur chaque bouton pour copier le contenu.
Topologie pfSense + switch L3 + 4 VLANs. À importer via File → Import portable project.
{
"name": "TP_Firewall_VLANs",
"version": "2.2.0",
"topology": {
"nodes": [
{"node_id": "sw1", "name": "Switch_VLAN", "node_type": "ethernet_switch", "x": 0, "y": 200, "properties": {"ethernet_ports": 24}},
{"node_id": "fw", "name": "pfSense_Firewall", "node_type": "qemu", "x": 400, "y": 200, "properties": {"image": "pfSense-2.6.0.iso", "ram": 1024}},
{"node_id": "pc1", "name": "PC_ADMIN", "node_type": "vpcs", "x": -150, "y": 100, "properties": {"script": "ip 10.0.10.10/24 10.0.10.254"}},
{"node_id": "pc2", "name": "PC_USERS", "node_type": "vpcs", "x": -150, "y": 200, "properties": {"script": "ip 10.0.20.10/24 10.0.20.254"}},
{"node_id": "pc3", "name": "PC_GUEST", "node_type": "vpcs", "x": -150, "y": 300, "properties": {"script": "ip 10.0.30.10/24 10.0.30.254"}},
{"node_id": "pc4", "name": "DMZ_Server", "node_type": "vpcs", "x": 200, "y": 350, "properties": {"script": "ip 10.0.40.10/24 10.0.40.254"}}
],
"links": [
{"nodes": [{"node_id": "pc1","port":0},{"node_id": "sw1","adapter":0,"port":1}]},
{"nodes": [{"node_id": "pc2","port":0},{"node_id": "sw1","adapter":0,"port":2}]},
{"nodes": [{"node_id": "pc3","port":0},{"node_id": "sw1","adapter":0,"port":3}]},
{"nodes": [{"node_id": "pc4","port":0},{"node_id": "sw1","adapter":0,"port":4}]},
{"nodes": [{"node_id": "sw1","adapter":0,"port":24},{"node_id": "fw","adapter":0,"port":0}]}
]
}
}
Testeur automatique des règles firewall (ping/tcp, génération rapport HTML).
Installation : pip install colorama
Utilisation : python3 firewall_tester.py --menu
#!/usr/bin/env python3
# firewall_tester.py - Testeur de règles firewall
import subprocess, sys, argparse
from datetime import datetime
try:
from colorama import init, Fore, Style
init()
except:
class Fore: RED=GREEN=YELLOW=CYAN=RESET=''
class FirewallTester:
def __init__(self):
self.results = []
self.config = {
"tests": [
{"src": "10.0.10.10", "src_name": "ADMIN", "dst": "10.0.20.10", "dst_name": "USERS", "expected": "ALLOW"},
{"src": "10.0.10.10", "src_name": "ADMIN", "dst": "10.0.30.10", "dst_name": "GUEST", "expected": "BLOCK"},
{"src": "10.0.20.10", "src_name": "USERS", "dst": "10.0.10.10", "dst_name": "ADMIN", "expected": "BLOCK"},
{"src": "10.0.30.10", "src_name": "GUEST", "dst": "10.0.10.10", "dst_name": "ADMIN", "expected": "BLOCK"},
{"src": "10.0.30.10", "src_name": "GUEST", "dst": "10.0.40.10", "dst_name": "DMZ", "port": 80, "expected": "ALLOW"},
{"src": "10.0.30.10", "src_name": "GUEST", "dst": "8.8.8.8", "dst_name": "INTERNET", "expected": "ALLOW"}
]
}
def ping(self, ip):
param = '-n' if sys.platform.lower().startswith('win') else '-c'
try:
r = subprocess.run(['ping', param, '2', '-W', '2', ip], capture_output=True)
return r.returncode == 0
except:
return False
def test_tcp(self, ip, port):
try:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
s.connect((ip, port))
s.close()
return True
except:
return False
def run(self):
print(f"{Fore.CYAN}🔍 Test des règles firewall...{Fore.RESET}\n")
for t in self.config["tests"]:
if "port" in t:
result = self.test_tcp(t["dst"], t["port"])
else:
result = self.ping(t["dst"])
passed = (result and t["expected"]=="ALLOW") or (not result and t["expected"]=="BLOCK")
self.results.append({**t, "actual": "ALLOW" if result else "BLOCK", "passed": passed})
status = f"{Fore.GREEN}✓{Fore.RESET}" if passed else f"{Fore.RED}✗{Fore.RESET}"
print(f"{status} {t['src_name']} → {t['dst_name']}: attendu={t['expected']} réel={self.results[-1]['actual']}")
return self.results
def html_report(self, filename="firewall_report.html"):
passed = sum(1 for r in self.results if r['passed'])
total = len(self.results)
score = (passed/total)*100 if total>0 else 0
html = f"""TP 2 — Firewall & filtrage inter‑VLAN | CyberRéseau Pro
📊 Rapport Firewall
Date: {datetime.now()}
Score: {score:.1f}% ({passed}/{total})
| Source | Destination | Attendu | Réel | Statut |
|---|---|---|---|---|
| {r['src_name']} | {r['dst_name']} | {r['expected']} | {r['actual']} | " html += f"{'✅ OK' if r['passed'] else '❌ ÉCHEC'} |
Généré par Firewall Tester | CyberRéseau Pro
" with open(filename, 'w', encoding='utf-8') as f: f.write(html) print(f"{Fore.GREEN}📄 Rapport généré: {filename}{Fore.RESET}") def menu(self): while True: print(f"\n{Fore.CYAN}════════════════════════════════════════╗{Fore.RESET}") print(f"{Fore.CYAN} TESTEUR FIREWALL{Fore.RESET}") print(f"{Fore.CYAN}════════════════════════════════════════╝{Fore.RESET}") print("1. 🔍 Lancer les tests") print("2. 📄 Générer rapport HTML") print("3. 🚪 Quitter") choice = input(f"{Fore.YELLOW}Votre choix : {Fore.RESET}") if choice == '1': self.run() elif choice == '2': if self.results: self.html_report() else: print("Lancez d'abord les tests") elif choice == '3': break if __name__ == "__main__": tester = FirewallTester() if len(sys.argv) > 1 and '--menu' in sys.argv: tester.menu() else: tester.run() tester.html_report()Diagnostic automatique des règles firewall, logs et connectivité.
Utilisation : chmod +x diagnostic_firewall.sh && ./diagnostic_firewall.sh --all
#!/bin/bash
RAPPORT="firewall_diag_$(date +%Y%m%d_%H%M%S).txt"
GREEN='\033[0;32m'; RED='\033[0;31m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
log() { echo -e "$1" | tee -a "$RAPPORT"; }
log_header() { echo ""; log "${CYAN}═══════════════════════════════════════${NC}"; log "$1"; log "${CYAN}═══════════════════════════════════════${NC}"; }
check_iptables() {
log_header "Règles iptables"
iptables -L -v -n | tee -a "$RAPPORT"
log "\n--- Règles NAT ---"
iptables -t nat -L -v -n | tee -a "$RAPPORT"
}
test_rules() {
log_header "Tests de connectivité"
local tests=(
"ADMIN:10.0.10.10:USERS:10.0.20.10:ALLOW"
"ADMIN:10.0.10.10:GUEST:10.0.30.10:BLOCK"
"USERS:10.0.20.10:ADMIN:10.0.10.10:BLOCK"
"GUEST:10.0.30.10:ADMIN:10.0.10.10:BLOCK"
"GUEST:10.0.30.10:DMZ:10.0.40.10:ALLOW"
"GUEST:10.0.30.10:INTERNET:8.8.8.8:ALLOW"
)
for test in "${tests[@]}"; do
IFS=':' read -r src_name src_ip dst_name dst_ip expected <<< "$test"
if ping -c 1 -W 1 "$dst_ip" &>/dev/null; then
actual="ALLOW"
else
actual="BLOCK"
fi
if [ "$actual" = "$expected" ]; then
log "${GREEN}✓ $src_name → $dst_name: $actual (attendu: $expected)${NC}"
else
log "${RED}✗ $src_name → $dst_name: $actual (attendu: $expected)${NC}"
fi
done
}
checklist() {
log_header "CHECKLIST FIREWALL"
cat >> "$RAPPORT" << 'EOF'
□ 1. VLANs créés sur le switch (show vlan brief)
□ 2. Ports dans les bons VLANs
□ 3. Trunk vers firewall configuré
□ 4. Interfaces VLAN créées sur le firewall
□ 5. IPs des VLANs configurées
□ 6. Règles de filtrage définies dans le bon ordre
□ 7. Routage inter-VLAN activé
□ 8. Tests de connectivité intra-VLAN OK
□ 9. Tests inter-VLAN conformes aux règles
□ 10. Logs firewall actifs et consultables
EOF
cat "$RAPPORT" | tail -15
}
auto_mode() {
log_header "DIAGNOSTIC FIREWALL AUTOMATIQUE"
check_iptables
test_rules
checklist
echo -e "${GREEN}✓ Rapport sauvegardé: $RAPPORT${NC}"
}
show_menu() {
echo ""; echo -e "${CYAN}═══════════════════════════════════════${NC}"
echo -e " DIAGNOSTIC FIREWALL"
echo -e "${CYAN}═══════════════════════════════════════${NC}"
echo "1. 🔍 Diagnostic complet"
echo "2. 🔥 Vérifier règles iptables"
echo "3. 🌐 Tester la connectivité"
echo "4. 📋 Afficher checklist"
echo "5. 🚪 Quitter"
echo -n "Votre choix : "
}
if [ "$1" == "--all" ] || [ "$1" == "-a" ]; then
auto_mode
else
while true; do
show_menu; read choice
case $choice in
1) auto_mode ;;
2) check_iptables | tee -a "$RAPPORT" ;;
3) test_rules | tee -a "$RAPPORT" ;;
4) checklist ;;
5) echo -e "${GREEN}Au revoir !${NC}"; exit 0 ;;
*) echo -e "${RED}Choix invalide${NC}" ;;
esac
done
fi
# 1. Rendre les scripts exécutables
chmod +x firewall_tester.py
chmod +x diagnostic_firewall.sh
# 2. Installer les dépendances Python
pip3 install colorama
# 3. Lancer le test interactif
python3 firewall_tester.py --menu
# 4. Lancer le diagnostic bash
./diagnostic_firewall.sh --all
# 5. Pour pfSense: vérifier les logs
# Status → System Logs → Firewall
# 6. Pour iptables: suivre les logs en temps réel
tail -f /var/log/kern.log | grep DPT
| Erreur | Pourquoi ? | Solution |
|---|---|---|
| Ping inter-VLAN fonctionne alors que règle blocage active | Ordre des règles (pass avant block) | Vérifier l'ordre et placer les blocages avant les passes |
| pfSense ne route pas inter-VLAN | Règle "Default allow LAN to any" absente ou trop restrictive | Ajouter règle pass sur l'interface LAN |
| Clients n'ont pas d'IP | DHCP non configuré ou VLAN mal assigné | Configurer serveur DHCP sur chaque interface VLAN |
| Trunk ne passe pas les VLANs | Allowed vlan trop restrictif | switchport trunk allowed vlan add 10,20,30,40 |
| Règle iptables non persistante | Non sauvegardée | iptables-save > /etc/iptables/rules.v4 |
| # | Source | Destination | Résultat attendu | Commande de test |
|---|---|---|---|---|
| 1 | ADMIN (10.0.10.10) | USERS (10.0.20.10) | ✅ SUCCÈS | ping 10.0.20.10 |
| 2 | ADMIN (10.0.10.10) | GUEST (10.0.30.10) | ❌ ÉCHEC | ping 10.0.30.10 |
| 3 | USERS (10.0.20.10) | ADMIN (10.0.10.10) | ❌ ÉCHEC | ping 10.0.10.10 |
| 4 | GUEST (10.0.30.10) | ADMIN (10.0.10.10) | ❌ ÉCHEC | ping 10.0.10.10 |
| 5 | GUEST (10.0.30.10) | DMZ (10.0.40.10) port 80 | ✅ SUCCÈS | curl http://10.0.40.10 |
| 6 | GUEST (10.0.30.10) | DMZ port 22 (SSH) | ❌ ÉCHEC | nc -zv 10.0.40.10 22 |
| 7 | GUEST (10.0.30.10) | Internet (8.8.8.8) | ✅ SUCCÈS | ping 8.8.8.8 |
| 8 | USERS (10.0.20.10) | Internet (8.8.8.8) | ✅ SUCCÈS | ping 8.8.8.8 |
# pfSense Interfaces → Assignments → VLANs # Vérifier que chaque VLAN a une IP assignée # FortiGate get system interface physical show system interface # iptables ip link show | grep vlan ip addr show vlan10
# pfSense - afficher les règles avec leur ordre Firewall → Rules → VLAN10 # Les règles sont exécutées de haut en bas. # Mettre les blocages AVANT les passes. # iptables - voir l'ordre iptables -L FORWARD --line-numbers # Reorder iptables iptables -I FORWARD 2 -i vlan20 -o vlan10 -j DROP
# Sur pfSense tcpdump -i vlan10 -n host 10.0.10.10 # Sur Linux tcpdump -i vlan10 -n icmp # Sur FortiGate diagnose debug flow filter addr 10.0.10.10 diagnose debug enable
#!/bin/bash
echo "=== DIAGNOSTIC FIREWALL RAPIDE ==="
echo "1. Interfaces VLAN"
ip link show | grep vlan
echo "2. Routes"
ip route show
echo "3. Règles iptables"
iptables -L FORWARD -v -n
echo "4. Tests de ping"
for dst in 10.0.20.10 10.0.30.10 8.8.8.8; do
ping -c 1 -W 1 $dst &>/dev/null && echo "✅ $dst OK" || echo "❌ $dst KO"
done
echo "=== Diagnostic terminé ==="
Ces liens correspondent au matériel utile pour reproduire ce TP en conditions réelles.
🔗 Liens affiliés Amazon — aucun surcoût pour vous.
Ce module fait partie du Pack TP Sécurité Réseau : VLAN, firewall, VPN, Wi‑Fi sécurisé et 802.1X. L’objectif est de passer d’une configuration isolée à une démarche complète de sécurisation PME.
Voir tout le Pack TP Télécharger le guide gratuitAvant de considérer ce module comme exploitable, vérifiez les points suivants :
Ce module fait partie du Pack TP Sécurité Réseau PME. Remplacez le lien ci-dessous par votre lien Gumroad après publication.
Acheter / télécharger le pack Voir la page du pack