ppp-ssh VPN
Author
Commands
# start with an empty set of ppp options mv /etc/ppp/options /etc/ppp/options.bak touch /etc/ppp/options # Can setting up an encrypted VPN really be this simple? pppd nodetach 10.0.3.1:10.0.3.2 pty "ssh -l root remotehost pppd notty"
These commands all have to be run from the root account.
Summary
Connecting two pppd commands together, on different hosts, over an existing network, by embedding an ssh command to start the remote one inside the pty argument of the one started on the local host. This creates an encrypted network tunnel through the existing network, aka, a VPN.
Discussion
There are lots of things that can go wrong with the third command above; so many that you may want to read the earlier articles in this series (../PPP with Pseudo Terminals and ../PPP with a pty Argument) so you will be in a position to validate each aspect of the connection between the two pppd processes this command creates.
Our first two commands move the existing /etc/ppp/options file out of the way and replace it with an empty file.
The pppd command will behave very differently depending on how all of its billion and one options are set. When experimenting, it's best to empty the /etc/ppp/options file so the only options in effect are the ones we supply on the command line. Each linux distribution may ship with a potentially different /etc/ppp/options file; you may want to save the default file somewhere before creating an empty one so you can restore the distribution's default policies once you are done experimenting.
The nodetach option prevents pppd from detaching from the terminal session it is invoked from, like it normally would, and sending its error and status messages to the syslog. Instead, it remains in the foreground, where it can easily be killed with a cntl-c, and all of its diagnostic output is printed to stdout. Without this option, you would be forced to do something like this to see the command's diagnostic messages:
tail -f /var/log/messages
The 10.0.3.1:10.0.3.2 argument is telling the outer pppd command to configure its end of the connection with IP address 10.0.3.1 and to tell the inner pppd command, when it asks, that it should set the IP address of its side of the connection to 10.0.3.2.
The discussion about pinging 10.0.3.1 or 10.0.3.2 in ../PPP_with_Pseudo_Terminals would apply to this scenario if "remotehost" and the localhost are in fact the same host. If they are different, you will see the ping packet go through ppp0 (on the host you are running from) and not through the loopback network interface lo.
Pitfalls
The third command will only work if the root account on the localhost has an RSA keypair (generated with an empty passphrase) and the public key has been added to root@remotehost:.ssh/authorized_keys. If this hasn't been done, the pty command will prompt the outer pppd process for a password, and receive a pppd link negotiation packet as its response.
Fortunately, it is easy to test this detail by running
ssh -l root remotehost
from the localhost to see if you get through without a password prompt.
The single liner presented here would typically need to be buried inside a much larger script to, at a minimum, figure out when the link may have gone down and restart it. Running a TCP/IP/PPP protocol stack on top of a TCP layer (which is what the ppp-ssh command in effect does) is not stable because of interactions between the two sets of TCP timers. There is the possibility that the link may become too slow as a result. I have, however, used this technique for many years to connect a workstation behind a firewall to my home network and have been suprised at how good its performance and stability are.
