首页 > 解决方案 > nginx + ssh_exchange_identification:连接被远程主机关闭

问题描述

一台 nginx 服务器作为反向代理服务器连接到上游,以在一个端口 (12345) 上分离 SSH 和 SSL。nginx 识别数据传输协议并相应地在两个端口上分离代理背后的数据流量-> SSH 被转发到 PORT 9999 和 SSL 请求到 PORT 8080(Python Web 服务器)。

nginx配置如下:

/etc/nginx/nginx_conf

[...]

stream {
    upstream ssh {
        server localhost:9999;
    }

    upstream https {
        server localhost:8080;
    }

    map $ssl_preread_protocol $upstream {
        default ssh;
        "" https;
        "TLSv1.2" https;
        "TLSv1.3" https;
        "TLSv1.1" https;
        "TLSv1.0" https;
    }

    # SSH and SSL on the same port
    server {
        listen 12345;

        proxy_pass $upstream;
        ssl_preread on;
    }
}

[...]

当通过http://rpi_ip:12345调用web服务器时,8080端口被干净转发,并按请求访问web服务器。

问题在于尝试通过 SSH 建立连接。

我可以通过 ssh user@ip-rpi -p 9999 在本地连接到 Raspberry Pi,但不能通过 nginx 端口 12345。

/etc/ssh/sshd_config 中的调整

[...]

Port 9999
AddressFamily any
ListenAddress 0.0.0.0
#ListenAddress ::

[...]

调用 ssh user@ip-rpi -p 12345 -vvv 会带来:

OpenSSH_7.9p1 Raspbian-10+deb10u2, OpenSSL 1.1.1d  10 Sep 2019
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug2: resolve_canonicalize: hostname 192.168.2.198 is address
debug2: ssh_connect_direct
debug1: Connecting to 192.168.2.198 [192.168.2.198] port 12345.
debug1: Connection established.
debug1: identity file /root/.ssh/id_rsa type -1
debug1: identity file /root/.ssh/id_rsa-cert type -1
debug1: identity file /root/.ssh/id_dsa type -1
debug1: identity file /root/.ssh/id_dsa-cert type -1
debug1: identity file /root/.ssh/id_ecdsa type -1
debug1: identity file /root/.ssh/id_ecdsa-cert type -1
debug1: identity file /root/.ssh/id_ed25519 type -1
debug1: identity file /root/.ssh/id_ed25519-cert type -1
debug1: identity file /root/.ssh/id_xmss type -1
debug1: identity file /root/.ssh/id_xmss-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_7.9p1 Raspbian-10+deb10u2
debug1: ssh_exchange_identification: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"

debug1: ssh_exchange_identification:         "http://www.w3.org/TR/html4/strict.dtd">

debug1: ssh_exchange_identification: <html>

debug1: ssh_exchange_identification:     <head>

debug1: ssh_exchange_identification:         <meta http-equiv="Content-Type" content="text/html;charset=utf-8">

debug1: ssh_exchange_identification:         <title>Error response</title>

debug1: ssh_exchange_identification:     </head>

debug1: ssh_exchange_identification:     <body>

debug1: ssh_exchange_identification:         <h1>Error response</h1>

debug1: ssh_exchange_identification:         <p>Error code: 400</p>

debug1: ssh_exchange_identification:         <p>Message: Bad HTTP/0.9 request type ('SSH-2.0-OpenSSH_7.9p1').</p>

debug1: ssh_exchange_identification:         <p>Error code explanation: HTTPStatus.BAD_REQUEST - Bad request syntax or unsupported method.</p>

debug1: ssh_exchange_identification:     </body>

debug1: ssh_exchange_identification: </html>

ssh_exchange_identification: Connection closed by remote host

在这一点上,我希望你的帮助/想法来解决我的问题。

标签: linuxnginxraspberry-pi

解决方案


更改"" https;"" ssh;应该工作。

模块文档

map $ssl_preread_protocol $upstream {
    ""        ssh.example.com:22;
    "TLSv1.2" new.example.com:443;
    default   tls.example.com:443;
}

推荐阅读