Translation(s): English - Français - Русский - Polski


OpenVPN Overview

OpenVPN is an SSL/TLS VPN solution. It is able to traverse NAT connections and firewalls. This page explains briefly how to configure a VPN with OpenVPN, from both server-side and client-side for different setups: from a simple raw connexion for testing purpose up to a TLS enabled connexion.

Installation

Install the openvpn package on both client and server.

# apt-get install openvpn

To enable OpenVPN in the Gnome NetworkManager applet for the taskbar notification area, the additional package network-manager-openvpn-gnome has to be installed on the client:

# apt-get install network-manager-openvpn-gnome

Prerequisites

On the server's firewall, open up UDP 1194 (default port).

Bear in mind that 90% of all connection problems encountered by new OpenVPN users are firewall-related.

Configuration

OpenVPN can authenticate users via user/pass, pre-shared key, certificates, etc.

NetworkManager / GNOME System Menu

It is possible to fully configure OpenVPN connections using the default Debian GNOME setup along with network-manager-openvpn-gnome. The VPN connection will be managed like any other network connection in NetworkManager, and will also have a control in the GNOME System Menu next to the WiFi and Ethernet controls. To make a given network connection automatically enable an OpenVPN configuration in GNOME 42 (used in bookworm), use nm-connection-editor. Find a network connection, open its settings, then under General, enable Automatically connect to VPN. After saving, a secondaries= line is added in that network's configuration file in the [connection] section. It will contain a list of secondary connection UUIDs to be activated. The configuration file is usually /etc/NetworkManager/system-connections/.

Raw (unsecured) VPN connection for test

Server part

From a server shell, run

# openvpn --remote CLIENT_IP --dev tun1 --ifconfig 10.9.8.1 10.9.8.2

if your client has a static IP#; otherwise, run

# openvpn --dev tun1 --ifconfig 10.9.8.1 10.9.8.2

You should see console output resembling

2021-09-03 21:22:18 library versions: OpenSSL 1.1.1k  25 Mar 2021, LZO 2.10
2021-09-03 21:22:18 ******* WARNING *******: All encryption and authentication features disabled -- All data will be tunnelled as clear text and will not be protected against man-in-the-middle changes. PLEASE DO RECONSIDER THIS CONFIGURATION!
2021-09-03 21:22:18 TUN/TAP device tun1 opened
...

While openvpn is running, check your network configuration with ip a. Output should include

9: tun1: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none
    inet 10.9.8.1 peer 10.9.8.2/32 scope global tun1
       valid_lft forever preferred_lft forever
    inet6 fe80::dc71:3707:693c:5017/64 scope link stable-privacy
       valid_lft forever preferred_lft forever

Note that, if you kill openvpn (e.g., with Control-c in its console), you will not see the above network interface.

Client part

# openvpn --remote SERVER_IP --dev tun1 --ifconfig 10.9.8.2 10.9.8.1
...
2021-09-03 21:32:32 Peer Connection Initiated with [AF_INET]SERVER_IP:PORT
2021-09-03 21:32:32 2012 WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
2021-09-03 21:32:32 Initialization Sequence Completed
...

You may also ping the server to test it can be reached: ping 10.9.8.1.

Static-Key VPN connection

Static-Key VPN server configuration

In the server's /etc/openvpn directory, run the following command to generate a static key:

# openvpn --genkey secret static.key

Note: for OpenVPN 2.4 on Debian 10, use --secret instead of secret.

Copy this static key to the clients /etc/openvpn directory using a secure channel like scp or sftp.

On the server, create a new /etc/openvpn/tun0.conf file and add the following:

dev tun0
ifconfig 10.9.8.1 10.9.8.2
secret /etc/openvpn/static.key

Where 10.9.8.x is your VPN subnetwork, 10.9.8.1 will be IP of the server, 10.9.8.2 is IP of client.

Static-Key VPN client configuration

On the client, copy /etc/openvpn/static.key from server and create a new /etc/openvpn/tun0.conf file and add the following:

remote your-server.org
dev tun0
ifconfig 10.9.8.2 10.9.8.1
secret /etc/openvpn/static.key

Start OpenVPN by hand on both sides with the following command (verbose output at 6):

# openvpn --config /etc/openvpn/tun0.conf --verb 6

To verify that the VPN is running, you should be able to ping 10.9.8.2 from the server and 10.9.8.1 from the client.

TLS-enabled VPN connection

