Setting up IPv6-only network with NAT64 and DNS64, on SRX 300

The time has come for me to attempt a single-stack network with IPv6 but still having access to IPv4-only servers (like Tiktok).

This will require you to either use Google’s DNS64 or your own, but I decided to use Google’s as it uses the known NAT64 prefix (64:ff9b::/96) which is very useful as you don’t need to run your own resolver.
This also expects you to know basic JunOS knowledge (like how to enter configuration mode).

Let’s start to configure it, which we will start from SRX side.

First we start with making sure we don’t have DHCPv4 enabled on the LAN:

show system services dhcp-local-server

There shouldn’t be anything for group that references our interface at this point, in my case it would be irb.0.

Make sure that your access address-assignment don’t have propogate-settings irb.0:

show access address-assignment

If all of that is fine as in there’s either nothing or v4 pool without propogate-settings, we can carry on.

First we create a dhcpv6 server, with local interface group and interface-client-limit:

set system services dhcp-local-server dhcpv6 overrides interface-client-limit 100
set system services dhcp-local-server dhcpv6 group local interface irb.0

Next we need to make sure our interface (irb.0) has an IPv6 block attached to it:

set interfaces irb unit 0 family inet6 address 2001:DB8:1::1/64

You can now commit the config, and test that you do get an IPv6 address from it.
If you do, then continue.

The fun begins, aka we need to create the NAT rules, first up is source NAT from LAN:

set security nat source rule-set LAB-Internet from zone trust
set security nat source rule-set LAB-Internet to zone untrust

The security zone trust is LAN, and untrust is WAN.

set security nat source rule-set LAB-Internet rule nat64-src match source-address 2001:DB8:1::/64 destination-address 0.0.0.0/0
set security nat source rule-set LAB-Internet rule nat64-src then source-nat interface

Next we need to add static NAT rules the other direction:

set security nat static rule-set nat64-LAB from zone trust
set security nat static rule-set nat64-LAB rule ipv6-clients1 match destination-address 64:ff9b::/96
set security nat static rule-set nat64-LAB rule ipv6-clients1 then static-nat inet

After which you need to make sure that prefix and DNS64 resolvers are being advertised via RA:

set protocols router-advertisement interface irb.0 dns-server-address 2001:4860:4860::6464
set protocols router-advertisement interface irb.0 dns-server-address 2001:4860:4860::64
set protocols router-advertisement interface irb.0 prefix 2001:DB8:1::/64

Now if you try to access for example tiktok.com the DNS response should have an AAAA record translated to an address from the 64:ff9b::/96 block.

The SRX configuration should be done at this stage so next up is configuring Tayga (NAT64 implementation for Linux) on a server with IPv4 and IPv6 address. I’m using Ubuntu Server for this step.

The Tayga software should be available from the default repositories on it so it’s just a matter of:

sudo apt update && sudo apt install tayga

Make sure that you have IPv4 and IPv6 forwarding enabled in /etc/sysctl.conf:

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

After you need to restart or execute sudo sysctl -p to activate them.

Next you need to configure Tayga for which the configuration files are below.

The configuration file at /etc/tayga.conf needs to look something like:

#
# Sample configuration file for TAYGA 0.9.2
#
# Modify this to use your own addresses!!
#

#
# TUN device that TAYGA will use to exchange IPv4 and IPv6 packets with the
# kernel.  You may use any name you like, but `nat64' is recommended.
#
# This device may be created before starting the tayga daemon by running
# `tayga --mktun`.  This allows routing and firewall rules to be set up prior
# to commencement of packet translation.
#
# Mandatory.
#
tun-device nat64

#
# TAYGA's IPv4 address.  This is NOT your router's IPv4 address!  TAYGA
# requires its own address because it acts as an IPv4 and IPv6 router, and
# needs to be able to send ICMP messages.  TAYGA will also respond to ICMP
# echo requests (ping) at this address.
#
# This address can safely be located inside the dynamic-pool prefix.
#
# Mandatory.
#
ipv4-addr 100.65.0.1

