Sunday, December 12, 2010

Setting up a VPN connection to a Linux Internet server

First, this has absolutely nothing to do with Ruby or Rails, but I wanted to post this since I couldn't find much good info anywhere.

If you have a need to connect to a server directly on the Internet (not on a private LAN) to access services on the server that are not publicly exposed, or to tunnel your Internet connection through that server, setting up a VPN connection to the server is the way to go. Most documentation, tutorials, etc. are for setting up a VPN to an entire behind the firewall network, but this guide is for setting up a VPN connection to just one server.

OpenVPN is the best server based VPN solution out there. It's open source so you can install it on any OS, I'll be guiding you through setting it up on a Ubuntu or Debian Linux server. Client software is readily available and easily configured for Windows, Linux, and Mac.

Setting up OpenVPN Server
Run "sudo apt-get install openvpn" to install the OpenVPN server.

Now you'll need to generate certificates and keys. Some example scripts are provided to make this easy.
  1. Run "sudo mkdir /etc/openvpn/easy-rsa/"
  2. Run "sudo cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa/"
  3. Run "sudo chown -R $USER /etc/openvpn/easy-rsa/"
  4. Edit the file /etc/openvpn/easy-rsa/vars, and change the KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, and KEY_EMAIL to what you want to show up in your server certificates.
  5. "cd /etc/openvpn/easy-rsa/"
  6. Run "source vars"
  7. Run "./clean-all"
  8. Run "./build-dh"
  9. Run "./pkitool --initca"
  10. Run "./pkitool --server server
  11. Now generate the actual keys in the keys folder. "cd keys"
  12. Run "openvpn --genkey --secret ta.key"
  13. Now copy all keys to the main open VPN folder with "sudo cp server.crt server.key ca.crt dh1024.pem ta.key /etc/openvpn/"
  14. Now you'll need to generate a client certificate. "cd .."
  15. Run "source vars"
  16. Run "./pkitool client-certificate-name", substituting client-certificate-name for whatever you want to call it.
Now you'll need to create a server config file for OpenVPN to use. Place this file in /etc/openvpn/server.conf. An example file with plenty of comments for all possible examples is in the file /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz. I'll show my example file here which is set up for the client to only access the server and to use the server's Internet connection.


# Port to listen on, this needs to be opened
# in the firewall
port 1194

# TCP or UDP server. I had better download
# throughput when using TCP, but slower
# upload throughput. If you have speed
# issues try switching this.
proto tcp
;proto udp

# Use "dev tun" to create a
# routed IP tunnel, where clients get their
# own subnet behind the server. This is
# what you should use if you only want to
# VPN to the server to access private server
# resources, or to get the client out to the
# Internet through the server's connection.
# "dev tap0" is used for an ethernet bridge
# VPN, this config isn't for this type of
# VPN.
dev tun

# Certificate and key file locations
# (in /etc/openvpn/)
ca ca.crt
cert server.crt
# This file should be kept secret
key server.key
# Diffie hellman parameters.
dh dh1024.pem

# For "dev tun" configurations only.
# Configure server mode and supply a VPN
# subnet for OpenVPN to draw client
# addresses from. This can be modified to be
# any private /24 network (ie 192.168.10.0,
# 10.8.8.0, etc.) that the server doesn't
# already know about.
# The server will take 172.18.100.1 for
# itself, the rest will be made available to
# clients. Each client will be given its own
# /30 subnet in this range, and will able to
# reach the server on 172.18.100.1. Comment
# this line out if you are using "dev tap"
# for ethernet bridging.
server 172.18.100.0 255.255.255.0

# Maintain a record of client <-> virtual IP address
# associations in this file. If OpenVPN goes down or
# is restarted, reconnecting clients can be assigned
# the same virtual IP address from the pool that was
# previously assigned.
ifconfig-pool-persist ipp.txt

# Push routes to the client, if you have
# other subnets that you want the client to
# access through the VPN. Isn't
# necessary for dev tun connections, as you
# only want the client to access the VPN
# server.
;push "route 192.168.10.0 255.255.255.0"

# Specify a DNS server that the client
# should use, by default it will continue
# to use its regular DNS server, which you
# probably don't want it using with all 
# traffic going through the VPN. 8.8.8.8
# is the Google public DNS server
push "dhcp-option DNS 8.8.8.8"

