Nginx | stream 四层反向代理:SSL、PREREAD 阶段模块指令浅析与实践

📅 发布时间:2026/7/9 11:25:07 👁️ 浏览次数:
Nginx | stream 四层反向代理:SSL、PREREAD 阶段模块指令浅析与实践
[ 知识是人生的灯塔只有不断学习才能照亮前行的道路 ] 大家好我是 WeiyiGeek一名深耕安全运维开发SecOpsDev领域的技术从业者致力于探索DevOps与安全的融合DevSecOps自动化运维工具开发与实践企业网络安全防护欢迎各位道友一起学习交流、一起进步 若此文对你有帮助一定记得点个关注⭐与小红星❤️或加入到作者知识星球『 全栈工程师修炼指南』转发收藏学习不迷路 。SSL 阶段描述前文《Nginx | stream 四层反向代理PREACCESS、ACCESS 阶段并发与访问限制模块浅析与实践》作者讲解了四层反向代理并发数限制以及与访问限制 由于互联网环境对安全性要求越来越高要求中间件或应用在处理TCP协议时支持携带 TLS/SSL 的安全通信通讯作为负载均衡的 Nginx 当然也是支持的在四层反向代理中能够处理来自下游客户端带有 TLS/SSL 加密的连接并透传裸TCP至上游服务器。温馨提示若文章代码块中存在乱码或不能复制请联系作者也可通过文末的阅读原文链接加入知识星球中阅读原文链接https://articles.zsxq.com/id_t5z28zcqv7us.html使用TLS/SSL的三种应用场景如下所示其中安全与非安全通信标识绿色线条表示使用TLS/SSL的安全网络通信如HTTPS蓝色线条表示未加密的裸TCP协议。• 场景1透传SSL流Nginx 不解析SSL直接将客户端发来的带有SSL协议的TCP流转发给上游服务器。• 场景2剥离SSL层重点学习Nginx 解析客户端发来的TLS协议将其转换为裸TCP协议后再发送至上游服务。• 场景3后端加密客户端与NGX之间无SSL协议但NGX向上游服务发送请求时启用SSL/TLS。weiyigeek.top-四层代理使用 TLS/SSL 的三种应用场景图◆ ssl 模块描述ngx_stream_ssl_module 模块使stream反向代理支持对下游客户端的TLS/SSL协议处理默认不编译进NGX可通过--with-stream_ssl_module参数显式加入该模块。指令参数实际上 steam 中的 ssl 指令参数与 HTTP 模块中的 ssl 指令几乎完全相同大家可参考ngx_stream_ssl_module模块文档了解此处仅列出部分常用指令参数。stream { map $ssl_alpn_protocol$proxy { h2 127.0.0.1:8001; http/1.1 127.0.0.1:8002; } # 全局配置例如全局私钥密码文件路径。 ssl_password_file /etc/keys/global.pass; server { listen 12346 ssl; proxy_pass $proxy; # ALPNApplication-Layer Protocol Negotiation协议例如h2 和 http/1.1 ssl_alpn h2 http/1.1; # 在 OpenSSL 1.0.2 及更高版本中支持不同的证书和密钥对例如RSA and ECDSA ssl_certificate example.com.rsa.crt; ssl_certificate_key example.com.rsa.key; ssl_certificate example.com.ecdsa.crt; ssl_certificate_key example.com.ecdsa.key; # 当且仅当密钥文件被加密时需要此参数。 ssl_password_file global.pass; # 支持的协议版本列表例如TLSv1.2 和 TLSv1.3 ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # 支持的加密套件列表 ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE:ECDH:AES:HIGH:EECDHCHACHA20:EECDHCHACHA20-draft:EECDHAES128:RSAAES128:EECDHAES256:RSAAES256:EECDH3DES:RSA3DES:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:!NULL:!aNULL:!eNULL:!EXPORT:!PSK:!ADH:!DH:!DES:!MD5:!RC4; # 指定SSL握手超时时间默认60秒。由于 http 模块中不关注握手超时此处仅在 stream 模块中才有。 ssl_handshake_timeout 10s; } }weiyigeek.top-stream ssl 常用指令图•ssl_alpn支持的ALPN协议列表。Syntax: ssl_alpn protocol ...; Default: — Context: stream, server # 例如表示支持 HTTP/2 和 HTTP/1.1 协议。 ssl_alpn h2 http/1.1;•ssl_certificate: 指定服务器证书文件路径用于SSL握手时验证服务端身份。Syntax: ssl_certificate file; Default: — Context: stream, server•ssl_certificate_key: 指定服务器私钥文件路径用于SSL握手时验证服务端身份。Syntax: ssl_certificate_key file; Default:— Context: stream, server•ssl_password_file: 指定包含私钥密码的文件路径用于解密服务器私钥。例如当使用加密的密钥文件时需要此参数。Syntax: ssl_password_file file; Default: — Context: stream, server•ssl_ciphers: 指定支持的加密套件列表用于协商安全连接。Syntax: ssl_ciphers ciphers; Default: ssl_ciphers HIGH:!aNULL:!MD5; Context: stream, server # 例如表示使用高强度加密算法且不包含匿名和MD5算法。 HIGH:!aNULL:!MD5•ssl_protocols: 指定支持的SSL协议版本列表为了安全建议使用TLSv1.2 和 TLSv1.3 协议版本。Syntax: ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3]; Default: ssl_protocols TLSv1.2 TLSv1.3; Context: stream, server # 特别注意 TLSv1.1 and TLSv1.2 : 仅在使用OpenSSL 1.0.1或更高版本时有效。 TLSv1.3 : 仅在使用OpenSSL 1.1.1或更高版本时有效从 1.23.4 版本开始为缺省值。•ssl_handshake_timeout: 设置SSL握手超时时间默认60秒由于 http 模块中不关注握手超时此处仅在 stream 模块中才有。Syntax: ssl_handshake_timeout time; Default: ssl_handshake_timeout 60s; Context: stream, server•ssl_certificate_cache用于缓存服务器证书减少每次SSL握手时的磁盘I/O开销。默认关闭可通过设置参数启用。Syntax: ssl_certificate_cache off; ssl_certificate_cache maxN [inactivetime] [validtime]; Default: ssl_certificate_cache off; Context: stream, server # 参数说明: max设置缓存中可存储的客户端证书数量。 inactive: 设置缓存项在不被访问后多久自动失效例如 60s。 valid设置缓存项的有效期例如 10m 表示有效期为 10 分钟。 # 例如表示最多存储 1000 个证书如果超过60秒未被访问则自动失效有效期为 10 分钟。 ssl_certificate_cache max1000 inactive60s valid10m;•ssl_session_cache: 设置SSL会话缓存用于存储和复用之前的TLS握手信息。默认关闭可通过设置参数启用。Syntax: ssl_session_cache off | none | [builtin[:size]] [shared:name:size]; Default: ssl_session_cache none; Context: stream, server # 参数说明 off 禁用会话缓存。 none 测试模式不实际缓存会话。 builtin[:size] 使用内置缓存可选参数 size 指定最大内存大小若如果没有指定大小则等于20480个会话另外使用内置缓存可能会导致内存碎片所以通常不建议使用。 shared:name:size 使用共享区域缓存其中 name 是缓存的名称size 指定最大内存大小1兆字节可以存储大约4000个会话。•ssl_session_tickets: 启用或禁用TLS会话票证Session Tickets功能默认开启。Syntax: ssl_session_tickets on | off; Default: ssl_session_tickets on; Context: stream, server•ssl_session_ticket_key: 设置会话票据密钥用于启用TLS会话票证Session Tickets功能。默认关闭可通过设置参数启用如果同一密钥必须在多个服务器之间共享则该指令是必需的。Syntax: ssl_session_ticket_key file; Default: — Context: stream, server # 根据文件大小可以使用AES256用于80字节密钥1.11.8或AES128用于48字节密钥进行加密。 openssl rand 80 ticket.key ssl_session_ticket_key current.key;•ssl_session_timeout: 设置SSL会话超时时间默认5分钟。Syntax: ssl_session_timeout time; Default: ssl_session_timeout 5m; Context: stream, server•ssl_verify_client: 启用或禁用客户端证书验证默认关闭。Syntax: ssl_verify_client on | off | optional | optional_no_ca; Default: ssl_verify_client off; Context: stream, server•ssl_verify_depth: 设置客户端证书链的验证深度默认1, 从信任的根 CA 开始计数不包含服务器证书本身,例如设置为2则验证客户端证书链的前两个证书但是值越大验证可能越耗时Syntax: ssl_verify_depth number; Default: ssl_verify_depth 1; Context: stream, server•ssl_trusted_certificate: 指定一个或多个可信CA证书文件用于验证客户端证书或OCSP响应。默认不启用此功能。Syntax: ssl_trusted_certificate file; Default:— Context: stream, server另外Stream SSL 模块中还提供了一些特殊的变量大致分为如下几类例如安全套件信息•$ssl_cipher获取本次通信使用的确切安全套件•$ssl_client_ciphers列出客户端如浏览器支持的所有安全套件•$ssl_protocol显示当前使用的TLS协议版本如 TLSv1.2•$ssl_alpn_protocol显示客户端支持的ALPN协议例如 h2 表示HTTP/2。•$ssl_curves显示协商使用的椭圆曲线如 X25519, secp384r1•$ssl_ech_status: 显示客户端支持的加密扩展协议状态例如 “FAILED”, “BACKEND”, “GREASE”, “SUCCESS”, or “NOT_TRIED” (1.29.4);证书内容信息•$ssl_client_raw_cert返回原始客户端证书内容。•$ssl_client_escaped_cert返回经URL编码后的客户端证书。•$ssl_client_cert返回客户端证书的PEM格式内容。•$ssl_client_fingerprint返回客户端证书的SHA-1指纹。证书结构化信息特别注意 stream 模块不支持旧版legacy以反斜杠分隔的DN格式仅支持标准格式。•$ssl_server_name通过SNI扩展获取客户端请求的域名。•$ssl_client_i_dn获取客户端证书的Issuer DN信息如国家、组织等。•$ssl_client_s_dn: 获取客户端证书的Subject DN信息每行前加Tab符便于打印输出。证书有效期信息•$ssl_client_v_end返回客户端证书的过期时间格式示例May 17 09:35:15 2033 GMT。•$ssl_client_v_remain返回客户端证书剩余有效天数单位天例如值为 3649 表示约十年。•$ssl_client_v_start返回客户端证书由CA颁发的起始日期。连接有效性相关变量•$ssl_client_serial_no返回客户端证书的序列号十六进制格式。•$ssl_client_verify返回客户端证书验证结果失败时显示具体原因未验证返回空字符串成功返回 “SUCCESS”。•$ssl_session_id获取已建立连接的SSL会话ID在OpenResty中常用。•$ssl_session_reused指示会话是否被复用是则返回 “r”否则为 “.”。实践示例目的展示 Nginx 作为四层反向代理时将客户端带SSL的TCP流剥离SSL层后以裸TCP形式转发至上游服务器。特别注意虽使用HTTP协议进行演示但 Nginx 的stream模块仅处理TCP与SSL层不关心应用层协议。步骤 01.重新构建编译 Nginx 以启用 stream ssl 模块。# 构建 ./configure --prefix/usr/local/nginx --usernginx --groupnginx --sbin-path/usr/sbin/nginx --conf-path/usr/local/nginx/conf/nginx.conf --pid-path/usr/local/nginx/nginx.pid --error-log-path/var/log/nginx/logs/error.log --http-log-path/var/log/nginx/logs/access.log --lock-path/var/run/nginx.lock --modules-path/usr/local/nginx/modules --with-http_stub_status_module --with-http_realip_module --with-http_v2_module --with-http_ssl_module --with-http_slice_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-cc-opt-O2 --with-compat # 编译安装 make -j $(nproc) make install步骤 02.准备两台 Nginx 服务器一台作为 stream 四层转发服务192.168.10.2另一台作为上游服务器192.168.10.3提供 http 服务。stream 四层转发服务器配置示例tee /usr/local/nginx/conf/nginx.conf EOF worker_processes auto; events { worker_connections 1024; } # stream 模块配置块 stream { # 定义一个日志模式格式加入了 $ssl_session_reused变量以便记录会话是否被复用。 log_format basic $remote_addr:$remote_port $realip_remote_addr:$realip_remote_port [$time_local] $protocol $status $bytes_sent $bytes_received $session_time $ssl_protocol $ssl_session_reused; # 开启日志文件描述符缓存减少打开和关闭文件的开销 open_log_file_cache max1000 inactive60s min_uses2 valid1m; # 开启访问日志记录注意这里为了测试未启用缓存生产环境中推荐使用缓存。 error_log /var/log/nginx/stream_error.log debug; access_log /var/log/nginx/stream_access.log basic; # 定义一个四层TCP服务 server { # 监听 8443 端口启用 ssl listen 8443 ssl; # 设置可信客户端IP地址即真实地址将排除下述IP或IP段的地址。 set_real_ip_from 127.0.0.1; set_real_ip_from 10.20.172.0/24; # SSL 证书文件server.weiyigeek.top ssl_certificate /usr/local/nginx/certs/server.crt; ssl_certificate_key /usr/local/nginx/certs/server.key; # 支持的 SSL/TLS 协议版本 ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; # 支持的 SSL/TLS 加密套件 ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-DHCHACHA20:EECDHCHACHA20-draft:EECDHAES128:RSAAES128:EECDHAES256:RSAAES256:EECDH3DES; # SSL 会话缓存 ssl_session_cache shared:SSL:10m; # SSL 会话超时时间 ssl_session_timeout 10m; # 优先使用服务器端支持的加密套件 ssl_prefer_server_ciphers on; # SSL 会话票据复用 ssl_session_tickets on; # 转发至上游服务器此处仅为示例实际应用中应替换为实际服务地址和端口。 proxy_pass 10.20.172.213:8011; } } EOF上游服务器192.168.10.3提供 http 服务配置示例$ echohttps://www.weiyigeek.top /usr/local/nginx/html/index.html $ vim /usr/local/nginx/conf.d/upstream.conf # 模拟上游服务器其监听端口为8011 server { listen 8011; server_name _; charset utf-8; default_type text/plain; # 静态文件服务配置 location / { root /usr/local/nginx/html; index index.html; } # 返回当前时间戳作为响应内容 location ^~ /api { return 200 $time_iso8601 $request_id $server_addr:$server_port $request_uri\n; } }步骤 03.启动 Nginx 服务并使用浏览器访问测试。$ nginx -t nginx -s reload nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successfu # 硬解析设置或添加到内部DNS解析记录以便浏览器能正确访问。 $ cat /etc/hosts 192.168.10.2 server.weiyigeek.top在上游服务中使用 tcpdump 抓取 ens18 网卡的 8011 通讯包命令tcpdump -i ens18 port 8011 -A -s 0然后在浏览器访问https://server.weiyigeek.top:8443/index.html以及https://server.weiyigeek.top:8443/api并查看 tcpdump 抓包结果。weiyigeek.top-抓包验证 steam 四层转发图步骤 04.另外从我们记录的 stream_access.log 日志中可查看到客户端与服务端之间的SSL会话是否复用等信息。$ tail -f /var/log/nginx/stream_access.log 10.20.172.103:61065 10.20.172.103:61065 [27/Jan/2026:11:52:41 0800] TCP 200 0 0 60.004 - TLSv1.3 . # 此处显示 . 表示会话未被复用即客户端与服务端之前的连接是全新的。 10.20.172.103:61064 10.20.172.103:61064 [27/Jan/2026:11:53:18 0800] TCP 200 1273 2221 96.621 - TLSv1.3 . 10.20.172.103:61501 10.20.172.103:61501 [27/Jan/2026:11:59:20 0800] TCP 200 0 0 60.001 - TLSv1.3 r # 此处显示 r 表示会话被复用即客户端与服务端之前的连接是复用的。 10.20.172.103:61499 10.20.172.103:61499 [27/Jan/2026:11:59:25 0800] TCP 200 253 783 65.002 - TLSv1.3 r # 此处显示 r 表示会话被复用即客户端与服务端之前的连接是复用的。 $ tail -f /var/log/nginx/stream_error.log 2026/01/27 11:51:41 [info] 3093559#0: *35 proxy 10.20.172.214:41324 connected to 10.20.172.213:8011 2026/01/27 11:51:41 [info] 3093560#0: *36 proxy 10.20.172.214:41332 connected to 10.20.172.213:8011 2026/01/27 11:52:41 [info] 3093560#0: *36 upstream disconnected, bytes from/to client:0/0, bytes from/to upstream:0/0 2026/01/27 11:53:18 [info] 3093559#0: *35 upstream disconnected, bytes from/to client:2221/1273, bytes from/to upstream:1273/2221weiyigeek.top-请求结果与请求日志查看图至此本小节实践了如何解析、验证客户端 SSL 证书并将带有 SSL 的TCP 流剥离 SSL 层并以裸 TCP 方式转发至上游服务器此模式在实际场景中非常常见尤其适用于非HTTP类协议的四层代理场景应用范围广泛。PREREAD 阶段描述上文讲解了如何在 SSL 阶段剥离 SSL 层并以裸 TCP 方式转发至上游服务器这虽然是最常用的场景但是在某些场景下例如上游和下游均使用 SSL 协议时Nginx 需在不剥离 SSL 层的情况下解析客户端Hello消息中的TLS版本、SNI域名和ALPN协议等信息。若直接转发带 SSL 的 TCP 流则无法获取握手信息若剥离 SSL 则改变了传输协议无法满足透明转发需求在这样的背景问题下Nginx 提供了stream SSL preread模块来解决。weiyigeek.top-SSL preread 模块使用场景图◆ ssl_preread 模块描述stream_ssl_preread_module 模块默认未编译进 Nginx需通过--with-stream_ssl_preread_module显式启用在不剥离SSL的情况下解析的下游发来的SSL握手消息Client Hello消息中的TLS版本、SNI域名和ALPN协议等信息并利用这些变量实现基于四层反向代理的上游服务动态选择提升负载均衡灵活性例如# 根据服务器名称选择上游 map $ssl_preread_server_name$name { backend.example.com backend1; default backend2; } # 根据协议选择上游 map $ssl_preread_alpn_protocols$proxy { ~\bh2\b 127.0.0.1:8001; ~\bhttp/1.1\b 127.0.0.1:8002; ~\bxmpp-client\b 127.0.0.1:8003; } # 根据SSL协议版本选择上游 map $ssl_preread_protocol$upstream { ssh.example.com:22; TLSv1.2 new.example.com:443; default tls.example.com:443; } # 例如 ssh 与 https 在同一端口根据协议分流 server { listen 192.168.0.1:443; proxy_pass $upstream; ssl_preread on; }特别注意使用stream_ssl_preread模块时向上游发送的是完整的SSL/TLS加密流不可同时启用stream_ssl模块若已执行SSL解密进入明文TCP流则ssl_preread阶段无法再获取原始Client Hello信息并会导致冲突。指令参数•ssl_preread是否允许在预读阶段从ClientHello消息中提取信息。Syntax: ssl_preread on | off; Default: ssl_preread off; Context: stream, server•preread_buffer_size: 设置用于解析SSL握手数据的缓冲区大小默认为 16KB属于 stream_core_module 的一部分因此可以在 stream 或 server 级别设置。Syntax: preread_buffer_size size; Default: preread_buffer_size 16k; Context: stream, server•preread_timeout: 设置等待Client Hello完成的时间默认 30 秒属于 stream_core_module 的一部分因此可以在 stream 或 server 级别设置。Syntax: preread_timeout timeout; Default: preread_timeout 30s; Context: stream, server另外该模块提供了以下变量以供后续模块选择使用•$ssl_preread_protocol: 客户端支持的最高TLS版本如 TLSv1.2, TLSv1.3可用于根据安全等级选择不同上游服务器。•$ssl_preread_server_name: 从 SNIServer Name Indication扩展中提取的服务器域名用于基于域名的路由决策。•$ssl_preread_alpn_protocols: 客户端建议使用的应用层协议如 h2 表示 HTTP/2http/1.1 等可用于协议优化匹配。示例演示目的使用stream_ssl_preread模块实现根据$ssl_preread_server_name获取客户端请求的域名并反向代理此域名对应的上游服务器。步骤 01.启用stream_ssl_preread模块加入到 Nginx 编译配置中并重新编译安装。# 构建 ./configure --prefix/usr/local/nginx --usernginx --groupnginx --sbin-path/usr/sbin/nginx --conf-path/usr/local/nginx/conf/nginx.conf --pid-path/usr/local/nginx/nginx.pid --error-log-path/var/log/nginx/logs/error.log --http-log-path/var/log/nginx/logs/access.log --lock-path/var/run/nginx.lock --modules-path/usr/local/nginx/modules --with-http_stub_status_module --with-http_realip_module --with-http_v2_module --with-http_ssl_module --with-http_slice_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt-O2 --with-compat # 编译安装 make -j $(nproc) make install步骤 02.配置 Nginx 以使用stream_ssl_preread模块提取的Client Hello 消息中关键变量实现基于域名的反向代理。tee /usr/local/nginx/conf/nginx.conf EOF worker_processes auto; events { worker_connections 1024; } # stream 模块配置块 stream { # 定义一个日志模式格式。 log_format ssl_basic $remote_addr:$remote_port $realip_remote_addr:$realip_remote_port [$time_local] $protocol $status $bytes_sent $bytes_received $session_time ssl_preread[$ssl_preread_server_name, $ssl_preread_protocol, $ssl_preread_alpn_protocols] $ssl_client_i_dn $ssl_client_s_dn $ssl_client_v_end $ssl_curves; # 开启日志文件描述符缓存减少打开和关闭文件的开销 # open_log_file_cache max1000 inactive60s min_uses2 valid1m; # 开启访问日志记录注意这里为了测试未启用缓存生产环境中推荐使用缓存。 error_log /var/log/nginx/stream_error.log debug; access_log /var/log/nginx/stream_access.log ssl_basic; # 反向代理到上游服务器此处使用 map 根据域名选择不同的后端服务。 map $ssl_preread_server_name$proxy_server { test.weiyigeek.top www.weiyigeek.top:443; # 作者首页 blog.weiyigeek.top blog.weiyigeek.top:443; # 作者博客 default 10.20.172.213:8443; # 其他情况默认指向默认服务 } # 定义一个四层TCP服务 server { # 监听 8443 端口 listen 8443; # 设置可信客户端IP地址即真实地址将排除下述IP或IP段的地址。 set_real_ip_from 127.0.0.1; set_real_ip_from 10.20.172.0/24; # 解析服务域名地址 resolver 61.128.128.68 valid30s; resolver_timeout 60s; # 开启SSL预读阶段以便提取客户端支持的TLS版本、SNI域名和ALPN协议等信息。 ssl_preread on; # 根据客户端请求的域名动态选择上游服务器 proxy_pass $proxy_server; } } EOF步骤 03.验证配置并重新启动 Nginx 服务将测试域名使用硬解析方式指向 nginx 服务器IP地址10.20.172.214根据实际情况更改 并使用浏览器分别访问test.weiyigeek.top:8443、blog.weiyigeek.top:8443以及10.20.172.214:8443测试配置是否生效。nginx -t nginx -s reload验证1访问https://test.weiyigeek.top:8443正常情况下应能正常访问作者的首页可在开发者工具【网络】选项卡查看到未发生HTTP重定向证明全程处于四层转发模式。weiyigeek.top-验证1访问作者首页图验证2访问https://blog.weiyigeek.top:8443正常情况下应能正常访问作者的博客。weiyigeek.top-验证2访问博客图验证3访问https://10.20.172.214:8443此时 $ssl_preread_server_name 变量将为空因此正常情况下应能正常访问10.20.172.213:8443这个内部服务。weiyigeek.top-验证3访问内部服务图步骤 04.查看 Nginx 日志文件验证是否正确记录了$ssl_preread_server_name以及协议版本ALPN协议等信息。tail -f /var/log/nginx/stream_access.log 10.20.172.103:52166 10.20.172.103:52166 [27/Jan/2026:16:07:26 0800] TCP 200 1423439 6485 223.494 ssl_preread[blog.weiyigeek.top, TLSv1.3, h2,http/1.1] - - - - # 验证2 10.20.172.103:52302 10.20.172.103:52302 [27/Jan/2026:16:07:53 0800] TCP 200 3405 1900 0.016 ssl_preread[, TLSv1.3, h2,http/1.1] - - - - # 验证3 10.20.172.103:52286 10.20.172.103:52286 [27/Jan/2026:16:08:37 0800] TCP 200 221095 3515 67.570 ssl_preread[test.weiyigeek.top, TLSv1.3, h2,http/1.1] - - - - # 验证1weiyigeek.top-利用日志文件验证ssl_preread模块图至此作者带领大家一起利用 stream_ssl_preread 模块实现了在保持SSL加密流完整性的前提下提取 Client Hello 中$ssl_preread_protocol、$ssl_preread_server_name和$ssl_preread_alpn_protocols三个关键变量并利用 map 模块实现了基于$ssl_preread_server_name变量动态选择上游服务。在实际的生产场景中非常场景尤其适用于非HTTP类协议的四层代理场景基于TLS版本、域名或应用层协议的精细化上游服务选择增强了四层反向代理的灵活性与智能化水平。END加入作者【全栈工程师修炼指南】知识星球『 全栈工程师修炼指南』星球主要涉及全栈工程师Full Stack Development实践文章持续更新包括但不限于企业SecDevOps和网络安全等保合规、安全渗透测试、编程开发、云原生Cloud Native、物联网工业控制IOT、人工智能Ai从业书籍笔记人生职场认识等方面资料或文章。Q: 加入作者【全栈工程师修炼指南】星球后有啥好处✅ 将获得作者最新工作学习实践文章以及网盘资源。✅ 将获得作者珍藏多年的全栈学习笔记(需连续两年及以上老星球友也可单次购买)✅ 将获得作者专门答疑学习交流群解决在工作学习中的问题。✅ 将获得作者远程支持在作者能力范围内且合规。获取作者工作学习全栈笔记作者整理了10年的工作学习笔记涉及网络、安全、运维、开发需要学习实践笔记的看友可添加作者微信或者回复【工作学习实践笔记】当前价格299除了获得从业笔记的同时还可进行问题答疑以及每月远程技术支持希望大家多多支持收获定大于付出知识推荐往期文章【最新】全栈工程师修炼指南 2025 公众号年度总结【最新】工具推荐 | 专为公众号 Markdown 排版利器【最新】反向代理 | 白嫖 Cloudflare 部署一个国外资源加速下载站【最新】告别杂乱审计日志多厂商网络设备日志统一采集与可视化分析最佳实践【相关】Nginx | stream 四层反向代理PREACCESS、ACCESS 阶段并发与访问限制模块浅析与实践【相关】Nginx | stream 四层反向代理LOG、POST_ACCEPT阶段模块指令浅析与实践【相关】Nginx | 核心知识150讲百万并发下性能优化之四层反向代理七个阶段浅析及核心模块实践若文章对你有帮助请将它转发给更多的看友若有疑问的小伙伴可在评论区留言你想法哟