HOWTO VPN over SSH and tun

Do it with a Script

Introduction

The following script will let you start a full featured VPN using SSH and tun.
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)

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."

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).

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’)

Do it Manually

That part will be useful if you are away and that you need a one-time vpn server Let’s say that machine S will be the vpn server, and machine C will be the vpn client * ssh into the machine S and change sshd_config:

File: /etc/ssh/sshd_config

PermitRootLogin yes
PermitTunnel yes
TCPKeepAlive yes # Not required but makes things much more stable. This is default now
* then restart ssh on the machine S and quit your current ssh connection
* then ssh with this command from the machine C: ssh -w 0:0 the_external_ip_of_machine_S
* then inside the machine S do: ifconfig tun0 10.0.0.1 netmask 255.255.255.0 note that the netmask is 255.255.255.255 by default so you must add the netmask...
* inside the machine C do: ifconfig tun0 10.0.0.2 netmask 255.255.255.0 normally each machine could ping each others...
* inside Machine A do: echo "1" > /proc/sys/net/ipv4/ip_forward echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE iptables -A FORWARD -j ACCEPT iptables -A FORWARD -j ACCEPT
* inside the machine B do: route del default route add default gw 10.0.0.1 tun0
* edit /etc/resolv.conf : comment all lines and add this one:

File: /etc/resolv.conf

nameserver 10.0.0.1
* inside the machine A do: emerge -av dnsmasq here's my /etc/dnsmasq.conf:
#filter what we send upstream domain-needed bogus-priv filterwin2k localise-queries
#allow /etc/hosts and dhcp lookups via *.lan local=/lan/ domain=workgroup expand-hosts
#resolv-file=/tmp/resolv.conf.auto dhcp-authoritative #dhcp-leasefile=/tmp/dhcp.leases
# use /etc/ethers for static hosts; same format as --dhcp-host
# #read-ethers
#other useful options:
#default route(s): dhcp-option=3,168.0.0.2
#dns server(s): dhcp-option=6,168.0.0.2 dhcp-range=168.0.0.100,168.0.0.255,255.255.255.0,12h then start dnsmasq: /etc/init.d/dnsmasq start then from machine C ping gentoo website for instance...

1 Comment

  1. Hola a todos, en mi primer post me gustaría compartir algo con vosotros, Ya sabéis que para buscar y descargar música en internet, tenemos muy pocas opciones, generalmente utilizamos el emule o el ares, pero yo personalmente encuentro bastante frustrante bajarme una canción y que no sea la que busco, porque pierdo bastante tiempo encontrando material de calidad.

    Una amiga me recomendó utilizar Altavz como mi buscador de música, y la verdad es una gozada.

    Además de poder escuchar la canción, descargarla o agregarla a tus listas preferidas puedes encontrar a otros usuarios y compartir tu música con ellos.

    Hace mucho que no utilizo emule, sino este buscador de música.

Leave a Reply

Your email address will not be published. Required fields are marked *