Skip to main content
nvisentin_FTNT
Staff
Staff
October 12, 2015

Technical Tip: How to resolve SNAT issue with multiple VIP mapped to the same internal IP

  • September 22, 2026 at 7:20 AM
  • 0 replies
  • 25518 views

Description

This article describes the proper configuration with multiple VIP mapped to the same internal IP.  In this article, firewall policies are configured with source and destination interfaces set to 'any'.  Therefore, VIPs are configured with the external interface set to 'any'.  In such a context, the FortiGate may apply the wrong VIP for SNAT, resulting in connectivity issues.

The use of VIP addresses is usually done to map external (public) to internal (private) IP addresses for Destination NAT (DNAT).

VIP is also used for outbound traffic translation with a static one-to-one mapping from internal to external IP (SNAT).

Scope


FortiGate.


Solution

Diagram.

nvisentin_FD37406_tn_FD37406-1.jpg


Required behavior and potential issue.
Traffic toward the Internet: Associate the internal IP with the external IP of the VIP-172.31.17.238.

Traffic toward VM26: Associate a fixed mapping of the internal IP to the external IP of the VIP-1.1.1.0-24.


Source IP | Destination IP | Translated IP
172.30.30.2   Internet        172.31.17.238
172.30.30.2   160.0.0.0/8     1.1.1.2
172.30.30.3   160.0.0.0/8     1.1.1.3
(…)
172.30.30.254 160.0.0.0/8     1.1.1.254


In the case of misconfiguration, the following could occur:

FGT # get sys session list
PROTO   EXPIRE SOURCE           SOURCE-NAT       DESTINATION      DESTINATION-NAT
icmp    7      172.30.30.2:4238 1.1.1.2:4238     160.0.0.1:8 
icmp    59     172.30.30.2:4247 1.1.1.2:4247     8.8.8.8:8 


Traffic going to 160.0.0.1 is translated to 1.1.1.2 as expected.

Traffic going to the Internet (8.8.8.8) is also translated to 1.1.1.2, which is not expected and causes Internet connectivity issues.

Configuration (relevant parts).
VIP: srcintf-filter must be set to the proper external interface to prevent the issue.


config firewall vip
    edit "VIP-1.1.1.0-24"
        set uuid 51944978-6e67-51e5-8e57-a7ead026b0d2
        set extip 1.1.1.0-1.1.1.255
        set extintf "any"
        set srcintf-filter "port3"
        set mappedip "172.30.30.0-172.30.30.255"
    next
    edit "VIP-172.31.17.238"
        set uuid 7f8a86f8-6e67-51e5-e59b-a97f9ae1973c
        set extip 172.31.17.238
        set extintf "any"
        set srcintf-filter "port4"
        set mappedip "172.30.30.2"
    next
end


Firewall policies.

config firewall policy
    edit 6
        set uuid 063d0846-6b5d-51e5-8435-10c0987913cc
        set srcintf "any"
        set dstintf "any"
        set srcaddr "160.0.0.0-8"
        set dstaddr "VIP-1.1.1.0-24"
        set action accept
        set schedule "always"
        set service "ALL"
    next
    edit 5
        set uuid 3e27056a-6b47-51e5-9ba9-085cbfb0c040
        set srcintf "any"
        set dstintf "any"
        set srcaddr "172.30.30.0-24"
        set dstaddr "160.0.0.0-8"
        set action accept
        set schedule "always"
        set service "ALL"
        set nat enable
    next
    edit 7
        set uuid a16c054e-6e67-51e5-3bf4-19b25c3782be
        set srcintf "any"
        set dstintf "any"
        set srcaddr "all"
        set dstaddr "VIP-172.31.17.238"
        set action accept
        set schedule "always"
        set service "ALL"
    next
    edit 4
        set uuid 117535a0-6e67-51e5-7705-3cfb33050c2b
        set srcintf "any"
        set dstintf "any"
        set srcaddr "172.30.30.0-24"
        set dstaddr "all"
        set action accept
        set schedule "always"
        set service "ALL"
        set nat enable
    next
end


Verification.
The translation can be verified in the session table:


FGT # get sys session list
PROTO   EXPIRE SOURCE           SOURCE-NAT       DESTINATION      DESTINATION-NAT
icmp    59     172.30.30.2:4284 1.1.1.2:4284      160.0.0.1:8      -
icmp    45     172.30.30.2:4283 172.31.17.238:4283 8.8.8.8:8         -


