How To Install and Configure an OpenVPN Server on Debian 9 In 5 Minutes

last updated in Categories , , , ,

I am a new Debian Linux version 9 server user. How do I setup an OpenVPN Server on Debian Linux version 9.x or 8.x server to shield my browsing activity from bad guys on public Wi-Fi, and more?

OpenVPN is a free and open source VPN (virtual private network) software for Linux and Unix-like systems. It implements OSI layer 2 or 3 secure network extension using the SSL/TLS protocol. A VPN allows you to connect securely to an insecure public network such as wifi network at the airport or hotel. VPN is also required to access your corporate or enterprise or home server resources. You can bypass geo-blocked site and increase your privacy or safety online.
howto setup openvpn server on debian 9-8.001
This tutorial provides step-by-step instructions for configuring an OpenVPN “road warrior” server on Debian Linux v8.x/9.x including ufw/iptables firewall configuration.

The steps are as follows:

  1. Find and note down your public IP address
  2. Download openvpn-install.sh script
  3. Run openvpn-install.sh to install OpenVPN server
  4. Connect an OpenVPN server using IOS/Android/Linux/Windows client
  5. Verify your connectivity

Step 1 – Find your public IP address

Use any one of the following command to find out your IPv4 public address. If your internface name is eth0 or eth1, enter:
$ ip addr show eth0
OR
$ ip addr show eth1
Or use the host command or dig command as follows:
$ host myip.opendns.com resolver1.opendns.com
OR
$ dig TXT +short o-o.myaddr.l.google.com @ns1.google.com
Sample outputs:
Fig.01: Finding my public IP address on Debian 9 server
Note down the public IP address 104.237.156.154 i.e. public ip address of your OpenVPN server.

Step 2 – Update your system and install ufw

Type the apt-get command/apt command to update your system:
$ sudo apt-get update
$ sudo apt-get upgrade

Sample outputs:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
Calculating upgrade... Done
The following packages will be upgraded:
  libc-bin libc-l10n libc6 libexpat1 linux-image-4.9.0-3-amd64 locales
  multiarch-support
7 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 46.6 MB of archives.
After this operation, 0 B of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://security.debian.org/debian-security stretch/updates/main amd64 libc6 amd64 2.24-11+deb9u1 [2,695 kB]
Get:2 http://security.debian.org/debian-security stretch/updates/main amd64 libc-bin amd64 2.24-11+deb9u1 [778 kB]
Get:3 http://security.debian.org/debian-security stretch/updates/main amd64 multiarch-support amd64 2.24-11+deb9u1 [200 kB]
Get:4 http://security.debian.org/debian-security stretch/updates/main amd64 libc-l10n all 2.24-11+deb9u1 [820 kB]
Get:5 http://security.debian.org/debian-security stretch/updates/main amd64 locales all 2.24-11+deb9u1 [3,290 kB]
Get:6 http://security.debian.org/debian-security stretch/updates/main amd64 libexpat1 amd64 2.2.0-2+deb9u1 [83.4 kB]
Get:7 http://security-cdn.debian.org stretch/updates/main amd64 linux-image-4.9.0-3-amd64 amd64 4.9.30-2+deb9u2 [38.7 MB]
Fetched 46.6 MB in 2s (15.5 MB/s)                    
Reading changelogs... Done
Preconfiguring packages ...
(Reading database ... 28439 files and directories currently installed.)
Preparing to unpack .../libc6_2.24-11+deb9u1_amd64.deb ...
Unpacking libc6:amd64 (2.24-11+deb9u1) over (2.24-11) ...
Setting up libc6:amd64 (2.24-11+deb9u1) ...
(Reading database ... 28439 files and directories currently installed.)
Preparing to unpack .../libc-bin_2.24-11+deb9u1_amd64.deb ...
Unpacking libc-bin (2.24-11+deb9u1) over (2.24-11) ...
Setting up libc-bin (2.24-11+deb9u1) ...
Updating /etc/nsswitch.conf to current default.
(Reading database ... 28439 files and directories currently installed.)
Preparing to unpack .../multiarch-support_2.24-11+deb9u1_amd64.deb ...
Unpacking multiarch-support (2.24-11+deb9u1) over (2.24-11) ...
Setting up multiarch-support (2.24-11+deb9u1) ...
(Reading database ... 28439 files and directories currently installed.)
Preparing to unpack .../libc-l10n_2.24-11+deb9u1_all.deb ...
Unpacking libc-l10n (2.24-11+deb9u1) over (2.24-11) ...
Preparing to unpack .../locales_2.24-11+deb9u1_all.deb ...
Unpacking locales (2.24-11+deb9u1) over (2.24-11) ...
Preparing to unpack .../libexpat1_2.2.0-2+deb9u1_amd64.deb ...
Unpacking libexpat1:amd64 (2.2.0-2+deb9u1) over (2.2.0-2) ...
Preparing to unpack .../linux-image-4.9.0-3-amd64_4.9.30-2+deb9u2_amd64.deb ...
Unpacking linux-image-4.9.0-3-amd64 (4.9.30-2+deb9u2) over (4.9.30-2) ...
Setting up libexpat1:amd64 (2.2.0-2+deb9u1) ...
Processing triggers for libc-bin (2.24-11+deb9u1) ...
Setting up libc-l10n (2.24-11+deb9u1) ...
Processing triggers for man-db (2.7.6.1-2) ...
Setting up linux-image-4.9.0-3-amd64 (4.9.30-2+deb9u2) ...
/etc/kernel/postinst.d/initramfs-tools:
update-initramfs: Generating /boot/initrd.img-4.9.0-3-amd64
/etc/kernel/postinst.d/zz-update-grub:
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.9.0-3-amd64
Found initrd image: /boot/initrd.img-4.9.0-3-amd64
done
Setting up locales (2.24-11+deb9u1) ...
Generating locales (this might take a while)...
  en_US.UTF-8... done
