Description
This article describes how to restrict IPSec VPN access to certain countries. Indeed, by default, dialup IPSec VPN’s are accessible to all public IP addresses on the Internet.
Scope
FortiGate.
Solution
FortiGate Firewalls have built-in Security Profiles called 'Local-In' policies.
These polices exist to permit access to various services and to support the inner working of the FortiGate and include access to ports used by IPSec VPN.
By configuring a Local-In policy in conjunction with a Geography address object it is possible to modify the default behaviour and restrict access to IPsec VPN to IP Addresses originating from certain countries.
The example below assumes that an IPsec VPN is already set up and accessible via a static IP Address on Interface WAN1 and that access is only required from VPN clients originating from IP addresses from a certain country.
- Create an Address Object for the WAN IP Address:
From the FortiGate’s GUI Interface select: Policy & Object, Addresses, select 'Create New' then Address. Select Type as 'Subnet', enter a Name (e.g. WAN_IP) and type in the IP WAN address:

- Create a Geography based Address Object for the networks that can access the VPN:
From the FortiGate’s GUI Interface select: Policy & Object, Addresses, Click ‘Create New’ then Address. Select Type as 'Geography', enter a Name (e.g. Allowed_IP_Sec), set the Interface to the external (WAN) interface and select the Country from the list.

- Create the Local-In policy to allow the access from trusted sources:
(For this step it is needed to be connect to the Firewall’s command line using SSH).
Once connected via SSH, enter the following commands to create the Local-In policy.
config firewall local-in-policy
edit 1
set intf “wan1” <----- Or whichever interface the VPN is accessible via.
set srcaddr “Allowed_IP_Sec_IP” <----- The name given in 2).
set dstaddress “WAN_IP” <----- The name given in 1).
set action accept <----- Allow the connection.
set service “IKE” <----- This is a built in service for UDP port 500 and port 4500 as used by IPsec.
set schedule “always’ <----- Always allow the policy.
next
end

- Create the Local-In policy to block the access from the rest (untrusted sources):
config firewall local-in-policy
edit 2
set intf “wan1” <----- Or whichever interface the VPN is accessible via.
set srcaddr “all” <----- In the first policy, there are specified trusted sources, in this policy sources 'all' will be used.
set dstaddress “WAN_IP” <----- The name given 1).
set action deny <----- Deny the connection from the rest sources that are not present in the first local-in policy.
set service “IKE” <----- This is a built in service for UDP port 500 and port 4500 as used by IPsec.
set schedule “always’ <----- Always allow the policy.
next
end
Note:
When configuring local-in policies please make sure that the first policy is to allow the access from the trusted sources, and second policy to deny rest sources that are not included in the first policy.
At the final there are two local-in policies, 1th policy to allow the traffic from trusted sources, 2nd policy to deny service for the rest untrusted sources.
config firewall local-in-policy
edit 1
set intf "wan1"
set srcaddr "GEO-IP - Canada" "G - ALL PRIVATE ADDRESS RANGES" "GEO-IP - USA"
set dstaddr "WAN_IP"
set action accept
set service "IKE"
set schedule "always"
next
edit 2
set intf "wan1"
set srcaddr "all"
set dstaddr "WAN_IP"
set service "IKE"
set schedule "always"
next
end
Another way to design the local-in-policy is to use the 'srcaddr-negate'. This option acts as a logical 'NOT' or 'XOR' condition where the action of the policy will apply to all addresses except the address option in the 'srcaddr' field:
config firewall local-in-policy
edit 1
set intf "wan1"
set srcaddr "GEO-IP-ALLOWED"
set srcaddr-negate enable <--- means the srcaddr "GEO-IP-ALLOWED" is the only object excluded from the deny action on this policy
set dstaddr "WAN_IP" set action accept
set service "IKE"
set schedule "always"
next
end
To verify that all works as expected:
diagnose debug disable
diagnose debug reset
diagnose debug flow filter clear
diagnose debug flow show function-name enable
diagnose debug flow filter daddr x.x.x.x <----- x.x.x.x will be the WAN1 IP address.
diagnose debug flow filter port 500
diagnose debug flow trace start 100
diagnose debug enableWhen traffic is blocked, debug output will be visible with message:
msg="iprope_in_check() check failed on policy 2, drop"To disable debug:
diagnose debug disable
diagnose debug reset
diagnose debug flow filter clear