Published: 18. 5. 2016   Category: GNU/Linux

OpenVPN administration in nutshell

If you are into a setup/administration of OpenVPN, I suggest to get a copy of book Jan Just Keijser: OpenVPN 2 Cookbook from PACKT Publishing. It helped me a lot to setup my first OpenVPN.

Client installation for several operating systems

GNU/Linux

  1. Install OpenVPN client:
    • Redhat based distros: yum install openvpn
    • Debian based distros: apt-get install openvpn
  2. (Optional.) Enable pulling of DNS configuration:
    • Redhat base distros: cp /usr/share/doc/openvpn/contrib/pull-resolv-conf/client.* /etc/openvpn; chmod a+x /etc/openvpn/client.*
    • Debian base distros: chmod a+x /etc/openvpn/update-resolv-conf
    • Check content of /etc/nsswitch.conf, line hosts: ‘dns’ must by right after ‘files’ and preced all other options!
      hosts: files dns mdns4_minimal [NOTFOUND=return] myhostname mymachines
  3. As user root: service openvpn start (config file must be in /etc/openvpn/*.conf)
  4. As normal user: openvpn --config YOUR_CONFIG.conf

Mac OS X

Tunnelblick (GUI)

  1. Download the Tunnelblick disk image file (a ".dmg" file) from tunnelblick.net.
  2. Install Tunnelblick.
  3. Optional: Fix permission on application and library folder. (See Help section in the error message window appear.)
  4. Comment log-append line in openvpn*.conf file.
  5. Double click on openvpn*.conf file and check in Tunnelblick window.
  6. Press Connect button to establish VPN connection.
  7. Check “Do not check for IP address changes” when Warning message appears. If the VPN access is only for private networks your IP address will remains same.

OpenVPN (CLI)

  1. Install brew package manager: ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null
  2. Install openvpn: brew install openvpn
  3. Disable IPv6 (sometimes it is very slow with IPv6 enabled in non-IPv6 network): networksetup -setv6off wi-fi
  4. Start openvpn: sudo /usr/local/Cellar/openvpn/2.3.10/sbin/openvpn --config YOUR_CONFIG.conf

Enable OpenVPN tunnel control for non-admin user with sudo

  1. Edit and save user tunnel configuration: ~/.ssh/openvpn.conf
  2. As admin: create script /usr/local/bin/server-vpn
    #!/bin/bash
    # OpenVPN client from Home Brew (brew install openvpn)
    OPENVPN=/usr/local/Cellar/openvpn/2.3.10/sbin/openvpn
    
    # OpenVPN client from TunnelBlick
    #OPENVPN=/Applications/Tunnelblick.app/Contents/Resources/openvpn/openvpn-2.3.6/openvpn
    
    # Your personal configuration with SSL certificate
    CONF=~/.ssh/openvpn.conf
    
    # Log file
    LOG=/var/log/openvpn.log 
    
    # Make log file readable for user
    touch $LOG; chmod 644 $LOG
    
    # Run tunnel
    $OPENVPN --config $CONF | tee $LOG
    
  3. As root, enable non-admin user to execute the script:
    1. Edit: /etc/sudoers
    2. Add: USER_LOGIN ALL=(root) NOPASSWD: /usr/local/bin/server-vpn
  4. As normal user start the tunnel in a new terminal window: sudo /usr/local/bin/server-vpn
  5. To disable tunnel press Ctrl+c in terminal window.
  6. To troubleshoot possible problems the script enables OpenVPN log to stdout and /var/log/openvpn.conf.

MS Windows

  1. Download and install OpenVPN installer for 32/64 bit.
  2. Start OpenVPN as administrator:
    • GUI:
      1. Copy configuration file into C:\Program Files\OpenVPN\config directory with *.ovpn extension.
      2. Start Menu ⟶ All Programs ⟶ OpenVPN ⟶ OpenVPN GUI
    • CLI: C:\Program Files\OpenVPN\bin\openvpn.exe --config YOUR_CONFIG.conf

Example client configuration

With option pull, all other settings are pushed from server (remote) to client, most important of them are routing tables for private network behind VPN routing packets through VPN tunnel. I was playing also with pushing of DNS settings, but it needs 3rd party script to modify current operating system and they are also different on each Linux distribution.

tls-client
dev tun
port 1194
remote openvpn.server.com
pull # Allow pulling routing tables from server
# Allows change DNS settings (see OpenVPN tunnel client start):
#script-security 2
#up /etc/openvpn/client.up
#down /etc/openvpn/client.down
#UBUNTU up /etc/openvpn/update-resolv-conf
#UBUNTU down /etc/openvpn/update-resolv-conf

log-append /var/log/openvpn.log
verb 3
<cert>
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
</key>
<ca>
-----BEGIN CERTIFICATE-----        
...               
-----END CERTIFICATE-----                       
</ca>

Client troubleshooting

Internet doesn’t work after VPN tunnel started

Check settings of your local network IP range, it must not collide with tunnel and private IP ranges!

Server installation on GNU/Linux

  1. Make sure that your network infrastructure forward default 1194 TCP/UDP port to OpenVPN server and it is accessible (e.g for everybody 0.0.0.0/0).
  2. Install RPMs: yum install openvpn easy-rsa
  3. Create directory for key storage: mkdir /root/ssl_keys/keys
  4. Setup easy-rsa scripts via environment variables, example:
    export EASY_RSA=/usr/share/easy-rsa/2.0/
    export KEY_SIZE=2048
    export KEY_DIR=/root/ssl_keys/keys
    export KEY_CONFIG="$EASY_RSA/openssl-1.0.0.cnf"
    export KEY_COUNTRY="CA"     
    export KEY_PROVINCE="Nova Scotia"
    export KEY_CITY="Halifax" 
    export KEY_ORG="Your company." 
    export KEY_EMAIL="engineering@company.com" 
    export KEY_OU="Engineering"
    export PKCS11_MODULE_PATH="dummy"
    export PKCS11_PIN="dummy"
    export OPENSSL=/usr/bin/openssl
    
  5. Save these variables to file /root/ssl_keys/vars, later can by invoked by source /root/ssl_keys/vars
  6. easy-rsa utils are installed in: cd /usr/share/easy-rsa/2.0
  7. Generate Certificate authority key and certificate: ./build-ca
  8. Enable packet forwarding: /sbin/sysctl -w net.ipv4.ip_forward=1; /sbin/sysctl -w net.ipv4.conf.default.rp_filter=1
  9. Enable NAT:
    • Allow tun interface: iptables -A INPUT -i tun+ -j ACCEPT
    • All packets comming from tunnel are from subnet defined in server configuration 10.200.0.xxx: iptables -t nat -A POSTROUTING -s 10.200.0.0/24 -o eth0 -j MASQUERADE
    • Configuration is stored in /etc/sysconfig/iptables: iptables-save >/etc/sysconfig/iptables
  10. Routing tables around private network can be stored in /etc/sysconfig/network-scripts/route-eth0 or they are handled on other network devices. However they need to be defined in server configuration and passed to clients.

Example of OpenVPN server configuration

Configuration is stored in /etc/openvpn/openvpn.conf:

port 1194
proto udp
multihome
dev tun
user nobody
group nobody
server 10.200.0.0 255.255.255.0
mode server
verb 3
log-append /var/log/openvpn.log
persist-key
persist-tun
keepalive 10 60
push "route 192.168.254.0 255.255.255.0" # prod-vpc-ops
push "route 10.121.0.0 255.255.0.0"      # proc-vpc-db
push "route 10.105.0.0 255.255.0.0"      # proc-vpc-db
push "route 10.254.0.0 255.255.255.0"
push "route 172.31.0.0 255.255.0.0"
ifconfig-pool-persist /var/run/ipp.txt
client-to-client
tls-server
ca /etc/openvpn/ca.crt
cert /etc/openvpn/ca.crt
key /etc/openvpn/ca.key
dh /etc/openvpn/dh2048.pem
crl-verify /etc/openvpn/crl.pem

Handling OpenSSL certificates

Create client certificate

# cd /root/ssl_keys
# source ./vars
# ./build-key-pass USER_ID

There will be several files generated in ./keys:

Certificates can be part of client configuration, update <cert> and <key> part in client configuration file. Forward configuration to client.

Disable client certificate on server

# cd /root/ssl_keys
# source ./vars
# ./revoke-full USER_ID
# cp keys/crl.pem /etc/openvpn
# service openvpn reload