photo
Jordan Sissel
geek

Mon, 01 Jan 2007

PPP Over SSH - a simple vpn solution for unix

What is PPP over SSH?

PPP over SSH is a quick and dirty vpn solution. You can run a PPP connection over an SSH connection to make for an easy, encrypted vpn. Sure, there are lots of existing, prepackaged vpn solutions out there, but how difficult are they to setup? What do you need to install on *both* points of the vpn connection? Why is the sky blue?

If you run any flavor of *nix (Free/Open/NetBSD, Linux, etc), chances are you have two things installed: ppp and ssh. With these two tools you can create your own encrypted vpn in only a few minutes. In this article, I will explain how to set it up under FreeBSD, though it should be similar in other OS's.

What do I need to know?

Before I get into the details, I'm first going to explain the situation I'm using ppp over ssh in. You need two machines for this, your client (say, my laptop) and the endpoint (one of my freebsd servers). Here's a picture, so you can get a general idea of what is going on and what the final result will be:

The gist of it is as follows: My laptop is on an insecure, wireless, untrusted network. I want my traffic to be more secure, so people can't gather anything useful out of my packets they sniff over the air. My server is on a more trusted network, so that's where I'll want to tunnel all of my traffic. From there, my traffic will hit the Internet or whatever it's intended destination may be.

Special mentions should be made: If I refer to client, I'm talking about my laptop. If I refer to gateway, I'm referring to my endpoint server on the trusted network.

What do I need to do?

There are many steps here, make sure you do all of them :)

You need root

Before you can actually run ppp(8), you must have root on both the client and gateway machines. Make sure you do.

Create an ssh key

First, you're going to need a passphraseless ssh key so we can login to your vpn gateway without a password. You do this by using the ssh-keygen command.

ssh-keygen -N "" -t rsa -f ~/.ssh/ppp.key

This should create two files, a public and private key: ~/.ssh/ppp.key and ~/.ssh/ppp.key.pub. The first one is your private key, you'll need to keep that on your client machine. The public key needs to go on your gateway (vpn endpoint). Assuming your end point is running OpenSSH, you need to copy the contents of your public key into ~/.ssh/authorized_keys on the gateway server. That's all you need to do for ssh keys right now , I'll come back to the key later.

Client ppp.conf

The next file you want to look at is /etc/ppp/ppp.conf. This is where FreeBSD's ppp(8) looks for it's configuration. You need to add a new entry, I called mine vpn. Here i what I used:

vpn:
  set ifaddr 192.168.10.2 192.168.10.1 255.255.255.255
  set dial 
  set device "!env SSH_AUTH_SOCK= ssh -C -c blowfish -i /home/psionic/.ssh/ppp.key psionic@129.21.61.7"
        
Remeber, this configuration is for the client only. The first line tells ppp to create a tunnel between 192.168.10.2 and 192.168.10.1. The first IP on this line is the desired IP of the client on your new private network. The second address is the target IP of the tunnel, which is the gateway.

These two IPs can be different, as long as they are on the same subnet and are in the nonroutable range. It'd work cleaner aswell if you didn't pick a subnet already in use in either end of your network, if any are in use at all.

The only special note here, is the device used in this ppp session. It is not a device, but ppp is told to execute ssh(1) and use it as a transport medium. It will ssh to 129.21.61.7 with the private key we created in the last step.

Gateway ppp.conf

The ppp.conf configuration for the gateway is much simpler. Again, I called the new section vpn. Here:
vpn:
  set ifaddr 192.168.10.1 192.168.10.2 255.255.255.255
        
Again, the first ip in that line is the desired private ip of this machine, which is the gateway this time. Remember above when we set the client's ip to 192.168.10.2 and the tunnel endpoint ip to 192.168.10.1?

More ssh key business

I said we'd come back to the ssh key, right? You should now have your private key on the client as ~/.ssh/ppp.key and have put the contents of the public key (~/.ssh/ppp.key.pub) into the gateway's ~/.ssh/authorized_keys file. You can verify that this key is working by doing:
 ssh -i ~/.ssh/ppp.key yourgatewayserver
If it lets you login without prompting for a password, then you've done it right. If it doesn't work, then you probably didn't copy the public key properly or at all. Check the permissions of the .ssh directory and the authorized_keys file on the gateway. .ssh should be 0700 and authorized_keys should be 0600.

Assuming all goes well, we'll need to tell the gateway to execute a specific command for the key we are using. Your current authorized_keys file should have something looking vaguely like this:
 ssh-rsa AAAAB....lotsofcharacters...= psionic@somehostname 
We need to add a command section now. Add this:
command="op pppvpn" ssh-rsa AAAAB...etc...
All you add is a command="op pppvpn" to the beginning of the line. That command is just what it looks like: when you login with the key you created, it will run "op pppvpn" regardless of what command you try to run, or even if you try to get a login shell. This secures your gateway by greatly limiting what can be done should your private key become compromised. Granted, with a ppp connection they'll be able to pretend they are coming from your gateway server, but they won't get access to the machine itself.

Installing 'op'

You don't have to do this. I use op to run things as root. It's similar to sudo, but I think it's easier to configure. Anyway, I have an entry in my op.access:
pppvpn  /usr/sbin/ppp -direct vpn; users=psionic environment
This means that when I (psionic) type "op pppvpn", then op will run "/usr/sbin/ppp -direct vpn" as root for me.

You can alternatively use sudo or put your public key in your root user's .ssh/authorized_keys and ssh to the server as root. Either way, you need to be able to ssh to your gateway from your client and attain root privileges so you can run ppp(8) on the gateway.

Let's test it!

Everything should be setup now:
  • ppp.conf on the client
  • ppp.conf on the gateway
  • ssh key with public/private parts put in the right places
  • root access attainable through ssh login on the gateway with the ssh key
We can now try starting our vpn, as root on the client, type:
ppp -auto vpn
Now try pinging the gateway ip, which if you remember should be 192.168.10.1 (unless you set it differently).
nightfall(~) [1012] % sudo ppp -auto vpn
Password:
Working in auto mode
Using interface: tun0
nightfall(~) [1013] % ping 192.168.10.1
PING 192.168.10.1 (192.168.10.1): 56 data bytes
64 bytes from 192.168.10.1: icmp_seq=0 ttl=64 time=2.672 ms
^C
Works! Now, how do you get traffic to go through this tunnel? Use routes. An example would be if I wanted all my google.com traffic to go through the tunnel:
nightfall(~) [1001] % sudo route add 216.239.39.99 192.168.10.1
add host 216.239.39.99: gateway 192.168.10.1
nightfall(~) [1002] % sudo route add 216.239.57.99 192.168.10.1
add host 216.239.57.99: gateway 192.168.10.1
nightfall(~) [1003] % sudo route add 216.239.37.99 192.168.10.1
add host 216.239.37.99: gateway 192.168.10.1

nightfall(~) [1004] % traceroute google.com
traceroute: Warning: google.com has multiple addresses; using 216.239.57.99
traceroute to google.com (216.239.57.99), 64 hops max, 40 byte packets
 1  192.168.10.1 (192.168.10.1)  2.589 ms  1.707 ms  1.728 ms
 2  rit-core1-vlan60.rit.edu (129.21.61.232)  2.673 ms  2.197 ms  1.966 ms
 3  rit-rit1-pp-core1-vlan807.rit.edu (129.21.8.25)  2.724 ms  2.607 ms  2.203 ms
 ...
And we're all done! You can see that the first route goes to 192.168.10.1.

Summary

So now you know how to tunel with ppp using ssh as transport. If something in this article is unclear or you need more information, shoot me an email and I'll try and clear it up for you :)

Comments: 9 (view comments)

Permalink: /articles/ppp-over-ssh/main
posted at: 00:11


9 responses to 'PPP Over SSH - a simple vpn solution for unix'

Fabio Pani posted at Fri Nov 24 05:08:43 2006...
Thank you very much for this useful howto! I could set up a VPN connection from home to my office and it works fine!




I'm using an inner host at my office's LAN so I had to enable packet forwarding. I also enabled "proxy" in the PPP connection (by adding `enable proxy` in the "vpn:" section).



Bye!

Root posted at Wed Jan 31 05:41:46 2007...
Complicated (for me anyway) .. but inspires me to think deeper about what's possible code-wise. BTW, could the "filtering" (for lack of a better word on my part) be done using domains instead of IPs? (as in your example using Google)

helge posted at Fri Aug 31 12:45:09 2007...
I'd say that

env SSH_AUTH_SOCK=

is superfluous, isn't it? Else, what is the purpose?

Secondly, I'm using a slightly similar setup. Instead creating a separate key for the ppp connection, I simply use the one already existing for (referring to the example) psionic@somehostname. I don't have to fiddle with ~/.ssh/authorized_keys but just start the ppp command from remote, viz:

set device "!su - psionic -c \"ssh somehost ppp -direct vpn\""

(Note this assumes that "psionic" is the user on the client as well as the server machine. You'll have to adapt the ssh command if not.)

The only shortcoming is that psionic on the server must be made member of the network group in order so start ppp. Now you may contest what is safer: making psionic member of network, or using sudo/op to gain root privileges in order to start ppp...

Jordan Sissel posted at Fri Aug 31 13:52:04 2007...
It may be superfluous. I forget why I added that, probably to keep the ssh-agent from being used at all (which I didn't need since I had a passphrase-less key to do my ssh+ppp with).

You certainly don't need it, especially if you're using ssh-agent for your keys. Good point :)

Fabio Piergentili posted at Sat Sep 1 09:49:30 2007...
I noticed that you explicitly set an IP address on the gate way for your laptop in the ppp.conf file. What if you have more than one machine vpning into the gateway. What would the gateway ppp.conf contain?

Thanks

Jordan Sissel posted at Sat Sep 1 17:30:07 2007...
That's a good question. I've never done a multiuser/multihost ssh vpn setup before. For those, I've always used PPTP. I don't know ;(

Andrew posted at Sun Sep 30 02:30:00 2007...
set ifaddr  192.168.10.1 192.168.10.5-192.168.10.10 255.255.255.255

David posted at Fri Oct 26 10:50:38 2007...
I'm getting errors that take the link down. On the server side:

Child process pppd (charshunt) (pid 4602) terminated with signal 13

and on the client side:
  171 Oct 25 22:52:27 client pppd[1477]: local  IP address 192.168.14.1
  172 Oct 25 22:52:27 client pppd[1477]: remote IP address 192.168.14.2
  173 Oct 25 22:52:28 client pppd[1479]: ioctl(set extended ACCM):
Invalid argument
  174 Oct 25 22:52:28 client pppd[1479]: ioctl(PPPIOCSASYNCMAP):
Invalid argument
  175 Oct 25 22:52:28 client pppd[1479]: ioctl(TIOCSETD, TTYDISC):
Inappropriate ioctl for device
  176 Oct 25 22:52:28 client pppd[1479]: ioctl(TIOCNXCL):
Inappropriate ioctl for device(25)

Any suggestions?

Kaos posted at Sun Aug 17 23:20:29 2008...
I have a very general question. Ignoring the security part, why do we need a PPP? Can't things work just fine using TCP?


Leave a reply

You need javascript enabled to use this form. Anti-spam efforts ongoing. Also, if the comment doesn't show up, it's because the form expired. Go back and copy your comment, reload the form, and resubmit. Apologies if this is a hassle, I'm just playing with antispam methods right now. If this insists on not working, please email me about it.

Name (required)
E-mail (optional, if you want me to be able to email you back)
URL (also optional)
Comment:


Search this site

Navigation

Metadata

Home About Resume My Code (SVN)

Articles

ARP Security Dynamic DNS with DHCP OpenLDAP+Kerberos+SASL PPP over SSH SSH Security: /bin/false Week of Unix Tools Work Efficiency

Projects

fex firefox tabsearch firefox urledit grok keynav liboverride newpsm (FreeBSD) nis2ldap pam_captcha poor man's backup Solaris audio utility xboxproxy xdotool xmlpresenter xpathtool misc scripts

Presentations

Yahoo! Hack Day '06 Unix Essentials Vi/Vim Essentials

Tag Cloud

Calendar

< January 2007 >
SuMoTuWeThFrSa
  1 2 3 4 5 6
7 8 910111213
14151617181920
21222324252627
28293031   

Friends

BarCamp Kent Brewster Tantek Çelik John Resig Wesley Shields Tyler Shields

Technorati