Starting with Jessie, easy-rsa is a separate package that should be pulled along with openvpn installation.

Init easy-rsa

# cd /etc/openvpn
# make-cadir easy-rsa/

To initialize the environment, just use the following command:

cd easy-rsa/
./easyrsa init-pki

All the commands that are run from the easy-rsa dir. Refer to ./easyrsa help for a detailed description of the available commands.

Remember:

Generate CA CERTIFICATE/KEY

Generate CERTIFICATE/KEY of the CERTIFICATE AUTHORITY (CA):

# ./easyrsa build-ca

It will generate ca.crt and ca.key in /etc/openvpn/easy-rsa/{pki,pki/private} directories.

Generate CERTIFICATE/KEY of the server:

# ./easyrsa build-server-full server

It will generate server.crt and server.key in /etc/openvpn/easy-rsa/pki/{issued/server.crt,private/server.key}, and signed with your root certificate.

Generate DIFFIE-HELLMAN PARAMETERS

Generate BUILD DIFFIE-HELLMAN PARAMETERS (necessary for the server end of a SSL/TLS connection):

./easyrsa gen-dh

Generate Static Key for TLS authentication

If you already generated a static key, you may rename it to ta.key and move it to the /etc/openvpn/server folder. Else execute the following:

openvpn --genkey secret /etc/openvpn/server/ta.key

Note: for OpenVPN 2.4 on Debian 10, use --secret instead of secret.

Generate CERTIFICATE/KEYs of the client(s)

Generate key for each client: Use one of the following two commands.

./easyrsa build-client-full clientname nopass

./easyrsa build-client-full clientname

It will generate keys in /etc/openvpn/easy-rsa/pki/{issued/clientname.crt,private/clientname.key}.

Install Client CERTIFICATE/KEYs

Copy the ca.crt, clientname.crt, clientname.key from Server to Client 's /etc/openvpn/easy-rsa/pki/{issued/clientname.crt,private/clientname.key} directories.

Check OpenVPN RSA Key for details.

VPN connection from command line

Server:

openvpn --dev tun1 --ifconfig 10.9.8.1 10.9.8.2 --tls-server --dh /etc/openvpn/easy-rsa/pki/dh.pem --ca /etc/openvpn/easy-rsa/pki/ca.crt --cert /etc/openvpn/easy-rsa/pki/issued/server.crt --key /etc/openvpn/easy-rsa/pki/private/server.key --reneg-sec 60 --verb 5 --cipher AES-256-CBC --auth SHA512 --tls-version-min 1.3 --auth-nocache

Client:

openvpn --remote SERVER_IP --dev tun1 --redirect-gateway def1 --ifconfig 10.9.8.2 10.9.8.1 --tls-client --ca /etc/openvpn/easy-rsa/pki/ca.crt --cert /etc/openvpn/easy-rsa/pki/issued/clientname.crt --key /etc/openvpn/easy-rsa/pki/private/clientname.key --reneg-sec 60 --verb 5 --cipher AES-256-CBC --auth SHA512 --tls-version-min 1.3 --auth-nocache

VPN Server configuration file

If the previous connection is successful, create the server configuration file /etc/openvpn/server.conf as follows:

port 1194
proto udp
dev tun

ca      /etc/openvpn/easy-rsa/pki/ca.crt
cert    /etc/openvpn/easy-rsa/pki/issued/server.crt
key     /etc/openvpn/easy-rsa/pki/private/server.key  # keep secret
dh      /etc/openvpn/easy-rsa/pki/dh.pem

topology subnet

server 10.9.8.0 255.255.255.0  # internal tun0 connection IP
ifconfig-pool-persist ipp.txt

push "route 192.168.0.0 255.255.255.0"
push "redirect-gateway def1 bypass-dhcp"

keepalive 10 120

tls-auth /etc/openvpn/server/ta.key 0
auth-nocache

cipher AES-256-CBC
data-ciphers AES-256-CBC

persist-key
persist-tun

status /var/log/openvpn/openvpn-status.log

verb 3  # verbose mode

client-to-client
explicit-exit-notify 1

Create log status file:

# touch /var/log/openvpn/openvpn-status.log

Restart OpenVPN.

# service openvpn restart

Note that the /etc/init.d/openvpn script launched by 'service openvpn restart' will start an openvpn server for every .conf file in /etc/openvpn/, so if you still have the tun0.conf file from above, rename it to something else than *.conf. This is because systemd wants only one openvpn server by default.

