RHEL / CentOS Maintenant pour ajouter des règles nftable à firewalld au démarrage du système?
J'utilise firewalld sur RHEL 8 et je dois également ajouter quelques règles nftable.
(Les règles nftable sont basées sur la réponse à CentOS 8 en tant que routeur NAT avec nft et firewalld - comment le faire passer TFTP? )
Dans un pare-feu en cours d'exécution, cela fonctionne bien avec la commande nft -f.
Cependant, cela se perd lors d'un redémarrage.
La documentation RedHat (derrière le paywall) suggère d'utiliser le service nftables.service pour charger les règles au redémarrage, mais cela ne fonctionne pas en conjonction avec firewalld. Les deux services sont répertoriés comme étant en conflit, et même s'ils ne l'étaient pas, firewalld viderait probablement les règles nftable.
Existe-t-il un autre moyen de charger les règles nftable au redémarrage?
Réponses
L' utilitaire firewalld , lors de l'utilisation du backend nftables , ne videra pas les tables qui ne lui appartiennent pas :
Ne vider que les règles de firewalld
Puisque nftables autorise les espaces de noms (via des tables), firewalld ne fait plus un vidage complet des règles de pare-feu . Cela videra uniquement les règles de la table firewalld . Cela évite les scénarios dans lesquels des règles utilisateur personnalisées ou des règles installées par d'autres outils sont effacées de manière inattendue lorsque firewalld a été redémarré ou rechargé.
La même chose doit être faite lors de la gestion d'autres tables.
En fait , dans la réponse précédente, il est déjà fait: les nftables règles supprime idempotently que leur propre table: handletftp
.
Malheureusement, ce n'est pas le cas nftables.service
pour l' action d' arrêt :
ExecStop=/sbin/nft flush ruleset
Il faut simplement s'assurer que la partie d'arrêt du service systemd ne vide pas directement toutes les règles tout en faisant le travail. Ce travail sera délégué dans des règles nftables dédiées pour l' action d' arrêt .
Voici donc une méthode pratique: dupliquer (par exemple systemctl cat nftables.services
:) et modifier nftables.service
en une version instanciée [email protected]
à insérer /etc/systemd/system/[email protected]
:
[Unit]
Description=Idempotent nftables rules for %I
Wants=network-pre.target
Before=network-pre.target
[Service]
Type=oneshot
ProtectSystem=full
ProtectHome=true
ExecStart=/sbin/nft -f /etc/nftables/idempotent/%I.nft
# As the rules are idempotent, ExecReload is same as ExecStart
ExecReload=/sbin/nft -f /etc/nftables/idempotent/%I.nft
# The stop rules should only have the first boilerplate parts
ExecStop=/sbin/nft -f /etc/nftables/idempotent/stop-%I.nft
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Créez le répertoire de configuration dédié utilisé ci-dessus:
mkdir -p /etc/nftables/idempotent
Placez les règles qui pour chaque table définie, commencent toujours comme ceci, donc le chargement des règles est indépendant des autres tables et idempotent (exemple avec des tables ip foo
et bridge bar
):
table ip foo
delete table ip foo
table bridge bar
delete table bridge bar
table ip foo {
...
}
table bridge bar {
....
}
ou utilisez simplement une table par fichier. La flush ruleset
déclaration est interdite car elle est globale.
La raison pour laquelle une table est créée, supprimée et recréée est d'obtenir le résultat idempotent: alors que la suppression d'une table inexistante est une erreur et ferait échouer atomiquement tout le chargement, déclarant une table existante sans la définir (en ajoutant une table vide) n'échoue jamais et ne fait rien sauf le créer vide s'il n'existait pas auparavant. Dans les deux cas (n'existait pas au démarrage, existe au rechargement), la suppression peut maintenant fonctionner, laissant la place pour vraiment définir la table juste après. Tout cela se passe dans la même transaction et est toujours atomique: aucun paquet ne sera jamais évalué avec une table ip foo manquante si elle existait auparavant pendant cela.
Préparez une version d' arrêt de ci-dessus qui supprimera uniquement (ici, les déclarations vides ne sont pas strictement nécessaires et pourraient être supprimées s'il n'y avait qu'une seule table, mais devraient être conservées s'il y a plus d'une table: l'échec concerne toute la transaction):
table ip foo
delete table ip foo
table bridge bar
delete table bridge bar
et mettez tout à leur emplacement:
/etc/nftables/idempotent/foobar.nft
/etc/nftables/idempotent/stop-foobar.nft
Cela peut maintenant être activé avec:
systemctl enable --now local-idempotent-nft@foobar
Exemple tiré de la question du précédent OP:
dans /etc/nftables/idempotent/handletftp.nft
:
table ip handletftp
delete table ip handletftp
table ip handletftp {
ct helper helper-tftp {
type "tftp" protocol udp
}
chain sethelper {
type filter hook forward priority 0; policy accept;
ip saddr 192.168.1.0/24 ip daddr 10.0.10.10 udp dport 69 ct helper set "helper-tftp"
}
}
Dans /etc/nftables/idempotent/stop-handletftp.nft
table ip handletftp
delete table ip handletftp
Activation et démarrage:
systemctl enable --now local-idempotent-nft@handletftp
L'arrêter:
systemctl stop local-idempotent-nft@handletftp
ce qui laissera les règles de firewalld en place. De même, l'arrêt ou le redémarrage de firewalld laissera ces règles en place.
Il y a probablement des améliorations à faire:
- nftables a une instruction include qui pourrait être utilisée d'une manière ou d'une autre pour éviter la duplication du passe-partout.
- l'exemple spécifique de TFTP repose sur le chargement de
nf_nat_tftp
ce qui ne se fera pas automatiquement (contrairement ànf_conntrack_tftp
ce qui est automatiquement chargé à partir de référence dans les règles ou contrairement à firewalld qui se chargeraitnf_nat_tftp
explicitement). Donc, les configurations liées mais non strictement nftables doivent être gardées à l'esprit (ce paramètre peut simplement être mis en place/etc/modules-load.d/
).