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.
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.