autossh 不适用于两个或多个隧道 - 或者有其他选择吗?

Chr*_*ris 4 ssh ssh-tunnel

我正在尝试使用 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 上运行最新更新

bhe*_*elm 5

从 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


Chr*_*ris 0

我使用了不同的方法来解决这个问题。起初,我设法在启动时从客户端启动 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 来尝试您的建议。