Mirroring an LDAP Key Directory to a Web Key Directory

An LDAP keyserver, for example implemented using a Windows LDS, is often used to keep track of own keys and keys of commonly used communication partners. This makes it easy to discover and fetch OpenPGP keys for sending mail to external peers or to encrypt files to them. However, external peers may also need to discover keys for their first mail contact. Obviously they won't be able to lookup keys on the other LDAP but they can still lookup the key using the Web Key Directory (WKD). In fact this is a very convenient method because GnuPG VS-Desktop automagically tries to fetch missing keys from WKD.

Several methods exist to maintain keys in the WKD. If an internal LDAP server already exists an elegant method is to mirror the keys from the LDAP server to the WKD. This article describes how to set this up.

Basic setup of an LDAP to WKD mirror

Since version 3.1.25 GnuPG VS-Desktop comes with support for mirroring the LDAP directory to a Web Key Directory. The way it works is to create a local copy of the WKD pages and then use established methods to upload the created pages to the actual web server.

The first step is to create a dedicated user and allow this user to access the LDAP. This user requires an installed GnuPG VS-Desktop (which we don't count towards the number of licenses) and the user needs read access to the LDAP. Thus it is configured like any other user of GnuPG VS-Desktop.

For a first test we run the commands directly. We assume that your domain is example.com

mkdir openpgpkey
gpg-wks-client --mirror example.com

Depending on the size of the LDAP directory this may take a while. The first command creates a top level directory. If you want to put it elsewhere use the option -C as in

gpg-wks-client --mirror -C x:/wkd-master example.com

Only keys with the mail address of its user ID ending in “@example.com” will be mirrored to the WKD. You may enter additional domains on the command line like in:

gpg-wks-client --mirror example.com example.de foo.example.org

This actually creates Web Key Directories for all three domains.

In case some keys from the given domains shall be excluded from the WKD, create a simple text file with the mail addresses to be excluded. For example a file internal-addresses.txt:

# Mail addresses which shall not be
# available via the Web Key Directory

chitchat@example.com
archive@example.com
test-account@foo.example.org
partytime@example.de

Empty lines and lines with a hash sign as the first non-blank character are ignored. Only mail addresses encoded in UTF-8 may be used. Do not enclose them in angle brackets. Now run the command:

gpg-wks-client --mirror --blacklist internal-addresses.txt \
  example.com example.de foo.example.org

(The backslash at the end of the first line merely indicates that the line is continued at the next line. Do not actually type it but use one line.)

The created directory structure may look like this:

openpgpkey
├── example.com
│   ├── hu
│   │   ├── mxqp8ogw4jfq83a58pn1wy1ccc1cx3f5
│   │   └── sofhofc64zck338ay4cmituhzs6h7p87
│   └── policy
└── example.de
    ├── hu
    │   ├── sofhofc64zck338ay4cmituhzs6h7p87
    │   └── ra7fsb7wiqyxddrdngjhx6n1jfke3qx3
    └── policy

Thus we see a directory for each domain. For each domain there is an empty policy file and below the hu directory the actual keys are stored under the hash of the names (e.g. support). The WKD uses hashes instead of plain names to avoid problems with file name encodings. For example, the local part "support" is always mapped to the string "mxqp8ogw4jfq83a58pn1wy1ccc1cx3f5".

Now that the directory structure exists, the next task is to sync it to the actual web server. In our example we use the rsync utility to upload directory by directory:

cd openpgpkey
rsync -r -p --chmod=Fa+r --delete example.com/  \
    server:/var/www/example.com/htdocs/.well-known/openpgpkey/
rsync -r -p --chmod=Fa+r --delete example.de/  \
    server:/var/www/example.de/htdocs/.well-known/openpgpkey/

A more elegant method is to upload all directories to a common place on the server and then use symlinks to hook them into the web structure. Although rsync is also available for Windows, often other techniques are used in a plain Windows environment. Please ask your web server administrators for the best method in your environment.

Automating the mirroring

The mirroring should happen at regular intervals, like once or twice a day. A simple script and a cron job or scheduled task is the way to go. The script should first remove the existing local mirror so that deleted or expired keys will be remove from the WKD as well (thus we use the delete option with rsync).

@echo off
if exist openpgpkey del /s/q openpgpkey 2>nul
set DOMAINS=example.com example.de foo.example.org
set BLACKLIST=c:\somewhere\internal-addresses.txt
gpg-wks-client --mirror --blacklist %BLACKLIST%  %DOMAINS%