FortiGate IPsec VPN for Windows Native VPN Client (IKEv2 and EAP)
In a previous post, I described the configuration needed for an IPsec VPN for FortiClient using IKEv2 and EAP for negotiation and user authentication, respectively. In case you don't want to use FortiClient as your IPsec VPN client, an alternative can be the Windows native VPN client, which also supports IKEv2 and EAP.
This post describes the configuration needed on both FortiGate and client sides when using the Windows 10 native VPN client. Because the native VPN client for Windows 7 and 8 also supports IKEv2 and EAP, the same procedure should also work for those Windows versions. On this post, the configuration is applied on the FortiGate CLI.
Firmware and Configuration Details
- FortiOS 6.2.3
- VDOMs: disabled
- Remote Windows user
- Windows 10 (native VPN client)
- Type of VPN: IKEv2
- Authentication: Secure password (EAP-MSCHAPv2)
Firewall address objects
config firewall address edit "LAN" set subnet 192.168.1.0 255.255.255.0 next edit "DMZ" set subnet 172.16.1.0 255.255.255.0 next end
- Address objects LAN and DMZ for 192.168.1.0/24 and 172.16.1.0/24 subnets.
On the Windows client, set the authentication method to Secure password (EAP-MSCHAPv2). Under this method, the Windows native VPN client authenticates the remote peer (FortiGate) with digital signatures, which means that you alneed to create a local certificate for the IPsec VPN phase 1 configuration on FortiGate. I already have a certificate installed on my FortiGate unit named fgt-hq-ipsec.checkthefirewall.com that has the following properties:
FGT-HQ # config vpn certificate local FGT-HQ (local) # edit fgt-hq-ipsec.checkthefirewall.com FGT-HQ (fgt-hq-ipsec.che~com) # get name : fgt-hq-ipsec.checkthefirewall.com password : * comments : private-key : * certificate : Subject: C = CA, ST = Ontario, L = Toronto, OU = Blog, O = Check The Firewall, CN = fgt-hq-ipsec.checkthefirewall.com Issuer: C = CA, ST = Ontario, L = Toronto, OU = Blog, O = Check The Firewall, CN = Check The Firewall Root CA Valid from: 2020-05-20 03:45:02 GMT Valid to: 2025-05-19 03:45:02 GMT Fingerprint: 6B:B9:1A:79:0F:D6:09:AE:89:ED:0F:41:EE:A3:89:C0 Root CA: No Version: 3 Serial Num: cf:26:f8:9b:48:42:62:99 Extensions: Name: X509v3 Basic Constraints Critical: no Content: CA:FALSE Name: X509v3 Key Usage Critical: no Content: Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment Name: X509v3 Extended Key Usage Critical: no Content: TLS Web Server Authentication state : OK range : global source : user source-ip : 0.0.0.0 ike-localid-type : asn1dn enroll-protocol : none
If you need to create the certificate, you can follow the steps shown on this link, but keep in mind the following:
- The common name (CN) must match the IP address or FQDN configured on the VPN client. In my case, I am using the FQDN fgt-hq-ipsec.checkthefirewall.com as my certificate CN. Therefore, the server name on my Windows client configuration must be set to fgt-hq-ipsec.checkthefirewall.com as well.
- The certificate must include TLS Web Server Authentication as Extended Key Usage extension.
- If there are intermediate CAs in the certificate chain, make sure to import those intermediate CAs into FortiGate local CA store. As a result, FortiGate will include the intermediate CAs when sending the certificate to the client during phase 1 negotiation, which allows the client to verify the certificate chain in case the intermediate CAs are not installed on its local certificate store.
Note: If the requirements above are not met, the Windows client may fail to authenticate FortiGate, and the VPN will not come up.
In my case, there are no intermediate CAs because my certificate was issued by my root CA (Check The Firewall Root CA). If you need to import your intermediate CAs into FortiGate, follow the procedure below on the FortiGate GUI:
- Go to System > Certificates.
- Click Import > CA Certificate.
- Click File > Upload and then browse to the CA certificate you want to import.
config vpn ipsec phase1-interface edit "WIN_IKEv2" set type dynamic set interface "port1" set ike-version 2 set authmethod signature set peertype any set net-device disable set mode-cfg enable set proposal aes128-sha1 aes256-sha256 set comments "Windows native VPN client - IKEv2 and EAP user auth" set dhgrp 2 set eap enable set eap-identity send-request set certificate "fgt-hq-ipsec.checkthefirewall.com" set ipv4-start-ip 192.168.255.1 set ipv4-end-ip 192.168.255.31 set dns-mode auto next end
- authmethod is set to signature (digital signature) so FortiGate authenticates to the remote peer with a certificate.
- ike-version is set to 2.
- peertype is set to any so FortiGate accepts any peerid presented by the remote peer.
- dhgroup is set to 2 because that's the only DH group offered by the Windows native VPN client by default.
- Because digital signature has been selected as the authentication method for FortiGate, you need to select a certificate ( fgt-hq-ipsec.checkthefirewall.com).
- EAP is enabled for authenticating the remote user's credentials. In addition, eap-identity is set to send-request so FortiGate requests remote peer credentials through EAP.
- ipv4-split-include (split tunneling) is disabled because the Windows client does not support IPv4 subnets through IKE mode config. ipv4-split-include setting is disabled by default, and therefore not seen in the configuration.
config vpn ipsec phase2-interface edit "WIN_IKEv2-p2" set phase1name "WIN_IKEv2" set proposal aes128-sha1 aes256-sha1 set pfs disable next end
- A phase 2 named WIN_IKEv2-p2 is created and bound to phase 1 WIN_IKEv2, which was created in the previous step.
- Perfect forward secrecy (PFS) is disabled because the Windows client does not offer PFS when negotiating phase 2.
VPN user credentials
config user local edit "bob" set type password set passwd checkthefirewall next end config user group edit "VPN" set member "bob" next end
- User bob, and user group VPN with bob as member.
config firewall policy edit 0 set name "From_WIN_IKEv2_to_LAN" set srcintf "WIN_IKEv2" set dstintf "port5" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set groups "VPN" next edit 0 set name "From_WIN_IKEv2_to_DMZ" set srcintf "WIN_IKEv2" set dstintf "port7" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set groups "VPN" next end
- Two incoming firewall policies are created: one to allow from the VPN to LAN (port5), and another from the VPN to DMZ (port7).
Importing the root CA certificate
In order to verify the digital signature and chain of FortiGate certificate, Windows needs the public key of the CA that issued the FortiGate certificate. For this reason, you need to install the root CA certificate into Windows Trusted Root Certification Authorities by following the next procedure:
- Copy the root CA certificate to the Windows computer.
- Double-click the certificate to open it.
- A security warning is displayed. Click Open to proceed.
- Click Install Certificate.
Local Machine, and then click
- Select Place all the certificates in the following store:, and then click Browse.
- Select Trusted Root Certification Authorities, click OK, and then click Next.
- Click Finish.
- The message The import was successful is displayed.
- Click OK on all remaining windows.
Creating VPN connection
- Right-click on the network system tray icon, and then click Open Network & Internet settings.
- Click VPN, and then click Add a VPN connection.
Enter the VPN settings below, and then click Save.
- Check the properties for the new VPN connection, and make sure the security tab look like the image below.
Configuring routes for split tunneling
As mentioned before, the Windows native VPN client does not support IPv4 subnets through IKE mode config (split tunneling). Instead, by default, Windows installs only a classful subnet matching the tunnel IP address range configured for IKE mode config, which in my case is 192.168.255.1- 192.168.255.31. Consequently, if you want to reach LAN and DMZ subnets, you need to configure VPN routes on Windows. You can either add a default route by enabling the Use default gateway on remote network option available on the VPN adapter Advanced TCP/IP Settings, or use the Windows PowerShell Add-VpnConnectionRoute cmdlet to install routes for the remote networks only. I prefer the latter, so I will run the following commands as an Administrator on Windows PowerShell:
PS C:\Windows\system32> Add-VpnConnectionRoute -ConnectionName "FortiGate" -DestinationPrefix "192.168.1.0/24" -PassThru DestinationPrefix : 192.168.1.0/24 InterfaceIndex : InterfaceAlias : FortiGate AddressFamily : IPv4 NextHop : 0.0.0.0 Publish : 0 RouteMetric : 1 PolicyStore : PS C:\Windows\system32> Add-VpnConnectionRoute -ConnectionName "FortiGate" -DestinationPrefix "172.16.1.0/24" -PassThru DestinationPrefix : 172.16.1.0/24 InterfaceIndex : InterfaceAlias : FortiGate AddressFamily : IPv4 NextHop : 0.0.0.0 Publish : 0 RouteMetric : 1 PolicyStore :
Note: The routes above are persistent and will be automatically added by Windows when the VPN is up.
Remote Windows user
- Right-click on the network system tray icon, and click Open Network & Internet settings.
Click VPN, and then the VPN connection we configured (FortiGate in my case).
- Click Connect.
- The VPN is shown as Connected.
- When checking the routing table on the remote user, I see the two routes installed by Windows (Add-VpnConnectionRoute cmdlet).
C:\Users\User>route print --- cut --- 172.16.1.0 255.255.255.0 On-link 192.168.255.1 26 --- cut --- 192.168.1.0 255.255.255.0 On-link 192.168.255.1 26 --- cut ---
- I ping LAN (192.168.1.254) and DMZ (18.104.22.168) interfaces. Pings are successful.
C:\Users\User>ping 192.168.1.254 -n 2 Pinging 192.168.1.254 with 32 bytes of data: Reply from 192.168.1.254: bytes=32 time=1ms TTL=255 Reply from 192.168.1.254: bytes=32 time=2ms TTL=255 Ping statistics for 192.168.1.254: Packets: Sent = 2, Received = 2, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 1ms, Maximum = 2ms, Average = 1ms C:\Users\User>ping 172.16.1.254 -n 2 Pinging 172.16.1.254 with 32 bytes of data: Reply from 172.16.1.254: bytes=32 time=1ms TTL=255 Reply from 172.16.1.254: bytes=32 time=1ms TTL=255 Ping statistics for 172.16.1.254: Packets: Sent = 2, Received = 2, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 1ms, Maximum = 1ms, Average = 1ms
- Go to Monitor > IPsec Monitor, and enable the Proxy ID Destination and XAUTH User columns. The tunnel WIN_IKEv2_0 for bob is up. Also, bob was assigned with address 192.168.255.1.
- On the GUI, go to Monitor > Routing Monitor . A static route has been added for bob 192.168.255.1.
- Phase 1. IKE version is 2 and phase 1 is up ( established).
FGT-HQ # get vpn ike gateway vd: root/0 name: WIN_IKEv2_0 version: 2 interface: port1 3 addr: 10.1.1.10:4500 -> 10.10.10.10:4500 created: 6s ago eap-user: bob assigned IP address: 192.168.255.1/0.0.0.0 IKE SA created: 1/1 established: 1/1 time: 160/160/160 ms IPsec SA created: 1/1 established: 1/1 time: 0/0/0 ms id/spi: 10 0c5dd05c24940851/72fc5305a4457cdb direction: responder status: established 6-6s ago = 160ms proposal: aes-128-sha1 SK_ei: a3b17973c3260411-11c1564c9778b4f8 SK_er: e81135e97f5166bf-da4795d445c6c850 SK_ai: 644fbeae917e757a-9a7186b2e97aef57-dc7f3ad5 SK_ar: d077c85ad3f4bfeaaeb5c0f095ca27701f7e0a94 lifetime/rekey: 86400/86123 DPD sent/recv: 00000000/00000000
- Phase 2. Security associations (SAs) were negotiated. Tunnel is up.
FGT-HQ # diagnose vpn tunnel list name WIN_IKEv2_0 list ipsec tunnel by names in vd 0 ------------------------------------------------------ name=WIN_IKEv2_0 ver=2 serial=6 10.1.1.10:0->10.10.10.10:4500 dst_mtu=1500 bound_if=3 lgwy=static/1 tun=intf/0 mode=dial_inst/3 encap=none/640 options=rgwy-chg frag-rfc run_state=1 accept_traffic=1 parent=WIN_IKEv2 index=0 proxyid_num=1 child_num=0 refcnt=6 ilast=6 olast=6 ad=/0 stat: rxp=23 txp=0 rxb=4168 txb=0 dpd: mode=on-demand on=1 idle=20000ms retry=3 count=0 seqno=1 natt: mode=none draft=0 interval=0 remote_port=0 proxyid=WIN_IKEv2-p2 proto=0 sa=1 ref=2 serial=1 add-route src: 0:0.0.0.0-255.255.255.255:0 dst: 0:192.168.255.1-192.168.255.1:0 SA: ref=3 options=a6 type=00 soft=0 mtu=1438 expire=43159/0B replaywin=2048 seqno=1 esn=0 replaywin_lastseq=00000017 itn=0 qat=0 life: type=01 bytes=0/0 timeout=43186/43200 dec: spi=bce7e575 esp=aes key=16 689c60a7fabe0db76abe2ca421a4e3be ah=sha1 key=20 706a5c8facd26cccce24dc6e5c72d17c4bd57632 enc: spi=1a4bdc22 esp=aes key=16 58db2693af827f2205f3d57a33409ea6 ah=sha1 key=20 87db42323bc50e267642453442ddccd621d2442a dec:pkts/bytes=23/2596, enc:pkts/bytes=0/0
- Routing table. A static route for bob (192.168.255.1) has been added.
FGT-HQ # get router info routing-table all Routing table for VRF=0 Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP O - OSPF, IA - OSPF inter area N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2 E1 - OSPF external type 1, E2 - OSPF external type 2 i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area * - candidate default S* 0.0.0.0/0 [10/0] via 10.1.1.1, port1 C 10.1.1.0/24 is directly connected, port1 C 172.16.1.0/24 is directly connected, port7 C 192.168.1.0/24 is directly connected, port5 S 192.168.255.1/32 [15/0] via 10.10.10.10, WIN_IKEv2
- When sniffing the pings sent by the remote user. ICMP requests and replies are seen.
FGT-HQ # diagnose sniffer packet any "(host 192.168.1.254 or host 172.16.1.254) and icmp" 4 0 l interfaces=[any] filters=[(host 192.168.1.254 or host 172.16.1.254) and icmp] 2020-06-08 20:45:16.017802 WIN_IKEv2 in 192.168.255.1 -> 192.168.1.254: icmp: echo request 2020-06-08 20:45:16.017868 WIN_IKEv2 out 192.168.1.254 -> 192.168.255.1: icmp: echo reply 2020-06-08 20:45:17.022793 WIN_IKEv2 in 192.168.255.1 -> 192.168.1.254: icmp: echo request 2020-06-08 20:45:17.022832 WIN_IKEv2 out 192.168.1.254 -> 192.168.255.1: icmp: echo reply 2020-06-08 20:45:22.052562 WIN_IKEv2 in 192.168.255.1 -> 172.16.1.254: icmp: echo request 2020-06-08 20:45:22.052652 WIN_IKEv2 out 172.16.1.254 -> 192.168.255.1: icmp: echo reply 2020-06-08 20:45:23.088762 WIN_IKEv2 in 192.168.255.1 -> 172.16.1.254: icmp: echo request 2020-06-08 20:45:23.088790 WIN_IKEv2 out 172.16.1.254 -> 192.168.255.1: icmp: echo reply
Feel free to download the configuration files I used for this lab, as well as the output taken for some debugs during testing.
|ipsec-windows-native-ikev2-FGT-HQ-623.conf||FortiGate HQ Configuration File||06/08/2020|
I described how to configure an IPsec VPN for the Windows native VPN client, which supports IKEv2 and EAP (EAP-MSCHAPv2). To achieve split tunneling, I had to add routes using the Add-VpnConnectionRoute cmdlet because the client does not support IPv4 subnets through IKE mode config.
In addition, the Windows native VPN client authenticates FortiGate using digital signatures, which then required a certificate for IPsec on FortiGate. Finally, the root CA certificate was imported into the Windows certificate store on the remote user for the digital signature verification to pass.
A Network Security Engineer based in Canada.