Get Rewarded! We will reward you with up to €50 credit on your account for every tutorial that you write and we publish!

Installing OpenVPN on Ubuntu or Debian with IPv6 support

profile picture
Author
Martin Sholev
Published
2019-06-12
Time to read
11 minutes reading time

Introduction

OpenVPN is an open-source project created by James Yonan and was released back in 2002. OpenVPN provides a high level of security using point-to-point or site-to-site connections with custom security protocol.

Prerequisites

  • Server with Linux Operating System:
    • Ubuntu 16.04|18.04|19.04
    • Debian 8|9
  • Root access
  • IPv4 and IPv6 Address
    • If you're unsure what your IP addresses are, you can look them up:

IPv4 address

ip addr show dev eth0 | grep "inet" | awk '{ print $2 }'

The output should be similar to this:

root@ubuntu-2gb-nbg1-1:~# ip addr show dev eth0 | grep "inet" | awk '{ print $2 }'
116.203.180.222/32

Our IPv4 is 116.203.180.222 and it has a /32 subnet mask.

IPv6 address

#IPv6
ip addr show dev eth0 | grep "inet6 " | awk '{ print $2 }'

The output should be similar to this:

root@ubuntu-2gb-nbg1-1:~# ip addr show dev eth0 | grep "inet6" | awk '{ print $2 }'
2a01:4f8:c2c:5fc7::1/64
fe80::9400:ff:fe27:10db/64

Our IPv6 is 2a01:4f8:c2c:5fc7::1 and it has a /64 subnet mask.

The second IPv6, fe80::9400:ff:fe27:10db, is the MAC address (RFC 4291).

Step 1 - Installation and configuration

Step 1.1 Installation

Installing OpenVPN, IPTables, OpenSSL and ca-certificates package.

apt-get install openvpn iptables openssl ca-certificates -y

When the installation is complete we need to download easy-rsa.

wget -O ~/easyrsa.tgz https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.6/EasyRSA-unix-v3.0.6.tgz 2>/dev/null || curl -Lo ~/easyrsa.tgz https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.6/EasyRSA-unix-v3.0.6.tgz
tar xzf ~/easyrsa.tgz -C ~/
mv ~/EasyRSA-v3.0.6/ /etc/openvpn/
mv /etc/openvpn/EasyRSA-v3.0.6/ /etc/openvpn/easy-rsa/
rm -f ~/easyrsa.tgz

After downloading easy-rsa, we have to create PKI and set up CA and server/client certificates

Note: Certificates will expire in 3650 days (10 years), you can change value.

Note: You can change the client certificate name (CLIENT), but don't use special characters.

cd /etc/openvpn/easy-rsa/
./easyrsa init-pki
./easyrsa --batch build-ca nopass

EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-server-full server nopass
EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full CLIENT nopass
EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl

Now we move certificates in OpenVPN folder and change their owner and group permissions.

cp pki/ca.crt pki/private/ca.key pki/issued/server.crt pki/private/server.key pki/crl.pem /etc/openvpn
chown nobody:nogroup /etc/openvpn/crl.pem

After moving certificates we are going to generate key for tls authentication (tls-auth), after that we need to create DH parameters and we gonna use predefined ffdhe2048 group.

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

Predefined DHE groups are recommended by the Internet Engineering Task Force (IETF) in RFC 7919. These groups are supposed to be more resistant to attacks than ones randomly generated

echo '-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
-----END DH PARAMETERS-----' > /etc/openvpn/dh.pem

Step 1.2 Configuration

Now it's time to create the OpenVPN server config.

Settings that you may change:

  • port: 1194 (default) or 443
  • proto: udp (default) or tcp

Note: It's better to change the port because OpenVPN port 1194 could be blocked. Furthermore, port 443 is ideal for avoiding censorship because OpenVPN traffic looks identical to the regular SSL traffic.

Note: UDP protocol has better performance than the TCP protocol, but it's not so reliable.

