Configurer le pare-feu avec des éléments nftables

Ce chapitre décrit la configuration du pare-feu avec nftables. Il fournit également des exemples de configuration de tables, de chaînes et de règles nftables qui appliquent la sécurité réseau sur un système à l'aide de la commande nft. Ces exemples sont appropriés pour l'apprentissage des fichiers nftables. Cependant, pour les utilisateurs plus avancés, envisagez de modifier les configurations nftables à partir d'un fichier. Pour plus d'informations sur la syntaxe du fichier nftables, reportez-vous à la page de manuel nft(8).

Procédez comme suit :

  • Pour Oracle Linux 8, ce chapitre décrit également la conversion de iptables et ip6tables en structure nftables.

  • Pour Oracle Linux 9 et Oracle Linux 10, utilisez plutôt les conseils de conversion de la documentation du pare-feu propre à la version.

Remarque

Lorsque vous créez des configurations nftables à l'aide des commandes nft, ces configurations résident dans la mémoire du système jusqu'à ce que vous vidiez la mémoire ou que vous redémarriez le système. Pour rendre ces configurations persistantes lors des initialisations du système, envisagez d'exporter les configurations dans un fichier .nft et configurez le système pour inclure le fichier lors du démarrage du service nftables. Pour plus d'informations sur l'exportation de configurations vers un fichier, reportez-vous à la section Disabling the firewalld Service. Pour plus d'informations sur le chargement manuel ou automatique d'un fichier de configuration dans nftables, reportez-vous à Désactivation du service firewalld.

Remarque

Lorsque vous utilisez nftables, il est recommandé de conserver une connexion locale (par exemple, avec une console série si possible) pour récupérer des erreurs susceptibles de vous bloquer du système.

Désactivation du service firewalld

Dans Oracle Linux, nftables n'est pas activé par défaut car le service firewalld l'utilise en tant que back-end. Désactivez firewalld avant de commencer à travailler avec nftables.

Procédez comme suit :

  • Pour Oracle Linux 8, le résultat est le suivant :

    firewalld.service
       Loaded: masked (Reason: Unit firewalld.service is masked.)
       Active: inactive (dead)
    
    Jan 20 15:16:07 localhost.localdomain systemd[1]: Starting firewalld - dynamic firewall daemon...
    Jan 20 15:16:08 localhost.localdomain systemd[1]: Started firewalld - dynamic firewall daemon.
    Jan 20 15:16:08 localhost.localdomain firewalld[1635]: WARNING: AllowZoneDrifting is enabled. This is considered an insecure configuration option. It will be removed in a future release. Please consider disabling it now.
    Jan 20 15:52:27 localhost.localdomain systemd[1]: Stopping firewalld - dynamic firewall daemon...
    Jan 20 15:52:27 localhost.localdomain systemd[1]: firewalld.service: Succeeded.
    Jan 20 15:52:27 localhost.localdomain systemd[1]: Stopped firewalld - dynamic firewall daemon.
    
  • Pour Oracle Linux 9, le résultat est le suivant :

    firewalld.service
         Loaded: masked (Reason: Unit firewalld.service is masked.)
         Active: inactive (dead)
    
    Jan 20 15:10:08 localhost.localdomain systemd[1]: Starting firewalld - dynamic firewall daemon...
    Jan 20 15:10:08 localhost.localdomain systemd[1]: Started firewalld - dynamic firewall daemon.
    Jan 20 15:26:25 localhost.localdomain systemd[1]: Stopping firewalld - dynamic firewall daemon...
    Jan 20 15:26:25 localhost.localdomain systemd[1]: firewalld.service: Deactivated successfully.
    Jan 20 15:26:25 localhost.localdomain systemd[1]: Stopped firewalld - dynamic firewall daemon.
    
  • Pour Oracle Linux 10, le résultat est le suivant :

    firewalld.service
         Loaded: masked (Reason: Unit firewalld.service is masked.)
         Active: inactive (dead)
    
    Jan 20 16:05:39 localhost.localdomain systemd[1]: Starting firewalld.service - firewalld - dynamic firewall daemon...
    Jan 20 16:05:40 localhost.localdomain systemd[1]: Started firewalld.service - firewalld - dynamic firewall daemon.
    Jan 20 16:08:33 localhost.localdomain systemd[1]: Stopping firewalld.service - firewalld - dynamic firewall daemon...
    Jan 20 16:08:33 localhost.localdomain systemd[1]: firewalld.service: Deactivated successfully.
    Jan 20 16:08:33 localhost.localdomain systemd[1]: Stopped firewalld.service - firewalld - dynamic firewall daemon.
  1. Jan 20 16:08:33 localhost.localdomain systemd[1]: Stopping firewalld.service - firewalld - dynamic firewall daemon...
      Jan 20 16:08:33 localhost.localdomain systemd[1]: firewalld.service: Deactivated successfully.
      Jan 20 16:08:33 localhost.localdomain systemd[1]: Stopped firewalld.service - firewalld - dynamic firewall daemon.

