To Home page
Most existing VPNs are extremely hard to set up correctly – and rather too easy to set up incorrectly.
Part of the problem is that many of them imitate or copy SSL's X.509 key negotiation. X.509 throws up its hands in despair at the key distribution problem and abandons it to the end user. SSL session setup performance is poor, and no one has succeeded in making SSL user friendly to use it in a way that is actually safe. If using SSL or its various successors, the end user must himself grapple with cryptographic concepts that give cryptographers a hard time, and which professional cryptographers frequently screw up. So inevitably, the end user gets it wrong almost all the time, even expert highly motivated users.
If you start from SSL or DTLS you are going to wind up with the sort of hopelessly difficult VPN setups that we have in fact wound up with. It is completely unacceptable to tell your end users to use OpenSSL to create certificates, certify them and then install the certificates, which is the sort of thing we are all too frequently instructed to do.
Instead, one needs to devise the user interface, then work backwards from the user interface to key negotiation, and then use SSL/TLS, or SSL/TLS concepts only to the extent that TLS fits the actual solution, rather than trying to build a solution out of TLS. In this page, I will describe VPN setup done right.
In any VPN system, each packet within a session must have its own unique IV (nonce), and each session must have its own symmetric encryption secret and authentication secret. We have to have a new session every client restart, every server restart, and every 2^64 bytes. At the beginning of each new session, new strong secrets, large truly random numbers, have to be negotiated for symmetric encryption and authentication.
The problem is that humans are not going to carry around large strong secrets every time either end of the connection restarts. In fact they are not going to transport large strong secrets any time ever, which is the flaw in SSL and its successors such as IPSec and DTLS.
Humans have long relied on shibboleths for security against treachery by outsiders. Thus the computer interface to our clever cryptographic algorithms must resemble as closely as possible the ancient human reliance on shibboleths for security.
What humans are going to do, and what the user interface must support, and the cryptography somehow make secure, is set up a user name and a rather short password, and enter that password on request – rather too easily enter it on request without necessarily checking who they are giving it to. Our security has to work with humans as they are, and make what humans are naturally inclined to do secure, rather than try to change what humans are naturally inclined to do.
So the VPN setup is this:.
Server starts VPN server program, client starts VPN client program for the very first time. Human at client enters a URL for the server program. If it connects to the server (or something pretending to be the server) it requests user name and password, which of course does not yet exist, and offers the user the choice of creating a new user name and password.
User at the client creates a new user name and password. Client logs in, and reports that user so and so has absolutely no privileges, needs to talk to the administrator on the server. The user at the client contacts the administrator on the server out of band, this being the standard way VPNs are in fact set up in practice. Our security ultimately rests on this out of band human to human discussion, which relies on standard human to human security, which humans are naturally quite good at, thanks to several million years of evolution involving frequently lethal treachery. The administrator then looks at the gui of the server program (yes, it has to have a gui, unlike most existing VPNs) which lists the various user names (but not their passwords, for, as we shall see, the server program does not in fact know the password). The administrator then gives user name the necessary privileges.
Obviously we do not want to repeat this scene every time either end of the connection restarts. So the client gives the end user the option that the client will remember the server address, user name and password, and logon automatically on startup – in which case anyone with physical access to the computer can steal the password, which can be strongly obfuscated but not truly hidden, but that is the kind of threat the end user can understand and properly evaluate. All existing VPNs have similar problems, as does email.
Also, anyone that installs malware on the end user's computer can steal the password, which threat the end user cannot be expected to understand or properly evaluate. We know how to defeat malware – Polaris and Bitfrost show how to make malware almost impossible, but malware resistant operating systems still have some rough edges. Regardless, SSL certificates and email programs have the same problem, so we are just going to live with the node weakness until the day that every operating system works the way that Bitfrost is intended to work.
Now we look at making this system cryptographically secure against active and passive attacks on the wire, phishing, and social engineering.
If the user enters the user name and password incorrectly, then he has to pass a reverse Turing test before entering the password again, to prevent scripts from trying millions of passwords. So if an attacker has tried to guess passwords, the VPN network will not automatically login on client startup, but will instead require user intervention to respond to the reverse Turing test. The user will be informed by the server that n unsuccessful login attempts have taken place against his user name, thus notifying him he is under attack. So the fact that the attacker can force manual intervention on client restart is hereby declared to be a feature, not a bug.
The user interface to create a connection never pops up spontaneously, but only as a direct result of the user choosing to cause it to pop up, typically by clicking the create-a-connection icon on his start menu.
We use password-authenticated key agreement to construct a strong frequently changing secret from the short infrequently changing secret. Thus if the user logs in to the wrong host – or to an adversary pretending to be the correct host in a man in the middle attack, the false server does not get the password or the session secret.
Password-authenticated key agreement also ensures that a passive eavesdropper will not discover the password or the strong session secret.
The short password is OK, because offline attacks are impossible due to password-authenticated key agreement. The total lack of security on the URL is OK because phishing attacks are impossible due to password-authenticated key agreement. Of course they are only impossible due to password-authenticated key agreement if the end user is using his own client with a hostile address and is therefore using password-authenticated key agreement. If he is using a hostile client, he is hosed. To reduce the risk that he may be fooled into using a hostile client, the user interface to create a connection should never pop up spontaneously. If the connection is needed, but not present, the operation should just fail.
The client software should always mangle the user passphrase with the unchanging server public key, so if the user uses the same password for accounts with multiple entities, those entities cannot use this against each other.
The reverse Turing test protects against scripted online password guessing attacks. The various retry, leakage, and replay attacks on symmetric encryption do not work because we always have a nonce for each and every packet, we password-authenticated key agreement renegotiate new shared secrets for every session and we have new sessions as often as cryptographically needed.
These documents are licensed under the Creative Commons Attribution-Share Alike 3.0 License