Nftables, configurez ce pare-feu Linux comme un expert
Nftables est un projet netfilter qui fournit le filtrage et la classification des paquets sous Linux. C’est l’évolution d’iptables, et en fait il les remplace (on ne peut pas mélanger nftables et iptables). Nftables est capable de remplacer iptables, ip6tables, arptables et ebtables dans le même framework, et tout cela sous le même espace utilisateur (nft) et rétrocompatibilité (avec la syntaxe iptables). Nftables est le framework par défaut dans Debian 10, bien qu’il ne soit pas activé par défaut car il continue d’utiliser la syntaxe iptables, mais pour une courte période.
Si nous utilisons à partir du système Debian 10, le framework installé par défaut est nftables, bien que nous ayons la possibilité de continuer à utiliser la syntaxe iptables sans problème, mais la «base» est le nouveau nftables. Pour utiliser la nouvelle syntaxe, il suffit de l’installer depuis les dépôts officiels. Nftables est compatible avec Kernel Linux 3.13 et versions ultérieures, mais il est recommandé d’utiliser un Kernel 4.7 et versions ultérieures, Debian 10 utilise Kernel 4.19, il fonctionnera donc parfaitement pour nous.
Le framework iptables souffre d’une série de limitations qui ont été améliorées avec ce nouveau framework :
- Évitez les doublons et les incohérences dans le code source.
- De nombreuses extensions iptables ont été dupliquées avec des modifications mineures pour interagir avec différents protocoles.
- Simplifiez l’utilisation dans les environnements IPv4 / IPv6.
- Améliorer les mises à jour de l’ensemble de règles. Cette tâche dans iptables est très coûteuse et peu évolutive.
- Améliorer la syntaxe.
Principales caractéristiques de nftables
Désormais, nftables utilise une syntaxe plus compacte et intuitive inspirée de l’outil tcpdump. Nftables fournit une couche de compatibilité avec iptables, en utilisant la même syntaxe au-dessus du framework nftables (qui est utilisé dans Debian 10 si nft n’est pas installé). Dans nftables, les tables et les chaînes sont entièrement configurables, il n’y a pas de tables prédéfinies qui devraient toujours être là, même si nous ne les utilisons pas (comme c’est le cas avec iptables). Les noms peuvent également être arbitraires.
Une autre caractéristique importante de nftables est que le «match» -m et le «target» -j disparaissent, les nftables ont des expressions. Nftables vous permet de faire plusieurs actions dans une seule règle (plusieurs cibles), ce qui n’était pas facilement possible avec iptables. Par défaut, nous n’avons pas de compteurs intégrés dans les règles et les chaînes, ils sont désormais facultatifs et peuvent être activés si nous le souhaitons. Enfin, nftables permet une gestion plus facile des ensembles de règles IPv4 et IPv6, désormais nous n’aurons plus à «adapter» les règles d’iptables à ip6tables comme auparavant.
Les possibilités de généralisation des règles sont bien meilleures, de plus, une fonctionnalité très importante d’iptables est la fonctionnalité «ipset», qui nous permet d’autoriser ou de bloquer efficacement des millions d’adresses IP ou de sous-réseaux. Nftables a hérité de cette même fonctionnalité mais ce n’est pas un «plugin» que nous devons installer, comme c’était le cas avec ipset et iptables, mais il est directement intégré dans nftables nativement, et son fonctionnement est vraiment simple et facile.
Nous vous recommandons de visiter le site officiel de nftables où vous trouverez tous les détails sur ce pare-feu pour les systèmes d’exploitation Linux.
Mise en place et exécution de nftables sur Debian 10
Pour démarrer nftables dans Debian 10, il suffit d’installer le frontend, tout le reste est déjà installé (et utilisé, même si on met iptables).
sudo apt install nftables
Il n’est pas nécessaire de redémarrer l’ordinateur ou le serveur, rien du Kernel n’est touché, seulement le frontend d’administration du firewall, qui passe désormais d’être en iptables, à être avec la syntaxe de nftables. Un détail très important est que nftables fait une distinction entre les règles temporaires créées sur la ligne de commande et les autres règles permanentes chargées ou enregistrées dans un fichier.
Le fichier par défaut est /etc/nftables.conf, qui contient déjà une simple table de pare-feu pour ipv4 / ipv6 appelée « filtre inet ».
L’utilitaire nftables de l’espace utilisateur, nft, effectue la plupart des évaluations des ensembles de règles avant de les transmettre au noyau du système d’exploitation. Par conséquent, si nous voulons exécuter une commande avec nftables, nous devrons mettre «nft» pour pouvoir l’exécuter, la syntaxe est très simple à comprendre, beaucoup plus facile que iptables que nous avons déjà vu précédemment.
Dans le cas des nftables, les règles sont stockées dans des chaînes, qui à leur tour sont stockées dans des tables. Pour que les modifications restent, nous devons enregistrer les règles directement dans le fichier /etc/nftables.conf . La commande que nous pouvons utiliser pour enregistrer ces règles en permanence et qu’elles soient exécutées avec le redémarrage du système, est la suivante :
nft list ruleset > /etc/nftables.conf
Ensuite, si nous avons incorporé de nouvelles règles manuellement, nous devons redémarrer nftables pour appliquer les modifications :
systemctl restart nftables.service
Toutes les commandes doivent être exécutées en tant qu’administrateur, soit avec «sudo» soit directement avec l’utilisateur «root».
Commandes et fonctionnement de base de Nftables
Si nous voulons consulter les règles que nous avons enregistrées dans le pare-feu, nous devrons mettre l’ordre suivant :
nft list ruleset
Les tables dans nftables hébergent les chaînes, dans nftables nous n’avons pas de tables intégrées comme dans iptables. Le nombre de tables que nous avons et les noms que nous leur donnons dépendent de l’utilisateur. Chaque table n’a qu’une seule famille d’adresses et elle ne s’applique qu’aux paquets de cette famille. Les familles peuvent être :
Famille dans nftables | Équivalent en iptables |
ip | iptables |
ip6 | Ip6tables |
inet | Iptables et ip6tables en même temps |
arp | Arptables |
pont | ebtables |
La famille par défaut est «ip», c’est celle qui sera utilisée si aucune famille n’est précisée lors de la création de la table. Si l’on veut créer une règle qui s’applique à la fois aux réseaux IPv4 et IPv6, l’idéal est d’utiliser «inet» puisqu’il s’agit de l’unification des deux familles. Où l’utiliser à partir d’inet ? Si on veut filtrer, par exemple, les ports TCP/UDP, c’est une très bonne alternative, pour éviter de «dupliquer» les règles dans les réseaux IPv4 et IPv6.
Un détail important est que inet ne fonctionne pas pour les chaînes «nat», seulement pour les chaînes «filtre», c’est-à-dire quand on va filtrer les paquets, mais pas pour faire du NAT. Nous devons nous rappeler qu’iptables autorisait également le NAT source et le NAT de destination, avec nftables exactement la même chose se produit.
Créer un tableau
La syntaxe utilisée pour créer une table est la suivante :
nft add table [familia] [nombre_tabla]
Exemples:
nft add table ip filtrado
nft add table inet filtrado
Comme vous pouvez le voir, nous pouvons créer différentes tables avec différentes familles, en plus, nous pourrions créer une table avec le même nom de table, tant qu’elles appartiennent à des familles différentes, il n’y a pas de problème car en interne nftables détectera qu’elles sont différentes tableaux en fonction de la famille sélectionnée.
Répertorier toutes les tables, chaînes et règles
La syntaxe utilisée pour lister toutes les tables est la suivante :
nft list tables
La syntaxe utilisée pour répertorier les chaînes et les règles d’une table spécifique :
nft list table [familia] [nombre_tabla]
Exemples:
nft list table ip filtrado
nft list table inet filtrado
Comme vous pouvez le voir, si nous avons deux tables avec le même nom (mais qui appartiennent à des familles différentes) nous pouvons les différencier en mettant la famille à laquelle elles appartiennent (ip, inet etc).
Supprimer un tableau
Si nous voulons supprimer une table, nous devons d’abord nous assurer qu’elle n’a aucune chaîne, si elle a une chaîne, elle ne donnera pas d’erreur indiquant que la table n’est pas vide.
La syntaxe pour supprimer une certaine table est :
nft delete table [familia] [nombre_tabla]
Il faut être très prudent lors de la suppression d’une table, car on ne peut pas se tromper de famille ou de nom de table. De plus, un détail très important est qu’il faut d’abord vider la table entière pour la supprimer plus tard, il n’est pas permis de supprimer directement une table s’il y a du contenu à l’intérieur.
Vider une table
Si nous voulons vider toute la table, nous pouvons le faire facilement :
nft flush table [familia] [nombre_tabla]
Cette commande s’occupera de vider toute la table, il faut s’assurer de mettre correctement la famille de la table pour ne pas avoir de problèmes avec celle-ci.
Chaînes : que sont-elles et comment les utiliser
Les chaînes se chargent d’héberger les règles que nous devrons définir par la suite. Contrairement aux chaînes dans iptables, il n’y a pas de chaînes intégrées dans nftables. Cela signifie que si aucune chaîne n’utilise un type ou un hook dans le framework netfilter, les paquets réseau qui transitent par ces chaînes ne seront pas touchés par nftables, contrairement à iptables. Les chaînes sont de deux types :
- Chaîne normale : peut être utilisée comme cible de saut pour une meilleure organisation.
- Chaîne de base : point d’entrée des paquets sur la pile réseau, où une valeur de liaison est spécifiée. La famille est facultative, si elle n’est pas spécifiée par défaut c’est «ip».
Si nous voulons ajouter une chaîne normale, la syntaxe que nous devons suivre est la suivante :
nft add chain [familia] [ tabla] [cadena]
Si nous voulons ajouter une chaîne normale appelée «stringexample» à la table «filtrée» créée précédemment, et que nous utilisons la famille «inet» dans table et chaîne (elles ne peuvent pas être mélangées, cela donne une erreur), nous devons écrire ce qui suit :
nft add table inet filtrado
nft add chain inet filtrado cadenaejemplo
Si nous voulons ajouter une chaîne de base, la syntaxe que nous devons utiliser est la suivante :
nft add chain [familia] [ tabla] [cadena] { type tipo hook el_hook_que_sea priority prioridad policy política; }
- Le «type» peut être : filter, route ou nat.
- Le «crochet» peut être :
Famille | Crochets |
ip/ip6/inet | pré-routage, entrée, transfert, sortie, post-routage |
arp | entrée sortie |
pont | pré-routage, entrée, transfert, sortie, post-routage |
- Priorité : est une valeur entière. Les chaînes avec des nombres inférieurs sont traitées en premier, elles peuvent être négatives, idéales pour une gestion plus facile des chaînes.
- Politique : peut être accepter, abandonner, mettre en file d’attente, continuer ou retourner.
nft add chain [familia] [ tabla] [cadena] { type tipo hook el_hook_que_sea priority prioridad ; }
nft add table inet filtrado
nft add chain inet filtrado cadenabase { type filter hook input priority 0; policy accept; }
Comme vous pouvez le voir, même si au premier abord cela peut sembler très déroutant par rapport à iptables, cette syntaxe est beaucoup plus intuitive que iptables, en plus, on peut modifier les chaînes de base sans aucun problème.
Modifier une chaîne
Ce que nous devons faire, c’est l’appeler par son nom, et définir la nouvelle règle «policy» que nous voulons changer : accepter ou abandonner par exemple. Avec l’exemple précédent, si nous voulons changer la «policy» d’accept to drop : le hook de l’entrée vers la sortie :
nft chain inet filtrado cadenabase { type filter hook output priority 0; policy drop}
Un détail important est que nous ne pourrons pas tout changer dans une chaîne de base, nous ne pourrons pas modifier le nom, ce que nous pouvons faire c’est modifier la politique ou la priorité, mais pas le nom, pour ce faire vous devrez besoin de créer une nouvelle chaîne de base qui se trouve à l’intérieur d’une table d’une certaine famille choisie.
Supprimer une chaîne
Pour supprimer une chaîne, la première chose à faire est de supprimer toutes les règles qu’elle contient. Il ne devrait y avoir aucune règle, aucune cible de saut. Pour supprimer toutes les règles d’une chaîne :
nft flush chain [familia] [tabla] [cadena]
Pour supprimer la chaîne déjà vide :
nft delete chain [familia] [tabla] [cadena]
Comme vous pouvez le voir, supprimer une chaîne est très simple, mais vous devez tenir compte de la table dans laquelle elle se trouve et de la table à laquelle elle appartient, sinon cela renverra une erreur indiquant que cette chaîne n’est pas trouvée.
Règles : qu’est-ce qu’elles sont et comment les créer
Les règles sont construites via des expressions ou des déclarations et sont contenues dans des chaînes. L’utilitaire iptables-translate se charge de « traduire » les règles iptables au format nftables : « iptables-translate –A INPUT –j ACCEPT ».
Pour ajouter une règle à une chaîne :
nft add rule [familia] [tabla] [cadena] handle [identificador] [declaracion]
La «poignée» est facultative et indique la position de la règle dans la chaîne. Si le handle n’est pas spécifié, la règle est placée en fin de chaîne. Pour ajouter une règle à une chaîne (ci-dessus).
nft insert rule [familia] [tabla] [cadena] handle [identificador] [declaracion]
Pour éliminer une règle individuelle spécifique, il faut les éliminer grâce à la poignée utilisée, ou dans la position où nftables l’a placée. Pour voir les identifiants des règles il faut le lister :
nft –-handle list
Pour le supprimer :
nft delete rule [tabla] [cadena] handle [identificador]
nft delete rule tabla input handle 10
Les règles dans nftables incluent une expression de correspondance, puis une instruction qui se résout (si elles correspondent).
Les matchs que nous avons disponibles dans nftables sont :
- meta (iif, iifname, oif, oifname) : index, nom, de l’interface d’entrée/sortie
- icmp : tapez [type d’icmp]
- icmpv6 : tapez [type d’icmpv6]
- Ip : daddr (adresse de destination), saddr (adresse source)
- IPv6 : daddr (adresse de destination), saddr (adresse source)
- Tcp, udp et sctp : dport et sport
- Ct : état [nouveau | établi | liés | invalide]
- Les instructions de résolution sont : accept, drop, queue, continue, return, [string] jump et [string] goto.
Ensuite, vous pouvez voir un exemple où nous bloquons une adresse IP source, et nous bloquons également le trafic TCP et UDP sur un certain port :
nft add table inet firewall
nft add chain inet firewall bloqueo { type filter hook input priority 0; policy accept ; }
nft add rule inet firewall bloqueo ip saddr 192.168.1.2 counter drop
nft add rule inet firewall bloqueo ip saddr 192.168.1.3 tcp dport 80 drop
nft add rule inet firewall bloqueo ip saddr 192.168.1.3 udp dport 80 drop
Maintenant, nous allons créer un «ipset» avec nftables, bien que logiquement ce ne soit pas la même chose. Nous devons nous rappeler qu’IPset nous a permis de créer une énorme liste d’adresses IP et d’adresses réseau à accepter ou à refuser. Cette fonction nftables va nous permettre de faire quelque chose de similaire, l’objectif est de pouvoir ajouter ou supprimer des éléments facilement, sans avoir à définir constamment de nouvelles règles.
nft add set inet firewall ips_baneadas { type ipv4_addr;}
nft add element inet firewall ips_baneadas { 192.168.1.2 }
nft add element inet firewall ips_baneadas { 192.168.1.3, 192.168.4.66 }
nft add rule inet firewall bloqueo ip saddr @ips_baneadas counter drop
Les «types» peuvent être : «ipv4_addr, ipv6_addr, ether_addr, inet_proto, inet_service»
NAT source : configuration du post-routage dans nftables
La configuration Source NAT dans nftables est très similaire à la façon dont nous l’avons fait avec iptables. La première chose que nous devons faire est de créer une table avec le nom que nous voulons, et de créer une chaîne, puis nous définirons le hook et la priorité
nft add table nat
nft add chain nat prerouting { type nat hook prerouting priority 0 ; }
nft add chain nat postrouting { type nat hook postrouting priority 100 ; }
Une fois la chaîne créée, nous allons maintenant définir la règle. Nous pouvons utiliser cette règle lorsque l’adresse IP publique, ou l’adresse IP que nous voulons NATear, est toujours la même :
nft add rule nat postrouting ip saddr 192.168.1.0/24 oif eth0 snat 1.2.3.4
Ou aussi mascarade pour que nous ne dépendions pas de la même adresse IP :
nft add rule nat postrouting masquerade
NAT de destination : configuration de pré-routage dans nftables
La configuration du NAT de destination dans nftables est très similaire à la façon dont nous l’avons fait avec iptables. La première chose que nous devons faire est de créer une table avec le nom que nous voulons, et de créer une chaîne, puis nous définirons le hook et la priorité
nft add table nat
nft add chain nat prerouting { type nat hook prerouting priority 0 ; }
nft add chain nat postrouting { type nat hook postrouting priority 100 ; }
Une fois la chaîne créée, nous allons maintenant définir la règle. Cette règle est utilisée pour transférer les ports TCP de destination 80 et 443, vers l’adresse IP privée définie :
nft add rule nat prerouting iif eth0 tcp dport { 80, 443 } dnat 192.168.1.120
Dans le cas de vouloir faire une redirection de port, d’utiliser un Proxy ou d’effectuer un MitM, nous le ferons de manière très similaire dans iptables :
nft add table nat
nft add chain nat prerouting { type nat hook prerouting priority 0 ; }
nft add chain nat postrouting { type nat hook postrouting priority 100 ; }
Une fois la chaîne créée, nous allons maintenant définir les règles.
nft add rule nat prerouting redirect
nft add rule nat prerouting tcp dport 22 redirect to 2222
Autres exemples de nftables
Nous utilisons «ct» pour contrôler les connexions nouvelles, établies et associées.
ct state established,related accept
Connexions invalides :
ct state invalid drop
Maîtriser les différents types d’ICMP
ip protocol icmp icmp type { destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem } accept
Contrôler une limite de pings reçus
ip protocol icmp icmp type echo-request limit rate over 10/second burst 4 packets drop
Limiter un nombre maximum de tentatives SSH
tcp dport ssh ct state new limit rate 15/minute accept
Si on veut «sauter» ou sauter sur une autre chaîne, on peut le faire très facilement et de manière plus intuitive :
table inet filter {
chain ssh_server {
tcp dport ssh accept
}
chain input {
type filter hook input priority 0;
ip saddr 10.10.2.2/24 jump ssh_server
drop
}
}
Comme vous l’avez vu, nftables est beaucoup plus simple à utiliser que iptables, c’est plus intuitif. Cependant, pour ceux d’entre nous qui sont habitués à iptables, nous devrons travailler et nous mettre à jour avec la nouvelle syntaxe intégrée à nftables. Nous espérons que ce tutoriel sur les caractéristiques et la configuration de base des nftables vous aidera et que vous vous entraînerez avec le nouveau pare-feu Linux.