https://help.ubuntu.com/12.04/serverguide/openvpn.html
http://openvpn.net/index.php/open-source/documentation/howto.html
http://openvpn.net/index.php/open-source/documentation/manuals/65-openvpn-20x-manpage.html
- Public Key Infrastructure (PKI) / pre-shared keys
- Routed / Bridged mode
- Routing probably better for most people - efficient and easier to set up; greater ability to selectively control access rights
- Bridged - handle non-IP such as IPX; applications over VPN rely on network broadcasts; allow browsing of windows file shares (also rely on broadcasting)
- UDP or TCP (read somewhere UDP is default and faster)
- Port number - configurable, 1194 default, only one single port is used for all communication
- PKI
- A pair of certificate / private key for server and each client
- CA certificate and private key for signing
- Bi-directional authenticate (both server and client authenticate each other)
- Avoid using 10.0.0.0/24 or 192.168.0.0/24 - easy to conflict with Wifi cafe, airport, hotel, etc.; use subnets in the middle of vast 10.0.0.0/8 block
OpenVPN Scripts
OpenVPN provided a set of scripts for creating the PKI and certificates. And different sets of scripts are used for OpenVPN 2.2.x and 2.3.x.
CA Preparation using OpenVPN provided scripts:
- Copy the easy-rsa dir to a secure location (like an encrypted volume)
- There is a bug in "whichopensslcnf" preventing it to detect openssl 1.0.1. Change the line detecting 1.0.x version to add an option mark ("?") after the alnum pattern.
- ./clean-all
- ./build-ca
Server Certificates:
- ./build-key-server server.common.name
- ./build-dh (this generates DH parameters for the server side, output is a key named dh${KEY_SIZE}.pem, for example dh1024.pem; this is the "DH public parameter" that each side rely on.)
Client Certificates:
- ./build-key client_name (client key and cert only required on client machine, remove from server)
Own CA
It's ok to use existing CA infrastructure and the issued certificates should work in standard condition.
If configure as mentioned in "Additional Security Notes", where client verify server certificate and prevent one client certificate being used in man-in-middle attack, certain usages should be built into server certificate. If plan to do this, further details should be found in the HOWTO and the scripts provided from OpenVPN.
Configuring Server and Clients
Best to use the sample configuration files as starting point. It's "sample-config-files" in /usr/share/doc/openvpn/examples/
Sample Server Configure File:
- create a VPN using a virtual TUN interface (for routing)
- listen for client connections on UDP 1194
- distribute virtual addresses to connecting clients from 10.8.0.0/24 subnet
- ca, cert, key, dh parameters to be edited to point to the generated files
- ----- should be usable to this point, below is optional -----
- if using Ethernet bridging - use server-bridge and "dev tap" instead of server and "dev tun"
- if want to listen on a TCP port - use "proto tcp" instead of "proto udp"; possible to listen on both with two instances
- if want to use other virtual IP range - edit "server" directive; it should be a private range unused on network
- if want clients being able to reach each other - uncomment "client-to-client"
- improve security - uncomment "user nobody" and "group nobody"
- multiple instances - use different configure file, mind to use different output files (i.e. logs, etc.)
Sample Client Configure File:
- edit ca, cert, key parameters
- edit "remote" directive to point to the hostname / IP and port number (ok if behind NAT)
- check "dev" (tun / tap) and "prop" (udp / tcp) to be consistent with server
- if "comp-lzo" and "fragment" is used, it's present in both client and server config files
Start up and test for initial connectivity
Setup firewall to make VPN server port accessible; make sure TUN/TAP interface not firewalled (iptables);
Test server start up, run "openvpn [server config file]"; should end with "Initialization Sequence Completed" message
Test client start up, run "openvpn [client config file]"; normal client start up will look similar to the server output and should end with "Initialization Sequence Completed" message;
If using routing, ping server "dev tun" address, for example "ping 10.8.0.1"; if using bridging, try to ping the IP address of a machine on the server's subnet;
The openvpn howto page gave some troubleshooting advises if something fail.
Automatic OpenVpn Start up depends on platform;
Control a Running Process
Following signals are accepted. Or try packaged control script.
SIGUSR1 -- Conditional restart, designed to restart without root privileges
SIGHUP -- Hard restart
SIGUSR2 -- Output connection statistics to log file or syslog
SIGTERM, SIGINT -- Exit
Expand the scope of VPN beyond two ends (Routed)
For client to communicate with any machine on server LAN and for other machine on server LAN to communicate with client or client LAN:
Server can push route to its subnet to client, with a directive in server-side configuration file:
push "route 10.66.0.0 255.255.255.0"
Then, on server LAN gateway, set up a route to route VPN client subnet to the server (if OpenVPN sever is not also the gateway) : this is for the return packages;
Make sure IP and TUN/TAP forwarding on serve machine is enabled.
For any machine on client LAN (so client maybe like a star office) to be able to communicate with any machine on server LAN:
- any subnet must not conflict
- client must have a unique Common Name in its certificate, for example "client2"
- the "duplicate-cn" flag must NOT be used in the OpenVPN server configuration file.
- make sure IP and TUN/TAP forwarding is enabled on client machine
- add reference to a client configuration directory on server configuration file, "client-config-dir ccd" (ccd is the name of a directory pre-created in the default directory where OpenVPN server daemon runs, on Linux this tends to be /etc/openvpn". When a new client connects to OpenVPN sever, daemon will check this directory for a file which matches the common name of the connecting client; if the file is found, it will be read and processed for additional configuration file directives to be applied to the named client.
- create a file matching the client (for example, "client2" in "ccd" dir), contain the line such as: "iroute 192.168.4.0 255.255.255.0" - telling server that the subnet should be routed to client2
- add a line to the MAIN serve configuration file (not client file) "route 192.168.4.0 255.255.255.0" - this controls the routing from kernel to OpenVPN server
- if want to allow computers on client2's subnet to communicate with other clients of the OpenVPN server - add two lines: "client-to-client" and 'push "route 192.168.4.0 255.255.255.0"'; this cause OpenVPN server to advertise client2's subnet to other connecting clients
- if OpenVPN server is not the gateway of the server-side LAN, add a route to the server's LAN gateway (or each machine of the server's LAN); similarly client LAN needs the same
Server can push DHCP options to clients, see "howto".
Basic approach:
- segregate user class into its own virtual IP address range
- define static unit number for tun interface, for example put "dev tun0" into server configure file
- define address pool, for example "server 10.8.0.0 255.255.255.0"
- add routes for all virtual IP address ranges "route 10.8.1.0 255.255.255.0"
- use client configuration directory "client-config-dir ccd"
- place configuration files in ccd to define fixed IP address for each client: "ifconfig-push 10.8.1.1 10.8.1.2" each pair of addresses represent virtual client and server IP endpoints and must be taken from successive /30 subnets in order to be compatible with some client and driver; so the last octet must be in a list from [1,2] [5,6] [9,10] [13,14] [17,18] ...
- control access by setting up firewall rules
- define firewall rules (like iptables) to control access : "iptables -A FORWARD -i tun0 -s 10.8.0.0/24 -d 10.66.4.4 -j ACCEPT"
Password User Authentication
Add "auth-user-pass" directive to client configuration so client will ask user for username/password and send to server.
Configure server to use an authentication plugin - it can be a script, shared object or DLL; the plugin returns (1) for failure or (0) for success.
See manual for further description.
Authentication by certificate may allow someone holding a legitimate client certificate to impersonate server. The "howto" provided means to prevent this.
- most "preferable" means is to (1) when issuing server key, mind to build with specific key usage and extended usages (2) add "remote-cert-tls server" into client configuration
- most convenient: use "tls-remote" to accept server connection based on common name of server certificate