Mark Uemura (mtu@) writes in:

I have always been intrigued with encrypted network tunnels, be it ipsec(4) or ssh(1) . Yet, I don't think that anything beats SSH VPN tunneling on OpenBSD for a quick, elegant and stealth-like solution without the IPsec headaches.

Read on to find out more about SSH VPN tunnels:

Articles 1 2 3 4 5

After discussing tunnels with Ryan McBride (mcbride@) and its implications for security and/or policy violations, he made a comment that he has yet to see a network that he was not able to tunnel out of. There are various tools in ports to do just that, assuming that you are not using IPsec or SSH. However, before I get into corporate policy violations and back-channel malware tunnels, I should back up in time to give some perspective and my experiences with VPNs.

At C2K6, I was working with Hans-Joerg Hoexer (hshoexer@) on IPsec failover VPNs using sasyncd(8). I also had the pleasure of sitting pretty close to Reyk Floeter (reyk@). He was the first person to introduce me to VPN tunnels using SSH. Reyk had a SIP phone that he was carrying around to call home with a SSH VPN using the tun interface. He developed this SSH VPN functionality with bits of code from Markus Friedl (markus@) and merged it into OpenSSH at the end of 2005. Since then, we have had the ability to create SSH based layer 2 or layer 3 VPN tunnels all handled at layer 7 :-).

It wasn't until last year that I started experimenting with this in earnest. Normally, I use SSH port forwarding with authpf(8) and key/passphrase authentication for most things and IPsec with authpf where port forwarding is not practical. Generally, with OpenSSH VPNs, you don't have to worry about Maximum Transition Unit (MTU) issues or firewalls getting in the way of the VPN. For the record, I'm not a fan of PKI so I have never gone down the ssl(8) VPN path.

SSH VPNs do their magic at the application layer (layer 7) without the headaches and baggage that come with traditional IPsec VPNs. Now, I can use OpenSSH to do what IPsec used to do for me in the past. IPsec on OpenBSD is really simple to set up but became more problematic with other Operating Systems. Yes, you need to work through this and familiarize yourself with IPsec implementations for each OS but it seems more complicated than it needs to be. OpenBSD has really simplified the setup and configuration of IPsec VPNs.

Unfortunately, in the real world, you often come across firewalls that block ESP/AH or ISAKMP/ISAKMP-NAT-T. Moreover, packet fragmentation caused by MTU issues were always a concern. If you didn't get the MTU just right, the user would run into fragmentation issues making the VPN really slow resulting in a negative end user experience. Lowering the MTU is really important in order to avoid this issue but in doing so, you inevitably reduce the maximum throughput of non-IPsec traffic. However, too many networks block icmp(4) or TCP MTU discovery which at times can cause "speed issues" with the road warriors you need to support. Well, with pf and scrub you can compensate for this but when you are dealing with Windows, changing the MTU is an all or nothing dilemma.

To the point, with SSH VPNs, you've got one of the most trusted of SSH implementations, OpenSSH, and all the security goodness that comes with it. Here's a simple config set borrowed from ssh(1):

How to use OpenSSH-based virtual private networks ------------------------------------------------- (1) Server: Enable support for SSH tunneling (/etc/ssh/sshd_config): PermitTunnel yes send the hangup signal (SIGHUP) to reload the new sshd_config (2) Server: Restrict client and assign the tunnel (/root/.ssh/authorized_keys) tunnel="1",command="sh /etc/netstart tun1" ssh-dss ... my_id_dsa (3) Server: /etc/hostname.tun1 inet 192.168.5.2 255.255.255.252 192.168.5.1 !/sbin/route add -inet zzz.yyy.xxx.0/24 192.168.5.1 (4) Client: Configure the local network tunnel interface (/etc/hostname.tun1) set up the layer 3 tunnel on the client: inet 192.168.5.1 255.255.255.252 192.168.5.2 !/sbin/route add -inet aaa.bbb.ccc.0/24 192.168.5.2 (5) Client: Configure the OpenSSH client (in /root/.ssh/config): Host AAA.BBB.CCC.DDD Tunnel yes TunnelDevice 1:any PermitLocalCommand yes LocalCommand sh /etc/netstart tun1 The following network plan illustrates the previous layer 2 configuration. zzz.yyy.xxx.0/24 aaa.bbb.ccc.0/24 ---------------- ---------------- | | | | zzz.yyy.xxx.www AAA.BBB.CCC.DDD +--------+ ( ) +--------+ | Client |--------------( Internet )---------------| Server | +--------+ ( ) +--------+ : 192.168.5.1 192.168.5.2 : :.....................................................: Forwarded ssh connection (Layer 3 tunnel) --- real connection ... "virtual connection" AAA.BBB.CCC.DDD "Server public IP address" aaa.bbb.ccc.0/24 "Private network behind above public IP address" zzz.yyy.xxx.www "Client private IP address" zzz.yyy.xxx.0/24 "Private network behind above private IP address" (6) Client: Connect to the server and establish the tunnel # ssh AAA.BBB.CCC.DDD when successful, you should see the following interface created on the server: tun1: flags=51 mtu 1500 groups: tun inet 192.168.5.2 --> 192.168.5.1 netmask 0xfffffffc (7) Client and Server: pf needs to be configured to allow and perhaps hide networks on either side via NAT. Essentially both the client and the server have become VPN peers. The Client above is not directly connected to the Internet. It is on a private network behind some Internet router. Imagine the client inside some corporate network.

I went a little crazy to see how far I could take this. When forced to use Windows, I would configure VMWare and install OpenBSD as a guest and then create the SSH VPN. I could then pass traffic to and from Windows through the tunnel using OpenBSD and OpenSSH as the conduit. I've done similar things with Mac OS X but David Gwynne (dlg@) informed me that there are more elegant hacks that can be done when using a Mac. Obviously, running OpenBSD in VMWare just to create a VPN to tunnel out of some restricted network seems a little much and dangerous for many reasons but it is not too difficult to do. Alternatively, you can create the SSH VPN tunnel on a different machine running OpenBSD and turn it into a router for other machines to enjoy the tunnel too.

Now the benefits are that you don't have to worry about firewalls as most networks don't proxy SSL connections. Configuring your SSH server to listen on port 443 and/or port 53 eliminates firewall issues most of the time. Since we are using OpenSSH for this VPN, we also don't have to worry about fragmentation issues :-). Thanks Reyk!

The above discussion is background info for another article that I have in the pipeline. In the meantime, I would be very curious and happy to hear what others have to say about their experience with SSH VPN tunnels using the tun interface. I am also interested in what packages and efforts you go through to break out of supposedly secure proxied networks.

Mark T. Uemura