Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
pratique:informatique:parefeu:nftables [02/06/2025 14:46] – [Fichier par défaut et fonctionnement] Zatalyzpratique:informatique:parefeu:nftables [25/06/2025 20:40] (Version actuelle) – [Sur hyperviseur exposé sur internet] Zatalyz
Ligne 85: Ligne 85:
  
 === Smurf Attack === === Smurf Attack ===
-C'est une attaque assez sournoise. En français "Attaque par rebond" mais c'est moins drôle comme nom.+C'est une attaque assez sournoise. En français "Attaque par rebond" mais c'est moins drôle comme nom. C’est une attaque par amplification où un attaquant envoie des paquets ICMP Echo Request (ping) avec une IP source usurpée (celle de la victime) à une adresse de diffusion (broadcast), souvent 255.255.255.255 (broadcast limité) ou 224.0.0.1 (multicast “all hosts”). Tous les hôtes qui reçoivent ça répondent à l’IP usurpée, il y a saturation du réseau et DoS ciblé.
  
 Il y a deux cas de figures. Il y a deux cas de figures.
Ligne 94: Ligne 94:
 ip daddr 224.0.0.1 drop</code> ip daddr 224.0.0.1 drop</code>
  
-Mais si on utilise un bridge réseau (cas classique quand on a un hyperviseur), on risque de mettre un sacré boxon dans le réseau interne, et il faut être plus fin. La solution basique consiste à utiliser le nom du réseau et donc à utiliser la règle suivante (si le bridge est br0) :  +Mais si on utilise un bridge réseau (cas classique quand on a un hyperviseur), on risque de mettre un sacré boxon dans le réseau interne, et il faut être plus fin.
-<code># Protection contre le Smurf Attack +
-iifname != "br0" ip daddr 255.255.255.255 drop +
-iifname != "br0" ip daddr 224.0.0.1 drop</code> +
-Ou même autoriser explicitement ARP (adresses MAC) et DHCP :  +
-<code># Protection contre le Smurf Attack +
-# Laisser passer ARP (sinon les VM ne pourront pas résoudre les adresses IP en MAC) +
-arp accept+
  
-# Laisser passer DHCP (car les requêtes DHCP utilisent 255.255.255.255) +La solution basique consiste à utiliser le nom du réseau (via un ''define IFACES_LAN = { "lo", "xenbr0" }''((Si le bridge est ''xenbr0'')) en début de table en général) et à utiliser la règle suivante : on bloque tout broadcast qui ne vient pas des interfaces internes, mais on autorise explicitement ARP((Adresses MAC)) et DHCP((les requêtes DHCP des VM utilisent 255.255.255.255)) à fonctionner en interne sinon on va être coincé.
-ip protocol udp th dport 67 accept +
-ip protocol udp th dport 68 accept+
  
-Bloquer les broadcasts/multicasts seulement sur les interfaces externes +<code bash>Autoriser ARP (sinon les VMs se retrouvent isolées) 
-iifname != "br0" ip daddr 255.255.255.255 drop +meta iifname $IFACES_LAN ether type arp accept 
-iifname != "br0" ip daddr 224.0.0.1 drop</code>+# Autoriser DHCP (indispensable avec des VMs clients DHCP) 
 +meta iifname $IFACES_LAN ip protocol udp udp dport { 67, 68 } accept 
 +# Bloquer le broadcast limité uniquement sur le WAN 
 +ip daddr 255.255.255.255224.0.0.1 } iifname != $IFACES_LAN drop</code>
  
 <WRAP center round info 100%> <WRAP center round info 100%>
-L'adaptation des règles dépend très fortement du type de pont. Je sens que ça va me filer des boutons. N'utilisez cette règle qu'en vérifiant son effet.+L'adaptation des règles dépend très fortement du type de pont. N'utilisez cette règle qu'en vérifiant son effet
 + 
 +Pour ipv6, ça a encore l'air d'être une autre affaire. Je ne maitrise pas.
 </WRAP> </WRAP>
  
Ligne 153: Ligne 149:
 }</code> }</code>
  
