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-subnetanddst-subnetare 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 disableis 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(thendiagnose debug enable) on the FortiGate can provide detailed IKE negotiation logs, which are invaluable for pinpointing where the tunnel fails. Remember todiagnose debug disableafterwards.