ricsanfre.firewall
Rôle Ansible : Pare-feu
Installer et configurer un pare-feu (basé sur nftables) sur Linux.
Exigences
Aucune.
Variables de Rôle
Les variables disponibles sont listées ci-dessous avec leurs valeurs par défaut (voir defaults\main.yaml
)
Activation du NAT et du transfert de trafic
- firewall_forward_enabled : Activer ou désactiver le support du transfert de trafic pour un hôte donné. [défaut :
false
]. - firewall_nat_enabled : Activer ou désactiver le support du NAT pour un hôte donné. [défaut :
false
].
Définir les ports ouverts par défaut
- in_tcp_port : Le trafic TCP entrant est autorisé sur ces ports. [défaut :
{ ssh }
]. - in_udp_port : Le trafic UDP entrant est autorisé sur ces ports. [défaut :
{ snmp }
]. - out_tcp_port : Le trafic TCP sortant est autorisé sur ces ports. [défaut :
{ http, https, ssh }
]. - out_udp_port : Le trafic UDP sortant est autorisé sur ces ports. [défaut :
{ domain, bootps , ntp }
].
Dictionnaires de Règles
Pour chaque chaîne dans la table IP (input, output, forward) et la table NAT (nat-prerouting et nat-postrouting), les règles nft sont stockées dans des dictionnaires qui peuvent être remplacés au niveau du groupe et de l'hôte.
Variables et ensembles de définitions et règles globales
Ensemble de variables et ensembles de définitions utilisés par les différentes chaînes de règles et règles de chaîne globale qui peuvent être invoquées depuis une autre chaîne en utilisant la règle jump global
.
définir | ensembles | chaîne globale |
---|---|---|
nft_define_default | nft_set_default | nft_global_default |
nft_define_group | nft_set_group | nft_global_group_rules |
nft_define_host | nft_set_host | nft_global_host_rules |
Règles de la table IP
chaîne d'entrée | chaîne de sortie | chaîne de transfert |
---|---|---|
nft_input_default_rules | nft_output_default_rules | nft_forward_default_rules |
nft_input_group_rules | nft_output_group_rules | nft_forward_group_rules |
nft_input_host_rules | nft_output_host_rules | nft_forward_host_rules |
Règles de la table NAT
chaîne de pré-routage | chaîne de post-routage |
---|---|
nft_nat_default_prerouting_rules | nft_nat_default_postrouting_rules |
nft_nat_group_prerouting_rules | nft_nat_group_postrouting_rules |
nft_nat_host_prerouting_rules | nft_nat_host_postrouting_rules |
Chaque type de dictionnaire de règles sera fusionné et les règles seront appliquées dans l'ordre alphabétique des clés (raison pour laquelle on utilise 000 à 999 comme préfixe). Donc :
- nft_*_default_rules : Définir les règles par défaut pour tous les nœuds. Vous pouvez le définir dans
group_vars/all
. - nft_*_group_rules : Peut ajouter des règles et remplacer celles définies par nft_*_default_rules et nft_*_rules. Vous pouvez le définir dans
group_vars/group_servers
. - nft_*_host_rules : Peut ajouter des règles et remplacer celles définies par nft_*_default_rules, nft_*_group_rules et nft_*_rules. Vous pouvez le définir dans
host_vars/specific_host
.
Configuration par défaut de nftables
Par défaut, le rôle générera le fichier de configuration suivant :
/etc/nftables.conf
#!/usr/sbin/nft -f
# Géré par Ansible
# nettoyer
flush ruleset
include "/etc/nftables.d/defines.nft"
table inet filter {
chaîne globale {
# 000 gestion de l'état
ct state established,related accept
ct state invalid drop
}
include "/etc/nftables.d/sets.nft"
include "/etc/nftables.d/filter-input.nft"
include "/etc/nftables.d/filter-output.nft"
}
/etc/nftables.d/defines.nft
# diffusion et multidiffusion
define badcast_addr = { 255.255.255.255, 224.0.0.1, 224.0.0.251 }
# diffusion et multidiffusion
define ip6_badcast_addr = { ff02::16 }
# in_tcp_accept
define in_tcp_accept = { ssh }
# in_udp_accept
define in_udp_accept = { snmp }
# out_tcp_accept
define out_tcp_accept = { http, https, ssh }
# out_udp_accept
define out_udp_accept = { domain, bootps , ntp }
/etc/nftables.d/sets.nft
set blackhole {
type ipv4_addr;
elements = $badcast_addr
}
set in_tcp_accept {
type inet_service; flags interval;
elements = $in_tcp_accept
}
set in_udp_accept {
type inet_service; flags interval;
elements = $in_udp_accept
}
set ip6blackhole {
type ipv6_addr;
elements = $ip6_badcast_addr
}
set out_tcp_accept {
type inet_service; flags interval;
elements = $out_tcp_accept
}
set out_udp_accept {
type inet_service; flags interval;
elements = $out_udp_accept
}
/etc/nftables.d/filter-input.nft
chaîne input {
# 000 politique
type filter hook input priority 0; policy drop;
# 005 global
jump global
# 010 supprimer les indésirables
ip daddr @blackhole counter drop
# 011 supprimer les indésirables ipv6
ip6 daddr @ip6blackhole counter drop
# 015 localhost
iif lo accept
# 050 icmp
meta l4proto {icmp,icmpv6} accept
# 200 udp d'entrée accepté
udp dport @in_udp_accept ct state new accept
# 210 tcp d'entrée accepté
tcp dport @in_tcp_accept ct state new accept
}
/etc/nftables.d/filter-output.nft
chaîne output {
# 000 politique
type filter hook output priority 0; policy drop;
# 005 global
jump global
# 015 localhost
oif lo accept
# 050 icmp
ip protocol icmp accept
ip6 nexthdr icmpv6 counter accept
# 200 udp sortant accepté
udp dport @out_udp_accept ct state new accept
# 210 tcp sortant accepté
tcp dport @out_tcp_accept ct state new accept
# 250 réinitialiser-ssh
tcp sport ssh tcp flags { rst, psh | ack } counter accept
}
Et le jeu de règles suivant sur l'hôte (montré en exécutant la commande nft list ruleset
):
table inet filter {
set blackhole {
type ipv4_addr
elements = { 224.0.0.1, 224.0.0.251,
255.255.255.255 }
}
set in_tcp_accept {
type inet_service
flags interval
elements = { 22 }
}
set in_udp_accept {
type inet_service
flags interval
elements = { 161 }
}
set ip6blackhole {
type ipv6_addr
elements = { ff02::16 }
}
set out_tcp_accept {
type inet_service
flags interval
elements = { 22, 80, 443 }
}
set out_udp_accept {
type inet_service
flags interval
elements = { 53, 67, 123 }
}
chaîné global {
ct state established,related accept
ct state invalid drop
}
chaîné input {
type filter hook input priority filter; policy drop;
jump global
ip daddr @blackhole counter packets 0 bytes 0 drop
ip6 daddr @ip6blackhole counter packets 0 bytes 0 drop
iif "lo" accept
meta l4proto { icmp, ipv6-icmp } accept
udp dport @in_udp_accept ct state new accept
tcp dport @in_tcp_accept ct state new accept
}
chaîné output {
type filter hook output priority filter; policy drop;
jump global
oif "lo" accept
ip protocol icmp accept
ip6 nexthdr ipv6-icmp counter packets 0 bytes 0 accept
udp dport @out_udp_accept ct state new accept
tcp dport @out_tcp_accept ct state new accept
tcp sport 22 tcp flags { rst, psh | ack } counter packets 0 bytes 0 accept
}
}
Dépendances
Aucune
Exemples de Playbooks
Appliquer les règles par défaut
Installer et configurer un pare-feu sur un hôte avec des règles par défaut
- hosts: serverx
roles:
- ricsanfre.firewall
dans group_vars/all.yml
, vous pouvez remplacer les règles par défaut pour tous vos hôtes :
nft_input_default_rules:
000 politique:
- type filter hook input priority 0; policy drop;
005 global:
- jump global
010 supprimer les indésirables:
- ip daddr @blackhole counter drop
011 supprimer les indésirables ipv6:
- ip6 daddr @ip6blackhole counter drop
015 localhost:
- iif lo accept
050 icmp:
- meta l4proto {icmp,icmpv6} accept
200 udp d'entrée accepté:
- udp dport @in_udp_accept ct state new accept
210 tcp d'entrée accepté:
- tcp dport @in_tcp_accept ct state new accept
Modifier les règles par défaut au niveau du groupe
Ouvrir le trafic HTTP entrant pour le groupe webservers
:
Dans group_vars/webservers.yml
, cela peut être fait en modifiant in_tcp_port
:
in_tcp_port: { ssh, http }
Ou en ajoutant une nouvelle règle spécifique
nft_input_group_rule:
220 entrée web acceptée:
- tcp dport http ct state new accept
Modifier les règles par défaut + les règles du groupe au niveau de l'hôte
Ouvrir le trafic HTTPS entrant pour l'hôte secureweb
dans host_vars/secureweb.yml
, vous voudriez ouvrir https et supprimer l'accès à http :
nft_input_group_rule:
220 entrée web acceptée: []
230 entrée sécurité web acceptée:
- tcp dport https ct state new accept
Les règles par défaut peuvent être supprimées
Pour "supprimer" des règles, vous assignez simplement une liste vide à une clé de dictionnaire existante : Exemple : désactiver le trafic ICMP entrant
nft_input_host_rules:
050 icmp: []
Supprimer les règles par défaut permettant tout le trafic sortant. dans un group_vars/group.yml
spécifique
nft_output_group_rules:
000 politique:
- type filter hook output priority 0;
005 global:
-
015 localhost:
-
050 icmp:
-
200 sortie udp acceptée:
-
210 sortie tcp acceptée:
-
La règle par défaut 000 politique
est remplacée pour accepter tout le trafic et le reste des règles est supprimé.
Pour résumer, les règles dans nft_X_host_rules
écraseront les règles dans nft_X_group_rules
, puis les règles dans nft_X_group_rules
écraseront les règles dans nft_X_default_rules
.
Licence
MIT/BSD
Informations sur l'auteur
Ricardo Sanchez (ricsanfre)
Nftables-based firewall installation and configuration role
ansible-galaxy install ricsanfre.firewall