Post Quantum Caddy

Hello guys,
thank for this nice project.

1. The problem I’m having:

I’m trying to compile caddy with support for PQC so X25519MLKEM768 or X25519Kyber768Draft00.

I tried multiple go version, because the behavior is different from what’s mentioned here:

I tried using sam-burns blog post steps.
And using caddy commit from july 2024, but failed also.

2. Error messages and/or full log output:

$ curl -vv -k https://localhost 2>&1  | grep "SSL connection"
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256 / X25519 / id-ecPublicKey

3. Caddy version:

5c47c2f147e5bef44fc8cb48a655d31f5a2a817c (30 Aug 24 15:01 UTC)
Also tried a version from february.

4. How I installed and ran Caddy:

Compiled from source once: tried with:

a. System environment:

docker
Linux 9ddf86fd45ee 6.11.0-17-generic #17~24.04.2-Ubuntu SMP PREEMPT_DYNAMIC Mon Jan 20 22:48:29 UTC 2 x86_64 GNU/Linux

docker run --rm -p 443:443 -v ./share:/share -it golang:1.23 bash
docker run --rm -p 443:443 -v ./share:/share -it golang:1.24 bash

b. Command:

caddy file-server --root /var/www/html/public/ --domain localhost
caddy run --config Caddyfile

d. My complete Caddy config:

Tried this config from here: Revisions · Compile Caddy with support for post-quantum key agreement (X25519+Kyber) · GitHub

localhost {
    reverse_proxy https://pq.cloudflareresearch.com {
        header_up Host {upstream_hostport}
        transport http {
            tls_curves X25519Kyber768Draft00 x25519 secp256r1
        }
    }
}

Here it’s mentioned that somehow the curves config should be nil. So I tried using this commit also : 2bc1e11ce514d0e42dc240ed0bba397b1e7f8f23

If you have pointers about which, go version, the commit hash and the config, it would help a lot :slight_smile:

Thank you.

This commit adds PQC:

Build with Go 1.24.

Although, upon looking at that, I noticed a typo – it probably won’t affect you testing from that commit, but I fixed it in this commit:

i.e. just build from the latest commit on master with Go 1.24 and you should get PQC.

2 Likes

Hello Matt,

thank for the reply! Appreciate it.

It’s still not working on my side, maybe my Caddyfile is not correct.

Caddyfile

localhost {
    reverse_proxy https://pq.cloudflareresearch.com {
        header_up Host {upstream_hostport}
        transport http {
            tls_curves x25519mlkem768
        }
    }
}

Compilation with Go 1.24

docker run --rm -p 443:443 -v ./share:/share -it golang:1.24 bash
cd /root
git clone https://github.com/caddyserver/caddy
cd caddy/cmd/caddy/
go build
cp caddy /share/caddy_04_03_2025

Curl

curl -vv https://localhost/ 2>&1 | grep "connection"
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256 / X25519 / id-ecPublicKey

Wireshark

Key Share Entry: Group: x25519, Key Exchange length: 32

Expected

I’m kind of expecting x25519mlkem768 instead of x25519, correct ?

Run

sudo ./caddy_04_03_2025 run --config Caddyfile
2025/03/04 12:34:36.859	INFO	maxprocs: Leaving GOMAXPROCS=8: CPU quota undefined
2025/03/04 12:34:36.859	INFO	GOMEMLIMIT is updated	{"package": "github.com/KimMachineGun/automemlimit/memlimit", "GOMEMLIMIT": 14910695424, "previous": 9223372036854775807}
2025/03/04 12:34:36.860	INFO	using config from file	{"file": "Caddyfile"}
2025/03/04 12:34:36.860	INFO	adapted config to JSON	{"adapter": "caddyfile"}
2025/03/04 12:34:36.860	WARN	Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies	{"adapter": "caddyfile", "file": "Caddyfile", "line": 2}
2025/03/04 12:34:36.861	INFO	admin	admin endpoint started	{"address": "localhost:2019", "enforce_origin": false, "origins": ["//[::1]:2019", "//127.0.0.1:2019", "//localhost:2019"]}
2025/03/04 12:34:36.861	INFO	http.auto_https	server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS	{"server_name": "srv0", "https_port": 443}
2025/03/04 12:34:36.861	INFO	http.auto_https	enabling automatic HTTP->HTTPS redirects	{"server_name": "srv0"}
2025/03/04 12:34:36.861	INFO	tls.cache.maintenance	started background certificate maintenance	{"cache": "0xc0001b3100"}
2025/03/04 12:34:36.862	INFO	http	enabling HTTP/3 listener	{"addr": ":443"}
2025/03/04 12:34:36.862	INFO	http.log	server running	{"name": "srv0", "protocols": ["h1", "h2", "h3"]}
2025/03/04 12:34:36.862	WARN	http	HTTP/2 skipped because it requires TLS	{"network": "tcp", "addr": ":80"}
2025/03/04 12:34:36.862	WARN	http	HTTP/3 skipped because it requires TLS	{"network": "tcp", "addr": ":80"}
2025/03/04 12:34:36.862	INFO	http.log	server running	{"name": "remaining_auto_https_redirects", "protocols": ["h1", "h2", "h3"]}
2025/03/04 12:34:36.862	INFO	http	enabling automatic TLS certificate management	{"domains": ["localhost"]}
2025/03/04 12:34:36.862	INFO	pki.ca.local	root certificate is already trusted by system	{"path": "storage:pki/authorities/local/root.crt"}
2025/03/04 12:34:36.862	WARN	tls	unable to get instance ID; storage clean stamps will be incomplete	{"error": "invalid UUID length: 0"}
2025/03/04 12:34:36.862	INFO	autosaved config (load with --resume flag)	{"file": "/root/.config/caddy/autosave.json"}
2025/03/04 12:34:36.862	INFO	serving initial configuration
2025/03/04 12:34:36.874	INFO	tls	storage cleaning happened too recently; skipping for now	{"storage": "FileStorage:/root/.local/share/caddy", "instance": "00000000-0000-0000-0000-000000000000", "try_again": "2025/03/05 12:34:36.874", "try_again_in": 86399.999999378}
2025/03/04 12:34:36.874	INFO	tls	finished cleaning storage units

Thank you :slight_smile:

Up :slight_smile:

Honestly, I don’t know – I’m not sure how individual clients are configured. Many may not even enable PQC yet, I dunno. (I’ve been very busy lately, sorry.)

If someone wants to dive deep to answer the question, that’d be welcomed!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.