Stackvora.tech

FortiGate IPsec Site-to-Site VPN (Step by Step)

Establishing secure, encrypted communication channels between geographically dispersed networks is a fundamental requirement for many organizations. IPsec…

Establishing secure, encrypted communication channels between geographically dispersed networks is a fundamental requirement for many organizations. IPsec Site-to-Site VPNs provide this capability, and FortiGate firewalls are a popular choice for their robust security features and flexible configuration options. This article details the step-by-step configuration of an IPsec VPN tunnel between two FortiGate devices, using a common hub-and-spoke topology as an example.

Our scenario involves a Head Office (HQ) network and a Branch Office network. HQ's internal network is 10.10.0.0/24, accessible via its public IP 203.0.113.10. The Branch Office's internal network is 10.20.0.0/24, with a public IP of 198.51.100.20. The goal is to allow seamless and secure communication between these two private subnets.

IPsec VPN Fundamentals

Before diving into configuration, it's essential to understand the two main phases of an IPsec VPN tunnel:

  • Phase 1 (IKE - Internet Key Exchange): This phase establishes a secure, authenticated channel between the two VPN peers. It negotiates encryption and authentication algorithms for the control plane (IKE SAs), authenticates the peers (using pre-shared keys or certificates), and sets up the shared secret for Phase 2. Common IKE versions are IKEv1 and IKEv2. FortiGate recommends IKEv2 for its improved security, reliability, and support for NAT traversal.
  • Phase 2 (IPsec SA - Security Association): Once Phase 1 is complete, Phase 2 negotiates the parameters for securing the actual data traffic (user data). This includes encryption algorithms (e.g., AES), authentication algorithms (e.g., SHA), and defines the local and remote subnets that will use the tunnel (traffic selectors). The result is an IPsec Security Association (SA).

Key Parameters and Protocols

For a successful IPsec tunnel, both ends must agree on several parameters. Mismatches in any of these will prevent the tunnel from coming up:

  • IKE Version: IKEv1 or IKEv2.
  • Authentication Method: Pre-shared Key (PSK) or Digital Certificates.
  • Phase 1 Proposal: Encryption (e.g., AES256), Authentication (e.g., SHA256), Diffie-Hellman Group (e.g., Group 14/24).
  • Phase 2 Proposal: Encryption (e.g., AES256), Authentication (e.g., SHA256), PFS Group (optional, e.g., Group 14/24).
  • Local/Remote ID (IKEv2): Often the public IP or FQDN of the peer, used for identification during IKE negotiation.
  • Local/Remote Subnets (Traffic Selectors): The private IP ranges that will communicate over the tunnel.

FortiGate HQ Configuration (Initiator)

We'll start with the Head Office FortiGate, which will initiate the VPN connection. Its external interface is wan1, with public IP 203.0.113.10. The internal network is 10.10.0.0/24.

Phase 1 Configuration (IKEv2)

This defines how the VPN tunnel itself is established securely.

config vpn ipsec phase1-interface
    edit "vpn-branch"
        set interface "wan1"
        set ike-version 2
        set peertype any
        set net-device disable <-- Important for route-based VPNs, creates virtual interface
        set proposal aes256-sha256 aes128-sha256 <-- Multiple proposals for negotiation flexibility
        set remote-gw 198.51.100.20 <-- Public IP of Branch FortiGate
        set psksecret YOUR_STRONG_PSK <-- Use a complex, long pre-shared key
        set dpd-retryinterval 5 <-- Dead Peer Detection every 5 seconds
        set dpd-retrycount 3 <-- After 3 retries, declare peer dead
        set local-id "HQ_FortiGate" <-- Optional but good practice for IKEv2, can be IP or FQDN
        set peer-id "Branch_FortiGate" <-- Optional, useful for authentication with multiple tunnels
        set nattraversal enable <-- Enable NAT traversal (typically default on modern FortiOS)
    next
end

Note: net-device disable is critical for a "route-based" VPN, which creates a virtual interface that routes can be bound to. For "policy-based" VPNs, this would be enable (creating a policy within the phase2 entry itself).

Phase 2 Configuration

This defines how data traffic is secured once Phase 1 is up. We're using traffic selectors to define what subnets can communicate.

config vpn ipsec phase2-interface
    edit "vpn-branch-p2"
        set phase1name "vpn-branch"
        set proposal aes256-sha256 aes128-sha256 <-- Must match or be compatible with Phase 1 proposal
        set pfs disable <-- Disable Perfect Forward Secrecy for simplicity; enable for higher security (e.g., set pfs group14)
        set src-subnet 10.10.0.0 255.255.255.0 <-- HQ's local subnet
        set dst-subnet 10.20.0.0 255.255.255.0 <-- Branch's remote subnet
        set keylifeseconds 3600 <-- Re-key every hour
        set keepalive enable <-- Periodically send traffic to keep the tunnel alive
    next
end

Static Route

For traffic from HQ to reach the Branch network, a static route is required that points to the VPN tunnel interface.

config router static
    edit 0
        set dst 10.20.0.0 255.255.255.0 <-- Branch network
        set device "vpn-branch" <-- The virtual interface created by Phase 1
    next
end

Firewall Policies

Two firewall policies are needed for bidirectional communication:

config firewall policy
    edit 0
        set name "HQ-to-Branch-VPN"
        set srcintf "internal" <-- Or your HQ LAN interface name
        set dstintf "vpn-branch"
        set srcaddr "HQ_Subnet" <-- Address object for 10.10.0.0/24
        set dstaddr "Branch_Subnet" <-- Address object for 10.20.0.0/24
        set action accept
        set service "ALL"
        set nat disable <-- Do NOT NAT traffic over VPN
    next
    edit 0
        set name "Branch-to-HQ-VPN"
        set srcintf "vpn-branch"
        set dstintf "internal"
        set srcaddr "Branch_Subnet"
        set dstaddr "HQ_Subnet"
        set action accept
        set service "ALL"
        set nat disable
    next
