Recently I took the JNCIE-SEC lab (that will be another post) and wanted to cover one of the study points that I initially struggled with, IPv4<->IPv6 NAT on a Juniper SRX device. This configuration is actually “relatively” simple once you understand it, yet most of the examples I found out there made it difficult to understand. My hope here is to put it in a format to help you understand how to configure it on a Juniper SRX device (this lab used vSRX on EVE-NG).

Before we get into the start of the config, please be aware that Site1 and Site2 SRX’s have been placed into packet mode. This mode makes them a router and not a security device, so no security policies will be required on these devices. The main SRX is still in flow mode and will require security policies to permit the traffic. For this lab, I will be using a simple global any/any/any policy.

Site1 & Site2 packet mode config:
set security forwarding-options family inet6 mode packet-based
set security forwarding-options family mpls mode packet-based
set security forwarding-options family iso mode packet-based
Global Security Policy on the SRX:
root@SRX-NAT> show configuration security policies
 global {
     policy PERMIT-ALL {
         match {
             source-address any;
             destination-address any;
             application any;
             from-zone [ IPV4 IPV6 ];
             to-zone [ IPV4 IPV6 ];
         }
         then {
             permit;
         }
     }
 }

Below is our lab topology. In the BLUE box on the left, we have our IPv4 only site using a subnet of 192.168.100.0/24. The host is assigned the IP of 192.168.100.2 and the SRX is assigned an IP of 192.168.100.1. On the SRX, will call this security zone IPV4

In the RED box on the right, we have our IPv6 network using 2001:db8::/64 for the subnet. The host is assigned 2001:db8::2/64 and the SRX has an IP of 2001:db8::1. On the SRX we will call this security zone IPV6.

In order for IPv4 to talk to an IPv6 network and IPv6 to talk to IPv4, we will need to perform source NAT as well as destination NAT. Source NAT will be used to NAT traffic from one zone to an interface and subnet in the other zone.

Destination NAT will be used so that the IPv4 host can initiate traffic towards the IPv6 host via an IPv4 NAT address. In the same fashion, we will have an IPv6 NAT address for the IPv6 host to initiate traffic towards the IPv4 host.

For the IPv4 host to generate traffic towards the IPv6 host we will use an IPv4 NAT address of 192.168.100.254. For the IPv6 host to generate traffic to the IPv4 host, we will use an IPv6 NAT of 2001:db8::254. This will make a bit more sense once we perform the configuration.

Ok – quick recap of all the information mentioned so far:

Global Security Policies
Source          - Any
Destination     - Any
Application     - Any
Zones           - IPV4 IPV6
IPv4 Information
Subnet          - 192.168.100.0/24
SRX ge-0/0/0    - 192.168.100.1/24
Host ge-0/0/0   - 192.168.100.2/24
IPv4 - IPv6 NAT - 192.168.100.254/32
Security Zone   - IPV4
IPv6 Information
Subnet          - 2001:db8::/64
SRX ge-0/0/1    - 2001:db8::1/64
Host ge-0/0/0   - 2001:db8::2/64
IPv6 - IPv4 NAT - 2001:db8::254/128
Security Zone   - IPV6

We will start with our Source NAT configuration. This is a standard source-NAT configuration that is commonly used to traffic from internal networks to the Internet on Juniper firewalls all the time.

In the configuration snippet below we have configured a source nat for all traffic from 192.168.100.0/24 (IPV4) towards 2001:db8::0/64 (IPV6) to be NAT’d to the ge-0/0/1 interface (2001:db8::1).

root@SRX-NAT> show configuration security nat source
rule-set IPV4-OUT {
     from zone IPV4;
     to zone IPV6;
     rule IPV4-IPV6-NAT {
         match {
             source-address 192.168.100.0/24;
             destination-address 2001:db8::0/64;
         }
         then {
             source-nat {
                 interface;
             }
         }
     }
 }

In the snippet below we configure another source NAT policy for all traffic from 2001:db8::/64 (IPV6) towards 192.168.100.0/24 (IPV4) to be NAT’d to the ge-0/0/0 interface (192.168.100.1).

