The suggested solutions are to (a) add a dedicated physical interface, which is usually impractical; or (b) create a TAP device, but there are no good instructions on how to do this, and personally I wasn't able to get it working.
I do have a solution though, using IP namespaces. This should be supported on any modern Linux variant. The PRO of this approach is that the VPN server runs in its own IP space and you have full control of what traffic goes in and out. The CON is that you don't get direct L2 connectivity to your LAN; your VPN clients get private IP addresses, and all traffic is NATed by the server.
The concepts are explained well in this article. I got a lot of the inspiration from there, and adapted it to work with SoftEther.
To start, you'll need to choose addresses for the VPN's private network. Personally, I use:
- 10.1.1.0/24: Private network for VPN server and clients
- 10.1.1.1: Address for the server from inside the private network
- 10.1.1.2: Address that SoftEther listens on inside the private network
- 10.1.1.3: Address that SoftEther uses for its own NAT with VPN clients
- 10.1.1.10-10.1.1.200: DHCP range for VPN clients
Code: Select all
ip netns add vpn
ip link add vpneth0 type veth peer name br-vpneth0
ip link set vpneth0 netns vpn
ip netns exec vpn ip addr add 10.1.1.2/24 dev vpneth0
ip link add name vpnbr type bridge
ip link set vpnbr up
ip link set br-vpneth0 up
ip netns exec vpn ip link set vpneth0 up
ip link set br-vpneth0 master vpnbr
ip addr add 10.1.1.1/24 brd + dev vpnbr
ip netns exec vpn ip route add default via 10.1.1.1
sysctl -qw net.ipv4.ip_forward=1
iptables -A PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 10.1.1.2:443
iptables -A POSTROUTING -s 10.1.1.0/24 -j MASQUERADE
ip netns exec vpn vpnserver start
- Create a new namespace called "vpn"
- Create a virtual ethernet pair and move one virtual interface into the vpn namespace
- Add an IP address to the virtual interface in the vpn namespace
- Create a bridge allowing traffic to flow between the namespaces
- Add an IP address to the virtual interface in the root namespace
- Add a default route from within the vpn namespace, going out over the bridge
- Set up iptables to forward inbound connections on port 443 into the vpn namespace
- Set up iptables to do NAT on all outbound connections originating from the vpn namespace
- Start SoftEther running inside the vpn namespace
You can verify that everything is working correctly by looking at the addresses in both namespaces and attempting an external connection from inside the vpn namespace:
Code: Select all
# ip a
# ...
90: br-vpneth0@if91: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master vpnbr state UP group default qlen 1000
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff link-netns vpn
92: vpnbr: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
inet 10.1.1.1/24 brd 10.1.1.255 scope global vpnbr
valid_lft forever preferred_lft forever
# ip netns exec vpn ip a
# ...
91: vpneth0@if90: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1986 qdisc noqueue state UP group default qlen 1000
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.1.1.2/24 scope global vpneth0
valid_lft forever preferred_lft forever
inet6 fe80::xxxx:xxxx:xxxx:xxxx/64 scope link
valid_lft forever preferred_lft forever
# ip netns exec vpn ping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=53 time=17.8 ms
...
Then in your Virtual Hub setup, go to Virtual NAT and Virtual DHCP Server. Enable SecureNAT and use the following settings:
Code: Select all
Virtual Host's Network Interface Settings:
IP Address: 10.1.1.3
Subnet Mask: 255.255.255.0
Virtual DHCP Server Settings:
Use Virtual DHCP Server Functions: checked
Distributes IP Addresses: 10.1.1.10 to 10.1.1.200
Subnet Mask: 255.255.255.0
Options Applied to Clients:
Default Gateway Address: 10.1.1.1
DNS Server Address: (set to your desired DNS server)
To shut down SoftEther, use this script to stop the server and clean up:
Code: Select all
ip netns exec vpn vpnserver stop
ip link del vpnbr
ip netns del vpn