A 2016 study found that 43% of dual-stack servers responded differently over IPv6 than IPv4.
Here is why iptables leaves IPv6 unprotected and how to audit your server in
one minute.

iptables VS ip6tables
The Linux Kernel maintains independent rule sets for each IP version:
iptables(8): "Iptables and ip6tables are used to set up, maintain, and inspect the tables of IPv4 and IPv6 packet filter rules in the Linux kernel."
Rules added with iptables apply exclusively to IPv4.
By default, the kernel source initializes built-in chains with an ACCEPT policy for both protocols.
As a result, a firewall built with iptables might leave IPv6 completely open.

When Unfiltered IPv6 Exposes Your Server
An empty ip6tables INPUT chain exposes a service when three conditions are
met:
- The host has a global IPv6 address.
- The service listens on
[::](all IPv6 interfaces). - No upstream firewall filters IPv6 traffic.
Upstream filtering is easily misassumed. While AWS security
groups
block IPv6 until you explicitly add a ::/0 rule, host firewalls on many
dual-stack VPS and on-premises systems are the only layer of defense.
Operators Rarely Intend to Leave IPv6 Open
Research done by Czyz, Luckie, Allman and Bailey for NDSS 2016 showed that 43% of servers serving both IP stacks behaved differently for each one.
The research covered 520,000 dual-stack servers and 25,000 routers. On 26% of servers, IPv6 was more permissive than IPv4. On routers, services like SSH, Telnet, and SNMP were twice as exposed over IPv6.
IPv6 firewall misconfiguration is not unique to system administrators. Hardware
vendors make those mistakes too! Pierre
Kim
showed that FiberHome HG6245D fiber terminals (running 2019 firmware) shipped
with every ip6tables chain defaulted to ACCEPT:
"By default, there are no firewall rules for the IPv6 connectivity, exposing the internal management interfaces from the Internet."

Audit Your Server in One Minute
Run these four commands on your host:
ip -6 addr show scope global # Is a global IPv6 address present?
ss -tlnp # Is a service listening on IPv6 ([::]:22 or *:22)?
sudo ip6tables -L -n -v # What are the active IPv6 rules?
sudo nft list ruleset # Does a dual-stack "table inet" exist?
How to Secure IPv6
- Disable IPv6: If you don't use IPv6, leaving it enabled is poor network hygiene.
- Mirror your rules: Duplicate every
iptablesrule withip6tables. - Use ufw: Uncomplicated Firewall enables IPv6 by default (
IPV6=yesin/etc/default/ufw), a standard feature since version 0.31 in 2012. - In firewalld, use rich rules without family specifiers: Omitting both
familyand address definitions tells the system to apply the rules to both IPv4 and IPv6, as per the firewalld documentation. - Migrate to an nftables
inettable: As noted in the nftables wiki, tables using theinetfamily process both IPv4 and IPv6 packets together.
Have you ever found a port responding over IPv6 that you believed was closed on IPv4?
References
- Linux man-pages — iptables(8)
- Jakub Czyz, Matthew Luckie, Mark Allman, Michael Bailey — Don't Forget to Lock the Back Door! A Characterization of IPv6 Network Security Policy, NDSS 2016
- Pierre Kim — Multiple vulnerabilities found in FiberHome HG6245D routers (12 January 2021)
- ufw — ChangeLog, release 0.31 (9 March 2012)
- nftables wiki — Nftables families
- Linux kernel — net/netfilter/xt_repldata.h
- firewalld — Rich language documentation
- AWS — Security group rules
