I won’t start out with a bad mouthing, we’ll get to that later. Overall, I’ve been incredibly happy with Fortigate’s hardware products, especially the amazing suite of features they pack into the lower end ones. For example, even the little baby 30D personal firewall that you can pick up for a couple hundred dollars can be a home office firewall, router (for internal networks too), can do per-interface configuration instead of working like a switch (if you want that), IPS, anti-virus, web filtering in proxy mode, trunk ports with VLAN tagging, 802.1x, wireless, wifi and even provide a PoE port. If you can get by with just Ethernet and wifi, it’s like having four times the features of a Cisco 1941W, and many times the packets per second throughput, for a tenth the price. Going up to the 60D gets you a nicer metal unit with much greater throughput, more ports, and it removes some limitations, such as the five VLANs per physical port limit the 30D has.
Anyway, on to VPN’s. I ran into some issues while trying to get things going so figured I’d outline all the currently possible things you can do and the road blocks I ran into. The primary problem I had was expecting modern VPN clients to support modern encryption and authentication protocols. The secondary problem I had was expecting Fortinet to do the same thing on all platforms they support. For example, I set my firewall to only accept AES256/SHA256 VPN sessions since I knew the FortiClient I was experimenting with on Windows supported this. They certainly don’t support those on several other client options, so you have to downgrade your security to the lowest common denominator.
If you don’t feel like reading further, the quick summary is that if you need to support users/devices of all types, on IPSec tunnels, not L2TP, is your VPN definition on the FortiGate side should have the following setup:
- Phase 1 should be, in order: AES256-SHA256, AES128-SHA1 and DH Groups 2, 5 and 14 enabled.
- Phase 2 should be, in order: AES256-SHA256, AES256-SHA1, AES128-SHA1 and DH Groups 2, 5 and 14 enabled.
If you do feel like getting into the nitty gritty, how about a nice table to outline things followed by all the caveats:
|Client||Best Encryption||Best Authentication||Supported DH Groups|
|Fortigate to Fortigate (i.e. site to site vpn)||AES256||SHA256, 384, 512||Any|
|FortiClient on Windows 7+||AES256||SHA256, 384, 512||14, 5, 2, 1|
|FortiClient on MacOS 10.10+ (Build 22.214.171.1240)||Phase 1: AES128
Phase 2: AES256
|Phase 1: SHA1
Phase 2: SHA256, 384, 512
|Phase 1: 2
Phase 2: 5
|FortiClient on Android (unusable on 4.4.x, see caveat 1 below)||AES128||SHA1||14, 5, 2, 1|
|Native (Cisco) IPSec Client on iOS 8.3||AES256||SHA1||2|
|Native Android 4.x L2TP over IPSec||FAILURE – see caveats 1 & 2 below|
|Native Android 5.x||Not yet tested|
Caveats from the above table:
- The first caveat to using FortiClient on Android is that you cannot be using an Android 4.4.x device on Verizon’s 4G LTE service. Verizon 4G LTE uses carrier grade NAT (CGN) behind the scenes so your phone may appear to have a relatively stable public IP, but internally to their network, there’s really a bunch of private 10.0.0.0/8 addresses in use which will prevent return UDP IPSec packets from reaching your phone from the FortiGate firewall. This behavior will also occur whether you have NAT Traversal (NAT-T) enabled or not. Attempting to use VPN will produce what appears to be a working connection, data will be flowing, and about ten seconds in, your VPN will drop inexplicably. The FortiGate logs will confirm this is due to Dead Peer Detection not being able to reach the remote VPN client and dropping the SA. If you turn DPD off, the same thing will occur, but then you’ll end up with an ‘active’ VPN session hanging around on the firewall side not knowing your client is no longer reachable, so don’t do that.
As best I can tell, this is an Android 4.4.x issue. The same behavior, on the same Verizon network, does not occur on Android 5+ or Android <4.4. It also does not occur on Windows or MacOS devices using a Verizon VL600 USB cell modem. It also does not occur on Verizon 4G iOS devices. Why does this really matter here in 2015? Well, that's because Verizon enjoys fucking their customers over with locked devices they never release updates for. For example, I'm blessed with their current 'flagship' phone, the Droid Turbo. It has a miraculous battery and great CPU, but nine months after release, is still running 2013-era Android 4.4.4 because the "Android 5.0 coming soon" that was promised in fall of 2014 when the phone came out has yet to materialize. They also won't give access to the boot loader and no one has yet to figure out how to root this phone yet. Same issue for many of their other phones, but at least some of them can be rooted.
There’s an open bug for this that Google has been ignoring for 18 months; I encourage you to go blast them there, in hopes they do something:
And a long thread in Verizon’s user forums since it’s mostly affecting Verizon users thanks to their boot locked and ancient version bullshit: https://community.verizonwireless.com/thread/826624?tstart=0
Here’s what you’ll see in the debug logs:
ike 0:TEST-VPN_0:524: send IKEv1 DPD probe, seqno 1 ike 0:TEST-VPN_0:524: sent IKE msg (R-U-THERE): 192.0.2.1:4500->192.168.0.1:8708, len=92,... ike 0:TEST-VPN_0: NAT keep-alive 70 192.0.2.1->192.168.0.1:8708. ike 0:TEST-VPN_0:524: sent IKE msg (keepalive): 192.0.2.1:4500->192.168.0.1:8708, len=1, id=ff00000000000000/0000000011000000:14000000 ike 0:TEST-VPN_0: link is idle 70 192.0.2.1->192.168.0.1:8708 dpd=1 seqno=1 ike 0:TEST-VPN_0: link fail 70 192.0.2.1->192.168.0.1:8708 dpd=1 ike 0:TEST-VPN_0: link down 70 192.0.2.1->192.168.0.1:8708 ike 0:TEST-VPN_0: deleting ike 0:TEST-VPN_0: flushing ike 0:TEST-VPN_0:524: send IPsec SA delete, spi c2404820 ike 0:TEST-VPN_0: delete dynamic ike 0:TEST-VPN_0: reset NAT-T ike 0:TEST-VPN_0: deleted
- With the above issues of NAT-T / CGN / DPD and FortiClient occurring, before I realized it was an Android 4.4.4 issue, I thought my problem of dropping VPN was a FortiClient issue so I began experimenting with the built-in L2TP over IPSec VPN offering that Android has. I could not even bring the session up in that configuration. The most critical-looking errors on the Fortigate side were:
avp_wrong_length()-214: avp 1 is incorrect size. expecting 8, got 10 L2TPD 90: 597:Peer did not specify mandatory AVP. Aborting call. Error: Fatal error in AVP handling.
Online searches suggest that Android 4.4.x’s L2TP client is broken and 5.x fixes this. However, the logs that a Fortigate spits out when in “diagnose debug application l2tp -1” mode also suggest that Fortigate may be secretly bundling OpenSwan/xl2tpd as their L2TP/ipsec solution, because that same ‘avp_wrong_length’ error can be found all over OpenSwan forum/mailing list posts. I also found references that this issue can also be resolved when going to OpenSwan 2.6.25 or later. So, this might be an Android bug, but possibly could also be fixed by Fortinet if they are indeed using OpenSwan/xl2tpd internally and aren’t up to date. I’m not spending additional time on it either way since I know Android 4.4.4 has a broken VPN implementation regardless.
As you can see, the options range from great (FortiClient on Windows) to horrible (FortiClient on Android) when it comes to support and authentication/encryption protocols. I have no idea why Fortigate has not yet updated the MacOS client to work like the Windows one since it seems to be fairly well developed, and I also have no idea why they haven’t produced a working iOS IPSec client. You’d think they would not like having their users see the Cisco name every time they bring up a VPN session, and it would be nice to get the FortiClient’s other benefits on the iOS side, like end point control.
Some additional helpful notes:
- Make sure to enable dead peer detection in your phase 1 settings after creating your tunnels on the Fortigate side. The wizard may or may not enable that by default. Without it, your VPN clients may be unable to reconnect after disconnecting because the Fortigate thinks the session is still up. This is mostly an issue on some Apple clients where Apple stupidly doesn’t send a delete SA when bringing down the tunnel, and on users stuck with Android 4.4.x on Verizon 4G service.
- If you’re using FortiToken for two factor authentication, and you’re connecting from something other than Windows or Android FortiClient which will prompt you for the token at the appropriate time, the way to do that is to simply append the token to your normal password when connecting.