There are many choice for OpenSource VPN Server:
- Point to Point Tunneling Protocol (PPTP)
- L2TP (Layer 2 Tunneling Protocol)
- SSTP
- OpenVPN
- IPSec
- IKEv2
From the list above, OpenVPN is preferred.
OpenVPN installation preparation
Cek IP Address
$ ifconfig or $ ip a
Download OpenVPN installation file
$ wget https://git.io/vpn -O openvpn-install.sh
Change the script as executable
$ chmod +x openvpn-install.sh
Run the installer
$ sudo ./openvpn-install.sh
Choose the IP Add
Welcome to this OpenVPN road warrior installer! Which IPv4 address should be used? 1) 172.x.x.215 2) 172.x.0.1 3) 172.x.0.1 IPv4 address [1]: This server is behind NAT. What is the public IPv4 address or hostname? Public IPv4 address / hostname [x.x.x.x]: Which protocol should OpenVPN use? 1) UDP (recommended) 2) TCP Protocol [1]: UDP is recommeded but i choose TCP since i want to use the link all the time. UDP will not have any mechanism to retry or reconnect. at the end of this session i will share the log file when i use UDP then decide to use TCP. What port should OpenVPN listen to? Port [1194]: Select a DNS server for the clients: 1) Current system resolvers 2) Google 3) 1.1.1.1 4) OpenDNS 5) Quad9 6) AdGuard DNS server [1]: We can put any name here Enter a name for the first client: Name [client]: rasp OpenVPN installation is ready to begin. Press any key to continue... After OpenVPN Server installed you will get rasp.ovpn in /root directory. copy it to home directory
check the status
$ sudo systemctl status openvpn-server@server.service ● openvpn-server@server.service - OpenVPN service for server Loaded: loaded (/lib/systemd/system/openvpn-server@.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2021-03-11 23:36:52 WIB; 2 days ago Docs: man:openvpn(8) https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage https://community.openvpn.net/openvpn/wiki/HOWTO Main PID: 11570 (openvpn) Status: "Initialization Sequence Completed" Tasks: 1 (limit: 1073) Memory: 2.5M CGroup: /system.slice/system-openvpn\x2dserver.slice/openvpn-server@server.service └─11570 /usr/sbin/openvpn --status /run/openvpn-server/status-server.log --status-version 2 --suppress-timestamps --config server.conf
If you run ifconfig command you will see new interface tun0 means tunnel at server side has been created.
ifconfig tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500 inet 10.8.0.1 netmask 255.255.255.0 destination 10.8.0.1 inet6 fe80::cbae:ba1c:7455:9a12 prefixlen 64 scopeid 0x20<link> inet6 fddd:1194:1194:1194::1 prefixlen 64 scopeid 0x0<global> unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 100 (UNSPEC) RX packets 652436 bytes 89974389 (89.9 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1226004 bytes 428035860 (428.0 MB) TX errors 0 dropped 676 overruns 0 carrier 0 collisions 0
Here’s my working configuration at server side
$ cat /etc/openvpn/server/server.conf local xx.xxx.xxx port 1194 proto tcp dev tun ca ca.crt cert server.crt key server.key dh dh.pem auth SHA256 tls-crypt tc.key topology subnet server 10.8.0.0 255.255.255.0 server-ipv6 fddd:1434:2394:dfdd::/64 push "redirect-gateway def1 ipv6 bypass-dhcp" ifconfig-pool-persist ipp.txt push "dhcp-option DNS 103.3.60.18" push "dhcp-option DNS 139.162.21.5" push "dhcp-option DNS 103.3.60.19" cipher AES-256-CBC user nobody group nogroup persist-key persist-tun verb 5 crl-verify crl.pem explicit-exit-notify 0 client-config-dir /etc/openvpn/client duplicate-cn
During installation OpenVPN Server also create following iptables rule
$cat /etc/systemd/system/openvpn-iptables.service [Unit] Before=network.target [Service] Type=oneshot ExecStart=/usr/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to 172.105.124.18 ExecStart=/usr/sbin/iptables -I INPUT -p tcp --dport 1194 -j ACCEPT ExecStart=/usr/sbin/iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT ExecStart=/usr/sbin/iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT ExecStop=/usr/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to 172.105.124.18 ExecStop=/usr/sbin/iptables -D INPUT -p tcp --dport 1194 -j ACCEPT ExecStop=/usr/sbin/iptables -D FORWARD -s 10.8.0.0/24 -j ACCEPT ExecStop=/usr/sbin/iptables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT ExecStart=/usr/sbin/ip6tables -t nat -A POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to 2400:8901::f03c:92ff:fedd:4fa7 ExecStart=/usr/sbin/ip6tables -I FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT ExecStart=/usr/sbin/ip6tables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT ExecStop=/usr/sbin/ip6tables -t nat -D POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to 2400:8901::f03c:92ff:fedd:4fa7 ExecStop=/usr/sbin/ip6tables -D FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT ExecStop=/usr/sbin/ip6tables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT RemainAfterExit=yes [Install] WantedBy=multi-user.target
Server side is completed but we still need some tweak. We’ll cover later on this document.
And now let’s install the client side.
OpenVPN support Redhat, Ubuntu, Windows, MacOS. Since Raspbian is based on Ubuntu then we will focus on Ubuntu only.
Copy rasp.ovpn from server to client computer using SCP command.
Install OpenVPN client
$ sudo apt install openvpn $ sudo cp rasp.ovpn /etc/openvpn/client.conf
Start openvpn client by issuing this command
$ sudo systemctl start openvpn@client
Run ifconfig on Raspberry Pi and you will see tun0 interface
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500 inet 10.8.0.2 netmask 255.255.255.0 destination 10.8.0.2 inet6 fddd:1194:1194:1194::1000 prefixlen 64 scopeid 0x0<global> inet6 fe80::279e:65f0:5628:67a1 prefixlen 64 scopeid 0x20<link> unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 100
To ensure the tunnel is working, ping to 10.8.0.1
pi@raspberrypi:~ $ ping 10.8.0.1 PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data. 64 bytes from 10.8.0.1: icmp_seq=1 ttl=64 time=16.2 ms 64 bytes from 10.8.0.1: icmp_seq=2 ttl=64 time=15.9 ms 64 bytes from 10.8.0.1: icmp_seq=3 ttl=64 time=16.4 ms 64 bytes from 10.8.0.1: icmp_seq=4 ttl=64 time=17.8 ms
Let’s talk more detail on why i change transport from UDP to UDP, to be honest i spend few days and never achieve what i expect.
When i use UDP tunnel always down after some time.
This is the most common issue happen
Mar 8 01:35:54 lab openvpn[1838]: raspi/158.140.180.116:55795 [raspi] Inactivity timeout (--ping-restart), restarting Mar 8 01:35:54 lab openvpn[1838]: raspi/158.140.180.116:55795 SIGUSR1[soft,ping-restart] received, client-instance restarting
All i need to do is restart the OpenVPN client application, then things back to Normal.
I went though many websites on how to solve that issue, and none is solving my problem.
Then i decide to change transport to TCP, i can see my tunnel interface stay longer (few hours) with default config until i saw issue in my log file.
Mar 9 09:26:48 lab openvpn[31463]: raspi/158.140.180.116:54120 MULTI: bad source address from client [192.168.100.100], packet dropped Mar 9 09:27:03 lab openvpn[31463]: message repeated 4 times: [ raspi/158.140.180.116:54120 MULTI: bad source address from client [192.168.100.100], packet dropped] Mar 9 09:27:20 lab openvpn[31463]: raspi/158.140.180.116:54120 MULTI: bad source address from client [192.168.100.100], packet dropped
As you can see dropped packet from 192.168.100.100, it is local IP of my Raspberry Pi.
While observing this packet dropped issue, i found more bad packets coming. This time is very bad, it make tunnel disconnected.
Mar 10 06:17:26 lab openvpn[5068]: rasp/158.140.180.116:36540 MULTI: bad source address from client [192.168.100.100], packet dropped Mar 10 06:17:46 lab openvpn[5068]: rasp/158.140.180.116:36540 MULTI: bad source address from client [192.168.100.100], packet dropped Mar 10 06:17:47 lab openvpn[5068]: message repeated 3 times: [ rasp/158.140.180.116:36540 MULTI: bad source address from client [192.168.100.100], packet dropped] Mar 10 06:17:56 lab openvpn[5068]: rasp/158.140.180.116:36540 MULTI: bad source address from client [192.168.100.100], packet dropped Mar 10 06:17:56 lab openvpn[5068]: rasp/158.140.180.116:36540 MULTI: bad source address from client [192.168.100.100], packet dropped Mar 10 06:18:35 lab openvpn[5068]: rasp/158.140.180.116:36540 MULTI: bad source address from client [192.168.100.100], packet dropped Mar 10 06:18:52 lab openvpn[5068]: rasp/158.140.180.116:36540 MULTI: bad source address from client [192.168.100.100], packet dropped Mar 10 06:18:53 lab openvpn[5068]: message repeated 2 times: [ rasp/158.140.180.116:36540 MULTI: bad source address from client [192.168.100.100], packet dropped] Mar 10 06:18:55 lab openvpn[5068]: rasp/158.140.180.116:36540 MULTI: bad source address from client [192.168.100.100], packet dropped Mar 10 06:19:00 lab openvpn[5068]: rasp/158.140.180.116:36540 MULTI: bad source address from client [192.168.100.100], packet dropped Mar 10 06:19:00 lab openvpn[5068]: rasp/158.140.180.116:36540 MULTI: bad source address from client [192.168.100.100], packet dropped Mar 10 06:20:07 lab openvpn[5068]: rasp/158.140.180.116:36540 MULTI: bad source address from client [192.168.100.100], packet dropped Mar 10 06:20:09 lab openvpn[5068]: rasp/158.140.180.116:36540 MULTI: bad source address from client [192.168.100.100], packet dropped Mar 10 06:25:01 lab CRON[16320]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1) Mar 10 06:25:01 lab CRON[16321]: (root) CMD (test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )) Mar 10 06:35:01 lab CRON[16655]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1) Mar 10 06:35:41 lab openvpn[5068]: rasp/158.140.180.116:36540 Connection reset, restarting [-1] Mar 10 06:35:41 lab openvpn[5068]: rasp/158.140.180.116:36540 SIGUSR1[soft,connection-reset] received, client-instance restarting
Then i found the final solution for my issue:
“Create routing from OpenVPN Server to my local network”
by issuing this command on Server side
$ sudo route add -net 192.168.100.0/24 gw 10.8.0.1
this is what i saw on the log after add route to my home network.
Mar 11 00:35:15 lab openvpn[9763]: rasp/158.140.180.116:49752 MULTI: Learn: 10.8.0.2 -> rasp/158.140.180.116:49752 Mar 11 00:35:15 lab openvpn[9763]: rasp/158.140.180.116:49752 MULTI: primary virtual IP for rasp/158.140.180.116:49752: 10.8.0.2 Mar 11 00:35:15 lab openvpn[9763]: rasp/158.140.180.116:49752 MULTI: Learn: fddd:1194:1194:1194::1000 -> rasp/158.140.180.116:49752 Mar 11 00:35:15 lab openvpn[9763]: rasp/158.140.180.116:49752 MULTI: primary virtual IPv6 for rasp/158.140.180.116:49752: fddd:1194:1194:1194::1000
Well now we finish the infra structure part (connectivity).
Next topic is HAProxy setup to achieve my idea.