feat(quic): enable HTTP/3 over QUIC on the edge + versioned images
HTTP/3 is config-only — the Debian haproxy package is built +QUIC via the OpenSSL compat shim. Changes: - hap_header.tpl: `limited-quic` (required to enable QUIC binds under the compat layer) + self-healing `cluster-secret` for QUIC token derivation. - hap_listener.tpl: `bind quic4@:443 ... alpn h3` in the shared frontend (so real-IP/rate-limit/IP-block/Coraza rules apply to H3 too) + alt-svc header. - Dockerfile/README: publish/document 443/udp; stamp image.version from VERSION. - CI: tag :latest + :<VERSION> + :<sha> so there's a pinnable rollback target. No 0-RTT (compat-layer limitation). Validated end-to-end on a standalone edge: config parses, UDP/443 binds, alt-svc advertised, real curl --http3 -> HTTP/3. Container must run with `-p 443:443/udp` + host UDP/443 open. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,23 @@ global
|
||||
# SSL and Performance
|
||||
tune.ssl.default-dh-param 2048
|
||||
|
||||
# HTTP/3 over QUIC. The Debian haproxy package is built against system
|
||||
# OpenSSL via the compatibility shim (USE_QUIC_OPENSSL_COMPAT), which is
|
||||
# not a native QUIC TLS stack. HAProxy therefore rejects `quic*@` binds
|
||||
# unless this opt-in is set. `limited-quic` enables QUIC through the compat
|
||||
# layer (no 0-RTT — that needs quictls/aws-lc or native OpenSSL 3.5 QUIC).
|
||||
# Without this, the quic bind in the frontend fails to start: "this SSL
|
||||
# library does not support the QUIC protocol".
|
||||
limited-quic
|
||||
{%- if cluster_secret %}
|
||||
|
||||
# Stable secret keying QUIC Retry/address-validation tokens. Self-healed
|
||||
# to /etc/haproxy/cluster-secret (named volume) by the manager so it
|
||||
# survives recreates; without it haproxy picks a random one per process
|
||||
# and tokens don't survive reloads (benign, just a startup notice).
|
||||
cluster-secret "{{ cluster_secret }}"
|
||||
{%- endif %}
|
||||
|
||||
# HTTP/2 protection against Rapid Reset (CVE-2023-44487) and stream abuse
|
||||
tune.h2.fe.max-total-streams 2000
|
||||
tune.h2.fe.glitches-threshold 50
|
||||
|
||||
@@ -4,6 +4,21 @@ frontend web
|
||||
# crt can now be a path, so it will load all .pem files in the path
|
||||
bind 0.0.0.0:443 ssl crt {{ crt_path }} alpn h2,http/1.1
|
||||
|
||||
# HTTP/3 over QUIC (UDP/443). Same cert path as the TCP listener above.
|
||||
# The Debian haproxy package is built +QUIC (QUIC_OPENSSL_COMPAT), so this
|
||||
# is config-only — no source build. Requires UDP/443 published on the
|
||||
# container (`-p 443:443/udp`) and open at the host firewall. `h3` is the
|
||||
# only ALPN QUIC negotiates; h2/http1 stay on the TCP bind above. Sharing
|
||||
# the frontend means all the real-IP, rate-limit, IP-block and Coraza
|
||||
# rules below apply identically to H3 traffic.
|
||||
bind quic4@0.0.0.0:443 ssl crt {{ crt_path }} alpn h3
|
||||
|
||||
# Advertise H3 so browsers upgrade their existing TCP (h2) connection to
|
||||
# QUIC on the next request. `ma` is how long (seconds) the client may
|
||||
# cache the advertisement. http-after-response applies it to every
|
||||
# response, including haproxy-generated ones (blocks, default page).
|
||||
http-after-response set-header alt-svc "h3=\":443\"; ma=86400"
|
||||
|
||||
# Capture Host header so it appears in httplog output (in %hr field)
|
||||
http-request capture req.hdr(Host) len 64
|
||||
|
||||
|
||||
Reference in New Issue
Block a user