{{tag>netadmin sécurité linux firewall pare-feu netfilter nft nftables}}
:TODO_DOCUPDATE:
====== nftables ======
**nftables** est le successeur d'**iptables**. Il est intégré aux noyaux >= 3.13 depuis 2014. Les distributions récentes fournissent par défaut nftables et sauf spécificité il est recommandé de migrer vers nftable.
Principales différences:
* iptables certaines tables sont présentes par défaut, ce n'est pas le cas pour nftables;
* iptables ne permet de définir qu'une cible par règle. Avec nftables plusieurs actions peuvent être associées à une règle;
* nftables inclus la gestion des ensembles (sets).
* le framework iptables proposait des outils dédiés par familles de protocoles (iptables,ip6tables, arptables,ebtables). ntables permet de gérer les différentes famille au sein d'un même CLI.
===== Généralités à propos de la syntaxe =====
**nft** est la CLI permettant de définir les règles. Elle interprète les caractères spéciaux tels que l'accolade ou le point virgule également utilisés par le shell. Si **nft** est appelé depuis le bash il faudra donc échapper les caractères spéciaux.
On peut également invoquer **nft** en mode interactif via l'option **-i**. En fonctionnant dans ce mode il devient inutile d'échapper les caractère spéciaux.
nft --handle --interactive
# équivalents
nft -a -i
nft -ai
Dans l'exemple ci-dessus on introduit également l'option **%%--handle%%** ou **-a**. Un handle (contrôleur) est un identifiant numérique associé à chaque élément de configuration. il peut être affiché grâce à cette option puis réutilisés par différentes commandes pour désigné de facon sure et concise l'élément a manipuler.
# nft depuis le bash : les caractères spéciaux doivent être échappés
nft 'add chain ip my_iptable input_chain { type filter hook input priority 0 ; policy drop ; comment "text comment" ;}'
Les modifications apportées depuis **nft** s'appliquent immédiatement mais ne seront pas sauvegardées après redémarrage. Comme beaucoup d'autre outils réseau il fonctionne en système transitoire (ou transiant).
===== Le ruleset =====
Le ruleset désigne l'ensemble des éléments de configuration existants. Des opérations peuvent être appliquées sur l'ensemble de la configuration comme:
# Sauvegarder/exporter le ruleset dans le fichier "my_ruleset.nft"
nft list ruleset > my_ruleset.nft
# Effacer le ruleset courant
nft flush ruleset
# Recharger un ruleset depuis le fichier "my_ruleset.nft"
nft -f my_ruleset.nft
===== Les tables =====
Les tables sont des conteneurs. On y trouve les **chaînes**, les **ensembles** et les objets à état (**compteurs**, **quotas**, **limites**). L'état désactivé (flag 'dormant') peut être positionné sur une table: dans ce cas les chaînes de base sont déchargées et ne sont plus évaluées.
Pour lister les tables existantes:
# nft list tables
# On peut choisir de lister les tables d'une famille en particulier
nft list tables bridge
nft list tables inet
nft list tables ip
Pour lister le contenu d'une table
nft list table aTableName
# La famille peut être précisée en préfixe
nft list table ip aTableName
nft list table ip6 aTableName
nft list table inet aTableName
nft list table arp aTableName
nft list table bridge aTableName
nft list table netdev aTableName
==== Création d'une table =====
Création d'une table "myTable" pour la famille ipv4.
add table ip myTable { flags dormant; comment "Basic firewall"; }
==== Suppression d'une table ====
delete table ip myTable
# Suppression de la table via son identifiant
delete table handle 2
L'utilisation du handle pour la suppression de la table est normalement possible mais provoque une erreur et l'arrêt du programme nft sur mon système de test (Debian 5.10.162-1 (2023-01-21)/KVM QEMU)
==== Activer/Désactiver la table ====
On positionne le drapeau ''dormant'' pour désactiver la table via la commande **add**:
add table aTableName { flags dormant; }
# La famille peut être précisée
add table ip6 aTableName { flags dormant; }
===== Les chaînes =====
Les chaînes contiennent les séquences de règles. On distingue les **chaînes de base** et les **chaînes normales** (regular):
* Un **chaîne de base** est un point d'entrée pour les paquets en provenance de la pile réseau. L'association au point d'entrée se fait via un système de hook);
* Une **chaîne normale** peut être utilisée comme cible par un saut (jump) elle permet notamment de regrouper et d'organiser un sous ensemble de règles.
add chain aTableName inbound { type filter hook input priority 0; comment "Filtrage du trafic entrant"; }
===== Lister les règles d'une chaine =====
Pour lister les règles contenues dans une chaine :
nft list chain aTablename aChain
===== Création/modification d'une chaîne ====
La chaîne est contenue dans une table. Lors de la création d'une chaîne de base les attributs type, hook et priority sont obligatoirement définis:
# Création d'une chaîne de base anInputBaseChain dans la table aTable
# commande saisie en mode interactif
create chain ip aTable anInputBaseChain { type filter hook input priority 0; policy drop; comment "a useful remark"; }
===== Les règles =====
**Ajouter** une nouvelle règle dans une chaine avec la syntaxe suivante :
**Remplacer** une règle existante toujours via le handler :
# On remplace la règle de la chaine "inbound" dans la table "ipfilter"
# désignée par le handler 21 par la définition qui suit
replace rule ipfilter inbound handle 21 iif lo counter accept comment "Accepte le trafic local sur l'interface loopback"
Pour **inserer** une règle on s'appuie sur le handler et l'argument "position" :
# Insertion d'une règle dns la chaine "outbound" de la table "ipfilter"
# au niveau du handler 12
insert rule ipfilter outbound position 12 oif lo ct state established,related counter accept comment "Accepte tout paquet en lien avec un trafic sortant explicitement autorise sur la boucle locale"
**Supprimer** la règle désignée par le contrôleur 5 (handler) :
# Supprime la règle de la chaine "aChain" dans la table "aTable"
# identifiée par le handle 5
delete rule aTable aChain handle 5
==== Désignation des interfaces =====
:TODO_DOCUPDATE:
Les règles peuvent intégrer des critères de sélection des interfaces
Source : [[https://serverfault.com/questions/985158/what-is-the-difference-between-iifname-and-iif-in-nftables|Différence entre iifname et iif (serverfault.com)]]
==== Les états ====
Une petite précision sur les états des **connexions TCP** disponibles via ct (conntrack), il en existe 5 :
* **NEW** : Il s'agit des premiers paquets d'une connexion (Exemple : premier paquet TCP SYN d'une connexion TCP).
* **ESTABLISHED** : Echange de paquet dans les deux sens, la connexion est dite "établie".
* **RELATED** : Connexion qui se réfère d'une connexion ESTABLISHED et créé par elle (Exemple, une connexion FTP-DATA après une authentification correcte via le protocole FTP).
* **INVALID** : Paquet sans état et ne pouvant être rattaché à une connexion déjà connue, à dropper.
* **UNTRACKED** : Paquet ne faisant pas partie d'une connexion connue.
==== Les sets (ensembles) ====
Voir la note [[netadmin/nftables/gestion_des_ensembles|Gestion des ensembles avec nftables]].
===== Compteurs =====
Les objets de type **counter** et **quota** sont déclarés dans les tables et peuvent être utilisés par les règles dans les chaînes.
icmp type echo-request
===== Journalisation =====
:TODO_DOCUPDATE:
Les valeurs possibles pour **level** correspondent aux niveau de syslog : emerg, alert, crit, err, warn (valeur par défault), notice, info, debug
===== Limites =====
Comme pour les ensembles ou les compteurs, on distingue les limites anonymes et les limites nommées.
Dans l'exemple ci-dessous on crée une limite nommée "limit_10ppm" dans la table "aTable"
add limit aTable limit_10ppm { rate 10/minute ; comment "Limitation du trafic a 10 paquets par minute" }
La limite nommée peut ensuite être utilisée par une ou plusieurs règles. Dans l'exemple ci-dessous on crée une règle dans la chaîne "inboundBaseChain" autorisant les requêtes ICMP entrantes dans la limite de 10 paquets par minutes:
add rule aTable inboundBaseChain icmp type echo-request limit name "limit_10ppm" accept comment "Autorisation limitee du ping"
Suppression de la limite
# Supprimer la limite par son label
delete limit aTable limit_10ppm
# Supprimer la limite via son identifiant
delete limit aTable handle 1
La suppression d'une limite nommée n'est possible que lorsqu' elle n'est plus utilisée. Dans le cas contraire on obtient une erreur du type ''Error: Could not process rule: Device or resource busy''.
===== Activer le service nftables ======
Sur les distributions récentes basées sur systemd, le service existe mais il n'est pas activé par défaut :
systemctl status nftables.service
○ nftables.service - nftables
Loaded: loaded (/lib/systemd/system/nftables.service; disabled; preset: enabled)
Active: inactive (dead)
Docs: man:nft(8)
http://wiki.nftables.org
Activer le service ''nftables.service'' :
systemctl enable --now nftables.service
Le ruleset ''/etc/nftables.conf'' utilisé par défaut par le service est vide, il faudra définir vos règles.
===== Exemple =====
# Lance netfilter en mode interactif
nft -ai
# création d'une table pour filtrage du trafic IP
# La table est désactivée
add table ip ipfilter { flag dormant; }
# Création de compteurs nommés
add counter ipfilter rejected_pkts
add counter ipfilter accepted_pkts
add chain ipfilter incoming { type filter hook input priority 0; policy drop; comment "Filtrage des paquets entrants" ; }
# Rejette et journalise le trafic non explicitement autorisé
add rule ipfilter incoming iif lan counter name rejected_pkts log prefix "[REJECT]" level notice reject with icmp type port-unreachable comment "Rejet de tout trafic entrant non explicitement autorisé"
# rejet et journalise le trafic non autorisé
add chain ipfilter outgoing { type filter hook output priority 0; policy drop; comment "Filtrage des paquets sortants"; }
add rule ipfilter outgoing oif lan counter name rejected_pkts log prefix "[REJECT]" level notice reject with icmp type port-unreachable comment "Rejet de tout trafic sortant non explicitement autorisé"
# Activer la table
add table ip ipfilter
===== Références =====
* https://nftables.org/
* https://wiki.nftables.org/wiki-nftables/index.php/Rejecting_traffic
* https://www.linuxembedded.fr/2022/06/introduction-a-nftables
* [[https://blog.debugo.fr/nftables-serie-tutos/|tutoriel netfilter nftables (debugo.fr)]]
* https://wiki.csnu.org/index.php/Nftables
* https://www.youtube.com/watch?v=EGKhIljDPCw
* [[https://wiki.nftables.org/wiki-nftables/index.php/Logging_traffic|Journalisation du trafic (nftables.org)]]
* [[https://wiki.archlinux.org/title/Nftables|guide d'utilisation de nftables (archlinux.org)]]
* [[https://thermalcircle.de/doku.php?id=blog:linux:connection_tracking_1_modules_and_hooks|Fonctionnement de conntrack]]