Load-balancing SKS

The synchronizing key server (SKS) is the most used implementation of OpenPGP key servers. Despite its many strengths, however, its web frontend scales badly and should generally be placed behind a reverse proxy such as nginx, apache or varnish. For inclusion in the High-Availability (HA) pool of sks-keyservers.net this is a requirement, and it is also part of the weighting criteria for the various geographical sub pools. With the increase in number of keys I've been thinking of ways to ensure that the pool stays even more responsive, and currently considering (i) to make it a hard-requirement for inclusion in the pool to have a reverse proxy set up (ii) to reuse the HA pool for a set of servers that are even more available, by proving that they are load-balanced across multiple instances of SKS.

 

My own keyserver, for historical reasons named keys2.kfwebs.net (keys.kfwebs.net was located in another server facility and is currently not operational),  is running such a load balanced setup using Nginx's upstream module.But before getting back to that, some basic information about my SKS setup.

Two or three SKS servers (depending on whether I need to use one of them for experimenting with other projects such as the Key Signing Party list auto-generating lists based on publications to a keyserver) are running on different Virtual Machines, one server peering with the global network and the other servers peering internally. To ease the load on SKS, static pages are served by nginx directly using:

location / {
root /var/sks/web;
index   index.xhtml;
}

 

The actual data being served by SKS is in the /pks subdirectory and is being handled by the directive

location /pks {
proxy_pass http://sks_servers/pks;
proxy_pass_header  Server;
add_header Via "1.1 keys2.kfwebs.net";
proxy_ignore_client_abort on;
}

And this is where the load-balancing is starting to happen. "sks_servers" is not a hostname that is being referenced but an upstream directive in Nginx that states;

upstream sks_servers
{
server  localhost:11372;
server  192.168.0.27:11371;
}

When adding and removing servers I simply edit this directive and reload nginx, and here I also have the possibility of assigning weights to each of the servers (defaults to 1).
In the status list of the pool such load-balanced servers can be identified by a blue flag for RProx (Reverse Proxy). Hopefully enough operators will set up load-balanced systems for an even more responsive High-Availability pool to exist.