How to Install OpenVPN and PPTP on RHEL v7

This procedure can be used to install OpenVPN and/or PPTP VPN access on a RHEL/CentOS v7 server or virtual server.

For OpenVZ you require root access to the physical server or a service provider willing to enable virtual server access to tun (OpenVPN) and ppp (PPTP) on the physical server.  Full hardware virtualization such as KVM or VMware is the same as a physical server for this procedure and does not require access to the physical server.

This install procedure was tested on CentOS v7.1 64bit.

Let’s get started

It is assumed you already have a server with a base CentOS v7 installation before you begin.  Do NOT install a GUI such as Gnome or KDE.  If you already have a desktop or server GUI installed you will want to exit to console mode.  You do that by typing  systemctl isolate multi-user.target from a terminal or console window as root.  All instructions in this guide are assuming you are logged in as root user.

OpenVPN

Check if tun is active.  This is required for the OpenVPN server to function.

cat /dev/net/tun

If you see File descriptor in bad state that is ok.  If you see something like device not found or No such file or directorythat means tun is not active and needs to be loaded.  With root access to the physical server load tun.

modprobe tun
at which point
lsmod | grep tun
should return something like
tun    19221  2

It will not return anything in an OpenVZ container.

Create a file so that this occurs automatically on reboot.  Again, this needs to be done on the physical server. Not on a virtual server unless it is full hardware virtualization such as KVM and VMware.

nano /etc/sysconfig/modules/vpn.modules
#!/bin/sh
/sbin/modprobe tun

Make it executable

chmod +x /etc/sysconfig/modules/vpn.modules

If you are using a virtual server on OpenVZ you will instead need to do the following on the physical server. Change CTID=101 to your container ID):

CTID=101
vzctl set $CTID --devnodes net/tun:rw --save
vzctl set $CTID --devices c:10:200:rw --save
vzctl set $CTID --capability net_admin:on --save
vzctl exec $CTID mkdir -p /dev/net
vzctl exec $CTID chmod 600 /dev/net/tun

Reboot the virtual server afterwards.

Install EPEL

yum install epel-release

Install OpenVPN

yum install openvpn easy-rsa

Configure OpenVPN

nano /etc/openvpn/server.conf
# see /usr/share/doc/openvpn*/sample/sample-config-files/server.conf
# for explantions of the following options

