Kingsfordweg 151, 1043GR Amsterdam, The Netherlands ● 24/7 support — support@novogara.com
Knowledge base

Firewalling IPv6

A machine with a strict IPv4 firewall and no IPv6 rules is an open machine. This is the single most common firewall mistake we see.

Check right now

From another network, not from the server:

nmap -6 -p- yourserver.example.com

Or at minimum, on the machine:

ip6tables -L -n -v

If that shows an empty ACCEPT policy while your IPv4 rules are strict, every service bound to :: is reachable from the entire internet. Databases, caches and admin panels included.

Use nftables and write it once

The inet family covers IPv4 and IPv6 in the same ruleset, which removes the whole class of problem:

table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;
    ct state established,related accept
    iif lo accept
    icmpv6 type { echo-request, nd-neighbor-solicit, nd-neighbor-advert, nd-router-advert, packet-too-big, time-exceeded, parameter-problem, destination-unreachable } accept
    icmp type { echo-request, destination-unreachable, time-exceeded } accept
    tcp dport { 22, 80, 443 } accept
  }
}

With ufw, every ufw allow already covers both families — just confirm IPV6=yes in /etc/default/ufw, which is the default but worth checking.

ICMPv6 is not optional

This is the part people get wrong after getting the ports right. IPv6 depends on ICMPv6 for things IPv4 does elsewhere:

  • Neighbour discovery replaces ARP. Block it and the machine cannot talk to its own gateway.
  • Packet too big is how path MTU discovery works, and there is no fragmentation by routers in IPv6 to fall back on. Block it and large transfers hang while small ones work — exactly the symptom in MTU, fragmentation and tunnels.

Blocking ICMPv6 wholesale is how people create a problem that takes days to find.

Check what is listening on which family

ss -ltnp

An entry showing *:3306 or [::]:6379 is listening on every address in both families. Bind it to localhost or a private address instead — see connecting your own servers. Firewall rules are the second layer, not the first.

Firewall by prefix, not by address

IPv6 addresses change — privacy extensions, renumbering, a new allocation. A rule pinned to a single address breaks silently. Allow the /64 or the customer's whole prefix instead, which is also how the address plan was meant to be used — see planning your address space.

Test from outside, both families

Every time. A rule that looks right in the file and a port that is actually open are different claims, and only one of them matters. See firewalling your server and IPv6 on your server.


Still stuck? Mail support@novogara.com — an engineer answers, at any hour. Back to the knowledge base