Create a gist now

Instantly share code, notes, and snippets.

# Generated by ip6tables-save v1.4.7 on Mon May 2 14:26:33 2011
# Loopback
-A INPUT -i lo -j ACCEPT
# ICMPv6
# TYPE 128 = Echo Request
# TYPE 129 = Echo Reply
# TYPE 3 = Time Exceeded
# TYPE 133 = Router Solicitation
# TYPE 134 = Router Advertisement
# TYPE 135 = Neighbor Solicitation
# TYPE 136 = Neighbor Advertisement
# TYPE 137 = Redirect Message
-A INPUT -p icmpv6 -m icmpv6 --icmpv6-type 128 -j ACCEPT
-A INPUT -p icmpv6 -m icmpv6 --icmpv6-type 129 -j ACCEPT
-A INPUT -p icmpv6 -m icmpv6 --icmpv6-type 3 -j ACCEPT
-A INPUT -p icmpv6 -m icmpv6 --icmpv6-type 133 -m hl --hl-eq 255 -j ACCEPT
-A INPUT -p icmpv6 -m icmpv6 --icmpv6-type 134 -m hl --hl-eq 255 -j ACCEPT
-A INPUT -p icmpv6 -m icmpv6 --icmpv6-type 135 -m hl --hl-eq 255 -j ACCEPT
-A INPUT -p icmpv6 -m icmpv6 --icmpv6-type 136 -m hl --hl-eq 255 -j ACCEPT
-A INPUT -p icmpv6 -m icmpv6 --icmpv6-type 137 -m hl --hl-eq 255 -j ACCEPT
-A INPUT -s 2001:db8::/32 -p tcp -m tcp --dport 22 --syn -j ACCEPT
# Public facing DNS server
-A INPUT -s ::/0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -s ::/0 -p tcp -m tcp --dport 53 --syn -j ACCEPT
-A INPUT -s 2001:db8::/32 -p udp -m udp --dport 123 -j ACCEPT
# Match tcp connections with a state of RELATED,ESTABLISHED.
# Include logging with a 3/min burst limit, so syslog doesn't get DoS'd
-A INPUT -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IP6TABLES: "
# Completed on Mon May 2 14:26:33 2011
Generated by iptables-save v1.4.7 on Mon May 2 14:26:33 2011
# Loopback
-A INPUT -i lo -j ACCEPT
# ICMP TYPE 8 = Echo Request
# ICMP TYPE 11 = Time Exceeded
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A INPUT -s -p tcp -m tcp --dport 22 --syn -j ACCEPT
# Public facing DNS server
-A INPUT -s 0/0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -s 0/0 -p tcp -m tcp --dport 53 --syn -j ACCEPT
-A INPUT -s -p udp -m udp --dport 123 -j ACCEPT
-A INPUT -s -p udp -m udp --dport 161 -j ACCEPT
# Stateful match
-A INPUT -m limit --limit 3/min --limit-burst 3 -j LOG --log-prefix "IPTABLES: "
# Completed on Mon May 2 15:18:59 2011

Explanation of IPV6 terminology used in this example.

  • A slash followed by numbers denotes the prefix length.
  • There are 8 hextets (16-bits) of an IPv6 address, or 128-bits total.
  • Therefore /16 represents one hextet, /32 represents two hextets, /48 represents three hextets.

IPv4/IPv6 addresses used in this example

  • fe80::/16 - Link local addresses
  • ff02::/16 - IPV6 multicast
  • 2001:db8::/32 - Example network for documentation, substitute your own network here.
  • - Example network for IPv4 documentation.
  • 0/0 - Public facing source address for an IPv4 service
  • ::/0 - Public facing source address for an IPv6 service

IPv6 Address abbreviation

Just two rules to remember:

  1. You may abbreviate a prefixed series of zeroes, with a single colon as many times as necessary.
  2. You may abbreviate the longest series of zeroes across hextets, with a double colon only once.

The address 2001:0db8:0000:0f00:0000:0000:dead:beef could be abbreviated as 2001:db8:0:f00:0:0:dead:beef by the first rule. The Address 2001:0db8:0000:0f00:0000:0000:dead:beef could be abbreviated as 2001:db8:0:f00::dead:beef by the second rule.

Explanation of IPV6 type codes

  • ICMPv6 type 128 is for the ability to accept a ping (echo request, this was ICMP type 8 on IPV4)
  • ICMPv6 type 129 is never explicitly accepted, it goes out on the OUTPUT table. This code should never come in on the INPUT table.
  • ICMPv6 type 3 is for the ability to get back information from traceroute (Time Exceeded, this was ICMP type 11 on IPV4)

I had to open an additional five ICMP types for NDP (Neighbor Discovery Protocol) to work, so I could ping (2001:4860:800b::6a). It is my understanding that NDP on IPv6 either replaces, or supplements, the ARP (Address Resolution Protocol) which you may be familiar with on IPv4. The NDP related ICMP types were allowed for packets with a hop-limit of 255. Where anything with a hop-limit of 255, would be within your own network segment. These are as follows:

  • ICMPv6 type 133 - Router Solicitation
  • ICMPv6 type 134 - Router Advertisement
  • ICMPv6 type 135 - Neighbor Solicitation
  • ICMPv6 type 136 - Neighbor Advertisement
  • ICMPv6 type 137 - Redirect Message

