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.
- Install the RRAS role.
- Go to Administrative Tools, run the "Routing and Remote Access" console:
- 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 (10.20.20.0/24) and on the FortiGate itself (192.168.0.1/32). 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:
config vpn certificate ca
edit OurRespectedCA
set ca "-----BEGIN CERTIFICATE-----
MIIDLjCCAhagAwIBAgIQNGhB9lMumqdIrn3YFI+EWDANBgkqhkiG9w0BAQsFADAX
...
1tAuWASUPRvwqDzvt7ZtUXDxaGFqh3i3YpasbHRdnlmeFCVG82eIS18ajDBSVrDe
lHU=
-----END CERTIFICATE-----"
set range global
set source user
set trusted enable
set scep-url ''
set source-ip 0.0.0.0
next
end
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
next
end
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 fortigate.dns.name
set peer Windows2016
set ipv4-start-ip 192.18.0.2
set ipv4-end-ip 192.18.0.2
next
end
config vpn ipsec phase2-interface
edit IKEv2
set phase1name IKEv2
set proposal aes256-sha1
set pfs disable
next
end
Notes:
- "set type dynamic" means that connection from any IP address will be accepted. We need this, because otherwise we cannot assign the tunnel address (192.168.0.2) 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.
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 192.18.0.1 255.255.255.255
set allowaccess ping
set type tunnel
set remote-ip 192.18.0.2 255.255.255.255
set interface wan1
next
end
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 10.10.10.0 255.255.255.0
set device IKEv2
next
end
That's it. Mischief managed. :-)
Limitations:
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.
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 fortigate.dns.name 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 fortigate.dns.name 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