OpenVPN setup script for Debian and Ubuntu

openvpnOpenVPN is a free and open-source software application that can be used to securely link two or more private networks using an encrypted tunnel over the Internet.  OpenVPN is bound to the OpenSSL library and derives much of its crypto capabilities from it.

Today we will share a script you can use to install and configure OpenVPN on an Ubuntu VPS. The script is pretty much self-explanatory.

Code

#!/usr/bin/env bash
#

# Functions
ok() { 
    echo -e '\e[32m'$1'\e[m'; 
}

die() { 
    echo -e '\e[1;31m'$1'\e[m'; exit 1; 
}

# Sanity check
if [[ $(id -g) != "0" ]] ; then
    die "❯❯❯ Script must be run as root."
fi

if [[  ! -e /dev/net/tun ]] ; then 
    die "❯❯❯ TUN/TAP device is not available."
fi

dpkg -l openvpn > /dev/null 2>&1
if [[ $? -eq 0 ]]; then
    die "❯❯❯ OpenVPN is already installed."
fi

# Install openvpn
ok "❯❯❯ apt-get update"
apt-get update -q > /dev/null 2>&1
ok "❯❯❯ apt-get install openvpn curl openssl"
apt-get install -qy openvpn curl > /dev/null 2>&1

# IP Address
SERVER_IP=$(curl -s ipv4.icanhazip.com)
if [[ -z "${SERVER_IP}" ]]; then
    SERVER_IP=$(ip a | awk -F"[ /]+" '/global/ && !/127.0/ {print $3; exit}')
fi

# Generate CA Config
ok "❯❯❯ Generating CA Config"
openssl dhparam -out /etc/openvpn/dh.pem 2048 > /dev/null 2>&1
openssl genrsa -out /etc/openvpn/ca-key.pem 2048 > /dev/null 2>&1
chmod 600 /etc/openvpn/ca-key.pem
openssl req -new -key /etc/openvpn/ca-key.pem -out /etc/openvpn/ca-csr.pem -subj /CN=OpenVPN-CA/ > /dev/null 2>&1
openssl x509 -req -in /etc/openvpn/ca-csr.pem -out /etc/openvpn/ca.pem -signkey /etc/openvpn/ca-key.pem -days 365 > /dev/null 2>&1
echo 01 > /etc/openvpn/ca.srl

# Generate Server Config
ok "❯❯❯ Generating Server Config"
openssl genrsa -out /etc/openvpn/server-key.pem 2048 > /dev/null 2>&1
chmod 600 /etc/openvpn/server-key.pem
openssl req -new -key /etc/openvpn/server-key.pem -out /etc/openvpn/server-csr.pem -subj /CN=OpenVPN/ > /dev/null 2>&1
openssl x509 -req -in /etc/openvpn/server-csr.pem -out /etc/openvpn/server-cert.pem -CA /etc/openvpn/ca.pem -CAkey /etc/openvpn/ca-key.pem -days 365 > /dev/null 2>&1

cat > /etc/openvpn/udp1194.conf <<EOF
server 10.8.0.0 255.255.255.0
verb 3
duplicate-cn
key server-key.pem
ca ca.pem
cert server-cert.pem
dh dh.pem
keepalive 10 120
persist-key
persist-tun
comp-lzo
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"

user nobody
group nogroup

proto udp
port 1194
dev tun1194
status openvpn-status-1194.log
EOF

# Generate Client Config
ok "❯❯❯ Generating Client Config"
openssl genrsa -out /etc/openvpn/client-key.pem 2048 > /dev/null 2>&1
chmod 600 /etc/openvpn/client-key.pem
openssl req -new -key /etc/openvpn/client-key.pem -out /etc/openvpn/client-csr.pem -subj /CN=OpenVPN-Client/ > /dev/null 2>&1
openssl x509 -req -in /etc/openvpn/client-csr.pem -out /etc/openvpn/client-cert.pem -CA /etc/openvpn/ca.pem -CAkey /etc/openvpn/ca-key.pem -days 36525 > /dev/null 2>&1

cat > /etc/openvpn/client.ovpn <<EOF
client
nobind
dev tun
redirect-gateway def1 bypass-dhcp
remote $SERVER_IP 1194 udp
comp-lzo yes

<key>
$(cat /etc/openvpn/client-key.pem)
</key>
<cert>
$(cat /etc/openvpn/client-cert.pem)
</cert>
<ca>
$(cat /etc/openvpn/ca.pem)
</ca>
EOF

# Iptables
if [[ ! -f /proc/user_beancounters ]]; then
    N_INT=$(ip a |awk -v sip="$SERVER_IP" '$0 ~ sip { print $7}')
    iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o $N_INT -j MASQUERADE
