The poor man's anonymizing VPN tunnel using SSH and pppd

published May 15, 2007, last modified Jun 26, 2013

Want to create a quick 'n dirty secure tunnel between your computer and a remote SSH server? Now you can.

/usr/sbin/pppd pty "ssh myinternetserver.com -t -e none -o 'Batchmode yes' \
/usr/sbin/pppd" 192.168.16.1:192.168.16.254 local nodetach silent \

This is all you need to create a secure tunnel between your computer and a computer that has the SSH running (in the example, myinternetserver.com) on the Internet.

Once you run this command, both your local and your remote computers will have new PPP network interfaces:

  • Local: interface ppp0, IP address 192.168.16.1
  • Remote: interface ppp0, IP address 192.168.16.254

But a few quick and easy preparations are needed in order to run and take advantage of this kind of tunnel.

The SSH server installed on the server, pppd on both machines

This should be self-explanatory. Use your Linux distribution's package management tools to install them -- should take less than 1 minute.

The right pppd configuration

You use the /etc/ppp/options file to configure it. Most options, once set in the configuration file, cannot be overriden in the command line.

On the server's /etc/ppp/options file

lock
noauth
ipcp-accept-local
ipcp-accept-remote
noproxyarp

On the client's /etc/ppp/options file

lock
noauth
noproxyarp

The right security configuration

[root@mycompanyserver.com #] /usr/sbin/groupadd -r ppp
...(add your SSH login user name to the ppp group in /etc/group)...
chown root.ppp /usr/sbin/pppd
chmod 750 /usr/sbin/pppd
chmod +s /usr/sbin/pppd

Now only members of the ppp group (namely, you) can join the fun.

SSH public key authentication enabled

  • Put PubkeyAuthentication yes in the server's /etc/ssh/sshd_options.
  • Generate an SSH key pair in your computer.
  • Upload the public key of the generated pair to your server's ~/.ssh/authorized_keys2 file. Don't forget to chmod 600 that file, or else SSH won't even look at it.

That's it!

Now run the following command on your computer:

/usr/sbin/pppd pty "ssh myinternetserver.com -t -e none -o 'Batchmode yes' \
/usr/sbin/pppd" 192.168.16.1:192.168.16.254 local nodetach silent \

What this command basically does is start pppd locally, tell it to connect via SSH in batch mode (using the public key, so it doesn't ask for your password), start pppd on the remote server, and use the SSH connection as their conversation path.

Wait a few seconds. pppd will utter a few things:

Using interface ppp0
Connect: ppp0 <--> /dev/pts/7

You will have to confirm that the PPP interface is up:

[youruser@yourcomputer $] /sbin/ifconfig ppp0
ppp0      Link encap:Point-to-Point Protocol
          inet addr:192.168.16.1  P-t-P:192.168.16.254  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:5 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3
          RX bytes:75 (75.0 b)  TX bytes:69 (69.0 b)

Now you can ping 192.168.16.254. If pinging fails, check the firewall rules on both the server and your computer.

To interrupt the tunnel, hit Ctrl+C on the terminal that holds the running pppd command.

What next?

Bringing the tunnel up is actually one part of the deal. If you're like me, perhaps you'll want to actually carry all of your network traffic across the tunnel.

Set up the remote server to route traffic for you

This is easy. On the server, either:

  • set firewall rules that will do NAT between the PPP interface and the Internet; or
  • replace noproxyarp with proxyarp in the (server's) /etc/ppp/options file; then set aside an extra IP address in the (server's) local network; then use it as the remote endpoint in the pppd command. If your server has IP address 2.3.4.5, then provision 2.3.4.6 and use it instead of 192.168.16.254.

Set the default route to be the tunnel's remote endpoint

If you want to route all of your network traffic through your newly created PPP link, you need to do two steps in this order:

  1. Manually add a route to your server, so the SSH traffic knows the physical route it should follow. If the IP address of your current default route is 4.5.6.7, then run route add mycompanyserver.com gw 4.5.6.7
  2. Replace the default route. Run route add default gw 192.168.16.254 dev ppp0

Before you suggest the pppd's defaultroute option: no, it won't work, because it'll disrupt the only communication route between your computer and the remote SSH server.

Perhaps you'd like to add manual, shorter routes to your DNS servers -- otherwise Web browsing may get a little slow. You know, due to the latency of the tunnel and stuff...

After doing this:

  • your computer will send all (SSH) traffic to mycompanyserver.com through your regular default route, so the tunnel keeps working fine;
  • the rest of the traffic will go through the PPP interface (notice we named the remote IP address in the default route command?)

Combine this with the proxyarp option on the server, and you have a recipe to make your computer appear as a completely different computer on the Internet. Perfect for anonymizing your real computer!