Fix informations about ICMPv6!

master
HUC Stéphane 2023-07-13 18:10:34 +02:00
parent 25eb85b298
commit 8f43228758
Signed by: hucste
GPG Key ID: C4ED64222D9B037F
4 changed files with 215 additions and 129 deletions

View File

@ -127,24 +127,25 @@ specified as:
In paranoid mode, here are this kind of rules:
```sh
ip6tables -A INPUT -p icmpv6 -m conntrack --ctstate INVALID -j DROP
```cfg
##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 -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT # Type: 134
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 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 -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT # Type: 133
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
```
@ -154,10 +155,10 @@ Here is an example, based on the understanding of the IETF recommendations,
of ICMP limited rules, and reject all others codes with the
`icmp6-adm-prohibited` messages.
```sh
```cfg
# 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 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
@ -177,7 +178,7 @@ ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 130/0 -s fe80::/64 -m conntrac
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 -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)
@ -206,12 +207,12 @@ ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 200 -j DROP # private experi
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 ! --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 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
@ -230,8 +231,8 @@ ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 130/0 -m conntrack --ctstate
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 -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 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
@ -241,8 +242,8 @@ ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 140/0 -j DROP # Should Be D
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 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
# needed for mobylity
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
@ -259,7 +260,7 @@ ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 200 -j DROP # private exper
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 ! --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
```

View File

