ag@linux:~$

history 16 of 36

How to Install OpenVPN on CentOS 6

My 2014 notes on installing OpenVPN on CentOS 6 with easy-rsa 2.0 certificates and PAM login, with corrections and notes on what to use today.

Written

From my Linux study notes, 2014. Some commands and versions here are old, so please reuse them carefully. Anything marked "added later", and the notes at the end, explain what has changed since.

Please read this first (added later): this is a historic post. It was written for CentOS 6, which reached end of life on 30 November 2020, and for OpenVPN 2.3 with the old easy-rsa 2.0 scripts. Several download links below point to sites or repositories that are no longer maintained, and some settings are weak by today’s standards. I have kept the steps as a record of how I did it, with corrections. For a new VPN, use a current OpenVPN package and its documentation for your system, or WireGuard (see the notes at the end).

How to install a VPN on CentOS. (My original heading said “from source”, but only the LZO library is rebuilt here; OpenVPN itself is installed from a package repository.)

Before you start

  • A test CentOS 6 server with root access. My commands are as I ran them, as root.
  • A firewall that lets UDP port 1194 through to the server (the port used in the config below).

Install the packages

  1. Make sure you have these packages installed:

    Terminal window
    yum install gcc make rpm-build autoconf.noarch zlib-devel pam-devel openssl-devel -y

    These are the compiler and build tools needed to rebuild the LZO package in the next steps. -y answers yes to the install prompt.

  2. Download the LZO source RPM and the RPMForge repository package (the release numbers can be different):

    Terminal window
    wget http://openvpn.net/release/lzo-1.08-4.rf.src.rpm
    wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.i686.rpm

    Note (added later): RepoForge (RPMForge) is no longer maintained, and these links may no longer work. The i686 package is for 32-bit systems; a 64-bit system would need the x86_64 package. LZO is a compression library used by OpenVPN.

  3. Build the RPM packages and install them:

    Terminal window
    rpmbuild --rebuild lzo-1.08-4.rf.src.rpm
    rpm -Uvh lzo-*.rpm
    rpm -Uvh rpmforge-release*

    Note (added later): rpmbuild --rebuild puts the finished packages under ~/rpmbuild/RPMS/ in a folder named after your architecture, not in the current folder. Change into that folder (or give the full path) before running rpm -Uvh lzo-*.rpm. rpm -Uvh installs or upgrades a package and shows progress.

  4. Install OpenVPN:

    Terminal window
    yum install openvpn -y

Get easy-rsa

Now check whether you have the easy-rsa folder. Look in this location: /usr/share/doc/openvpn-2.3.1/easy-rsa. (The version number in the path depends on the OpenVPN version you installed.)

If you do not have the easy-rsa folder, download it from the link below:

Terminal window
wget https://github.com/downloads/OpenVPN/easy-rsa/easy-rsa-2.2.0_master.tar.gz

Make sure you have /usr/share/doc/openvpn-2.3.1/easy-rsa, or the downloaded copy, and copy it into /etc/openvpn/:

Terminal window
cp -R easy-rsa-2.2.0_master/easy-rsa/ /etc/openvpn/

Note (added later): extract the download first with tar -xzf easy-rsa-2.2.0_master.tar.gz. If you are using the copy from /usr/share/doc, copy that folder instead.

Please note that on CentOS 6 we need to make a small change before running the commands below. Open /etc/openvpn/easy-rsa/2.0/vars and change this line:

Terminal window
export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`

to this:

Terminal window
export KEY_CONFIG=/etc/openvpn/easy-rsa/2.0/openssl-1.0.0.cnf

Create the certificates

  1. Set up the easy-rsa environment:

    Terminal window
    cd /etc/openvpn/easy-rsa/2.0
    chmod 755 *
    source ./vars
    ./vars
    ./clean-all
    • source ./vars loads the settings into your current shell. Running ./vars again afterwards does nothing useful, because it runs in a separate shell; the source line is the one that matters.
    • ./clean-all deletes everything in the keys folder. Only run it on a fresh setup, never once you have keys you are using.
    • Note (added later): the vars file also sets KEY_SIZE. My setup used 1024 (the server config below points to dh1024.pem). 1024-bit keys are considered too weak today; set export KEY_SIZE=2048 (or higher) in vars before running source ./vars. The Diffie-Hellman file name then changes to match, for example dh2048.pem.
  2. Build the Certificate Authority (CA):

    Terminal window
    ./build-ca

    Answer the questions:

    • Country Name: fill in or press Enter
    • State or Province Name: fill in or press Enter
    • City: fill in or press Enter
    • Org Name: fill in or press Enter
    • Org Unit Name: fill in or press Enter
    • Common Name: your server host name
    • Email Address: fill in or press Enter
  3. Build the key for the server:

    Terminal window
    ./build-key-server server

    The questions are almost the same as ./build-ca, but check these changes and additions:

    • Common Name: server
    • A challenge password: leave blank
    • Optional company name: fill in or press Enter
    • Sign the certificate: y
    • 1 out of 1 certificate requests, commit: y
  4. Build Diffie-Hellman parameters (wait until the process finishes; it can take a while):

    Terminal window
    ./build-dh

Create the server config

  1. Create the config file:

    Terminal window
    touch /etc/openvpn/server.conf

    and add the following lines:

    port 1194 #- port
    proto udp #- protocol
    dev tun
    tun-mtu 1500
    tun-mtu-extra 32
    mssfix 1450
    reneg-sec 0
    ca /etc/openvpn/easy-rsa/2.0/keys/ca.crt
    cert /etc/openvpn/easy-rsa/2.0/keys/server.crt
    key /etc/openvpn/easy-rsa/2.0/keys/server.key
    dh /etc/openvpn/easy-rsa/2.0/keys/dh1024.pem
    plugin /usr/share/openvpn/plugin/lib/openvpn-auth-pam.so /etc/pam.d/login #- Comment this line if you are using FreeRADIUS
    #plugin /etc/openvpn/radiusplugin.so /etc/openvpn/radiusplugin.cnf #- Uncomment this line if you are using FreeRADIUS
    client-cert-not-required
    username-as-common-name
    server 10.8.0.0 255.255.255.0
    push "redirect-gateway def1"
    push "dhcp-option DNS 8.8.8.8"
    push "dhcp-option DNS 8.8.4.4"
    keepalive 5 30
    comp-lzo
    persist-key
    persist-tun
    status 1194.log
    verb 3

    A few lines explained (added later):

    • ca, cert, key and dh point to the files you created above. If you changed KEY_SIZE, change dh1024.pem to match.
    • The plugin line with openvpn-auth-pam.so makes users log in with a Linux user name and password (checked through PAM).
    • client-cert-not-required means the server does not ask clients for a certificate; they log in with a user name and password instead.
    • server 10.8.0.0 255.255.255.0 is the private address range handed out to VPN clients.
    • push "redirect-gateway def1" sends all of the client’s internet traffic through the VPN, and the two dhcp-option DNS lines tell clients to use Google’s public DNS servers.
    • comp-lzo turns on LZO compression; the client config must match.
  2. Start OpenVPN:

    Terminal window
    service openvpn start

    To start it at boot as well (added later): chkconfig openvpn on.

    Note: if OpenVPN does not start, check /var/log/messages, find the problem and start debugging.

If the PAM plugin cannot be found

You may get this error:

PLUGIN_INIT: could not load plugin shared object /usr/share/openvpn/plugin/lib/openvpn-auth-pam.so: /usr/share/openvpn/plugin/lib/openvpn-auth-pam.so: cannot open shared object file: No such file or directory

My fix at the time was to download the plugin:

Terminal window
wget http://safesrv.net/public/dl/openvpn-auth-pam.zip
unzip openvpn-auth-pam.zip
mv openvpn-auth-pam.so /etc/openvpn/openvpn-auth-pam.so

Then replace the PAM plugin line in your server.conf with this:

plugin /etc/openvpn/openvpn-auth-pam.so /etc/pam.d/login

And restart OpenVPN:

Terminal window
killall -9 openvpn
service openvpn start

Safety note (added later): do not install a compiled plugin downloaded from a third-party website. It runs inside your VPN server and handles passwords. The PAM plugin is part of the OpenVPN package itself; the error usually means the path in server.conf is wrong. Find the real path with:

Terminal window
rpm -ql openvpn | grep pam

and put that path in the plugin line. (killall -9 force-stops every openvpn process; service openvpn restart is the gentler way.)

Turn on IP forwarding

Edit /etc/sysctl.conf (my original had etc/sysctl.conf without the leading /):

Terminal window
vi /etc/sysctl.conf

and set:

net.ipv4.ip_forward = 1

This lets the server pass traffic between the VPN and the network. Apply it without rebooting with sysctl -p.

Note (added later): because redirect-gateway sends clients’ internet traffic through the server, the server’s firewall also needs a NAT (masquerade) rule for the 10.8.0.0/24 range, and must allow UDP 1194. My original notes did not cover this; check the OpenVPN documentation for your setup.

Generate client keys

Time to generate the client keys (ca.crt, client.crt, client.key):

Terminal window
cd /etc/openvpn/easy-rsa
./build-key client

or

Terminal window
cd /etc/openvpn/easy-rsa/keys
source ./vars
/build-key keyname

Correction (added later): both versions use the wrong folder, and the second is missing a . before /build-key. The scripts and vars are in the 2.0 folder, so run:

Terminal window
cd /etc/openvpn/easy-rsa/2.0
source ./vars
./build-key client

The files are created in /etc/openvpn/easy-rsa/2.0/keys/. Use a different name for each client.

Note (added later): with client-cert-not-required in the server config above, the server does not check client certificates, so clients only need ca.crt plus a user name and password. Client keys are needed only if you remove that line and use certificate login. Never share ca.key or server.key; they stay on the server.

Notes for today

  • CentOS 6 is end of life and RepoForge is no longer maintained. Rocky Linux and AlmaLinux are the common free replacements for CentOS; Debian and Ubuntu are alternatives. On a current system, install OpenVPN from your distribution’s packages (on Red Hat-family systems it is in the EPEL repository) rather than rebuilding packages by hand.
  • easy-rsa 3 replaced the separate build-ca, build-key-server and other scripts with a single easyrsa command, so the certificate steps above do not apply to it as written. Follow the easy-rsa and OpenVPN documentation for your version.
  • Some options in the config above, such as comp-lzo and client-cert-not-required, are deprecated in later OpenVPN releases. Check the manual for the version you install rather than copying this file.
  • WireGuard is a simpler modern VPN that has been part of the Linux kernel since version 5.6 (2020). For a new setup it is often easier than OpenVPN.
  • service / chkconfig became systemctl on newer systems, and yum became dnf. The OpenVPN service name and config folder layout differ between versions, so check your distribution’s documentation.
  • Documentation: https://openvpn.net/ and https://www.wireguard.com/