VPN Client configuration file

In client, create /etc/openvpn/client.conf as follows:

(note: you may use graphical vpn tool network-manager UI by providing the key and certificates)

client
dev tun
proto udp

remote VPNSERVER_IP 1194             # [VPN server IP] [PORT]
resolv-retry infinite
nobind

persist-key
persist-tun

ca      /etc/openvpn/easy-rsa/pki/ca.crt
cert    /etc/openvpn/easy-rsa/pki/issued/clientname.crt
key     /etc/openvpn/easy-rsa/pki/private/clientname.key

remote-cert-tls server
tls-auth /etc/openvpn/server/ta.key 1
auth-nocache

cipher AES-256-CBC
data-ciphers AES-256-CBC

mute-replay-warnings

verb 3

Restart OpenVPN:

# service openvpn restart

VPN connection started as a Systemd service

At the root of /etc/openvpn/

By default, all configured VPNs in /etc/openvpn/ are started during system boot. Edit /etc/default/openvpn to start specific VPNs or to disable this behavior. You need to run systemctl daemon-reload once to enable new VPNs

in subfolders server and client

On Debian the systemd service expects the server and client configuration files to be, respectively, in /etc/openvpn/server and /etc/openvpn/client. Once you created the config file in the correct folder, you need to enable it. For example, suppose you created the configuration in /etc/openvpn/server/myserver.conf:

systemctl start openvpn-server@myserver
systemctl enable openvpn-server@myserver

VPN connection started via interfaces file

openvpn ifupdown hooks are also available for starting/stopping tunnels using /etc/network/interfaces, e.g.:

auto dsl
iface dsl inet ppp
    provider dsl-provider
    openvpn work_vpn

See /usr/share/doc/openvpn/README.Debian.gz for more information.

Android / iOS devices certificate generation

OpenVPN Debian Server can be configured to use with Android / iOS devices.

on the Server

In Debian Server, create required certificates - we consider you installed via apt openvpn and created the easy-rsa folder as described above:

# cd /etc/openvpn/easy-rsa
# ./easyrsa init-pki
# ./easyrsa build-ca nopass
# ./easyrsa build-server-full server nopass
# ./easyrsa build-client-full YOUR_CLIENT_NAME nopass
# ./easyrsa gen-dh
# cd .. # should now be in /etc/openvpn

# cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf  ./server.conf
# # Below filenames are all based on things in server.conf. If things don't work, read that file and make sure the filenames match up.
# openvpn --genkey secret /etc/openvpn/server/ta.key

Modify below lines in /etc/openvpn/server.conf:

...
proto tcp
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
user nobody
group nogroup
...

8.8.8.8 is Google DNS server. You may change to your preferred DNS server.

Test that the configuration works:

# openvpn --config server.conf

If it does, Ctrl-C out of this and restart OpenVPN server to use the new configuration:

# service openvpn restart

Create client profile file /etc/openvpn/client.ovpn and attach certificates to it:

YOUR_CLIENT_NAME=clientname &&\
cd /etc/openvpn &&\
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf $YOUR_CLIENT_NAME.ovpn && \
echo "key-direction 1" >> $YOUR_CLIENT_NAME.ovpn && \
echo "<ca>" >> $YOUR_CLIENT_NAME.ovpn && \
sed -n '/BEGIN CERTIFICATE/,/END CERTIFICATE/p' < easy-rsa/pki/ca.crt >> $YOUR_CLIENT_NAME.ovpn && \
echo "</ca>" >> $YOUR_CLIENT_NAME.ovpn && \
echo "<cert>" >> $YOUR_CLIENT_NAME.ovpn && \
sed -n '/BEGIN CERTIFICATE/,/END CERTIFICATE/p' < easy-rsa/pki/issued/$YOUR_CLIENT_NAME.crt >> $YOUR_CLIENT_NAME.ovpn && \
echo "</cert>" >> $YOUR_CLIENT_NAME.ovpn && \
echo "<key>" >> $YOUR_CLIENT_NAME.ovpn && \
sed -n '/BEGIN PRIVATE KEY/,/END PRIVATE KEY/p' < easy-rsa/pki/private/$YOUR_CLIENT_NAME.key >> $YOUR_CLIENT_NAME.ovpn && \
echo "</key>" >> $YOUR_CLIENT_NAME.ovpn && \
echo "<tls-auth>" >> $YOUR_CLIENT_NAME.ovpn && \
sed -n '/BEGIN OpenVPN Static key V1/,/END OpenVPN Static key V1/p' < server/ta.key >> $YOUR_CLIENT_NAME.ovpn && \
echo "</tls-auth>" >> $YOUR_CLIENT_NAME.ovpn