A propos des jeux de règles et des tables

nftables inclut des ensembles de règles qui contiennent toutes les structures de configuration dans les tables nftables. Les tables sont la structure de niveau supérieur des jeux de règles dans lesquels se trouvent divers objets tels que des chaînes, des règles, etc.

Gérer les jeux de règles et les tables

Pour gérer les ensembles de règles et les tables nftable en mémoire, procédez comme suit :
  1. Créez une table pour un type de famille d'adresses spécifique à l'aide de la syntaxe suivante :

    sudo nft add table <address_family> <table_name>
    Dans le précédent,
    • <address_family> peut être ip, ip6, inet, arp, bridge ou netdev. Tous les objets nftables appartiennent à l'une de ces familles d'adresses. Pour plus d'informations sur ces familles d'adresses, consultez la page de manuel nft(8).
    • <table_name> est le nom de la table. Les tables contiennent des chaînes, qui à leur tour contiennent des règles.
    Par exemple, la commande suivante crée une table nommée mytable avec la famille inet, qui inclut les adresses pour les versions IP 4 et 6 :
    sudo nft add table inet mytable
  2. Procédez comme suit :
    • Pour afficher tous les ensembles de règles, procédez comme suit :
      sudo nft list ruleset
    • Pour afficher une table unique, procédez comme suit :
      sudo nft list table <address_family> <table_name> 

A propos des crochets et des chaînes

Les crochets sont des points d'un système où les paquets peuvent être interceptés pour traitement. Ces crochets permettent à nftables d'appliquer des chaînes et des règles qui déterminent ce qui arrive à un paquet. Différents crochets sont disponibles en fonction de la famille d'adresses appliquée à une table.

Le tableau suivant présente les hooks disponibles pour chaque famille d'adresses.

Famille d'adresse

Point d'ancrage

Description

IP, IPv6, inet/pont

préroutage

Traite tous les paquets entrants avant les décisions de routage.

entrée

Gère les paquets destinés au système local.

avant

Gère les paquets transférés vers un autre hôte.

sortie

Traite les paquets provenant du système local.

postroutage

Traite avec tous les paquets sortants après le routage.

entrée

Gère les paquets entrants avant le prerouting, disponible à partir du noyau Linux 5.10 pour la famille inet.

ARP

entrée

Traite les paquets pour le système local.

sortie

Gère les paquets envoyés depuis le système local.

Périphérique réseau

entrée

Traite les paquets entrants après les prises réseau, telles que tcpdump, avant la gestion de la couche 3.

sortie

Gère les paquets sortants après la gestion de la couche 3, mais avant la sortie finale du réseau.

Les chaînes de base sont attachées aux crochets. Lorsqu'un paquet arrive à un crochet, configuré avec une chaîne de base, le paquet traverse alors la chaîne, et chaque règle de la chaîne est évaluée dans l'ordre jusqu'à ce qu'une règle corresponde ou que la fin de la chaîne soit atteinte. nftables inclut les types de chaîne suivants :
  • Chaînes de base : Il s'agit de chaînes directement construites sur un crochet. Par exemple, une chaîne de base nommée myinput peut être liée au point d'accrochage d'entrée inet pour les paquets IPv4 ou IPv6 arrivant sur le système local.
  • Chaînes régulières : il s'agit de chaînes qui sautent des chaînes de base ou d'autres chaînes régulières. Ils ne sont pas construits directement à un crochet, mais peuvent faire partie du processus de prise de décision au sein d'une chaîne de base.
