HOWTO VPN over SSH and tun

From Gentoo Linux Wiki

Jump to: navigation, search

Image:OpenSSH-logo.png

SSH Basics

Tips & Tricks

Other Gentoo-wiki SSH

edit

[edit] Introduction

The following script will let you start a full featured VPN using SSH and tun.

[edit] Requirements

  • OpenSSH with tun support on both sides (tested Debian 4.3 on server, Gentoo 4.5 on client)
  • Root access on both sides
  • Allowed root access and tunnel on server side:
File: /etc/ssh/sshd_config
PermitRootLogin yes
PermitTunnel yes
TCPKeepAlive yes # Not required but makes things much more stable. This is default now
  • Compiled ‘tun’ module on both sides
  • Loaded ‘tun’ module on server side
  • Allowed ARP proxy (required only for accessing client from within the private network)

[edit] The script

Code: vpn.sh
#!/bin/sh
HOST=your.web.server
HOST_PORT=22
TUN_LOCAL=0
TUN_REMOTE=1
IP_LOCAL=192.168.2.2
IP_REMOTE=192.168.2.1
IP_MASK=24
PRIVATE_NETWORK=10.0.0.0/8
PRIVATE_DOMAIN="your.private.domain private.domain"
PRIVATE_NAMESERVER=192.168.2.1
PRIVATE_LOCAL=10.0.1.2

echo "Starting VPN tunnel ..."
modprobe tun
ssh -w ${TUN_LOCAL}:${TUN_REMOTE} -f ${HOST} -p ${HOST_PORT} "\
	ip addr add ${IP_REMOTE}/${IP_MASK} dev tun${TUN_REMOTE} \
	&& ip link set tun${TUN_REMOTE} up \
	&& iptables -t nat -I POSTROUTING -s ${IP_LOCAL} -j SNAT --to ${PRIVATE_LOCAL} \
	&& iptables -t nat -I PREROUTING -d ${PRIVATE_LOCAL} -j DNAT --to ${IP_LOCAL} \
	&& iptables -I INPUT -i tun${TUN_REMOTE} -j ACCEPT \
	&& iptables -I FORWARD -i tun${TUN_REMOTE} -j ACCEPT \
	&& iptables -t nat -I PREROUTING -i tun${TUN_REMOTE} -j ACCEPT \
	&& true"
sleep 3
ip addr add ${IP_LOCAL}/${IP_MASK} dev tun${TUN_LOCAL}
ip link set tun${TUN_LOCAL} up
ip route add ${PRIVATE_NETWORK} dev tun${TUN_LOCAL}
echo "search ${PRIVATE_DOMAIN}
nameserver ${PRIVATE_NAMESERVER}
" >/etc/resolv.conf
echo "... done."

[edit] Configuration

The following configuration can be set at the beginning of the script:

Item Description
HOST Hostname of the remote SSH server (either IP or DNS name).
HOST_PORT Host port of the remote ssh server (default: 22)
TUN_LOCAL Number of local tun interface. You cannot use ‘any’.
TUN_REMOTE Number of remote tun interface. You cannot use ‘any’.
IP_LOCAL IP address of local tun interface.
IP_REMOTE IP address of server tun interface.
IP_MASK IP address mask of the tuns.
PRIVATE_NETWORK Network specification (any of its IP addresses and mask) of the private network.
PRIVATE_DOMAIN Space delimiteed list of domain names of the private network (if any).
PRIVATE_NAMESERVER Nameserver in the private network.
PRIVATE_LOCAL IP address in the private network that uses this computer (in order to allow access from the private network).

[edit] TODO

  • Convert to init.d script (ie. create stop script)
  • Detect failure
  • On close clear the server’s iptables and restore local ‘/etc/resolv.conf’
  • More secure access with ‘sudo’ instead of root access on server side
  • Allow using first unused tun interface (‘any’)
Personal tools