@ -48,34 +48,54 @@ If necessary, you may need to pass and limit them.
---
⇒ Routeur case:
A router **must never transmit** a packet whose source or destination
address is local link address:
```cfg
block drop quick on egress inet6 proto icmp6 from fe80::/64 to any
block drop quick on egress inet6 proto icmp6 from any to fe80::/64
```
### Pass
⇒ For a station:
```cfg
icmp6_auth = "{ unreach toobig timex paramprob echorep echoreq routeradv neighbradv neighbrsol }"
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts
pass in quick on egress inet6 proto icmp6 from any to egress icmp6-type redir allow-opts
icmp6_auth = "{ unreach toobig timex paramprob echoreq echoreq neighbradv neighbrsol }"
pass out quick on egress inet6 proto icmp6 from any to ff02::2 icmp6-type { routersol, listenrepv2 }
pass in quick on egress inet6 proto icmp6 from fe80::/64 to ff02::1 icmp6-type { routeradv }
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts
pass in quick on egress inet6 proto icmp6 from any to egress icmp6-type redir allow-opts
```
**Explainations**
* The second rule authorize in input and output all from or to the IPv6
stack, from or to the ICMPv6 targeting the types on the `$icmp6_auth`
macro.
* The first rule define all authorized ICMPv6 types required, a minimum.
* The second rule authorize only in output:
- solicitations messages from the station to the routeur — `ff02::2`
is the local multicast address of any router
- and the "Multicast Listener Report Message v2" messages, `listenrepv2`
- both ICMPv6 types are needed to communicate locally
- this rule is the first because the station announce that it needs
a routable address to communicate with others.
* The third rule authorize only in input messages from router — type 143 —
to the station's local node — `ff02::1`.
- this is the router's reply to the previous request from the station
* The 4th rule autorise in input, and output all defined types from the
first rule — the macro `$icmp6_auth`.
* The 5 rule authorize only in input the redirection ICMPv6 message.
⇒ Router case:
Pour débuter, faisons simplement :
```cfg
icmp6_auth = "{ echoreq echoreq neighbradv neighbrsol }"
pass in quick on egress inet6 proto icmp6 icmp6-type { routersol, listenrepv2 }
pass out quick on egress inet6 proto icmp6 icmp6-type routeradv
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth
```
* The third authoriez in input all from the IPv6 stack, to the ICMPv6
redirection message
#### Limit
@ -85,49 +105,55 @@ To limit ICMPv6 traffic, PF can be use
To continue the example above, using the `max-src-conn-rate` option:
```cfg
icmp_sto = "(max-src-conn-rate 100/10)"
icmp6_auth = "{ unreach toobig timex paramprob echoreq routeradv neighbradv neighbrsol }"
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts $icmp_sto
pass in quick on egress inet6 proto icmp6 from any to egress icmp6-type redir allow-opts $icmp_sto
```
icmp6_auth = "{ unreach toobig timex paramprob echoreq neighbradv neighbrsol }"
icmp6_sto = "( max-src-conn-rate 100/10 )"
pass out quick on egress inet6 proto icmp6 from any to ff02::2 icmp6-type { routersol, listenrepv2 }
pass in quick on egress inet6 proto icmp6 from fe80::/64 to ff02::1 icmp6-type { routeradv }
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts $icmp6_sto
pass in quick on egress inet6 proto icmp6 from any to egress icmp6-type redir allow-opts $icmp6_sto
```
#### More paranoid
```cfg
icmp6_auth = "{ unreach, toobig, timex code 0, timex code 1, paramprob code 1, paramprob code 2, echorep, echoreq, routeradv, neighbradv, neighbrsol }"
icmp6_in = "{ redir }"
icmp6_out = "{ echorep, echoreq, neighborsol, routersol }"
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts
pass in quick on egress inet6 proto from any to egress icmp6 icmp6-type $icmp6_in allow-opts
pass out quick on egress inet6 proto from egress to any icmp6 icmp6-type $icmp6_out allow-opts
icmp6_auth = "{ unreach, toobig, timex code 0, timex code 1, paramprob code 1, paramprob code 2, echorep, echoreq, neighbradv, neighbrsol }"
icmp6_out = "{ echorep, echoreq, neighbradv, neighbrsol }"
icmp6_sto = "( max-src-conn-rate 100/10 )"
pass out quick on egress inet6 proto icmp6 from any to ff02::2 icmp6-type { routersol, listenrepv2 }
pass in quick on egress inet6 proto icmp6 from fe80::/64 to ff02::1 icmp6-type { routeradv, redir }
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts $icmp6_sto
pass out quick on egress inet6 proto from egress to any icmp6 icmp6-type $icmp6_out allow-opts $icmp6_sto
```
**Explainations**
* `icmp6_auth`: manage only what it's absolutely necessary.
* `icmp6_in`: to manage the redirection message, to a shorter route…
- normally, this must be in input, either a station, or a server
- better, it should absolutely only come from a router
* `icmp6_out`: to manage echoes replies — the "Pong" ­— from routeur or
neighbours.
* `icmp6_out`: to manage echoes replies — the "Pong" ­— from routeur and
neighbours messages
* in the first `in` rule, we have added management of redirection messages
to a shorter route, only from a router to our machine. to our machine.
**WARNING**: allowing redirection messages message in any other way
will cause security problems, to the extent that that it seems
advisable to remove them from the firewall context!
---
⇒ Router case:
If you have the nice idea to "build", yourself, your own router
*under OpenBSD, for example*, it is necessary that this one allows all
neighbor discovery codes, i.e. the options options **133** to **137**,
to and from it:
```cfg
icmp6_auth = "{ unreach toobig timex paramprob echorep echoreq }"
icmp6_nd = "{ routersol routeradv neighbrsol neighbradv redir }"
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts
pass inet6 proto ipv6-icmp from any to { ff02::/8, (self) } icmp6-type $icmp6_nd allow-opts
icmp6_auth = "{ unreach toobig timex paramprob echoreq echoreq neighbradv neighbrsol }"
icmp6_sto = "( max-src-conn-rate 100/10 )"
pass in quick on egress inet6 proto icmp6 icmp6-type { routersol, listenrepv2 }
pass out quick on egress inet6 proto icmp6 icmp6-type { routeradv, redir }
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts $icmp6_sto
```
## Documentation

View File

@ -67,41 +67,53 @@ les codes suivants :
### Précisions utiles
Concernant les codes suivants, il est précisé, dans leur RFC correspondante, leur format de message :
Concernant les codes suivants, il est précisé, dans leur RFC correspondante,
leur format de message :
* tous les codes dits **{{< abbr MLD "Multicast Listener Discovery" >}}**
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` - *selon la {{< anchor "RFC 2710" "RFC 2710" >}}* ;
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`
- *selon la {{< anchor "RFC 2710" "RFC 2710" >}}* ;
*le type 143 étant défini par la {{< anchor "RFC 3810" "RFC 3810" >}}*.
* tous les codes dits **{{< abbr ND "Neighbor Discovery" >}}** de **133**
à **137** doivent être envoyés avec un `hop-limit` à `255` - *définis par
la {{< anchor "RFC 4861" "RFC 4861" >}}*. <br>
à **137** doivent être envoyés avec un `hop-limit` à `255` -
*définis par la {{< anchor "RFC 4861" "RFC 4861" >}}*. <br>
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 **{{< abbr NIQ "Node Information Queries" >}}** - donc
**139** - **ICMP Node Information Query** - et **140** - **ICMP Node Information Response** -
**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`. <br>
À savoir qu'il y a d'autres mesures de sécurité, plus complexes… *{{< anchor "RFC 4620" "RFC 4620" >}}*
À savoir qu'il y a d'autres mesures de sécurité, plus complexes…
*{{< anchor "RFC 4620" "RFC 4620" >}}*
* les codes dits **{{< abbr "ND ID" "Neighbor Discovery Inverse Discovery" >}}** -
donc **141** - **Inverse Neighbor Discovery Solicitation Message** -
et **142** - **Inverse Neighbor Discovery Advertisement Message** -,
@ -110,11 +122,13 @@ Concernant les codes suivants, il est précisé, dans leur RFC correspondante, l
* 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 **{{< abbr SEND "SEcure Neighbor Discovery" >}}** - donc
**148** - **Certification Path Solicitation Message** - et **149** -
**Certification Path Advertisement Message** - doivent être envoyés
avec un `hop-limit` à `255` - *c'est la {{< anchor "RFC 3971" "RFC 3971" >}}
qui définit ces codes*.
* les codes dits **{{< abbr MRD "Multicast Router Discovery" >}}** - donc
**151** à **153**, *définis par la {{< anchor "RFC 4286" "RFC 4286" >}}*,
doivent être envoyés depuis une addresse assignée, lien local IPv6,
@ -127,23 +141,24 @@ Concernant les codes suivants, il est précisé, dans leur RFC correspondante, l
En mode paranoïaque, cela donne ce genre de règles :
```cfg
ip6tables -A INPUT -p icmpv6 -m conntrack --ctstate INVALID -j DROP
##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 -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT # Type: 134
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 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 -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT # Type: 133
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
```
@ -156,7 +171,7 @@ avec le message `icmp6-adm-prohibited`.
```cfg
# 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 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
@ -176,7 +191,7 @@ ip6tables -A INPUT_ICMPV6 -p icmpv6 --icmpv6-type 130/0 -s fe80::/64 -m conntrac
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 -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)
@ -210,7 +225,7 @@ 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 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
@ -229,8 +244,8 @@ ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 130/0 -m conntrack --ctstate
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 -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 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
@ -240,7 +255,7 @@ ip6tables -A OUTPUT_ICMPV6 -p icmpv6 --icmpv6-type 140/0 -j DROP # Should Be D
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 -m conntrack --ctstate NEW -m hl --hl-eq 1 -j ACCEPT # Must Not Be Dropped
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
@ -277,6 +292,8 @@ un commentaire par mail.*
* le <span lang="en">[draft ICMP filtering][101]</span>
* le <span lang="en">[draft ICMPv6 filtering][102]</span>
* [GNU Linux Magazine : Netfilter et le filtrage du protocole IPv6](https://connect.ed-diamond.com/GNU-Linux-Magazine/glmfhs-041/netfilter-et-le-filtrage-du-protocole-ipv6)
---
{{< rfcdoc 2710 >}}

View File

@ -12,17 +12,21 @@ translationKey: "pf-firewall-icmpv6"
## Description
{{< note tip >}}
Cet article peut très bien être utile pour le PF embarqué dans [Debian GNU/kFreeBSD](https://wiki.debian.org/fr/Debian_GNU/kFreeBSD) !
Cet article peut très bien être utile pour le PF embarqué dans
[Debian GNU/kFreeBSD](https://wiki.debian.org/fr/Debian_GNU/kFreeBSD) !
{{</note>}}
Reprenant le principe des informations renfermées dans mon autre {{< inside "sec:firewall:linux-firewall-icmpv6" article >}},
à-propos des recommandations faites pour autoriser ou bloquer le flux ICMPv6,
voici les règles PF adéquates pour tout BSD qui utilise Packet Filter, dont OpenBSD :
Reprenant le principe des informations renfermées dans mon autre
{{< inside "sec:firewall:linux-firewall-icmpv6" article >}},
à-propos des recommandations faites pour autoriser ou bloquer le flux
ICMPv6, voici les règles PF adéquates pour tout BSD qui utilise
Packet Filter, dont OpenBSD :
{{< note warning >}}
Ne JAMAIS oublier que toute la pile IPv6, à la différence d'IPv4, se repose
vraiment sur ICMPv6 ; ainsi, une mauvaise configuration d'ICMPv6 empêchera
assurément tout ou partie du flux IPv6 de fonctionner correctement, ou comme attendu !
assurément tout ou partie du flux IPv6 de fonctionner correctement, ou
comme attendu !
{{</note>}}
## Gestion
@ -44,33 +48,63 @@ dans ce contexte, il est nécessaire de ne pas les supprimer.
---
⇒ Cas d'un routeur :
Un routeur **ne doit jamais transmettre** un paquet ayant pour adresse source
ou de destination une adresse de type lien local :
```cfg
block drop quick on egress inet6 proto icmp6 from fe80::/64 to any
block drop quick on egress inet6 proto icmp6 from any to fe80::/64
```
### Les codes ICMPv6 à autoriser
⇒ Gestion d'une station :
```cfg
icmp6_auth = "{ unreach toobig timex paramprob echoreq routeradv neighbradv neighbrsol }"
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts
pass in quick on egress inet6 proto icmp6 from any to egress icmp6-type redir allow-opts
icmp6_auth = "{ unreach toobig timex paramprob echoreq echoreq neighbradv neighbrsol }"
pass out quick on egress inet6 proto icmp6 from any to ff02::2 icmp6-type { routersol, listenrepv2 }
pass in quick on egress inet6 proto icmp6 from fe80::/64 to ff02::1 icmp6-type { routeradv }
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts
pass in quick on egress inet6 proto icmp6 from any to egress icmp6-type redir allow-opts
```
**Explications**
* La deuxième règle autorise en entrée et sortie tout ce qui vient de la
pile IPv6 vers ou depuis ICMPv6 ciblant les types mentionnés dans la
macro `$icmp6_auth`.
* La troisième règle autorise en entrée tout ce qui vient de la pile IPv6
vers l'annonce ICMPv6 de redirection vers une route plus courte.
* La première règle définit les types ICMPv6 autorisés nécessaires,
au minimum.
* La deuxième règle autorise en sortie :
- les sollicitations depuis notre station à destination d'un routeur
`ff02::2` est l'adresse multicast local de tout routeur —
- ainsi que les messages "Multicast Listener Report Message v2"
`listenrepv2`
- ces deux types ICMPv6 sont nécessaires pour communiquer localement
- cette règle est placée en premier car il faut bien que la station
annonce qu'elle a besoin d'une adresse routable.
* La troisième règle autorise en entrée les annonces de routeur — type 143 —
à destination du nœud local de notre station — `ff02::1`.
- c'est la réponse du routeur vers la requête précédente de notre
station
* La quatrième règle autorise en entrée et en sortie, tous les types
mentionnés dans la première règle — la macro `$icmp6_auth`.
* La cinquième règle autorise en entrée toute annonce ICMPv6 de
redirection vers une route plus courte.
Les règles deux et trois sont strictement nécessaires pour débuter une
communication sur le protocole IPv6 ; sans elles, la station sera
incapable de le faire correctement !
---
⇒ Gestion d'un routeur :
Pour débuter, faisons simplement :
```cfg
icmp6_auth = "{ echoreq echoreq neighbradv neighbrsol }"
pass in quick on egress inet6 proto icmp6 icmp6-type { routersol, listenrepv2 }
pass out quick on egress inet6 proto icmp6 icmp6-type routeradv
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth
```
#### Limiter le trafic
@ -81,51 +115,59 @@ Pour reprendre l'exemple ci-dessus, en utilisant l'option
`max-src-conn-rate` :
```cfg
icmp_sto = "(max-src-conn-rate 100/10)"
icmp6_auth = "{ unreach toobig timex paramprob echoreq routeradv neighbradv neighbrsol }"
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts $icmp_sto
pass in quick on egress inet6 proto icmp6 from any to egress icmp6-type redir allow-opts $icmp_sto
icmp6_auth = "{ unreach toobig timex paramprob echoreq neighbradv neighbrsol }"
icmp6_sto = "( max-src-conn-rate 100/10 )"
pass out quick on egress inet6 proto icmp6 from any to ff02::2 icmp6-type { routersol, listenrepv2 }
pass in quick on egress inet6 proto icmp6 from fe80::/64 to ff02::1 icmp6-type { routeradv }
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts $icmp6_sto
pass in quick on egress inet6 proto icmp6 from any to egress icmp6-type redir allow-opts $icmp6_sto
```
#### Autorisations plus restrictives
```cfg
icmp6_auth = "{ unreach, toobig, timex code 0, timex code 1, paramprob code 1, paramprob code 2, echoreq, routeradv, neighbradv, neighbrsol }"
icmp6_in = "{ redir }"
icmp6_out = "{ echorep, echoreq, neighborsol, routersol }"
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts
pass in quick on egress inet6 proto from any to egress icmp6 icmp6-type $icmp6_in allow-opts
pass out quick on egress inet6 proto from egress to any icmp6 icmp6-type $icmp6_out allow-opts
icmp6_auth = "{ unreach, toobig, timex code 0, timex code 1, paramprob code 1, paramprob code 2, echorep, echoreq, neighbradv, neighbrsol }"
icmp6_out = "{ echorep, echoreq, neighbradv, neighbrsol }"
icmp6_sto = "( max-src-conn-rate 100/10 )"
pass out quick on egress inet6 proto icmp6 from any to ff02::2 icmp6-type { routersol, listenrepv2 }
pass in quick on egress inet6 proto icmp6 from fe80::/64 to ff02::1 icmp6-type { routeradv, redir }
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts $icmp6_sto
pass out quick on egress inet6 proto from egress to any icmp6 icmp6-type $icmp6_out allow-opts $icmp6_sto
```
**Explications**
* La règle `icmp6_auth` ne gére que ce qui est absolument nécessaire… **attention
à bien utiliser les virgules séparant les codes, autrement elle ne
serait pas fonctionnelle** !
* La règle `icmp6_in` gére le cas de l'annonce de redirection `redir` vers
une route sortante plus courte, et normalement ne doit être qu'entrante,
pour une station ou un serveur ; mieux, elle devrait cibler le fait
de ne venir absolument que d'un routeur !
* La règle `icmp6_out` gére les cas de réponse ping - *le pong* -, des
réponses de routeur, et de voisins.
* La règle `icmp6_auth` ne gére que ce qui est absolument nécessaire…
**attention à bien utiliser les virgules séparant les codes,
autrement elle ne serait pas fonctionnelle** !
* La règle `icmp6_out` n'autorise seulement que les messages d'echo et
les messages de découvertes des voisins.
* on a ajouté dans la première règle `in` la gestion des messages de
redirection vers une route plus courte, seulement depuis un routeur
vers notre machine. **ATTENTION** : autoriser le message de redirection
de toute autre manière posera des problèmes de sécurité, à tel point
qu'il semble recommander de les supprimer dans le contexte de parefeu !
---
⇒ Cas d'un routeur :
Si vous avez la belle idée de "construire", vous-même, votre propre routeur
*sous OpenBSD, par exemple*, il est nécessaire que celui-ci autorise tous
les codes **ND** dits de découvertes des voisins, c'est-à-dire les options
**133** à **137**, à destination de lui et depuis lui :
```cfg
icmp6_auth = "{ unreach toobig timex paramprob echorep echoreq }"
icmp6_nd = "{ routersol routeradv neighbrsol neighbradv redir }"
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts
pass inet6 proto ipv6-icmp from any to { ff02::/8, (self) } icmp6-type $icmp6_nd allow-opts
```
icmp6_auth = "{ unreach toobig timex paramprob echoreq echoreq neighbradv neighbrsol }"
icmp6_sto = "( max-src-conn-rate 100/10 )"
pass in quick on egress inet6 proto icmp6 icmp6-type { routersol, listenrepv2 }
pass out quick on egress inet6 proto icmp6 icmp6-type { routeradv, redir }
pass quick on egress inet6 proto icmp6 icmp6-type $icmp6_auth allow-opts $icmp6_sto
```
## Documentation