我需要访问 NAT 内的一些服务器。由于我确实有一个公共服务器,所以我正在这样做:
A和B都有一个运行该命令的服务:ssh -fnN -R 17000:localhost:22 [email protected] -i privateA
唯一的区别是端口。对于 B,端口是 17001。
这将创建一个从 NAT 内部的服务器到我的公共服务器的全天候休眠连接。
现在我可以随时连接到 S 并使用命令:ssh -i privateS -p 17000 user@localhost
连接到 A。
太棒了。它解决了我眼前的问题。但在寻找解决方法时,我还有其他选择,所以我无法找到实际使用它的方法。
该方法的主要缺点是必须提前知道每个服务器的远程端口并配置每个服务器以使用它,因为端口选择来自 A 和 B 中的命令,而不是 S 中的命令。
如果我们使用-R 0:localhost:22
第一个命令(在 A 和 B 中),所有操作都一样,但远程端口将是随机的。SSH 命令甚至会回显在 S 中创建的端口号。但此信息仅在 A 和 B 中可用。
从 SI 简单看到两个处于监听模式的开放端口,但不知道使用哪一个来到达 A 或 B。
想象一下,我有 50 个远程服务器,而不是 2 个。
我如何识别每个 SSH 连接?
我的第一个尝试是使用 authorized_keys 文件中的命令,并通过使用中的私有文件进行识别。在这里,我可以检索 SSH 进程,然后检索该进程下的端口列表。
但是,由于我使用的-N
命令根本没有执行。我还可以尝试什么其他方法?
在远程机器上创建随机端口但不向其共享此信息的命令有什么用处? 的预期用途是什么-R 0:host:22
?
再次,我的问题解决了,只是想在这里学习......
答案1
从服务器的角度来看,使用-R 17000:…
或-R 0:…
在客户端上没有区别。一些端口被分配。服务器机器并不关心它是由客户端机器的人类用户还是某种算法选择的。
假设它是由客户端机器的人类用户选择的,而这个用户就是你。那么你就有责任将你选择的数字(例如17000
)传递给隧道的未来用户。
如果你决定使用-R 0:…
那么通知未来的隧道用户仍然您的责任,这件事没有任何变化。而且您会在运行时知道该号码(“SSH 命令甚至会回显在 S 中创建的端口号”)。
笔记一般来说隧道的未来用户可能会或者可能不会是 S 的用户。-R
您可以指定远程(即本地到 S)绑定地址,它可能是一个外部地址;如果服务器配置为允许这样做(请参阅我的这个答案)那么就可以从 S 的外部使用隧道进行连接,没有登录到 S。
所以一般来说在 S 上存储(或了解)哪个端口通过隧道传输到哪里并不能解决问题。您认为这是一个好主意,因为您可以登录到 S。
要么你(在客户端上运行ssh
)使用静态号码,然后你可以提前通知隧道的未来用户(包括你你自己);要么你使用-R 0:…
并负责不提前通知隧道的未来用户(包括你你自己)。
我理解每一个ssh -R 0:…
你的情况是每个步骤都是自动的。所以你应该还自动执行通知隧道未来用户的程序。您可以这样做来通知user
S 上的某人(可能是您自己):
#!/bin/sh
# client-side, say A
ssh -fNMS /path/to/socket [email protected]
port="$(ssh -S /path/to/socket -O forward -R 0:localhost:22 placeholder)"
echo "$port" | ssh -S /path/to/socket placeholder 'cat >A.port' # or B.port etc.
这是一个快速而粗糙的脚本,它基于这是我的另一个答案您可以在那里找到一些详细的解释。