SSL Support =========== PostgreSQL provides 4 levels of support for SSL. SSH Tunnels ----------- The minimal SSL support is provided by SSH tunnels. The benefits of SSL tunnels are that they are widely available and fairly well understood. Unfortunately, there are many potential drawbacks to SSL tunnels: - the SSH implementation may be flawed, - the SSH protocol may be flawed, - the installation may be flawed, - the database server must provide shell accounts for all users (or systems) setting up SSH tunnels. This makes it very hard to ensure that the database server is 'locked down,' - it can get very confusing if multiple users on the same system connect to a remote database (do you set up a systemwide tunnel? individual tunnels?), - neither the database nor clients can determine the level of encryption provided by the SSH tunnel, and - SSH tunnels don't provide SSL authentication to applications. The problems with the SSH protocols and implementations should not be trivialized - both SSH and OpenSSH seem to be have a "critical" bug that requires an immediate software upgrade every 18- to 24-months. Bottom line: if you're concerned about confidentiality, SSH tunnels are a good first step while you evaluate whether the performance hit due to the encryption is acceptable. But in the long run you'll probably want to migrate to a true SSL solution. Setup ..... To set up an SSH tunnel to a database server, use something like $HOME/.ssh/config ----------------- + LocalForward 5555 psql.example.com:5432 $HOME/bin/psql --------------- #!/bin/sh HOST=psql.example.com IDENTITY=$HOME/.ssh/identity.psql /usr/bin/ssh -1 -i $IDENTITY -n $HOST 'sleep 60' & \ /usr/bin/psql -h $HOST -p 5555 $1 ANONYMOUS DH Server ------------------- The biggest problem with SSH tunnels is the need to maintain those tunnels. If we the backend can support SSL connections directly, most of the problems with SSH tunnel will disappear. "ANONYMOUS DH" is the most basic SSL implementation. It does not require a server certificate, so it can be enabled immediately once the database has SSL support compiled in. Once this has been done the database server does not need to provide shell accounts for users, and can be fully locked down. The drawback to ANONYMOUS DH is that the client still has no way of determining the true identity of the backend. Setup ..... To set up ANONYMOUS DH, make sure the database is compiled with support for SSL and start postmaster with the "-i -l" flags. There is no need to set up a server key. SERVER-only Authentication -------------------------- The biggest problem with ANONYMOUS DH servers is that the client has no way of determining the identity of the server. Server Authentication (with certificates) solves this problem - indeed it should eliminate all "man-in-the-middle" attacks. The main drawback to Server Authentication is that is requires creating a server certificate, and distributing the server cert (or a CA cert) to all clients. Fortunately it is straightforward to compile a certificate into the client library so that the net cost to clients is no more than for ANONYMOUS DH SSL. A more subtle drawback to Server Authentication is that it gives the server no information about the clients connecting to it. This can result in confusing instructions for "road warriors" who need to access the database remotely. (Remember that the problem isn't granting access to the road warriors, it's letting them in while blocking the 6-billion odd people who shouldn't have remote access to your database.) Setup ..... To set up Server Authentication, run the mkcert.sh script provided with PosgreSQL to generate the server cert and private key. Then either copy the "root.crt" file to each user's $HOME/.postgresql directory, or recompile the database with [[insructions to be determined]]. MUTUAL Authentication --------------------- The biggest drawback to Server-only Authentication is the poor support for "road warriors." Mutual authentication neatly solves this problem since clients are permitted (or required) to provide their own certificate to establish a connection. Setup ..... Set up the server as described above, then have each user run pgkeygen(1) to generate their own client certificate and private key. The client certificates should be mailed to the DBA for him to "sign" these certs and associate a PostgreSQL user with each of them. The signed certs should then be stored in the user's $HOME/.postgresql directory.