-On peut aussi définir des variables avec ''define'' (au début du fichier plutôt) et ensuite les appeler. +On peut aussi définir des variables avec ''define'' (au début du fichier plutôt, mais dans la table) et ensuite les appeler. 
-<code>define tcp_ports = {80, 443}+<code>
 table inet firewall { table inet firewall {
-        chain inbound { +  define tcp_ports = {80, 443} 
-                type filter hook input priority 0; policy drop; +  chain inbound { 
-                tcp dport { $tcp_ports } ct state new accept+    type filter hook input priority 0; policy drop; 
 +    tcp dport { $tcp_ports } ct state new accept 
 +  } 
 +}
  
 </code> </code>
 +
 +=== Modulariser : une ou plusieurs chaines/fichiers ? ===
 +Comme expliqué en intro, on peut donner n'importe quel nom à une chaine, mais il y a des conditions pour qu'elle soit exécutée. 
 +
 +  * Une chaine est exécutée si elle a l'élément ''type [x] hook [y]''
 +  * Ou si elle a été appelé depuis une autre chaine avec ''jump machaine''.
 +
 +Par exemple : 
 +<code>
 +table inet firewall {
 +  chain inbound {
 +    type filter hook input priority 0; policy drop;
 +      jump machinssh
 +  }
 +  chain machinssh {
 +    counter comment "Compteur SSH"
 +  }
 +}
 +</code>
 +
 +Pourquoi faire "jump" et pas simplement tout mettre dans la même chaine ? 
 +  * Quand une règle doit être appelée plusieurs fois (par exemple pour input ET output)
 +  * pour déclarer
 +  * Pour clarifier les blocs et potentiellement n'intervenir que sur un bout. Cela pourrait être des fichiers séparés, modifiés par Ansible par exemple. 
 +  * Il suffit de commenter un "jump" pour désactiver tout ce qui ne va pas avec ;)
 +
 +Exemple d'architecture avec des fichiers séparés : 
 +<code>/etc/nftables.d/
 +├── 00-definitions.nft
 +├── 10-sets.nft
 +├── 20-input.nft
 +├── 30-fight.nft
 +├── 40-confperso.nft
 +└── 99-main.nft</code>
 +
 +Le nftables.conf ressemblera alors à ceci : 
 +<code bash nftables.conf>#!/usr/sbin/nft -f
 +
 +flush ruleset
 +
 +include "/etc/nftables.d/00-definitions.nft"
 +include "/etc/nftables.d/10-sets.nft"
 +include "/etc/nftables.d/20-input.nft"
 +include "/etc/nftables.d/30-fight.nft"
 +include "/etc/nftables.d/40-confperso.nft"</code>
 +
 +Cela permet alors de ne recharger/modifier qu'un seul des fichiers. Ils peuvent même être générés dynamiquement (par des scripts, Fail2ban ou Reaction). 
  
 === Ips martiennes === === Ips martiennes ===
Ligne 215: Ligne 261:
  
 J'ai mis une option : si l'hyperviseur est derrière une box, on peut permettre ssh en direct sur le réseau local (adresses en 192.168.1.*). Mais il ne faut pas permettre de le faire depuis les VM (10.0.0.*)...  J'ai mis une option : si l'hyperviseur est derrière une box, on peut permettre ssh en direct sur le réseau local (adresses en 192.168.1.*). Mais il ne faut pas permettre de le faire depuis les VM (10.0.0.*)... 
 +
 +<WRAP center round important 100%>
 +Ça <del>compile</del> ne génère pas d'erreur avec ''sudo nft -cof nftables.conf''. Ça ne veux pas dire que tout va marcher. J'ai pas encore assez testé certaines des règles. 
 +</WRAP>
 +
  
 <code bash /etc/nftables.conf> <code bash /etc/nftables.conf>
Ligne 221: Ligne 272:
 flush ruleset flush ruleset
  
-# Table sur le trafic de type input/output/forward. De base on rejette tout, sauf ce qui est explicitement autorisé.+# Table sur le trafic de type input/output/forward.  
 +De base on rejette tout, sauf ce qui est explicitement autorisé. 
 +# Séparer ipv4 et ipv6 simplifie le travail... 
 table inet firewall { table inet firewall {
-    # Liste pour bannir les IP malveillantes temporairement +    # ------------------------------ 
-    set blocklist +    # Define : des trucs à déclarer une fois ici 
-        type addr +    # ------------------------------ 
-        # Ceci va ajuster le temps de bannissement suivant les récidives +    # Le nom de nos interfaces 
-        flags timeout+    define IFACES_LAN = { "lo", "xenbr0"
 +    define IFACES_WAN = { "enp2s0"
 +    # ------------------------------ 
 +    # SETS - alimenter des listes suivant des critères précis 
 +    # ------------------------------ 
 +    set allowlistsys 
 +        # Les ip autorisées à faire des trucs sur le réseau  
 +        # Ip internes et ip fixes de sysadmin 
 +        type ipv4_addr 
 +        flags interval 
 +        elements = { 109.190.202.194, 192.168.1.0/24 }
     }     }
-    # Et ceci est le compteur pour les récidivistes +    # Blocklist : ce qui est bloqué durablement. Alimenté par Reaction/Fail2ban. 
-    set offender_count +    # Interval : permet de bloquer des plages d'ip. 
-        type addr +    set blocklist_v4 
-        counters+        type ipv4_addr 
 +        flags interval
     }     }
-    # Set dynamique pour suivre les (plagesIP suspectes en temps réel +    set blocklist_v6 { 
-    set realtime_block +        type ipv6_addr 
-        type addr family inet hash+        flags interval 
 +    } 
 +    blocage temporaire à court terme en cas d'excès, timeout court (10s).  
 +    # Sert à "tamponner". Et à alimenter Blocklist au besoin. 
 +    set tempblock_v4 
 +        type ipv4_addr 
 +        flags timeout 
 +        timeout 10s
         size 1024         size 1024
