根据我对 SSH 端口转发的基本理解,SSH 客户端软件会在 IP:PORT(例如 185.68.93.141:80)上打开一个侦听套接字。因此,如果我转到 Web 浏览器并访问解析为 185.68.93.141 的 somewebsite.com,那么我的 Web 浏览器将打开一个套接字与 185.68.93.141:80 进行通信。
可惜的是,浏览器不知道它不是在与 Web 服务器通信,而是在与 SSH 客户端通信。SSH 客户端将通过 SSH 连接发送该信息(通过端口 22,这是唯一允许通过 NAT 和防火墙的端口),然后 SSH 服务器将其转发到 localhost:80。
但是,根据我的经验和几次谷歌搜索,您无法将监听套接字绑定到外部 IP。您会收到“IP 在此上下文中无效”的错误。
那么,这实际上是如何实现的呢?
答案1
假设:
- NAT 后面有一个远程服务器,有公共 IP,
185.68.93.141
但由于 NAT,该服务器不能直接可用。 - 服务器
sshd
在端口22
和httpd
端口 上运行80
。 185.68.93.141:22
被转发到服务器,这样我们就可以ssh
(如ssh 185.68.93.141
)了。185.68.93.141:80
是不是转发至服务器。
目标:
httpd
从外部接触遥控器。
可能的方法:
ssh -L 5678:localhost:80 185.68.93.141
(注意:
localhost
以上内容在远程服务器上下文中表示 localhost)。现在,localhost:5678
本地计算机上到 的每个连接都将到达远程服务器的localhost:80
(127.0.0.1:80
)。远程服务器httpd
将“看到”来自远程服务器本身的连接。您的本地浏览器应该可以访问http://localhost:5678
。有几个障碍:- 远程端
httpd
可能会拒绝连接,因为使用的 URL 不是它所期望的,假设它期望http://example.com
。您可以通过在本地重定向example.com
到 来解决这个问题,方法是提供您自己的 DNS 服务或修改。即使这样,您也需要连接到。127.0.0.1
/etc/hosts
http://example.com:5678
- 您可能希望使用端口
80
而不是5678
本地端口(因此使用上述技巧,要使用的 URL 是所需的http://example.com
),但您的本地操作系统可能不允许您打开低于的端口号1024
,除非您是(或管理员等)。不建议以root
身份运行。ssh
root
- 远程端
ssh -D 5678 185.68.93.141
localhost:5678
在这种情况下,您需要在( )上设置本地浏览器以使用 SOCKS4 或 SOCKS5 动态代理127.0.0.1:5678
。与它访问的任何站点的连接均由sshd
代表浏览器的远程端建立。您的浏览器被“视为”是从远程服务器连接的。现在您所要做的就是使用从远程服务器连接到其自身时有效的 URLhttpd
(但如果是http://localhost
或类似,请记住您的本地浏览器可能有一个选项,如“不对本地地址使用代理”)。更多信息这里。
如果您想在本地浏览器中使用185.68.93.141
(或somewebsite.com
解析为185.68.93.141
) 作为 URL 的主要部分,并且sshd
尽管 上没有端口80
转发,仍可以访问远程185.68.93.141
,那么您需要以某种方式让浏览器根据上述规则进行连接。Solessh
无法拦截不合作的浏览器的流量。
答案2
SSH 客户端绑定到本地主机上的端口。浏览器将请求发送到 SSH 客户端。客户端将请求转发到 SSH 服务器(防火墙外)。SSH 服务器连接到 URL。SSH 服务器不必绑定到端口(22 除外),因为在这种情况下它充当客户端,远程 Web 服务器将获取其默认 IP 地址。
另外,浏览器连接到 localhost 而不是 URL 上的 IP 地址的原因是由于浏览器代理设置。当您设置代理时,浏览器始终连接到代理 IP 地址(在本例中可能是 localhost),并告诉代理服务器您要连接的真实地址。
答案3
从评论中回答你的问题:
如果我有一个支持 SSH 的远程主机运行 Web 服务器,但端口 80 未公开,我可以配置 SSH 客户端,以便当有人在本地计算机上打开 Web 浏览器时,它可以访问远程计算机上的 Web 服务器吗?
如果远程主机上的 SSH 正在监听 22 并且您可以访问它,那么您可以使用本地端口转发进行连接。例如,考虑一个 Linux 客户端:
ssh remotehost -L 81:localhost:80
运行上述命令后,您应该会看到端口 81 上有一个新的监听套接字(您可以使用 进行检查netstat -latn | grep 81
)。
结果,本地端口 81 将被转发到 remotehost:80。
您现在可以在客户端计算机上浏览http://本地主机:81您将会看到网络服务器。