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 #<hwaddr> <ipaddr> #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...
Last modified: Thu, 04 Sep 2008 14:12:00 +1000 Hits: 23,578
Created by NickStallman.net, Luxury Homes Australia
Real estate agents should be using interactive floor plans and list their apartments, townhouses and units.
