ccie blog

Juniper SRX NAT Configuration Examples

In this section I will demonstrate various NAT configurations that would typically be used in a production environment.  The topology I’ll be working with is shown below.

SRX-NAT-BASE-TOPOLOGY

Current Configuration

Each of the three routers have a default route that point towards the SRX. And the SRX has been configured with a security policy that essentially performs the following:

  • Trust zone is permitted to any zone
  • DMZ is only permitted to the untrust zone
  • Untrust is not permitted anywhere

The configuration below shows the existing security policy I have pre-configured.

root# show security policies
from-zone trust to-zone trust {
    policy default-permit {
        match {
            source-address any;
            destination-address any;
            application any;
        }
        then {
            permit;
        }
    }
}
from-zone trust to-zone untrust {
    policy default-permit {
        match {
            source-address any;
            destination-address any;
            application any;
        }
        then {
            permit;
        }
    }
}
from-zone untrust to-zone trust {
    policy default-deny {
        match {
            source-address any;
            destination-address any;
            application any;
        }
        then {
            deny;
        }
    }
}
from-zone trust to-zone DMZ {
    policy permit-trust {
        match {
            source-address any;
            destination-address any;
            application any;
        }
        then {
            permit;
        }
    }
}
from-zone DMZ to-zone untrust {
    policy DMZ-UNTRUST {
        match {
            source-address any;
            destination-address any;
            application any;
        }
        then {
            permit;
        }
    }
}

 

NAT Overload

The trust zone subnet 192.168.0.0/24 will be configured to use NAT overload when sending traffic to the internet (i.e. the untrust zone).  This will be a basic source NAT using the interface IP of the untrust zone.

root# edit security nat source
 set rule-set TRUST-TO-UNTRUST from zone trust
 set rule-set TRUST-TO-UNTRUST to zone untrust
 set rule-set TRUST-TO-UNTRUST rule TRUST-TO-INTERNET match source-address 192.168.0.0/24
 set rule-set TRUST-TO-UNTRUST rule TRUST-TO-INTERNET match destination-address 0.0.0.0/0
 set rule-set TRUST-TO-UNTRUST rule TRUST-TO-INTERNET then source-nat interface
commit

As our existing security policy permits access from the trust zone to the untrust zone, this configuration is complete. There are a few ways to verify the configuration. I can ping from R1 (trust zone) to R3 (untrust zone).  What we should see, if I enable #debug ip icmp on R3, is that R3 now sends echo replies to 30.0.0.254 instead of the original source IP 192.168.0.1.

R1#ping 30.0.0.1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 30.0.0.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 44/58/64 ms


R3#
*Apr 18 22:17:38.071: ICMP: echo reply sent, src 30.0.0.1, dst 30.0.0.254
*Apr 18 22:17:38.135: ICMP: echo reply sent, src 30.0.0.1, dst 30.0.0.254
*Apr 18 22:17:38.195: ICMP: echo reply sent, src 30.0.0.1, dst 30.0.0.254
*Apr 18 22:17:38.255: ICMP: echo reply sent, src 30.0.0.1, dst 30.0.0.254
*Apr 18 22:17:38.327: ICMP: echo reply sent, src 30.0.0.1, dst 30.0.0.254

Secondly, you can view the nat sessions by using the command below (right after you send the pings from R1 to R3).

root# run show security flow session nat source-prefix 192.168.0.0/24
Session ID: 172, Policy name: default-permit/5, Timeout: 4, Valid
  In: 192.168.0.1/0 --> 30.0.0.1/25;icmp, If: ge-0/0/1.0, Pkts: 1, Bytes: 100
  Out: 30.0.0.1/25 --> 30.0.0.254/13183;icmp, If: ge-0/0/3.0, Pkts: 1, Bytes: 100

Essentially, the SRX output shows two flows for NAT. The “In flow”, which is how the packet is structured as the flow comes from the trust zone to the untrust zone. Then the “Out” flow, which is how the return flow looks. So to read the output, you basically need to read the two lines as two seperate flows. The highlighted IP addresses just help identify the translation.

