Description
Following the recommendations from my article about the rules to be put in place to allow or block ICMPv6 messages, here are the adequate rules for PF, for *BSD that use Packet Filter, including OpenBSD:
Manage ICMPv6
Drop
These ICMPv6 types are to be rejected absolutely:
icmp6_block = "{ 100 101 127 138 139 140 144 145 146 147 150 200 201 }"
block drop quick log on egress inet6 proto icmp6 icmp6-type $icmp6_block
Be Carefull: About Mobile IPv6 messages types (144 → 147), there are needed to assist mobility, depending mobile nodes normally on the site, or foreign mobile nodes roaming (tablets, laptops, …)…
If necessary, you may need to pass and limit them.
Pass
⇒ For a station:
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 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.
- solicitations messages from the station to the routeur —
-
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 :
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
Limit
To limit ICMPv6 traffic, PF can be use STO .
To continue the example above, using the max-src-conn-rate
option:
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
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_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:
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