问题
Nginx 自从 1.25.0 版本以来对 QUIC 的支持已被合并入 mainline,对于想体验的用户而言可以直接使用官方发布的 nginx
docker 镜像,非常方便。
但是我的服务器上的 nginx 使用了 SNI 分流,源于 Shadow TLS 和 Xray Reality 等新一代基于 TLS 的代理协议的需求。这些代理协议并不能由 nginx 代为处理 TLS 层(和之前可以使用 gPRC/WebSocket 等作为数据传输方式的协议不同),但为了实现最好的伪装效果,使用 443/tcp
端口是有必要的(伪装的白名单目标网站一般情况下也只会在 443/tcp
端口开放 HTTPS 服务)。因此 443/tcp
端口的复用是必要的。
如果要让 SNI 分流和 QUIC 共存,在原来的 SNI 分流配置上只需要给每个 server 加上 listen 443 quic
即可。示例配置如下。
配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| http {
server { server_name example.com;
listen 443 quic reuseport; listen [::]:443 quic reuseport;
listen unix:/dev/shm/nginx-example.sock ssl http2 proxy_protocol; set_real_ip_from unix:; real_ip_header proxy_protocol;
add_header Alt-Svc 'h3=":443"; ma=86400';
}
server { server_name foo.example.com;
listen 443 quic; listen [::]:443 quic;
listen unix:/dev/shm/nginx-example-foo.sock ssl http2 proxy_protocol; set_real_ip_from unix:; real_ip_header proxy_protocol;
add_header Alt-Svc 'h3=":443"; ma=86400';
} }
stream {
map $ssl_preread_server_name $name { example.com unix:/dev/shm/nginx-example.sock; foo.example.com unix:/dev/shm/nginx-example-foo.sock; learn.microsoft.com 127.0.0.1:8443; default unix:/dev/shm/nginx-default.sock; }
server { listen 443 reuseport so_keepalive=on; listen [::]:443 reuseport so_keepalive=on; proxy_pass $name; ssl_preread on; proxy_protocol on; }
}
|
测试
目前 curl
/wget
mainline 还没有支持 QUIC,可以使用 ymuski/curl-http3
这个 docker 镜像:
1 2 3 4 5 6 7 8
| $ docker run -it --rm ymuski/curl-http3 curl https://static.monsoon-cs.moe/public/ --http3 -IL
HTTP/3 200 server: nginx/1.25.2 date: Tue, 26 Sep 2023 14:52:29 GMT content-type: text/html; charset=utf-8 strict-transport-security: max-age=63072000 alt-svc: h3=":443"; ma=86400
|
参考