Thank Goodness for NAT66

I’m participating in a beta test with my ISP for IPv6 connectivity. The ISP deployed a basic IPv6 service that relies exclusively on SLAAC for address assignment. I can connect my end stations to a gigabit switch with direct connectivity to the provider or insert a router in a path. Without receiving a /64 for my office network via DHCPv6 prefix discovery, accessing the IPv6 Internet behind a router requires NAT66. In this post, I’ll describe my experience with NAT66 and point out a strange issue I encountered with IPv6 forwarding in Linux.

Terry Moës implemented stateless and stateful SNAT/DNAT for his thesis. He produced working code for Linux and an interesting paper on his work. His sourceforge page for the project includes:

  • iptables extensions
  • two NAT66 kernel modules
  • modified netfilter and ipv6 header files for the kernel

Here is a logical diagram of the test environment. Stateful NAT66 is implemented on the debian router.



The debian router and end system are VMs. Incidentally, the end system is a vyatta 6.2 VM, which is great as a router or end system in virtualized proof-of-concept testing. The debian router connects directly to the Internet by bridging my ethernet interface on my VM host.

The most challenging aspect of creating the test bed was preparing and configuring the debian router. Kernel compilation is much more difficult in these days of package managers than it was in the late 1990s when I was building customized kernels. With Terry’s assistance, I was able to compile the kernel, modules, and iptables.

I struggled to figure out why the debian router wouldn’t use SLAAC to configure its external interface. I knew that enabling forwarding would result in the OS ignoring Router Advertisements (RAs). I tried tweaking the IPv6 variables in the /proc filesystem. No luck. Fortunately, I stumbled upon a blog post called Linux, IPv6, Router Advertisements, and Forwarding.

The author of the post highlights two methods for accepting RAs when forwarding is enabled.

  • Kernel 2.6.37 and later – Set the “boolean” variable accept_ra to 2 (is this geek humor?) on the interface.
  • Kernel 2.6.32 (current debian stable kernel) – Turn off forwarding on the interface that you want accept RAs. As long as forwarding is enabled globally, the system will route packets.

Soon after I made the change, I successfully obtained an IP address on the external debian router interface. I used the following ip6tables rules for stateful SNAT.

ip6tables -t nat66 -A POSTROUTING -o $OUTSIDE -j SNAT66 --to-range $EXTERNALIP
ip6tables -A FORWARD -i $OUTSIDE -o $INSIDE -m state --state RELATED,ESTABLISHED -j ACCEPT

I was ready for the big test: I pinged 2600:: from the end system. Success!

For NAT66 to be useful in my office, I’d have to port it to my Soekris 4501 or Linksys router. Cross-compiling in itself would take more time than I can invest. There is a subset of end hosts in my office that I can expose to the Internet after hardening the hosts. For my office to be completely IPv6-enabled, I’ll have to wait for my provider to implement DHCPv6 PD.

End-to-end principle be damned! I want to jam the NAT kludge through to the IPv6 Internet. I kid, of course. I encourage readers who haven’t gotten their hands dirty with IPv6 in Linux to pursue a small project. Whether it’s Terry Moës’s NAT66, Ecdysis NAT64, or something else, satisfy your network engineer curiosity. You’ll increase your IPv6 knowledge in the process.

Jeff Loughridge
Jeff Loughridge has been promoting simplicity in IP networks since 1997. In his role as principal consultant at Brooks Consulting, Jeff helps his clients design and operate large-scale wireline and wireless networks. Prior to starting his company in 2009, Jeff spent ten years at Sprint in engineer and manager positions.
Jeff Loughridge

