前言

本文为小白向笔记(教程),大神不喜勿喷,如有错误欢迎指正
如你所见,运行这个博客的是一台4H4G80M的线路优秀的美国VPS

搭建的服务

OpenList(自建网盘,端口5244)
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
流量如图
借用一下Xiaomage's Blog的图片.png

奇思妙想

原文使用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
  • 粘贴配置文件

完结撒花

觉得有用的话,打赏一下吧!就算只有一分钱,作者也很满意了!(第二个字是业)

最后修改:2025 年 11 月 13 日
(T_T)没钱了,救济一下吧