Can safely block these ICMPv6 message types on a web server?

I have a Debian 11 VPS on a cloud provider, with both IPv4 and IPv6 enabled and the eth0 interface with both a global-scoped ipv6 address (public) and a link-scoped ipv6 address (fe80::/10).

The sole purpose of the server is to host a public website.

I’m implementing a firewall on the server using iptables/ip6tables. I read RFC4890 but still not sure how to handle some ICMPv6 message types and if they are really needed for my use case. Whereas I am permitting any traffic on the link-scoped, I am not sure if I can safely block the following ICMPv6 message types on the global-scoped:

  • Router Solicitation (Type 133)

  • Router Advertisement (Type 134)

  • Neighbor Solicitation (Type 135)

  • Neighbor Advertisement (Type 136)

  • Inverse Neighbor Discovery Solicitation (Type 141)

  • Inverse Neighbor Discovery Advertisement (Type 142)

  • Listener Query (Type 130)

  • Listener Report (Type 131)

  • Listener Done (Type 132)

  • Listener Report v2 (Type 143)

  • Certificate Path Solicitation (Type 148)

  • Certificate Path Advertisement (Type 149)

  • Multicast Router Advertisement (Type 151)

  • Multicast Router Solicitation (Type 152)

  • Multicast Router Termination (Type 153)

Many thanks for any help.


Solution 1:

Allow all ICMPv6 types. Rate limit ICMPv6 packets per second, where possible, to limit resource use on IP devices. This is the easy way, and is not as insecure as it sounds.


Or, the do your research method is to read RFC 4890 Recommendations for Filtering ICMPv6 Messages in Firewalls. Note the lack of must be dropped recommendations for a start.

"Link-global" is not a standard term. I think you mean (global) unicast. As opposed to link-local or multicast, which are in defined ranges. Further, you will want a firewall with a zone concept. As you probably want a different policy on your prefixes vs the internet, but both are global unicast scope.

The RFC explains, many of these local scoped messages do not require special filtering. Compliant routers will not forward link local sourced. Compliant hosts receiving neighbor discovery messages will confirm they did not go through a router. And many firewalls are routers, so you need neighbor discovery, including RAs, to work.


As a practical example, let's take a quick look at the default ICMPv6 handling of a libre router, OpenWrt. This question includes more or less the default ICMPv6 firewall rules.

Zone "lan" defaults to all accept. Zone "wan" defaults to only outgoing. Typical simple firewall. Allow rules are sourced from wan:

config rule
        option name 'Allow-ICMPv6-Input'
        option src 'wan'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        list icmp_type 'router-solicitation'
        list icmp_type 'neighbour-solicitation'
        list icmp_type 'router-advertisement'
        list icmp_type 'neighbour-advertisement'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Forward'
        option src 'wan'
        option dest '*'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

Mostly must not be dropped types, see section 4.4.1. Note in 'Allow-ICMPv6-Forward' the error types and echo are always allowed, inbound or outbound.

config rule
        option name 'Allow-MLD'
        option src 'wan'
        option proto 'icmp'
        option src_ip 'fe80::/10'
        list icmp_type '130/0'
        list icmp_type '131/0'
        list icmp_type '132/0'
        list icmp_type '143/0'
        option family 'ipv6'
        option target 'ACCEPT'

Link-local multicast receiver notification messages.

Overall, allows everything in the internal zone, and enables error, echo, neighbor discovery, and multicast related ICMP to come from the internet. Doesn't allow other things like SEND to traverse the internet. Not the only way to filter this stuff, but at least does not break IPv6.