-        timeout 10s  # Timeout après 10 secondes 
     }     }
 +    set tempblock_v6 { 
 +        type ipv6_addr 
 +        flags timeout 
 +        timeout 10s 
 +        size 1024 
 +    } 
 +    set martienne_v4 { 
 +        # Adresses non-routables ou réservées, si ça ne vient pas du bon port, c'est une attaque. 
 +        type ipv4_addr 
 +        flags interval 
 +        elements = { 0.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.0.0/24, 192.0.2.0/24, 192.88.99.0/24, 192.168.0.0/16, 198.18.0.0/15, 198.51.100.0/24, 203.0.113.0/24, 224.0.0.0/4, 240.0.0.0/4 } 
 +    } 
 +    set martienne_v6 { 
 +        type ipv6_addr 
 +        flags interval 
 +        elements = { ::/128, ::1/128, ::ffff:0:0/96, 64:ff9b::/96, 100::/64, 2001::/23, 2001:db8::/32, 2002::/16, fc00::/7, fe80::/10, ff00::/8 } 
 +    }
     # ------------------------------     # ------------------------------
-    # Règles spécifiques IPv6+    # Autorisations explicites 
 +    # TODO : Adapter au réel ;)
     # ------------------------------     # ------------------------------
-    chain input_ipv6 +    chain confperso 
-        # Paquets ICMPv6 qui ne doivent pas être rejetés, voir https://tools.ietf.org/html/rfc4890#section-4.4.1 et https://wiki.nftables.org/wiki-nftables/index.php/Simple_ruleset_for_a_server +        # Autoriser SSH si : 
-        meta nfproto ipv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-reply, echo-request, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, 148, 149 } accept +        # - source = Bastion1 (externe)mettre son ip, c'est pas 101.1.1.1 
-        # Protège contre certaines attaques de spoofing en s'assurant que ces messages viennent bien d’un hôte local. +        OU source dans le LAN 192.168.1.0/24 (UNIQUEMENT quand on est derrière une box
-        ip6 saddr fe80::/10 icmpv6 type { 130, 131, 132, 143, 151, 152, 153 } accept +        # SSH ne sera sans doute pas sur le port 22, adapter..
- +        ip saddr @allowlistsys tcp dport 22 ct state new accept 
-        # Vérifie si l'IP est bannie +        # Autoriser certains ports quand les services liés sont actifs, ici le web 
-        # On différencie ipv4 et ipv6 parce que si les règles sont les mêmes (cf plus bas),  +        tcp dport 80, 443 ct state new accept 
- # visiblement ça va aider de filtrer par type d'ip +        # Proxmox : autoriser l’accès à l’interface web uniquement depuis certaines ip (fixesperso
-        ip6 saddr @blocklist drop +        ip saddr @allowlistsys tcp dport 8006 accept 
-        # Mise à jour du compteur de récidive IPv6 +        tcp dport 8006 drop  # Refuser tout le reste
-        # Ces temps (10m, 30m, 1h) suffisent à limiter les attaques sans trop grossir la BL +
-        # et ne bloquent pas un humain de façon trop violente+
-        ip6 saddr @offender_count update counter +
-        ip6 saddr @offender_count counter > 5 add @blocklist { ip6 saddr timeout 1h } +
-        ip6 saddr @offender_count counter > 3 add @blocklist ip6 saddr timeout 30m } +
-        ip6 saddr @offender_count counter > 1 add @blocklist { ip6 saddr timeout 10m } +
- +
-        # Protection contre les attaques IPv6 (flood udpsyn, ack, rst, ping (on accepte+
-        ip6 nexthdr udp limit rate over 200/second add @offender_count { ip6 saddr } drop +
-        tcp flags syn limit rate over 100/second add @offender_count { ip6 saddr } drop +
-        tcp flags ack limit rate over 100/second add @offender_count { ip6 saddr } drop +
-        tcp flags rst limit rate over 50/second add @offender_count { ip6 saddr } drop +
-        icmpv6 type echo-request limit rate 10/second accept +
-        icmpv6 type echo-request limit rate over 10/second add @offender_count { ip6 saddr } drop+
     }     }
 +    
     # ------------------------------     # ------------------------------
     # Règles génériques entrantes     # Règles génériques entrantes
