nftables memo
Memo sur la gestion du pare-feu netfilter, via l'outil nftables.
Les commandes essentielles sont présentées, avec des exemples.
Gestion des tables
Création d'une table:
nft add table add inet example_filter
Ici notre table se nomme "example_filter".
- inet: table ipv' et ipv-
- ip: table ipv4
- ip6: table ipv6
- arp: table pour arp
Pour la liste des tables: Wiki nftable
Suppression d'une table :
nft delete table inet example_filter
Lister le contenu d'une table:
nft list inet example_filter
Gestion des chaines
Ensuite il va falloir ajouter des chaines à notre table et les lier à des "hooks". Ces derniers vont définir à quel type de hook de netfilter ils sont rattachés.
Ces chaines peuvent avoir n'importe quel nom, du moment qu'elles sont rattachées au bon hook (input, output...).
Ici on va créer une chaine "input" et "output" pour que ça soit clair, mais on aurait pu les appeler autrement, du moment qu'ils bien rattachés aux hook:
nft add chain inet filter input '{type filter hook input priority 0; policy drop; }'
nft add chain inet filter output '{type filter hook output priority 0;}'
Ici le "priority 0" faut référence à la priorité de la table, c'est à dire l'ordre de prise en compte des chaines. Par défaut c'est 0, mais on aurait pu créer plusieurs type de chaines, liées au hook 'input', mais avec des priorité déférentes.
On a donc la table suivante, avec ce contenu (commande nft list table inet filter):
table inet filter {
chain input {
type filter hook input priority filter; policy accept;drop;
}
chain output {
type filter hook output priority filter; policy accept;
}
}
Gestion des règles
Ajout de règles
Ajout d'une règle:
nft add rule filter input regle_a_appliquer
Par exemple pour ouvrir le port 80:
nft add rule inet filter input tcp dport 80 accept
Et pour bloquer tout ce qui n'est pas explicitement écrit, on place cette règle à la fin, donc après avoir définie toutes nos règles:
nft add rule filter input drop
Pareil, si on veut bloquer tout le trafic sortant:
nft add rule filter output drop
Insertion de règles
Si on veut ajouter des règles, il va falloir les insérer. En effet, l'ajout du drop, aura pour conséquence la non prise en compte des règles ajoutée après.
il faut donc passer par une insertion de règles par rapport à celles déjà présentes.
Pour cela, il faut d'abor lister nos règles avec l'option -a:
root@debian:~# nft -a list table ip mon_filtreIPv4
table ip mon_filtreIPv4 { # handle 4
chain input { # handle 1
type filter hook input priority filter; policy accept;drop;
tcp dport 80 accept # handle 4
drop # handle 5
}
chain output { # handle 3
type filter hook output priority filter; policy accept;
tcp sport 80 accept # handle 7
drop # handle 8
}
}
le "handle" correspond à l’identifiant de la règle.
Donc si on veut ajouter une règle autorisant l'accès au port ssh:
nft add rule inet filter input position 4 tcp dport 22 accept
nft add rule inet filter output position 7 tcp sport 22 accept
La règle sera donc ajouter après position ciblée (ici 4 et 7).
Si on veut ajouter la règle avant la position ciblé, il faut juste faire un insert:
nft insert rule inet filter input position 4 tcp dport 22 accept
nft insert rule inet filter output position 7 tcp sport 22 accept
Suppression d'une règle
Pour supprimer une règle, il faudra utiliser le même principe que l'ajout, c'est à dire utiliser les handle (avec la command nft -a list).
Par exemple pour supprimer la règle en position 7:
nft delete rule inet filter input handle 7
Sets et named sets
Les named sets permettent une gestion dynamique des règles, via la l'utilisation de Docset.
Ces dernières étant des collections, on l'on poura ajouter ou supprimer dynamiquement des éléments (IP, MAC, ports...).
Ainsi, quand on créer une règle liée à faireune named set, tous les éléments de celle-ci seront concernés.
Par exemple, si on veut bloquer des IPs, pour détailleréviter de créer une règle pour les bloquer individuellement, on les ajoute à une named set et on lie à celle-ci une règle pour drop le traffic de ces IPs.
Exemple, issue de la doc de nftable, pour bloquer des IPs ajoutées dans la named set IP_BLACKLIST:
- Création de
IP_BLACKLISTde type ipv4_addr, pour stocker des IP:
nft add set inet filter IP_BLACKLIST { type ipv4_addr\; comment \"IP blacklistées\" \; }
- Ajout d'une règle pour drop les IP dans
IP_BLACKLIST:
nft add rule inet filter input ip saddr @IP_BLACKLIST drop
- Pour ajouter des IPs, qui seront bloquées:
nft add element inet filter IP_BLACKLIST { 192.168.3.4 }
nft add element iinetp filter IP_BLACKLIST { 192.168.1.4, 192.168.1.5 }
- Pour supprimer un élement:
nft add delete inet filter IP_BLACKLIST { 192.168.3.4 }
Délai de conservation d'un élément
Via l'option timeout, on peut définir un délai de conservation d'un élément dans la named set:
nft add set inet filter IP_BLACKLIST { type ipv4_addr\; comment \"IP blacklistées\" \; timeout 1h \;}
Dans cet exemple, chaque IP ajoutée sera supprimée au bout d'une heure de IP_BLACKLIST.
On peut aussi appliquer un délai uniquement pour une IP, lors de son ajout:
nft add element inet filter IP_BLACKLIST { 192.168.3.4 timeout 60s }
Après 60 secondes, l'IP sera supprimée.
Pour en savoir plus sur l'utilisation des namesnamed sets:set, https://wiki.nftables.org/wiki-nftables/index.php/Setsse repoter à "la doc"
Limite de connexion
Via l'utilisation des "meters", on peut définir des limites de connexion, par exemple limiter un nombre max de connexion par IP sur le port SSH.
Exemple pour limiter le nombre de connexion entrantes sur le port SSH (22) à 5 par minutes:minute:
- Création set
ssh_ratelimit, qui contiendra les IP:
nft add set inet filter ssh_ratelimit { type ipv4_addr\; flags dynamic\; timeout 60s \; }
- Création d'une règle pour limiter les connexions SSH, liée à named set
:ssh_ratelimit
nft add rule inet filter input ct state new tcp dport 22 update @ssh_ratelimit { ip saddr limit rate 5/minute } accept
Cette règle aura pour effet, qu'a chaque nouvelle requete sur le port 22, l'IP sera ajoutée à la table ssh_ratelimit.
Elle sera mémorisée pendant 60 secondes. Si cette IP effectue plus de 5 requêtes, les prochaines seront bloquées pendant 1 minute.
Lister les named set
Avec la commande suivante, on peut lister les named set existantes:
nft list sets
Pour lister les élements d'une named set (dans la table inet filter):
nft list set inet filter IP_BLACKLIST
Sauvegarde des règles
La sauvegarde des règles de nftable est assez similaire à iptables.
On sauvegarde les règles existantes dans un fichier:
nft list table inet filter > nft_rules.rules
Les règles seront donc sauvegardées dans le fichier nft_rules.rules.
Pour restaurer les règles:
nft -f nft_rules.rules
Comme iptables, si on redémarre la machine, les règles ne sont pas persistantes.
Il faut soit faire un script qui se lance au démarrage et qui restaure nos règles avec "nft -f", soit ajouter la ligne suivante au fichier /etc/network/interface:
allow-hotplug ens192
iface ens192 inet static
address 192.168.5.2/24
gateway 192.168.5.254
pre-up nft -f /etc/nftables/nft.fw
Ici nos règles sont dans le fichier /etc/nftables/nft.fw.
Cela ne marche que sur les systèmes sous debian.
Ressources: