June 17, 2011, 12:16 p.m.
posted by alexpi
Use PPP and SSH to create a secure VPN tunnel.
There are so many options to choose from when creating a VPN or tunneled connection that it's mind-boggling. You may not be aware that all the software you need to create a VPN is probably already installed on your Unix machines—namely PPP and SSH daemons.
You might have used PPP back in the day to connect to the Internet over a dial-up connection, so you may be wondering how the same PPP can operate over SSH. Well, when you used PPP in conjunction with a modem, it was talking to the modem through what the operating system presented as a TTY interface, which is, in short, a regular terminal device. The PPP daemon on your end would send its output to the TTY, which the operating system would send out the modem and across the telephone network until it reached the remote end, where the same thing would happen in reverse.
The terminals that you use to run shell commands on (e.g., the console, an xterm, etc.) use pseudo-TTY interfaces, which are designed to operate similarly to TTYs. Because of this, PPP daemons can also operate over pseudo-TTYs. So, you can replace the serial TTYs with pseudo-TTYs, but you still need a way to connect the local pseudo-TTY to the remote one. Here's where SSH comes into the picture.
You can create the actual PPP connection in one quick command. For instance, if you wanted to use the IP 10.1.1.20 for your local end of the connection and 10.1.1.1 on the remote end, you could run a command similar to this:
# /usr/sbin/pppd updetach noauth silent nodeflate \ pty "/usr/bin/ssh [email protected] /usr/sbin/pppd nodetach notty noauth" \ ipparam 10.1.1.20:10.1.1.1 [email protected]'s password: local IP address 10.1.1.20 remote IP address 10.1.1.1
The first line of the command starts the pppd process on the local machine and tells it to fork into the background once the connection has been established (updetach). It also tells pppd to not do any authentication (noauth)—the SSH daemon already provides very strong authentication. The pppd command also turns off deflate compression (nodeflate). The second line of the command tells pppd to run a program and to communicate with it through the program's standard input and standard output. This is used to log into the remote machine and run a pppd process there. Finally, the last line specifies the local and remote IP addresses that are to be used for the PPP connection.
After the command returns you to the shell, you should be able to see a ppp interface in the output of ifconfig:
$ /sbin/ifconfig ppp0 ppp0 Link encap:Point-to-Point Protocol inet addr:10.1.1.20 P-t-P:10.1.1.1 Mask:255.255.255.255 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1 RX packets:58 errors:0 dropped:0 overruns:0 frame:0 TX packets:50 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:3 RX bytes:5372 (5.2 Kb) TX bytes:6131 (5.9 Kb)
Now to try pinging the remote end's IP address:
$ ping 10.1.1.1 PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data. 64 bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=4.56 ms 64 bytes from 10.1.1.1: icmp_seq=2 ttl=64 time=4.53 ms 64 bytes from 10.1.1.1: icmp_seq=3 ttl=64 time=5.45 ms 64 bytes from 10.1.1.1: icmp_seq=4 ttl=64 time=4.51 ms --- 10.1.1.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3025ms rtt min/avg/max/mdev = 4.511/4.765/5.451/0.399 ms
And finally, the ultimate litmus test—actually using the tunnel for something other than ping:
$ ssh 10.1.1.1 The authenticity of host '10.1.1.1 (10.1.1.1)' can't be established. RSA key fingerprint is 56:36:db:7a:02:8b:05:b2:4d:d4:d1:24:e9:4f:35:49. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '10.1.1.1' (RSA) to the list of known hosts. [email protected]'s password: [[email protected] andrew]$
Before deciding to keep this setup, you may want to generate login keys to use with ssh [Hack #73], so that you don't need to type in a password each time. In addition, you may want to create a separate user for logging in on the remote machine and starting pppd. However, pppd needs to be started as root, so you'll have to make use of sudo [Hack #6]. Also, you can enable SSH's built-in compression by adding a -C to the ssh command. In some circumstances, SSH compression can greatly improve the speed of the link. Finally, to tear down the tunnel, simply kill the ssh process that pppd spawned.
Although it's ugly and might not be as stable and full of features as actual VPN implementations, the PPP and SSH combination can help you create an instant encrypted network without the need to install additional software.
The section "Creating a VPN with PPP and SSH" in Virtual Private Networks, Second Edition, by Charlie Scott, Paul Wolfe, and Mike Erwin (O'Reilly)