Ligne 278: Ligne 352:
         type filter hook input priority 0; policy drop;         type filter hook input priority 0; policy drop;
                  
-        # Vérifie si l'IP est bannie +        # Vérifie si l'IP est bannie durablement 
-        ip saddr @blocklist drop +        ip saddr @blocklist_v4 drop 
-        # Mise à jour du compteur de récidive IPv4 +        ip6 saddr @blocklist_v6 drop 
-        ip saddr @offender_count update counter +        # Ou dans la liste temporaire 
-        ip saddr @offender_count counter > 5 add @blocklist { ip saddr timeout 1h } +        ip saddr @tempblock_v4 drop 
-        ip saddr @offender_count counter > 3 add @blocklist { ip saddr timeout 30m } +        ip6 saddr @tempblock_v6 drop
-        ip saddr @offender_count counter > 1 add @blocklist { ip saddr timeout 10m }+
  
         # Autoriser le trafic de paquets "etablished" et associés, supprimer les paquets non valides         # Autoriser le trafic de paquets "etablished" et associés, supprimer les paquets non valides
         ct state vmap { established : accept, related : accept, invalid : drop }         ct state vmap { established : accept, related : accept, invalid : drop }
 +        
         # Autorise le loopback         # Autorise le loopback
         iifname "lo" accept         iifname "lo" accept
  
