8 releases (stable)

1.2.4 Oct 3, 2024
1.2.3 Oct 2, 2024
1.2.1 May 30, 2024
1.1.0 Feb 18, 2024
0.1.0 Feb 18, 2024

#198 in Cryptography

Download history 20/week @ 2024-09-22 422/week @ 2024-09-29 39/week @ 2024-10-06 1/week @ 2024-10-13

401 downloads per month

GPL-3.0 license

45KB
406 lines

Rust WKD server

What is WKD?

https://wiki.gnupg.org/WKD

Running this project

Put your public keys into ./openpgp/keys. Files should be named after the email address that the key is registered for. See some examples below:

  • Valid names:
    • user@example.com
    • user@example.com.asc (optional .asc file ending will be ignored)
  • Invalid names:
    • ktujkt7nrz91b17es7prizffedzxrsna (wkd hash -- this tool will hash the username)
    • my-public-key.asc

Optionally, put your policy into a text file in ./openpgp.

cargo build --release
./target/release/wkd-server ./openpgp/keys

Usage

Usage: wkd-server [OPTIONS] <KEYS_PATH>

Arguments:
  <KEYS_PATH>  The path where the GPG keys are stored

Options:
      --address <ADDRESS>  [env: ADDRESS=] [default: 0.0.0.0]
      --port <PORT>        [env: PORT=] [default: 8080]
  -p, --policy <POLICY>    The path to the policy file. If not set, an empty policy is served [env: POLICY=]
  -h, --help               Print help

Security

This server will refuse to serve private or invalid keys. If a file contains a private and a public key, only the public key will be served. Nonetheless, make sure to only include your public key.

Deployment

You can use this docker-compose.yaml example file as a starting off point for your deployment. Make sure to add your public keys as a volume.

services:
  wkd-server:
    image: ghcr.io/martin-fink/rust-wkd-server:latest
    volumes:
      - ./keys:/openpgp-keys:ro
    ports:
      - 127.0.0.1:8080:8080
    environment:
      - RUST_LOG=error,wkd_server=info # change this to trace for debugging
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.rust-wkd-server.rule=(Host(`<your-domain>`) && PathPrefix(`/.well-known/openpgpkey`))"
      - "traefik.http.routers.rust-wkd-server.entrypoints=<your-https-entrypoint>"
      - "traefik.http.routers.rust-wkd-server.tls=true"
      - "traefik.http.routers.rust-wkd-server.tls.certResolver=<your-certResolver>"
      - "traefik.services.rust-wkd-server.loadbalancer.passHostHeader=true"

Reverse proxy setup

You probably want to move this behind a reverse proxy such as nginx in order for it to handle https. You can use the following snippet for nginx. The important bit is to set the X-Forwarded-Host header, as that header is used to differentiate domains.

location ^~ /.well-known/openpgpkey {
    resolver 127.0.0.11 valid=5s;
    set $upstream_endpoint http://address:port;
    proxy_pass $upstream_endpoint;
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-Host $host;
}

Dependencies

~30–43MB
~648K SLoC