Generation complete.

I need to reboot the box as Linux kernel was installed. Type the following reboot command:
$ sudo reboot

Install ufw ( Uncomplicated Firewall )

To install ufw on a Debian 9/8, type the following apt-get command
$ sudo apt-get install ufw
Sample outputs:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  ufw
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 164 kB of archives.
After this operation, 848 kB of additional disk space will be used.
Get:1 http://mirrors.linode.com/debian stretch/main amd64 ufw all 0.35-4 [164 kB]
Fetched 164 kB in 0s (13.1 MB/s)
Preconfiguring packages ...
Selecting previously unselected package ufw.
(Reading database ... 28439 files and directories currently installed.)
Preparing to unpack .../archives/ufw_0.35-4_all.deb ...
Unpacking ufw (0.35-4) ...
Setting up ufw (0.35-4) ...
 
Creating config file /etc/ufw/before.rules with new version
 
Creating config file /etc/ufw/before6.rules with new version
 
Creating config file /etc/ufw/after.rules with new version
 
Creating config file /etc/ufw/after6.rules with new version
Created symlink /etc/systemd/system/multi-user.target.wants/ufw.service ? /lib/systemd/system/ufw.service.
Processing triggers for systemd (232-25) ...
Processing triggers for man-db (2.7.6.1-2) ...
Processing triggers for rsyslog (8.24.0-1) ...

You must open required ports such as SSH port 22, 80, 443 and so on:
$ sudo ufw allow 22
$ sudo ufw allow 80
$ sudo ufw allow 443

Enable the firewall, run:
$ sudo ufw enable

Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

Verify firewall rules
$ sudo ufw status
Sample outputs:

Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere                  
80                         ALLOW       Anywhere                  
443                        ALLOW       Anywhere                  
22 (v6)                    ALLOW       Anywhere (v6)             
80 (v6)                    ALLOW       Anywhere (v6)             
443 (v6)                   ALLOW       Anywhere (v6)             

Step 3 – Download openvpn-install.sh script

Type the following wget command:
$ wget https://git.io/vpn -O openvpn-install.sh
Sample outputs:

--2017-06-29 20:19:41--  https://git.io/vpn
Resolving git.io (git.io)... 23.23.159.159, 50.16.231.196, 23.23.154.116, ...
Connecting to git.io (git.io)|23.23.159.159|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://raw.github.com/Nyr/openvpn-install/master/openvpn-install.sh [following]
--2017-06-29 20:19:41--  https://raw.github.com/Nyr/openvpn-install/master/openvpn-install.sh
Resolving raw.github.com (raw.github.com)... 151.101.40.133
Connecting to raw.github.com (raw.github.com)|151.101.40.133|:443... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://raw.githubusercontent.com/Nyr/openvpn-install/master/openvpn-install.sh [following]
--2017-06-29 20:19:41--  https://raw.githubusercontent.com/Nyr/openvpn-install/master/openvpn-install.sh
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.40.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.40.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 14938 (15K) [text/plain]
Saving to: ‘openvpn-install.sh’
 
openvpn-install.sh  100%[===================>]  14.59K  --.-KB/s    in 0s      
 
2017-06-29 20:19:41 (134 MB/s) - ‘openvpn-install.sh’ saved [14938/14938]

Run openvpn-install.sh script to install and configure OpenVPN server automatically for you:
$ sudo bash openvpn-install.sh
When prompted set IP address to 104.237.156.154 (replace 104.237.156.154 with your actual IP address) and Port to 1194 (or 443 if you are not using a web server). Use Google or OpenDNS DNS servers with the vpn. Next, type client name (such as iPhone, Nexus6, LinuxRouter, BackupServer etc). Finally, press [Enter] key to install and setup OpenVPN on your system:

Fig.02: Setting up OpenVPN on my Debian 9 box
Fig.02: Setting up OpenVPN on my Debian 9 box

That is all. Your OpenVPN server has been configured and ready to use. You can see added firewall rules /etc/rc.local file using cat command:
$ cat /etc/rc.local
Sample outputs:

#!/bin/sh -e
iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT
iptables -I INPUT -p udp --dport 1194 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to 104.237.156.154
exit 0

You can view your openvpn server config file generated by the script as follows (do not edit this file by hand):
$ sudo more /etc/openvpn/server.conf
$ sudo vi -M /etc/openvpn/server.conf

Sample outputs:

port 1194
proto udp
dev tun
sndbuf 0
rcvbuf 0
ca ca.crt
cert server.crt
key server.key
dh dh.pem
auth SHA512
tls-auth ta.key 0
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 173.230.155.5"
push "dhcp-option DNS 173.255.212.5"
push "dhcp-option DNS 173.255.219.5"
push "dhcp-option DNS 173.255.241.5"
push "dhcp-option DNS 173.255.243.5"
push "dhcp-option DNS 173.255.244.5"
push "dhcp-option DNS 173.230.145.5"
push "dhcp-option DNS 173.230.147.5"
push "dhcp-option DNS 74.207.241.5"
push "dhcp-option DNS 74.207.242.5"
keepalive 10 120
cipher AES-256-CBC
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 3
crl-verify crl.pem

How do I start/stop/restart OpenVPN server on a Debian Linux 9.x/8.x LTS?

Type the following command stop the OpenVPN service:
$ sudo systemctl stop openvpn@server
Type the following command start the OpenVPN service:
$ sudo systemctl start openvpn@server
Type the following command restart the OpenVPN service:
$ sudo systemctl restart openvpn@server

Step 4 – Client configuration

On server your will find a client configuration file called ~/macos-vpn-client.ovpn. All you have to do is copy this file to your local desktop using the scp and provide this file to your OpenVPN client to connect:
$ scp vivek@104.237.156.154:~/macos-vpn-client.ovpn .
Next, you need to download OpenVPN client as per your operating system:

MacOS/OS X OpenVPN client configuration

First install OpenVPN macos client. Next, double click on macos-vpn-client.ovpn file and it will open in your tunnelblick client > Click on the “Only me” to install it.

Fig.03: MacOS / OS X openvpn client configuration
Fig.03: MacOS / OS X openvpn client configuration

Once installed click on Connect button and you will be online. Use the following command on MacOS client to verify that your public IP changed to the VPN server IP (type on your Linux/Unix/MacOS desktop):
$ dig TXT +short o-o.myaddr.l.google.com @ns1.google.com
Sample outputs:

"104.237.156.154"

You can ping to OpenVPN server private IP:
$ ping 10.8.0.1
Sample outputs:

PING 10.8.0.1 (10.8.0.1): 56 data bytes
64 bytes from 10.8.0.1: icmp_seq=0 ttl=64 time=287.760 ms
64 bytes from 10.8.0.1: icmp_seq=1 ttl=64 time=283.046 ms
64 bytes from 10.8.0.1: icmp_seq=2 ttl=64 time=278.271 ms
64 bytes from 10.8.0.1: icmp_seq=3 ttl=64 time=283.679 ms
^C
--- 10.8.0.1 ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 278.271/283.189/287.760/3.367 ms

Linux OpenVPN client configuration

Install the openvpn client on RHEL/CentOS Linux using yum command:
$ sudo yum install openvpn
OR, Install the openvpn client on a Debian/Ubuntu Linux Linux using apt command:
$ sudo apt install openvpn
Next, copy macos-vpn-client.ovpn as follows:
$ sudo cp macos-vpn-client.ovpn /etc/openvpn/client.conf
Test connectivity from the CLI:
$ sudo openvpn --client --config /etc/openvpn/client.conf
Your Linux system will automatically connect when computer restart using /etc/init.d/openvpn script:
$ sudo /etc/init.d/openvpn start
For systemd based system, use the following command:
$ sudo systemctl start openvpn@client
Test the connectivity:
$ ping 10.8.0.1 # Ping to OpenVPN server gateway
$ ip route # Make sure routing setup
$ dig TXT +short o-o.myaddr.l.google.com @ns1.google.com # Make sure your public IP set to OpenVPN server

FreeBSD OpenVPN client configuration

First, install the openvpn client, enter:
$ sudo pkg install openvpn
Next, copy macos-vpn-client.ovpn as follows:
$ mkdir -p /usr/local/etc/openvpn/
$ sudo cp macos-vpn-client.ovpn /usr/local/etc/openvpn/client.conf

