Junos Security – Source NAT address shifting Alan Gravett

Version: 12.1X44-D10.4-domestic

I am describing the source NAT address shifting behaviour on SRX device that I experienced when I recently played with it a bit. In source NAT translation the address allocation from the pool is done sequentially for incomming requests regardless of the original source address, i.e. the address selection is performed by the device. The source NAT address shifting offers to influence this selection by configuring a fixed mapping between the „pre-translation“ and „post-translation“ addresses. The mapping is based on the „host-address-base“ parameter that defines which pre-translation address will be always translated to the first address from the pool. The increment of the „host-address-base“ IP address will translated to the second address from the pool, the the next increment address to the third address and so on, until the highest address from the pool is reached.

For example lets assume following source NAT configuration:

[edit security]
lab@SRX1# show nat
source {
    pool A {
        address {
            2.2.2.2/32 to 2.2.2.6/32;
        }
        host-address-base 1.1.1.3/32;
    }
    rule-set TEST {
        from zone trust;
        to zone unstrust;
        rule srcNAT-shift {
            match {
                source-address 1.1.1.0/24;
            }
            then {
                source-nat {
                    pool {
                        A;
                    }
                }
            }
        }
    }
}

The translation mapping is:
1.1.1.3 –> 2.2.2.2
1.1.1.4 –> 2.2.2.3
1.1.1.5 –> 2.2.2.4
1.1.1.6 –> 2.2.2.5
1.1.1.7 –> 2.2.2.6

The security policies are configured to allow traffic to test the translation.

The translation occurs for the addresses above 1.1.1.3 – 1.1.1.7. Below is an example for the session from the host 1.1.1.3.

1.1.1.3/0->5.5.5.5/24838

Session ID: 200, Policy name: default-permit/4, Timeout: 60, Valid
  In: 1.1.1.3/2 --> 5.5.5.5/25094;icmp, If: ge-0/0/1.0, Pkts: 1, Bytes: 84
  Out: 5.5.5.5/25094 --> 2.2.2.2/2;icmp, If: ge-0/0/0.0, Pkts: 0, Bytes: 0
Total sessions: 5

However when a request comes from the 1.1.1.2 host the packet is dropped even though the security policies allow the connection and the conditions in the rule and rule-set are met. The reason is the device cannot allocate an address for the connection because the translation mappings are fixed and starts with the address 1.1.1.3.

...
Dec 11 09:22:36 09:22:35.1676574:CID-0:RT: find flow: table 0x552d6ca8, hash 5856(0xffff), sa 1.1.1.2, da 5.5.5.5, sp 0, dp 14598, proto 1, tok 6
Dec 11 09:22:36 09:22:35.1676574:CID-0:RT:  no session found, start first path. in_tunnel - 0x0, from_cp_flag - 0
Dec 11 09:22:36 09:22:35.1676574:CID-0:RT:  flow_first_create_session
...
Dec 11 09:22:36 09:22:35.1676574:CID-0:RT:  permitted by policy default-permit(4)
Dec 11 09:22:36 09:22:35.1676574:CID-0:RT:  packet passed, Permitted by policy.
Dec 11 09:22:36 09:22:35.1676574:CID-0:RT:flow_first_src_xlate:  nat_src_xlated: False, nat_src_xlate_failed: False
Dec 11 09:22:36 09:22:35.1676574:CID-0:RT:flow_first_src_xlate: src nat returns status: 1, rule/pool id: 1/4, pst_nat: False.
Dec 11 09:22:36 09:22:35.1676574:CID-0:RT:  dip alloc failed. dip_id = 0/0
Dec 11 09:22:36 09:22:35.1676574:CID-0:RT:  packet dropped, dip alloc failed
Dec 11 09:22:36 09:22:35.1676574:CID-0:RT:  flow find session returns error.

The same happens for connections from the 1.1.1.1 host and for hosts 1.1.1.8 and above.

The example configuration below is very similar to the previous one. The only difference is the match condition in the rule – 1.1.1.4/30 instead of the previous 1.1.1.0/24.

[edit security]
lab@SRX1# show nat
source {
    pool A {
        address {
            2.2.2.2/32 to 2.2.2.6/32;
        }
        host-address-base 1.1.1.3/32;
    }
    rule-set TEST {
        from zone trust;
        to zone unstrust;
        rule srcNAT-shift {
            match {
                source-address 1.1.1.4/30;
            }
            then {
                source-nat {
                    pool {
                        A;
                    }
                }
            }
        }
    }
}

The pool configuration did not change and the address mappings listed previously remain. The changed match condition causes only addresses 1.1.1.4 – 1.1.1.7 being translated. The address 1.1.1.3 goes through without modification even though the pool contains it, because it does not match the condition in the rule. This leaves the 2.2.2.2 address unused.

Session ID: 263, Policy name: default-permit/4, Timeout: 8, Valid
  In: 1.1.1.3/58 --> 5.5.5.5/25094;icmp, If: ge-0/0/1.0, Pkts: 1, Bytes: 84
  Out: 5.5.5.5/25094 --> 1.1.1.3/58;icmp, If: ge-0/0/0.0, Pkts: 0, Bytes: 0

The source NAT address shifting is a suitable option for situations where the address translation needs to be performed based on fixed relationship between pre- and post-translation addresses. The rule match conditions should be defined cautiously to avoid overinclusive criteria that would result in packet drop. Of course security policies need to have appropriate and correct criteria as well.

Written by Alan Gravett on

Leave a comment