Static or destination NAT is not working in filter based forwarding or source-based routing scenarios.
User has two ISPs: ISP-1 and ISP-2 connected to SRX on ge-0/0/0 and ge-0/0/1 respectively. Both the ISPs are in the same zone untrust. A server (192.168.1.69) is connected on interface ge-0/0/2, for which there is a static (or destination) NAT configured on the device for all the packets coming from zone untrust. User wants to send all the packets from a server to ISP-1. The topology is as follows:
The configuration is as follows:
interfaces { ge-0/0/0 { description ISP-1 unit 0 { family inet { address 192.168.2.2/24; } } } ge-0/0/1 { description ISP-2 unit 0 { family inet { address 192.168.4.1/24; } } } ge-0/0/2 { unit 0 { family inet { filter { input fbf; } address 192.168.1.1/24; } } } } routing-options { static { route 0.0.0.0/0 next-hop 192.168.4.2; } } policy-options { policy-statement from-inet { term t1 { from { instance master; protocol direct; route-filter 192.168.2.0/24 exact; route-filter 192.168.1.0/24 exact; } then accept; } term t2 { then reject; } } } security { nat { static { rule-set from-untrust { from zone untrust; rule r1 { match { destination-address 192.168.3.69/32; } then { static-nat { prefix { 192.168.1.69/32; } } } } } } } zones { security-zone trust { host-inbound-traffic { system-services { all; } protocols { all; } } interfaces { ge-0/0/2.0; } } security-zone untrust { host-inbound-traffic { system-services { all; } protocols { all; } } interfaces { ge-0/0/0.0; ge-0/0/1.0; } } } } firewall { filter fbf { term t1 { from { source-address { 192.168.1.69/32; } } then { routing-instance fbf; } } term t2 { then accept; } } } routing-instances { fbf { instance-type forwarding; routing-options { static { route 0.0.0.0/0 next-hop 192.168.2.1; } instance-import from-inet; } } }
If we try to ping from our server 192.168.1.69 to Internet (say 192.168.5.1) we are able to ping successfully but ping from Internet (say 192.168.5.1) fails to 192.168.3.69 (public IP of 192.168.1.69). We want the ping from Internet to our server to succeed.
If we enable traceoptions on our device to see why the packet is getting dropped:
security { flow { traceoptions { file flowtrace; flag basic-datapath; flag packet-drops; packet-filter pf1 { protocol icmp; source-prefix 192.168.5.1/32; destination-prefix 192.168.3.69/32; } packet-filter pf2 { protocol icmp; source-prefix 192.168.1.69/32; destination-prefix 192.168.5.1/32; } } } }
On checking the log file we will find the following: Apr 23 23:12:30 23:12:29.969642:CID-0:RT: route lookup: dest-ip 192.168.5.1 orig ifp ge-0/0/0.0 output_ifp ge-0/0/1.0 orig-zone 7 out-zone 7 vsd 0 The above log entry means that though the packet came through ge-0/0/0 but reverse route lookup of the source i.e. 192.168.5.1 finds the output interface as ge-0/0/1 (If these interface were in different zones we would have seen a zone mismatch error). Also if we will check the session for the ping packets: xroot@220# run show security flow session protocol icmp Session ID: 10773, Policy name: default-policy-00/2, Timeout: 2, Valid In: 192.168.5.1/0 --> 192.168.3.69/3430;icmp, If: ge-0/0/1.0, Pkts: 1, Bytes: 84 Out: 192.168.1.69/3430 --> 192.168.5.1/0;icmp, If: ge-0/0/2.0, Pkts: 1, Bytes: 84 Total sessions: 1 You can see in the above session interface is ge-0/0/1.0 and not ge-0/0/0 through which packet actually came. This happens as reverse route lookup will only take place in the routing-instance of the interface at which the packet arrived. In this case that interface is ge-0/0/0 which is in default routing-instance and since in default routing-instance the default route is through ge-0/0/1 reverse route lookup results in that interface.
To correct change the routing-instance from type “forwarding” to “virtual-router” and put the interface ge-0/0/0 in that virtual-router so that the route lookup now takes place in the newly created routing-instance table in which the default route is through ISP-1 i.e. ge-0/0/0. Also we will have to create different zones now for the ISP-1 and ISP-2. New configuration will be as follows:
interfaces { ge-0/0/0 { description ISP-1; unit 0 { family inet { address 192.168.2.2/24; } } } ge-0/0/1 { description ISP-2; unit 0 { family inet { address 192.168.4.1/24; } } } ge-0/0/2 { unit 0 { family inet { inactive: filter { input fbf; } address 192.168.1.1/24; } } } } routing-options { static { route 0.0.0.0/0 next-hop 192.168.4.2; } } policy-options { policy-statement from-inet { term t1 { from { instance master; protocol direct; route-filter 192.168.2.0/24 exact; route-filter 192.168.1.0/24 exact; } then accept; } term t2 { then reject; } } } security { nat { static { rule-set from-untrust { from zone [ untrust-1 untrust-2 ]; rule r1 { match { destination-address 192.168.3.69/32; } then { static-nat { prefix { 192.168.1.69/32; } } } } } } } zones { security-zone trust { host-inbound-traffic { system-services { all; } protocols { all; } } interfaces { ge-0/0/2.0; } } security-zone untrust-2 { host-inbound-traffic { system-services { all; } protocols { all; } } interfaces { ge-0/0/1.0; } } security-zone untrust-1 { host-inbound-traffic { system-services { all; } protocols { all; } } interfaces { ge-0/0/0.0; } } } } firewall { filter fbf { term t1 { from { source-address { 192.168.1.69/32; } } then { routing-instance fbf; } } term t2 { then accept; } } } routing-instances { fbf { instance-type virtual-router; interface ge-0/0/0.0; routing-options { static { route 0.0.0.0/0 next-hop 192.168.2.1; } instance-import from-inet; } } }
Now if we will check the traceoptions the same log entry will now appear like this:
Apr 23 23:44:41 23:44:41.609788:CID-0:RT: route lookup: dest-ip 192.168.5.1 orig ifp ge-0/0/0.0 output_ifp ge-0/0/0.0 orig-zone 10 out-zone 10 vsd 0
You can see now both original and output interface are same.
Also if you check the session:
xroot@220# run show security flow session protocol icmp
Session ID: 12067, Policy name: default-policy-00/2, Timeout: 2, Valid
In: 192.168.5.1/0 –> 192.168.3.69/3454;icmp, If: ge-0/0/0.0, Pkts: 1, Bytes: 84
Out: 192.168.1.69/3454 –> 192.168.5.1/0;icmp, If: ge-0/0/2.0, Pkts: 1, Bytes: 84
Total sessions: 1
Now the interface is ge-0/0/0 instead of ge-0/0/1 as seen earlier.