Saturday, November 29, 2008

Drop Dead Simple OpenVPN on OpenBSD 4.4

Like OpenBSD, OpenVPN is something I always end using every couple of years but not often enough to stay fluent with the setup & configuration. Although I don't get into it here, you can do some really cool stuff with bridged mode. We actually used it in the SCADA Honeynet to send traffic to a target PLC. OpenVPN is also an ideal free VPN solution for a small company since it is available on Windows, OSX, and Linux.

After reviewing docs and blog entries since the last time is used it, I found that not only are the too way many howtos out there (when can too much documentation be a bad thing?) many of them are overkill for what I needed and focus on using certificate authentication, when shared key was all I needed. But the Static Key Mini-HOWTO was too simple.

This configuration could be used to provide remote access to a private network over the Internet (or, as the case is here) providing access to the Internet over an insecure wireless network. The OpenVPN server becomes the default route. There is obviously a lot more than you

1. Install on OpenBSD 4.4 (OpenVPN server) via ports (or package if if you lazy)
# cd /usr/ports/net/openvpn && make install
2. Install on Debuntu (client)
# apt-get install openvpn
3. Generate your static key on the server
openvpn --genkey --secret static.key
4. Create Server OpenVPN config (/etc/openvpn/server.conf
dev tun0
port 1234
ifconfig 10.0.0.1 10.0.0.2
secret static.key
ping 15
verb 4

4. Create your PF rules in /etc/pf.conf. The key rules I added were to allow the incoming UDP OpenVPN traffic (port 1234) and to allow all the traffic in on the tun0.
ext_if="xl0"
int_if="rl0"
vpn_if="tun0"
set skip on lo
scrub in
nat on $ext_if from !($ext_if) -> ($ext_if)
block in log
pass out keep state
pass quick on $int_if no state
pass in on $vpn_if keep state
pass in on $ext_if proto udp to ($ext_if) port 1234
pass out proto icmp keep state
pass in proto icmp keep state
pass in on $ext_if proto tcp to ($ext_if) port ssh

5. OpenVPN client config (in /etc/openvpn/openvpn.conf)

Paste over the key to /etc/openvpn/static.key
dev tun0
remote 192.168.1.44
port 1234
nobind
ifconfig 10.0.0.2 10.0.0.1
secret /etc/openvpn/static.key
redirect-gateway def1
ping 15
verb 4

The new option I learned about was "redirect-gateway def1" which adds a default route to the OpenVPN terminating tunnel address (10.0.0.1) so that all non-local traffic gets sent over the tunnel, which is what I want. Obviously this leaves any local traffic unprotected.

mfranz@mfranz-t61:~$ netstat -nr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
10.0.0.1 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
192.168.1.100 0.0.0.0 255.255.255.255 UH 0 0 0 venet0
192.168.1.44 192.168.10.254 255.255.255.255 UGH 0 0 0 wlan0
192.168.10.0 0.0.0.0 255.255.255.0 U 0 0 0 wlan0
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 vnet0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 wlan0
0.0.0.0 10.0.0.1 128.0.0.0 UG 0 0 0 tun0
128.0.0.0 10.0.0.1 128.0.0.0 UG 0 0 0 tun0
0.0.0.0 192.168.10.254 0.0.0.0 UG 0 0 0 wlan0


6. Startup your server (and add this to rc.local)
openvpn --daemon --config /etc/openvpn/server.conf
When you are testing, obviously don't select the --daemon option

7. Connect with the client
# openvpn --config /etc/openvpn/openvpn.conf

Sat Nov 29 14:47:34 2008 OpenVPN 2.1_rc7 i486-pc-linux-gnu [SSL] [LZO2] [EPOLL] built on Jun 11 2008
Sat Nov 29 14:47:34 2008 /usr/sbin/openvpn-vulnkey -q /etc/openvpn/static.key
Sat Nov 29 14:47:34 2008 Static Encrypt: Cipher 'BF-CBC' initialized with 128 bit key
Sat Nov 29 14:47:34 2008 Static Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Sat Nov 29 14:47:34 2008 Static Decrypt: Cipher 'BF-CBC' initialized with 128 bit key
Sat Nov 29 14:47:34 2008 Static Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Sat Nov 29 14:47:34 2008 TUN/TAP device tun0 opened
Sat Nov 29 14:47:34 2008 ifconfig tun0 10.0.0.2 pointopoint 10.0.0.1 mtu 1500
Sat Nov 29 14:47:34 2008 Data Channel MTU parms [ L:1544 D:1450 EF:44 EB:4 ET:0 EL:0 ]
Sat Nov 29 14:47:34 2008 Local Options hash (VER=V4): '5c3fe1ab'
Sat Nov 29 14:47:34 2008 Expected Remote Options hash (VER=V4): '522471df'
Sat Nov 29 14:47:34 2008 UDPv4 link local: [undef]
Sat Nov 29 14:47:34 2008 UDPv4 link remote: 192.168.1.44:1234
Sat Nov 29 14:47:44 2008 Peer Connection Initiated with 192.168.1.44:1234
Sat Nov 29 14:47:46 2008 Initialization Sequence Completed

2 comments:

alex smith said...

I have vpn setup on my Linode and then connect from my laptop, home fileserver, and wife's desktop. This allows each machine to send outgoing mail through the Linode as well as provinding seemless connections to my home LAN from my laptop when away from home.

Another plus is being able to quickly scp a file from the Linode to any specific machine at home rather then just to the machine port 22 is forwarded to.

Unknown said...

I have OpenBSD 4.3, and compiled OpenVPN 2.1rc16 from source. Your howto is great, so TIA. When I start up the OpenVPN server, I'm unable to ping the IP 10.0.0.1 from the server. I'm not sure where to start looking. Countless tut's on the net are either for ancient OBSD releases or for different configs. You don't mention creating a hostname.tun0 file. Is this not necessary?