Les chaînes de base doivent inclure le type de chaîne de base, le crochet et les paramètres de priorité. Les types de chaîne sont les suivants :
  • filter : principalement utilisé pour le filtrage de paquets, par exemple pour autoriser ou bloquer des paquets en fonction de divers critères tels que l'adresse IP source et de destination, les ports, les protocoles, etc. Ce type de chaîne fonctionne avec toutes les familles d'adresses et leurs crochets.
  • nat : principalement utilisé pour modifier les adresses IP, les ports ou les deux dans les en-têtes de paquet pour les opérations NAT. Cela inclut les modifications apportées au NAT source (SNAT) pour le trafic sortant et au NAT de destination (DNAT) pour le trafic entrant. Ce type de chaîne peut être configuré avec des familles d'adresses ip, ipv6 et inet et peut prendre les crochets de prerouting, d'entrée, de sortie et de posttrouting.
  • route : principalement utilisé pour les décisions de routage telles que la modification d'une table de routage ou le marquage de paquets pour des stratégies de routage spécifiques. Ce type de chaîne peut être utilisé avec les familles d'adresses ip et ipv6 et peut prendre le crochet de sortie uniquement.

Lors de l'utilisation des points d'accrochage entrants ou sortants, indiquez un nom d'interface réseau en tant que chaîne avec le paramètre device. Toutes les chaînes entrantes ou sortantes filtrent uniquement le trafic à partir de l'interface indiquée dans le paramètre de périphérique.

Le paramètre de priorité utilise un entier signé ou un nom de priorité standard pour déterminer l'ordre dans lequel les chaînes avec le même hook sont traitées. Les chaînes passent de valeurs ou de noms de priorité inférieure à des valeurs ou noms de priorité supérieure.

Le tableau suivant présente les noms et les valeurs de priorité pour chaque famille d'adresses et type de point d'accrochage associés.

Nom

Valeur

Droit de la famille Points d'ancrage

brut

-300

ip, ip6, inet tout

essoreuse à main

-150

ip, ip6, inet tout

dsnat

-100

ip, ip6, inet préroutage

filtre

0

ip, ip6, inet, arp, netdev tout

sécurité

50

ip, ip6, inet tout

srcnat

100

ip, ip6, inet postroutage

Le tableau suivant présente les noms et valeurs de priorité pour la famille d'adresses de pont et le type de point d'accrochage.

Nom

Valeur

Points d'ancrage

dsnat

-300

préroutage

filtre

-200

tout

sortie

100

sortie

srcnat

300

postroutage

Vous pouvez également choisir de définir une stratégie sur une chaîne qui définit si un paquet doit être accept ou drop lorsqu'aucune des règles définies sur la chaîne ne correspond au paquet. Par défaut, les chaînes de base acceptent tous les paquets. Toutefois, pour des raisons de sécurité, il est recommandé de définir une stratégie de suppression de tout le trafic qui n'est pas explicitement autorisé par une chaîne.

Créer des chaînes de base

Pour créer des chaînes de base nftable en mémoire, procédez comme suit :
  1. Créez une chaîne pour un type de famille d'adresses et une table spécifiques à l'aide de la syntaxe suivante :

    sudo nft add chain <address_family> <table_name> <chain_name>{ type <chain_type> hook <hook_type> device <network_interface_name> priority <priority> policy <policy> comment <comment> ; }
    
    Dans le précédent,
    • <address_family> peut être ip, ip6, inet, arp, bridge ou netdev. Tous les objets nftables appartiennent à l'une de ces familles d'adresses. Pour plus d'informations sur ces familles d'adresses, consultez la page de manuel nft(8).
    • <table_name> est le nom de la table. Les tables sont des conteneurs pour les chaînes, qui sont à leur tour des conteneurs pour les règles.
    • <chain_name> est un nom arbitraire pour la chaîne. Les personnes migrant à partir de pare-feu basés sur iptables utilisent souvent la dénomination iptables traditionnelle.
    • <chain_type> est le type de chaîne. Les valeurs valides pour les chaînes de base sont filter, nat et route. Pour plus d'informations, reportez-vous à A propos des hooks et des chaînes.
    • <hook_type> est le type de point d'accrochage. Les valeurs possibles dépendent de la famille d'adresses et du type de chaîne sélectionnés. Pour plus d'informations, reportez-vous à A propos des hooks et des chaînes.
    • <network_interface_name> est le nom de l'interface réseau pour le paramètre du périphérique. Ce paramètre est uniquement requis lors de l'utilisation des crochets d'entrée ou de sortie.
    • <priority> est la valeur ou le nom de priorité de la chaîne. La priorité dépend de la famille d'adresses et du type de point d'accrochage sélectionnés. Pour plus d'informations, reportez-vous à A propos des hooks et des chaînes.
    • <policy> est l'action effectuée si toutes les règles définies sur la chaîne ne correspondent pas au paquet. Les valeurs valides sont accept ou drop. Si aucune valeur n'est indiquée, la valeur par défaut est accept.
    Par exemple, la commande suivante crée une chaîne dans la table mytable appelée mychain avec la famille inet. Le type de chaîne est filter, le hook est input et la priorité est 0. Enfin, la stratégie est définie pour supprimer tous les paquets qui ne correspondent pas à une règle :
    sudo nft add chain inet mytable mychain "{ type filter hook input priority 0 ; policy drop ; }"
  2. Procédez comme suit :
    • Pour afficher toutes les chaînes, procédez comme suit :
      sudo nft list chains
    • Pour afficher une chaîne unique, procédez comme suit :
      sudo nft list chain <address_family> <table_name> <chain_name>