#
# TAYGA's IPv6 address.  This is NOT your router's IPv6 address!  TAYGA
# requires its own address because it acts as an IPv4 and IPv6 router, and
# needs to be able to send ICMP messages.  TAYGA will also respond to ICMP
# echo requests (ping6) at this address.
#
# You can leave ipv6-addr unspecified and TAYGA will construct its IPv6
# address using ipv4-addr and the NAT64 prefix.
#
# Optional if the NAT64 prefix is specified, otherwise mandatory.  It is also
# mandatory if the NAT64 prefix is 64:ff9b::/96 and ipv4-addr is a private
# (RFC1918) address.
#
ipv6-addr 2001:DB8:10a:e807:f3ff:fe6f:2f5d

#
# The NAT64 prefix.  The IPv4 address space is mapped into the IPv6 address
# space by prepending this prefix to the IPv4 address.  Using a /96 prefix is
# recommended in most situations, but all lengths specified in RFC 6052 are
# supported.
#
# This must be a prefix selected from your organization's IPv6 address space
# or the Well-Known Prefix 64:ff9b::/96.  Note that using the Well-Known
# Prefix will prohibit IPv6 hosts from contacting IPv4 hosts that have private
# (RFC1918) addresses, per RFC 6052.
#
# The NAT64 prefix need not be specified if all required address mappings are
# listed in `map' directives.  (See below.)
#
# Optional.
#
#prefix 2001:db8:1:ffff::/96
prefix 64:ff9b::/96

#
# Dynamic pool prefix.  IPv6 hosts which send traffic through TAYGA (and do
# not correspond to a static map or an IPv4-translatable address in the NAT64
# prefix) will be assigned an IPv4 address from the dynamic pool.  Dynamic
# maps are valid for 124 minutes after the last matching packet is seen.
#
# If no unassigned addresses remain in the dynamic pool (or no dynamic pool is
# configured), packets from unknown IPv6 hosts will be rejected with an ICMP
# unreachable error.
#
# Optional.
#
#dynamic-pool 192.168.255.0/24
dynamic-pool 100.65.0.0/16
#
# Persistent data storage directory.  The dynamic.map file, which saves the
# dynamic maps that are created from dynamic-pool, is stored in this
# directory.  Omit if you do not need these maps to be persistent between
# instances of TAYGA.
#
# Optional.
#
data-dir /var/spool/tayga

#
# Establishes a single-host map.  If an IPv6 host should be consistently
# reachable at a specific IPv4 address, the mapping can be specified in a
# `map' directive.  (IPv6 hosts numbered with an IPv4-translatable address do
# not need map directives.)
#
# IPv4 addresses specified in the `map' directive can safely be located inside
# the dynamic-pool prefix.
#
# Optional.
#
#map 192.168.5.42 2001:db8:1:4444::1
#map 192.168.5.43 2001:db8:1:4444::2
#map 192.168.255.2 2001:db8:1:569::143

The default file for Tayga at /etc/default/tayga needs to look something like:

# Defaults for tayga initscript
# sourced by /etc/init.d/tayga
# installed at /etc/default/tayga by the maintainer scripts

# Change this to "yes" to enable tayga
RUN="yes"

# Configure interface and set the routes up
CONFIGURE_IFACE="yes"

# Configure NAT44 for the private IPv4 range
CONFIGURE_NAT44="yes"

# Additional options that are passed to the Daemon.
DAEMON_OPTS=""

# IPv4 address to assign to the NAT64 tunnel device
IPV4_TUN_ADDR=""

# IPv6 address to assign to the NAT64 tunnel device
IPV6_TUN_ADDR=""

After all of that, you should only need to enable Tayga and start the service:

sudo systemctl enable tayga && sudo systemctl start tayga

After you have reached this stage, you should be able to verify it works correctly by doing: ip -6 r s dev nat64 or whatever the interface name you used in the tun device was.

Now it will work if you have routing setup correctly, you can use BGP or static routes. Choice is yours.


© 2018-2021 Skyler Mäntysaari