我使用 SSH 在服务器上远程执行命令(Nagios 的模块 check_by_ssh)。但是 SSH 在尝试执行命令时不时挂起。我可以通过 SSH 登录到服务器,但不能执行简单的“ls”。它似乎阻止来自同一 IP 地址的所有客户端。身份验证不是问题,可能是通过 SSH 密钥或密码进行的。
ssh -l root -p 2222 server.domain.tld 'ls'
Run Code Online (Sandbox Code Playgroud)
这里是客户端调试信息
debug1: Entering interactive session.
debug2: callback start
debug2: client_session2_setup: id 0
debug1: Sending environment.
debug3: Ignored env ORBIT_SOCKETDIR
*** skipping approx 40 env var ignored
debug1: Sending command: ls
debug2: channel 0: request exec confirm 1
Run Code Online (Sandbox Code Playgroud)
它挂在那里。然后在随机时间后,它再次工作(不做任何事情)。杀死服务器上的所有 sshd 进程似乎也有效。它从腻子工作。我看到有些人因为 ISP 反向 DNS 问题而遇到这样的麻烦,但这里似乎并非如此。
它可以工作几个小时,然后不工作半小时左右。
什么可以解释这种行为?
编辑:似乎使用 -t 或 -T 选项,ssh 不会挂起,但我无法在 nagios 的 check_by_ssh 中传递这些选项之一
小智 9
我遇到了同样的问题,今天终于发现了导致问题的原因(至少对我而言)。这也可能对你有帮助。
当 ssh 建立会话时,IP 标头中的 DSCP 标志字段设置为 0x0。如果建立交互式会话,则设置为 0x10 (16),如果建立非交互式会话,则设置为 0x8 (8)。ssh 客户端使用 setsockopt() 系统调用(我在源代码中验证过)设置 DSCP 字段
我雇主的 VPN 配置错误,丢弃了 DSCP 为 0x8 的数据包,导致所有非交互式 ssh 流量也被丢弃。为了验证是 DSCP 字段导致了丢失,我在 ssh 服务器上使用了 iptables 强制将 DSCP 字段设置为 0x16 并测试了我的非交互式流量(ssh ls,你正在尝试的同样的事情)并且它起作用了在那之后。你也可以尝试同样的事情,看看这是否是你的会话挂起的原因。
要将来自 ssh 服务器的所有传出 ssh 流量的 DSCP 设置为 0x10,请运行:
$ sudo iptables -t mangle -A OUTPUT -p tcp --sport 22 -j DSCP --set-dscp 0x19
这是在rhel 6.5盒子上。
小智 5
我从这个博客中得到了解决我的问题的想法。我也有很有趣的问题
我有一个 L2vpn 链接(供应商提供 MPLS L2)来连接我的 HO 和分支机构。所有 ping 连接测试工作正常。当我使用 debian 服务器从 HO ssh 到客户端的 debian 服务器时,我可以登录到该服务器,但是在远程 ssh 登录到分支服务器后,我无法运行 ifconfig、htop 或 ps -ef 命令。当我应用这些命令时,会话会冻结。即使我使用腻子从 Windows pc 检查它,结果是一样的。有趣的是,当我通过 win 7 pc 的应用程序使用腻子管理器和 ssh 时,它工作正常。阅读此博客后,我从服务提供商处获得了 mpls mtu 信息,并在 HO 的源 debian 服务器接口上尝试使用不同 mtu 大小的相同场景。最后,从 1440 到 1470 的 mtu 大小工作正常,而默认的 mtu 大小 1500 不起作用。结论:两端 debian 服务器的 mtu 大小是默认值,即 1500,但在中间方式,服务提供商 MPLS L2vpn mtu 大小未匹配。谢谢
检查服务器端的ssh。您可以“跟踪”创建的进程/邮件 sshd 进程并查看它正在调用哪些系统调用。这应该可以为您提供有关它在做什么的更多信息。
还可以尝试“touch /tmp/randomfile”并查看挂起是否在创建后或之后发生。