root@SRX-NAT> show configuration security nat source
 rule-set IPV6-OUT {
     from zone IPV6;
     to zone IPV4;
     rule IPV6-IPV4-NAT {
         match {
             source-address 2001:db8::/64;
             destination-address 192.168.100.0/24;
         }
         then {
             source-nat {
                 interface;
             }
         }
     }
 }

Now that we have a way to translate traffic between the networks we need a way to initiate traffic. This is where the destination NAT addresses of 192.168.100.254 and 2001:db8::254 come into play.

The first thing we will do is configure two destination NAT pools. One pool for each of the hosts we want to talk to. To keep it simple I will use the names IPV4-HOST for 192.168.100.2 and IPV6-HOST for 2001:db8::2. The reason that the pool is the IP address of the destination host is that we will translate our NAT to that IP.

root@SRX-NAT> show configuration security nat destination
 pool IPv4-HOST {
     address 192.168.100.2/32;
 }
 pool IPv6-HOST {
     address 2001:db8::2/128;
 }

We will start with the IPv4 to IPv6 destination NAT configuration. Here you can see we are specifying the source zone of IPV4 and matching the destination address of 192.168.100.254 (NAT). We are then telling the policy to use the destination-nat pool that references the IPv6 host (2001:db8::2). So what this policy is doing is NATing 192.168.100.254/32 -> 2001:db8::2/128.

root@SRX-NAT> show configuration security nat destination
 rule-set IPV4-to-IPV6 {
     from zone IPV4;
     rule IPV4-NAT {
         match {
             destination-address 192.168.100.254/32;
         }
         then {
             destination-nat {
                 pool {
                     IPv6-HOST;
                 }
             }
         }
     }
 }

Below we are specifying the source zone of IPV6 now and matching the destination address of 2001:db8::254 (NAT). We are then telling the policy to use the destination-nat pool that references the IPv4 host (192.168.100.2). So what this policy is doing is NATing 2001:db8::254/128 -> 192.168.100.2/32.

root@SRX-NAT> show configuration security nat destination
 rule-set IPV6-to-IPV4 {
     from zone IPV6;
     rule IPV6-NAT {
         match {
             destination-address 2001:db8::254/128;
         }
         then {
             destination-nat {
                 pool {
                     IPv4-HOST;
                 }
             }
         }
     }
 }

Now let’s test PING between the two sites.

root@IPV4-HOST> ping 192.168.100.254 rapid
 PING 192.168.100.254 (192.168.100.254): 56 data bytes
 …..
 --- 192.168.100.254 ping statistics ---
 5 packets transmitted, 0 packets received, 100% packet loss
root@IPV6-HOST> ping 2001:db8::254 rapid
 PING6(56=40+8+8 bytes) 2001:db8::2 --> 2001:db8::254
 …..
 --- 2001:db8::254 ping6 statistics ---
 5 packets transmitted, 0 packets received, 100% packet loss

You would think it would work, right? Well, it is not working yet because we are missing a few commands. In order to see what is wrong, we can look at our IPv4 and IPv6 host ARP/Neighbor tables.

root@IPV4-HOST> show arp no-resolve
 MAC Address       Address         Interface     Flags
 50:00:00:01:00:01 192.168.100.1   ge-0/0/0.0           none
root@IPV6-HOST> show ipv6 neighbors
 IPv6 Address                 Linklayer Address  State       Exp Rtr Secure Interface
 2001:db8::1                  50:00:00:01:00:02  stale       1083 yes no     ge-0/0/0.0
 2001:db8::254                none               unreachable 1   yes no      ge-0/0/0.0

As you can see, we do not have an ARP entry for 192.168.100.254 nor a neighbor entry for 2001:db8::254. This is because the source and destination NAT IPs are on the same subnet and Juniper SRX requires proxy ARP for IPv4 and proxy NDP for IPv6 to be configured.

