如何检测孤立的 Unix 套接字文件?

如何检测孤立的 Unix 套接字文件?

我已经创建了一个反向 SSH 隧道,它在远程服务器上创建了一个 UNIX 套接字(我们称之为 proxy_srv),这样我就可以通过 2 个步骤连接隧道所有者(在本问题的其余部分中名为 target_srv):使用创建从 Unix 套接字到 TCP 端口的链接socat,然后使用 SSH 客户端连接到该端口(SSH 客户端似乎不接受连接到 Unix 套接字,因此我使用该socat技巧作为解决方法)。

所涉及的命令(足以重现,在实践中还需要更多,使用身份文件等),顺序如下:

来自 target_srv:

me@target_srv:% ssh -CNR /tmp/$(hostname):127.0.0.1:22 me@proxy_srv -o ExitOnForwardFailure=yes

来自 proxy_srv:

me@proxy_srv:% socat TCP-LISTEN:2222 UNIX-CONNECT:/tmp/target_srv

从任何其他可以访问 proxy_srv 的计算机:

ssh someone@proxy_srv

所有这些的目标是自动从使用 GPRS 网络的机器到接入点建立一个隧道,以便我在出现问题时可以访问它们,考虑到我无法物理访问它们(距离太远了)。

我有两个主要问题:

  • 当有人删除 proxy_srv 上的 Unix 套接字文件时,隧道不会结束,所以我无法重新创建它(解决方法很简单,只需使用专用用户,但对我来说仍然有点担心),

  • 最重要的是,如果由于某种原因 target_srv 上的某些东西重新启动,无论是物理重启还是系统崩溃,之后都会自动启动,proxy_srv 上的文件不会被删除,隧道也无法重建。当然,我可以直接删除它,并希望问题不是与另一台计算机发生冲突,但我认为至少应该有更好的方法可以解决这个问题,例如检测不再有侦听器的套接字文件并定期自动删除它们(当然是在专用文件夹内)。

任何想法?

答案1

我知道有很多 target_srv 机器,因此您不使用而是将proxy_srv 的端口临时-R 2222:127.0.0.1:22连接到您选择的机器。2222

我认为正确的工具是 VPN。如果 proxy_srv 是 VPN 服务器,而 target_srv 机器是客户端,则可以通过 SSH 隧道连接到所需客户端的 (VPN) IP 地址。如果您也将本地计算机设为客户端,您甚至可以半直接地访问其他客户端(无需 SSH 隧道)。VPN 软件将负责在虚拟网络中建立、维护和更新任何 target_srv 的存在。

假设您无法使用 VPN,而您的这个基于套接字的设备是必须的。我不知道如何检测孤立的 Unix 域套接字,但是还有另一种方法可以处理这种情况。

在 proxy_srv 上创建一个辅助脚本,假设/home/me/bin/ssh-tunnel-helper.sh

#!/bin/sh

soc1="$1".tmp
soc2="$1"

mv "$soc1" "$soc2" || { rm "$soc1"; exit 2; }
while sleep 40; do
   [ -e "$soc2" ] || exit 1
done

(不要忘记使其可执行)。

然后在 target_srv 上调用:

socket="/tmp/$(hostname)-tunnel"
while sleep 5; do
   ssh -CR "$socket".tmp:127.0.0.1:22 -o ExitOnForwardFailure=yes me@proxy_srv \
      /home/me/bin/ssh-tunnel-helper.sh "$socket"
done

现在

  • 当有人删除 proxy_srv 上的 unix 套接字文件时

脚本ssh-tunnel-helper.sh检测到它并退出。target_srvwhile上的循环会更新隧道。

  • 如果由于某种原因 target_srv 上的某些东西重新启动了,[…] proxy_srv 上的文件不会被删除

套接字*-tunnel确实没有被删除,但sshd最初创建*-tunnel.tmp并重命名之后。诀窍在于,在 Unix 中,您可以打开文件并移动它(甚至删除它)。重命名套接字不会干扰现有隧道,但允许将来创建新套接字。

如果辅助脚本被中断,它可能会留下一个过时的*-tunnel.tmp套接字,从而阻止将来的隧道建立。我预计此类事件很少见。rm /tmp/*-tunnel.tmp在 proxy_srv 上运行以恢复。即使你碰巧删除了其他此时即将重命名的套接字,其帮助脚本将退出,并且隧道将在一段时间后更新。

笔记:

  • 您可能想要在 target_srv 机器上使用autossh而不是ssh来检测断开的连接等。即使autossh您仍然需要while循环,因为autossh如果辅助脚本退出(例如当有人删除 proxy_srv 上的套接字时)它也会退出。

相关内容