nano /etc/openvpn/server.conf
port 1194
proto udp
dev tun
sndbuf 0
rcvbuf 0

ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh /etc/openvpn/dh.pem
auth SHA512
tls-auth /etc/openvpn/ta.key 0

topology subnet

server 10.8.0.0 255.255.255.0
local 116.203.180.222                                       #Here you should add the server ipv4 address
ifconfig-pool-persist /etc/openvpn/ipp.txt
push "redirect-gateway def1 bypass-dhcp"

server-ipv6 2a01:4f8:c2c:5fc7:80::/112                      #Here you should add the server ipv6 address
tun-ipv6
push tun-ipv6
ifconfig-ipv6 2a01:4f8:c2c:5fc7::1 2a01:4f8:c2c:5fc7::2     #Here you should add the server ipv6 address
push "route-ipv6 2a01:4f8:c2c:5fc7:2::/64"                  #Here you should add the server ipv6 address
push "route-ipv6 2000::/3"

Now is the DNS part, you have a few options to choose from.

  1. Use default system DNS
  2. Cloudflare DNS
  3. Google DNS
  4. Quad9 DNS

System DNS

grep -v '#' /run/systemd/resolve/resolv.conf | grep 'nameserver' | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'

The output should be similar to this:

185.12.64.1
185.12.64.2

Hetzner (default) DNS

IPV4:
    Primary     DNS: 185.12.64.1
    Alternative DNS: 185.12.64.2
IPV6
    Primary     DNS: 2a01:4ff:ff00::add:1
    Alternative DNS: 2a01:4ff:ff00::add:2

Cloudflare DNS

IPV4:
    Primary     DNS: 1.1.1.1
    Alternative DNS: 1.0.0.1
IPV6
    Primary     DNS: 2606:4700:4700::1111
    Alternative DNS: 2606:4700:4700::1001

Google DNS

IPV4:
    Primary     DNS: 8.8.8.8
    Alternative DNS: 8.8.4.4
IPV6
    Primary     DNS: 2001:4860:4860::8888
    Alternative DNS: 2001:4860:4860::8844

Quad9 DNS

IPV4:
    Primary     DNS: 9.9.9.9
    Alternative DNS: 149.112.112.112
IPV6
    Primary     DNS: 2620:fe::fe
    Alternative DNS: 2620:fe::9

After you choose DNS provider, add them at the end of the file.

Note: You should add both DNS servers (IPv4 and IPv6), the first is primary DNS server and the second is alternative DNS server.

nano /etc/openvpn/server.conf
push "dhcp-option DNS SELECTED-DNS-PROVIDER"
push "dhcp-option DNS SELECTED-DNS-PROVIDER"

After we're done with the DNS part, it's time to continue with the rest of the configuration file.

Add the rest of the configuration at the end of the file.

nano /etc/openvpn/server.conf
keepalive 10 120
cipher AES-256-CBC
user nobody
group nogroup
persist-key
persist-tun
client-to-client
status /etc/openvpn/openvpn-status.log
verb 3
crl-verify /etc/openvpn/crl.pem

Now we have to add the firewall rules.

If you are using firewalld:

# We are not going to use --add-service=openvpn because that would only work with default port and protocol
firewall-cmd --zone=public --add-port=1194/udp
firewall-cmd --zone=trusted --add-source=10.8.0.0/24
firewall-cmd --permanent --zone=public --add-port=1194/udp
firewall-cmd --permanent --zone=trusted --add-source=10.8.0.0/24
# Set NAT for the VPN subnet
firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to SERVER_IP
firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to SERVER_IP
firewall-cmd --permanent --direct --add-rule ipv6 filter FORWARD_direct 0 -i tun0 -o eth0 -j ACCEPT

If you are using iptables

iptables -t nat -A POSTROUTING -o eth0 -s 10.8.0.0/24 -j MASQUERADE
#Note: If you use tcp protocol you must change -p udp to -p tcp and --ddport 1194 to --ddport 443
iptables -A INPUT -i eth0 -p udp --dport 1194 -j ACCEPT
iptables -A INPUT -i tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -o eth0 -s 10.8.0.0/24 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

