Description
This article describes how a VIP's external IP address can be used to perform Source NAT (SNAT) when Central NAT is disabled. The use of Virtual IP addresses is usually done to map external (public) to internal (private) IP addresses for Destination NAT (DNAT).
Scope
FortiGate.
Solution
Topology:
HOST <-----> FGT <–----> Internet
SNAT with VIP and Central-NAT disabled:
CLI configuration:
- Create a Firewall Policy to allow Internet access for the HOST. Enable SNAT on this firewall policy.
config firewall policy
edit 1
set srcintf "lan"
set dstintf "wan"
set srcaddr "HOST"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
set nat enable
next
end
- The VIP entry must be referenced in at least one firewall policy in order to use VIP's external IP for performing SNAT.
config firewall policy
edit 2
set name "activate vip"
set srcintf "wan"
set dstintf "lan"
set srcaddr "none"
set dstaddr "VIP"
set action accept
set schedule "none"
set service "NONE"
set logtraffic disable
set comments "Used only to activate Source NAT for HOST"
next
end
config firewall vip
edit "VIP"
set extip 20.1.2.3
set mappedip "10.185.3.199"
set extintf "wan" <-- For SNAT to be matched, extintf must be 'any' or same as firewall policy dstintf
set nat-source-vip enable
next
end
config firewall address
edit "HOST"
set subnet 10.185.3.199 255.255.255.255
next
end
Note:
- In this example, firewall policy #2 activates the VIP so that its external IP address can be used to perform SNAT when the HOST generates traffic towards the Internet. If no firewall policy is configured using the VIP, it will not be checked for SNAT.
- Internet Traffic from the HOST will be allowed by firewall policy #1 for SNAT with the VIP's external IP address.
The priority of which external IP is selected for SNAT is as follows:
- External IP of the matching VIP if nat-source-vip enabled; otherwise
- ippool specified in the policy (LAN to WAN policy).
- Reverse SNAT according to the VIP if nat-source-vip is disabled.
- IP of the outgoing interface.
Important notes:
- When port-forwarding is disabled on the VIP and Source NAT with Outgoing Interface Address is enabled on Firewall Policy#1, irrespective of the 'nat-source-vip' setting, traffic matching firewall policy #1 will be Source NATtedd with the VIP's external IP address instead of the outgoing physical interface IP address.
Debug log verification:
id=20085 trace_id=1125 func=fw_forward_handler line=749 msg="Allowed by Policy-1: SNAT"
id=20085 trace_id=1125 func=__ip_session_run_tuple line=3226 msg="SNAT 10.185.3.199->20.1.2.3:65324"
Sniffer result:
16.430250 lan in 10.185.3.199 -> 8.8.8.8: icmp: echo request
16.430348 wan out 20.1.2.3 -> 8.8.8.8: icmp: echo request
- When port-forwarding is disabled on the VIP and Source NAT with IP Pool is enabled on Firewall Policy#1, the 'set nat-source-vip enable must be enabled on the VIP configuration in order for FortiGate to perform SNAT using VIP's external IP address instead of the IP Pool in the policy.
- When port-forwarding is enabled on the VIP, the 'nat-source-vip' setting must be enabled and VIP's external IP will be used for SNAT only when the source port of the HOST-generated traffic falls in the port range configured for VIP.
- VIP only checked if outgoing interface included in the extintf setting. If extintf references a specific interface, the VIP will only be checked for Source NAT for traffic going out over that interface. For most environments, it is recommended to specify an extintf. Configuring a VIP with extintf 'any' is frequently a misconfiguration that can cause unintended Source NAT.
Port Forwarding Example 1:
When a port-forwarding VIP is created to translate TCP port 80 to 80 and if the HOST is generating TCP traffic with a dynamic source port, then the SNAT will be performed using outgoing interface IP and not the VIP external IP.
[10.185.3.199:62189->8.8.8.8:80] - SNAT will be performed with outgoing Interface IP.
Example 2:
When a port-forwarding VIP is created to translate all TCP ports 1-65535 to 1-65535, any TCP traffic from the HOST will have Source NAT applied using VIP's external IP address.
[10.185.3.199:62189->8.8.8.8:80] - SNAT will be performed with VIP's External IP.
Example 3:
When a port-forwarding VIP is created to translate all TCP ports 1-65535 to 1-65535, UDP traffic from the host will have Source NAT applied using outgoing interface IP address.
[10.185.3.199:62189->8.8.8.8:53] - SNAT will be performed with outgoing Interface IP.
Example 4:
When port-forwarding is enabled, SNAT with the VIP's external IP address will only be applied for traffic that has both a source IP matching the mappedip and a source port matching the mappedport.
In the following example, only traffic from IP address 10.101.5.12 with source port 8080 will have the VIP's external IP address applied. In that scenario, the source port is also be translated to match the configured extport.
config firewall vip
edit "VIP_NEW"
set extip 10.5.63.90
set mappedip "10.101.5.12"
set extintf "any"
set nat-source-vip enable
set portforward enable
set extport 80
set mappedport 8080
next
end
id=65308 trace_id=55 func=print_pkt_detail line=5857 msg="vd-root:0 received a packet(proto=6, 10.101.5.12:8080->8.8.8.8:443) tun_id=0.0.0.0 from port3. flag [S], seq 4119738715, ack 0, win 1480"
id=65308 trace_id=55 func=init_ip_session_common line=6043 msg="allocate a new session-0000c4b7, tun_id=0.0.0.0"
id=65308 trace_id=55 func=__vf_ip_route_input_rcu line=2001 msg="find a route: flag=00000000 gw-10.5.63.254 via port1"
id=65308 trace_id=55 func=__iprope_tree_check line=524 msg="gnum-100004, use int hash, slot=43, len=2"
id=65308 trace_id=55 func=get_new_addr line=1239 msg="find SNAT: IP-10.5.63.82(from IPPOOL), port-8080"
id=65308 trace_id=55 func=get_new_addr line=1239 msg="find DNAT: IP-10.5.63.90, port-80"
id=65308 trace_id=55 func=fw_forward_handler line=1000 msg="Allowed by Policy-2: SNAT"
id=65308 trace_id=55 func=ip_session_confirm_final line=3090 msg="npu_state=0x1100, hook=4"
id=65308 trace_id=55 func=ids_receive line=430 msg="send to ips"
id=65308 trace_id=55 func=__ip_session_run_tuple line=3432 msg="SNAT 10.101.5.12->10.5.63.90:80"
diagnose sniffer packet any "host 8.8.8.8 and port 443" 4 0 a
Using Original Sniffing Mode
interfaces=[any]
filters=[host 8.8.8.8 and port 443]
2024-08-22 06:49:50.463088 port3 in 10.101.5.12.8080 -> 8.8.8.8.443: syn 1288039825
2024-08-22 06:49:50.470739 port1 out 10.5.63.90.80 -> 8.8.8.8.443: syn 1288039825