What's new
  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

Tutorial Change Strongswan ciphersuite and enable MOBIKE to get rid of terrible VPN speeds

CB7

Occasional Visitor
-EDIT- I fixed this myself, see 2nd post in the thread. This thread is therefore marked as a tutorial now.

Hello,

Running merlin; but I believe this is a stock firmware thing? So posting here, sorry if wrong board.
I'm using the ASUS' built-in Strongswan (so enabling IPSEC VPN with IKEv2 in the ASUS admin panel) and its speeds are absolutely atrocious for some reason. (Eg: without VPN I have a downlink of 480MBit/sec and 25MBit/sec up on 5G; but with VPN enabled it's only 43MBit/sec down and 5MBit/sec up. (Ref: I have 1000/1000 symmetric fiber and speedtests at the home connection are 800MBit/sec on average (up/down), so that's not the problem)). I didn't have this issue when running it on a standalone virtual machine, so looking in to that now.

However; upon analyzing its config, I realized this is part of ASUS stock firmware and therefore I probably don't have unlimited freedom with modifying the configuration.
As such I have two questions I hope someone may be able to answer:

1.) MOBIKE is disabled, does anyone know of any objection against enabling it on ASUS routers?
2.) I noticed the ciphersuite in use is deprecated and not the best for performance. It is using "aes256-sha1-modp1024" which is both a crappy hashing algorithm as well as poor DH groups. I'd prefer using ChaCha20 but I'm not sure if that's a good fit for the ASUS hardware, so I suppose aes256-sha256-modp2048 would have to do; or maybe for performance reasons go for aes256-sha256-ecp256 instead. I was also wondering for this one if anyone knows if there are any major objections in to doing so or that it should be smooth sailing. (Or maybe someone tried something different already, please do tell. :))

Hope its not too much of a niche question. Thanks in advance! :)

-edit-
Ah... As it turns out, the router keeps resetting this file whenever it reboots. :(
-edit2- Fixed the above problem. See post below.
 
Last edited:
Alright, so revisiting this anyway as I couldn't live with the terrible speeds I was getting from the IKEv2 on my AX3000Gv2:
- The first thing I did was enable MOBIKE as this improves stability AND allows for much easier transition between 5G and WiFi (or when roaming: different carrier).
- I modified the DPD settings to be a.) less aggressive (so less overhead), b.) try to re-establish connection instead of clearing the peer immediately.
- I changed the ciphersuites. The ciphers are based around ChaCha20 which is very lenient on CPU, very fast and considered highly secure. I forced the same type on ESP to ensure consistency and similar speed on that front.

This increased the speed on 5G<>VPN from an average of ~30MBit/sec up/down to an average of ~90MBit/sec up/down (with peaks to 130MBit, where before 30 was the max I could squeeze out of it). This is still nowhere near the ~900MBit/sec on average I get on WiFi and the +/- ~300MBit/sec average I do on 5G without the VPN enabled: but at least now its an acceptable speed, lower latency and for me this is more than ample speed for daily usage on my iPhone.

If you wish to do the same and make it permanent, here is what I did:

In the "conn Host-to-Netv2" section of /tmp/etc/ipsec.conf, modify the following variables to read like this:
Code:
  mobike=yes
  ike=chacha20poly1305-prfsha256-curve25519
  esp=chacha20poly1305
  dpdtimeout=30s
  dpdaction=restart
  dpddelay=10s
You can open the file with nano (nano /tmp/etc/ipsec.conf), make the changes and then save & exit with CTRL+X.
(Note that "esp", contrary to the other variables, will not be defined already. Its a new addition to ensure consistency in ciphers; so copy/paste that in below the ike variable. Manually change the rest.)
(Note2: if you so happen to have an ASUS router with AES-NI (hardware acceleration for AES), then I'd suggest using aes256-sha256-ecp256 for ike and aes256gcm128 for esp instead of ChaCha20.)
If you want to test the new configuration, run command: ipsec stop && sleep 2s && ipsec start

To make it permanent and survive a reboot, following changes were made (note: this assumes you already have the /jffs/configs and /jffs/scripts directories):
after making the changes to ipsec.conf described above, do the following:
Run command: cp /tmp/etc/ipsec.conf /jffs/configs/ipsec.conf
Run command: touch /jffs/scripts/strongswan.sh && chmod +x /jffs/scripts/strongswan.sh
Then: nano /jffs/scripts/strongswan.sh and input:
Bash:
#!/bin/sh

#Stop StrongSwan and wait a second to be sure the process exited cleanly
ipsec stop
sleep 1s

#Replace the bad default ipsec.conf with the proper copy and wait a second to ensure the operation completed
echo > /etc/ipsec.conf
cp -f /jffs/configs/ipsec.conf /tmp/etc/ipsec.conf
sleep 1s

#Start StrongSwan again to get going
ipsec start
Then, Run command: echo "/bin/sh /jffs/scripts/strongswan.sh # Modify ipsec.conf to ChaCha20 and enable MOBIKE" >> /jffs/scripts/post-mount

That's it. Your ciphersuite is now changed to use ChaCha20, MOBIKE is enabled and the changes will be made permanent and survives a reboot of the router. (Well it doesn't exactly survive, rather: jffs scripts will undo the damage done by a reboot. ;))
If anyone has a better way of of doing this, please feel more than free to chime in.

