How-to OpenVPN over SSH
Table of Contents
Introduction
This how-to would allow you to set up an encrypted tunnel between two LANs, using OpenVPN and SSH.
This document uses Gentoo only to refer to installation procedures. It should be used in other distributions with minimal effort.
The !OpenVPN project contains documentation which I found pretty straight-forward to follow. If you find problems setting OpenVPN up, I recommend its website1 and man pages.
Context
- You want an encrypted tunnel between two separate LANs, across another LANs or internet itself.
- You cannot define rules for outgoing traffic in one of the LANs (server´s), but can definitely define rules for both incoming and outgoing traffic in the other (client´s).
- You have a public port available (or else can enable it) for public service (across the hetereogeneous networks in between) in the client network, and such port is accessible by the server LAN.
Solution
The proposed solution is to
- Set up a SSH server listening to the enabled port of the client LAN's public IP address.
- Generate server and client certificates (PKI stuff).
- Copy the client certificates to the client´s OpenVPN configuration.
- Set up the OpenVPN server ensuring it only cares about TCP traffic.
- Connect to the SSH service in the client from the server, redirecting OpenVPN port to the client.
- Set up the OpenVPN client for communicating to the redirecting server port on localhost, again using just TCP traffic.
- Automate the tunnel
SSH service on the client
In case you haven't already done so (pretty unlikely):
emerge -v openssh
In /etc/ssh/sshd_config, either change the port, define a xinetd wrapper, in case the firewall of the server´s LAN filters out TCP connections to external SSH ports. In any case, probably you'd need to do a little port forwarding to make your router handling external traffic and the box running the SSH service.
PKI stuff
This section is just a summary of what is well documented in OpenVPN´s site 1.
First of all, install OpenVPN on both sides.
USE="doc" emerge -v openvpn
Then, for the server, and following OpenVPN instructions 2, we need to copy the default scripts to perform our changes without affecting the package defaults:
mkdir /etc/openvpn cp /usr/share/openvpn/easy-rsa/* /etc/openvpn
Edit /etc/openvpn/vars file and customize it.
cd /etc/openvpn source vars ./clean-all ./build-ca ./build-key-server server ./build-key [client] ./build-dh
Copy required certificates
scp -P [port] /etc/openvpn/keys/[client].crt [client-public-ip]:/etc/openvpn/ scp -P [port] /etc/openvpn/keys/[client].key [client-public-ip]:/etc/openvpn/ scp -P [port] /etc/openvpn/keys/ca.cert [client-public-ip]:/etc/openvpn/ rm -f /etc/openvpn/keys/[client].crt rm -f /etc/openvpn/keys/[client].key
Set up the OpenVPN server
We'll take a sample configuration as template:
bzcat /usr/share/doc/openvpn-2.0.6/examples/sample-config-files/server.conf.bz2 >> /etc/openvpn/openvpn.conf
Now, edit such file to make sure it sticks to TCP, and sets up the correct routes.
Connect to the client´s SSH from the server
ssh -N -g -p [port] -R 1194:localhost:1194 [client-public-ip]
Set up the OpenVPN client
It's simpler to start with a default template as before:
bzcat /usr/share/doc/openvpn-2.0.6/examples/sample-config-files/client.conf.bz2 >> /etc/openvpn/openvpn.conf
Now edit the file making sure it specifies TCP traffic explicitly, and the server points to localhost.
/etc/init.d/openvpn start
Automate the tunnel
Both in the client and the server, autostart the services on boot:
rc-update add openvpn default
Also, you can use AutoSSH to automatically restart the SSH tunnel if necessary (on the server, needless to say).
emerge -v autossh
Then, make sure the connection is set-up when the box boots:
cat <<EOF>> /etc/conf.d/local.start autossh -M 21000 -N -g -p [port] -R 1194:localhost:1194 [client-public-ip] & EOF
