17 votes

Quelle est la différence entre "iifname" et "iif" dans nftables ?

https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes#Meta

Y a-t-il une différence entre iifname (hors le nom est une chaîne) et iif et ce qui est recommandé ?

22voto

A.B Points 7722

iif recherche et compare l'index de l'interface du paquet reçu, alors que iifname effectue une comparaison de chaîne avec le nom de l'interface. Les deux ont des avantages et des inconvénients.

Alors iif utilise moins de ressources, parce que l'index de l'interface est une numéro simple déjà stocké dans le paquet traversant la pile réseau et les nftables et donc immédiatement disponibles pour la comparaison. Mais son inconvénient est que si l'interface est supprimée (et très probablement recréée, mais avec une valeur d'index plus récente), la règle correspondante dans nftables ne correspondra plus. Le seul index d'interface garanti à tout moment est celui de l'interface de bouclage (nommé lo par défaut) : il est toujours le premier créé dans l'espace de noms et ne peut pas être supprimé (ni ajouté une seconde fois), donc sa valeur d'index est toujours 1 .

iifname d'un autre côté, tout comme l'option d'iptables --in-interface effectue une comparaison de chaîne avec le nom de l'interface actuelle. Cela utilise plus de ressources, mais permet de créer une règle pour une interface inexistante, à l'avance, avec un nom déterministe, qui iif ne se fera pas facilement. iifname peut aussi faire des correspondances avec des caractères génériques, comme dans iifname "ppp*" qui iif ne peut pas faire et peut être pratique lorsque les interfaces sont créées et supprimées souvent, mais garder une convention d'appellation (comme commencer par ppp pour les liaisons PPP).

Exemple (avec nftables 0.9.2) :

$ unshare -r -n
# ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# nft add table ip filter
# nft add chain ip filter input '{ type filter hook input priority 0; policy accept; }'
# nft add rule ip filter input iif lo counter
# nft add rule ip filter input iif dummy0 counter
Error: Interface does not exist
add rule ip filter input iif dummy0 counter
                             ^^^^^^
# nft add rule ip filter input iifname dummy0 counter
# ip link add name dummy0 type dummy
# ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 4a:09:68:3a:34:91 brd ff:ff:ff:ff:ff:ff
# nft add rule ip filter input iif dummy0 counter
# nft list ruleset
table ip filter {
    chain input {
        type filter hook input priority filter; policy accept;
        iif "lo" counter packets 0 bytes 0
        iifname "dummy0" counter packets 0 bytes 0
        iif "dummy0" counter packets 0 bytes 0
    }
}
# ip link delete dev dummy0
# nft list ruleset
table ip filter {
    chain input {
        type filter hook input priority filter; policy accept;
        iif "lo" counter packets 0 bytes 0
        iifname "dummy0" counter packets 0 bytes 0
        iif 2 counter packets 0 bytes 0
    }
}

L'interface ayant disparu, sa valeur d'index est affichée à la place. De même, une valeur d'index peut être utilisée, même à l'avance, lors de l'ajout d'une règle :

# nft add rule ip filter input iif 3 counter
# nft list ruleset
table ip filter {
    chain input {
        type filter hook input priority filter; policy accept;
        iif "lo" counter packets 0 bytes 0
        iifname "dummy0" counter packets 0 bytes 0
        iif 2 counter packets 0 bytes 0
        iif 3 counter packets 0 bytes 0
    }
}
# ip link add name dummy4 type dummy
# ip link add name dummy0 type dummy
# nft list ruleset
table ip filter {
    chain input {
        type filter hook input priority filter; policy accept;
        iif "lo" counter packets 0 bytes 0
        iifname "dummy0" counter packets 0 bytes 0
        iif 2 counter packets 0 bytes 0
        iif "dummy4" counter packets 0 bytes 0
    }
}

Étant donné que les valeurs d'index d'interface ne sont pas recyclées au sein de l'espace de nommage mais seulement augmentées, la règle concernant l'index 2 est "perdue" (elle n'aura plus jamais la chance de correspondre). La prochaine interface créée, factice4 s'est vu attribuer l'indice 3, qui se résume maintenant à dummy4 dans le jeu de règles. fictif0 a reçu la valeur d'index 4, qui n'est pas référencée dans une quelconque iif mais elle correspondra toujours à la règle iifname règle.


Qu'est-ce qui est recommandé ?

Mon conseil :

Vous devez utiliser iif pour les interfaces "stables" qui ne changeront pas une fois créées, comme les interfaces ethernet physiques disponibles au démarrage, avant que la règle ne soit appliquée (si l'on utilise la nouvelle convention de dénomination stable des interfaces physiques, celle-ci ne changera pas si l'ordre d'énumération change), et bien sûr l'option lo interface. Cela n'a pas été montré dans l'exemple, mais vous pouvez toujours faire correspondre une liste d'interfaces avec iif aussi, comme iif { lo, dummy4 } . Donc vous pouvez toujours avoir un seul iif correspondant à plusieurs interfaces.

Vous devez utiliser iifname pour les interfaces dynamiques qui ne sont pas connues au démarrage (et lors de la création des règles) mais qui devraient apparaître plus tard, ou pour faire correspondre un groupe d'interfaces avec une convention de dénomination lors de l'utilisation d'un caractère générique.

Pas très connu, pour optimiser, au lieu d'utiliser des jokers, vous pourriez attribuer un groupe à chaque interface nouvellement créée, (par exemple en utilisant ip link set dev interface group 99 ) et ensuite faire correspondre le groupe d'interface avec iifgroup plutôt que iifname + joker. Mais cela nécessite un mécanisme supplémentaire pour regrouper les interfaces nouvellement créées.

Vous pouvez également utiliser l'interface ensembles nommés ce qui permet de conserver les règles génériques utilisant iif y iifname et de modifier le contenu des ensembles nommés, plutôt que les règles elles-mêmes. Notez que le lien wiki précédent ne parle pas de l'utilisation des interfaces dans les ensembles, mais il n'est tout simplement pas à jour. Plus d'informations à ce sujet dans ma réponse UL SE à cette question : Comment créer un ensemble nommé de chaînes de caractères dans nftables (pour les noms d'interface) ? .

4voto

Andrej Podzimek Points 131

Il ne s'agit pas d'une réponse, mais simplement d'un commentaire sur une réponse précédente . (Ma mauvaise réputation ne me permet pas de commenter).

Mais cela nécessite un mécanisme supplémentaire pour regrouper les interfaces nouvellement créées.

J'utilise systemd-networkd pour faire ça^^^. Il a un [Link] où vous pouvez définir le groupe d'interface pour chaque interface. (Il s'agit du [Link] section lue à partir de .network fichiers par systemd-networkd et non le [Link] section lue à partir de .link fichiers par systemd-udevd .)

Je mettrais donc quelque chose comme ceci dans /etc/systemd/network/something.network

[Match]
MACAddress=my:in:te:rf:ac:e0
...

[Link]
Group=99
...

et ensuite ip link show group 99 peut être utilisé pour vérifier que les interfaces sont (effectivement) marquées correctement. (Celles qui n'ont pas de groupe sont dans le groupe 0 .) (Aussi ip link show imprime les numéros de groupe).

Cela permet d'utiliser iifgroup y oifgroup en nftables.conf .

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X