Now, sometimes when the router changes settings (not necessarily related to the VPN itself) it will revert ipsec.conf to its default values as well without a reboot. Quite annoying. JFFS only fixes the ipsec.conf after a reboot, but not at any other time so it won't recover until the next reboot OR a manual intervention. To fix that, we'll create a cronjob.

Create file: nano /jffs/scripts/strongswancron.sh
Input the following:
Bash:
#!/bin/sh

# Define the pattern to search for
PATTERN="chacha20poly1305-prfsha256-curve25519"

# Check if /etc/ipsec.conf contains the pattern
if grep -q "$PATTERN" /etc/ipsec.conf; then
    # Pattern found, no action required
    # Unhash line below for debugging
    # echo "$(date): IPSEC DEBUG No action taken." >> /var/log/cron.log
    exit 0
fi

# Proceed if the pattern is not found
ipsec stop
sleep 1s

# Clear and update ipsec.conf
echo > /etc/ipsec.conf
cp -f /jffs/configs/ipsec.conf /tmp/etc/ipsec.conf
sleep 1s

# Restart IPsec service
ipsec start

# Log the action for traceability
echo "$(date): Found missing ChaCha20 policy. Configuration updated and IPsec restarted." >> /var/log/cron.log
NOTE: if you're using aes256-sha256-ecp256 because you have a more powerful router with dedicated AES chip, change the pattern to "aes256-sha256-ecp256".
CTRL + X to save.
Then run command: chmod +x /jffs/scripts/strongswancron.sh

Then, create the cronjob:
Run command: nano /jffs/scripts/services-start
Insert this at the end:
Code:
cru a ipsec_check "*/5 * * * * /jffs/scripts/strongswancron.sh"
(Change at will. This check currently runs every 5 minutes, every hour, every day. Should be moooooore than enough, the config should hardly ever be overwritten at times other than reboot. If anything, you may wish to consider running this less frequently; not more frequently.)
CTRL + X to save.

The first time, either reboot the router or manually run this command to activate the cronjob: cru a ipsec_check "*/5 * * * * /jffs/scripts/strongswancron.sh"

That's it, the router will now check every 15 minutes whether or not the ipsec.conf is "faulty" and no longer contains ChaCha20. If it does contain the correct ciphersuite: it does absolutely nothing. Doesn't write any logs either, that's useless. If it finds a bad configuration: it forcefully updates and then writes a line to /var/log/cron.log.
 
Last edited:
Please be advised that in my post above from the 18th of December, I erroneously wrote to modify "/jffs/services-start". This should have been "/jffs/scripts/services-start". (Modified now). If you used the above tutorial before this was changed, please double-check if you have it in the wrong or right location and thus whether or not you cronjob is being setup properly at boot time. Apologies for the inconvenience, if any was caused.
 
I'd be curious if you could share the advantages you see to using IKEv2 over Wireguard. After I got over the fact that I needed an app instead of built-in Android functionality, I haven't looked back.
 
I'd be curious if you could share the advantages you see to using IKEv2 over Wireguard. After I got over the fact that I needed an app instead of built-in Android functionality, I haven't looked back.

The need for an app is exactly the problem. :) With IKEv2 I can simply push a configuration profile to our iPhone's and iPad's that forces an always-on VPN on an OS-level. As soon as we lose connection to the home WiFi: the device will setup the VPN tunnel immediately and blocks all traffic that attempts to bypass the VPN. (Some of the advantages of doing that are: access to resources at home, enjoying AdGuard + private DNS (incl. blocking DoH), enjoying the firewall rules, even when abroad the connections to outside services stem from our home country, reduces tracking ability, connection is always encrypted from the PoV of the network the device connects to, etc. etc.) The trigger to disable the VPN is connecting to home WiFi. (So VPN stays enabled also on other WiFi-networks, and thanks to MOBIKE this transition is seamless with zero connection loss (tunnel and all connections survive the switch to a different network so to say)). It is also possible to manually disable it. (This can be blocked, but being able to do so is rather handy in case home network goes down and your phone refuses to connect to anything until the VPN tunnel is re-established.)

I cannot achieve this type of functionality (reliably) with WireGuard.
 
