Workings of a Virtual Private Network, Part 1
Commercial Virtual Private Network (VPN) products are becoming widespread. They let confidential data safely take the “free ride” offered by the Internet, compensating for the Net's intrinsic lack of security. A Linux VPN can be constructed several ways. One is outlined in the clever but spare VPN mini-HOWTO by Arpad Magosanyi. I implemented it for a business and present some of the insights gained.
Part 1 of this article is theoretical and explanatory, Part 2 practical. I first define VPNs and describe technologies they employ. I discuss the combination of Linux building blocks used by the HOWTO for constructing one. In Part 2, I show log and screen output depicting the results of actually running the script that constructs the VPN.
A VPN uses a public transport—the Internet—for private communications. It applies encryption to preserve privacy. Traditionally, companies have used private transport to do that—dedicated phone lines. The two ways of keeping an electronic conversation private are to make the line private and the data private. Dedicated lines are private because the line is private, i.e., inaccessible to others. VPNs are private because the data is private, i.e., rendered unintelligible by encryption—different means, same result.
VPNs are most commonly used to connect two networks at different sites of the same company. The technique in effect plugs the remote computers into the local network, consolidating the two physical nets into a single logical one. Remote computers have access to the same local resources as local ones. At the same time, remote machines enjoy the same degree of privacy as local ones. All this is location-transparent in terms of operation (though not performance) as if they were attached to the local network. This combination of full participation plus full privacy between networks, while using a link that isn't private, is the hallmark of a VPN. The compelling appeal of the VPN is that it's cheap. Dedicated lines are expensive, so displacing them with a free transport is economic.
The VPN in the HOWTO is fashioned from two main ingredients: the secure shell (ssh/sshd) and the point-to-point protocol (pppd). One machine (the “local” one in my terminology, “master” in Mr. Magosanyi's) runs the HOWTO's script to call another (my “remote”, his “slave”). I'll call these VPN servers. The idea is that they belong to the two networks to be joined and serve as the contact points or data conduits between them, on behalf of any remotely situated pair of workstations that want to converse.
The diagram in Table 1 depicts the layout and addresses in section 4.1 of the VPN HOWTO. For the public Internet addresses (fellini-out, polanski-out), I have substituted those actually in force when I generated the screen captures and log snippets shown later in this article for agreement.
To construct the VPN, the script on the local VPN server must execute four main commands, two of them on the remote VPN server:
pppd remotely, triggered somehow on the other VPN server
pppd locally, on the VPN server where the script runs
The pppd commands establish a working connection. It's strictly a bilateral umbilical cord between the VPN servers that extends no mutual connectivity to workstations on the networks. That is done by the route commands. Once these commands have been executed, the two networks have been transparently pooled into a single group of machines, all mutually visible via Internet addresses.
Privacy comes through the tool used by the first computer to trigger commands on the second, because that tool also does authentication and encryption. It's called the secure shell program, which is a remote command executor and an encryptor. Actually, it's a pair of programs, ssh and sshd, deliberately crafted to work together on the client-server model. Other familiar programs that use the model are ftp/ftpd, telnet/telnetd and any browser/httpd.
The “d” in sshd, ftpd and httpd stands for daemon, a synonym for server. Server programs are like genies that grant categories of wishes to their client/petitioners. So, ftpd grants file wishes to the ftp client and the httpd grants web-page wishes to a browser client. Likewise, sshd grants remote-command wishes to the ssh client. Additionally, ssh and sshd are written to encrypt and decrypt all traffic as it passes between them.
As a command executor, ssh can process a single command and exit. Alternatively, it can set up an open-ended login session where the user submits commands ad hoc. In both cases, ssh delivers back to the local machine the standard output from commands it tells sshd to run in the remote machine. The user sits physically at the local machine, logically logged in and functioning as one of the remote machine's users. All command or session output is delivered from the remote machine to his local monitor. This is much like telnet. Unlike telnet, everything gets encrypted and decrypted on the fly during the session.
The first sentence of the ssh man page highlights these roles:
ssh (Secure Shell) is a program for logging into a remote machine and for executing commands in a remote machine. It is intended to replace rlogin and rsh, and provide secure encrypted communications between two untrusted hosts over an insecure channel.
The syntax for setting up a remote login session is
ssh -lThe syntax for executing a single remote command is
ssh -l-l stands for “login” and specifies the user name for the remote computer login. The first command form gets you logged into the other machine as remote-user, with his login prompt on your screen. The second also logs you in and launches command on the remote machine all at one stroke. When the command terminates in the latter case, so does your connection. If command is ls /home, the listing of the other machine's /home subdirectory will be delivered to your screen. Here's an actual screen capture of it:
# ssh -l slave 220.127.116.11 ls /home david ftp httpd panderson samba slaveThe login prompt is that of the local machine, where the user is seated. The output comes from the remote machine, where ls was run (as a user on that machine called slave), but appears here on the local monitor. It shows the contents found in the remote directory /home.
Notice execution was unimpeded by password challenge. This is surprising for a program that's supposed to provide security. However, ssh did authenticate in an alternative, transparent way; its technique uses public-key cryptography and is called RSA authentication. I'll show you the evidence from the remote machine's log file, then explain how the keys work.
Concurrent with the above local activity, these entries appeared in the remote machine's log file (/var/log/messages):
Nov 7 20:15:54 localhost sshd: log: Connection from 18.104.22.168 port 1023 Nov 7 20:15:57 localhost sshd: log: RSA authentication for slave accepted. Nov 7 20:15:57 localhost sshd: log: executing remote command as user slave Nov 7 20:15:58 localhost sshd: log: Closing connection to 22.214.171.124 Nov 7 20:15:58 localhost PAM_pwdb: (ssh) session closed for user slave
Note that these entries were authored by sshd, the server half of the secure shell tandem of programs. That's reasonable, since the calling program on the local machine was the client half, ssh. By design, ssh calls and asks for the sshd process, hooking up to it by TCP port number where sshd runs, 22 by default but configurable. sshd then swings into action and they proceed to do their thing: authenticate and encrypt. We just saw secondary evidence of the authentication, although so far we've seen no evidence of the encryption. Both rely on the use of keys, in particular the matched pairs of keys that characterize public-key cryptography. Let me describe the essential theory and how you configure ssh with keys, before explaining how authentication results from their use.
First, here's a good nutshell summary from the README.SSH file:
When started, ssh connects sshd on the server machine, verifies that the server machine really is the machine it wanted to connect, exchanges encryption keys (in a manner which prevents an outside listener from getting the keys), performs authentication using...RSA authentication.... The server then (normally) allocates a pseudo-terminal and starts an interactive shell or user program.
Note that using ssh's -v option allows you to watch these activities.