How to setup OpenVPN on Ubuntu or Debian

Linux Tutorials VPS

April 5, 2020 by Harry

How to setup OpenVPN on Ubuntu or Debian

OpenVPN is an open-source project that was published in 2002 by James Yonan. OpenVPN uses custom security protocols to provide high security using point-to-point or site-to-site connections. Join us to check how to install OpenVPN in Ubuntu or Debian with IPv6 support.

Pre-requirements

  • A Linux VPS server with operating systems like Ubuntu 16.04, Ubuntu 18.04. Ubuntu 19.04, Debian 8 or 9.
  • Root access
  • Static IP

First of all, we should find the IP address of our Ubuntu or Debian VPS:
IPv4 Address

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

The result should be something like this

[email protected]:~# ip addr show dev eth0 | grep "inet" | awk '{ print $2 }' 
184.85.49.120/32

Our IP is 184.85.49.120 and contains the subnet mask 32.

IPv6 Address

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

The result should be something like this

[email protected]:~# ip addr show dev eth0 | grep "inet6" | awk '{ print $2 }' 
۲a01:4f8:c2c:5fc7::1/64
fe80::9400:ff:fe27:10db/64

Our IP is fe80::9400:ff:fe27:10db and contains the subnet mask 32.
Second IPv6 fe80:: 9400: ff: fe27: 10db is the Address of mac RFC 4291

Step 1 – OpenVPN Installation and configuration

Install OpenVPN, IPTables, OpenSSL and ca-certificates.

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

After installation, we need easy-rsa loading.

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 loading easy-rsa, we need to create a PKI and set the CA and server/client certificates.
Note: Certificates expire in 3650 days (10 years), you can change the value.
Note: You can rename the CLIENT, but do not 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

We will now move the certificates to the OpenVPN folder and change the group and owner 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 transferring the certificates, we want to generate the validation key using (tls (tls-auth), then we should create the DH parameters and use the predefined group ffdhe2048.

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

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

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

Now it’s time to configure the OpenVPN server

Edit the OpenVPN configuration file(server.conf) with an editor like nano or vi:

nano /etc/openvpn/server.conf

Settings that you should change:
Port 1194 (default) to 443
Porto UDP(default) to TCP
Note: It is better to change the port because you can block the OpenVPN 1194 port. In addition, port 443 is ideal for preventing censorship because OpenVPN traffic is the same as regular SSL traffic.
Note: The UDP protocol performs better than the TCP protocol, but is not very reliable.

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 for the DNS section, you need to select a few options

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

Default DNS

IPV4:
    Primary     DNS: 213.133.98.98
    Alternative DNS: 213.133.99.99
    Alternative DNS: 213.133.100.100
IPV6
    Primary     DNS: 2a01:4f8:0:1::add:9898
    Alternative DNS: 2a01:4f8:0:1::add:9999
    Alternative DNS: 2a01:4f8:0:1::add:1010

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 selecting the DNS provider, add them at the end of the file.
Note: You must add both DNS servers and (IPv4 and IPv6), the first is the main DNS server and the second is the DNS replacement server.

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

Once you’re done with the DNS section, it’s time to move on to 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

OpenVPN firewall rules

If you are using Firewalld, add the following code and save the file and exit.

# 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

but If you are using iptables, add the following code and save the file and exit.

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 following configuration to the file client.txt

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, the OpenVPN server configuration should look like this:

Display server.conf filer

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 2 – Creating a User

In order to add a new user, we want to create a new script. This script has 2 options

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

Copy and paste the following configuration

#!/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

Enter the required permissions

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

Note: If you cannot connect to the VPN server, restart the VPS.

Step 3 – Using of OpenVPN user manager

Run the script

bash openvpn-user-manager.sh

The output should look like this

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

You can easily enter the options and create/remove a user for OpenVPN and connect through it.

We hope you find this article useful and helpful. Share your comments with us

 

 

Helpful

About the Author Harry

I like to learn and to teach to make things easier

Leave a Reply

Your email address will not be published. Required fields are marked *