Forward a Port to an Internal Server (VIP / DNAT)¶
When someone on the internet needs to reach a server inside your network — a web server, a remote desktop gateway, a VoIP PBX — you set up port forwarding, also called DNAT (Destination NAT). On FortiGate this is done via a VIP (Virtual IP) object plus a firewall policy that references it.
This is the OTHER thing people often mean when they say "IP forwarding." See also Enable IP Forwarding Between Interfaces for the routing meaning.
How It Works¶
- External request hits the FortiGate on a public IP + port.
- The VIP says "anything to public-IP:443 should be sent to internal-IP:443."
- A firewall policy says "WAN can reach
on HTTPS — allow." - FortiGate rewrites the destination and forwards the packet.
- The internal server replies; FortiGate rewrites its source back to the public IP.
Without BOTH the VIP and the firewall policy, port forwarding doesn't work. This is the #1 mistake.
Before You Start¶
- The internal server is up and reachable from the FortiGate (test with a ping from FortiGate CLI).
- You know the public IP that will receive the request (often the WAN interface IP, but can be an additional public IP if you have a block).
- You know the external port and the internal port (often the same; sometimes different to obscure the service).
- A firewall policy permitting WAN → DMZ/LAN to the service.
Steps¶
1. Create the VIP¶
- Policy & Objects → Virtual IPs → + Create New → Virtual IP.
- Fill in:
- VIP type —
IPv4. - Name — e.g.
VIP-WebServer-HTTPS. - Comments — optional notes.
- Color — optional.
- Network → Interface —
any(default) or a specific WAN interface. - External IP Address/Range — the public IP that external requests will hit. e.g.
203.0.113.10. Use the WAN IP itself, or a secondary IP on the WAN, or a public IP routed to you. - Mapped IP Address/Range — the internal IP of the server. e.g.
10.0.0.10. - Optional Filters — restrict by source address (only specific external IPs can use this VIP).
- Port Forwarding — toggle ON.
- Protocol —
TCPtypical (alsoUDP,SCTP,ICMP). - External Service Port — the public port, e.g.
443. - Map to IPv4 Port — the internal port, e.g.
443(or8443if you're remapping).
- Protocol —
- VIP type —
- Click OK.
2. Create the firewall policy¶
- Policy & Objects → Firewall Policy → + Create New.
- Fill in:
- Name — e.g.
Allow-WAN-to-WebServer. - Incoming Interface —
wan1. - Outgoing Interface — the interface where the server lives (e.g.
dmzorinternal). - Source —
all(public access) or a restricted set if needed. - Destination — pick your VIP object (
VIP-WebServer-HTTPS). - Service —
HTTPS(or whatever protocol matches the external port). - Action —
Accept. - NAT —
Disabled(the VIP handles the NAT; don't double-NAT). - Inspection Mode —
Flow-basedtypical. - Security Profiles — attach IPS at minimum on internet-exposed services.
- Logging Options —
All Sessionsrecommended for internet-facing.
- Name — e.g.
- OK.
3. Drag the policy above any broader deny rules.¶
CLI Equivalent¶
config firewall vip
edit "VIP-WebServer-HTTPS"
set extip 203.0.113.10
set mappedip "10.0.0.10"
set extintf "any"
set portforward enable
set protocol tcp
set extport 443
set mappedport 443
next
end
config firewall policy
edit 0
set name "Allow-WAN-to-WebServer"
set srcintf "wan1"
set dstintf "dmz"
set srcaddr "all"
set dstaddr "VIP-WebServer-HTTPS"
set service "HTTPS"
set action accept
set schedule "always"
set logtraffic all
next
end
Verify¶
From an external network (a cell phone on LTE, or a different ISP):
curl -kI https://203.0.113.10
# Should connect.
# Or with telnet to check the port:
telnet 203.0.113.10 443
On the FortiGate, check the VIP and session:
get firewall vip
diagnose sys session filter dport 443
diagnose sys session list
# Look for sessions matching the VIP — the "natdst" should show the internal IP.
VIP with Multiple Ports¶
If a server uses several ports (e.g. web + RDP), create one VIP per port, OR use a VIP group referenced in a single firewall policy:
config firewall vip
edit "VIP-Server-HTTPS"
set extip 203.0.113.10
set mappedip 10.0.0.10
set portforward enable
set protocol tcp
set extport 443
set mappedport 443
next
edit "VIP-Server-RDP"
set extip 203.0.113.10
set mappedip 10.0.0.10
set portforward enable
set protocol tcp
set extport 3389
set mappedport 3389
next
end
config firewall vipgrp
edit "VIPGRP-Server"
set member "VIP-Server-HTTPS" "VIP-Server-RDP"
next
end
Common Issues¶
- Connection refused / timeout from outside. Most common: missing firewall policy. The VIP alone does nothing without a policy that references it.
- Hits the FortiGate but never the server. VIP's mapped IP is wrong, or server is down. From FortiGate CLI:
execute ping <mapped-ip>— must succeed. - Server gets the connection but client sees connection reset. Asymmetric routing — the server's reply goes out a different gateway, bypassing FortiGate. Make sure server's default gateway is the FortiGate.
- External port already in use by FortiGate itself. E.g. you forward TCP/443 but FortiGate's admin GUI is also on 443. Move admin GUI to a different port (System → Settings → Administration Settings) OR pick a different external port for the VIP.
- NAT toggled on the firewall policy AND the VIP exists. Don't enable NAT on the policy when the destination is a VIP — the VIP already handles NAT. Double-NAT breaks return traffic.
- VIP works internally but not from outside. Public IP isn't actually routed to your FortiGate. Verify with your ISP.