Recommended references

Using IP calculators for IPv6

I use a couple programs for IPv6 subnetting, and choosing an appropriate IPv6 address based on a LAN IPv4 address. If you subnet your IPv4 LAN into /24 (253) addresses, you can directly map the least significant bit directly to an IPv6 address.

Example mapping IPv4 LAN addresses to unique IPv6 addresses:

  • Using the IPv4 subnet directly mapped to 2001:db8:3::/48

    • Given a host (host bit 4) maps directly to 2001:db8:3::4/48 (4 decimal is equal to 4 hexadecimal)
    • Given a host (host bit 10) maps directly to 2001:db8:3::a/48 (where a in hexadecimal is equal to 10 in decimal).

Given a larger IPv4 subnet, we may have to use more IPv4 octets to directly map to an IPv6 to avoid host ID collisions.

  • Using the IPv4 subnet (1.2.4/24 - 1.2.7/24) directly mapped to 2001:db8:4::/48

    • Given a host, I can directly map this to 2001:db8:4:419/48 (where 419 in hexadecimal, is equivalent to 4.25 in IPv4).
    • Therefore when I map, I can directly map this to 2001:db8:4:719/48 (where 719 in hexadecimal, is equivalent to 7.25 in IPv4).

You can use gethostip <IPv4 address> for an easy way to convert the least significant octets in IPv4 to a unique IPv6 host ID. The program, gethostip, ships with the syslinux distribution (

Sample output of gethostip

gethostip 01020419
gethostip 01020719

Using sipcalc

When I run sipcalc against a given IPv6 address it returns /128, which is equivalent to a /32 address in IPv4 terminology. You may or may not recall that a /32 address is a host ID. So literally means the IP address in IPv4 terminology. So when you use sipcalc, you need to specify the prefix length. This goes back to the previous comment about hextets. To help visualize the part of the address you're masking off with a prefix length, here is a diagram. When you mask with a prefix length, this is the part of the address you cannot change.

  • /16 - ffff: + 7 unmasked hextets
  • /32 - ffff:ffff: + 6 unmasked hextets
  • /48 - ffff:ffff:ffff: + 5 umasked hextets
  • /64 - ffff:ffff:ffff:ffff: + 4 unmasked hextets
  • /80 - ffff:ffff:ffff:ffff:ffff: + 3 unmasked hextets
  • /96 - ffff:ffff:ffff:ffff:ffff:ffff: + 2 unmasked hextets
  • /112 - ffff:ffff:ffff:ffff:ffff:ffff:ffff + 1 unmasked hextet
  • /128 - ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff = host ID

Therefore, if your organization is given an address space of 3 hextets masked, then the corresponding prefix length is 3 * 16 = 48. The example address space is 2001:db8::/32. The prefix length /32 means two hextets are masked (2 * 16 = 32). Feeding this CIDR notation to sipcalc returns the following output:

sipcalc 2001:db8::/32
-[ipv6 : 2001:db8::/32] - 0

Expanded Address        - 2001:0db8:0000:0000:0000:0000:0000:0000
Compressed address      - 2001:db8::
Subnet prefix (masked)  - 2001:db8:0:0:0:0:0:0/32
Address ID (masked)     - 0:0:0:0:0:0:0:0/32
Prefix address          - ffff:ffff:0:0:0:0:0:0
Prefix length           - 32
Address type            - Aggregatable Global Unicast Addresses
Network range           - 2001:0db8:0000:0000:0000:0000:0000:0000 -

Notes concerning static IPv6 addresses on RedHat Enterprise Linux

There seems to be very little in the way of documentation on RHEL, and IPv6 documentation. There is no way to configure IPv6 with the network setup interface on RHEL, even as late as the RHEL 6 release. However, the System V Init scripts shipped with the system do understand IPv6, it just takes a little tinkering to get it right. If you've explicitly disabled IPv6 on RHEL machines, you'll need to reverse these steps. You can usually do this by editing /etc/sysconfig/network, and checking for the existence of something like 'alias ipv6 off' and removing this from your /etc/modprobe* files.

The attached ifcfg-eth0 script shows how to add an IPv4 and IPv6 address to a machine with one active network interface. You will need to set 'IPV6INIT=yes', and an IPV6ADDR equal to your assigned IPv6 host address. As far as I can tell the IPV6_AUTOCONF variable doesn't do anything, yet. Even if you explicitly set IPV6_AUTOCONF to no, it will still behave as if this variable is set to yes. Once everything related to IPv6 is in place, you can run service network restart. Then run iptables-restore < /etc/sysconfig/iptables.

The attached ifcfg-eth1 script shows how to add an IPv4 address and IPv6 address to a multi-homed machine. You must include the IPV6_DEFAULTGW variable on a multi-homed machine with more than one interface. The next hop in this example, 2001:db8:3::2, followed by a \%eth1, denoting the interface name results in setting IPV6_DEFAULTGW equal to 2001:db8:3::2%eth1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment