Apache2双虚拟主机配置异常:仅单站点启用HTTP2故障排查
Apache2 虚拟主机HTTP/2配置异常问题解析
核心问题原因
你遇到的--http2-prior-knowledge测试异常,本质是非TLS环境下(80端口)Apache处理HTTP/2请求的虚拟主机匹配逻辑导致的:
--http2参数:curl先发送HTTP/1.1请求并携带Upgrade: h2c头,Apache此时能通过Host头匹配到对应虚拟主机,再根据该VH的Protocols配置决定是否允许协议升级,所以结果符合预期。--http2-prior-knowledge参数:curl直接发送HTTP/2请求,没有HTTP/1.1握手阶段。Apache在接收这类请求时,会先使用第一个加载的虚拟主机的Protocols配置判断是否接受HTTP/2连接,完成连接后才会读取HTTP/2帧中的Host字段匹配对应VH。这就导致:- 如果第一个加载的是
http2.com(支持h2c),所有HTTP/2请求都会被接受,哪怕目标是nohttp2.com; - 如果第一个加载的是
nohttp2.com(仅支持http/1.1),所有HTTP/2请求都会被直接拒绝,哪怕目标是http2.com。
- 如果第一个加载的是
解决方案
方案1:调整默认虚拟主机配置(非TLS场景)
- 将
nohttp2.com设为默认虚拟主机:修改配置文件名为00-nohttp2.com.conf(确保它是第一个被加载的),配置保持不变:
<VirtualHost *:80> ServerAdmin webmaster@aris.com ServerName nohttp2.com DirectoryIndex index.html DocumentRoot /var/www/nohttp2.com Protocols http/1.1 ProtocolsHonorOrder On </VirtualHost>
- 保留
http2.com的配置,明确启用h2c:
<VirtualHost *:80> ServerAdmin webmaster@aris.com ServerName http2.com DirectoryIndex index.html DocumentRoot /var/www/http2.com Protocols h2c http/1.1 </VirtualHost>
这样配置后:
- 发送HTTP/2请求到
http2.com:Apache先通过默认VH接受连接,后续匹配到目标VH后,使用其支持的协议完成请求; - 发送HTTP/2请求到
nohttp2.com:Apache通过默认VH的配置拒绝HTTP/2连接,返回错误,符合预期。
方案2:切换到TLS端口(443)推荐
TLS环境下,Apache会通过**SNI(服务器名称指示)**在握手阶段就匹配到对应虚拟主机,同时结合ALPN协商HTTP/2协议,此时--http2-prior-knowledge能正常识别不同VH的Protocols配置。配置示例:
# nohttp2.com.conf(仅HTTP/1.1) <VirtualHost *:443> ServerAdmin webmaster@aris.com ServerName nohttp2.com DirectoryIndex index.html DocumentRoot /var/www/nohttp2.com Protocols http/1.1 SSLEngine On SSLCertificateFile /path/to/cert.pem SSLCertificateKeyFile /path/to/key.pem </VirtualHost> # http2.com.conf(支持HTTP/2) <VirtualHost *:443> ServerAdmin webmaster@aris.com ServerName http2.com DirectoryIndex index.html DocumentRoot /var/www/http2.com Protocols h2 http/1.1 SSLEngine On SSLCertificateFile /path/to/cert.pem SSLCertificateKeyFile /path/to/key.pem </VirtualHost>
内容的提问来源于stack exchange,提问作者jlanza
相关产品推荐
相关产品推荐

