FortiGate IPsec VPN for Windows Native VPN Client (IKEv2 and EAP)

IPsec VPN with Windows native VPN client (IKEv2 and EAP)

Introduction

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

  • FortiGate
    • FortiOS 6.2.3
    • VDOMs: disabled
  • Remote Windows user
    • Windows 10 (native VPN client)
      • Type of VPN: IKEv2
      • Authentication: Secure password (EAP-MSCHAPv2)

FortiGate Configuration

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.

Certificate

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.

Phase 1

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.

Phase 2

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.

Firewall policies

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).

Windows Configuration

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.
  • Select Local Machine, and then click Next.
  • 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.

Windows native VPN client - creating new connection


  • Click VPN, and then click Add a VPN connection.

Windows native VPN client - creating new connection


  • Enter the VPN settings below, and then click Save.

Windows native VPN client - New connection

  • Check the properties for the new VPN connection, and make sure the security tab look like the image below.

Windows native VPN client - adapter properties


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.

Verification

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.

Windows native VPN client - 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 (172.168.1.254) 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

FortiGate GUI

  • 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.
FortiGate IPsec Monitor - Tunnel is up
  • On the GUI, go to Monitor > Routing Monitor . A static route has been added for bob 192.168.255.1.
FortiGate Routing Monitor - IPsec route

FortiGate CLI

  • 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[0280]=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

Lab Files

Feel free to download the configuration files I used for this lab, as well as the output taken for some debugs during testing.

File Description Date
ipsec-windows-native-ikev2-FGT-HQ-623.conf FortiGate HQ Configuration File 06/08/2020
ipsec-windows-native-ikev2-ike-debug.txt IKE debug 06/08/2020
ipsec-windows-native-ikev2-ike-sniffer.pcap IKE pcap 06/08/2020

Bottom Line

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.


Paul Marin

Paul Marin
A Network Security Engineer based in Canada.

3 comments

  • @Leila, the issue you described is caused by a common limitation of LDAP servers, such as Windows AD. The Windows native VPN client uses PEAP (more specifically PEAPv0/EAP-MSCHAPv2) as the authentication method. The problem is that LDAP does not know how to handle EAP or any of the CHAP variants (CHAP, MSCHAP, MSCHAPv2) because LDAP is not really an authentication protocol, it’s a directory access protocol. LDAP servers expect passwords in cleartext. For this reason, when FortiGate sees that the user credentials need to be verified against an LDAP server, it doesn’t even try to do that and returns an error to FortiClient.

    A solution is to use RADIUS authentication instead. For example, if you are using Windows AD, you can then configure the NPS service to run RADIUS. The NPS service can then look up your AD users during authentication. Because RADIUS supports EAP, then the authentication will work this time.

    Another option is to use FortiAuthenticator (FAC), which is Fortinet’s authentication server. On FAC, you configure the RADIUS service and configure a Windows AD as a backend. The idea is that FAC uses RADIUS with FortiGate and Kerberos with Windows AD. This proxy setup allows FAC to pass on the PEAP messages to Windows AD using Kerberos.

    Hope it helps.

    Paul Marin
  • Hello Paul,

    I am not able to make this working with LDAP users while local users are fine.
    Is it expected behavior?
    Thanks

    Leila
  • Hello Paul,

    I am not able to make this work with LDAP users while local users are fine.
    Is it expected behavior?
    Thanks

    Leila

Leave a comment

Please note, comments must be approved before they are published