Joh*_*hnW 21 multiplexing nginx
我有一个用于网络的个人服务器。我有时需要 SSH/SFTP 到它。
免责声明:我对nginx内部结构的经验很少。
今天早上,我发现一家知名咖啡馆连锁店的免费 wifi 阻止了 SSH(实际上,他们阻止了任何不在 80/443 上的东西)。但是当我需要 SSH 时,我需要它,所以我寻找在同一端口上共享 SSH 和 HTTPS 的方法。
我查看了一些可以在端口 443 上运行的可能解决方案:
SSHL:SSH/OpenVPN/HTTPS 多路复用器;OpenVPN:VPN 解决方案具有用于 OpenVPN 和 HTTPS 的内置多路复用器;HAProxy:网络服务器/负载平衡器也可以多路复用所有内容。所有这些看起来都很简单,但我真的不喜欢添加层和复杂性的事实,并且可能会在不太可能的情况下放慢速度,因为我需要在 443 上使用 SSH。
我知道它nginx已经支持原始 TCP 流处理。所以我想知道我是否可以直接在nginx. 这个想法是,如果模块识别 HTTP(S) 或其他所有内容,则nginx可以选择使用该http模块stream。
在这种情况下,我有两个问题:
nginx即使能够做这样的区别?(我什至不确定我是否能够同时http在stream块和块中侦听端口 443。)小智 19
由于 nginx 版本 1.15.2 添加了新变量$ssl_preread_protocol。并在官方博客中添加了关于如何使用此变量在同一端口上复用 HTTPS 和 SSH 的帖子
https://www.nginx.com/blog/running-non-ssl-protocols-over-ssl-port-nginx-1 -15-2/
配置 SSH(默认)和 HTTPS 的示例:
stream {
upstream ssh {
server 192.0.2.1:22;
}
upstream web {
server 192.0.2.2:443;
}
map $ssl_preread_protocol $upstream {
default ssh;
"TLSv1.2" web;
}
# SSH and SSL on the same port
server {
listen 443;
proxy_pass $upstream;
ssl_preread on;
}
}
Run Code Online (Sandbox Code Playgroud)
tux*_*tux 11
我有一个工作配置,使用 nginx 流模块在端口 443 上通过 tls 隧道传输 ssh。我还在同一端口上通过 TLS 和普通 HTTP 执行 XMPP。我通过 ALPN 进行多路复用。
(您需要 nginx > 1.13.10 才能将 ssl_preread 模块与 alpn http://nginx.org/en/docs/stream/ngx_stream_ssl_preread_module.html#ssl_preread 一起使用)
我的配置使用了 nginx 的 docker 版本,但它也应该在没有 docker 的情况下工作。
stream {
# check ALPN for xmpp client or server and redirect to local ssl termination endpoints
map $ssl_preread_alpn_protocols $ssl_multiplexer {
"xmpp-client" 127.0.0.1:5422;
"xmpp-server" 127.0.0.1:5469;
"identifyssh" 127.0.0.1:8822;
default 127.0.0.1:8443;
}
server {
listen 443;
ssl_preread on;
proxy_pass $ssl_multiplexer;
proxy_protocol on;
set_real_ip_from 172.18.0.0/32;
}
# ssl termination for c2s connections
server {
listen 5422 ssl proxy_protocol;
# ... <- tls keys and options here
proxy_ssl off;
proxy_pass ejabberd:5222;
}
# ssl termination for s2s connections
server {
listen 5469 ssl proxy_protocol;
# ... <- tls keys and options here
proxy_ssl off;
proxy_pass ejabberd:5269;
}
# ssl termination for ssh connections
server {
listen 8822 ssl proxy_protocol;
# ... <- tls keys and options here
proxy_ssl off;
proxy_pass yourserver:22;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您想使用 XMPP 的东西,您必须添加一些 SRV 记录以指向您的服务器 443 端口,请参阅https://xmpp.org/extensions/xep-0368.html
如果您想连接到您的 ssh 服务器,您必须将您的 ssh 会话包装在一个 ssl 会话中,该会话发送您在流配置中定义的 ALPN 字符串。我在上面的例子中使用了“identifyssh”。您可以使用任何东西,但尽量不要与官方定义的名称冲突:https : //www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
要启动从客户端到准备好的服务器的 ssh 会话,请使用:
ssh you@yourserver -o "ProxyCommand openssl s_client -alpn identifyssh -ign_eof -connect yourserver:443"
Run Code Online (Sandbox Code Playgroud)
你应该连接。
我还应该注意,我使用 proxy_protocol 在传递到我的后端时保留客户端标头和 IP 地址。
您在 http {} 部分配置的普通 http 服务器应该处理这个问题:
server {
listen 8443 ssl proxy_protocol;
# ...
}
Run Code Online (Sandbox Code Playgroud)
最好的事情是,您不需要像 sslh、stunnel、proxytunnel 或其他工具来完成这项工作。你只需要一个更新的 nginx 和 openssl。希望这可以帮助某人。它会帮助我深入研究这些东西。
据我所知,目前nginx不支持。
在SSH-2中,客户端将向服务器发送一条 hello 消息:
当连接建立后,双方必须发送一个标识字符串。该标识字符串必须是
Run Code Online (Sandbox Code Playgroud)SSH-protoversion-softwareversion SP comments CR LF
在TLS 1.2中,客户端需要先发送:
Client Server
ClientHello -------->
ServerHello
[ChangeCipherSpec]
<-------- Finished
[ChangeCipherSpec]
Finished -------->
Application Data <-------> Application Data
Run Code Online (Sandbox Code Playgroud)
客户可以使用此信息进行实施。
| 归档时间: |
|
| 查看次数: |
30292 次 |
| 最近记录: |