Static NAT

In this example, I want a one-to-one NAT configuration so that 172.16.0.1 appears as 1.1.1.1 to the untrust zone (i.e. internet).

SRX-STATIC-NAT

The configuration to achieve this static NAT rule has been provided below.  As a FYI, the interface connecting to R2 is ge-0/0/2.0.  Likewise, ge-0/0/3.0 connects to R3.

edit security nat
 set static rule-set STATIC_NAT_FOR_DMZ from zone untrust
 set static rule-set STATIC_NAT_FOR_DMZ rule SERVER1 match destination-address 1.1.1.1/32
 set static rule-set STATIC_NAT_FOR_DMZ rule SERVER1 then static-nat prefix 172.16.0.1/32
 set proxy-arp interface ge-0/0/3.0 address 1.1.1.1/32
commit

I find that the easiest way to write the rule, is just imagine as though you are on the internet, and trying to send a packet towards the DMZ server. So your destination would be the public IP, then you’d want to NAT that to the internal IP.

To test the configuration, I’ve left the #debug ip icmp command on R3 from earlier, and I’ll send some ICMP traffic from R2 to R3.  What we should see, is that when R3 replies to the ping, the destination address is now 1.1.1.1 instead of 172.16.0.1.

R2#ping 30.0.0.1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 30.0.0.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 60/60/64 ms

R3#
*Apr 19 06:58:49.301: ICMP: echo reply sent, src 30.0.0.1, dst 1.1.1.1
*Apr 19 06:58:49.361: ICMP: echo reply sent, src 30.0.0.1, dst 1.1.1.1
*Apr 19 06:58:49.425: ICMP: echo reply sent, src 30.0.0.1, dst 1.1.1.1
*Apr 19 06:58:49.489: ICMP: echo reply sent, src 30.0.0.1, dst 1.1.1.1
*Apr 19 06:58:49.549: ICMP: echo reply sent, src 30.0.0.1, dst 1.1.1.1

Additionally, as before, you can also view the NAT sessions on the SRX itself by using the command below:

root# run show security flow session nat
Session ID: 231, Policy name: DMZ-UNTRUST/8, Timeout: 2, Valid
  In: 172.16.0.1/0 --> 30.0.0.1/17;icmp, If: ge-0/0/2.0, Pkts: 1, Bytes: 100
  Out: 30.0.0.1/17 --> 1.1.1.1/0;icmp, If: ge-0/0/3.0, Pkts: 1, Bytes: 100

In a production environment, you typically use this setup to enable a service on the internet. So let’s say you R2 is running a HTTP server on the public internet. I would need to allow HTTP connections from the internet to R2. The configuration to achieve this is shown below.

set security address-book global address R2 172.16.0.1/32

edit security policies from-zone untrust to-zone DMZ
 set policy UNTRUST-TO-DMZ match source-address any
 set policy UNTRUST-TO-DMZ match destination-address R2
 set policy UNTRUST-TO-DMZ match application junos-http
 set policy UNTRUST-TO-DMZ then permit
commit

Note: The security policy works the same as it does on the ASA using code 8.4 or above. So when permitting access from the web to an internal host, you create the policy as being destined to the post-NAT IP address.

To verify the config, a simple test using Telnet from R3 to R2 on port 80 will suffice:

R3#telnet 1.1.1.1 80
Trying 1.1.1.1, 80 ... Open

And finally, a check on the nat flow information on the SRX.

root# run show security flow session destination-port 80
Session ID: 288, Policy name: UNTRUST-TO-DMZ/9, Timeout: 278, Valid
  In: 30.0.0.1/16812 --> 1.1.1.1/80;tcp, If: ge-0/0/3.0, Pkts: 4, Bytes: 164
  Out: 172.16.0.1/80 --> 30.0.0.1/16812;tcp, If: ge-0/0/2.0, Pkts: 2, Bytes: 84
Total sessions: 1

Leave a comment

Your comment