Ubuntu 20.04 LTS Server Edition
Installing OpenVPN

Updated 28 July 2021


Install OpenVPN: I recommend you link to this page, which has an excellent tutorial on how to quickly install and initially configure the software. I recommend that you use the /root home directory to wget(1) the script and run it, as root.For my VPN server, I used the entries as shown in this screen display:



Welcome to this OpenVPN road warrior installer!

Which IPv4 address should be used?
     1) 76.209.1.163
     2) 10.1.1.35
     3) 10.1.3.35
IPv4 address [1]: 1

Which protocol should OpenVPN use?
   1) UDP (recommended)
   2) TCP
Protocol [1]: 2

What port should OpenVPN listen to?
Port [1194]: 443

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]: 1

Enter a name for the first client:
Name [client]: phonehome

OpenVPN installation is ready to begin.
  

What we have at this point in the process: The client configuration file built by the script (assuming you use the above parameters) can be found at /root/phonehome.ovpn, which is a plain-text file.

For the purposes of this discussion, "client" refers to the computer calling into the VPN server, and "VPN server" is the computer into which we just installed the software.

In a nutshell: OpenVPN uses the tun0 interfaces in both server and client to built a point-to-point tunnek between server(10.8.0.1/24) and client (10.8.0.*/24) -- the client address is assigned when the client and server negotiate the connection. Multiple connections, up to 253, may be open at a time to different clients. OpenVPN then exchanges data with the client through this tunnel, encrypting and decrypting the data using the key pairs created by OpenVPN, stored in the directory /etc/openvpn/server, and included in the client's configuration file.

In the classic VPN use case, where you want all your client's traffic through the tunnel to the VPN server. All packets leaving the VPN server (either into your LAN or out to the world) has the source IP address set to the public interface's IP address, in this case 76.209.1.163. This doesn't work well for a phone-home connection to LAN addresses, because the responses will go out the gateway (which is on a different IP address) and come back in via the VPN's public interface. The VPN server will then see the source-ip/source-port/destination-ip/destination-port and send the response back via the tunnel to your client.

In other words, the return packet does not take the same path that the original packet took. It gets to where it should, but in a more roundabout way.

For a phone-home use case, we don't want all traffic tunnel. What happens when your client computer is inside a network with additional routing to non-routed netblocks? (Search for "Reserved IP Addresses" to learn more.) If you send all traffic home, that traffic is now outside the network that computer resides on. That means that anything on, say, the 172.16.0.0/12 netblock is now invisible in your client computer. Some sysadmins would not like that.

So, for the phone-home use case, we need to make some adjustments to the various files. The following sections describe the surgery that needs to be performed. All the surgery needs to be done on configuration files that reside on the VPN server; the client configuration file is unchanged.

Edit the OpenVPN Firewall Service file: Replace the file /etc/systemd/system/openvpn-iptables.service with this content:

[Unit]
Before=network.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 \
     -d 10.1.1.0/24 -o enp2s0 -j MASQUERADE
ExecStart=/usr/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 \
     ! -d 10.8.0.0/24 -j SNAT --to 76.209.1.163
ExecStart=/usr/sbin/iptables -I INPUT -p tcp --dport 443 -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.1.1.0/24 -o enp2s0 -j MASQUERADE
ExecStop=/usr/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.0/24 \
     ! -d 10.8.0.0/24 -j SNAT --to 76.209.1.163
ExecStop=/usr/sbin/iptables -D INPUT -p tcp --dport 443 -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
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
  

A little explanation of what all these commands do:

Edit the Server Configuration File: Replace the line push "redirect-gateway def1 bypass-dhcp" with these three lines:

##### push "redirect-gateway def1 bypass-dhcp"
push "route 10.1.1.0 255.255.255.0"
  

Also remove the line push "dhcp-option DNS 127.0.0.1". These changes remove the default-route redirection, advertises the LAN netblock, and advertises the DNS server on the LAN.


Comments, suggestions, and error reports are welcome.
Send them to: spamfilter (at) satchell (dot) net)
© 2021 Stephen Satchell, Reno NV