我已经使用 ssh 访问远程服务器好几个月了,但最近我一直无法建立可靠的连接。有时我无法登录并收到消息“连接已通过端口 22 重置”,当我可以登录时,我会在几分钟内收到错误消息“client_loop:发送断开连接:管道损坏”(即使终端不空闲)。
我的 ~/.ssh/config 文件有:
Host *
ServerAliveInterval 300
ServerAliveCountMax 2
TCPKeepAlive yes
我的 /etc/ssh/sshd_config 文件有:
#ClientAliveInterval 300
#ClientAliveCountMax 3
我最近将我的 xfinity 计划升级到更快的速度,然后问题就开始发生。但 xfinity 坚持认为问题在于我。请注意,我的室友也有同样的 ssh 问题......
我有什么遗漏的吗?任何帮助将不胜感激! (我在Mac上运行)
答案1
我通过编辑文件 ~/.ssh/config 来解决同样的问题:
Host *
ServerAliveInterval 20
TCPKeepAlive no
动机:
TCPKeepAlive no
意思是“不向服务器发送保活消息”。当设置相反的 TCPKeepAlive yes 时,客户端会向服务器发送 keepalive 消息,并需要响应以维持连接结束。这将检测服务器是否出现故障、重新启动等。这样做的问题是,如果客户端和服务器之间的连接在短时间内中断(由于网络连接不稳定),这将导致 keepalive 消息失败,客户端将以“broken pipeline”结束连接。
设置TCPKeepAlive no
告诉客户端假设连接仍然良好,直到用户请求证明连接仍然良好,这意味着当您的 ssh 术语在后台闲置时临时连接中断不会终止连接。
答案2
大卫的回答是可以的,但是下面会解释更全面的解决方案。
您可以在客户端或服务器上解决此问题。
你怎么知道在哪里做呢?
如果您通过 SSH 连接到多个服务器,请在您的计算机上设置它。
如果您是系统管理员,并且有多个用户抱怨 SSH 连接频繁断开,您可以在服务器上进行设置。
客户端
连接到服务器时,使用以下-o
选项:
ssh -o ServerAliveInterval=600 [email protected]
该值600
代表600秒;即10分钟。
或者,将其添加到您的 ssh 配置文件中:
- 创建 ssh 配置文件(如果不存在):
touch ~/.ssh/config
- 设置权限:
chmod 600 ~/.ssh/config
- 在配置文件中设置参数。例如:
...或使用编辑器。echo "ServerAliveInterval 600" >> ~/.ssh/config
服务器端
- 打开位于 的 sshd 配置文件
/etc/ssh/sshd_config
。 - 将参数
ClientAliveInterval
和设置ClientAliveCountMax
为所需的值。
例如,ClientAliveInterval=200
和ClientAliveCountMax=3
表示服务器将在 200 秒后发送一条活动消息。如果客户端没有响应,它将在 400 秒后再次发送一条活动消息。如果客户端仍然没有响应,它将在 600 秒后发送另一条存活消息。如果仍然没有响应,SSH 连接将被断开。
来源:修复 SSH 连接的管道损坏错误 在 Linux手册。
答案3
我在尝试从 Mac 通过 SSH 连接到 Windows 笔记本电脑时遇到了这个问题。我尝试了上述解决方案ServerAliveInterval
,但TCPKeepAlive
没有效果。
我不太确定为什么会这样,但我通过从远程笔记本电脑的~/.ssh/authorized_keys
文件中删除我的公共 SSH 密钥解决了这个问题。不过,这特别奇怪,因为根据我的ssh -v
日志,我的公钥似乎可以很好地用于身份验证:
debug1: Authentication succeeded (publickey).
Authenticated to 192.168.1.21 ([192.168.1.21]:22).
debug1: channel 0: new [client-session]
debug1: Requesting [email protected]
debug1: Entering interactive session.
debug1: pledge: filesystem full
client_loop: send disconnect: Broken pipe
无论如何,删除密钥让我摆脱了client_loop: send disconnect: Broken pipe
错误,现在我可以登录了。
答案4
如果您使用子系统,则可以解决此问题,那么您需要确保这些所有者应该是 root 而不是任何其他所有者,并且权限应该受到限制
我也遇到过这个问题
Client_loop: send disconnect: broken pipe
因为我被授予了创建问题的所有其他用户的所有权限
看到我/var/log/auth.log
并发现错误,我被授予对所有创建问题的用户的完全权限。
更改权限后,连接成功。我很惊讶这是因为需要更少的权限
sudo chown root:root /rooted/Environment
sudo chmod 755 /rooted/Environment