else
    iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j SNAT --to-source $SERVER_IP
fi

iptables-save > /etc/iptables.conf

cat > /etc/network/if-up.d/iptables <<EOF
#!/bin/sh
iptables-restore < /etc/iptables.conf
EOF

chmod +x /etc/network/if-up.d/iptables

# Enable net.ipv4.ip_forward
sed -i 's|#net.ipv4.ip_forward=1|net.ipv4.ip_forward=1|' /etc/sysctl.conf
echo 1 > /proc/sys/net/ipv4/ip_forward

# Restart Service
ok "❯❯❯ service openvpn restart"
service openvpn restart > /dev/null 2>&1
ok "❯❯❯ Your client config is available at /etc/openvpn/client.ovpn"
ok "❯❯❯ All done!"

What does the script do?

The script will automatically install OpenVPN and all the necessary dependencies, configure, and add a new user.

How to use it ?

1. Download the script

wget https://raw.github.com/rosehosting/OpenVPN_setup_script/master/install_openvpn.sh

2. Make it executable

chmod +x install_openvpn.sh

3. Run

./install_openvpn.sh

Of course, if you are one of our Linux VPS Hosting customers, you don’t have to do any of this, simply ask our admins, sit back and relax. Our admins will install OpenVPN for you immediately.

PS. If you liked this post please share it with your friends on the social networks using the buttons on the left or simply leave a reply below. Thanks.

Here’s the latest update for How To Set Up an OpenVPN Server on Debian 10.

14 thoughts on “OpenVPN setup script for Debian and Ubuntu”

  1. Excellent! Seems to be working. Script went well, except for:

    ❯❯❯ Generating Client Config
    ./install_openvpn.sh: line 108: N_INT: command not found
    Bad argument `MASQUERADE’
    Try `iptables -h’ or ‘iptables –help’ for more information.
    ❯❯❯ service openvpn restart

    Reply
    • Please provide us with the output of the following command:

      ip a |awk -v sip=”$SERVER_IP” ‘$0 ~ sip { print $7}’

      Or, try replacing $N_INT with your network interface, for example:

      iptables -t nat -A POSTROUTING -s 10.1.0.0/24 -o eth0 -j MASQUERADE

      Reply
      • Actually, the error is due to syntax. You will want to cut the spaces when setting the N_INT variable, like so:

        N_INT=$(ip a |awk -v sip=”$SERVER_IP” ‘$0 ~ sip { print $7}’)

        Otherwise, thanks for the script, I’m porting it for RHEL systems as well as adding the options to create/revoke access. I’ll be sure to leave creds :)

        Reply
  2. I used your script and OpenVPN installed successfully. But when trying to connect using OpenVPN connect on Android, I get this error:

    OpenVPN server certificate verification failed : PolarSSL: SSL read error : X509 – Certifcate verification failed, e.g. CRL, CA or signature check failed

    Do you have any idea what the problem is?

    Reply
    • Are you using OpenVPN Connect on your Android phone? Please check your server log files for any specific errors that should point you in the right direction.

      Reply
  3. There is still one bug in the script that causes an error~
    cat > /etc/openvpn/client.ovpn <<EOF
    client
    nobind
    dev tun
    redirect-gateway def1 bypass-dhcp

    bypass-dhcp needs removing as it causes an error in client.ovpn
    Options error: unknown –redirect-gateway flag: bypass-dhcp
    Use –help for more information.

    It can be fixed client side by editing editing config to read ~
    redirect-gateway def1 #bypass-dhcp
    or by deleting it

    Reply
    • Make sure you have the latest version of OpenVPN client (2.3.6) installed on your machine.

      If not, download it at https://openvpn.net/index.php/open-source/downloads.html

      Reply
  4. Hi,
    Followed your script and seems like everything installed as it should except some regarding to iptables ?
    I’m getting following error:
    WARNING: Deprecated config file /etc/modprobe.conf, all config files belong into /etc/modprobe.d/.
    FATAL: Module ip_tables not found.
    iptables v1.4.8: can’t initialize iptables table `nat’: Table does not exist (do you need to insmod?)
    Perhaps iptables or your kernel needs to be upgraded.
    thx.

    Reply
  5. Thanks for the script. Script successfully installed OpenVPN on my Ubuntu 14.04 VPS and it is working perfectly.
    I edited script to use TCP 443, instead of UDP 1194.

    Reply
  6. Script is very nice, but one note. The average user might want to first modify the certificate validity period for the Server and CA. The script has the client certificates only good for 365 days. I was running a server that was setup with this and it took me a while to determine why the client stopped connecting almost exactly a year after I started it.

    Just change the -days parameter under “# Generate CA Config” and “# Generate Server Config” from 365 to something like 3650.

    Reply

Leave a Comment