Thanks for the information! I am not familiar with the apple devices, but VPN apps like Wireguard in Android can be enabled as "always on" vpn and internet blocking when down. I never tested Wireguard reliability, particularly when switching from wifi to mobile, so I can't comment on that. But I do think many of the other benefits you mentioned come with any vpn connection to the home network. Wireguard speeds tend to be faster than the ones you quoted for IKE2, so that is one benefit in that column. Thanks again
 
Wireguard speeds tend to be faster than the ones you quoted for IKE2, so that is one benefit in that column.

Yes, I recently found out why that's happening. For some reason packets larger than 1252 bytes appear to be dropped and don't make it through the tunnel, so there's probably tons of packet fragmentation going on that severely impacts the throughput speeds. But so far I've been unable to remediate this as Strongwan doesn't support changing MTU for the tunnel (expects the interface to define it) and the ASUS implementation prevents you from changing it on a dedicated tunnel interface. (There doesn't appear to be one) So I'm a bit stuck. I don't understand yet why everything breaks when larger than 1252 to begin with as that's pretty damn low, but it wouldn't really be a problem if I can just specify a different MTU. Come to think of it, maybe I can do that in the profile sent to the devices - but I doubt it.
 
I suspect the speed limits are coming from the high latency of your 5G connection, particularly if it is TCP traffic you are sending through the tunnel.
 
I suspect the speed limits are coming from the high latency of your 5G connection, particularly if it is TCP traffic you are sending through the tunnel.

Thanks for chiming in - appreciate that :) This is exactly what I thought at first as well, but the thing is: the 5G connection is actually decent with very acceptable latency. To demonstrate (average values after 3 consecutive tests with 1 minute waiting time in between):

Speedtest 5G:
- Down: 376Mbps (peak: 402),
- Up: 97Mbps (peak: 101)
- Latency: 15ms
Its pretty consistently hovering around these numbers.

Speedtest 5G after enabling VPN:
- Down: 108Mbps (Peak: 112)
- Up: 72Mbps (Peak: 80)
- Latency: 25ms

Note1: this is using speedtest.net, using the exact same mirror and provider as the landline. (Landline + 5G = same provider for me.) The 10ms extra latency whilst it has to go phone->tower->home->server->home->tower->phone is very reasonable overhead imho, I wouldn't call it high latency. (For gaming maybe, but even 25ms is perfectly acceptable there.)
Note2: this is only after changing the ciphersuites and config as explained in the post above. When using the default ASUS settings, I can praise $deity; if I can squeeze more than 35MBit down out of it.

To me the speeds are acceptable as it's more than plenty enough to do everything I want on my phone including 4K+HDR streaming, so its not a very big deal...
... However, the download speeds only reaching 30% of the throughput I get on 5G with the VPN disabled cannot go unnoticed and I can't quite stand it. ;) A 70% performance hit is insane. The only possible culprit I've been able to identify is that there's a high chance of packet fragmentation occurring due to the small max. packetsize it appears to be dealing with. And (unexpected) packet fragmentation would certainly explain the drop in performance as that introduces a major amount of overhead. And of course, mind you, this is on a decent 5G connection. When I'm in an area with low reception or congestion, where without VPN I only get ~25MBit/s for example, the speeds on the VPN are atrocious at maybe 5 to 8MBit down and it becomes less acceptable, heh!

I suppose I could try and put this theory to test by disabling VPN on the ASUS and instead spinning up a Virtual Machine with IKEv2 IPSEC on the NAS and port-forward it through the ASUS and see what happens to throughput speeds and packet fragmentation there (and what happens when changing MTU on the eth interface). That or maybe introduce clamping on the ASUS iptables, but that's... A level of copulationery that I'm not quite well versed enough in to do with confidence.

-edit-
1.) Forgot to say: the connection at home is 1000/1000 symmetric (though I typically "only" get about 920/850 in speedtests), so plenty of room there
2.) I deployed WireGuard as a means of testing: the throughput was slightly higher for the download speeds at ~140Mbps average (compared to 108MBps average on the earlier IKEv2 test). That's better, but not so much significantly better that I want to deal with switching protocol or dealing with the lack of native support. :)
3.) Tried introducing MSS clamping, had no effect - so I suppose fragmentation might not be the issue. (Or the clamping rule was applied wrong, lol. I applied it to the FORWARD chain with source IP being my VPN client IP's)
 
Last edited:
Is it possible that your 5G provider is doing DPI and limiting the bandwidth of your VPN connection?
 
Speedtest 5G:
- Down: 376Mbps (peak: 402),
- Up: 97Mbps (peak: 101)
- Latency: 15ms
Its pretty consistently hovering around these numbers.

Speedtest 5G after enabling VPN:
- Down: 108Mbps (Peak: 112)
- Up: 72Mbps (Peak: 80)
- Latency: 25ms

If you're on 5G-Fixed Wireless - consider dropping the MaxMTU on the WAN interface a bit when using any kind of VPN...
 

Similar threads

Latest threads

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!

Staff online

Back
Top