Publishing internal applications to the Internet safely requires precise control over Destination Network Address Translation (DNAT) and firewall security rules. On FortiGate firewalls, DNAT and port forwarding are implemented using Virtual IPs (VIPs). A Virtual IP maps an external public IP address and port to an internal private IP address and port.

Understanding FortiGate VIP port forwarding is essential for network and security administrators who need to host web applications, email servers, or public services behind a firewall without exposing internal networks to unnecessary risk. This step-by-step technical guide covers the concepts, configuration, packet processing flow, and troubleshooting methods for Virtual IPs on FortiOS.

Real-Life Scenario

Acme Corporation hosts an internal documentation portal on a Linux web server located in its DMZ subnet. The server runs an HTTPS web service listening on standard port TCP 443 with private IP 10.0.10.50.

The company’s Internet Service Provider (ISP) assigned a public IPv4 block to the primary WAN interface (wan1). Acme Corp needs to publish this web server to external remote employees using a public documentation address (203.0.113.10) over standard HTTPS port 443.

To achieve this securely, you must configure a FortiGate Virtual IP to translate external incoming requests on 203.0.113.10:443 to 10.0.10.50:443, then create a matching firewall policy allowing ingress traffic from the WAN to the DMZ.

Lab Topology

The network topology below illustrates the physical and logical placement of the FortiGate firewall between the Internet host and the internal DMZ web server.

+-----------------------+              +-----------------------+              +-----------------------+
|    External Client    |              |   FortiGate Firewall  |              |    DMZ Web Server     |
|   (Internet User)     |              |     (FortiOS 7.x)     |              |   (HTTPS Portal)      |
|                       |              |                       |              |                       |
| IP: 198.51.100.25     |=============>| Interface: wan1       |=============>| Interface: dmz        |
| Target: 203.0.113.10  |  Public WAN  | VIP: 203.0.113.10     |  Internal    | IP: 10.0.10.50        |
| Port: TCP 443         |              | Mapped: 10.0.10.50    |  DMZ Subnet  | Port: TCP 443         |
+-----------------------+              +-----------------------+              +-----------------------+

Example Addressing and Objects

The following example values are used throughout this guide. In production environments, replace these placeholder values with your actual public IPs, internal subnets, and interface names.

Object / Parameter Example Value Description
External WAN Interface wan1 Public interface connected to the ISP router.
Internal DMZ Interface dmz Private interface connected to the DMZ switch segment.
Public Destination IP (External) 203.0.113.10 Public documentation IP address bound to the Virtual IP object.
Mapped Private IP (Internal) 10.0.10.50 Internal IP address of the Linux HTTPS server.
External Port / Services TCP 443 (HTTPS) Incoming service port requested by external clients.
Mapped Port TCP 443 (HTTPS) Destination port where the application server listens.
VIP Object Name VIP_DMZ_HTTPS_Server Name assigned to the FortiGate Virtual IP object.

Prerequisites

  • Routing: Upstream ISP routers must route destination traffic for 203.0.113.10 toward the FortiGate wan1 interface.
  • Interface Configuration: The dmz interface must be configured with a valid IP (e.g., 10.0.10.1/24) and reachability to host 10.0.10.50 must be verified.
  • Administrative Access: Read/Write access to the FortiGate GUI or CLI with system administrator privileges.
  • FortiOS Version Context: Menu options and syntax shown reflect standard FortiOS 7.0/7.2/7.4 behaviors. Minor menu names can vary across feature visibility settings and hardware models.

Step-by-Step GUI Configuration

Creating a published service using FortiGate VIP port forwarding in the graphical interface involves two primary steps: defining the Virtual IP object and creating the firewall policy that permits traffic through it.

Step 1: Create the Virtual IP (VIP) Object

  1. Log into the FortiGate GUI.
  2. Navigate to Policy & Objects > Virtual IPs.
  3. Click Create New and select Virtual IP.
  4. Configure the VIP properties as follows:
    • Name: Enter VIP_DMZ_HTTPS_Server.
    • Interface: Select wan1 (or any if traffic arrives across multiple WAN connections).
    • Type: Select Static NAT.
    • External IP Address/Range: Enter 203.0.113.10.
    • Map to IPv4 Address/Range: Enter 10.0.10.50.
  5. Enable the Port Forwarding toggle button.
    • Protocol: Select TCP.
    • Status: Enable service port mapping.
    • External Service Port: Enter 443 to 443.
    • Map to Port: Enter 443 to 443.
  6. Click OK to save the Virtual IP configuration.