# Enable this to cause all of the client's
# Internet traffic to go through the VPN,
# including DNS requests (if this is set
# you should enable the above DNS option).
push "redirect-gateway def1 bypass-dhcp"

# The keepalive directive causes ping-like
# messages to be sent back and forth over
# the link so that each side knows when
# the other side has gone down.
# Ping every 10 seconds, assume that remote
# peer is down if no ping received during
# a 120 second time period.
keepalive 10 120

# The server and each client must have
# a copy of this key.
# The second parameter should be '0'
# on the server and '1' on the clients.
tls-auth ta.key 0 # This file is secret

# Enable compression on the VPN link.
comp-lzo

# It's a good idea to reduce the OpenVPN
# daemon's privileges after initialization.
user nobody
group nogroup

# The persist options will try to avoid
# accessing certain resources on restart
# that may no longer be accessible because
# of the privilege downgrade.
persist-key
persist-tun

# Output a short status file showing
# current connections, truncated
# and rewritten every minute.
status openvpn-status.log

# By default, log messages will go to the syslog
# Use log or log-append to override this default.
# "log" will truncate the log file on OpenVPN startup,
# while "log-append" will append to it. Use one
# or the other (but not both).
;log openvpn.log
;log-append openvpn.log

# Set the appropriate level of log
# file verbosity.
# 0 is silent, except for fatal errors
# 4 is reasonable for general usage
# 5 and 6 can help to debug connection problems
# 9 is extremely verbose
verb 3

# Silence repeating messages. At most 20
# sequential messages of the same message
# category will be output to the log.
;mute 20


Now that you have the server configured, if you're running a firewall on the server, here are the rules that you should add to iptables to allow traffic from your VPN clients to go through, and to open the OpenVPN port (these are usually in /etc/iptables.rules). First, add this to the top section, above the current rules. Substitute eth0 with the interface for the public Internet on your server.

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -s 172.18.100.0/24 -o eth0 -j MASQUERADE
COMMIT

Now, add these to your filter rules:

-A INPUT -i tun+ -j ACCCEPT
-A INPUT -p tcp -m tcp --dport 1194 -j ACCEPT
-A INPUT -p udp -m udp --dport 1194 -j ACCEPT
One last thing you'll need to do. To enable forwarding of data from your VPN clients to the server's Internet connection, edit the file /etc/sysctl.conf and uncomment the following line:

net.ipv4.ip_forward = 1

Now, the server's configuration should be complete! To make sure the firewall settings are correct just reboot the server.

Configuring the Client
Now you need a client to use with your OpenVPN server. For Linux, just use openvpn. You can simply place a client.conf file and all necessary certificates/keys in /etc/openvpn/. For Windows and Mac, get your client software from http://openvpn.net/index.php/openvpn-client.html. Use Community version for Windows.

I had some trouble getting the Windows client to install in Windows 7, particularly the network driver install. Be sure that the first time you install it, that when it pops up to install the driver, check to trust all software from this provider before clicking Install. If you don't check this, you must first run Delete all TAP virtual ethernet drivers from the OpenVPN -> Utilities folder on the start menu as an administrator (right click, Run as Administrator). Then uninstall it. Then right click on the install file and click Run as Administrator.

Now you'll need to copy the keys from the server to the client. For Windows, copy the following files to C:\Program Files (x86)\OpenVPN\config from /etc/openvpn/easy-rsa/keys on the server. For Linux, copy these files in to /etc/openvpn/.
  • client-certificate-name.crt
  • client-certificate-name.key
  • ca.crt
  • ta.key
And you'll need to create a servername.ovpn file that contains the client configuration file in the same directory. In Linux just call it client.conf in /etc/openvpn/. Here is my example servername.ovpn file:



client
dev tun
proto tcp
remote your_server_ip_address 1194
nobind
persist-key
persist-tun
ca ca.crt
cert client-certificate-name.crt
key client-certificate-name.key
tls-auth ta.key 1
comp-lzo
verb 3

Now, in Windows, to launch the client, you'll need to right click on the desktop and click Run as Administrator. If you don't run it as administrator, the routes can't be modified. Once you do this, just right click on the tray icon and click Connect. This should be it! Now all of your Internet traffic will be going through your server.

No comments: