PPP Over SSH - a simple vpn solution for unix
Posted Mon, 01 Jan 2007
Table of Contents
Before you can actually run ppp(8), you must have root on both the client and gateway machines. Make sure you do.
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 -N "" -t rsa -f ~/.ssh/ppp.key
This should create two files, a public and private key:
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.
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 email@example.com"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
deviceused 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 18.104.22.168 with the private key we created in the last step.
ppp.confconfiguration for the gateway is much simpler. Again, I called the new section
vpn: set ifaddr 192.168.10.1 192.168.10.2 255.255.255.255Again, 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?
~/.ssh/ppp.keyand have put the contents of the public key (
~/.ssh/ppp.key.pub) into the gateway's
~/.ssh/authorized_keysfile. You can verify that this key is working by doing:
ssh -i ~/.ssh/ppp.key yourgatewayserverIf 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_keysfile should have something looking vaguely like this:
ssh-rsa AAAAB....lotsofcharacters...= psionic@somehostnameWe 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.
sudo, but I think it's easier to configure. Anyway, I have an entry in my
pppvpn /usr/sbin/ppp -direct vpn; users=psionic environmentThis 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.
- 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
ppp -auto vpnNow try pinging the gateway ip, which if you remember should be 192.168.10.1 (unless you set it differently).
nightfall(~)  % sudo ppp -auto vpn Password: Working in auto mode Using interface: tun0 nightfall(~)  % 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 ^CWorks! 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(~)  % sudo route add 22.214.171.124 192.168.10.1 add host 126.96.36.199: gateway 192.168.10.1 nightfall(~)  % sudo route add 188.8.131.52 192.168.10.1 add host 184.108.40.206: gateway 192.168.10.1 nightfall(~)  % sudo route add 220.127.116.11 192.168.10.1 add host 18.104.22.168: gateway 192.168.10.1 nightfall(~)  % traceroute google.com traceroute: Warning: google.com has multiple addresses; using 22.214.171.124 traceroute to google.com (126.96.36.199), 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 (188.8.131.52) 2.673 ms 2.197 ms 1.966 ms 3 rit-rit1-pp-core1-vlan807.rit.edu (184.108.40.206) 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.