nftables : Règles de filtrage basique du pare-feu (firewall) Le sujet est résolu

Demande d'aide : c'est ici.
Répondre
Avatar de l’utilisateur
dezix
Membre hyper actif
Membre hyper actif
Messages : 3548
Inscription : 04 juin 2016, 14:50
Status : Hors-ligne

Bonjour, :006:

Je rencontre quelques difficultés pour mettre en place des règles simples de filtrage pour le pare-feu avec nftables

Pour que les choses soient claires : J'ai zéro expérience avec iptables que je ne compte jamais utiliser, puisque c'est déjà du passé.

J'ai lu, traduit, résumé le gros de la doc ; du moins en ce qui concerne les commandes nft ...


Mon but

Pour l'installation de base d'un poste d'administrateur sécurisé,
dans un 1er temps je souhaite autoriser uniquement le trafic d'APT
entre le poste et les dépôts du sources.list — soit le minimum pour la mise à jour du poste.

La situation

Code : Tout sélectionner

$ cat /etc/apt/sources.list

deb [arch=amd64] http://deb.debian.org/debian/ buster main non-free contrib
deb [arch=amd64] http://security.debian.org/debian-security buster/updates main contrib non-free
deb [arch=amd64] http://deb.debian.org/debian/ buster-updates main contrib non-free
Adresse des serveurs de dépôts Debian

Déjà un léger soucis :

Sur mon poste de travail habituel (testing) j'ai :

Code : Tout sélectionner

$ ping -c 1 security.debian.org
PING security.debian.org (151.101.130.132): 56 data bytes
64 bytes from 151.101.130.132: icmp_seq=0 ttl=57 time=11,086 ms
--- security.debian.org ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 11,086/11,086/11,086/0,000 ms

$ ping -c 1 deb.debian.org
PING debian.map.fastlydns.net (199.232.178.132): 56 data bytes
64 bytes from 199.232.178.132: icmp_seq=0 ttl=57 time=10,235 ms
--- debian.map.fastlydns.net ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 10,235/10,235/10,235/0,000 ms
donc une sortie en IPv4

et sur le poste Admin (stable)

Code : Tout sélectionner

# ping -c 1 deb.debian.org
PING deb.debian.org(2a04:4e42:6c::644 (2a04:4e42:6c::644)) 56 data bytes
64 bytes from 2a04:4e42:6c::644 (2a04:4e42:6c::644): icmp_seq=1 ttl=57 time=10.8 ms

--- deb.debian.org ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 10.823/10.823/10.823/0.000 ms

# ping -c 1 security.debian.org
PING security.debian.org(2a04:4e42:600::644 (2a04:4e42:600::644)) 56 data bytes
64 bytes from 2a04:4e42:600::644 (2a04:4e42:600::644): icmp_seq=1 ttl=57 time=11.7 ms

--- security.debian.org ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 11.740/11.740/11.740/0.000 ms

donc en IPv6

et je n'ai pas trouvé dans : man ping
l'information sur le choix de type d'adresse test/sortie ???

NFTABLES

Code : Tout sélectionner

# apt install nftables

# systemctl enable nftables

# systemctl start nftables

# systemctl status nftables
● nftables.service - nftables
   Loaded: loaded (/lib/systemd/system/nftables.service; enabled; vendor preset: enabled)
   Active: active (exited) since Sun 2021-03-14 14:07:13 UTC; 18min ago
     Docs: man:nft(8)
           http://wiki.nftables.org
  Process: 289 ExecStart=/usr/sbin/nft -f /etc/nftables.conf (code=exited, status=0/SUCCESS)
 Main PID: 289 (code=exited, status=0/SUCCESS)


Donc le service est Actif


Règles de filtrage

J'ai placé dans : /etc/nftables/admin.rules

Code : Tout sélectionner


#!/sbin/nft -f

flush ruleset

table ip filter {
        chain input {
                type filter hook input priority 0; policy drop;
                ip saddr 199.232.178.132 accept
                ip saddr 151.101.130.132 accept
        }

        chain forward {
                type filter hook forward priority 0; policy drop;
                counter comment "count dropped packets"
        }

        chain output {
                type filter hook output priority 0; policy drop;
		ip daddr 199.232.178.132 accept
		ip daddr 151.101.130.132 accept
        }
}

table ip6 filter {
        chain input {
                type filter hook input priority 0; policy drop;
		ip6 saddr 2a04:4e42:6c::644 accept
		ip6 saddr 2a04:4e42::644 accept
        }

        chain forward {
                type filter hook forward priority 0; policy drop;
                counter comment "count dropped packets"
        }

        # If you're not counting packets, this chain can be omitted.
        chain output {
                type filter hook output priority 0; policy drop;
		ip6 daddr 2a04:4e42:6c::644 accept
		ip6 daddr 2a04:4e42::644 accept
        }
}



Puis :

# nft -f /etc/nftables/admin.rules

Les régles sont correctement prises en compte :

Code : Tout sélectionner

# nft list ruleset

