前言
本文为小白向笔记(教程),大神不喜勿喷,如有错误欢迎指正
如你所见,运行这个博客的是一台4H4G80M的线路优秀的美国VPS
搭建的服务
OpenList(自建网盘,端口5244)
1Panel(面板,端口28202)
AdguardHome(DNS中转,端口443、53)
Typecho(博客,端口445)
1Panel(面板,端口28202)
AdguardHome(DNS中转,端口443、53)
Typecho(博客,端口445)
初次尝试
参考Xiaomage's Blog,我们得到了如下的配置文件
这让Nginx的stream模块再充当一次和TCP应用交流的媒人,再TCP应用前面用stream模块做一层转发,将Proxy
protocol这层外衣给去掉,传递给TCP应用的还是最原始的TCP流。
配置文件
stream {
# SNI识别,将一个个域名映射成一个配置名
map $ssl_preread_server_name $stream_map {
sec,141664.xyz bweb;
panel.141664.xyz bpan;
file.141664.xyz bfile;
dns.141664.xyz bdns;
}
upstream bdns {
server 127.0.0.1:5533;
}
upstream bpan {
server 127.0.0.1:28203;
}
upstream bweb {
server 127.0.0.1:446;
}
upstream bfile {
server 127.0.0.1:5245;
}
upstream dns {
server 127.0.0.1:553;
}
upstream pan {
server 127.0.0.1:28202;
}
upstream web {
server 127.0.0.1:445;
}
upstream file {
server 127.0.0.1:5244;
}
server {
listen 443 reuseport;
proxy_pass $stream_map;
ssl_preread on;
}
server {
listen 127.0.0.1:28203 proxy_protocol;# 开启Proxy protocol
proxy_pass pan; # 以真实的服务作为上游,这一层是与服务交互的“媒人”
}
server {
listen 127.0.0.1:5245 proxy_protocol;
proxy_pass file;
}
server {
listen 127.0.0.1:5533 proxy_protocol;
proxy_pass dns;
}
server {
listen 127.0.0.1:446 proxy_protocol;
proxy_pass web;
}
}
server {
listen 8443 ssl http2;# 监听本地443端口,要和上面的stream模块配置中的upstream配置对的上
port_in_redirect off;
......
if ($ssl_protocol = "") {
return 301 https://$host$request_uri;
}
index index.html index.htm index.php;
try_files $uri $uri/ /index.php?$args;
......
}
发现此配置文件不完整,且需要自编译nginx
流量如图

奇思妙想
原文使用Proxy protocol使后端获取访客真实IP地址,用stream做SNI分流。但换个思路,为什么我们不能用server_name呢?于是:
修改后配置
user root;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /run/nginx.pid;
# 默认情况下,HTTP/3 (QUIC) 使用 UDP 端口 443。
# 确保你的防火墙已打开 UDP 443 端口!
events {
worker_connections 1024;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_names_hash_bucket_size 128;
# Logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# SSL session cache
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1h;
# 公共的SSL/TLSv1.3配置,这是QUIC/HTTP3的基础
ssl_protocols TLSv1.2 TLSv1.3;
# 对于HTTP/3,推荐使用支持TLSv1.3的ciphers
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256';
ssl_prefer_server_ciphers on;
# 为HTTP/3启用0-RTT (需要在客户端和服务端都支持,否则0-RTT数据会被丢弃)
ssl_early_data on;
# --- Server Block for file.141664.xyz ---
server {
# TCP 监听 (HTTP/1.1, HTTP/2)
listen 443 ssl http2;
server_name file.141664.xyz;
# SSL Certificate and Key - Replace with your actual paths for file.141664.xyz
ssl_certificate /etc/nginx/ssl/file.141664.xyz.crt;
ssl_certificate_key /etc/nginx/ssl/file.141664.xyz.key;
# 通知客户端支持HTTP/3,客户端会尝试通过UDP/443连接
add_header Alt-Svc 'h3=":443"; ma=86400';
# HSTS (HTTP Strict Transport Security) - 强制客户端使用HTTPS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Logging
access_log /var/log/nginx/file.141664.xyz_access.log;
error_log /var/log/nginx/file.141664.xyz_error.log;
location / {
# Proxy settings for HTTPS backend on 127.0.0.1:5244
proxy_pass https://127.0.0.1:5244/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_ssl_server_name on; # Enable SNI when proxying to the backend
proxy_redirect off; # Avoid potential issues with backend redirects
proxy_set_header Accept-Encoding ""; # 如果后端已经进行gzip压缩,则禁用Nginx的gzip,避免二次压缩
# 缓冲区和超时设置
proxy_buffering off;
proxy_read_timeout 90;
proxy_send_timeout 90;
proxy_connect_timeout 90;
# 客户端SSL证书验证 (可选但强烈建议,这部分与HTTP/3本身无直接关系,但增强安全性)
# ssl_verify_client optional; # 或 "on" 如果严格要求
# ssl_client_certificate /etc/nginx/ssl/ca.crt; # 信任的CA证书束
# ssl_verify_depth 2; # 证书链深度
}
}
# --- Server Block for panel.141664.xyz ---
server {
# TCP 监听 (HTTP/1.1, HTTP/2)
listen 443 ssl http2;
server_name panel.141664.xyz;
# SSL Certificate and Key - Replace with your actual paths for panel.141664.xyz
ssl_certificate /etc/nginx/ssl/panel.141664.xyz.crt;
ssl_certificate_key /etc/nginx/ssl/panel.141664.xyz.key;
# 通知客户端支持HTTP/3
add_header Alt-Svc 'h3=":443"; ma=86400';
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Logging
access_log /var/log/nginx/panel.141664.xyz_access.log;
error_log /var/log/nginx/panel.141664.xyz_error.log;
location / {
# Proxy settings for HTTPS backend on 127.0.0.1:28202
proxy_pass https://127.0.0.1:28202/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_ssl_server_name on; # Enable SNI when proxying to the backend
proxy_redirect off; # Avoid potential issues with backend redirects
proxy_set_header Accept-Encoding ""; # 如果后端已经进行gzip压缩,则禁用Nginx的gzip,避免二次压缩
# 缓冲区和超时设置
proxy_buffering off;
proxy_read_timeout 90;
proxy_send_timeout 90;
proxy_connect_timeout 90;
# 客户端SSL证书验证 (可选)
# ssl_verify_client optional;
# ssl_client_certificate /etc/nginx/ssl/ca.crt;
# ssl_verify_depth 2;
}
}
# 可以包含其他虚拟主机配置
include /etc/nginx/conf.d/*.conf;
}
需要自行修改SSL证书位置
注意使用的证书类型(比如EC384)必须已在套件中启用(大多数情况不用考虑)
证书路径和密钥路径都写绝对路径,不能写反
方案对比
这个配置文件的好处是:不用自编译nginx
原文中用stream分流需要编译nginx使nginx包含stream模块;
但此配置使用的所有功能都被包含在了apt、yum之类的包管理器中的nginx里!
使得只需要:
- 用包管理器安装nginx:
apt instal nginx -y - 粘贴配置文件
完结撒花
觉得有用的话,打赏一下吧!就算只有一分钱,作者也很满意了!(第二个字是业)