Repository navigation
Conversation
A host with "h3" in Protocols now serves HTTP/3 with the certificate mod_ssl already resolved for it (SSLCertificateFile and mod_md alike), the way mod_http2 rides mod_ssl. The certificate and key are loaded in the ap_ssl_add_cert_files hook, during startup while httpd still runs privileged, so a key readable only by root loads for QUIC as it does for mod_ssl instead of failing in the unprivileged child. H3CertificatePath and H3CertificateKeyPath are removed; drop them from existing configurations. Each virtual host on a shared port now presents its own certificate over HTTP/3, chosen by the client SNI; an unmatched name gets the listener default. Names come from ServerName, ServerAlias and the wildcard ServerAlias names that httpd keeps in wild_names, and every entry is matched with ap_strcasecmp_match, the matcher httpd uses for its own virtual hosts. A cert_cb on the listener context applies the matched host certificate, key and chain to the connection: SSL_set_SSL_CTX does not switch the certificate of a QUIC connection. Landing it exposed that the module ran with AP_MODULE_FLAG_NONE, so a host without H3 directives shared the main server configuration; per-host H3AltSvc and H3AltSvcMaxAge were silently ignored. Set ALWAYS_MERGE.
httpd prepends virtual hosts to the server list, so the first host with an HTTP/3 context in that list is the last one defined. The listener took that host's settings and certificate, and a client whose SNI matched no host got that certificate, where mod_ssl serves the first virtual host defined for the address. Take the last match in both h3_post_config and find_h3_server instead.
This was referenced Nov 5, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
mod_http3 now takes its certificate from mod_ssl instead of its own directives, and picks it per virtual host by SNI.
1. Inherit the HTTP/3 certificate from mod_ssl, select it by SNI
h3inProtocolsserves HTTP/3 with the certificate mod_ssl already resolved for it, through theap_ssl_add_cert_fileshook.SSLCertificateFileand mod_md certificates work alike, the same way mod_http2 relies on mod_ssl.0600 root) fails withPermission deniedand HTTP/3 never starts.ServerName,ServerAliasand the wildcard aliases, matched withap_strcasecmp_matchas httpd matches its virtual hosts. Acert_cbon the listener context applies the matched certificate, key and chain to the connection, becauseSSL_set_SSL_CTXdoes not switch the certificate of an OpenSSL QUIC connection.AP_MODULE_FLAG_NONE, so a host without H3 directives shared the main server's configuration, and per-hostH3AltSvc/H3AltSvcMaxAgewere ignored. It now setsAP_MODULE_FLAG_ALWAYS_MERGE.Breaking:
H3CertificatePathandH3CertificateKeyPathare removed. Configurations that use them must drop them; the certificate now comes from the host's mod_ssl directives.2. Serve HTTP/3 from the first virtual host defined, as mod_ssl does
httpd prepends virtual hosts to the server list, so "the first host with HTTP/3" in that list was the last one defined. The listener took that host's settings, and a client whose SNI matched no host got that host's certificate, where mod_ssl serves the first virtual host defined for the address. Both
h3_post_configandfind_h3_servernow take the last match.Tested on EL9 (OpenSSL 4.0 with QUIC, nghttp3 1.19), httpd trunk built with
--enable-http3=shared, no new warnings. Two name-based virtual hosts on one port, keys0600 root, no H3 certificate directives:a.testCN=a.testb.testCN=b.testx.b.test(ServerAlias *.b.test)CN=b.testother.test(no match)CN=a.test, the first vhostAll four returned 200 over HTTP/3, and so did a request after a graceful restart.