-        ## Mesures anti-DDoS+        # Spécial ipv6 
 +        # Paquets ICMPv6 qui ne doivent pas être rejetés, voir https://tools.ietf.org/html/rfc4890#section-4.4.1 et https://wiki.nftables.org/wiki-nftables/index.php/Simple_ruleset_for_a_server 
 +        ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-reply, echo-request, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, 148, 149 } accept 
 +        # Protège contre certaines attaques de spoofing en s'assurant que ces messages viennent bien d’un hôte local. 
 +        meta iifname $IFACES_LAN ip6 saddr fe80::/10 icmpv6 type { 130, 131, 132, 143, 151, 152, 153 } accept 
 + 
 +        # Appelle les chaines utiles 
 +        jump confperso 
 +        jump fight 
 + 
 +    } 
 + 
 +    # ------------------------------ 
 +    # Mesures pour limiter diverses attaques 
 +    # ------------------------------ 
 +    chain fight { 
 +        # Empêcher le loopback reçu ailleurs que sur lo 
 +        ip saddr 127.0.0.0/8 iifname != "lo" drop 
 +        ip6 saddr ::1 iifname != "lo" drop 
 +        # Bloquer les IP martiennes si elles ne viennent pas de LAN 
 +        ip saddr @martienne_v4 iifname != $IFACES_LAN drop 
 +        ip6 saddr @martienne_v6 iifname != $IFACES_LAN drop 
 +        # Attention suivant le réseau local, il faut peut-être autoriser des ip explicitement (définir un set au besoin) 
 + 
         # Autorise le ping avec une limite pour les abus / Protection contre ICMP Flood (Ping Flood)         # Autorise le ping avec une limite pour les abus / Protection contre ICMP Flood (Ping Flood)
         # Ping normal : 1/s. Attention des outils de monitorings peuvent être plus rapides (jusque 20/s).         # Ping normal : 1/s. Attention des outils de monitorings peuvent être plus rapides (jusque 20/s).
-        icmp type echo-request limit rate 10/second accept +        # Ping IPv4 
-        icmp type echo-request limit rate over 10/second add @offender_count { ip saddr } drop+        ip protocol icmp icmp type echo-request limit rate 10/second accept 
 +        ip protocol icmp icmp type echo-request limit rate over 10/second add @tempblock_v4 { ip saddr } counter log prefix "[TEMPBLOCK PING]" drop 
 +        # Ping IPv6 
 +        ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate 10/second accept 
 +        ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate over 10/second add @tempblock_v6 { ip6 saddr } counter log prefix "[TEMPBLOCK PING6]" drop
  
         # Protection contre UDP Flood         # Protection contre UDP Flood
-        ip protocol udp limit rate over 200/second add @offender_count { ip saddr } drop +        ip protocol udp limit rate over 200/second add @tempblock_v4 { ip saddr } counter log prefix "[TEMPBLOCK UDP]" drop 
 +        ip6 nexthdr udp limit rate over 200/second add @tempblock_v6 { ip6 saddr } counter log prefix "[TEMPBLOCK UDP6]" drop 
 +        
         # Protection contre le DNS Query Flood         # Protection contre le DNS Query Flood
-        ip protocol udp th dport 53 limit rate over 50/second add @offender_count { ip saddr } drop+        ip protocol udp th dport 53 limit rate over 50/second add @tempblock_v4 { ip saddr } counter log prefix "[TEMPBLOCK DNS]" drop
  
         # Protection contre le SYN Flood, ACK Flood & RST Flood         # Protection contre le SYN Flood, ACK Flood & RST Flood
-        tcp flags syn limit rate over 100/second add @offender_count { ip saddr } drop +        # Mais on ne rejette pas tout, faut bien que les serveurs puissent se saluer 
-        tcp flags ack limit rate over 100/second add @offender_count { ip saddr } drop +        # Les attaques sur syn sont plus fréquentes, valeur entre 50 et 100, rst répond donc idem, 
-        tcp flags rst limit rate over 50/second add @offender_count { ip saddr } drop+        # mais ack bénéficie de valeurs plus hautes (jusque 200) 
 +        # Bref à adapter au trafic réel (=> monitoring !) 
 +        tcp flags syn,rst limit rate over 100/second add @tempblock_v4 { ip saddr } counter log prefix "[TEMPBLOCK SYN]" drop 
 +        tcp flags ack limit rate over 100/second add @tempblock_v4 { ip saddr } counter log prefix "[TEMPBLOCK ACK]" drop
  
 +        ip6 nexthdr tcp tcp flags syn,rst limit rate over 50/second add @tempblock_v6 { ip6 saddr } counter log prefix "[TEMPBLOCK SYN6]" drop
 +        ip6 nexthdr tcp tcp flags ack limit rate over 100/second add @tempblock_v6 { ip6 saddr } counter log prefix "[TEMPBLOCK ACK6]" drop
 +        
         # Protection contre le Smurf Attack         # Protection contre le Smurf Attack
-        ip daddr 255.255.255.255 drop +        # Autoriser ARP (sinon les VMs se retrouvent isolées) 
-        ip daddr 224.0.0.1 drop +        meta iifname $IFACES_LAN ether type arp accept 
-        # Attention en cas d'utilisation d'un bridgeça va mettre le boxon +        # Autoriser DHCP (indispensable avec des VMs clients DHCP) 
-        # Dans ce cas exclure spécifiquement d'après le nom du bridge +        meta iifname $IFACES_LAN ip protocol udp udp dport { 6768 } accept 
-        #iifname != "br0" ip daddr 255.255.255.255 drop +        # Bloquer le broadcast limité uniquement sur le WAN 
-        #iifname != "br0" ip daddr 224.0.0.1 drop+        ip daddr 255.255.255.255224.0.0.1 } iifname != $IFACES_LAN drop
  
         # Protection contre le SMTP/Email Bombing         # Protection contre le SMTP/Email Bombing
-        ip protocol tcp th dport 25 limit rate over 10/second add @offender_count { ip saddr } drop+        ip protocol tcp th dport 25 limit rate over 10/second add @tempblock_v4 { ip saddr } counter log prefix "[TEMPBLOCK SMTP]" drop
  
-        # Protection contre les botnets sur les ports fréquemment ciblés+        # Protection contre les botnets sur les ports fréquemment ciblés (peuvent servir de honeypot)
         # tcp  : telnet (23, 2323), UPnP (7547)         # tcp  : telnet (23, 2323), UPnP (7547)
         # udp : Memcached (11211), SSDP (1900), LDAP (389), NTP (123), IoT (48101)          # udp : Memcached (11211), SSDP (1900), LDAP (389), NTP (123), IoT (48101) 
-        ip protocol tcp th dport { 23, 2323, 7547 } add @offender_count { ip saddr } drop +        ip protocol tcp th dport { 23, 2323, 7547 } add @tempblock_v4 { ip saddr } counter log prefix "[TEMPBLOCK BADPORT]" drop 
-        ip protocol udp th dport { 11211, 1900, 389, 123, 48101 } add @offender_count { ip saddr } drop+        ip protocol udp th dport { 11211, 1900, 389, 123, 48101 } add @tempblock_v4 { ip saddr } counter log prefix "[TEMPBLOCK BADPORT]" drop
  
         # Bloquer les scans de ports en cas de tentative de connexion rapide sur des ports multiples         # Bloquer les scans de ports en cas de tentative de connexion rapide sur des ports multiples
-        ip protocol tcp limit rate over 50/second counter add @offender_count { ip saddr } drop +        ip protocol tcp limit rate over 50/second add @tempblock_v4 { ip saddr } counter log prefix "[TEMPBLOCK SCAN]" drop 
-        ip protocol udp limit rate over 50/second counter add @offender_count { ip saddr } drop +        ip protocol udp limit rate over 50/second add @tempblock_v4 { ip saddr } counter log prefix "[TEMPBLOCK SCAN]" drop
-        # Règle de détection de scan de port via compteur (connexions multiples sur des ports distincts, ici 50 ports/seconde) +
-        ip protocol tcp sport != 0 limit rate over 50/second add @offender_count { ip saddr } drop +
- +
-        # Applique les règles en plus suivant le protocole (ici ipv6) +
-        meta protocol vmap { ip6 : jump input_ipv6 } +
- +
-        # Realtime Blocking pour détecter les attaques basées sur des plages d'IP +
-        ip saddr @realtime_block counter add @realtime_block { ip saddr } drop +
-        ip saddr @realtime_block limit rate over 200/second add @realtime_block { ip saddr } drop +
-         +
-        # Autoriser SSH si : +
-        # - source = Bastion1 (externe). mettre son ip, c'est pas 101.1.1.1 +
-        # - OU source dans le LAN 192.168.1.0/24 (UNIQUEMENT quand on est derrière une box) +
-        # SSH ne sera sans doute pas sur le port 22, adapter... +
-        ip saddr { 101.1.1.1, 192.168.1.0/24 } tcp dport 22 ct state new accept +
-        # Autoriser certains ports quand les services liés sont actifs, ici le web +
-        tcp dport { 80, 443 } ct state new accept +
- +
-        # Logging des connexions bloquées +
-        log prefix "[nftablesInbound Denied: counter drop +
-         +
-        # Proxmox : autoriser l’accès à l’interface web uniquement depuis certaines ip (fixes, perso) +
-        ip saddr 10.0.0.10 tcp dport 8006 accept +
-        tcp dport 8006 drop  # Refuser tout le reste +
-        +
     }     }