#Note: If you use tcp protocol you must change -p udp to -p tcp and --ddport 1194 to --ddport 443
ip6tables -A INPUT -i eth0 -p udp --dport 1194 -j ACCEPT
ip6tables -A INPUT -i tun0 -j ACCEPT
ip6tables -A FORWARD -i tun0 -o eth0 -s 2a01:4f8:c2c:5fc7:80::/112 -m state --state NEW -j ACCEPT

Save iptables

iptables-save > /etc/iptables.rules
ip6tables-save > /etc/ip6tables.rules

Now we need to create a client configuration file.

nano  /etc/openvpn/client.txt

Add the whole configuration.

client
dev tun
proto udp
sndbuf 0
rcvbuf 0
tun-mtu 1500
mssfix 1420
remote 116.203.180.222 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth SHA512
auth-nocache
cipher AES-256-CBC
setenv opt block-outside-dns
key-direction 1
verb 3

In the end OpenVPN server configuration it should look similar to this:

Show server.conf file

port 1194
proto udp
dev tun
sndbuf 0
rcvbuf 0
ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh /etc/openvpn/dh.pem
auth SHA512
tls-auth /etc/openvpn/ta.key 0

topology subnet

server 10.8.0.0 255.255.255.0
local 116.203.180.222               #Here you should add the server ipv4 address
ifconfig-pool-persist /etc/openvpn/ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 1.0.0.1"

#ipv6 support
server-ipv6 2a01:4f8:c2c:5fc7:80::/112  #Here you should add the server ipv6 address
tun-ipv6
push tun-ipv6
ifconfig-ipv6 2a01:4f8:c2c:5fc7::1 2a01:4f8:c2c:5fc7::2 #Here you should add the server ipv6 address
push "route-ipv6 2a01:4f8:c2c:5fc7:2::/64"               #Here you should add the server ipv6 address
push "route-ipv6 2000::/3"
push "dhcp-option DNS 2606:4700:4700::1111"
push "dhcp-option DNS 2606:4700:4700::1001"


keepalive 10 120
cipher AES-256-CBC
user nobody
group nogroup
persist-key
persist-tun
client-to-client
status /etc/openvpn/openvpn-status.log
verb 3
crl-verify /etc/openvpn/crl.pem

Step 1.3 (Optional)

Some VPS are with disabled IPv4/IPv6 packet forwarding. To enable IPv4 forwarding you should edit /etc/sysctl.conf

nano /etc/sysctl.conf

Search for the following lines:

# Uncomment the next line to enable packet forwarding for IPv4
#net.ipv4.ip_forward=1
net.ipv4.ip_forward=1

# Uncomment the next line to enable packet forwarding for IPv6
#net.ipv6.conf.all.forwarding=1
net.ipv6.conf.all.forwarding=1

Then, run the following command

sysctl -p.

Step 2 - Create OpenVPN client

In order to be easy for us to add a new user, we're going to create a script. The script will have 2 options:

  1. Add a new user
  2. Remove an existing user
cd ~
nano openvpn-user-manager.sh

Copy and paste the configuration below:

#!/usr/bin/env bash

if readlink /proc/$$/exe | grep -q "dash"; then
	echo "This script needs to be run with bash, not sh."
	exit
fi

if [[ "$EUID" -ne 0 ]]; then
	echo "Sorry, you need to run this as root"
	exit
fi