end

Note: Replace "HQ_Subnet" and "Branch_Subnet" with actual address objects configured on your FortiGate. You can create them under Policy & Objects > Addresses. For example, config firewall address edit "HQ_Subnet" set subnet 10.10.0.0 255.255.255.0 next end.

FortiGate Branch Configuration (Responder)

Now, configure the Branch Office FortiGate. Its external interface is also wan1, with public IP 198.51.100.20. The internal network is 10.20.0.0/24.

Phase 1 Configuration (IKEv2)

This must mirror the HQ configuration.

config vpn ipsec phase1-interface
    edit "vpn-hq"
        set interface "wan1"
        set ike-version 2
        set peertype any
        set net-device disable
        set proposal aes256-sha256 aes128-sha256
        set remote-gw 203.0.113.10 <-- Public IP of HQ FortiGate
        set psksecret YOUR_STRONG_PSK <-- MUST be identical to HQ
        set dpd-retryinterval 5
        set dpd-retrycount 3
        set local-id "Branch_FortiGate"
        set peer-id "HQ_FortiGate"
        set nattraversal enable
    next
end

Phase 2 Configuration

Again, this must mirror the HQ configuration, with source and destination subnets swapped.

config vpn ipsec phase2-interface
    edit "vpn-hq-p2"
        set phase1name "vpn-hq"
        set proposal aes256-sha256 aes128-sha256
        set pfs disable
        set src-subnet 10.20.0.0 255.255.255.0 <-- Branch's local subnet
        set dst-subnet 10.10.0.0 255.255.255.0 <-- HQ's remote subnet
        set keylifeseconds 3600
        set keepalive enable
    next
end

Static Route

Route traffic from Branch to the HQ network via the VPN tunnel interface.

config router static
    edit 0
        set dst 10.10.0.0 255.255.255.0 <-- HQ network
        set device "vpn-hq" <-- The virtual interface created by Phase 1
    next
end

Firewall Policies

Two firewall policies for bidirectional communication at the Branch.

config firewall policy
    edit 0
        set name "Branch-to-HQ-VPN"
        set srcintf "internal" <-- Or your Branch LAN interface name
        set dstintf "vpn-hq"
        set srcaddr "Branch_Subnet" <-- Address object for 10.20.0.0/24
        set dstaddr "HQ_Subnet" <-- Address object for 10.10.0.0/24
        set action accept
        set service "ALL"
        set nat disable
    next
    edit 0
        set name "HQ-to-Branch-VPN"
        set srcintf "vpn-hq"
        set dstintf "internal"
        set srcaddr "HQ_Subnet"
        set dstaddr "Branch_Subnet"
        set action accept
        set service "ALL"
        set nat disable
    next
end

Remember to create the necessary address objects on the Branch FortiGate as well.

Verification and Monitoring

After configuring both FortiGates, verify the tunnel status:

On the FortiGate CLI, execute:

diagnose vpn ike gateway list <-- Shows Phase 1 status
diagnose vpn ike tunnel list <-- Shows Phase 2 status and traffic selectors
get vpn ipsec tunnel status <-- High-level overview, useful in FortiOS 7.0+
execute ping 10.20.0.1 <-- From HQ CLI to a Branch device (ensure ping is allowed by firewall)
execute ping 10.10.0.1 <-- From Branch CLI to an HQ device

On the GUI, navigate to VPN > IPsec Tunnels. You should see the tunnel status as "Up" or green. Hover over the status to see more details. Also, check Log & Report > VPN Events for IKE negotiation messages.

Common Pitfalls and Troubleshooting

  • Mismatching Parameters: This is the most common issue. Double-check all Phase 1 and Phase 2 proposals (encryption, authentication, DH group, PFS), IKE version, pre-shared key, and remote gateway IP. Even a single character difference in the PSK will prevent the tunnel from coming up.
  • Incorrect Traffic Selectors: Ensure src-subnet and dst-subnet are correctly defined on both ends (local subnet as source, remote subnet as destination). A common mistake is to swap them or use overlapping subnets improperly.
  • Firewall Policies: Policies must be configured on both FortiGates for traffic to flow. Ensure nat disable is set for VPN policies. Verify that the correct interfaces, source/destination addresses, and services are specified. Check logs for "denied by policy" messages.
  • Routing Issues: Ensure static routes are correctly configured and point to the VPN tunnel interface. If you have other routing protocols (OSPF, BGP), ensure they don't override the VPN route or that the VPN route is preferred.
  • NAT Traversal (NAT-T): If one or both FortiGates are behind another NAT device, NAT-T (UDP port 4500) must be enabled and allowed through the upstream NAT device. FortiGate typically enables this by default.
  • Public IP Reachability: Ensure the public IPs of both FortiGates can ping each other and that UDP ports 500 (IKE) and 4500 (NAT-T) are not blocked by any upstream firewalls.
  • Aggressive Mode (IKEv1): If using IKEv1, be aware of "aggressive mode" which sends peer IDs in cleartext. Main mode is preferred. For IKEv2, this is less of a concern due to design improvements.
  • Logs, Logs, Logs: The CLI command diagnose debug application ike -1 (then diagnose debug enable) on the FortiGate can provide detailed IKE negotiation logs, which are invaluable for pinpointing where the tunnel fails. Remember to diagnose debug disable afterwards.

Back to the knowledge base · Ask the AI assistant