Modify below lines in client profile file /etc/openvpn/client.ovpn:

...
proto tcp
remote YourServerIp YourServerPort
mute-replay-warnings
# ca ca.crt
# cert client.crt
# key client.key
key-direction 1
...

where ?YourServerIp and ?YourServerPort should be changed to your server. Three lines (#ca, #cert, #key) are commented as the required certificates were integrated into the ovpn file instead of being individual files.

e-mail or upload the client configuration file /etc/openvpn/$YOUR_CLIENT_NAME.ovpn to google drive in order to download to iPhone.

You'll also want to run the server parts of the "Forward traffic via VPN" steps below.

on the Client

For iOS devices, install OpenVPN Connect client. Then transfer the client configuration file /etc/openvpn/$YOUR_CLIENT_NAME.ovpn to the device by e-mail or by Google Drive. Open the configuration file in Mail apps or Google Drive apps.

For Android devices, install OpenVPN Connect client. Then copy the client configuration file /etc/openvpn/$YOUR_CLIENT_NAME.ovpn to the storage of the device. Open the configuration file in OpenVPN apps.

Your phone OpenVPN client should take care of the client parts automatically.

Forward traffic to provide access to the Internet

on the Server

In Server enable runtime IP forwarding:

echo 1 > /proc/sys/net/ipv4/ip_forward

Edit /etc/sysctl.conf uncomment the following line to make it permanent:

net.ipv4.ip_forward = 1

Execute the following command in server for testing (Old way):

IF_MAIN=eth0
IF_TUNNEL=tun0
YOUR_OPENVPN_SUBNET=10.9.8.0/24
#YOUR_OPENVPN_SUBNET=10.8.0.0/16 # if using server.conf from sample-server-config
iptables -A FORWARD -i $IF_MAIN -o $IF_TUNNEL -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -s $YOUR_OPENVPN_SUBNET -o $IF_MAIN -j ACCEPT
iptables -t nat -A POSTROUTING -s $YOUR_OPENVPN_SUBNET -o $IF_MAIN -j MASQUERADE

Execute the following command in server for testing (Starting with Bullseye):

IF_MAIN=eth0
IF_TUNNEL=tun0
YOUR_OPENVPN_SUBNET=10.9.8.0/24
#YOUR_OPENVPN_SUBNET=10.8.0.0/16 # if using server.conf from sample-server-config
nft add rule ip filter FORWARD iifname "$IF_MAIN" oifname "$IF_TUNNEL" ct state related,established counter accept
nft add rule ip filter FORWARD oifname "$IF_MAIN" ip saddr $YOUR_OPENVPN_SUBNET counter accept
nft add rule ip nat POSTROUTING oifname "$IF_MAIN" ip saddr $YOUR_OPENVPN_SUBNET counter masquerade

You may also use the rc.firewall-iptables script from TLDP Masquerade as an alternative.

If everything is working fine, save the rules: Debian wiki iptables and nftables pages for details.

Manage the Public Key Infrastructure

?easy-rsa helps to manage the key of your PKI:

More info here: /usr/share/doc/easy-rsa/doc

For security purpose, it is advised to set up the PKI in a different server that the openvpn server.

Application to a VPN passing through a http proxy

Prerequisites: install an HTTP proxy

This part describe how to configure a VPN to pass through a http proxy, which allow only trafic on port 443 (and 80). This use the http-proxy option of OpenVPN.

  1. First of all, check that the port 443 isn't already used by another service on your server.
  2. Configure OpenVPN on server side by adding port 443 and proto tcp-server to the configuration file. This option works only with TCP as the tunnel carrier protocol

  3. Configure OpenVPN on the client side by adding port 443, proto tcp-client and http-proxy 1.1.1.1 8080 to the configuration file.

Where 1.1.1.1 and 8080 are IP and port of your proxy.

  1. Now you should launch OpenVPN on the server and next on the client.

Enable and use the Management Interface

Enable the option in server conf file by adding:

management localhost 7505

Connect to this interface:

telnet localhost 7505

This is useful for authentication (http-proxy) or killing an open session. More info

Troubleshooting


See also


CategoryNetwork