OpenVPN server and CentOS
OpenVPN is the de facto standard VPN free open source software; it is widely used, tested, well documented and also included in the CentOS repos (EPEL).
.:. Server side configuration
yum install openvpn easy-rsa dnsmasq
When yum is done installing the required packages, copy the sample config file.
cp /usr/share/doc/openvpn-*/sample/sample-config-files/server.conf /etc/openvpn
Uncomment/edit the following lines in /etc/openvpn/server.conf:
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh4096.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1"
push "dhcp-option DNS 10.8.0.1"
keepalive 10 120
tls-auth ta.key 0 # This file is secret
key-direction 0
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-CBC-SHA256
auth SHA512
cipher AES-256-GCM
#comp-lzo # Disable LZO compression
persist-key
persist-tun
status openvpn-status.log
;log openvpn.log # disable log, optional
;log-append openvpn.log # disable log, optional
user nobody
group nobody
Now, create two folders easy-rsa/keys in /etc/openvpn and copy some files into them:
mkdir -p /etc/openvpn/easy-rsa/keys
cp -rf /usr/share/easy-rsa/3/* /etc/openvpn/easy-rsa
Edit the following file and add these lines at the bottom of it:
vi /etc/openvpn/easy-rsa/vars
---
export KEY_COUNTRY="***"
export KEY_PROVINCE="***"
export KEY_CITY="***"
export KEY_ORG="***"
export KEY_EMAIL="***"
export KEY_CN=***
export KEY_NAME=***
export KEY_OU=***
Now it is time to build our own Certificate Authority:
cd /etc/openvpn/easy-rsa
source ./vars
./clean-all
./build-ca
NOTE: in case CentOS fail to detect OpenSSL version manually copy openssl-version_used.cnf file to /etc/openvpn/easy-rsa/:
cp /etc/openvpn/easy-rsa/openssl-1.0.0.cnf /etc/openvpn/easy-rsa/openssl.cnf
The next step consist in creating the certificate for the server, a Diffie Hellman key and then copy them in to the parent folder (/etc/openvpn):
./build-key-server server
./build-dh
cd /etc/openvpn/easy-rsa/keys
cp dh4096.pem ca.crt server.crt server.key /etc/openvpn
cd /etc/openvpn
openvpn --genkey --secret ta.key
Build a certificate for each client (replace “client” with the hostname of the client or something that can be used to identify it):
cd /etc/openvpn/easy-rsa
./build-key client
Enable IPv4 forwarding in /etc/sysctl1.conf:
vi /etc/sysctl.conf
net.ipv4.ip_forward = 1
Configure dnsmasq to resolve domain names:
vi /etc/dnsmasq.conf
---
listen-address=127.0.0.1, 10.8.0.1
bind-interfaces
Edit systemd unit script to instruct dnsmasq to wait for tun0 to be up:
cp /usr/lib/systemd/system/dnsmasq.service /etc/systemd/system
vi /etc/systemd/system/dnsmasq.service
---
[Unit]
Wants=sys-devices-virtual-net-tun0.device
After=sys-devices-virtual-net-tun0.device
Apply settings, start dnsmasq, start OpenVPN daemon and set it to automatically start at boot with:
/sbin/sysctl -p
service openvpn start
chkconfig openvpn on
## or, if using CentOS 7
systemctl enable dnsmasq
systemctl start dnsmasq
systemctl enable openvpn@server
systemctl start openvpn@server
Last thing to do is instruct iptables to allow connections on UDP ports 53 and 1194 and properly route requests:
iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o tun0 -j ACCEPT
iptables -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 1194 -j ACCEPT
service iptables save
service iptables restart
Other useful commands are:
### list the current rules, tables and chains
service iptables status
### delete the first (1) line of Table=nat and Chain=POSTROUTING
iptables -t nat -D POSTROUTING 1
### search and delete the matching rule
iptables -D INPUT -p udp -m udp --dport 1194 -j ACCEPT
### check open connections
netstat -lnptu
.:. Client certificate revoke/unrevoke
To revoke a client’s certificate run the following commands:
cd [easy-rsa path]
source ./vars
./revoke-all [certificate name]
Unrevoke a client’s certificate requires a few steps to be completed:
cd [easy-rsa path]
source ./vars
cd keys
# Unervoke a specific certificate
vi index.txt
---
# R in the first column means that the cert is revoked, V stands for verified
# To UNREVOKE a certificate replace the R with a V and then rebuild the CRL
---
# Rebuild the CRL
openssl ca -gencrl -out "crl.pem" -config "$KEY_CONFIG"
.:. Client side configuration
First of all we have to retrieve the certificates from the server and put them in a folder called “.cert” located in the user’s home directory, I suggest using SCP or rsync to move the files from server to client (an SSH server must be installed and configured).
scp file... user@host.domain:path
scp user@host.domain:path ... dest
In Fedora 18 + XFCE configuration is all done via GUI, open the Network Manager
(from the tray or from Applications Menu) and add a new VPN. Set a VPN name, a
gateway (IP address of the server), import the keys and, from Advanced menu,
set LZO data compression to “no”.
If SELinux is enabled we should also apply the correct security context to our
keys, in my case the keys are in “/home/mafio/.cert”, so “chcon -t cert_t
/home/mafio/.cert/*”.
This is it, you should now be able to connect to the VPN server and reach the
internet through it.
The standalone way to connect to an OpenVPN server is create a file called
“client.ovpn” containing what follows:
client
dev tun
remote vpn_server_IP_address 1194 udp
connect-retry 2 300
resolv-retry 60
nobind
# Downgrade privileges after initialization (non-Windows only)
user nobody
group nobody
#persist-key
persist-tun
key-direction 1
remote-cert-tls server
cipher AES-256-GCM
tls-cipher TLS-DHE-RSA-WITH-AES-256-CBC-SHA256
auth SHA512
verb 3
script-security 2
up /etc/openvpn/client.up
down /etc/openvpn/client.down
tls-client
auth-nocache
### keys ###
;ca ca.crt
;tls ta.key
;cert op3.crt
;key op3.key
### Content of ca.crt
<ca>
---
</ca>
### Content of ta.key
<tls-auth>
---
</tls-auth>
### Content of client.crt
<cert>
---
</cert>
### Content of client.key
<key>
---
</key>
Script client.down and client.up can be found in
/usr/share/doc/openvpn/contrib/pull-resolv-conf/ and are used to enforce DNS
pushed by OpenVPN server.
To use the VPN simply run the following command:
sudo openvpn --config ~/path/to/client.ovpn