Wednesday, December 5, 2018

IPsec tunnel from Windows RRAS to FortiGate

Dial-up IPsec tunnel from Windows RRAS to FortiGate

The aim:

Encrypted, mutually authenticated VPN tunnel, initiated by Windows Routing & Remote Access Service and terminated by FortiGate firewall.

Both sides of the tunnel are equipped with private IP addresses and are placed behind NAT routers.

The method:

  • We utilize IKEv2 protocol supported by both sides.
  • Each side authenticates one another by certificate. It checks validity of certificate (dates, signature of a CA) and that its name matches a predefined value. CAs that issued certificates for both side can be different or be the same one.
  • NAT traversal is achieved automatically, by encapsulating IPsec packets in UDP datagrams sent between source & destination ports 4500 (except initial IKE exchange, which is between src & dst port 500). We don't need to configure anything special about it.

Certificates pre-requisites:
  • Windows should have a certificate in the computer Personal store (can be managed by certlm.msc):
    • its Subject should be something like "CN = windows2016". This string will be used by FortiGate to authenticate the peer.
    • It should be signed by CA known to FortiGate. Let's say it's called OurRespectedCA. It should be imported to the "Trusted Root Certification Authorities" or "Intermediate Certification Authorities" store on Windows, and to the FortiGate.
  • FortiGate should also have a certificate:
    • It should list a name in "Subject" or "Subject Alternative Name" field matching the hostname or IP address that RRAS will use to access it.
    • It should be signed by CA trusted by Windows. It may be the same CA as the one that issued certificate for Windows, or may be not.
Windows RRAS configuration:

  • Right-click "Network Interfaces" and select "New Demand-dial Interface".

  • Enter name for the logical interface representing the tunnel. We're going to use IKEv2 protocol, so here I'm setting the name to "IKEv2".

  • Select "Connect using virtual private networking (VPN)":

  • Select the IKEv2 protocol:
  • Enter DNS name or IP address of the FortiGate. This name must appear in the Subject or SAN field of a certificate presented by FortiGate. In case of a mismatch RRAS won't connect.

  • Select "Route IP packets on this interface" and press Next:

  • Define remote subnets sitting behind the FortiGate ( and on the FortiGate itself ( These will appear in the Windows routing table (shown by "route print" command) as static routes, when the IKEv2 interface is up:

  • Leave all "Dial-out credentials" empty, just press Next:

  • Press Finish:

  • You'll see a new interface in the "Network Interfaces" list - IKEv2. Right-click it and open Properties:
  • On Options tab, set type of connection to "Persistent" and redial attempts number and intervals to something making sense:

  • On Security tab, verify that:
    • Type of VPN: IKEv2
    • Data encryption is set to "Maximum strength"
    • The "Use machine certificates" option selected, and "Verify the Name and Usage attributes of the server's certificate" flag is marked.

  • On Networking tab, disable IPv6. Any changes in IPv4 settings have no effect, for some unclear reason, so we cannot set up IPv4 address manually - it will be received from FortiGate:

  • Close Properties, right-click the IKEv2 interface and select "Connect". 

You should be connected.

FortiGate configuration:

Upload certificate & its private key for the FortiGate itself. Import it via WebUI (System --> Certificates --> Import):

Upload certificate of the CA that signed the certificate of the Windows peer. The best way to do it is via CLI, because it allows you to assign custom name to the CA, instead of  some vague CA_Cert_X:

config vpn certificate ca
    edit OurRespectedCA
        set ca "-----BEGIN CERTIFICATE-----
        set range global
        set source user
        set trusted enable
        set scep-url ''
        set source-ip

Define a PKI user account for the remote peer, referencing the CA certificate that we've uploaded:
config user peer
    edit Windows2016
        set ca OurRespectedCA
        set subject Windows2016
        set cn Windows2016

This means that this PKI user must have valid certificate issued by OurRespectedCA, with "CN = Windows2016" in Subject.

Now let's define our tunnel:
config vpn ipsec phase1-interface
    edit IKEv2
        set type dynamic
        set interface wan1
        set ike-version 2
        set authmethod signature
        set mode-cfg enable
        set proposal aes256-sha256
        set dpd disable
        set dhgrp 2
        set certificate
        set peer Windows2016
        set ipv4-start-ip
        set ipv4-end-ip
config vpn ipsec phase2-interface
    edit IKEv2
        set phase1name IKEv2
        set proposal aes256-sha1
        set pfs disable

  • "set type dynamic" means that connection from any IP address will be accepted. We need this, because otherwise we cannot assign the tunnel address ( to Windows ("mode-cfg enable" will not be available). If we want to limit our peer to specific IP or subnet, we should use another firewall before FortiGate.
  • "set authmethod signature" means that certificates are used for authentication of both sides.
  • "set certificate" specifies certificate & private key used by FortiGate.
  • "set peer" references the PKI user account representing the Windows machine.
  • "set proposal aes256-sha256" & "set pfs disable" mean security algorithms to use (AES256 for encryption, SHA256 for integrity, no Perfect Forward Secrety (Diffie-Hellman key exchange). These algorithms match the "Maximum strength encryption" setting on RRAS interface, as we know from "VPN Interoperability guide for Windows Server 2012 R2".
  • "set mode-cfg enable", "set ipv4-start-ip" and "set ipv4-end-ip" are used to assign tunnel address to our peer.

So now we have a logical interface named IKEv2. It now can be joined to security zones or used directly in firewall policies (although I always prefer wrapping them by zones).

But first let's configure it, to allow FortiGate and Windows to reach each other by tunnel addresses:
config system interface
    edit IKEv2
        set vdom root
        set ip
        set allowaccess ping
        set type tunnel
        set remote-ip
        set interface wan1
Note that remote-ip matches the address that we assigned to Windows by the "phase1-interface" configuration.

We can also define static routes towards networks behind Windows:
config router static
    edit 0
        set dst
        set device IKEv2

That's it. Mischief managed. :-)


1. As said above, if we want to limit FortiGate's peer to specific addresses, we should use another firewall before FortiGate  (or maybe "local-in-policy", I didn't check).

2. Assigning static address to the dial-up interface doesn't work in RRAS. Any settings are just ignored.

3. Unfortunately, Windows doesn't allow to specify explicitly the CAs, certificates issued by which will be accepted. This means that it will accept any peer certificate as long as it has in Subject or SAN and chains up to any CA in the "Trusted Root Certification Authorities" list. So theoretically an adversary, which is able to direct traffic to towards its own server, can get a certificate from another trusted CA, such as LetsEncrypt or Comodo, and impersonate the FortiGate.
  • The only way around this is to leave only our CA as trusted and delete any else from the list. But it means that the server can experience problems in other areas (such as browsing), and that Windows Update must be turned off (otherwise it will populate the list again).
  • The adversary still won't be able to perform full man-in-the-middle, as he cannot impersonate Windows machine to FortiGate (FortiGate does limit accepted certs to specific CAs).
  • The native FortiGate client software (FortiClient) has exactly the same problem.

4. Using pre-shared keys instead of certificates looks as natural solution for this, but unfortunately, it didn't work for me. Sporadically, the tunnel got established, but mostly it failed with authentication errors. I've found no logical explanation why. So certificates were the only option left.

No comments:

Post a Comment