Here we configure proxy-arp for the 192.168.100.254 address on the IPv4 interface (ge-0/0/0.0) and proxy-ndp for the 2001:db8::254 on the IPv6 interface (ge-0/0/1.0).

root@SRX-NAT> show configuration security nat
 proxy-arp {
     interface ge-0/0/0.0 {
         address {
             192.168.100.254/32;
         }
     }
 }
 proxy-ndp {
     interface ge-0/0/1.0 {
         address {
             2001:db8::254/128;
         }
     }
 }

Now that we have that configured, let’s initiate a PING from the IPv4 host towards the IPv4 NAT address of 192.168.100.254. As you can see from the output below, the ping succeeds and we now have an ARP entry for the 192.168.100.254 IP.

root@IPV4-HOST> ping 192.168.100.254 rapid
 PING 192.168.100.254 (192.168.100.254): 56 data bytes
 !!!!!
 --- 192.168.100.254 ping statistics ---
 5 packets transmitted, 5 packets received, 0% packet loss
 round-trip min/avg/max/stddev = 14.687/18.725/20.134/2.048 ms
 root@IPV4-HOST> show arp no-resolve
 MAC Address       Address         Interface     Flags
 50:00:00:01:00:01 192.168.100.254 ge-0/0/0.0           none

Now let us go look at our NAT rules for this traffic to see if they are actually being matched. We will look at the source IPv4 rule (IPV4-IPV6-NAT) and the destination NAT rule (IPV4-NAT). As you can see in the output below we have Translation hits of 10 on each.

root@SRX-NAT> show security nat source rule IPV4-IPV6-NAT
 source NAT rule: IPV4-IPV6-NAT          Rule-set: IPV4-OUT
   Rule-Id                    : 1
   Rule position              : 1
   From zone                  : IPV4
   To zone                    : IPV6
   Match
     Source addresses         : 192.168.100.0   - 192.168.100.255
     Destination addresses    : 2001:db8::      - 2001:db8::ffff:ffff:ffff:ffff
   Action                        : interface
     Persistent NAT type         : N/A
     Persistent NAT mapping type : address-port-mapping
     Inactivity timeout          : 0
     Max session number          : 0
   Translation hits           : 10
     Successful sessions      : 10
     Failed sessions          : 0
   Number of sessions         : 0
 root@SRX-NAT> show security nat destination rule IPV4-NAT
 Destination NAT rule: IPV4-NAT               Rule-set: IPV4-to-IPV6
   Rule-Id                    : 1
   Rule position              : 1
   From zone                  : IPV4
     Destination addresses    : 192.168.100.254 - 192.168.100.254
   Action                     : IPv6-HOST
   Translation hits           : 10
     Successful sessions      : 10
     Failed sessions          : 0
   Number of sessions         : 0

Now we can test connectivity from the IPv6 host towards the IPv4 host using the IPv6 NAT (2001:db8::254). As you can see in the output below, it was successful.

root@IPV6-HOST> ping 2001:db8::254 rapid
 PING6(56=40+8+8 bytes) 2001:db8::2 --> 2001:db8::254
 !!!!!
 --- 2001:db8::254 ping6 statistics ---
 5 packets transmitted, 5 packets received, 0% packet loss
 round-trip min/avg/max/std-dev = 9.519/10.763/14.351/1.805 ms

Now we can look at the IPv6 NAT policies that are used for this traffic. Again we can see we have 10 matches for each policy.

root@SRX-NAT> show security nat destination rule IPV6-NAT
 Destination NAT rule: IPV6-NAT               Rule-set: IPV6-to-IPV4
   Rule-Id                    : 2
   Rule position              : 2
   From zone                  : IPV6
     Destination addresses    : 2001:db8::254   - 2001:db8::254
   Action                     : IPv4-HOST
   Translation hits           : 10
     Successful sessions      : 10
     Failed sessions          : 0
   Number of sessions         : 0
 root@SRX-NAT> show security nat source rule IPV6-IPV4-NAT
 source NAT rule: IPV6-IPV4-NAT          Rule-set: IPV6-OUT
   Rule-Id                    : 2
   Rule position              : 2
   From zone                  : IPV6
   To zone                    : IPV4
   Match
     Source addresses         : 2001:db8::      - 2001:db8::ffff:ffff:ffff:ffff
     Destination addresses    : 192.168.100.0   - 192.168.100.255
   Action                        : interface
     Persistent NAT type         : N/A
     Persistent NAT mapping type : address-port-mapping
     Inactivity timeout          : 0
     Max session number          : 0
   Translation hits           : 10
     Successful sessions      : 10
     Failed sessions          : 0
   Number of sessions         : 0

