Description
Filtering ICMPv6 on Linux!
A few hours ago, I wrote this other article … now, it’s time to discuss about the filtering measures to be put in place around ICMPv6.
I am not going to remind you why this protocol exists, nor the fact that it can be dangerous if misused; and, of course, unfortunately there will always be people who misuse it!
Manage ICMPv6
Refuse
As a precaution, it is advisable to filter out all experimental codes, such as 100, 101, 200, and 201, as well as codes reserved for the future, namely codes 127 and 255.
It is recommended to block the following codes:
- 5 ⇒ 99: unallocated error messages
- 100, 101: experimentals
- 102 ⇒ 126: unallocated error messages
- 137 - Redirect Message — except in case of necessity
- 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 — except in case of necessity
- 154 ⇒ 199: non assigned
- 200, 201: experimentals
- 202 ⇒ 254: non assigned
Limit
The recommendations are to limit, in input AND in input, all those codes:
- 1 - Destination Unreachable
- 4 - Parameter Problem Message
And to limit in input only those following codes:
- 2/0 - Packet Too Big Message
- 3 - Time Exceeded Message
- and all other existing codes, especially:
- 128/0 - Echo Request message (le ping) -
- 129/0 - Echo reply message (le pong).
Useful details
For the following codes, in the corresponding RFC, the message format is specified as:
-
all MLD codes — 130, 131, 132, 143 - and MLDv2 must be sent from an address whose source is an IPv6 local link, with an
hop limit
of1
-
all ND codes — from 133 to 137 — must be sent with an
hop-limit
to255
- see RFC 4861 .
About those codes, here are useful informations:
- 133 - Router Solicitation - must be sent from a source that must have an assigned IP address, or from an unspecified address if the network interface does not yet have an assigned IP address, to any router.
- 134 - Router Advertisement - must ABSOLUTELY be sent by a router, issuing a periodic router notification, or response to a router solicitation, to any multicast node or to the source address invoking the router.
- 135 - Neighbor Solicitation - must be sent from a source that must have an assigned IP address, or from an unspecified address if the network interface does not yet have an assigned IP address, to any multicast node.
- 136 - Neighbor Advertisement - must ABSOLUTELY be sent by an assigned IP address, to the source address invoking the 135 code, or to any multicast node, if there is no assigned address.
- 137 - Redirect Message - must ABSOLUTELY be sent by an assigned IP address, an IPv6 link-local, by a router to the source address that requested the redirection of the message.
-
all NIQ codes - 139: ICMP Node Information Query and 140: ICMP Node Information Response - must refuse all requests from IPv6 global addresses and should apply the use of the
limit
option. Note that there are more complex security measures… see: RFC 4620 -
all ND ID codes - 141: Inverse Neighbor Discovery Solicitation Message and 142: Inverse Neighbor Discovery Advertisement Message - both must have an assigned IP address as source;
- 141 must be sent to any multicast node, whose format is FF02::1.
- 142 must respond only to a request of type 141.
- see: RFC 3122
-
all SEND codes - 148: Certification Path Solicitation Message and 149: Certification Path Advertisement Message - must be sent with an
hop-limit
to255
- see: RFC 3971 .
-
all MRD codes - from 151 to 153 must be sent from an assigned address, an IPv6 local-link, and have an
hop-limit
to255
.- see RFC 4286
Examples
Paranoid ICMPv6
In paranoid mode, here are this kind of rules:
##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
Limit ICMP
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.
# 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