Edit /etc/rc.conf and add the following:

openvpn_enable="YES"
openvpn_configfile="/usr/local/etc/openvpn/client.conf"

Start the OpenVPN service:
$ sudo /usr/local/etc/rc.d/openvpn start
Verify it:
$ ping 10.8.0.1 #Ping to OpenVPN server gateway
$
$ netstat -nr #Make sure routing setup
$
$ drill myip.opendns.com @resolver1.opendns.com #Make sure your public IP set to OpenVPN server

References

And there you have it, OpenVPN server installed in five minutes to increase your privacy on your very own Debian 9.x/8.x server hosted in the cloud.

This entry is 4 of 5 in the OpenVPN Tutorial series. Keep reading the rest of the series:
  1. How To Setup OpenVPN Server In 5 Minutes on Ubuntu Server
  2. Install Pi-hole with an OpenVPN to block ads
  3. How to update/upgrade Pi-hole with an OpenVPN
  4. How to install an OpenVPN server on Debian 9/8
  5. How to import a OpenVPN .ovpn file with Network Manager

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the latest tutorials on SysAdmin, Linux/Unix and open source topics via RSS/XML feed or weekly email newsletter.

21 comment

  1. Man, thank you veeeery much. I spend two days trying to configure it and still had some problems with connecting to it. With this it just works :D Great job

  2. I ran the script on my server, and I can connect from the client but I can’t access the internet.
    ping 10.8.0.1 works
    ping 8.8.8.8 does not work

    1. Great manual. Unfortunately I have the same problem as Dustin. I cannot connect to the internet while I am connected to openvpn.

      As a temporarily solution I have commented out line: push “redirect-gateway def1 bypass-dhcp” in server.conf

      Can anyone suggest how to solve this issue without my temporarily fix?

          1. Without ufw/firewall routing will not work. You must have firewall configured as described in this tutorial.

            1. I redid it following the guide with ufw. I still have the same issue
              This is the output of cat /etc/rc.local
              #!/bin/sh -e
              iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT –to 24.28.244.8
              exit 0

  3. Hi there, excellent tutorial. After the initial installation, and later I need to modify the server.conf file? How do I create multiple clients?

    1. You just run the script again and choose option “Add a cert for a new user” when prompted and save as client2 and so on:
      $ sudo bash openvpn-install.sh
      Sample session:

      Looks like OpenVPN is already installed
      
      What do you want to do?
         1) Add a cert for a new user
         2) Revoke existing user cert
         3) Remove OpenVPN
         4) Exit
      Select an option [1-4]: 1
      
  4. Hi again, the question about multiple clients is solved. How do I solve the modification of the server.conf file???? Once again thanks

    1. Just edit the file in /etc/openvpn/ directory. Server config file remains same for all client tho.

  5. Hi there. Thanks for the previous answer.

    The openvpn server is not running. what can I check?. The following is the result on the console

    root@vpn-altamira:/etc/openvpn# systemctl start openvpn@server
    root@vpn-altamira:/etc/openvpn# service openvpn status
    ? openvpn.service – OpenVPN service
    Loaded: loaded (/lib/systemd/system/openvpn.service; enabled; vendor preset: enabled)
    Active: inactive (dead)
    root@vpn-altamira:/etc/openvpn#

  6. I followed the guide on a brand new installation of Debian. I can connect to the VPN but the only addresses I can ping are 192.168.1.157 (local address of server) and 10.8.0.1. Nothing else will connect

      1. Yes. I can SSH into it and access the internet.
        While connected to the VPN I can’t access the internet or ping any other device on my network.

  7. Thank you very much for this. I spend two days trying to configure the shit and still not working. With this it work in only 5 minutes.

    I almost never leave a comment but great job for that man.

  8. Thanks for the guide, I have always had issues following the longer guides and would always break something, this is the first time I have been able to set up an OpenVPN server.

    For people not being able to get internet, it’s because your DNS entry is not being updated. You will notice in your client .ovpn that an update-resolv-conf script is initiated to update DNS entires.

    In order for this to work you need to have resolvconf installed

    apt-get install resolvconf. Re-run the openvpn client with the profile again and you should now have internet access. You will also notice when the connection is made as to what the new DNS entries are.

  9. Hello, I have tried to walk through your tutorial and when I run the “wget” command it creates the openvpn-install.sh. it doesn’t show the sample output that you have. I looked at the contents of the file and the content looks like your sample output. These doesn’t seem right, and I cannot run the script to start the install. Can you help me figure out how to get it working?

  10. OK, I followed the guide, but I’m still having issues. When trying to connect I get “TLS Error: TLS key negotiation failed to occur within…” any idea how I can fix this?

    Have a question? Post it on our forum!