Page 1 of 1

Linux always-on VPN client (starting dhclient automatically)

Posted: Wed Jun 17, 2020 7:10 pm
by riny
I just want to share a configuration for a Linux host with an always-on SoftEther client. As everyone knows, the Windows client automatically handles DHCP and routing, but the Linux client does not. The documentation recommends that you manually start dhclient and make the necessary routing table changes after connecting. But this clearly doesn't work for non-interactive startup.

I'm doing this on an Ubuntu server and I spent a long time trying to get netplan (and/or NetworkManager directly) to own the SoftEther interface, but I just couldn't get it to work. So instead I created a systemd unit file to start dhclient automatically with SoftEther. Then I made my VPN connection a "startup connection" in the VPN client config. Now SoftEther automatically connects on startup, and dhclient starts right after.

This depends on using the bundled softether-vpnclient.service in the latest releases on github. Use make -C tmp && make -C tmp package to build an OS-specific package (rpm or deb) which includes this, and systemd enable softether-vpnclient.service so it always starts on reboot.

Here's the unit file for dhclient. Install this as /lib/systemd/system/dhclient-vpn.service and then use systemd enable dhclient-vpn.service to enable it.

Code: Select all

[Unit]
Description=DHCP Client for SoftEther VPN
After=softether-vpnclient.service
Requires=softether-vpnclient.service
PartOf=softether-vpnclient.service

[Service]
Type=forking
ExecStart=/sbin/dhclient -v vpn # <--- Use the name of your VPN interface here
ExecStop=/sbin/dhclient -v -r vpn
Restart=always
RestartSec=30

[Install]
WantedBy=multi-user.target
Now there's the question of the routing table modifications. Personally I did this in my DHCP server using DHCP option 121, so clients automatically get the routes they need and manual routing table entries are never needed. This setup is a little more complex but I can post more details if anyone is interested.

Re: Linux always-on VPN client (starting dhclient automatically)

Posted: Tue Jun 23, 2020 6:51 am
by AleXSR700
Hello @riny

I would really be interested in this.

I am currently away on business and was once again reminded how good it would be to have a proper VPN server at home.
So when I get back I will build a SoftEther server on a Raspberry Pi 4 B and then also a SoftEther client, again on a RasPi 4 B.

Both should auto-start after reboot. And the client one should also automatically start an AP as well. So it acts as an AP with permanent VPN connection.

Your approach, I believe, will help achieve this :-)

Re: Linux always-on VPN client (starting dhclient automatically)

Posted: Thu Jun 25, 2020 10:41 pm
by riny
That's a clever idea! Well this gives you the client side of things. For the server side, see this link. Make sure you read and understand that, because this builds on it.

The only thing not covered there is the routing. Once you start DHCP, you still need to manually add routes through the VPN. I use dnsmasq for DNS on my home network with this setup:
  • Main network: 10.0.0.0/16, default gateway 10.0.1.2; VPN server running on 10.0.0.111
  • VPN network: 10.1.1.0/24, default gateway 10.1.1.1 (the inside address in the VPN namespace)
Inside the VPN namespace, I use dhcrelay to forward DHCP out to my main network. dhcrelay is started with this command-line:

Code: Select all

/usr/sbin/ip netns exec vpn /usr/sbin/dhcrelay 10.0.0.3 -a
10.0.0.3 is the address of my DHCP server running dnsmasq, and the "-a" option is important so dnsmasq can identify requests from VPN clients.

Here's the relevant snippet from my dnsmasq config:

Code: Select all

dhcp-match=set:vpn,option:agent-id
tag-if=set:int,tag:!vpn

dhcp-range=tag:int,10.0.0.80,10.0.0.99,4h
dhcp-option=tag:int,121,10.1.1.0/24,10.0.0.111
dhcp-option=tag:int,249,10.1.1.0/24,10.0.0.111
dhcp-option=tag:int,option:router,10.0.1.2

dhcp-range=tag:vpn,10.1.1.50,10.1.1.200,255.255.255.0,2h
dhcp-option=tag:vpn,121,10.0.0.0/16,10.1.1.1
dhcp-option=tag:vpn,249,10.0.0.0/16,10.1.1.1
dhcp-option=tag:vpn,option:router,10.1.1.1
The first block says to look at the agent-id option (set by dhcrelay -a) and tag requests as either "int" or "vpn" based on whether that option is set. Internal clients get classless static routes into the VPN through SoftEther, and VPN clients get routes into the main network.

I'm only routing local traffic so there's no default gateway set. If you want ALL traffic to go through the VPN, then you could add a 0.0.0.0/0 route to the tag:vpn section.

Re: Linux always-on VPN client (starting dhclient automatically)

Posted: Fri Jul 31, 2020 12:28 am
by delation44
Thank you so much for sharing this, I wonder what is difference between this and adding a script file in /etc/init.d/vpnserver

Re: Linux always-on VPN client (starting dhclient automatically)

Posted: Fri Jul 31, 2020 3:53 am
by riny
Happy to help! An init script (or a systemd unit, if you're using systemd) can easily start the vpnserver. However, like it says right at the top:
riny wrote:
Wed Jun 17, 2020 7:10 pm
the Windows client automatically handles DHCP and routing, but the Linux client does not. The documentation recommends that you manually start dhclient and make the necessary routing table changes after connecting. But this clearly doesn't work for non-interactive startup.
So if you use an init script to start the vpnserver, you'll find that it's up and connected, but you have a VPN interface with no IP address or routes. So SoftEther will be connected internally but you'll have no way to make use of that connection.

Since posting all of this though, I've got an even better option. Normally there are other OS-level services (like NetworkManager) that handle this thing for you, but I couldn't get any of them to work for SoftEther. This is because the vpnserver wasn't properly managing the up/down state of the interface. This was corrected by this change.

Now if you build the latest release from github, you can use netplug (available pre-built for most distributions) and ifupdown to manage the interface for you, and you don't have to do any of do anything with dhclient. I still can't get NetworkManager to do it but this works just fine, and it recovers automatically if the VPN connection goes down for any reason. For example:

Code: Select all

# cat /etc/netplug/netplugd.conf
vpn

# cat /etc/network/interfaces
allow-hotplug vpn
iface vpn inet dhcp

Re: Linux always-on VPN client (starting dhclient automatically)

Posted: Sat Aug 01, 2020 2:57 pm
by delation44
Thanks a lot riny.
should I remove the old one and install it from Github?
you should definitely write a blog post about new installation method. because many installation guide is old.

Re: Linux always-on VPN client (starting dhclient automatically)

Posted: Sat Aug 01, 2020 9:34 pm
by riny
Yeah unfortunately the earlier method had some shortcomings. It mostly worked fine but wouldn't always reconnect properly after the VPN connection was dropped, e.g. due to a network outage or a reboot on the server side. This method is much more reliable. I'll work on getting it all together in one write-up!

Re: Linux always-on VPN client (starting dhclient automatically)

Posted: Sun Aug 02, 2020 2:12 am
by delation44
That would be really great and help many, please also explain about compatibility with firewalld and https://www.vpnusers.com/viewtopic.php?f=7&t=66091

Thank you so much

Re: Linux always-on VPN client (starting dhclient automatically)

Posted: Tue Sep 22, 2020 5:42 am
by rihtik123
Better believe it shockingly the previous strategy had a few deficiencies. It generally worked fine yet wouldn't generally reconnect appropriately after the VPN association was dropped, for example because of an organization blackout or a reboot on the worker side. This technique is considerably more solid. I'll deal with getting everything together in one review!