That about covers the configuration of IPv4 <-> IPv6 NAT. Below is the full configuration from the NAT router for your reference. If you would like to download the configs – the links are below as well as the lab topology for EVE-NG if you want to lab it up yourself.

IPv4 Host Config
IPv6 Host Config
vSRX NAT Config
EVE-NG Lab

root@SRX-NAT> show configuration
 Last commit: 2019-05-03 00:40:07 UTC by root
 version 17.3R1.10;
 system {
     host-name SRX-NAT;
     root-authentication {
         encrypted-password "postedatfryguy.net"; ## SECRET-DATA
     }
 }
 security {
     nat {
         source {
             rule-set IPV4-OUT {
                 from zone IPV4;
                 to zone IPV6;
                 rule IPV4-IPV6-NAT {
                     match {
                         source-address 192.168.100.0/24;
                         destination-address 2001:db8::0/64;
                     }
                     then {
                         source-nat {
                             interface;
                         }
                     }
                 }
             }
             rule-set IPV6-OUT {
                 from zone IPV6;
                 to zone IPV4;
                 rule IPV6-IPV4-NAT {
                     match {
                         source-address 2001:db8::/64;
                         destination-address 192.168.100.0/24;
                     }
                     then {
                         source-nat {
                             interface;
                         }
                     }
                 }
             }
         }
         destination {
             pool IPv4-HOST {
                 address 192.168.100.2/32;
             }
             pool IPv6-HOST {
                 address 2001:db8::2/128;
             }
             rule-set IPV4-to-IPV6 {
                 from zone IPV4;
                 rule IPV4-NAT {
                     match {
                         destination-address 192.168.100.254/32;
                     }
                     then {
                         destination-nat {
                             pool {
                                 IPv6-HOST;
                             }
                         }
                     }
                 }
             }
             rule-set IPV6-to-IPV4 {
                 from zone IPV6;
                 rule IPV6-NAT {
                     match {
                         destination-address 2001:db8::254/128;
                     }
                     then {
                         destination-nat {
                             pool {
                                 IPv4-HOST;
                             }
                         }
                     }
                 }
             }
         }
         proxy-arp {
             interface ge-0/0/0.0 {
                 address {
                     192.168.100.254/32;
                 }
             }
         }
         proxy-ndp {
             interface ge-0/0/1.0 {
                 address {
                     2001:db8::254/128;
                 }
             }
         }
     }
     policies {
         global {
             policy PERMIT-ALL {
                 match {
                     source-address any;
                     destination-address any;
                     application any;
                     from-zone [ IPV4 IPV6 ];
                     to-zone [ IPV4 IPV6 ];
                 }
                 then {
                     permit;
                 }
             }
         }
     }
     zones {
         security-zone IPV4 {
             interfaces {
                 ge-0/0/0.0 {
                     host-inbound-traffic {
                         system-services {
                             all;
                         }
                         protocols {
                             all;
                         }
                     }
                 }
             }
         }
         security-zone IPV6 {
             interfaces {
                 ge-0/0/1.0 {
                     host-inbound-traffic {
                         system-services {
                             all;
                         }
                         protocols {
                             all;
                         }
                     }
                 }
             }
         }
     }
 }
 interfaces {
     ge-0/0/0 {
         unit 0 {
             family inet {
                 address 192.168.100.1/24;
             }
         }
     }
     ge-0/0/1 {
         unit 0 {
             family inet6 {
                 address 2001:db8::1/64;
             }
         }
     }
 }