table ip filter {
	chain input {
		type filter hook input priority 0; policy drop;
		ip saddr 199.232.178.132 accept
		ip saddr 151.101.130.132 accept
	}

	chain forward {
		type filter hook forward priority 0; policy drop;
		counter packets 0 bytes 0 comment "count dropped packets"
	}

	chain output {
		type filter hook output priority 0; policy drop;
		ip daddr 199.232.178.132 accept
		ip daddr 151.101.130.132 accept
	}
}
table ip6 filter {
	chain input {
		type filter hook input priority 0; policy drop;
		ip6 saddr 2a04:4e42:6c::644 accept
		ip6 saddr 2a04:4e42::644 accept
	}

	chain forward {
		type filter hook forward priority 0; policy drop;
		counter packets 0 bytes 0 comment "count dropped packets"
	}

	chain output {
		type filter hook output priority 0; policy drop;
		ip6 daddr 2a04:4e42:6c::644 accept
		ip6 daddr 2a04:4e42::644 accept
	}
}

Sauf que :

Code : Tout sélectionner

# apt update
Err :1 http://deb.debian.org/debian buster InRelease
  Erreur temporaire de résolution de « deb.debian.org »
Err :2 http://security.debian.org/debian-security buster/updates InRelease
  Erreur temporaire de résolution de « security.debian.org »
Err :3 http://deb.debian.org/debian buster-updates InRelease
  Erreur temporaire de résolution de « deb.debian.org »
Lecture des listes de paquets... Fait
Construction de l'arbre des dépendances       
Lecture des informations d'état... Fait
5 paquets peuvent être mis à jour. Exécutez « apt list --upgradable » pour les voir.
W: Impossible de récupérer http://deb.debian.org/debian/dists/buster/InRelease  Erreur temporaire de résolution de « deb.debian.org »
W: Impossible de récupérer http://security.debian.org/debian-security/dists/buster/updates/InRelease  Erreur temporaire de résolution de « security.debian.org »
W: Impossible de récupérer http://deb.debian.org/debian/dists/buster-updates/InRelease  Erreur temporaire de résolution de « deb.debian.org »
W: Le téléchargement de quelques fichiers d'index a échoué, ils ont été ignorés, ou les anciens ont été utilisés à la place.

idem pour ping

Code : Tout sélectionner

# ping -c 1 deb.debian.org
ping: deb.debian.org: Échec temporaire dans la résolution du nom

# ping -c 1 security.debian.org
ping: security.debian.org: Échec temporaire dans la résolution du nom

Par contre après :

# nft flush ruleset

Code : Tout sélectionner

# ping -c 1 deb.debian.org
# ping -c 1 security.debian.org
# ping -c 1 199.232.178.132
# ping -c 1 151.101.130.132
# ping -c 1 2a04:4e42:6c::644
# ping -c 1 2a04:4e42::644
tous les "pings" refonctionnent bien.



Question

Que faut-il modifier dans le script : /etc/nftables/admin.rules

pour atteindre le but recherché ?


Merci.
**Simple Utilisateur** -- Debian stable - XFCE
PascalHambourg
Contributeur
Contributeur
Messages : 930
Inscription : 05 août 2016, 20:25
Status : Hors-ligne

dezix a écrit : 14 mars 2021, 17:16 dans un 1er temps je souhaite autoriser uniquement le trafic d'APT
entre le poste et les dépôts du sources.list — soit le minimum pour la mise à jour du poste.
Mon pauvre, tu n'as pas choisi le plus simple pour tes débuts avec le filtrage de paquets.

En préambule, je précise que je ne suis pas encore familiarisé avec nftables, mais les principes du filtrage IP restent les mêmes qu'avec iptables. La règle n° 1, tu l'as compris, c'est d'identifier le trafic. Et ce n'est pas si simple.
dezix a écrit : 14 mars 2021, 17:16 je n'ai pas trouvé dans : man ping
l'information sur le choix de type d'adresse
Ça dépend de la version/variante de ping et de la connectivité de la machine.
Avec certaines versions, ping = IPv4 et ping6 = IPv6.
Avec d'autres, ping4 ou "ping -4" = IPv4, ping6 ou "ping -6" = IPv6 et ping = IPv4 ou IPv6 selon ce que retourne la résolution de nom et la connectivité IPV4/IPv6 de la machine.

De toute façon, ping n'est pas le bon outil pour déterminer la ou plutôt les adresses IP associées à un nom de domaine car il n"utilise et affiche qu'une seule des adresses IP possibles. Il vaut mieux utiliser les outils dédiés aux requêtes DNS comme dig, host ou nslookup. host est pratique parce que par défaut il recherche les adresses IPv4 et IPv6. Mais ce n'est pas toujours suffisant car les adresses IP retournées peuvent varier dans le temps ou selon la localisation "géographique" (GeoDNS).

En passant, tu as oublié d'autoriser le trafic DNS dans tes règles nftables, c'est ce qui cause les erreurs que tu observes.