A propos des règles

Vous pouvez ajouter des règles à des chaînes dans une table. Les règles sont constituées d'instructions qui correspondent aux paquets en fonction de divers critères et appliquent des actions telles que l'acceptation, la suppression, le rejet, etc. Ces instructions comprennent des éléments tels que :
  • Jeux, qui sont des ensembles d'éléments utilisés pour la mise en correspondance.
  • Les expressions, qui sont des blocs de construction pour les règles qui définissent la façon dont les paquets sont mis en correspondance ou manipulés. Exemples :
    • Correspondances spécifiques au protocole (par exemple, ip, ip6, tcp, udp).
    • Correspondance d'adresse (adresse, adresse).
    • Correspondance de port (sport, dport).
    • L'interface réseau correspond (iifname, oifname).
  • Les cartes, qui sont similaires aux jeux mais peuvent mapper une valeur à une autre. Les mappings sont utilisés pour des scénarios de mise en correspondance ou de transformation plus complexes.
  • Les cartes de verdict, qui peuvent modifier les verdicts en fonction du contenu des paquets, permettent des décisions de stratégie plus dynamiques.
  • Compteurs, qui suivent le nombre de paquets correspondant à une règle et s'affichent lors de l'exécution d'une commande list nft qui inclut la règle. Les compteurs sont un moyen utile de vérifier si une règle fonctionne.
  • Quotas, qui limitent la quantité de données pouvant passer par une règle avant qu'une action ne change (par exemple, de accept à drop).
  • Flowtables, qui permet le transfert rapide des paquets de chemin, améliorant les performances en contournant le traitement régulier des paquets pour un certain trafic.
  • Instructions, qui incluent des opérations telles que log, reject, jump et goto qui modifient le comportement de gestion des paquets.

Les règles ajoutées à une chaîne sont évaluées de haut en bas et de gauche à droite.

Pour plus d'informations sur la configuration de ces instructions, consultez la page de manuel nft(8).

Créer des règles - Exemples

Cette section inclut un exemple commun de règles créées dans les chaînes.

Autoriser le trafic local

La commande suivante crée une règle dans mytable dans mychain pour la famille inet qui permet au trafic local d'entrer via l'interface loopback (iff lo) :
sudo nft add rule inet mytable mychain iif lo accept

Autoriser le trafic entrant pour une connexion existante ou liée à une connexion existante

Cette commande ajoute une règle à la chaîne mychain de mytable qui accepte tout le trafic entrant qui fait partie d'une connexion existante ou qui y est associé :
sudo nft add rule inet mytable mychain ct state established, related accept
Dans l'exemple précédent,
  • ct est un assistant de suivi de connexion pour IPv4, IPv6 ou inet qui fait partie du module nf_conntrack. Ce module est généralement chargé par défaut sur la plupart des systèmes. Vous pouvez afficher l'état de toutes les connexions au système à l'aide de la commande suivante :
    sudo cat /proc/net/nf_conntrack
    Les états de connexion possibles sont les suivants :
    • NEW : le paquet a démarré une nouvelle connexion ou est associé à une connexion qui n'a pas reçu et envoyé de paquets.
    • ESTABLISHED : le paquet est associé à une connexion qui a reçu et envoyé des paquets.
    • RELATED : le paquet démarre une nouvelle connexion, mais il est associé à une connexion existante.
    • INVALID : le paquet n'est associé à aucune connexion connue.
  • state established, related indique que la commande s'applique uniquement aux connexions dont l'état est ESTABLISHED ou RELATED.
  • accept indique que tout paquet avec l'état approprié peut être accepté.

