VPS as a VPN Server with SoftEther

Setup a VPN Server Using LXD and Ubuntu 20

We assume that your VPS is the gateway connected to the Internet and the internal network, and the VPN container is a machine with LXD connected to the local network that has as a gateway the private address of your gateway (VPS server)

1. Configure aditional local network card:

From control panel go to:

Servers --> Select server --> Manage --> Network and RDNS --. Click on "Add local network"

After this it will look something like this:

Where: eth0 is a WAN nic eth1 is a LAN nic

oot@pacman:~# ifconfig -a eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet x.x.x.x netmask broadcast x.x.x.x inet6 fe80::216:3eff:fe5f:e994 prefixlen 64 scopeid 0x20 ether 00:16:3e:5f:e9:94 txqueuelen 1000 (Ethernet) RX packets 138035 bytes 118977575 (118.9 MB) RX errors 0 dropped 9 overruns 0 frame 0 TX packets 18971 bytes 1340779 (1.3 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

eth1: flags=4098<BROADCAST,MULTICAST> mtu 1500 ether 00:16:3e:16:58:a9 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet netmask inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

Create a bridge for your LAN and setup it

root@pacman:~# apt install bridge-utils -y

root@pacman:~# cat /etc/network/interfaces

auto lo iface lo inet loopback

auto eth0 iface eth0 inet static address xxx.xxx.xxx.xxx netmask xxx.xxx.xxx.xxx broadcast xxx.xxx.xxx.xxx network xxx.xxx.xxx.xxx gateway xxx.xxx.xxx.xxx

auto LAN iface LAN inet static address netmask broadcast network bridge_ports eth1 bridge_stp off bridge_fd 0 bridge_maxwait 0 root@pacman:~#

2. Setup a DHCP server for LAN

root@pacman:~# apt install isc-dhcp-server -y

And generate a basic configuration, to allow VPN clients to obtain an ip from the LAN

oot@pacman:~# cd /etc/dhcp/ root@pacman:/etc/dhcp# mv dhcpd.conf dhcpd.conf.old root@pacman:/etc/dhcp#

root@pacman:~# more /etc/dhcp/dhcpd.conf INTERFACES="LAN"; default-lease-time 600; max-lease-time 7200;

subnet netmask{ range; option routers; option domain-name-servers,; option domain-name "vpsvpn.net"; }

3.Initialize LXD

root@pacman:~# lxd init Would you like to use LXD clustering? (yes/no) [default=no]: Do you want to configure a new storage pool? (yes/no) [default=yes]: Name of the new storage pool [default=default]: Name of the storage backend to use (ceph, btrfs, dir, lvm, zfs) [default=zfs]: dir Would you like to connect to a MAAS server? (yes/no) [default=no]: Would you like to create a new local network bridge? (yes/no) [default=yes]: What should the new bridge be called? [default=lxdbr0]: What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: none Would you like LXD to be available over the network? (yes/no) [default=no]: Would you like stale cached images to be updated automatically? (yes/no) [default=yes] Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: root@pacman:~#

4. Create your VPN server

root@pacman:~# lxc launch ubuntu:20.04 vpn Creating vpn Starting vpn

5. Create a profile for VPN use the local network and setup the IP

By default the new container will use the default profile which looks like this:

oot@pacman:~# lxc profile show default config: {} description: Default LXD profile devices: eth0: name: eth0 network: lxdbr0 type: nic root: path: / pool: default type: disk name: default used_by: - /1.0/instances/vpn

We just copy this default profile and edit it to use the network card connected to the internal network

root@pacman:~# lxc profile copy default LAN

root@pacman:~# lxc profile edit LAN

config: {} description: Default LXD profile devices: eth0: name: eth0 nictype: bridged parent: LAN type: nic root: path: / pool: default type: disk name: LAN used_by: []

After you have the LAN profile as it looks, fit the profile container

root@pacman:~# lxc profile list +---------+---------+ | NAME | USED BY | +---------+---------+ | LAN | 0 | +---------+---------+ | default | 1 | +---------+---------+ root@pacman:~#

