Disclosure up front: I run IPYE, a company that leases IP space. It gets one short paragraph at the end; the rest is plain networking.
In IPv4, ICMP is a diagnostic extra, and blocking all of it hurts but rarely breaks everything. In IPv6, ICMPv6 is part of the protocol itself: address resolution, router discovery, path MTU discovery, and error reporting all depend on it. A firewall that drops ICMPv6 wholesale produces failures that look random. RFC 4890 ("Recommendations for Filtering ICMPv6 Messages in Firewalls") is the reference for what to permit. This article is a type-by-type table built from it, with the reasoning, plus an nftables sketch. Examples use 2001:db8::/32.
Two families of messages
ICMPv6 (RFC 4443) splits by type number:
- Error messages have types 0 to 127: Destination Unreachable (1), Packet Too Big (2), Time Exceeded (3), Parameter Problem (4).
- Informational messages have types 128 to 255: Echo Request (128), Echo Reply (129), the Neighbor Discovery family (133 to 137), and multicast listener messages.
Reference table
| Type | Name | Scope | Guidance (from RFC 4890) |
|---|---|---|---|
| 1 | Destination Unreachable | Transit and local | Must not be dropped |
| 2 | Packet Too Big | Transit and local | Must not be dropped; path MTU discovery depends on it |
| 3 | Time Exceeded (code 0, hop limit) | Transit and local | Must not be dropped; traceroute and loop reporting need it |
| 4 | Parameter Problem (codes 1 and 2) | Transit and local | Must not be dropped; code 0 should also be allowed |
| 128 | Echo Request | Inbound to your hosts | Allow, ideally rate-limited, for services you want to be testable |
| 129 | Echo Reply | Return | Allow for replies to your own pings |
| 133 | Router Solicitation | Link-local only | Allow on the local link; never forward off-link |
| 134 | Router Advertisement | Link-local only | Allow on the local link, from routers only |
| 135 | Neighbor Solicitation | Link-local only | Allow on the local link |
| 136 | Neighbor Advertisement | Link-local only | Allow on the local link |
| 137 | Redirect | Link-local only | Allow only if you use it; many hosts ignore or disable it |
| 130, 131, 132, 143 | Multicast Listener (MLD) | Link-local only | Allow on-link where multicast is used |
The principle behind the "transit" versus "link-local" split: error messages and echo cross networks, so they need to pass through border firewalls. Neighbor Discovery and MLD are confined to one link, so they must work on the link but should not cross it.
Why each group matters
Packet Too Big (2). IPv6 routers never fragment, so the sender learns the path MTU only from this message (RFC 8201). Drop it and large transfers hang after the handshake while small packets work. This is the most common ICMPv6 mistake in firewalls.
Destination Unreachable (1) and Time Exceeded (3). Without them, connections to closed ports or dead addresses time out rather than failing fast, and traceroute shows nothing.
Parameter Problem (4). Reports a malformed header or an unrecognised option or Next Header. Code 1 (unrecognised Next Header) and code 2 (unrecognised IPv6 option) are meaningful for upper layers and for extension header handling, so allow them.
Neighbor Discovery (133 to 137). Hosts find each other's link-layer addresses with Neighbor Solicitation and Advertisement, and find routers with Router Solicitation and Advertisement (RFC 4861). Blocking these on a link breaks the link. These messages are sent with a hop limit of 255, and receivers verify it: a packet arriving with a lower value has crossed a router and must be discarded, which is the defence against off-link forgery. Therefore never forward them across links, and do not change hop limits on them.
Echo (128, 129). Allowing inbound echo to servers is a policy choice. Blocking it gains little security and makes diagnosis harder. RFC 4890 suggests allowing it, with rate limits.
MLD (130, 131, 132, 143). Multicast Listener Discovery reports which multicast groups a host listens to. IPv6 Neighbor Discovery uses solicited-node multicast addresses, so MLD matters on switches that do MLD snooping: if the switch does not see the reports, it can prune the multicast traffic that Neighbor Solicitation needs. If you see intermittent neighbor failures on a snooping switch, check MLD.
nftables sketch for a host
This is a starting point for a host input chain; adapt it, and keep the policy default-deny for everything else:
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
# Error messages and path MTU discovery
icmpv6 type { destination-unreachable, packet-too-big,
time-exceeded, parameter-problem } accept
# Neighbor Discovery: only valid with hop limit 255
icmpv6 type { nd-router-solicit, nd-router-advert,
nd-neighbor-solicit, nd-neighbor-advert } ip6 hoplimit 255 accept
# Echo, rate-limited
icmpv6 type echo-request limit rate 10/second accept
}
}
Hosts that are not routers do not need to accept Router Solicitation, so remove nd-router-solicit there. A router, in turn, needs the forward chain handled separately: allow the error messages and echo to pass, and do not forward the link-local ones. Check the syntax against your nftables version. The rate figure in the example is arbitrary; choose a value for your own traffic.
Rate-limit, do not block
The usual worry about permitting ICMPv6 is abuse. The proportionate response is rate limiting for the types that can be triggered by outsiders, such as echo and error generation, not a blanket drop. Router CPUs also limit how quickly they generate ICMPv6 errors, which is why traceroute and mtr can show missing or slow hops that do not reflect real forwarding problems.
How to test
From a different network, ping -6 your server, then fetch a large page with curl -6 to exercise path MTU discovery. On a link, ndisc6 or ip -6 neigh shows whether Neighbor Discovery works. If anything fails only over IPv6 and only for larger transfers, suspect a drop of Packet Too Big first.
About IPYE
IPYE (https://my.ipye.com) leases IPv4, IPv6, and ASN space; a /48 IPv6 block is free for the first year. LOA, ROA, rDNS, and WHOIS are handled by IPYE. Locations: Los Angeles, New York, Ashburn, Salt Lake City, London, Amsterdam, and Frankfurt. Questions: ipye@turnel.com.
Disclosure: I run IPYE
Top comments (0)