Comment configurer le pare-feu nftables sous Linux avec des exemples
- Mise à jour le 25 févr. 2025

nftables est le nouvel outil pour gérer le firewall du noyau Linux : Netfilter, il est amené à remplacer iptables. Je poste ici des exemples de configuration sur lesquels je m'appuie.
Configuration
- OS : Debian 12
- nftables : 1.0.6
Informations générales
- Activer le service nftables au démarrage avec la commande systemctl:
root@host:~# systemctl enable nftables.service
- Fichier de configuration nftables:
root@host:~# /etc/nftables.conf
- Charger le fichier nftables:
root@host:~# nft -f /etc/nftables.conf
- Afficher les règles courantes:
root@host:~# nft list ruleset
- Effacer les règles:
root@host:~# nft flush ruleset
- Notes :
inet
inclus les adressesipv4
etipv6
. On peut utiliser les motsip
pour les adresses ipv4 ouipv6
pour les adresses ipv6.iif
pourinput interface
etoif
pouroutput interface
.- La règle
log prefix "NFTABLES LOG : "
permet de tracer le trafic la traversant dans/var/log/syslog
.
SMTP Server
Un fichier de configuration pour un serveur smtp.
#!/usr/sbin/nft -f
flush ruleset
# ----- IPv4 -----
table ip filter {
chain INPUT {
type filter hook input priority 0; policy drop; #by default, we drop traffic
iif lo accept comment "Accept any localhost traffic"
ct state invalid counter drop comment "Drop invalid connections"
ct state { established, related } counter accept comment "Accept traffic originated from us"
iif != lo ip daddr 127.0.0.1/8 counter drop comment "drop connections to loopback not coming from loopback"
ip protocol icmp icmp type { destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem } accept comment "Accept ICMP"
iif eth0 ip saddr 10.0.0.10 tcp dport ssh ct state { new, related, established } counter accept comment "Accept ssh from 10.0.0.10"
tcp dport { smtp, 465, 143, 993 } ct state { new, related, established } counter accept comment "Accept imap, imaps, smtp protocols"
log prefix "INPUT : " #trace dropped traffic (use journalctl -k --grep="INPUT")
counter drop #count and drop
}
chain FORWARD {
type filter hook forward priority 0; policy drop;
counter comment "count dropped packets"
}
chain OUTPUT {
type filter hook output priority 0; policy accept;
}
}
# ----- IPv6 -----
table ip6 filter {
chain INPUT {
type filter hook input priority 0; policy drop; #by default, we drop traffic
iif lo accept comment "Accept any localhost traffic"
iif != lo ip6 daddr ::1/128 counter drop comment "drop connections to loopback not coming from loopback"
ct state invalid drop comment "Drop invalid connections"
ct state { established, related } accept comment "Accept traffic originated from us"
ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, mld-listener-query, mld-listener-report, mld-listener-reduction, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, ind-neighbor-solicit, ind-neighbor-advert, mld2-listener-report } accept comment "Accept ICMPv6"
#ip protocol igmp accept comment "Accept IGMP"
tcp dport { smtp, 465, 143, 993 } ct state { new, related, established } counter accept comment "Accept imap, imaps, smtp"
counter drop #count and drop
}
chain FORWARD {
type filter hook forward priority 0; policy drop;
counter comment "count dropped packets"
}
chain OUTPUT {
type filter hook output priority 0;
}
}
Routeur
Un fichier de configuration pour un routeur.
#!/usr/sbin/nft -f
flush ruleset
table ip my_nat {
chain my_masquerade {
type nat hook postrouting priority 100; policy accept;
ip daddr != { 192.168.0.0/16 } oifname "wan" masquerade comment "outgoing NAT"
}
chain my_prerouting {
type nat hook prerouting priority -100; policy accept;
iifname "wan" tcp dport { http, https } dnat to 192.168.10.250 comment "Web Redirect"
iifname "wan" udp dport 9994 dnat to 192.168.10.251:1194 comment "OpenVPN Redirect"
}
}
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif "lo" accept
ct state { related, established} accept
ct state invalid drop
meta l4proto icmp accept
ip saddr 192.168.0.0/16 tcp dport { ntp, domain, ssh } ct state { new, related, established } accept comment "dns, ntp, ssh"
ip saddr 192.168.0.0/16 udp dport { ntp, domain } ct state { new, related, established } accept comment "dns, ntp"
iifname "wan" jump input_wan
iifname "lan" jump input_lan
log prefix "INPUT : " #trace dropped traffic (use journalctl --grep=INPUT")
}
chain input_wan {
ip saddr { 46.105.57.169 } tcp dport ssh accept comment "allow external SSH"
}
chain input_lan {
tcp dport ssh accept
}
chain forward {
type filter hook forward priority 0; policy drop; #by default, we drop traffic
ct state { related, established } accept
ct state invalid drop
ip saddr 192.168.0.0/16 tcp dport { http, https } accept comment "accept WEB"
iifname { "lan" } oifname "wan" udp dport { domain, ntp } accept comment "DNS"
ip saddr 192.168.0.0/16 ip daddr 192.168.0.0/16 icmp type { echo-reply, echo-request} accept comment "allow icmp"
}
chain output {
type filter hook output priority 0; policy accept;
}
}