Step 2: Create the Ingress Firewall Policy

A Virtual IP alone does not pass traffic; it only defines translation rules. A security policy must explicitly allow traffic to pass from the external zone/interface to the internal zone/interface.

  1. Navigate to Policy & Objects > Firewall Policy.
  2. Click Create New.
  3. Fill out the policy fields:
    • Name: Enter Allow-External-To-DMZ-HTTPS.
    • Incoming Interface: Select wan1.
    • Outgoing Interface: Select dmz.
    • Source: Select all (or restrict to specific geographic/IP objects).
    • Destination: Select the Virtual IP object created earlier: VIP_DMZ_HTTPS_Server.
    • Schedule: Select always.
    • Service: Select HTTPS.
    • Action: Select ACCEPT.
  4. Set NAT to disabled (pushed slider left).

    Note: Destination NAT is performed automatically by the Virtual IP object. Outbound Source NAT (SNAT) on this incoming policy is generally kept disabled unless you require hairpin NAT or special proxy handling.

  5. Enable Security Profiles (e.g., AntiVirus, IPS, Web Filtering) to inspect incoming SSL/TLS traffic if deep inspection is deployed.
  6. Set Log Allowed Traffic to All Sessions for tracking and troubleshooting.
  7. Click OK to activate the policy.

CLI Configuration

For engineers who prefer the command-line interface or require automation scripts, the equivalent FortiOS CLI syntax is provided below.

1. Define the Virtual IP Object

config firewall vip
    edit "VIP_DMZ_HTTPS_Server"
        set comment "DNAT mapping for DMZ HTTPS web portal"
        set type static-nat
        set extintf "wan1"
        set extip 203.0.113.10
        set mappedip "10.0.10.50"
        set portforward enable
        set protocol tcp
        set extport 443
        set mappedport 443
    next
end

2. Define the Firewall Security Policy

config firewall policy
    edit 10
        set name "Allow-External-To-DMZ-HTTPS"
        set srcintf "wan1"
        set dstintf "dmz"
        set srcaddr "all"
        set dstaddr "VIP_DMZ_HTTPS_Server"
        set action accept
        set schedule "always"
        set service "HTTPS"
        set utm-status enable
        set ips-sensor "default"
        set logtraffic all
        set comments "Permit inbound HTTPS to VIP"
    next
end

How the Traffic Flows

Understanding the order of operations inside FortiOS is critical when troubleshooting VIP behavior. The firewall processes incoming requests in a precise sequence:

  1. Ingress Packet Reception: A packet arrives on interface wan1 with Source IP 198.51.100.25:52134 and Destination IP 203.0.113.10:443.
  2. VIP / DNAT Lookup: FortiOS evaluates Destination NAT rules early in the packet flow lifecycle before routing and policy evaluation. It identifies that 203.0.113.10:443 maps to Virtual IP VIP_DMZ_HTTPS_Server.
  3. Address Translation Kernel Pre-processing: The system translates the destination address from 203.0.113.10 to 10.0.10.50.
  4. Routing Table Lookup: FortiGate queries its routing table for destination 10.0.10.50 to determine the egress interface. The route resolves via interface dmz.
  5. Firewall Policy Match: The firewall kernel checks policy rules from direction wan1 to dmz. It checks if the packet matches a rule where destination address equals object VIP_DMZ_HTTPS_Server.
  6. Session Table Creation: Upon policy match, FortiGate writes a stateful session entry into its firewall kernel session table tracking both pre-NAT and post-NAT tuples.
  7. Egress to Destination: The transformed packet leaves the dmz interface with Source IP 198.51.100.25:52134 and Destination IP 10.0.10.50:443.
  8. Return Traffic Processing: When the web server replies from 10.0.10.50:443 to 198.51.100.25:52134, FortiGate matches the existing stateful session, translates the source address back to 203.0.113.10:443, and transmits the packet back out wan1.

Verification

Once configured, verify that the active session table correctly handles real-time translations.

Check Session Filters in CLI

Use the firewall session filter to isolate traffic bound for your target server IP address:

diagnose firewall session filter dst 10.0.10.50
diagnose firewall session list

Sample Diagnostic Output:

session info: proto=6 proto_state=01 duration=12 expire=3587 timeout=3600 flags=00000000 dev=3/4 gwy=10.0.10.50/0
pkts/bytes(req): 5/340 pkts/bytes(resp): 4/820
state=may_dirty npu_valid
statistic(bytes): req=340 resp=820 total=1160
orgin->sink: client 198.51.100.25:52134 -> 203.0.113.10:443 [10.0.10.50:443]
reply->sink: server 10.0.10.50:443 -> 198.51.100.25:52134 [203.0.113.10:443]
help=0 status=none rc=0

