How to: Junos IPv6 to IPv4 NAT

By on 13 May 2019

Category: Tech matters

Tags: , , , ,

Blog home

While studying for my JNCIE-SEC lab there was a topic that I 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 with this post is to put it in a format to help you understand how to configure it on a Juniper SRX device.

Note: This lab used vSRX on EVE-NG but you might like to also use the APNIC Academy Juniper Full Mesh Router (Sandbox) Lab to carry out the configuration.

Before I get started with 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 and 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;
         }
     }
 }

Figure 1 shows the lab topology. In the BLUE box on the left, we have the 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, l 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 I call this security zone IPv6.


Figure 1 — Lab topology. Security zone IPv4 is on the left and security zone IPv6 is on the right.

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 is used so that the IPv4 host can initiate traffic towards the IPv6 host via an IPv4 NAT address. In the same fashion, I 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 I use an IPv4 NAT address of 192.168.100.254. For the IPv6 host to generate traffic to the IPv4 host, I use an IPv6 NAT of 2001:db8::254. This will make a bit more sense once we perform the configuration.

Ok, a 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

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

In the configuration snippet below I 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 I have a way to translate traffic between the networks, I 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 I do is configure two destination NAT pools — one pool for each of the hosts I want to talk to. To keep it simple I 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 I will translate the 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;
 }

I will start with the IPv4 to IPv6 destination NAT configuration. Here you can see I am specifying the source zone of IPv4 and matching the destination address of 192.168.100.254 (NAT). I am 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 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 I am missing a few commands. In order to see what is wrong, I will look at my 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, I don’t 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 I 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 I have that configured, I 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 I 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 my NAT rules for this traffic to see if they are actually being matched. To do this I 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 I 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 I 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 I can look at the IPv6 NAT policies that are used for this traffic. Again I 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. Check out the links below if you would like to download the configs 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

Adapted from original post, which appeared on Fryguy.net

Jeffrey Fry is a Senior Consultant at Dimension Data.

Rate this article

The views expressed by the authors of this blog are their own and do not necessarily reflect the views of APNIC. Please note a Code of Conduct applies to this blog.

Leave a Reply

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

Top