port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
log-append  /var/log/openvpn.log
verb 3
​Create keys directory and copy certificate generation scripts
mkdir -p /etc/openvpn/easy-rsa/keys
cp -rf /usr/share/easy-rsa/2.0/* /etc/openvpn/easy-rsa
cp /etc/openvpn/easy-rsa/openssl-1.0.0.cnf /etc/openvpn/easy-rsa/openssl.conf

Generate keys

cd /etc/openvpn/easy-rsa
source ./vars
./clean-all

Generate Certificate Authority (ca)

./build-ca 
Country Name: may be filled or press enter
State or Province Name: may be filled or press enter
City: may be filled or press enter
Org Name: may be filled or press enter
Org Unit Name: may be filled or press enter
Common Name:your server hostname
Email Address: may be filled or press enter
 

Generate certificate & private key for server

./build-key-server server

Almost the same as build.ca

Common Name: server 
A challenge password: leave blank
Optional company name: fill or enter 
sign the certificate: y
1 out of 1 certificate requests: y

Generate Diffie Hellman parameters

./build-dh

Generate client key and certificate

./build-key client

Use same values used for ./build-key-server server

Copy keys and certs from working directory to openvpn directory

cp /etc/openvpn/easy-rsa/keys/{dh2048.pem,ca.crt,server.crt,server.key} /etc/openvpn/

See if openvpn starts

systemctl start openvpn@server.service
systemctl status openvpn@server.service

if this doesn’t work double check the server.conf file

configure start on reboot

systemctl enable openvpn@server.service

OpenVPN client setup

The following 3 files in /etc/openvpn/easy-rsa/keys/ are used when creating the Windows client .ovpn file

ca.crt
client.crt
​client.key

Download and install the OpenVPN Windows client from the OpenVPN website.  

NOTE: You MUST run OpenVPN Windows client on Windows as Administrator.  To do that right click OpenVPN-GUI Icon and select “Run as Administrator” .  Set it permanently by right clicking the executable at /Program Files/OpenVPN/bin/OpenVPN-GUI.exe and selecting Properties>Compatibility>Run this program as an administrator.  If you do not do this OpenVPN may not work properly.

Create the following file on your Windows computer called (for example) client.ovpn in C:\Program Files\OpenVPN\config.  Replace the text between the BEGIN and END CERTIFICATE heading with the text from the 3 relevant files.

client
dev tun
proto udp
# Replace xx.xx.xx.xx with your server IP address
remote xx.xx.xx.xx 1194
resolv-retry infinite
nobind
persist-key
persist-tun
comp-lzo
verb 3

# Replace the following text with the text between those headings in the 3 relevant files

# From ca.crt
<ca>
-----BEGIN CERTIFICATE-----
MIIFEjCCA/qgAwIBAgIJALmkJPlIH5kjMA0GCSqGSIb3DQEBCwUAMIG2MQswCQYD
VQQGEwJVUzELMAkGA1UECBMCQ0ExFTATBgNVBAcTDFNhbkZyYW5jaXNjbzEVMBMG
...
...
...
MZShMROii2k9pBA+VLtZktAz2hCDR2LdLYiLkB2XVv4NAzz1iQuwnu0wEseRE3
t87lUzzGo1leTt9zw6bBtziG+QjoYzwOxmLGHXOnAiZT/gA3GxeJxklNLV4fAj3b
KwGWMsf2
-----END CERTIFICATE-----
</ca>

# From client.crt
<cert>
-----BEGIN CERTIFICATE-----
MIIFTzCCBDegAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBtjELMAkGA1UEBhMCVVMx
CzAJBgNVBAgTAkNBMRUwEwYDVQQHEwxTYW5GcmFuY2lzY28xFTATBgNVBAoTDEZv
...
...
...
DATGLLOgInsdrL8vbddKUiALO32ykHzIGIj3gyqgFtQ4LuCRlyXBfBlFy0N1G1
EsTp7dvCR5UC6BPEO5RRb0jvAw==
-----END CERTIFICATE-----
</cert>

# From client.key
<key>
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDI53GB/fU7eYhY
I2WUENYSgk0H+eP1GU0weVUpqDq69+TsrKW1VnrPe+SreKQWk8eVTJPF9CxLk7hx
...
...
...
EjpzrfBb/+Sbl1ymlJ2XtKQB6nJXtmbEqouYNcST2z/sKmsBX75u1ZWvF82QK1
wQgvMGG0Isrih2y1qZ4UGmtnKw==
-----END PRIVATE KEY-----
</key>

If not installing PPTP go down to the Common Configuration section which is mandatory for both methods.

PPTP

yum install ppp
pppd

You should see gibberish similar to the following which will continue for about 30seconds then return to command prompt. ~�}#�!}!}!} }4}"}&} } } } }%}&)Q�}4}'}"}(}"p}) If you get an error message instead you may need to load the ppp modules on the physical server.

modprobe ppp_async
modprobe ppp_deflate
modprobe ppp_mppe
at which point
lsmod | grep ppp
should return something like
ppp_mppe               13002  0
ppp_async              17413  0
crc_ccitt              12707  1 ppp_async
ppp_generic            33037  2 ppp_mppe,ppp_async
slhc                   13450  1 ppp_generic

It will not return anything if inside an OpenVZ VPS container.

Create a file or add to existing file so that the ppp modules are automatically loaded on boot.  If using OpenVZ this needs to be done on the physical server.
nano /etc/sysconfig/modules/vpn.modules
#!/bin/sh
/sbin/modprobe ppp_async
/sbin/modprobe ppp_deflate
/sbin/modprobe ppp_mppe

Make it executable

chmod +x /etc/sysconfig/modules/vpn.modules

If you are using a VPS on OpenVZ virtual server you also need to do the following on the physical server so that the VPS container can use the ppp device (change CTID=101 to your container ID):

CTID=101
vzctl set $CTID --features ppp:on --save
vzctl set $CTID --devices c:108:0:rw --save
vzctl exec $CTID mknod /dev/ppp c 108 0
vzctl exec $CTID chmod 600 /dev/ppp

Reboot the virtual server afterwards.

Install the following required packages on server or OpenVZ virtual server

yum install yum install gcc make rpm-build autoconf.noarch zlib-devel pam-devel openssl-devel ppp

Install EPEL

yum install epel-release

Install pptp

yum install pptpd

Configure pptp

nano /etc/pptpd.conf
option /etc/ppp/options.pptpd
logwtmp
# replace the following with your server IP
localip 11.22.33.44
# replace the following with the desired private IP
# and range handed out to connecting pptp clients
# the private IP should not be on the same subnet
# as openvpn to avoid problems.
remoteip 10.10.0.1-100

Add DNS servers

nano /etc/ppp/options.pptpd

make sure the following google DNS servers are added or use alternative DNS servers.

ms-dns 8.8.4.4
ms-dns 8.8.8.8
nano /etc/ppp/chap-secrets
username1  pptpd  password1  *
username2  pptpd  password2  *
where the format is [username] [space] [server] [space] [password] [space][IP addresses]

Check that pptpd starts

systemctl start pptpd
systemctl status pptpd

enable start on reboot

systemctl enable pptpd

The following Common Configuration section is mandatory.

Common configuration for OpenVPN and PPTP

Disable firewallD and enable iptables

systemctl mask firewalld
systemctl stop firewalld
yum install iptables-services
systemctl enable iptables
systemctl start iptables

Configure IPTables NAT. This is required for OpenVPN and PPTP and not using an OpenVZ virtual server.

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

If using an OpenVZ virtual server

iptables -t nat -A POSTROUTING -j SNAT --to-source 11.22.33.44

and replace 11.22.33.44 with your virtual server ip.

If you have other iptables rules that prevent everything by default you also need to open up the required ports.  PPTP also requires gre protocol enabled (ie. iptables -A INPUT -i eth0 -p gre -j ACCEPT)

Save iptables rules

/usr/libexec/iptables/iptables.init save

Enable IP packet forwarding This is required for Openvpn and pptp

nano /etc/sysctl.conf

and change the following line

net.ipv4.ip_forward = 1

run the following to enable the change immediately

sysctl -p

Troubleshooting PPTP

If you have problems connecting to some websites via pptp such as godaddy.com whereas other websites such as google.com work fine you may have an mtu problem.  

If you do a search you will find a lot of posts instructing people to add an mtu setting to various configuration files.  However, none of that seems to affect the mtu setting of the ppp device that is created when clients connect.  To see if you have this problem do an ifconfig while a pptp client is connected.  You will see a venet0 or eth0 device with an mtu of 1500 or perhaps some other number.  However your mtu for the connected client (first client is ppp0, second is ppp1 etc.) device might be something like 1396.

In order to verify this fix works, from command line type ifconfig ppp0 mtu 1500 assuming we want to fix the first connected client (ie. ppp0) and assuming our mtu for venet0 or eth0 is 1500.  If that works add the following to /etc/ppp/ip-up to make it permanent. Alternatively, create a separate file /etc/ppp/ip-up.local and chmod +x /etc/ppp/ip-up.local and add the following.

/sbin/ifconfig $1 mtu 1500

Where “$1” is the pppX variable of each connecting client as assigned in /etc/ppp/ip-up script. Change the 1500 to whatever mtu your venet0 or eth0 is set to.  If you try put that mtu setting somewhere else such as /etc/ppp/options.pptpd or /etc/ppp/options it will NOT effect the mtu setting of connecting clients and therefore will not solve this particular problem.