Poor man's VPN using PPP over SSH
PPP (Point to Point Protocol) is a mechanism for running IP (Internet Protocol) over a terminal. Usually the terminal is a modem, but any tty will do. SSH creates secure ttys. Running a PPP connection over an SSH connection makes for an easy, encrypted VPN. (SSH has native tunneling support which requires root access, this method only requires root privileges on the client.)
If you run any flavor of *nix (Free/Open/NetBSD, Linux, etc), chances are everything you need is already installed (ppp and ssh). and since SSH uses a single client/server TCP connection, it NATs cleanly, easily passing through firewalls and NAT routers. It has its drawbacks though as you have PPP (TCP) inside of SSH (TCP) which is a bad idea.
On the remote end, install pppd if not already installed,
apt-get install ipppd
Enable IP Forwarding by editing /proc/sys/net/ipv4/ip\forward
echo 1 > /proc/sys/net/ipv4/ip_forward
Configure your iptables settings to enable access for PPP Clients,
iptables -F FORWARD iptables -A FORWARD -j ACCEPT iptables -A POSTROUTING -t nat -o eth0 -j MASQUERADE iptables -A POSTROUTING -t nat -o ppp+ -j MASQUERADE
And make sure you can login without a password.
On the local end, start pppd, tell it to connect using SSH in batch mode, start pppd on the remote server, and use the SSH connection as the communication channel.
pppd updetach defaultroute replacedefaultroute usepeerdns noauth passive pty \ "ssh root@$remote -o Batchmode=yes /usr/sbin/pppd nodetach notty noauth ms-dns 8.8.8.8" \ 10.0.0.1:10.0.0.2
When run, both your local and your remote computers will have new PPP network interfaces,
- Local interface ppp0 with IP address 10.0.0.1
- Remote interface ppp0 with IP address 10.0.0.2
Once pppd adds default route via ppp0 all traffic will be routed through the tunnel thus SSH will go down because OS will try to route the tunnel through the tunnel, to fix that we add a route to remote-host via local-gateway.
route add $remote gw $gateway
OS will send all SSH traffic to remote-host through our default gateway, so the tunnel keeps working fine, the rest of the traffic will go through the tunnel.
The script below automates all of the steps above, when run it will figure out the current gateway setup the tunnel and the routes so all traffic goes through the tunnel.
#!/bin/bash pidfile=/var/run/ppp0.pid pid= remote=95.85.48.115 gateway=$(/sbin/ip route | awk '/default/ { print $3 }') # trap ctrl-c and signal pppd to shutdown trap close_conn INT function close_conn(){ echo "Closing Connection." kill -HUP $pid } function setup_conn(){ cd ~/ echo "Current Gateway " $gateway route add $remote gw $gateway pppd updetach defaultroute replacedefaultroute usepeerdns noauth passive pty \ "ssh root@$remote -o Batchmode=yes /usr/sbin/pppd nodetach notty noauth ms-dns 8.8.8.8" \ 10.0.0.1:10.0.0.2 pid=`cat $pidfile` echo "Public Facing IP " `curl -s 'http://checkip.dyndns.org' | sed 's/.*Current IP Address: \([ 0-9\.\.]*\).*/\1/g'` } setup_conn while ps -p $pid > /dev/null; do sleep 1; printf \ "\rConnected For: %02d:%02d:%02d:%02d" \ "$((SECONDS/86400))" "$((SECONDS/3600%24))" "$((SECONDS/60%60))" "$((SECONDS%60))" done route del $remote gw $gateway