newclient () {
	# Generates the custom client.ovpn
	cp /etc/openvpn/client.txt ~/$1.ovpn
	echo "<ca>" >> ~/$1.ovpn
	cat /etc/openvpn/easy-rsa/pki/ca.crt >> ~/$1.ovpn
	echo "</ca>" >> ~/$1.ovpn
	echo "<cert>" >> ~/$1.ovpn
	sed -ne '/BEGIN CERTIFICATE/,$ p' /etc/openvpn/easy-rsa/pki/issued/$1.crt >> ~/$1.ovpn
	echo "</cert>" >> ~/$1.ovpn
	echo "<key>" >> ~/$1.ovpn
	cat /etc/openvpn/easy-rsa/pki/private/$1.key >> ~/$1.ovpn
	echo "</key>" >> ~/$1.ovpn
	echo "<tls-auth>" >> ~/$1.ovpn
	sed -ne '/BEGIN OpenVPN Static key/,$ p' /etc/openvpn/ta.key >> ~/$1.ovpn
	echo "</tls-auth>" >> ~/$1.ovpn
}

if [[ -e /etc/openvpn/server.conf ]]; then
	while :
	do
	clear
		echo ""
		echo "What do you want to do?"
		echo "   1) Add a new user"
		echo "   2) Remove an existing user"
		echo "   3) Exit"
		read -p "Select an option [1-3]: " option
		case $option in
			1)
			echo
			echo "Please don't use special characters, only clear words."
			read -p "Client name: " -e CLIENT
			cd /etc/openvpn/easy-rsa/
			EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full $CLIENT nopass
			newclient "$CLIENT"
			echo
			echo "Client $CLIENT added, configuration is available at:" ~/"$CLIENT.ovpn"
			exit
			;;
			2)
			NUMBEROFCLIENTS=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep -c "^V")
			if [[ "$NUMBEROFCLIENTS" = '0' ]]; then
				echo
				echo "We were not able to find existing clients!"
				exit
			fi
			echo
			echo "Select the existing client certificate you want to revoke:"
			tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
			if [[ "$NUMBEROFCLIENTS" = '1' ]]; then
				read -p "Select one client [1]: " CLIENTNUMBER
			else
				read -p "Select one client [1-$NUMBEROFCLIENTS]: " CLIENTNUMBER
			fi
			CLIENT=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$CLIENTNUMBER"p)
			echo
			read -p "Do you actually desire to revoke the access of the client? $CLIENT? [y/N]: " -e REVOKE
			if [[ "$REVOKE" = 'y' || "$REVOKE" = 'Y' ]]; then
				cd /etc/openvpn/easy-rsa/
				./easyrsa --batch revoke $CLIENT
				EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
				rm -f pki/reqs/$CLIENT.req
				rm -f pki/private/$CLIENT.key
				rm -f pki/issued/$CLIENT.crt
				rm -f /etc/openvpn/crl.pem
				cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem
				chown nobody:nogroup /etc/openvpn/crl.pem
				echo
				echo "Certificate for the client $CLIENT is revoked!"
			else
				echo
				echo "Certificate revocation for client $CLIENT aborted!"
			fi
			exit
			;;
			3)
			exit
			;;
        esac
	done
else
    clear
    echo "OpenVPN is not installed."
    echo "Install OpenVPN first"
    echo "https://community.hetzner.com/tutorials/install-and-configure-openvpn-on-ubuntu-and-debian"
fi

Give permissions:

chmod 755 ~/root/openvpn-user-manager.sh

Note: If you can't connect to the vpn server, reboot the VPS. If the problem exists after reboot, follow the step 1.3.

Step 3 - Using OpenVPN User Manager (openvpn-user-manager.sh)

Run the script:

bash openvpn-user-manager.sh

The output should be similar to this:

OpenVPN is installed.

What do you want to do?
   1) Add a new user
   2) Remove an existing user
   3) Exit
Select an option [1-3]:

Conclusion

Your OpenVPN server is now ready. You can browse and enter sites that are restricted or send private files.

License: MIT
Want to contribute?

Get Rewarded: Get up to €50 in credit! Be a part of the community and contribute. Do it for the money. Do it for the bragging rights. And do it to teach others!

Report Issue

Discover our

Dedicated Servers

Configure your dream server. Top performance with an excellent connection at an unbeatable price!

Want to contribute?

Get Rewarded: Get up to €50 credit on your account for every tutorial you write and we publish!

Find out more