Traffic going to 160.0.0.1 is translated with 1.1.1.2 as expected.

Traffic going to the Internet (8.8.8.8) is translated to 172.31.17.238 as expected.


As a complement to the behavior described here regarding multiple VIPs mapped to the same internal IP address, the scenario where the same FQDN destination is published through two or more active public A records, for example via Cloudflare or another DNS provider, should be considered. In the case when some clients may attempt simultaneous connections to more than one public IP address (located in the FortiGate) with the same FQDN. If these public IP addresses correspond to different VIPs on the FortiGate, but both point to the same internal server and the same service, parallel sessions can be generated across different WANs/VIPs to the same backend. Connection attempts to this service may result in TCP retransmissions and 'no session matched' messages, because they are parallel sessions to the same internal server under 2 different IPs on the same associated FQDN.


Therefore, DNS round-robin should not be considered equivalent to a high availability or active-active load balancing mechanism. For this scenario, it is recommended to use DNS failover with health checks, so that only one public IP address is active for the FQDN and the second is used only in case of failure. As an alternative mitigation, if both VIPs remain active, consider mapping each VIP to a different internal IP address.


2026-06-05 09:24:22 id=65308 trace_id=17403 func=print_pkt_detail line=5813 msg="vd-root:0 received a packet(proto=6, 10.10.10.177:59871->10.85.161.140:443) tun_id=0.0.0.0 from wan2. flag [S], seq 3149212316, ack 0, win 65535"
2026-06-05 09:24:22 id=65308 trace_id=17403 func=init_ip_session_common line=5997 msg="allocate a new session-2793a262"
2026-06-05 09:24:22 id=65308 trace_id=17403 func=get_new_addr line=1205 msg="find DNAT: IP-192.168.199.231, port-443"
2026-06-05 09:24:22 id=65308 trace_id=17403 func=fw_pre_route_handler line=180 msg="VIP-192.168.199.231:443, outdev-wan2"
2026-06-05 09:24:22 id=65308 trace_id=17403 func=__ip_session_run_tuple line=3413 msg="DNAT 10.85.161.140:443->192.168.199.231:443"
2026-06-05 09:24:22 id=65308 trace_id=17403 func=vf_ip_route_input_common line=2611 msg="find a route: flag=00000000 gw-192.168.199.231 via REDE - DMZ"
2026-06-05 09:24:22 id=65308 trace_id=17403 func=__iprope_tree_check line=539 msg="gnum-100004, use addr/intf hash, len=37"
2026-06-05 09:24:22 id=65308 trace_id=17403 func=get_new_addr line=1205 msg="find SNAT: IP-192.168.199.254(from IPPOOL), port-59871"
2026-06-05 09:24:22 id=65308 trace_id=17403 func=fw_forward_handler line=980 msg="Allowed by Policy-140: SNAT"
2026-06-05 09:24:22 id=65308 trace_id=17403 func=__ip_session_run_tuple line=3400 msg="SNAT 10.10.10.177->192.168.199.254:59871"
2026-06-05 09:24:22 id=65308 trace_id=17404 func=print_pkt_detail line=5813 msg="vd-root:0 received a packet(proto=6, 10.10.10.177:59869->10.90.56.18:443) tun_id=0.0.0.0 from wan1. flag [.], seq 1301758700, ack 434166267, win 64"
2026-06-05 09:24:22 id=65308 trace_id=17404 func=vf_ip_route_input_common line=2611 msg="find a route: flag=80000000 gw-10.90.56.18 via root"
2026-06-05 09:24:22 id=65308 trace_id=17404 func=ip_session_core_in line=6521 msg="no session matched"


Related article:

Technical Tip: Using VIP range for SNAT and static 1-to-1 mapping from internal to external IP addresses

Thought Leadership. Security Summit. Thursday, November 12th, PGA National Resort, Palm Beach Gardens, FL.
Security Operations Summit: Modernize SecOps. Operate AI-Native.AMER: November 4 | 9:00 AM PST. India and SAARC: November 5 | 10:00 AM IST. EMEA: November 5 | 10:30 AM CET. APAC: November 5 | 11:00 AM SGT