OpenVpnSetup
Setting up OpenVPN on a CentOS 4.8 Server
These are my notes on setting up a small company linux server to work as an OpenVPN vpn server. This machine acts as the router, public/private DNS server, and Samba server - basically the only server in the office. The clients are mainly Windows home machines. These steps should be suitable for anyone setting up a similar configuration.
Setting Up the Server
I will assume you have RPMForge set up already. Then it's a simple yum command to install openvpn:
$ sudo yum install openvpn
Next, add a firewall rules to your /etc/sysconfig/iptables
(put right before the final REJECT line):
# OpenVPN -A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 1194 -j ACCEPT
Manually insert firewall rules for initial testing:
$ sudo /sbin/iptables -nvL --line-numbers
Find in that output the number of the last line (REJECT) and use that location to insert rule:
$ sudo /sbin/iptables -I RH-Firewall-1-INPUT 21 -m state --state NEW -m udp -p udp --dport 1194 -j ACCEPT
Verify that the openvpn port is open from outside via netcat. Start a netcat server on the machine:
$ nc -u -l -p 1194
then use netcat on the outside host to connect in to your server:
$ nc -u server.example.com 1194
the text you type in the client session should appear in server session. Note that I'm setting up a udp openvpn server but you can use tcp as well In that case, open and test a tcp port instead.
Here's some helpful links to get started:
- The official OpenVPN quickstart guide.
- The official OpenVPN howto docs.
- A (somewhat outdated) howto for setting up OpenVPN.
- A tutorial on setting up mac and windows OpenVPN clients.
- A howto on setting up OpenVPN as a hulu proxy.
Create /etc/openvpn/server.conf
as follows:
# TUN driver seems simplest, but I had some problems setting windows networking up # so I switched to tap. tap is bridged, tun is routed. dev tap # UDP or TCP. No idea which is better. Clients just have to match. proto udp # 1194 is the standard openvpn port port 1194 # server keys generated via easy-rsa ca /etc/openvpn/easy-rsa/keys/ca.crt cert /etc/openvpn/easy-rsa/keys/server.crt key /etc/openvpn/easy-rsa/keys/server.key dh /etc/openvpn/easy-rsa/keys/dh1024.pem # I've got user nobody in group nobody so this seems right. user nobody group nobody # pick a random 10.8 class C. server 10.8.15.0 255.255.255.0 # these are some sort of performance optimization. persist-key persist-tun # if you leave out log-append logging goes to regular syslog. # note this means you need to do your own log rotation log-append /var/log/openvpn.log # default keepalive values? keepalive 10 120 # verbose level - 3 is pretty chatty verb 3 # This is a status file that gets updated every few minutes. # not a log file, gets erased every refresh. status /var/log/openvpn-status # give clients access to the whole work network, not just the server. push "route 192.168.10.0 255.255.255.0" # tell clients to use your internal dns server and samba wins server push "dhcp-option DNS 10.8.15.1" push "dhcp-option WINS 10.8.15.1" push "dhcp-option DOMAIN inside.example.com"
Make sure openvpn is configured to start on boot:
$ /sbin/chkconfig openvpn on
Set up custom log rotation by dropping file in /etc/logrotate.daily
:
/var/log/openvpn.log { rotate 10 copytruncate size=1m missingok }
Here's some background info on using tun vs using tap. I think that if you are going to support full windows networking it might make more sense to use tap.
Use easy-rsa to generate server keys, with some tweaks. First copy the whole easy-rsa from /usr/share/doc/openvpn:
$ sudo cp -r /usr/share/doc/openvpn/easy-rsa/2.0 /etc/openvpn/ $ sudo chmod 777 /etc/openvpn/easy-rsa/*
Aside: the whole easy-rsa thing, although well-intentioned, is super kludgey. Wish it were a little more automated. See my script below for one way to automate user key and config file generation.
Edit /etc/openvpn/easy-rsa/vars
. You should only need to change:
export KEY_COUNTRY="US" export KEY_PROVINCE="CA" export KEY_CITY="My City" export KEY_ORG="My Company" export KEY_EMAIL="[email protected]"
Note that you should probably go ahead and create that alias email address on your server just for completeness.
Before you use any of the scripts in the easy-rsa directory you need to source the vars file:
$ sudo -H -s # cd /etc/openvpn/easy-rsa # . ./vars
do this for each step below which calls a script in the easy-rsa directory.
Now you can create your certificate authority:
$ sudo -H -s # cd /etc/openvpn/easy-rsa # . ./vars # ./clean-all # ./build-ca
build-ca
will ask you some questions about how you want to set up the cert. The defaults for everything should be fine. Choose 'yes' at any prompts.
Next, create your server key:
$ sudo -H -s # cd /etc/openvpn/easy-rsa # . ./vars # ./build-key-server server
Note that when you answer the CN (common name) prompt, you should set it to server.
Generate Diffie-Hellman keypair for the server. Don't really understand this one, but do this:
$ sudo -H -s # cd /etc/openvpn/easy-rsa # . ./vars # ./build-dh
Now you are ready to create keypairs for every client. Every client machine needs a uniquely named keypair. If your users have unix usernames, use those. If they have more than one client device, use username-device
. This will make it easier to track things later on.
$ sudo -H -s # cd /etc/openvpn/easy-rsa # . ./vars # ./build-key user1 # ./build-key user2
...etc. You can use the defaults for all the questions.
I went ahead and wrapped the commands to create new client certs in some shell script automation. Save this script as /etc/openvpn/create-client-pkg:
#!/bin/bash # wrapper script to create client keys and package them up with a conf # file suitable for distribution to end user if [ $UID -ne 0 ] then echo "must be run as root" >&2 exit 1 fi if [ -z $1 ] then echo "must supply a username for only argument" >&2 exit 1 fi username=$1 export EASY_RSA=/etc/openvpn/easy-rsa cd $EASY_RSA # check if this client package already exists if grep -q "CN=$username/" $EASY_RSA/keys/index.txt then echo "keys for user $username have already been built" >&2 exit 1 fi echo "building key and conf package for $username" . ./vars # create the certificate "$EASY_RSA/pkitool" --batch $username # create a tempdir and gather the files TMPDIR=$(mktemp -d -p /root) || exit 1 cp $EASY_RSA/keys/$username.{crt,key} $TMPDIR cp $EASY_RSA/keys/ca.crt $TMPDIR # put the right names in the conf file so it's all ready for the client. # .ovpn seems the generally accepted config file extension. sed -e "s/SNOWFLAKE/$username/" /etc/openvpn/client.conf.template >$TMPDIR/client.ovpn cd $TMPDIR # zip -l to set windows line endings on files # windows client works with config file having unix line endings, but # config file is hard to read. zip -l /root/${username}-openvpn.zip * cd - # yeah I know I should trap on exit to delete this directory. Lazy. rm -rf $TMPDIR echo "/root/${username}-openvpn.zip ready for distribution"
And here's the /etc/openvpn/client.conf.template file:
# we are a client client # dev and proto must match server dev tap proto udp # change this to the public name and port of your server remote server.example.com 1194 resolv-retry infinite nobind # Try to preserve some state across restarts. persist-key persist-tun # keyfiles # SNOWFLAKE gets replaced during user zipfile generation ca ca.crt cert SNOWFLAKE.crt key SNOWFLAKE.key # Set log file verbosity. verb 3
Give that file to the external user - it contains a custom config file and their public keys. Users should be able to drop those files in the proper location on their machine and start up their vpn immediately. See the next section for client details.
Setting up Samba shares
I'm assuming the same linux server serves as a windows workgroup server in the office. Since I'm using the tap driver, windows sharing should automatically work over the vpn (after samba and firewall config are adjusted). Here's the official OpenVPN samba howto which has some details on the changes to make. Specifically, edit your /etc/samba/smb.conf
as follows:
Find the hosts allow
and interfaces
lines and add your new 10.8
vpn network so they look like this:
hosts allow = 192.168.10.0/24 127.0.0.1 10.8.15.0/24 interfaces = 192.168.10.0/24 10.8.15.0/24
Then tell samba to reload it's configuration with /etc/init.d/samba restart
Next you have to open up firewall ports. The stock linux server router firewall setup typically allows wide open connections from the internal interface, and minimal connections on the outside port. Your vpn traffic automatically ends up in the same category as your outside traffic. If you allow outside users to connect to your webserver, vpn users will also be allowed to connect to both the web server on the vpn server and to web servers on other internal machines.
Since you don't usually allow unrestricted access to windows networking by outside machines (unless you're an idiot), this means by default your vpn clients can't connect to your internal windows network. To change this, you can either
- treat the vpn interface like your internal interface and allow all traffic
or
- add special rules to partially open up your network to vpn clients.
You can't control the machines on the other end of the vpn connection so the second option seems the wiser choice. I did the following to open the internal windows network to vpn machines (based on this samba firewall article):
First I added the rules to the end of /etc/sysconfig/iptables
, right before the final REJECT:
# Allow windows share connectivity from vpn -A RH-Firewall-1-INPUT -p udp -m udp -s 10.8.15.0/24 --dport 137 -j ACCEPT -A RH-Firewall-1-INPUT -p udp -m udp -s 10.8.15.0/24 --dport 138 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp -s 10.8.15.0/24 --dport 139 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp -s 10.8.15.0/24 --dport 445 -j ACCEPT
then I inserted the rules into the running rule chain as above, to minimize service disruptions.
After all this I was able to browse and connect to internal windows network shares over the vpn.
Allowing vpn clients to use the DNS server
Don't forget that your vpn clients will need access to your internal DNS server. If your server is already acting as a nameserver for your public domain, the client will be able to look up name right away (because of the push
lines in the openvpn server config). However, clients won't be able to look up internal names until you modify your DNS server configuration. If you are running named, edit the file /etc/named.conf
and find all the zone
sections. Each of these should have an allow-query
sections detailing which networks are allowed to make dns queries. Add the VPN network to that list. For example your configuration should look something like this:
zone "10.168.192.IN-ADDR.ARPA" { type master; file "192.168.10"; allow-query { localhost; 192.168.10/24; 10.8.15/24; };
Setting Up the Client
On the mac, use the Tunnelblick client.
On the PC use the OpenVPN client client. Note that this includes the OpenVPN GUI, so you don't need to get that from the separate OpenVPN GUI website.
Setup on the Mac
Double click the Tunnelblick installer to launch it and install in /Applications.
Run Tunnelblick by launching /Applications/Tunnelblick
. When you run the application, select 'I have configuration files'. Then select 'OpenVPN Configuration' and 'Create Tunnelblick VPN Configuration'. The app will open a finder window for the configuration directory. Put the contents of the zipfile in this directory (config file and keys).
Rename the folder Empty Tunnelblick VPN Configuration on the desktop to Company.tblk. Then, double click on that folder to import into Tunnelblick. Choose 'install Configuration only for me'.
There will be a Tunnelblick icon in your menu bar on the extreme right. Click that to open the Tunnelblick menu and choose 'Connect Company'. After a moment the icon will change to an open tunnel, indicating the connection is active.
Setup on a Windows PC
Note that on Vista (and presumably Windows 7) the permission model is confusing. You have to right click on the OpenVPN app and choose 'run as administrator' to get it to work right. If you just start it normally, the vpn will start up, but the server will be unable to push the route change to your machine. This means you can only connect to the server and no other machines on the remote network.
Disable your antivirus/spyware software before installing OpenVPN on Windows, as it will likely try to block installation of the Win32 TUN driver.
Download and install the Windows VPN client from the OpenVPN website download area. Note that you should probably just use the latest beta version. In fact that's probably the only version (2.2) that works with Windows Vista as of February 2011.
Run the installer and use defaults for all answers. When it completes, go to Start Menu->OpenVPN->OpenVPN Config File Directory
.
You must have the user-openvpn.zip file created on the server to continue. Unzip that file. Place the contents in the open OpenVPN config file directory on your desktop. Then, choose OpenVPN GUI
from the windows start menu to launch the GUI. This will place an icon in your taskbar; double click that icon to start your vpn. After a few moments you should see a message that the vpn has connected. See below for a caveat if you are running Windows 7.
To test the vpn, try a couple things:
- Open your web browser and connect to an internal web server.
- Connect directly to a windows share by opening the start menu and typing
directly in the run box.
server\share
If you have any problems with the VPN, right click on the OpenVPN icon in the task bar and choose View Log
to view the log for troubleshooting. If you see an 'unable to load route' message and you are running Windows Vista, it means that you forgot to start the client properly. Right click the tskbar icon and choose 'Exit'. Then go to the start menu and right click on OpenVPN GUI
. Choose Run As Administrator
to start the client with the proper permissions.
Special note for Windows 7: it appears you need to do some extra work to make the icon appear in the taskbar. Specifically, follow these instructions. Looks like you need to run OpenVPN as an administrator and enable Windows Vista Compatibility Mode.