- 
     # ------------------------------     # ------------------------------
     # Règles génériques sortantes     # Règles génériques sortantes
     # ------------------------------     # ------------------------------
 +
     chain output {     chain output {
         # Par défaut, on rejette tout à moins de suivre une des règles ci-dessous.         # Par défaut, on rejette tout à moins de suivre une des règles ci-dessous.
         type filter hook output priority 0; policy drop;         type filter hook output priority 0; policy drop;
         # Autoriser le trafic de paquets "etablished" et associés, supprimer les paquets non valides         # Autoriser le trafic de paquets "etablished" et associés, supprimer les paquets non valides
-        ct state established accept+        ct state established,related accept
         # Autorise le loopback sortant         # Autorise le loopback sortant
         oifname "lo" accept         oifname "lo" accept
         # Autorise le ping sortant         # Autorise le ping sortant
         ip protocol icmp accept         ip protocol icmp accept
 +        ip6 nexthdr icmpv6 accept
         # Autoriser d'aller sur internet et de contacter les dns (domain)         # Autoriser d'aller sur internet et de contacter les dns (domain)
         tcp dport { http, https } accept         tcp dport { http, https } accept
         udp dport domain accept         udp dport domain accept
 +        tcp dport domain accept
 +        # Autoriser msmtp à envoyer ses mails
 +        tcp dport { 25, 465, 587 } ct state new,established accept
 +        # Autoriser NTP
 + udp dport { 53, 123 } ct state new,established accept
 +        # Log de ce qui est bloqué
 +        log prefix "[NFT OUTPUT DROP] " flags all drop
 +       
     }     }
  
Ligne 380: Ligne 473:
         # Autoriser le trafic de paquets "etablished" et associés, supprimer les paquets non valides         # Autoriser le trafic de paquets "etablished" et associés, supprimer les paquets non valides
         ct state established accept         ct state established accept
-        # Redirection des connexions web vers la VM 11 (proxy gérant le web). TODO différence daddr/saddr 
-        ip daddr 192.168.1.11 tcp dport { http, https } accept 
-        ip saddr 192.168.1.11 udp dport domain accept 
-        ip saddr 192.168.1.11 tcp dport { http, https } accept 
-        # Mail vers la VM mail 
-        ip daddr 192.168.1.10 tcp dport { 25, 143, 587, 993 } accept 
-        ip saddr 192.168.1.10 tcp dport { 25, 143, 587, 993 } accept 
     }     }
 } }
  
-# Table sur le trafic de type prerouting/postrouting, par défaut sur accept pour que les connexions puissent s'initialiser 
-table ip nat { 
-    chain prerout { 
-        type nat hook prerouting priority 0; policy accept; 
-        # ce qui va sur les ports web doit être redirigé vers la VM 
-        tcp dport { http, https } dnat to 192.168.1.11 
-        # Rediriger SMTP, IMAP, etc. vers la VM mail 
-        tcp dport { 25, 143, 587, 993 } dnat to 192.168.1.10 
-    } 
- 
-    chain postrout { 
-        type nat hook postrouting priority 0; policy accept; 
-        # Ce qui vient de la VM et qui tente de se connecter au web doit sortir par l'ip de notre proxy 
-        # Sinon on est redirigé sur nous-même... 
-        ip saddr 192.168.1.11 snat to 66.66.66.66 
-    } 
-} 
  
 </code> </code>
  
