Porting iptables to ip6tables

A couple of days ago I received an email notification by the Berkeley Security Notifications Team that a Linux server of mine had less restrictive firewall rules for IPv6 than it had for IPv4. This prompted me to update my ip6tables settings on that host to make it is as secure via IPv6 as it was for IPv4.

If you have a dual stack server with IPv4 A records and IPv6 AAAA records published in DNS, you should have it protected with firewall rules on both protocols. Even if you only publish A records and not AAAA ones, you should secure IPv6 access because its address may leak to potential attackers in other ways.

The ip6tables tool is installed as part of iptables on recent distributions, but you need to set up one set of rules for each protocol. They’re independent of each other. A (not very secure) default ip6tables configuration might look like this:

# Generated by ip6tables-save v1.4.21 on Thu Sep 24 11:17:56 2015
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1456:118498]
-A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p ipv6-icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state –state NEW -m tcp –dport 22 -j ACCEPT
-A INPUT -j REJECT –reject-with icmp6-adm-prohibited
-A FORWARD -j REJECT –reject-with icmp6-adm-prohibited
COMMIT
# Completed on Thu Sep 24 11:17:56 2015

It’s relatively easy to port additional settings from iptables to ip6tables (e.g. in /etc/sysconfig/iptables and /etc/sysconfig/ip6tables for CentOS).

Below are some of the changes needed when porting common entries. As you can see, some names are replaced with those of IPv6 equivalents. Any IP addresses and CIDRs for ip6tables need to be written in IPv6 notation.

To easily port over IPv4 addresses, simply prefix them with “::ffff:”. If they’re followed by a bit count such as /24 (the routing prefix size), add 96 to that number (IPv6 addresses are 128 bits each versus 32 bits for IPv4). Add equivalent rules for the corresponding native IPv6 addresses as needed.

  1. Accept ping from any source:

    IPv4:

    -A INPUT -p icmp -j ACCEPT

    IPv6:

    -A INPUT -p ipv6-icmp -j ACCEPT

  2. Accept connection from white-listed address:

    IPv4:

    -A SSH-IN -s 123.45.67.89/32 -j ACCEPT

    IPv6:

    -A SSH-IN -s ::ffff:123.45.67.89/128 -j ACCEPT
    -A SSH-IN -s 2345:abcd:678:42::/64 -j ACCEPT

  3. Rule to block access (after all the exceptions):

    IPv4:

    -A INPUT -j REJECT –reject-with icmp-host-prohibited
    -A FORWARD -j REJECT –reject-with icmp-host-prohibited

    IPV6:

    -A INPUT -j REJECT –reject-with icmp6-adm-prohibited
    -A FORWARD -j REJECT –reject-with icmp6-adm-prohibited

Leave a Reply

Your email address will not be published. Required fields are marked *