Latest posts by Jeff Loughridge (see all)

  • Ben Jencks

    Did you consider using ND-proxy as an alternative?

    • Jeff Loughridge


      I didn’t consider ND proxy. I’m unaware of any implementations. If you can point some out, please share.

      Jeff L.

      • Will


        I had to do this on a OpenVPN server for awhile until my hosting provider got a routed block to us.
        It was slightly easier in we had client connect scripts that could add/remove proxy_ndp entries.

        For a LAN, you could write a script to proxy a bunch of addresses to create a pool and handout via DHCPv6.

        • Jeff Loughridge


          Thanks for sharing the URL. I’ll try it.

          Jeff L.

  • ktokash

    I know the anti-NAT folks will poop on me, but I really hope NAT66 becomes the norm in home equipment (though I’m on the cusp of upgrading the house to an SRX, need to justify it to the Chief Wife Officer).  The simple reason is I suspect cable/dsl providers intend to charge extra for multiple addresses.  If NAT66 exists as an alternative they’ll never even propose it because it won’t go anywhere.

    I very selfishly have no intention of paying TWC an extra $8/month or whatever they end up dinging me so I can have a usable LAN at home on v6.

  • TJ Evans

    Has your provider upgraded to Native IPv6 connectivity, available to everyone, yet?

    (I give props to Comcast, in my service region they have deployed native IPv6 for their customers … living w/o a tunnel feels good!)

    • Jeff Loughridge


      Unfortunately, my provider’s IPv6 service is still in beta with no ETA on when it will be generally available.

  • Peyton Quast

    Hey Jeff, did you have to do anything to get nat66 to compile correctly? I’m having trouble on Fedora and figured I would ask you.

    • Jeff Loughridge


      I did the compilation on a Ubuntu server. I compiled using the kernel sources from I did not use the Ubuntu package. I recommend avoiding packages in Fedora as well.

      The nat66 README covers many of the issues I encountered. If you follow the directions exactly, it *should* compile successfully.

      Hit me up on email if you want to discuss further.

      • Zhe

        Hi, could you please let me know where is the nat66 README file? Thanks so much

        • Jeff Loughridge

          Looks like the project’s author forgot to post it on sourceforge. I emailed him. I’ll let you know.

  • jbuddy

    I tried compiling following author’s instructions on sourceforge everything went fine but iptables won’t compile with extensions, by looking at the error I tried to hack it and copied nf_nat66.h from Kernel_modules to include folder of iptables and it compiled did anyone have similar issue?

  • jbuddy

    Hi Jeff,
    Can you explain what you mean by –to-range in the example:
    ip6tables -t nat66 -A POSTROUTING -o $OUTSIDE -j SNAT66 –to-range $EXTERNALIP

    • Jeff Loughridge

      As I recall, the “–to-range” flag takes a single IP or a range of IPs (e.g., /24). These IP addresses are the external, globally routable addresses.

  • be4stie


    Assuming your Soekris serves as a firewall, you could easily put OpenBSD on it.

    This way there is no need to recompile a kernel module and whatnot.

    OpenBSD PF (Packet Filter) is really nice to work with and very robust. You will need to port your firewall rules, but it’s worth it in my opinion. (not to mention that the rules syntax is a breeze) Assuming you don’t use any fancy linux/netfilter only thing, then OpenBSD can probably fill your needs. It’s also really low maintenance: your typical OpenBSD firewall only needs an upgrade every 6months – a year. PF syntax hardly ever changes too, so the maintenance procedure is just : backup (you already do that, don’t you?), upgrade / install from scratch, restore backup .. and you’re good to go.

    The reason I’m mentionning this is because PF has been doing NAT66 for ages now (and it even does NAT64 now :)).

    Other than that, thanks for the post, as I’m on a projet where I need to work Linux exclusively and your precisions were really helpful

    • Jeff Loughridge

      Thanks for letting me know about OpenBSD PF. I have several spare Soekris boxes lying around. I’ll give PF a shot.

  • UltraMega

    NAT66 is required, really?! LOL

    • Jeff Loughridge

      The title of the article is tongue-in-cheek. You’ll find people with strong feelings for and against NAT66. I’d like to see the return of the end-to-end model. Since writing this article, my provider allocated a /64 that is statically routed to my CPE.