Notice that the orgin->sink line reflects the external public VIP address transformed in brackets to the internal DMZ IP address [10.0.10.50:443].

Troubleshooting

If external clients cannot establish connections to the published service, follow this systematic diagnostic workflow.

1. Packet Tracing with Debug Flow

The FortiGate debug flow utility traces internal execution decisions packet by packet. Use this tool to isolate routing, NAT, or firewall policy failures.

Execute the following diagnostic commands:

diagnose debug reset
diagnose debug flow filter saddr 198.51.100.25
diagnose debug flow filter dport 443
diagnose debug flow show function-name enable
diagnose debug flow trace start 10
diagnose debug enable

Initiate a connection from an external client. Analyze the generated logs to confirm whether the packet matches your VIP and policy. Common findings include:

  • nat line matching... confirms Virtual IP resolution.
  • Allowed by Rule(10): confirms policy evaluation success.
  • reverse route lookup failed indicates a routing problem returning to the internet user.

Caution: Running live debugs on high-throughput production firewalls can consume substantial system CPU resources. Always disable debug mode immediately after completing test capture runs.

To safely clear and disable the diagnostic output, run:

diagnose debug disable
diagnose debug reset

2. Checking ARP Table Resolution

If the public IP address used in the Virtual IP is an additional IP address assigned to the WAN interface (secondary IP / IP range), FortiGate must reply to ARP requests for that IP address on the WAN interface. Confirm that ARP queries are answered correctly by running:

diagnose ip arp list | grep wan1

Common Mistakes

  • Selecting Private IP in Firewall Policy Destination: A very common error is setting the destination address in the firewall policy to the mapped real IP (10.0.10.50) instead of selecting the VIP object (VIP_DMZ_HTTPS_Server). In standard policy NAT mode, FortiGate policy matches require selecting the VIP object name as the policy destination.
  • Incorrect Interface Binding: If a Virtual IP’s interface parameter is explicitly set to wan1, but incoming traffic arrives over a secondary WAN interface or IPSec tunnel, FortiGate ignores the VIP. Set the VIP interface to any if traffic arrives across multiple path sources.
  • Missing Reverse Route / Default Gateway on Server: If the web server lacks a valid default gateway pointing back to the FortiGate DMZ interface (10.0.10.1), return packets are dropped at the host layer.
  • Port Overlap Conflicts: If the external VIP port conflicts with a local service listening on the FortiGate WAN interface (e.g., FortiGate Administrative HTTPS interface listening on port 443 of the same public IP), the firewall management port can override or intercept traffic. Change the FortiGate administrative access port under System > Settings to non-standard ports (e.g., 8443) to avoid service collisions.

Production Considerations

Hairpin NAT (NAT Loopback)

If internal hosts on private LAN segments try to access the public VIP address (203.0.113.10) to reach the DMZ server, connection attempts often fail due to asymmetric routing or source translation mismatch. FortiGate enables Virtual IP NAT loopback by default. However, you must ensure a valid firewall policy exists from the LAN interface to the DMZ interface referencing the same VIP object as its destination.

Central NAT Compatibility

If your FortiGate operates in Central NAT mode (configured under System > Settings or CLI), NAT rules are evaluated independently from security policies:

  • In Central NAT mode, destination address matching inside the Firewall Policy uses the internal mapped private IP object (10.0.10.50) rather than the VIP object.
  • DNAT mappings are managed under Policy & Objects > Central SNAT / DNAT maps.
  • Ensure you identify whether your device runs Policy-based NAT or Central NAT mode before deploying new rules.

IPS and Web Application Firewall Protection

Exposing servers directly to the public Internet presents continuous automated scanning risks. Always attach an Intrusion Prevention System (IPS) sensor profile to ingress VIP policies. If the published service processes HTTPS, enable Deep SSL Inspection along with Web Application Firewall (WAF) profiles on compatible FortiGate enterprise hardware models.

Summary

FortiGate Virtual IPs provide a robust method for managing Destination NAT and port forwarding rules across enterprise networks. By isolating translation parameters inside Virtual IP objects and linking them to explicit ingress firewall policies, FortiOS delivers both traffic forwarding capability and strong security boundaries.

When deploying VIPs in your environment, remember to reference the VIP object in your security policy destination field, verify upstream and return routing, inspect active session filters, and disable CLI debug monitors promptly after verification.