Il s'agit d'une règle courante dans les configurations de pare-feu pour garantir que les réponses au trafic sortant sont autorisées à nouveau, ce qui permet le fonctionnement normal des services réseau tels que la navigation Web, la connectivité SSH, etc., sans avoir à ouvrir explicitement tous les ports pour les connexions entrantes.

Autoriser le trafic SSH entrant

La ligne suivante ajoute une règle à la chaîne mychain de mytable qui accepte tout le trafic TCP entrant sur le port de destination 22.
sudo nft add rule inet mytable mychain tcp dport 22 accept

Ce port est généralement utilisé pour le trafic SSH et suppose que le démon SSH est configuré et en cours d'exécution sur le système.

Restriction de l'ensemble du trafic IPv4 et IPv6 (bouton Panic)

La ligne suivante ajoute une règle à la table mytable qui supprime toutes les adresses IPv4 et IPv6 entrantes et sortantes et agit comme une sorte de bouton de panique.
sudo nft add rule inet mytable drop

Export de configurations vers un fichier

Pour conserver les configurations nftable d'une initialisation à l'autre ou pour passer d'une configuration à une autre, vous pouvez exporter un fichier nftable en mémoire.

Pour exporter des configurations nftable vers un fichier, procédez comme suit :
  1. Répertoriez les jeux de règles et enregistrez la sortie dans un fichier :

    sudo nft list ruleset > /etc/nftables/<export_file_name>.nft

    Dans la version précédente, <export_file_name> est le nom du fichier pour les informations exportées. Ce fichier contient désormais toutes les tables, chaînes et règles disponibles en mémoire.

  2. Répertoriez une table et enregistrez la sortie dans un fichier :

    sudo nft list table <address_family> <table_name> > /etc/nftables/<export_file_name>.nft

    Ce fichier contient désormais une table et toutes les chaînes et règles associées disponibles en mémoire.

  3. Répertoriez une chaîne et enregistrez la sortie dans un fichier :

    sudo nft list chain <address_family> <table_name> <chain_name> > /etc/nftables/<export_file_name>.nft

    Ce fichier contient désormais une chaîne dans une table et toutes les règles associées de la chaîne disponibles en mémoire.

  4. Assurez-vous que les fichiers inclus dans /etc/nftables sont exécutables :
    sudo chmod +x /etc/nftables/<export_file_name>.nft

Charger des configurations à partir d'un fichier

Pour charger un ensemble de règles, une table ou une chaîne nftable à partir d'un fichier dans la mémoire, vous pouvez effectuer cette tâche manuellement ou automatiquement lors de la réinitialisation d'un système.

Pour charger manuellement un fichier nftables, procédez comme suit :
  1. Avant de charger une nouvelle configuration à partir d'un fichier, supprimez les tables existantes :
    sudo nft flush ruleset
    Remarque

    Cette étape est cruciale pour éviter les conflits entre les nouvelles et les anciennes configurations et garantir une application propre et cohérente des nouvelles règles.
  2. Exécutez la commande suivante pour charger le fichier dans la mémoire :

    sudo nft -f /etc/nftables/<import_file_name>.nft
    Dans la version précédente, <import_file_name> est le nom du fichier contenant les informations à importer. Ce fichier peut contenir un ensemble de règles, une ou plusieurs tables, une ou plusieurs chaînes au sein d'une table et toutes les règles associées.
    Remarque

    Le rechargement atomique est une fonctionnalité nftables qui garantit que le suivi de connexion est conservé lors du rechargement de la règle, ce qui permet une transition transparente vers la nouvelle configuration.
  3. Répertoriez un jeu de règles pour vérifier que le fichier a été importé correctement :

    sudo nft list rulesets
Pour charger automatiquement un ensemble de règles à partir d'un fichier lors du redémarrage du système, procédez comme suit :
  1. Modifiez le fichier /etc/sysconfig/nftables.conf pour inclure les fichiers de table .nft que vous souhaitez inclure au démarrage. Si ce fichier n'existe pas, créez-le Par exemple, l'exemple suivant montre que /etc/sysconfig/nftables.conf inclut désormais le fichier /etc/nftables/myruleset.nft exporté.

    # Uncomment the include statement here to load the default config sample
    # in /etc/nftables for nftables service.
    
    include "/etc/nftables/myruleset.nft"
    
    # To customize, either edit the samples in /etc/nftables, append further
    # commands to the end of this file or overwrite it after first service
    # start by calling: 'nft list ruleset >/etc/sysconfig/nftables.conf'.
    
  2. Activez et démarrez le service nftables :

    sudo systemctl enable --now nftables