Description
Ou cette fois-ci, comment titrer : Filtrer le protocole ICMPv6 sous Linux - l’équivalent du protocole ICMP mais pour IPv6
Il y a quelques heures, j’ai écrit cet autre mémo … maintenant, je retranscris à-propos des mesures de filtrage à mettre en place autour de ce protocole qu’est ICMPv6.
Je ne vais pas faire un rappel de ce pourquoi existe ce protocole, ni du fait que mal utilisé, il peut-être dangereux ; et, bien sûr, malheureusement, il y aura toujours des gens pour mal l’utiliser !
Gérer ICMPv6
Les codes ICMPv6 à refuser
Par prudence, il est recommandable de filtrer tous les codes expérimentaux, tels que 100, 101, 200, et 201, ainsi que les codes réservés pour le futur, à savoir les codes 127 et 255.
Il est recommandé de bloquer les codes suivants :
- 5 à 99 : ces codes sont non alloués !
- 100, 101 : codes expérimentaux
- 102 à 126 : codes non alloués
- 137 - Redirect Message - sauf en cas de nécessité
- 138 - Router Renumbering
- 139 - ICMP Node Information Query
- 140 - ICMP Node Information Response
- 144 - Home Agent Address Discovery Request Message
- 145 - Home Agent Address Discovery Reply Message
- 146 - Mobile Prefix Solicitation
- 147 - Mobile Prefix Advertisement
- 150 - Seamoby Experimental - sauf en cas de nécessité
- 154 à 199 : codes non alloués
- 200, 201 : codes expérimentaux
- 202 à 254 : codes non alloués
Les codes ICMPv6 à limiter
Les recommandations sont de limiter, en entrée et en sortie de machine, tous les codes de type :
- 1 - Destination Unreachable
- 4 - Parameter Problem Message
Les recommandations suivantes sont de limiter en entrée seulement, tous les codes suivants :
- 2/0 - Packet Too Big Message
- 3 - Time Exceeded Message
- et tous les autres codes existants, dont particulièrement :
- le code 128/0 - Echo Request message (le ping) -
- et le code 129/0 - Echo reply message (le pong).
Précisions utiles
Concernant les codes suivants, il est précisé, dans leur RFC correspondante, leur format de message :
-
tous les codes dits MLD donc 130, 131, 132 et 143 - et MLDv2 doivent être envoyés depuis une adresse dont la source est un lien local IPv6, avec un
hop limit
à1
-
tous les codes dits ND de 133 à 137 doivent être envoyés avec un
hop-limit
à255
- définis par la RFC 4861 . Quelques précisions concernant ces codes :-
le code 133 - Router Solicitation - doit être envoyé par une source ayant forcément une adresse IP assignée, ou depuis une adresse non spécifiée si l’interface réseau n’a pas encore d’adresse IP assignée, vers tout routeur.
-
le code 134 - Router Advertisement - doit ABSOLUMENT être envoyé par un routeur, émettant un avis de routeur périodique, ou une réponse à une sollicitation de routeur, à destination de tout nœud multicast ou à l’adresse source invoquant le routeur.
-
le code 135 - Neighbor Solicitation - doit être envoyé par une source ayant forcément une adresse IP assignée, ou depuis une adresse non spécifiée si l’interface réseau n’a pas encore d’adresse IP assignée, vers tout nœud multicast.
-
le code 136 - Neighbor Advertisement - doit ABSOLUMENT être envoyé par une adresse IP assignée, vers l’adresse source invoquant le code 135, ou vers tout nœud multicast, s’il n’y a pas d’adresse assignée.
-
le code 137 - Redirect Message - doit ABSOLUMENT être envoyé par une adresse IP assignée, lien local IPv6, d’un routeur vers l’adresse source qui a demandé la redirection du message.
-
-
les codes dits NIQ - donc 139 - ICMP Node Information Query - et 140 - ICMP Node Information Response - doivent refuser toutes requêtes venant d’adresses IPv6 dites globales et devraient appliquer l’emploi de l’option
limit
. À savoir qu’il y a d’autres mesures de sécurité, plus complexes… RFC 4620 -
les codes dits ND ID - donc 141 - Inverse Neighbor Discovery Solicitation Message - et 142 - Inverse Neighbor Discovery Advertisement Message -, tous deux doivent avoir pour source une adresse IP assignée - codes définis par la RFC 3122 :
- le code 141 doit être envoyé à destination de tout noeud multicast, dont le format est de type FF02::1
- le code 142 doit répondre seulement à une requête de type 141.
-
les codes dits SEND - donc 148 - Certification Path Solicitation Message - et 149 - Certification Path Advertisement Message - doivent être envoyés avec un
hop-limit
à255
- c’est la RFC 3971 qui définit ces codes. -
les codes dits MRD - donc 151 à 153, définis par la RFC 4286 , doivent être envoyés depuis une addresse assignée, lien local IPv6, et avoir un
hop-limit
à255
.
Exemples
ICMPv6 en mode parano
En mode paranoïaque, cela donne ce genre de règles :
##ip6tables -A INPUT -p icmpv6 -m conntrack --ctstate INVALID -j DROP
ip6tables -A INPUT -p icmpv6 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
ip6tables -A INPUT -p icmpv6 -m limit --limit 3/s --limit-burst 7 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -m conntrack --ctstate NEW -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -m conntrack --ctstate NEW -j ACCEPT
ip6tables -A INPUT -s fe80::/64 -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT # Type: 134
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT # Type: 135
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT # Type: 136
ip6tables -A INPUT -p icmpv6 -j DROP
##ip6tables -A OUTPUT -p icmpv6 -m conntrack --ctstate INVALID -j DROP
ip6tables -A OUTPUT -p icmpv6 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
ip6tables -A OUTPUT -p icmpv6 --icmpv6-type echo-request -m conntrack --ctstate NEW -j ACCEPT
ip6tables -A OUTPUT -p icmpv6 --icmpv6-type echo-reply -m conntrack --ctstate NEW -j ACCEPT
ip6tables -A OUTPUT -d ff02::/16 -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT # Type: 133
ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbour-solicitation -j ACCEPT # Type: 135
ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbour-advertisement -j ACCEPT # Type: 136
ip6tables -A OUTPUT -d ff02::/16 -p icmpv6 --icmpv6-type 143/0 -j ACCEPT # Type: 143/0
ip6tables -A OUTPUT -p icmpv6 -j DROP
ICMP filtré, limité
Voici, pour l’exemple, basé sur la compréhension des recommandations IETF,
des règles ICMP filtrées, limitées ; puis de rejeter tous les autres codes,
avec le message icmp6-adm-prohibited
.
# INPUT RULES
ip6tables -N INPUT_ICMPV6
##ip6tables -A INPUT_ICMPV6 -p icmpv6 -m conntrack --ctstate INVALID -j DROP
ip6tables -A INPUT_ICMPV6 -p icmpv6 -m limit --limit 3/s --limit-burst 7 -j ACCEPT
ip6tables -A INPUT_ICMPV6 -p icmpv6 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 1 -m conntrack --ctstate NEW -j ACCEPT # destination-unreachable; Must Not Be Dropped
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 2/0 -m conntrack --ctstate NEW -j ACCEPT # packet too big; Must Not Be Dropped
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 3/0 -m conntrack --ctstate NEW -j ACCEPT # time exceeded; Must Not Be Dropped
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 3/1 -m conntrack --ctstate NEW -j ACCEPT # time exceeded; Should Not Be Dropped
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 4/0 -m conntrack --ctstate NEW -j ACCEPT # parameter pb: Erroneous header field encountered; Should Not Be Dropped
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 4/1 -m conntrack --ctstate NEW -j ACCEPT # parameter pb: Unrecognized Next Header Type encountered; Must Not Be Dropped
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 4/2 -m conntrack --ctstate NEW -j ACCEPT # parameter pb: Unrecognized IPv6 option encountered; Must Not Be Dropped
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 100 -j DROP # private experimentation
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 101 -j DROP # private experimentation
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 127 -j DROP # error messages ICMPv6
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 128/0 -m conntrack --ctstate NEW -j ACCEPT # ping tool: echo request message; Must Not Be Dropped
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 129/0 -m conntrack --ctstate NEW -j ACCEPT # ping tool: echo reply message; Must Not Be Dropped
# link-local multicast receive notification mssg (need link-local src address, with hop-limit: 1)
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 130/0 -s fe80::/64 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 131/0 -s fe80::/64 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 132/0 -s fe80::/64 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
# address configuration and routeur selection mssg (received with hop limit = 255)
##ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 133/0 -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)
ip6tables -A INPUT_ICMPV6 -s fe80::/64 -p icmpv6 --icmpv6-type 134/0 -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 135/0 -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 136/0 -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 137/0 -j DROP # Will Be Dropped Anyway
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 138/0 -j DROP # Will Be Dropped Anyway
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 139/0 -j DROP # Should Be Dropped Unless a Good Case Can Be Made
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 140/0 -j DROP # Should Be Dropped Unless a Good Case Can Be Made
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 141/0 -d ff02::1 -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 142/0 -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)
# link-local multicast receive notification mssg (need link-local src address, with hop-limit: 1)
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 143 -s fe80::/64 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
# needed for mobylity
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 144/0 -j DROP # Will Be Dropped Anyway
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 145/0 -j DROP # Will Be Dropped Anyway
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 146/0 -j DROP # Will Be Dropped Anyway
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 147 -j DROP # Will Be Dropped Anyway
# SEND certificate path notification mssg (received with hop limit = 255)
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 148 -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 149 -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped (only RELATED,ESTABLISHED,UNTRACKED)
# multicast routeur discovery mssg (need link-local src address and hop limit = 1)
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 151 -s fe80::/64 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 152 -s fe80::/64 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 153 -s fe80::/64 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
#
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 200 -j DROP # private experimentation
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 201 -j DROP # private experimentation
ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 255 -j DROP # error messages ICMPv6
# all others are dropped
#ip6tables -A INPUT_ICMPV6 -p icmpv6 ! --icmpv6-type -j DROP or -j REJECT --reject-with icmp6-adm-prohibited ⇐ this type seems not correctly supported!
ip6tables -A INPUT_ICMPV6 -p icmpv6 -j REJECT --reject-with no-route
# OUTPUT RULES
ip6tables -N OUTPUT_ICMPV6
##ip6tables -A OUTPUT_ICMPV6 -p icmpv6 -m conntrack --ctstate INVALID -j DROP
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 -m conntrack --ctstate RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 1 -m conntrack --ctstate NEW -m limit --limit 3/s --limit-burst 7 -j ACCEPT # destination-unreachable; Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 2/0 -m conntrack --ctstate NEW -j ACCEPT # packet too big; Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 3/0 -m conntrack --ctstate NEW -j ACCEPT # time exceeded; Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 3/1 -m conntrack --ctstate NEW -j ACCEPT # time exceeded; Should Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 4/0 -m conntrack --ctstate NEW -m limit --limit 3/s --limit-burst 7 -j ACCEPT # parameter pb: Erroneous header field encountered; Should Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 4/1 -m conntrack --ctstate NEW -m limit --limit 3/s --limit-burst 7 -j ACCEPT # parameter pb: Unrecognized Next Header Type encountered; Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 4/2 -m conntrack --ctstate NEW -m limit --limit 3/s --limit-burst 7 -j ACCEPT # parameter pb: Unrecognized IPv6 option encountered; Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 100 -j DROP # private experimentation
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 101 -j DROP # private experimentation
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 127 -j DROP # error messages ICMPv6
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 128/0 -m conntrack --ctstate NEW -j ACCEPT # ping tool: echo request message; Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 129/0 -m conntrack --ctstate NEW -j ACCEPT # ping tool: echo reply message; Must Not Be Dropped
# link-local multicast receive notification mssg (need link-local src address, with hop-limit: 1)
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 130/0 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 131/0 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 132/0 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
# address configuration and routeur selection mssg (received with hop limit = 255)
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 133/0 -d ff02::/16 -m conntrack --ctstate NEW -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped
##ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 134/0 -d fe80::/64 -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 135/0 -m conntrack --ctstate NEW -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 136/0 -m conntrack --ctstate NEW -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 137/0 -j DROP # Will Be Dropped Anyway
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 138/0 -j DROP # Will Be Dropped Anyway
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 139/0 -j DROP # Should Be Dropped Unless a Good Case Can Be Made
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 140/0 -j DROP # Should Be Dropped Unless a Good Case Can Be Made
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 141/0 -d ff02::1 -m conntrack --ctstate NEW -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 142/0 -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped
# link-local multicast receive notification mssg (need link-local src address, with hop-limit: 1)
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 143 -d ff02::/16 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
# needed for mobylity: except if the context requires it, then it will be necessary to limit them
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 144/0 -j DROP # Will Be Dropped Anyway
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 145/0 -j DROP # Will Be Dropped Anyway
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 146/0 -j DROP # Will Be Dropped Anyway
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 147 -j DROP # Will Be Dropped Anyway
# SEND certificate path notification mssg (received with hop limit = 255)
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 148 -m conntrack --ctstate NEW -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 149 -m conntrack --ctstate NEW -m hl --hl-eq 255 -j ACCEPT # Must Not Be Dropped
# multicast routeur discovery mssg (need link-local src address and hop limit = 1)
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 151 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 152 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 153 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
#
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 200 -j DROP # private experimentation
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 201 -j DROP # private experimentation
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 255 -j DROP # error messages ICMPv6
# all others are dropped
#ip6tables -A OUTPUT_ICMPV6 -p icmpv6 ! --icmpv6-type -j DROP or -j REJECT --reject-with icmp6-adm-prohibited # ⇐ this type seems not correctly supported!
ip6tables -A OUTPUT_ICMPV6 -p icmpv6 -j REJECT --reject-with no-route
Documentations
Je ne vais pas reprendre le petit laïus sur IETF , ou IANA, mais simplement rappeler de bonnes lectures à faire.
Si jamais, vous avez d’autres “tuyaux” du même acabit, n’hésitez pas m’envoyer un commentaire par mail.
-
les différents paramètres ICMPv6
-
la RFC 4890
-
la RFC 5927
-
GNU Linux Magazine : Netfilter et le filtrage du protocole IPv6