Score:0

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

ca flag

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.

Score:3
cn flag

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.

ca flag
Thank you for pointing me to the correct terminology (referring to link and global scope), I fixed it. Of course thank you for your answer, let me study it and elaborate before giving a feedback.
ca flag
On the basis of your suggestions and the example rules included in the RFC, and on the basis of what observed so far on my Debian box (ie. the only ip6tables rules counting packets being ICMPv6 types 128, 135, 136), I ended up with a set of rules that allow the following types on the global-scope: 1, 2, 3, 4, 128, 135, 136. Whereas the link-scope (fe80::/10) allows all traffic. I guess that other ICMPv6 types are not needed because the IPv6 address and gateway are assigned statically. I'm monitoring this situation to see if something breaks. So far so good. Any feedback appreciated.
Score:0
ca flag

On the basis of my research I ended up with the following rules. I have a 0 packet count by the LOG REJECT rule for ICMPv6 types in commented rules (ie: disabled types).

#
# INBOUND ICMPv6
# Commented types are not needed;
# those types that would be allowed for link-local only are commented as well 
# because link-local is allowed all traffic.
#

ip6tables -N ICMP6

ip6tables -A ICMP6 -p icmpv6 --icmpv6-type 1 -j ACCEPT                      # Destination Unreachable
ip6tables -A ICMP6 -p icmpv6 --icmpv6-type 2 -j ACCEPT                      # Packet Too Big
ip6tables -A ICMP6 -p icmpv6 --icmpv6-type 3 -j ACCEPT                      # Time Exceeded
ip6tables -A ICMP6 -p icmpv6 --icmpv6-type 4 -j ACCEPT                      # Parameter Problem
ip6tables -A ICMP6 -p icmpv6 --icmpv6-type 128 -j ACCEPT                    # Echo Request
#ip6tables -A ICMP6 -p icmpv6 --icmpv6-type 133 -j ACCEPT                    # Router Solicitation
#ip6tables -A ICMP6 -p icmpv6 --icmpv6-type 134 -j ACCEPT                    # Router Advertisement
ip6tables -A ICMP6 -p icmpv6 --icmpv6-type 135 -j ACCEPT                    # Neighbor Solicitation
ip6tables -A ICMP6 -p icmpv6 --icmpv6-type 136 -j ACCEPT                    # Neighbor Advertisement
#ip6tables -A ICMP6 -p icmpv6 --icmpv6-type 141 -j ACCEPT                    # Inverse Neighbor Discovery Solicitation
#ip6tables -A ICMP6 -p icmpv6 --icmpv6-type 142 -j ACCEPT                    # Inverse Neighbor Discovery Advertisement
#ip6tables -A ICMP6 -s fe80::/10 -p icmpv6 --icmpv6-type 130 -j ACCEPT      # Listener Query
#ip6tables -A ICMP6 -s fe80::/10 -p icmpv6 --icmpv6-type 131 -j ACCEPT      # Listener Report
#ip6tables -A ICMP6 -s fe80::/10 -p icmpv6 --icmpv6-type 132 -j ACCEPT      # Listener Done
#ip6tables -A ICMP6 -s fe80::/10 -p icmpv6 --icmpv6-type 143 -j ACCEPT      # Listener Report v2
#ip6tables -A ICMP6 -p icmpv6 --icmpv6-type 148 -j ACCEPT                    # Certificate Path Solicitation
#ip6tables -A ICMP6 -p icmpv6 --icmpv6-type 149 -j ACCEPT                    # Certificate Path Advertisement
#ip6tables -A ICMP6 -s fe80::/10 -p icmpv6 --icmpv6-type 151 -j ACCEPT      # Multicast Router Advertisement
#ip6tables -A ICMP6 -s fe80::/10 -p icmpv6 --icmpv6-type 152 -j ACCEPT      # Multicast Router Solicitation
#ip6tables -A ICMP6 -s fe80::/10 -p icmpv6 --icmpv6-type 153 -j ACCEPT      # Multicast Router Termination

# DROP everything else on chain ICMP6
ip6tables -A ICMP6 -p icmpv6 -j LOG --log-level 7 --log-prefix "[FW.IN drop ICMP6] "
ip6tables -A ICMP6 -p icmpv6 -j DROP

ip6tables -A INPUT -p icmpv6 -j ICMP6

So my conclusion is that a web server only needs types 1,2,3,4,128,135,136

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.