How to Write iptables Rules for IPv6

105544

We US-ians have been sheltered from the exhaustion of IPv4 addresses, but they have run out. IPv6 networks are up and running, so we have no excuses for not being IPv6 literate. Today our scintillating topic is iptables rules for IPv6, because, I am sad to report, our faithful IPv4 iptables rules do not magically work on IPv6 packets, and we must write new rules.

Before we dive in, you might want to review these previous articles for basic iptables concepts and scripts:

Iptables Commands

iptables should be the same on all Linuxes, as it is part of the kernel, but if your chosen Linux distribution does something weird, it’s not my fault. You should have ip6tables, ip6tables-restore, ip6tables-save, ip6tables-apply, and their corresponding man pages. Some Linux distributions install with a ready-made firewall and their own tools for stopping and starting it. You must decide whether to disable your distro configuration, or modify it if it’s based on iptables.

ip6tables operates the same way as iptables. It even supports NAT, network address translation, although I can’t think of a good use case for NAT in IPv6. NAT does masquerading and port forwarding, which has extended the lifespan of the inadequate IPv4 address pool by making a single public IPv4 address serve many hosts in private address spaces. NAT rewrites the private addresses to the single public address, and keeps track of which packets belong to which private addresses. This isn’t necessary in IPv6 because the pool of available addresses is so large we’ll never run out (at least not in my lifetime).

Block All IPv6

Because IPv4 rules do not affect IPv6 packets, theoretically, we are vulnerable to attacks over IPv6. The Internet of Gratuitously Connected Insecure Things (IoGIT, creatively abbreviated to pronounce as “idjit”) is experiencing denial-of-service and SYN flood attacks over IPv6, though it seems to me the bigger threat is snoopy vendors who suck up and exploit our personal data. Even iRobot is joining this abusive game by collecting and selling maps of our homes, from Roomba models 960 and 980. When you can’t even trust your cute robot vacuum cleaner, they have gone too far.

You might think meh, I don’t even need IPv6, so why not block it completely? You can, though this may cause some problems, but you won’t know until you try. Add these lines to /etc/sysctl.conf:

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1

Then load your changes:

$ sudo sysctl -p
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1

Test this by pinging the link local address of your computer from a second computer on your LAN:

$ ping6 -c3 -I eth0 fe80::f07:3c7a:6d69:8d11
PING fe80::f07:3c7a:6d69:8d11(fe80::f07:3c7a:6d69:8d11) 
from fe80::2eef:d5cc:acac:67c wlan0 56 data bytes
--- fe80::2eef:d5cc:acac:67c ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2999s

This shows that it is disabled. When you re-enable IPv6, you must renew the DHCP lease on your interface to get an IPv6 address again.

Listing and Flushing Rules

First, see if you already have any rules:

$ sudo ip6tables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 

This shows there are no existing rules. If you already have some rules, clear them with this command:

$ sudo ip6tables -F

If you already have active firewall scripts, a reboot restores your rules.

Example Host Rules

This is similar to the host firewall example in Building Linux Firewalls With Good Old Iptables: Part 2. The main difference managing ICMP packets; IPv6 relies a lot more on good ole ping, it is a bad idea to completely block ICMP, even though some howtos recommend this, because it is necessary for proper network operations. In this example all ICMP packets are allowed.

When you’re unsure about protocol names, look in /etc/protocols to find the correct names.

#!/bin/bash

# ip6tables single-host firewall script

# Define your command variables
ipt6="/sbin/ip6tables"

# Flush all rules and delete all chains
# for a clean startup
$ipt6 -F
$ipt6 -X 

# Zero out all counters
$ipt6 -Z

# Default policies: deny all incoming
# Unrestricted outgoing

$ipt6 -P INPUT DROP
$ipt6 -P FORWARD DROP
$ipt6 -P OUTPUT ACCEPT

# Must allow loopback interface
$ipt6 -A INPUT -i lo -j ACCEPT

# Reject connection attempts not initiated from the host
$ipt6 -A INPUT -p tcp --syn -j DROP

# Allow return connections initiated from the host
$ipt6 -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Accept all ICMP v6 packets
$ipt6 -A INPUT -p ipv6-icmp -j ACCEPT

# Optional rules to allow other LAN hosts access 
# to services. Delete $ipt6 -A INPUT -p tcp --syn -j DROP

# Allow DHCPv6 from LAN only
$ipt6 -A INPUT -m state --state NEW -m udp -p udp 
-s fe80::/10 --dport 546 -j ACCEPT

# Allow connections from SSH clients
$ipt6 -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

# Allow HTTP and HTTPS traffic 
$ipt6 -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
$ipt6 -A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT

# Allow access to SMTP, POP3, and IMAP
$ipt -A INPUT -m state --state NEW -p tcp -m multiport 
--dport 25,110,143 -j ACCEPT

There isn’t much in the way of updated official documentation that I can find for ip6tables other than man iptables. If you’re using online man pages make sure they are for your version, iptables --version.

In a future installment, we’ll go into detail on managing ICMP packets, controlling which ones have Internet access, which ones should be LAN-only, rate limiting, and other cool fine-tunings. We’ll also make an Internet gateway and look at rules for restricting source and destination addresses in more details.

Learn more about Linux through the free “Introduction to Linux” course from The Linux Foundation and edX.