我正在尝试使用 SSH 服务器作为连接多个内部服务器的网关。在这种情况下,内部意味着它们不能直接访问,它们没有分配给它们的公共 IP。
所以场景应该是这样的(例如有 2 个服务器,可能更多),网关公共 IP 123.456.789.45 内部为 10.12.40.13
+--------+ +---------+ +----------+
| client |--> 2214/tcp --> | | --> 22/tcp --> | Server 1 |
+--------+ | | +----------+
| Gateway |
+--------+ | | +----------+
| client |--> 2215/tcp --> | | --> 22/tcp --> | Server 2 |
+--------+ +---------+ +----------+
Run Code Online (Sandbox Code Playgroud)
我的第一种方法是将它们从网关设置到服务器,类似于
ssh -N -L 123.456.789.45:2214:127.0.0.1:22 tunnel-user@server1
ssh -N -L 123.456.789.45:2215:127.0.0.1:22 tunnel-user@server2
Run Code Online (Sandbox Code Playgroud)
虽然这可行,但我偶然发现了隧道不太可靠的问题,到处都失败了。合乎逻辑的下一步是尝试autossh运行。在这里我遇到了很多问题。可以毫无问题地建立第一个隧道
autossh -M 20000 -f -N -L 123.456.789.45:2214:127.0.0.1:22 tunnel-user@server1
Run Code Online (Sandbox Code Playgroud)
我可以通过外部连接到端口 2214 的网关来访问 server1。但是我无法使用 autossh 启动并运行第二个。现在头撞了几个小时,我决定反之亦然。所以:
第二种方法是将它们从服务器设置到网关。再次,虽然纯 ssh 的变体使用这样的东西工作......
ssh -R 123.456.789.45:2214:127.0.0.1:22 tunnel-user@gateway # <- init from server 1
ssh -R 123.456.789.45:2215:127.0.0.1:22 tunnel-user@gateway # <- init from server 2
Run Code Online (Sandbox Code Playgroud)
...使用 autossh 失败。
autossh -M 20000 -f -R 123.456.789.45:2214:127.0.0.1:22 tunnel-user@gateway
Run Code Online (Sandbox Code Playgroud)
日志文件只是什么也没说。Syslog 至少提出了
ssh exited prematurely with status 0; autossh exiting
Run Code Online (Sandbox Code Playgroud)
现在有人知道如何解决这autossh两种方法的问题吗?有没有类似的东西autossh我可以试一试?有没有办法实现上面提到的纯 ssh 版本的刷新?
所有涉及的服务器都在 Ubuntu 10.04 LTS 和 autossh 1.4b 上运行最新更新
从 autossh 文档:
autossh 使用 ssh 构建一个 ssh 转发循环(一个从本地到远程,一个从远程到本地),然后发送它期望返回的测试数据。
-M port[:echo_port] 指定要使用的基本监控端口。如果没有回显端口,这个端口和它上面的端口(端口 + 1)应该没有其他东西在使用。autossh 将在基本监控端口上发送测试数据,并在上面的端口上接收它。例如,如果您指定“-M 20000”,autossh 将设置转发,以便它可以在端口 20000 上发送数据并在 20001 上接收它。
如果您使用 -M 20000 两次,这一定会失败。为此使用不同的端口(它们之间有一个端口空间,因此 -M 20000 和 -M 20002 会起作用)。我建议做一个“man autossh”并阅读 autossh 的文档,它也可以在线获得:http : //www.manpagez.com/man/1/autossh/。如果你使用了很多 autossh 隧道,你可以设置一个专用的 echo 服务(再次来自 autossh 文档):
或者,可以指定远程回显服务的端口。如果您希望使用标准的 inetd echo 服务,这应该是端口 7。当指定echo port时,只使用指定的monitor port,并且双向携带monitor报文。这允许 autossh 在不阻塞远程端每个隧道的端口的情况下验证连接。
如果您想为此使用 xinetd,这是我的 echo 服务声明:
service echo
{
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/bin/cat
log_on_failure += USERID
only_from = 127.0.0.1
disable = no
}
Run Code Online (Sandbox Code Playgroud)
那么你可以在来自不同机器的所有隧道上使用 -M 20000:7 。如果您在一台机器上有多个隧道,请使用多个 -L 或 -R 选项或使用不同的端口,例如 -M 20002:7
我使用了不同的方法来解决这个问题。起初,我设法在启动时从客户端启动 SSH 隧道。我为此编写了一个 init.d 脚本,将其设为一项服务,并让 puppet 处理它的启动。
然而,这太麻烦了,我决定转身并在网关服务器及其 UFW 配置上使用 NAT 和端口转发。尽管它不是 SSH 问题本身的答案,但这里的解决方案解决了基本问题:
启用并/etc/ufw/sysctl运行net/ipv4/ip_forward=1sysctl -p
在/etc/ufw/before.rules
*nat
:POSTROUTING ACCEPT [0:0]
# forward traffic from eth1 through eth0
-A POSTROUTING -s 10.12.40.0/24 -o eth0 -j MASQUERADE
# some DNAT rules
-A PREROUTING -i eth0 -p tcp --dport 2214 -j DNAT --to-destination 10.12.40.14:22
-A PREROUTING -i eth0 -p tcp --dport 2215 -j DNAT --to-destination 10.12.40.15:22
#
COMMIT
Run Code Online (Sandbox Code Playgroud)
然后跑了ufw disable && ufw enable。所需要做的就是检查客户端上的正确路由。
不同的方法,想要的结果。感谢大家阅读和思考我的问题以及@sonassi:一旦我有更多时间并且需要的不仅仅是 SSH 端口,我就会尝试使用 OpenVPN 来尝试您的建议。
| 归档时间: |
|
| 查看次数: |
13446 次 |
| 最近记录: |