2.7. Exemple : Protection d'un réseau local et d'une zone démilitarisée à l'aide d'un script nftables
Utilisez le framework nftables
sur un routeur RHEL pour écrire et installer un script de pare-feu qui protège les clients d'un réseau local interne et un serveur web dans une zone démilitarisée (DMZ) contre les accès non autorisés provenant d'Internet et d'autres réseaux.
Cet exemple n'est donné qu'à titre de démonstration et décrit un scénario avec des exigences spécifiques.
Les scripts de pare-feu dépendent fortement de l'infrastructure du réseau et des exigences en matière de sécurité. Utilisez cet exemple pour apprendre les concepts des pare-feu nftables
lorsque vous écrivez des scripts pour votre propre environnement.
2.7.1. Conditions du réseau
Le réseau de cet exemple présente les conditions suivantes :
Le routeur est connecté aux réseaux suivants :
-
L'Internet par l'interface
enp1s0
-
L'interface interne du réseau local (LAN)
enp7s0
-
La DMZ à travers
enp8s0
-
L'Internet par l'interface
-
L'interface Internet du routeur dispose d'une adresse IPv4 statique (
203.0.113.1
) et d'une adresse IPv6 (2001:db8:a::1
). -
Les clients du réseau local interne utilisent uniquement des adresses IPv4 privées de la plage
10.0.0.0/24
. Par conséquent, le trafic entre le réseau local et l'internet nécessite une traduction de l'adresse du réseau source (SNAT). -
Les PC administrateurs du réseau local interne utilisent les adresses IP
10.0.0.100
et10.0.0.200
. -
La zone démilitarisée utilise les adresses IP publiques des plages
198.51.100.0/24
et2001:db8:b::/56
. -
Le serveur web de la zone démilitarisée utilise les adresses IP
198.51.100.5
et2001:db8:b::5
. - Le routeur fait office de serveur DNS de cache pour les hôtes du réseau local et de la zone démilitarisée.
2.7.2. Exigences de sécurité pour le script du pare-feu
Voici les conditions requises pour le pare-feu nftables
dans l'exemple de réseau :
Le routeur doit pouvoir
- Résoudre de manière récursive les requêtes DNS.
- Effectuer toutes les connexions sur l'interface de bouclage.
Les clients du réseau local interne doivent pouvoir :
- Interroger le serveur DNS de mise en cache installé sur le routeur.
- Accédez au serveur HTTPS dans la zone démilitarisée.
- Accéder à n'importe quel serveur HTTPS sur Internet.
- Les PC des administrateurs doivent pouvoir accéder au routeur et à tous les serveurs de la zone démilitarisée à l'aide de SSH.
Le serveur web dans la zone démilitarisée doit être capable de :
- Interroger le serveur DNS de mise en cache installé sur le routeur.
- Accéder à des serveurs HTTPS sur Internet pour télécharger des mises à jour.
Les hôtes sur l'Internet doivent être en mesure de.. :
- Accédez aux serveurs HTTPS dans la zone démilitarisée.
En outre, les exigences de sécurité suivantes s'appliquent :
- Les tentatives de connexion qui ne sont pas explicitement autorisées doivent être abandonnées.
- Les paquets abandonnés doivent être enregistrés.
2.7.3. Configuration de la journalisation des paquets abandonnés dans un fichier
Par défaut, systemd
enregistre les messages du noyau, tels que les paquets abandonnés, dans le journal. En outre, vous pouvez configurer le service rsyslog
pour qu'il consigne ces entrées dans un fichier distinct. Pour éviter que le fichier journal ne grossisse à l'infini, configurez une politique de rotation.
Conditions préalables
-
Le paquet
rsyslog
est installé. -
Le service
rsyslog
est en cours d'exécution.
Procédure
Créez le fichier
/etc/rsyslog.d/nftables.conf
avec le contenu suivant ::msg, startswith, "nft drop" -/var/log/nftables.log & stop
Avec cette configuration, le service
rsyslog
enregistre les paquets abandonnés dans le fichier/var/log/nftables.log
au lieu de/var/log/messages
.Redémarrez le service
rsyslog
:# systemctl restart rsyslog
Créez le fichier
/etc/logrotate.d/nftables
avec le contenu suivant pour faire pivoter/var/log/nftables.log
si la taille dépasse 10 Mo :/var/log/nftables.log { size +10M maxage 30 sharedscripts postrotate /usr/bin/systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true endscript }
Le paramètre
maxage 30
définit quelogrotate
supprime les journaux en rotation âgés de plus de 30 jours lors de la prochaine opération de rotation.
Ressources supplémentaires
-
rsyslog.conf(5)
page de manuel -
logrotate(8)
page de manuel
2.7.4. Écriture et activation du script nftables
Cet exemple est un script de pare-feu nftables
qui s'exécute sur un routeur RHEL et protège les clients d'un réseau local interne et un serveur web dans une zone démilitarisée. Pour plus de détails sur le réseau et les exigences relatives au pare-feu utilisé dans l'exemple, voir Conditions du réseau et Exigences de sécurité pour le script de pare-feu.
Ce script de pare-feu nftables
est uniquement destiné à des fins de démonstration. Ne l'utilisez pas sans l'adapter à votre environnement et à vos exigences de sécurité.
Conditions préalables
- Le réseau est configuré comme décrit dans la section Conditions du réseau.
Procédure
Créez le script
/etc/nftables/firewall.nft
avec le contenu suivant :# Remove all rules flush ruleset # Table for both IPv4 and IPv6 rules table inet nftables_svc { # Define variables for the interface name define INET_DEV = enp1s0 define LAN_DEV = enp7s0 define DMZ_DEV = enp8s0 # Set with the IPv4 addresses of admin PCs set admin_pc_ipv4 { type ipv4_addr elements = { 10.0.0.100, 10.0.0.200 } } # Chain for incoming trafic. Default policy: drop chain INPUT { type filter hook input priority filter policy drop # Accept packets in established and related state, drop invalid packets ct state vmap { established:accept, related:accept, invalid:drop } # Accept incoming traffic on loopback interface iifname lo accept # Allow request from LAN and DMZ to local DNS server iifname { $LAN_DEV, $DMZ_DEV } meta l4proto { tcp, udp } th dport 53 accept # Allow admins PCs to access the router using SSH iifname $LAN_DEV ip saddr @admin_pc_ipv4 tcp dport 22 accept # Last action: Log blocked packets # (packets that were not accepted in previous rules in this chain) log prefix "nft drop IN : " } # Chain for outgoing traffic. Default policy: drop chain OUTPUT { type filter hook output priority filter policy drop # Accept packets in established and related state, drop invalid packets ct state vmap { established:accept, related:accept, invalid:drop } # Accept outgoing traffic on loopback interface oifname lo accept # Allow local DNS server to recursively resolve queries oifname $INET_DEV meta l4proto { tcp, udp } th dport 53 accept # Last action: Log blocked packets log prefix "nft drop OUT: " } # Chain for forwarding traffic. Default policy: drop chain FORWARD { type filter hook forward priority filter policy drop # Accept packets in established and related state, drop invalid packets ct state vmap { established:accept, related:accept, invalid:drop } # IPv4 access from LAN and Internet to the HTTPS server in the DMZ iifname { $LAN_DEV, $INET_DEV } oifname $DMZ_DEV ip daddr 198.51.100.5 tcp dport 443 accept # IPv6 access from Internet to the HTTPS server in the DMZ iifname $INET_DEV oifname $DMZ_DEV ip6 daddr 2001:db8:b::5 tcp dport 443 accept # Access from LAN and DMZ to HTTPS servers on the Internet iifname { $LAN_DEV, $DMZ_DEV } oifname $INET_DEV tcp dport 443 accept # Last action: Log blocked packets log prefix "nft drop FWD: " } # Postrouting chain to handle SNAT chain postrouting { type nat hook postrouting priority srcnat; policy accept; # SNAT for IPv4 traffic from LAN to Internet iifname $LAN_DEV oifname $INET_DEV snat ip to 203.0.113.1 } }
Inclure le script
/etc/nftables/firewall.nft
dans le fichier/etc/sysconfig/nftables.conf
:include "/etc/nftables/firewall.nft"
Activer le transfert IPv4 :
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
Activez et démarrez le service
nftables
:# systemctl enable --now nftables
Vérification
Facultatif : Vérifiez l'ensemble de règles
nftables
:# nft list ruleset ...
Essayez d'effectuer un accès que le pare-feu empêche. Par exemple, essayez d'accéder au routeur en utilisant SSH depuis la zone démilitarisée :
# ssh router.example.com ssh: connect to host router.example.com port 22: Network is unreachable
En fonction de vos paramètres de journalisation, vous pouvez effectuer une recherche :
Le journal
systemd
pour les paquets bloqués :# journalctl -k -g "nft drop" Oct 14 17:27:18 router kernel: nft drop IN : IN=enp8s0 OUT= MAC=... SRC=198.51.100.5 DST=198.51.100.1 ... PROTO=TCP SPT=40464 DPT=22 ... SYN ...
Le fichier
/var/log/nftables.log
pour les paquets bloqués :Oct 14 17:27:18 router kernel: nft drop IN : IN=enp8s0 OUT= MAC=... SRC=198.51.100.5 DST=198.51.100.1 ... PROTO=TCP SPT=40464 DPT=22 ... SYN ...