| Solution |
It is necessary to create 2 Objects and 2 Firewall rules.
(Note: While this example uses the Virtual Server IP type, it also applies to other common types such as HTTP or HTTPS.)
Why 2 objects and 2 firewall rules are required:
When the VIP and real servers are on the same subnet, the FortiGate must separate two distinct traffic flows, being:
- The traffic that is destined to the VIP (i.e. DNAT / load balancing).
- The traffic originating from the real servers (i.e. normal outbound sessions).
Because the VIP and the real servers reside in the same Layer-2 broadcast domain, the FortiGate must explicitly:
-
Control the inbound (NAT) path.
-
Control the outbound return path.
-
Maintain a symmetric session.
Having two policies ensures:
-
the correct Destination NAT handling for the client access to the server
-
the proper Source NAT (and routing) for the server's normal outbound traffic
-
that asymmetric routing never happens.
-
normal Internet connectivity for the real servers.
Objects.
Create a VIP object.
- Go to Policy & Objects -> Virtual Servers and select 'Create New'.
- Type: IP
- Interface: port6
- Load balancing: Not relevant
- Real servers: 192.168.5.50
Create a new address for the VIP IP.
- Go to Policy & Objects -> Addresses and select 'Create new' (Address).
Firewall Rules:
Create a 1st rule:
- From the 'interface wished from the client networks' and destination port of VIP network.
- Source 'Networks from client networks or All' and destination a normal IP address with the same IP as the VIP.
Create a 2nd rule:
- From and to the same interface
- Source 'All' and destination 'the VIP'.
Caution for Firewall rules: as this virtual server (see Technical Tip: Configure a virtual server) is for the same internal network, make sure that NAT is not enabled on the Firewall policies.

Alternative CLI:
VIP:
config firewall vip edit "VIP_192.168.5.100" set type server-load-balance set extip 192.168.5.100 set extintf "port6" set server-type ip set monitor "ping" set ldb-method weighted
config realservers edit 1 set ip 192.168.5.50 next end next end
Address:
config firewall address edit "IP_192.168.5.100" set uuid 74601658-23b9-51ed-458d-970e043d9a63 set subnet 192.168.5.100 255.255.255.255 next end
Relevant Policy:
config firewall policy edit 14 set name "Allow from other to VIP IP" set srcintf "port3" set dstintf "port6" set action accept set srcaddr "Vlan_14_10.191.80.0/20" set dstaddr "IP_192.168.5.100" set schedule "always" set service "ALL" set logtraffic all next edit 15 set name "Allow vip in same network" set srcintf "port6" set dstintf "port6" set action accept set srcaddr "all" set dstaddr "VIP_192.168.5.100" set schedule "always" set service "ALL" set logtraffic all next end
Result:
Ping from PC in port3.
id=65308 trace_id=131 func=print_pkt_detail line=5895 msg="vd-root:0 received a packet(proto=1, 10.191.84.239:1->192.168.5.100:2048) tun_id=0.0.0.0 from port3. type=8, code=0, id=1, seq=17." id=65308 trace_id=131 func=init_ip_session_common line=6076 msg="allocate a new session-015ea045, tun_id=0.0.0.0" id=65308 trace_id=131 func=iprope_dnat_check line=5331 msg="in-[port3], out-[]" id=65308 trace_id=131 func=iprope_dnat_tree_check line=823 msg="len=1" id=65308 trace_id=131 func=__iprope_check_one_dnat_policy line=5191 msg="checking gnum-100000 policy-3" id=65308 trace_id=131 func=__iprope_check_one_dnat_policy line=5240 msg="match vip-VIP_192.168.5.100, naddr=192.168.5.50, nport=0" id=65308 trace_id=131 func=__iprope_check_one_dnat_policy line=5286 msg="matched policy-3, act=accept, vip=3, flag=104, sflag=2000000" id=65308 trace_id=131 func=iprope_dnat_check line=5343 msg="result: skb_flags-02000000, vid-3, ret-matched, act-accept, flag-00000104" id=65308 trace_id=131 func=iprope_fwd_check line=789 msg="in-[port3], out-[port6], skb_flags-02000000, vid-3, app_id: 0, url_cat_id: 0" id=65308 trace_id=131 func=__iprope_tree_check line=557 msg="gnum-100004, use addr/intf hash, len=2" id=65308 trace_id=131 func=__iprope_check_one_policy line=2044 msg="checked gnum-100004 policy-14, ret-matched, act-accept" id=65308 trace_id=131 func=__iprope_user_identity_check line=1819 msg="ret-matched" id=65308 trace_id=131 func=__iprope_check_one_policy line=2262 msg="policy-14 is matched, act-accept" id=65308 trace_id=131 func=iprope_fwd_check line=826 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-14" id=65308 trace_id=131 func=iprope_fwd_auth_check line=845 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-14" id=65308 trace_id=131 func=fw_pre_route_handler line=178 msg="VIP-192.168.5.50:1, outdev-unknown" id=65308 trace_id=131 func=__ip_session_run_tuple line=3515 msg="DNAT 192.168.5.100:8->192.168.5.50:1" id=65308 trace_id=131 func=vf_ip_route_input_common line=2605 msg="find a route: flag=04000000 gw-192.168.5.50 via port6" id=65308 trace_id=131 func=iprope_fwd_check line=789 msg="in-[port6], out-[port6], skb_flags-020000c0, vid-3, app_id: 0, url_cat_id: 0" id=65308 trace_id=131 func=__iprope_tree_check line=557 msg="gnum-100004, use addr/intf hash, len=5" id=65308 trace_id=131 func=__iprope_check_one_policy line=2044 msg="checked gnum-100004 policy-15, ret-matched, act-accept" id=65308 trace_id=131 func=__iprope_user_identity_check line=1819 msg="ret-matched" id=65308 trace_id=131 func=__iprope_check_one_policy line=2262 msg="policy-15 is matched, act-accept" id=65308 trace_id=131 func=iprope_fwd_check line=826 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-15" id=65308 trace_id=131 func=iprope_fwd_auth_check line=845 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-15" id=65308 trace_id=131 func=iprope_shaping_check line=935 msg="in-[port6], out-[port6], skb_flags-020000c0, vid-3" id=65308 trace_id=131 func=__iprope_check line=2292 msg="gnum-100015, check-ffffffffa002b224" id=65308 trace_id=131 func=__iprope_check_one_policy line=2044 msg="checked gnum-100015 policy-1, ret-no-match, act-accept" id=65308 trace_id=131 func=__iprope_check_one_policy line=2044 msg="checked gnum-100015 policy-2, ret-no-match, act-accept" id=65308 trace_id=131 func=__iprope_check line=2309 msg="gnum-100015 check result: ret-no-match, act-accept, flag-00000000, flag2-00000000" id=65308 trace_id=131 func=iprope_policy_group_check line=4752 msg="after check: ret-no-match, act-accept, flag-00000000, flag2-00000000" id=65308 trace_id=131 func=fw_forward_handler line=903 msg="Allowed by Policy-15:"
Related document:
Virtual server load balance - Administration Guide 7.6
|