我的问题与同时提供 ssh 和 https 服务或者将 http 请求重定向到 ssh。我不想多路复用该流。我有一个虚拟服务器可以“备用”。
我在想,是否有可能拥有不同的虚拟服务器,我可以始终通过 ssh 连接,而其他人可以始终通过 https 连接。没有多路复用;干净/直接的解决方案,无需做决定。因此,例如,服务器web.myserver.com
将是仅支持 https 的服务器和ssh.myserver.com
仅支持 ssh 的服务器。
如果可能的话,最好不要产生额外的“流开销”。在我看来,stream
顶级指令似乎有这种开销。
编辑:添加更多信息到目前为止我尝试过什么:
在stream{}
配置部分我放了以下代码:
upstream ssh {
server 192.168.1.5:22;
}
server {
listen 443;
listen [::]:443;
proxy_pass ssh;
}
当我尝试连接到 ssh 时,我收到了以下日志信息:
debug2: resolving "***" port 443
debug3: resolve_host: lookup ***:443
debug3: ssh_connect_direct: entering
debug1: Connecting to *** [***] port 443.
debug3: set_sock_tos: set socket 3 IP_TOS 0x48
debug1: Connection established.
...
debug1: Local version string SSH-2.0-OpenSSH_9.2
debug1: kex_exchange_identification: banner line 0: HTTP/1.1 400 Bad Request
debug1: kex_exchange_identification: banner line 1: Server: nginx/1.18.0
debug1: kex_exchange_identification: banner line 2: Date: Thu, 09 Mar 2023 15:10:38 GMT
debug1: kex_exchange_identification: banner line 3: Content-Type: text/html
debug1: kex_exchange_identification: banner line 4: Content-Length: 157
debug1: kex_exchange_identification: banner line 5: Connection: close
debug1: kex_exchange_identification: banner line 6:
debug1: kex_exchange_identification: banner line 7: <html>
debug1: kex_exchange_identification: banner line 8: <head><title>400 Bad Request</title></head>
debug1: kex_exchange_identification: banner line 9: <body>
debug1: kex_exchange_identification: banner line 10: <center><h1>400 Bad Request</h1></center>
debug1: kex_exchange_identification: banner line 11: <hr><center>nginx/1.18.0</center>
debug1: kex_exchange_identification: banner line 12: </body>
debug1: kex_exchange_identification: banner line 13: </html>
kex_exchange_identification: Connection closed by remote host
答案1
根据您的最新评论,您似乎想在非常早期的阶段,直接在建立连接时进行流量分割。
此时,接收服务器没有关于您尝试连接的主机名的信息,因此它早期无法做太多事情。它的工作方式是,您的客户端进行 DNS 查找以获取web.myserver.com
或的 IP ssh.myserver.com
,然后与该 IP(在本例中为端口 443)进行 TCP 连接。现在,您在该 IP 上的该端口上侦听的任何内容都会经过正常的 TCP 连接建立,其中只有 IP/端口信息,没有主机名。
由于似乎要求两者都响应相同的端口(443),具体取决于您的设置(即,如果您有可能向代理服务器添加第二个 IP),您可以通过 IP 区分并让 DNS 映射每个web.myserver.com
IP ssh.myserver.com
,然后根据客户端连接到的 IP 尽早进行拆分(例如使用某些iptables
规则)。
如果没有可能添加第二个 IP,那么我实在看不到解决方案,至少在建立连接后检查前几个数据包,这正是上述涉及nginx
stream
部分的解决方案所做的。您提到的“流开销”应该是最小的,因为该stream
部分会在最初确定目的地后直接转发所有数据包而不进行检查。但似乎“流开销”并不是您试图避免的唯一部分,正如您所说:
不提供额外的“流开销”将还被渴望
(重点是我的……)。如果您分享任何其他要求,使得nginx
解决方案不适用于您的用例,我可以用任何其他可能想到的可能性来更新我的答案(或者社区中的其他人可能会想到更好的方法)。