-<WRAP center round todo 100%> +=== Ports suivant les services ===
-=== Machine seule ===+
-Pour un dédié, une machine exposé directement à internet.  +
- +
- +
-==== Machine terminale ==== +
-<WRAP center round todo 60%> +
-À reprendre +
-</WRAP> +
- +
-Config dans une vm après un proxy etc. Cette machine est placée derrière un routeur (box, proxy...) qui sera un peu plus complet, et surtout qui empêche déjà de rentrer n'importe comment. +
-<code bash /etc/nftables.conf> +
-#!/usr/sbin/nft -f +
- +
-flush ruleset +
- +
-table inet firewall { +
-        # Règles spécifiques ipv6 +
-        chain inbound_ipv6 { +
-            # accept neighbour discovery otherwise connectivity breaks +
-            # source : https://wiki.nftables.org/wiki-nftables/index.php/Simple_ruleset_for_a_server +
-            icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept +
-            # TODO comprendre ! ICMPv6 packets which must not be dropped, see https://tools.ietf.org/html/rfc4890#section-4.4.1 +
-            meta nfproto ipv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-reply, echo-request, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, 148, 149 } accept +
-            ip6 saddr fe80::/10 icmpv6 type { 130, 131, 132, 143, 151, 152, 153 } accept +
-        } +
-  +
-        # Règles génériques entrantes +
-        chain inbound { +
-            # Par défaut, on rejette tout à moins de suivre une des règles ci-dessous. +
-            type filter hook input priority 0; policy drop; +
-            # Autoriser le trafic de paquets "etablished" et associés, supprimer les paquets non valides +
-            ct state vmap { established : accept, related : accept, invalid : drop } +
-            # Autorise le loopback +
-            iifname "lo" accept +
-            # Autorise le ping avec une limite pour les abus +
-            icmp type echo-request limit rate 5/second accept +
-            # Applique les règles en plus suivant le protocole(ici ipv6, on pourrait ajouter des trucs sur ipv4) +
-            meta protocol vmap { ip6 : jump inbound_ipv6 } +
-            # Autoriser certains ports quand les services liés sont actifs (donc à adapter), ici le web et ssh +
-            tcp dport { 22, 80, 443 } ct state new accept +
-            # Uncomment to enable logging of denied inbound traffic +
-            # log prefix "[nftables] Inbound Denied: " counter drop +
-            # TODO ! count and drop any other traffic +
-            #counter drop +
-        } +
-        # En sortie (output) par défaut ça autorise tout et en théorie c'est ok. +
-        # forward, nat etc : pas utile dans ce cas de figure. +
-+
- +
-</code>+
  
 Si serveur mail : remplacer Si serveur mail : remplacer
Ligne 470: Ligne 489:
   tcp dport { 22, 80, 443, 25, 587, 993, 4190 } ct state new accept   tcp dport { 22, 80, 443, 25, 587, 993, 4190 } ct state new accept
  
