Openvpn/talk
From Wsms
These are notes for the November 15, 2008 presentation to the Barcamp San Diego
Contents |
Speaker's Bio
George Geller stayed in school for way too long. He finally escaped, screaming, with a Ph.D. in Chemistry from UCLA. After working at Caltech, Suntory (in Osaka, Japan) and Columbia University, he joined a company producing molecular simulation applications for chemical and pharmaceutical research. Eventually he figured out that writing good software was even more rewarding and fun than trying to make molecules behave. Thereafter he worked as a programmer at several software companies in the San Diego region, most notably Intuit, and enjoyed modest success in founding his own software startups. He is a founding member of the Kernel-Panic Linux Users Group and the sponsor and primary editor of wsms.wikiplanet.com (the Web Server Maintenance and Security Wiki), a website dedicated to documenting the often-challenging job of keeping computers operating smoothly.
Talk Abstract
Openvpn is a, free, open-source, client-server virtual private network solution that relies on SSL for encryption. It is simple to set up and has a good track record for security. Openvpn includes clients for Linux, Windows and Macintosh. It can be set up to use X509 certificates and scales well to large organizations. George will show you how to set up openvpn so that you can access your office network using your laptop from remote locations.
Talk
A vpn is a "Virtual Private Network". It lets you connect to your office LAN from a remote location and access all the network services you would have if you were physically in the office.
There are many
put a picture of my network here (or draw it on the whiteboard).
demonstration
In this demonstration, I use a shared key file. Openvpn can also use x.509 certificate or username/password authentication via PAM. After installing openvpn, you make the shared key file with:
[root@arthur ~]# openvpn --genkey --secret static.key
The key file is just a text file with a 2048 bit key written in hexadecimal notation. You need to have the file on both the client and the server.
The LAN in my office is 192.168.2.0/24. On my laptop which is serving as the remote machine, I route traffic to the office LAN through the vpn tunnel. The server's hostname is arthur. It is accessible on the internet as ns2.sdlinuxguy.com. The client laptop (remote machine) hostname is harrison.
server setup and initialization
Here is the configuration file for the server:
## openvpn server4.conf dev tun port 443 proto tcp-server ifconfig 192.168.77.1 192.168.77.2 secret /etc/openvpn/keys/static.key keepalive 10 60 comp-lzo daemon
Launch the openvpn server with:
[root@arthur openvpn]# openvpn server4.conf
If you wish you can monitor the openvpn connections with:
[root@arthur openvpn]# tail -f /var/log/messages ... Oct 9 09:51:15 arthur openvpn[5326]: Initialization Sequence Completed ...
When the client connects, you will see "Initialization Sequence Completed" as shown above.
Once the tunnel is established, the client can access services on the server. For the client to access the LAN, you need to forward packets from the tunnel interface to the LAN interface. Here is a script that does so:
#!/bin/sh #20081009 October 9, 2008 #arthur:/root/ip2.sh ##Adapted from Linux Networking Cookbook, page 183 #minimal iptables script for sharing a LAN through openvpn #define variables ipt="/sbin/iptables" mod="/sbin/modprobe" TUN_IFACE="tun0" LAN_IFACE="eth1" #turn on ip forwarding echo 1 > /proc/sys/net/ipv4/ip_forward #load kernel modules $mod ip_tables $mod iptable_filter $mod iptable_nat $mod ip_conntrack $mod iptable_mangle $mod ipt_MASQUERADE $mod ip_nat_ftp $mod ip_nat_irc $mod ip_conntrack_ftp $mod ip_conntrack_irc #Flush all active rules and delete all custom chains $ipt -F $ipt -t nat -F $ipt -t mangle -F $ipt -X $ipt -t nat -X $ipt -t mangle -X #Set default policies $ipt -P INPUT ACCEPT $ipt -P FORWARD ACCEPT $ipt -P OUTPUT ACCEPT $ipt -t nat -P OUTPUT ACCEPT $ipt -t nat -P PREROUTING ACCEPT $ipt -t nat -P POSTROUTING ACCEPT $ipt -t mangle -P PREROUTING ACCEPT $ipt -t mangle -P POSTROUTING ACCEPT #always have an entry for interface lo $ipt -A INPUT -i lo -j ACCEPT $ipt -A OUTPUT -o lo -j ACCEPT #Enable IP masquerading $ipt -t nat -A POSTROUTING -o $LAN_IFACE -j MASQUERADE #Enable traffic from/to the LAN and tunnel $ipt -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT $ipt -A FORWARD -i $LAN_IFACE -o $TUN_IFACE -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT $ipt -A FORWARD -i $TUN_IFACE -o $LAN_IFACE -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT # Accept important ICMP messages $ipt -A INPUT -p icmp --icmp-type echo-request -j ACCEPT $ipt -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT $ipt -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
Start this on the server with:
[root@arthur ~]# ./ip2.sh
You can see if this looks right with iptables-save:
[root@arthur ~]# iptables-save # Generated by iptables-save v1.3.5 on Thu Oct 9 10:44:15 2008 *mangle :PREROUTING ACCEPT [52963:20297536] :INPUT ACCEPT [28424:3228666] :FORWARD ACCEPT [52862:23718986] :OUTPUT ACCEPT [34565:25049181] :POSTROUTING ACCEPT [59134:37387142] COMMIT # Completed on Thu Oct 9 10:44:15 2008 # Generated by iptables-save v1.3.5 on Thu Oct 9 10:44:15 2008 *nat :PREROUTING ACCEPT [4:294] :POSTROUTING ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A POSTROUTING -o eth1 -j MASQUERADE COMMIT # Completed on Thu Oct 9 10:44:15 2008 # Generated by iptables-save v1.3.5 on Thu Oct 9 10:44:15 2008 *filter :INPUT ACCEPT [738:57430] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [22038:19022108] -A INPUT -i lo -j ACCEPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT -A INPUT -p icmp -m icmp --icmp-type 11 -j ACCEPT -A INPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT -A FORWARD -i eth1 -o tun0 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT -A FORWARD -i tun0 -o eth1 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT -A OUTPUT -o lo -j ACCEPT COMMIT # Completed on Thu Oct 9 10:44:15 2008
client
Here is the configuration file for the client:
## /etc/openvpn/client4.conf float remote example.com 443 proto tcp-client auto-proxy dev tun ifconfig 192.168.77.2 192.168.77.1 route 192.168.2.0 255.255.255.0 secret /etc/openvpn/keys/static.key keepalive 10 60 comp-lzo
Start it with:
root@harrison:/etc/openvpn# openvpn client4.conf
details
Let's look at client3.conf first:
- float - is an option that allows a connection through a firewall on the server end. Specifically, it tells the client to accept packets from the server that have gone through NAT.
- remote ns2.sdlinuxguy.com 443 - tells the client to use port 443. The default port is 1194, which is often blocked for outgoing connections.
- proto tcp-client - use tcp so that you look like a browser connecting using https (the default is udp)
- auto-proxy - automatically detect and use https proxy
- dev tun - specifies the type of interface to use. The other option is TAP.
- ifconfig ... - specifies the local and remote IP address for the tunnel.
- route... - Routes the traffic to the office LAN through the tunnel
- secret... - is the name of the file containing the static key
- keepalive... - restarts the vpn if there is a temporary network outage
- comp-lzo... - specifies a compression scheme
discussion
Various organizations use set up restrictions on the wireless access and outgoing connections.
- San Diego City Library - Blocks most outgoing ports except 80 and 443. Filters numerous internet sites for content deemed inappropriate.
- San Diego County Library - Blocks most outgoing ports except 80 and 443. Also blocks udp protocol on these ports.
- Microsoft's local office - Forces all traffic to go through an http proxy
- sdcoe - No restrictions
- Intuit Santa Fe campus - Blocks outgoing udp on port 443.
- Barcamp at intuit - udp on port 443 is blocked.
udp is the default protocol for openvpn. So, the setup demonstrated here does not work at the County library or at the Intuit campus.
The configuration here does not work at the local Microsoft office. However, you can configure openvpn to use tcp on port 443 and look like an https server. See the http-proxy option. Markus Feilner shows a working example of this on page 221 of his OpenVPN book.
Mike White asked if openvpn require a public IP address on the server end, or can it work like gotomypc and traverse NAT. I think you could set up a public server to direct the two NATed addresses to each other using STUN or a similar scheme. See http://en.wikipedia.org/wiki/Simple_traversal_of_UDP_over_NATs
see also
- wikipedia article
- OpenVPN project homepage
- the openvpn howto
- openvpn presentation and demonstration video by Adrian Bridgett of the Hampshire Linux User Group
- slides for Adrian's talk
- OpenVPN: Building and Integrating Virtual Private Networks by Markus Feilner
- Linux Networking Cookbook by Carla Schroder (Author) Chapter 9 is dedicated to OpenVPN. But, watch out for the typos in the examples.
- http://tinyurl.com/6384ou Slides for a presentation
notes for talk
slide 1
OpenVPN Only the righteous may enter.
This is a picture of Kongo Rishiki. He is the guardian of the Buddist temple gates. This particular reprsentation is located at Horyuji in Nara, Japan. So, I think he is a good mascot for software that protects your office LAN from crackers and simultaneously lets authorized user access it freely.
slide 2
Speaker bio
Here's who I am. I hope you can read it from the seats in the back.
How many people here suffered through organic chemistry in college. Fun, wasn't it?
A little is missing from the bottom of the slide. I'm actually starting my third career after being a chemist and a computer guy. I'm studying to be a financial planner and working on opening my own office. Catch me later if you want to talk about that.
Everything I'm presenting today is availble at this link. We'll visit it and get a tour of my website towards the end of my presentation.
slide 3
OpenVPN summary
It is free and open-source.
It uses SSL encryption.
There are GUI clients for Windows and Mac and a command-line client for Linux which you can set up as an automated service.
You can use openvpn with no encryption at all, which only makes sense for testing.
You can use it with a shared key, which gives good encryption, but is limited to only a single client.
Or you can use openvpn with rsa keys which allows you to have many clients connect to a single server.
Open vpn also supports other authentication mechanisms including LDAP and PAM.
The OpenVPN distribution includes a very nice set of scripts called easy-rsa for creating x.509 certificates. Today I'll show you how to generate x.509 certificates and keys for the client and server.
slide 4
A VPN, in case you don't know, joins two networks together across the internet.
I drew a more specific picture of my network setup on the white board over here.
It is good for protecting services such as samba or web application that you want on your office intranet, but not exposed to the whole world.
There are a lot of VPN solutions available, and some things that call themselves VPN even though they are not.
Most VPNs use IPSec. I haven't tried to use IPSec myself. I've been told me that IPSec is difficult to configure, has serious problems with NAT (Network Address Translation), and some commercial vendors have add-ons that introduce incompatibilities.
Example of things that call themselves VPNs, but really are not are application gateways that use SSL encryptions. Think about your webmail account. If is has an https login, you can safely use it from your laptop at through an untrusted wireless hotspot. But, you shouldn't walk up to an untrusted computer and login, because that computer might have spyware installed and steal your password.
In contrast, a VPN has trusted endpoints and lets you safely access any service on your office LAN.
slide 5
Gamma rays? How did they get in here?
slide 6
OpenVPN is not the not the only choice.
If you are only accessing one application remotely, it may be easier to forward a port using ssh.
There are also numerous commercial vpns that use IPSec as well as a one or two open-source IPSec vpns.
There is also PTPP, but it is reputed to have security issues. I don't know anyone who uses it.
Now that I've exposed my gross ignorance, let me explain that for this type of problem, I tend to approach it by doing a little research and try one of the easier solutions first. When I have something that works, I go on to the next problem.
My problem was that I wanted to access my server, located at a static IP address, from my laptop from the library and other remote locations. At first, I could just use ssh to connect to port 22. After some time, most of the wireless hot spots began blocking outgoing connections to port 22. So, I had ssh on my server listen to port 443 instead. Unless the firewall does deep packet inspection, it allows outgoing TCP connections on port 443 because they resemble https connections.
Eventually, my coworkers and I set up file sharing and some web applications on our intranet. At that point I decided to set up a vpn. At first I only had one laptop, so I used openvpn with a shared key. When I got a second laptop, I switched to x.509 certificates.
slide 7
Server setup
Earlier I mentioned that you can use x.509 certificates or a shared key. In fact OpenVPN can run without encription at all. The encryption is provided by SSL. Hence, OpenVPN's encryption is just as good as the encryption used by ssh/ssl. In the first simple configuration, I use a unique shared key that generated with this command and store in a secure location on both the client and the server.
In the configuration file you see the options we are using:
- The tun device, a virtual network interface built into the Linux kernel.
- port 443 so we look like https
- the tcp protocol, so we really look like https
- the location of the secret key file
- a keepalive option that tells openvpn try to auto reconnect in case of a network outage
- Lempel-Ziv compression
- run in the deamon mode.
The deamon mode goes to the background and sends its output to /var/log/messages
Note that the only thing going on in the kernel is the tun0 device. Everything else is in user space. This is different than IPSec, which modifies the IP protocol itself.
If you don't have to look like https, you might try the TCP protocol instead. It has less overhead in this instance, since openvpn includes the work that TCP does to be "reliable".
slide 8
Launch the server.
Then check /var/log/messages to see that it went OK.
slide 9
More server setup.
Once the client is connected to the server, it will have access to services that are listening on the tun interface. If you want the client to have access to the other services on the LAN, you need to do port forwarding.
Note: You can set up open vpn with "bridged" networking instead of NAT so that the port forwarding part is not needed. NAT is the default setup and easier to use overall.
I set up NAT and forwarding from the tun device to the LAN so that the remote client has access to everything on the office LAN.
This is the interesting part of the script to set up iptables. You can see the entire script on the link from the second slide.
slide 8
Client configuration.
The float is necessary because the server is behind a NAT firewall.
Remote is the the firewall address and port number.
Start it with the openvpn command pointed to the config file.
Now for the demonstration.
In fact I already have the VPN running for an hour or so just to show you that it is working. arthur is the computer that acts as the VPN server. mckinley is another computer on my office LAN. So, you can see that I got to arthur, then to mckinley, etc.
Let's look at route -n on the client:
ggeller@harrison:~$ route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.77.1 0.0.0.0 255.255.255.255 UH 0 0 0 tun0 192.168.2.0 192.168.77.1 255.255.255.0 UG 0 0 0 tun0 10.66.66.0 0.0.0.0 255.255.254.0 U 0 0 0 eth1 169.254.0.0 0.0.0.0 255.255.0.0 U 1000 0 0 eth1 0.0.0.0 10.66.66.1 0.0.0.0 UG 100 0 0 eth1
You see that packets to 192.168.2.0/24 are routed through the tun0 interface.
Quit the pinging on mckinley, log out of mckinley, shut down the terminal. Quit following /var/log/messages on arthur; log out of the root account on arthur; log out of the ggeller account on arthur, shut the terminal.
As root on the client, shut down the VPN connection. Check the routing table and ifconfig.
So, let's shut everything down and see if we can restart it.
