答案1
如果我们可以访问具有公共 IP 地址的服务器,那么我们可以将其用作网关。我们可以通过反向 SSH 端口转发连接实现这一点。假设我们有三个实例:
公共服务器:这里我们有一个可运行的 SSH 服务器和公共 IP 地址(和/或域名)。我们能够使用公钥-私钥对连接到此服务器,该服务器不受密码保护(设置参考)。
私人服务器:这里我们有一个可运行的 SSH 服务器。它位于防火墙(NAT、ISP 等)后面,没有公共 IP 地址,但我们能够从它到公共服务器建立 SSH 连接,因此这里我们也有 SSH 客户端。
客户端计算机:这里我们(需要)只有 SSH 客户端。我们能够与公共服务器建立 SSH 连接。我们希望从该实例到私人服务器建立 SSH 连接。
校长级别
在原则层面,我们至少可以应用两种场景。
场景 1。我们不想在公共服务器的防火墙中打开额外的端口:
- 建立从私人服务器到公共服务器的带有端口转发的 SSH 连接。
- 建立从客户端计算机到公共服务器的带有端口转发的 SSH 连接。
- 通过转发端口(通过其自身)从客户端机器连接到私人服务器。
场景 2。我们倾向于在公共服务器的防火墙上打开一个额外的端口:
- 建立从私人服务器到公共服务器的带有端口转发的 SSH 连接。
- 通过公共服务器从客户端机器连接到私人服务器。
方案 1 的主要优点是我们不需要考虑我们的私人服务器有多安全。方案 2 的主要优点是我们省略了一个步骤,但在这种情况下我们应该考虑私人服务器的安全性,因为它可以通过转发端口公开访问。此外,这些方案可以应用于不同的端口和服务,而不仅仅是 SSH,例如 HTTP。
如何在 Ubuntu 中应用场景 1
建立从私有服务器到公共服务器的带端口转发的 SSH 连接
我们可以通过以下命令来实现:
ssh user-of-the-public-server@public-server -p 22 -R 2222:127.0.0.1:22 -i ~/.ssh/pass-less/id_rsa
-p 22
提供公共服务器的 SSH 端口(这不是强制性的)。-i ~/.ssh/pass-less/id_rsa
提供身份验证密钥文件。-R 2222:127.0.0.1:22
意味着2222
(远程)公共服务器上的端口将被转发到(本地)私人服务器的 SSH 端口,在本例中为22
。
-fTN
我们可以通过添加选项(OpenSSH 客户端的选项)将此连接推送到后台-参考)。我们还可以使用该工具autossh
来确保连接能够长时间保持活动状态(参考):
autossh user-of-the-public-server@public-server -p 22 -fTN -R 2222:127.0.0.1:22 -i ~/.ssh/pass-less/id_rsa
我们可以通过在文件中执行以下几行来简化上述命令~/.ssh/config
:
Host public-server-reverse
HostName 100.100.100.100
IdentityFile ~/.ssh/pass-less/id_rsa
User user-of-the-public-server
Port 22
RemoteForward 2222 localhost:22
- 100.100.100.100 是公共服务器的 IP 地址或域名
在这种情况下,上述命令将变成:
autossh public-server-reverse -fTN
我们可以通过下一个 Cron 作业在系统重启时轻松自动执行此任务(或者我们可以创建服务这应该是更好的方法):
@reboot sleep 45 && autossh public-server-reverse -fTN
一旦建立连接,我们就可以通过反向隧道从公共服务器连接到私人服务器,命令如下:
ssh user-of-the-private-server@localhost -p 2222 # provide an additional authentication data (for the Private Server) if it is needed…
建立从客户端计算机到公共服务器的带端口转发的 SSH 连接
我们可以通过以下命令来实现:
ssh user-of-the-public-server@public-server -p 22 -fTN -L 1111:127.0.0.1:2222 -i ~/.ssh/pass-less/id_rsa
-L 1111:127.0.0.1:2222
意味着1111
(本地) 客户端计算机上的端口将转发到 (远程) 公共服务器的端口2222
(即转发到私人服务器的 SSH 端口)。注意我们可以使用-L 2222:127.0.0.1:2222
。-fTN
如上所述,这些选项将把连接推送到后台。我们还可以使用指令或来实现
autossh
和~/.ssh/config
文件。RemoteForward
LocalForward
从客户端机器通过其自身连接到私人服务器
完成以上两个步骤后,我们就可以通过以下命令从客户端机器连接到公共服务器:
ssh user-of-the-private-server@localhost -p 1111 # provide an additional authentication data (for the Private Server) if it is needed…
如何在 Ubuntu 中应用场景 2
建立从私有服务器到公共服务器的带端口转发的 SSH 连接
此步骤与场景 1 中的第一步相同,但需要做一些额外的事情。
2222
打开公共服务器防火墙上的转发端口- 这超出了本答案的范围。
修改/etc/ssh/sshd_config
公共服务器并添加下一个指令,这将允许向公众开放我们的 SSH 隧道(不要忘记重新启动服务器:)sudo systemctl restart sshd.service
:
GatewayPorts yes
将我们的 SSH 隧道向公众开放。此步骤在问题中进行了很好的描述:(如何使 ssh 隧道向公众开放?)。根据那里的答案,我们可以向-g
在私有服务器和公共服务器之间建立连接的命令中添加选项:
autossh public-server-reverse -gfTN
@reboot sleep 45 && autossh public-server-reverse -gfTN
或者,我们可以用~/.ssh/config
这种方式修改文件:
Host public-server-reverse
HostName 100.100.100.100
IdentityFile ~/.ssh/pass-less/id_rsa
User user-of-the-public-server
Port 22
RemoteForward \*:2222 localhost:22
- 100.100.100.100 是公共服务器的 IP 地址或域名
最后我们应该killall autossh
重新建立连接。
通过公共服务器从客户端计算机连接到私人服务器
完成上述步骤后,我们可以通过以下命令实现我们的目的:
ssh user-of-the-private-server@public-server -p 2222 # provide an additional authentication data (for the Private Server) if it is needed… forward some ports, etc.
更新
如果民众服务器和私人的服务器位于同一 LAN 中,您可以使用任一选项代理命令或者代理跳转。 选项代理跳转在 OpenSSH 7.4+ 中可用,使用此选项你可以轻松通过多个网关。以下是几个例子:
ssh -J PublicServer PrivateServer
ssh -J user1@PublicServer:port1 user2@PrivateServer -p port2
ssh -J user1@PublicServer:port1,user2@IntermediateServer:port2 user3@PrivateServer -p port3
或者如果您愿意使用~/.ssh/config
条目:
Host PublicServer
HostName 100.100.100.100
IdentityFile ~/.ssh/public_server_id_rsa
User User1
Port 10222
Host PrivateServer
HostName 172.16.1.100
IdentityFile ~/.ssh/private_server_id_rsa
User User2
Port 22
ProxyJump PublicServer
请注意,两个 SSH 密钥都存储在客户端机器上。
100.100.100.100 为公网服务器的 IP 地址或域名,172.16.1.0/24 为公网服务器可以访问私网服务器的局域网络,172.16.1.100 为私网服务器的局域网络 IP 地址。
然后,为了连接到私人服务器,只需使用:
ssh PrivateServer