Par ailleurs, les miroirs Debian, et notamment deb.debian.org, sont un cas particulier comme on peut le voir sur sa page d'accueil http://deb.debian.org/ :
- Le nom n'est pas utilisé dans une requête DNS de type A ou AAAA pour obtenir directement une adresse IPv4 ou IPv6 comme le fait ping, mais dans une requête DNS de type SRV pour obtenir les ports et les noms de domaine des véritables serveurs. C'est seulement en absence d'enregistrement SRV qu'apt va faire une requête A ou AAAA.
- Le serveur, qu'il ait été obtenu par SRV ou A/AAAA, peut n'être qu'un "aiguilleur" qui va répondre à chaque requête par une redirection vers un URL pointant sur un autre serveur, qui peut être différent pour chaque requête.

Par exemple, de chez moi :

Code : Tout sélectionner

host -t srv _http._tcp.deb.debian.org
_http._tcp.deb.debian.org has SRV record 10 1 80 debian.map.fastlydns.net.

host debian.map.fastlydns.net.
debian.map.fastlydns.net has address 199.232.178.132
debian.map.fastlydns.net has IPv6 address 2a04:4e42:6c::644
Mais rien ne dit qu'à l'expiration des enregistrements DNS ils ne retourneront pas d'autres adresses, et ça ne prend pas en compte d'éventuelles redirections HTTP. Bref, tu n'es pas sorti de l'auberge.

Concernant tes règles nftables elles-mêmes, elles ne sont pas bonnes. Pour autoriser les connexions à un serveur, on ne fait pas :
- autoriser tous les paquets sortants à destination du serveur
- autoriser tous les paquets entrants provenant du serveur
car cela autorise tout protocole autre que celui envisagé, et dans les deux sens. Donc on fait plutôt :
- autoriser les paquet sortants à destination du serveur pour le protocole et le port destination de l'application
- autoriser les paquets entrants qui appartiennent à une connexion établie

J'oubliais un dernier mot concernant IPv6 : sur un réseau local, pour qu'une communication IPv6 soit possible il faut autoriser les paquets ICMPv6 "NDP" (équivalent d'ARP), soit les types neighbor-advertisement et neighbor-solicitation en entrée et sortie, et si la machine utilise l'autoconfiguration sans état, router-advertisement en entrée et router-solicitation en sortie.
Avatar de l’utilisateur
dezix
Membre hyper actif
Membre hyper actif
Messages : 3548
Inscription : 04 juin 2016, 14:50
Status : Hors-ligne

Oui, effectivement ça n'a pas l'air d'être simple.

Merci pour ces pistes.
**Simple Utilisateur** -- Debian stable - XFCE
Avatar de l’utilisateur
dezix
Membre hyper actif
Membre hyper actif
Messages : 3548
Inscription : 04 juin 2016, 14:50
Status : Hors-ligne

PascalHambourg a écrit : 14 mars 2021, 20:14 En passant, tu as oublié d'autoriser le trafic DNS dans tes règles nftables, c'est ce qui cause les erreurs que tu observes.

Effectivement, avec les règles autorisant le trafic sur le port 53 dédié aux requêtes dns :

Code : Tout sélectionner

tcp sport 53 accept
udp sport 53 accept
cela résoud le problème, et c'est nécessaire aussi p.ex pour permettre la navigation internet (http ; https) sur les ports 80 et 443 respectivement


Je pensais pouvoir faire l'économie d'une règle avec la syntaxe :

{tcp, udp} sport 53 accept

mais cela me renvoie une erreur de syntaxe au chargement du script.



Pour mon cas d'usage : Uniquement le trafic d'APT,
j'ai inclu le dns et simplifié comme suit :

Code : Tout sélectionner

#!/sbin/nft -f

flush ruleset

table inet filter {
        chain input {
                type filter hook input priority 0; policy drop;
		tcp sport 53 accept
		udp sport 53 accept
                ip saddr 199.232.178.132 accept
                ip saddr 151.101.130.132 accept
        }
        chain output {
                type filter hook output priority 0; policy drop;
                tcp dport 53 accept
		udp dport 53 accept
                ip daddr 199.232.178.132 accept
                ip daddr 151.101.130.132 accept
        }
}
avec cela les commandes apt update ; apt install
fonctionnent correctement.

Remarquez que j'utise un script car l'usage des commandes # nft add .... passées directement dans bash me renvoient des erreurs de syntaxes que je suis pas parvenu à corriger.


Si une bonne âme dispose d'un pense-bête complet et bien fait pour écrire les règles nftables
.... ce serait avec joie merci !
**Simple Utilisateur** -- Debian stable - XFCE
Avatar de l’utilisateur
dezix
Membre hyper actif
Membre hyper actif
Messages : 3548
Inscription : 04 juin 2016, 14:50
Status : Hors-ligne

Au niveau du pense-bête je n'ai rien trouvé de mieux que : Quick reference-nftables in 10 minutes - nftables wiki
**Simple Utilisateur** -- Debian stable - XFCE
Répondre