You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx SSL预读无法从SSH连接提取服务器名的问题与解决

Nginx配置SSL预读实现SSH按服务器名路由失败的解决方法

问题场景

尝试通过Nginx的SSL预读功能,根据服务器名将入站SSH连接路由至不同上游节点,但连接被拒绝,且Nginx无法提取服务器名。已确认Nginx编译时包含--with-stream和--with-stream-ssl-preread-module模块,配置无语法错误:

stream {

    log_format  ssh  '|| SSL_PreRead $ssl_preread_server_name ||';
    access_log  /opt/homebrew/var/log/nginx/ssh_access.log  ssh;

    map $ssl_preread_server_name $ssh_upstream {
            app1.mydomain.com   app1-deviceIP:22;
            app2.mydomain.com   app2-deviceIP:22;
            app3.mydomain.com   app3-deviceIP:22;
            app4.mydomain.com   app4-deviceIP:22;
        app5.mydomain.com   app5-deviceIP:22;
        app6.mydomain.com   app6-deviceIP:22;
        app7.mydomain.com   app7-deviceIP:22;
        app8.mydomain.com   app8-deviceIP:22;
        app9.mydomain.com   app9-deviceIP:22;
    }

    server {
        listen 22000;  # 网络路由器将入站22端口流量转发至Nginx的22000端口
        proxy_pass $ssh_upstream;
        ssl_preread on;
    }

}

多次尝试连接后,ssh_access.log中$ssl_preread_server_name变量为空:

|| SSL_PreRead -  ||
|| SSL_PreRead -  ||
|| SSL_PreRead -  ||
|| SSL_PreRead -  ||
|| SSL_PreRead -  ||
|| SSL_PreRead -  ||

使用的连接命令:

ssh -i my_private_key_file username@app1.mydomain.com

问题原因与解决方案

问题原因

SSH本身不支持SSL的Server Name Indication(SNI)机制,直接发起SSH连接无法携带SNI信息,导致Nginx无法通过$ssl_preread_server_name提取服务器名。

解决方案

需要将SSH封装在SSL连接中并携带SNI,同时修改Nginx配置终止SSL连接,通过$ssl_server_name识别服务器名并路由。

1. 客户端连接命令修改

使用如下命令发起封装了SSL的SSH连接:

ssh -o ProxyCommand="openssl s_client -quiet -servername app1.mydomain.com -connect MyNginxServer:22000" app1_username@app1.mydomain.com -i ssh_private_key_file

2. Nginx配置修改

修改后的Stream配置如下,需配置SSL证书以终止SSL连接:

stream {
log_format  ssh  '|| SSL_ServerName $ssl_server_name || Upstream $ssh_upstream ||';
access_log  /opt/homebrew/var/log/nginx/ssh_access.log  ssh;

map $ssl_server_name $ssh_upstream {
    app1.mydomain.com   app1-deviceIP:22;
    app2.mydomain.com   app2-deviceIP:22;
    app3.mydomain.com   app3-deviceIP:22;
    app4.mydomain.com   app4-deviceIP:22;
    app5.mydomain.com   app5-deviceIP:22;
    app6.mydomain.com   app6-deviceIP:22;
    app7.mydomain.com   app7-deviceIP:22;
    app8.mydomain.com   app8-deviceIP:22;
    app9.mydomain.com   app9-deviceIP:22;
}

server {
    listen 22000 ssl; # 网络路由器将入站22端口流量转发至Nginx的22000端口

    ssl_certificate /myPath/fullchain.pem;
    ssl_certificate_key /myPath/privkey.pem;

    proxy_pass $ssh_upstream;
}
}

注意事项

直接映射服务器名到上游IP并非最佳实践,建议参考Nginx文档定义上游组。

内容的提问来源于stack exchange,提问作者Junto026

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 05:40:20