HOWTO: Poor man VPN in Debian/Ubuntu with OpenSSH

If you are managing a remote Linux network and you are tired of NATting or two ssh hops to enter a remote server, but OpenVPN poses too much overhead, you can use ssh tunneling to easily create a workstation-to-site VPN.
I’ve tested this with Ubuntu 9.10 Karmic Koala as the workstation and Debian 5.0 Lenny as the server, but it should work identically with older Ubuntu and Debian (both server or workstation).

I’ve been inspired by these two tutorials, although both didn’t work 100% for me, but joining pieces did the trick, so here I am :)

Software prerequisites:

  • Standard Debian or Ubuntu
  • openssh-server on the remote side of the VPN
  • openssh-client on the local side of the VPN (your PC)

Network configuration (as an example)

  • Workstation LAN: 192.168.0.0/24
  • Server LAN: 192.168.10.0/24 on eth1
  • VPN: 10.0.0.0/24
  • Remote server public address: 1.2.3.4 on eth0

First of all, on the workstation generate a dedicated key (it should be a dedicated one cause the server will identify you’re going to bring up a tunnel based on the key you’re using to connect) with

# ssh-keygen -f /root/.ssh/VPNkey -b 2048

Now edit /etc/network/interfaces and create a new stanza like this one (remember to change IP addresses – in bold – according to your personal network configuration)

iface tun0 inet static
# from pre-up to true on the same line
pre-up ssh -i /root/.ssh/VPN -S /var/run/ssh-vpn-tunnel-control -M -f -w 0:0 1.2.3.4 true
pre-up sleep 5
address 10.1.0.2
pointopoint 10.1.0.1
netmask 255.255.255.0
up route add -net 192.168.10.0 netmask 255.255.255.0 gw 10.1.0.1 tun0
post-down ssh -i /root/.ssh/VPN -S /var/run/ssh-vpn-tunnel-control -O exit 1.2.3.4

Just a copuple of notes: address is your VPN local endpoint address (say, your workstation) while pointopoint is the remote VPNaddress (your server), which are the two tunnel’s endpoints.

Now let’s go to the server.

Edit /etc/ssh/sshd_server, add the line
PermitTunnel point-to-point

and restart your sshd instance.
Now edit (or create) /root/.ssh/authorized_keys (remember, we are on the server now, not your workstation) and add a line like

tunnel="0",command="/sbin/ifdown tun0; /sbin/ifup tun0" ssh-rsa HERE IT GOES YOUR VPNkey.pub FROM YOUR WORKSTATION

now edit /etc/network/interfaces and add this stanza:

iface tun0 inet static
address 10.1.0.1
netmask 255.255.255.0
pointopoint 10.1.0.2
post-up /sbin/sysctl -w net.ipv4.ip_forward=1
post-up /sbin/iptables -t nat -A POSTROUTING -s 10.1.0.0/24 -o eth1 -j MASQUERADE
post-down /sbin/iptables -t nat -D POSTROUTING -s 10.1.0.0/24 -o eth1 -j MASQUERADE
post-down /sbin/sysctl -w net.ipv4.ip_forward=0

the post-up and post-down commands enable the network sharing between the VPN server endpoint and the remote LAN (it’s called masquerading), so you can access the remote LAN from your workstation and not only the remote server. Obviously you need to instruct your workstation with a dedicated static route to reach the remote LAN network, and this is the route add -net in your workstation config.

Now, bring up the tunnel on the workstation with
# ifup tun0
and you should be able to reach a remote server on your remote LAN, with traffic secured by OpenSSH encryption.

2 thoughts on “HOWTO: Poor man VPN in Debian/Ubuntu with OpenSSH

  1. is that a typo on the pre-up and post-down? VPN should be VPNkey (the name you used when you created it above)

Leave a comment