- +=== Todo === 
-==== Machine proxy, configuration sécuritaire ==== +Faire plus modulaireAdapter quand c'est pour une VM, un dédié... Mais la config de l'hyperviseur doit être une bonne base
-<WRAP center round todo 60%> +
-À reprendre ; mieux vaut utiliser ma première config ! +
-</WRAP> +
-Cette machine redirige une partie du trafic vers d'autres machines (probablement localement, mais ça peut être ailleurs) et on va donc ajouter NAT et ForwardCas typique des proxy, xen, proxmox, etc.  +
- +
-Ici on va desservir l'ip interne (une VM) ''10.10.10.69'' (adresse à adapter suivant les machines derrière le proxy, donc). L'adresse ipv4 externe d'exemple est 66.66.66.66.  +
- +
-<WRAP center round todo 60%> +
-Faudra améliorer sur ipv6. +
-</WRAP> +
- +
- +
-L'exemple est assez parano sur le trafic sortant et ce qui passe par l'autre machine, par défaut rien n'est permis sauf ce qui est explicite. On peut évidement être plus souple sur output/forward suivant les cas d'usage.  +
- +
-<code bash /etc/nftables.conf> +
-#!/usr/sbin/nft -f +
- +
-flush ruleset +
- +
-# Table sur le trafic de type input/output/forward. De base on rejette tout, sauf ce qui est explicitement autorisé. +
-table inet firewall { +
-        # Règles spécifiques ipv6 +
-        chain input_ipv6 { +
-            # accept neighbour discovery otherwise connectivity breaks +
-            # source : https://wiki.nftables.org/wiki-nftables/index.php/Simple_ruleset_for_a_server +
-            icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept +
-            # TODO comprendre ! ICMPv6 packets which must not be dropped, see https://tools.ietf.org/html/rfc4890#section-4.4.1 +
-            meta nfproto ipv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-reply, echo-request, nd-router-solicit,> +
-            ip6 saddr fe80::/10 icmpv6 type { 130, 131, 132, 143, 151, 152, 153 } accept +
-        } +
-  +
-        # Règles génériques entrantes (valables pour ipv6 et ipv4) +
-        chain input_all { +
-            # Par défaut, on rejette tout à moins de suivre une des règles ci-dessous. +
-            type filter hook input priority 0; policy drop; +
-            # Autoriser le trafic de paquets "etablished" et associés, supprimer les paquets non valides +
-            ct state vmap { established : accept, related : accept, invalid : drop } +
-            # Autorise le loopback +
-            iifname "lo" accept +
-            # Autorise le ping avec une limite pour les abus +
-            icmp type echo-request limit rate 5/second accept +
-            # Applique les règles en plus suivant le protocole(ici ipv6, on pourrait ajouter des trucs sur ipv4) +
-            meta protocol vmap { ip6 : jump input_ipv6 } +
-            # Autoriser certains ports quand les services liés sont actifs (donc à adapter), ici le web et ssh +
-            tcp dport { 22, 80, 443 } ct state new accept +
-            # Uncomment to enable logging of denied inbound traffic +
-            # log prefix "[nftables] Inbound Denied: " counter drop +
-            # TODO ! count and drop any other traffic +
-            #counter drop +
-        } +
-        # Règles génériques sortantes +
-        chain output { +
-            # Par défaut, on rejette tout à moins de suivre une des règles ci-dessous. +
-            type filter hook output priority 0; policy drop; +
-            # Autoriser le trafic de paquets "etablished" et associés, supprimer les paquets non valides +
-            ct state established accept +
-            # Autorise le loopback sortant +
-            oifname "lo" accept +
-            # Autorise le ping sortant +
-            ip protocol icmp accept +
-            # Autoriser d'aller sur internet et de contacter les dns (domain) +
-            tcp dport { http, https } accept +
-            udp dport domain accept +
-        } +
-        # Règles génériques "forward" (ce qui circule vers les autres adresses routées) +
-        chain forward { +
-            # Par défaut, on rejette tout à moins de suivre une des règles ci-dessous. +
-            type filter hook forward priority 0; policy drop; +
-            # Autoriser le trafic de paquets "etablished" et associés, supprimer les paquets non valides +
-            ct state established accept +
-            # transfère le web ? TODO différence daddr/saddr +
-            ip daddr 10.10.10.69 tcp dport { http, https } accept +
-            ip saddr 10.10.10.69 udp dport domain accept +
-            ip saddr 10.10.10.69 tcp dport { http, https } accept +
-    } +
-+
-# Table sur le trafic de type prerouting/postrouting, par défaut sur accept pour que les connexions puissent s'initialiser +
-table ip nat { +
-    chain prerout { +
-        type nat hook prerouting priority 0; policy accept; +
-        # ce qui va sur les ports web doit être redirigé vers la VM +
-        tcp dport { httphttps } dnat to 10.10.10.69 +
-    } +
- +
-    chain postrout { +
-        type nat hook postrouting priority 0; policy accept; +
-        # Ce qui vient de la VM et qui tente de se connecter au web doit sortir par l'ip de notre proxy +
-        # Sinon on est redirigé sur nous-même... +
-        ip saddr 10.10.10.69 snat to 66.66.66.66 +
-    } +
-+
- +
-</code> +
-</WRAP>+
  
  
Ligne 586: Ligne 511:
   sudo nft list ruleset   sudo nft list ruleset
  
 +Pour recharger le fichier de configuration : 
 +  nft -f /etc/nftables.conf
 +
 +Admirer en temps réel les bans ? Pour admirer le contenu d'un set (par exemple tempblock_v4), c'est 
 +  sudo watch -n 1 'nft list set inet firewall tempblock_v4'
 +
 +Et pour les logs, si on a activé les [[pratique:informatique:systemd_error#avoir_des_vrais_journaux_de_log|logs lisibles]] (sinon, débrouillez vous avec journalctl) :
 +  tail -f /var/log/kern.log 
 ===== Sources ===== ===== Sources =====
  
pratique/informatique/parefeu/nftables.1748868410.txt.gz · Dernière modification : 02/06/2025 14:46 de Zatalyz