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 255.255.252.0 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 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10
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 10.10.200.1 netmask 255.255.255.0 broadcast 10.10.200.255 network 10.10.200.0 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 10.10.200.0 netmask 255.255.255.0{ range 10.10.200.150 10.10.200.240; option routers 10.10.200.1; option domain-name-servers 1.1.1.1, 8.8.8.8; 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
root@pacman:~#
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: - 10.10.200.2/24 gateway4: 10.10.200.1 nameservers: search: [vpsvpn.net] addresses: [1.1.1.1 ,8.8.8.8]
root@vpn:~# root@vpn:~# netplan apply root@vpn:~#
root@vpn:~# ping 10.10.200.1 PING 10.10.200.1 (10.10.200.1) 56(84) bytes of data. 64 bytes from 10.10.200.1: icmp_seq=1 ttl=64 time=0.194 ms ^C --- 10.10.200.1 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:10.10.200.2
DNAT udp -- anywhere pacman.localdomain udp multiport dports isakmp,l2f,ipsec-nat-t to:10.10.200.2
DNAT tcp -- anywhere pacman.localdomain tcp multiport dports http,https to:10.10.200.3
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 -- 10.150.205.0/24 !10.150.205.0/24 /* generated for LXD network lxdbr0 */
SNAT all -- 10.10.200.0/24 anywhere to:185.144.157.178
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