ssh 连接超时,为什么 sudo service sshd restart 可以解决它?

ssh 连接超时,为什么 sudo service sshd restart 可以解决它?

我遇到了一些无法解释的棘手行为。我有一个运行的虚拟机Ubuntu 20.04docker 19.03.6以及一个托管在Hyper-V 机器redis上的容器;Windows 2019

有第二台虚拟机(同一网络但不同的物理服务器)正在运行W2k19redis-client连接到redis实例。

由于有时配置不当,redisUbuntu 机器不堪重负,使用过多内存,并*connection timed out*在 中产生数千个异常redis-client

发生这种情况时,机器之间的所有连接都会停止工作。如果我尝试ssh从 W2k19 机器连接到 Ubuntu 或使用telnet同一台机器上的任何端口,我就会得到一个*connection timed out*

就像 Linux 机器上的某些东西自动禁止了 W2k19 机器的 IP 地址。从任何其他机器,我都可以通过sshtelnet等进行连接。

  • Ufw已关闭
  • 我们没有fail2ban安装
  • iptables配置为所有端口都打开

但我们仍然无法连接。我们在另一台机器上重现了这种行为,第二台虚拟机也出现了W2k19同样的情况redis-client

我们发现,要重新建立这些机器之间的连接,需要重新启动sshUbuntu 机器上的服务并重新启动W2k19机器。

仅单次操作sudo service sshd restart是不够的,仅重启机器W2k19也是不够的。我搞不清楚到底发生了什么,在这些情况下,我们不能接受将重新启动服务ssh和重启机器作为标准程序。

但迄今为止我们无法找出阻止连接的规则/配置。这ssh可能与服务有关,因为重新启动确实有助于恢复连接,但如何恢复呢?

为什么重新启动ssh服务(并重新启动W2k19机器)实际上会解除对 6379 端口的连接redis

!!! 更新 !!!tcpdump在 ubuntu 机器上尝试过,没有看到来自另一台虚拟机的流量。我为 ubuntu 机器配置了网络镜像,并使用 wireshark 分析了流量,也没有看到来自另一台虚拟机的流量。我在分析流量时禁用了所有防火墙(ubuntu VM、客户端 VM、hyper-v 主机)。

某些东西在流量到达虚拟机之前阻止了它,但我不知道是什么。

答案1

连接超时意味着初始 TCP SYN 没有引起任何响应 [在连接超时期限内]。客户端没有收到 SYN/ACK、RST 或 ICMP 错误 - 什么都没有。

发生这种情况的原因有很多。让我们按照 TCP 握手的各个阶段来大致分析一下。

故障1:初始 SYN 未传送到服务器。

故障2:服务器已经收到SYN,但是处理accept()连接请求的时间太长。

故障3:SYN/ACK 响应未传送到客户端机器。

故障4:最后一个 ACK​​ 以及它的所有重发都已丢失。(这可能会产生不同的错误,但我不确定。)


这部分让我有一个预感:

… 有时,redis 会使 Ubuntu 机器不堪重负,占用过多内存……

Linux OOM killer 是一个敏感话题;除非你对它进行配置——否则它通常更喜欢挂起用户空间而不是杀死任何东西。(不要问我为什么;我仍然不知道。配置它比找到最终的原因更容易。)

所以让我给你OOM 测试:问题重现时,您能ping访问服务器吗?您能ssh进入吗?可能的结果是:ping 成功,ssh 失败 — 表示故障 2。

这是 OOM 机器的典型特征:内核仍然活跃且运行正常,并且像什么都没发生一样响应 ping。但请注意:与 ping 不同,建立 TCP 需要用户空间服务器程序(例如 redis 或 sshd)主动调用accept()即将打开的连接。在 OOM 情况下,这需要很长时间,因为程序会等待其内存分配请求的完成。

OOM 测试结果“无法 ping,无法 ssh”——表明这不是故障 2;我猜是某种桥接虚拟化东西出了问题。

在 docker 中运行 redis 使情况更加复杂。Docker 有自己的内存核算逻辑(请参阅--memory和朋友们)。 它还不得不调整iptables容器网络规则以使其正常运行。


如果这没有帮助:请在此处提供有关网络设置的更多详细信息,包括虚拟化网络。我觉得我已经需要一个图表来正确计算您的虚拟机了。

相关内容