root@pacman:~# lxc profile assign vpn LAN Profiles LAN applied to vpn root@pacman:~# lxc profile list +---------+---------+ | NAME | USED BY | +---------+---------+ | LAN | 1 | +---------+---------+ | default | 0 | +---------+---------+ root@pacman:~#

6. Configure the network on VPN server

The ubuntu 20 installation on the container uses netplan (vpsserver uses the traditional interfaces file in /etc/network). Adapt the network configuration file to your needs...

root@pacman:~# lxc exec vpn bash

root@vpn:~# cat /etc/netplan/50-cloud-init.yaml

network: version: 2 ethernets: eth0: addresses: - gateway4: nameservers: search: [vpsvpn.net] addresses: [ ,]

root@vpn:~# root@vpn:~# netplan apply root@vpn:~#

root@vpn:~# ping PING ( 56(84) bytes of data. 64 bytes from icmp_seq=1 ttl=64 time=0.194 ms ^C --- ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.194/0.194/0.194/0.000 ms root@vpn:~#

Time to configure the access from the LAN to the Internet and from the Internet to our vpn server. Just mask the LAN to see the internet with the public address of our VPS and forward the vpn traffic from the internet to our VPN server. There are several ways to do this using iptables so we won't go into detail about it, personally I use fwbuilder[1], which I recommend for its ease and power.

7. Firewall rules

Just check that the NAT rules look like this:

root@pacman:~# iptables -t nat -L Chain PREROUTING (policy ACCEPT) target prot opt source destination
DNAT tcp -- anywhere pacman.localdomain tcp dpt:https to: DNAT udp -- anywhere pacman.localdomain udp multiport dports isakmp,l2f,ipsec-nat-t to: DNAT tcp -- anywhere pacman.localdomain tcp multiport dports http,https to:

Chain INPUT (policy ACCEPT) target prot opt source destination

Chain OUTPUT (policy ACCEPT) target prot opt source destination

Chain POSTROUTING (policy ACCEPT) target prot opt source destination
MASQUERADE all -- ! /* generated for LXD network lxdbr0 */ SNAT all -- anywhere to:

8. Install the VPN software in the container

Download the latest version of softether (vpn of easy use and unparalleled versatility) from https://www.softether.org/

root@vpn:~# wget wget https://www.softether-download.com/files/softether/v4.34-9745-rtm-2020.04.05-tree/Linux/SoftEther_VPN_Server/64bit_-_Intel_x64_or_AMD64/softether-vpnserver-v4.34-9745-rtm-2020.04.05-linux-x64-64bit.tar.gz

root@vpn:~# apt install build-essential -y

root@vpn:~# mv vpnserver/ /usr/local/

root@vpn:~# cd /usr/local/vpnserver/

root@vpn:/usr/local/vpnserver# make

After compilation, we enable the service for automatic start

root@vpn:/usr/local/vpnserver# vi /lib/systemd/system/vpnserver.service

[Unit] Description=SoftEther VPN Server After=network.target

[Service] Type=forking ExecStart=/usr/local/vpnserver/vpnserver start ExecStop=/usr/local/vpnserver/vpnserver stop

[Install] WantedBy=multi-user.target

root@vpn:/usr/local/vpnserver# systemctl enable vpnserver.service

root@vpn:/usr/local/vpnserver# systemctl start vpnserver.service

Now we just need to configure softether

9. Configuring softether

Download the SoftEther manager, run it. Click on new setting, choose the name you want and put the public ip of your VPS and click on ok (as it is the first time you connect the vpn server has no password set, it will ask you to put one). Once inside you will see a wizard, close it and go to IPSec / L2tp, there activate the first option l2tp on ipsec and change or take note of the pre shared key and click ok. Then go to Local Bridge Setting in virtual hub choose the default and the network card eth0 and click on Create Local Bridge option and verify that the status is operational.

Now double click on the virtual hub default, then Manage Users to create the users.

Configure the native client from iOS, android, windows or Mac. Enjoy!

[1]: https://github.com/fwbuilder/fwbuilder