Table of Contents
Openvpn installation
Install
apt install openvpn
Enable ip forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
Simple setup with static key
This simple setup with static key is really only usable with single client and server, unless you want to run separate openvpn instances on different server ports with different server configurations.
cd /etc/openvpn/ openvpn --genkey --secret static.key
Set up the server.conf, here's a minimum konfiguration
dev tun ifconfig 10.8.0.1 10.8.0.2 secret /etc/openvpn/static.key cipher AES-256-CBC
And client.conf
remote 1.2.3.4 dev tun ifconfig 10.8.0.2 10.8.0.1 secret static.key #route 4.5.6.7 255.255.255.255 vpn_gateway
redirect-gateway def1 cipher AES-256-CBC
Note the static key
and redirect-gateway
options. Redirect gateway will route all client's traffic to go through VPN. For visiting public sites you will need to setup SNAT/MASQUERADING on firewall. See below.
Uncomment route
and comment out redirect-gateway
if you only want to route traffic to specific IP e.g. 4.5.6.7
Start the openvpn on both server and client. Server:
/etc/openvpn# openvpn server/server.conf
and client
sudo openvpn client.ovpn
Both commands should show at the end something like:
... 2024-04-09 10:25:08 Peer Connection Initiated with [AF_INET]1.2.3.4:port 2024-04-09 10:25:08 Initialization Sequence Completed
To verify that the VPN is running, you should be able to ping 10.8.0.2 from the server and 10.8.0.1 from the client.
Setup for multiple clients - one server
This is the “proper” way to do it when there are multiple clients involved.
Certificate generation
Download the easy-rsa:
wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.7/EasyRSA-3.1.7.tgz tar xf EasyRSA-3.1.7.tgz cd EasyRSA-3.1.7
Copy vars.example to vars and change variables accordingly. vars will be automatically sourced by easy-rsa script.
cp vars.example vars
Also add the keyEncipherment
option in x509-types/client file otherwise you will get an error like
Client failed: unsupported certificate purpose
eg.
etc/openvpn/EasyRSA-3.1.7# cat x509-types/client # X509 extensions for a client basicConstraints = CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always extendedKeyUsage = clientAuth keyUsage = digitalSignature, keyEncipherment
1. Initialize the PKI directories
./easyrsa init-pki
2. Create the CA. Used in client and server configuration:
./easyrsa build-ca
3. Generate Diffie-Hellman (DH) params.
./easyrsa gen-dh
4. Create the vpn server's sign request and then certificate. This should be used in server.conf cert
along with key
which will also be generated with these commands. Here you need to provide the password of the CA.key in step 2:
./easyrsa gen-req server nopass ./easyrsa sign-req server server
5. Create client signing request and certificate. Change EntityName, nopass
if you don't want private key to be encrypted
./easyrsa gen-req EntityName nopass ./easyrsa sign-req client EntityName
For each new client just repeat last step.
Creating configuration files for server and clients
Server
You can copy the example file and adapt the fields to your config
cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf server.conf
Edit the ca, cert, key, and dh parameters to point to the files you generated and any other configuration you need. Also create the ta.key
openvpn --genkey tls-auth ta.key
Also create the openvpn user
adduser --no-create-home --disabled-login openvpn
and uncomment this in server.conf
... ;user openvpn ;group openvpn ...
Client
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf client.conf.example
- Like the server configuration file, first edit the ca, cert, and key parameters to point to the files you generated.
- Edit the
remote
directive to point to the hostname/IP address and port number of the OpenVPN server - Ensure that the client configuration file is consistent with the directives used in the server configuration. The major thing to check for is that the dev (tun or tap) and proto (udp or tcp) directives are consistent. Also make sure that comp-lzo and fragment, if used, are present in both client and server config files.
You can now try running the openvpn on client and server like mentioned in Simple setup above.
Redirecting traffic over VPN
Redirect all traffic
In server.conf add
push "redirect-gateway def1 bypass-dhcp"
In client.conf add:
redirect-gateway def1
Redirect only some IPs (aka Split tunnel)
In server.conf add:
push "route 192.168.10.0 255.255.255.0" push "route 192.168.20.0 255.255.255.0" ...
Remove the redirect-gateway lines from conf.
Ubuntu Network Manager doesn't seem to need above settings, so you can just uncheck the “Use this connection only for resources on its network” to redirect all traffic over VPN.
Redirect DNS through VPN
First uninstall any other DNS server/resolver like systemd-resolved
. Now install dnsmasq
apt install dnsmasq
Now make the /etc/resolv.conf look like this
nameserver ::1 nameserver 127.0.0.1 options trust-ad
You might need to write protect this file because some other programs might overwrite this.
In /etc/dnsmasq.conf add one or more upstream servers that dnsmasq will use for name resolution i.e.
listen-address=::1,127.0.0.1,10.8.0.1 interface=tun0 # Google's nameservers, for example server=8.8.8.8 server=8.8.4.4
Adapt the listen-address IP to your VPN interface IP and interface as well and uncomment no-resolv
.
In /etc/openvpn/server/server.conf make sure you push DNS and redirect gateway:
... push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS 10.13.13.1" ...
If you run into problems with DNS not going through VPN in Windows installed as a VM in Virtualbox for example, you will need to disable automatic metric on VPN interface and set it to lower then the default Ethernet or wifi. To check open the powershell and type nslookup example.org
and you should get a response from VPN IP e.g. 10.8.0.1.
Resolve specific domains names to hard-coded IP
Say you need to always resolve example.org to 1.2.3.4 address, you have two options.
1. Add the resolution to /etc/hosts i.e.
... 1.2.3.4 www.example.org example.org
2. Remove the above from /etc/hosts and in /etc/dnsmasq.conf add following
address=/example.org/1.2.3.4
Also there are other stuff you can do.
Firewall setup
Shorewall
Example configuration.
/etc/shorewall/interfaces
############################################################################### #ZONE INTERFACE BROADCAST OPTIONS net eth0 detect tcpflags,logmartians,nosmurfs,dhcp vpn tun0 detect
/etc/shorewall/zones
############################################################################### #ZONE TYPE OPTIONS IN OUT # OPTIONS OPTIONS fw firewall net ipv4 vpn ipv4
/etc/shorewall/snat - this will masq all traffic to appear to be coming from the IP of the server running Openvpn.
MASQUERADE 10.8.0.0/24 eth0
/etc/shorewall/policy
############################################################################### #SOURCE DEST POLICY LOG LEVEL LIMIT:BURST $FW net ACCEPT $FW vpn ACCEPT vpn $FW ACCEPT vpn net ACCEPT net all DROP info # The FOLLOWING POLICY MUST BE LAST all all REJECT info
/etc/shorewall/rules - connect to openvpn service at this port
... ACCEPT net $FW udp 1194 ...
iptables
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
Running openvpn server as a service
Debian 12 ships with systemd units for this. The way to run it is to first make sure the server configuration file is located in /etc/openvpn/server directory. The file must end with .conf. So if you have a configuration file called myvpnserver.conf
you need to run it as
systemctl enable --now openvpn-server@myvpnserver
Check logs with
journalctl -xefu openvpn-server@server.service
Tested on
- Debian 12 Bookworw
- shorewall 5.2.8