Ubuntu Server 14.04 - 如何远程修复 openssh“断开的管道”?

Ubuntu Server 14.04 - 如何远程修复 openssh“断开的管道”?

我刚刚设置了一个 Ubuntu 服务器,并在服务器上使用 openssh 通过 SSH 对其进行了配置。我不得不重新启动,并且由于Write failed: Broken pipe错误无法通过 SSH 连接。

就我的研究而言(https://wiki.archlinux.org/index.php/SFTP_chroot- 故障排除,第一条),这是 ChrootDirectory 所有权问题。我在设置 apache 网络服务器时可能搞砸了某件事。

无论如何,现在我无法使用我的用户名通过 SSH 登录。不幸的是,我只有一个用户,所以我不能使用其他用户。有没有办法让我在不物理访问服务器的情况下修复所有权或 openssh 设置?谢谢!

尝试使用调试选项连接显示:

ssh -v [email protected]
OpenSSH_6.6.1, OpenSSL 1.0.1f 6 Jan 2014
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug1: Connecting to 123.123.123.123 [123.123.123.123] port 22.
debug1: Connection established.
debug1: identity file /home/username/.ssh/id_rsa type -1
debug1: identity file /home/username/.ssh/id_rsa-cert type -1
debug1: identity file /home/username/.ssh/id_dsa type -1
debug1: identity file /home/username/.ssh/id_dsa-cert type -1
debug1: identity file /home/username/.ssh/id_ecdsa type -1
debug1: identity file /home/username/.ssh/id_ecdsa-cert type -1
debug1: identity file /home/username/.ssh/id_ed25519 type -1
debug1: identity file /home/username/.ssh/id_ed25519-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2
debug1: Remote protocol version 2.0, remote software version OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.4
debug1: match: OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.4 pat OpenSSH_6.6.1* compat 0x04000000
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr [email protected] none
debug1: kex: client->server aes128-ctr [email protected] none
debug1: sending SSH2_MSG_KEX_ECDH_INIT
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: ECDSA ...
debug1: Host '123.123.123.123' is known and matches the ECDSA host key.
debug1: Found key in /home/username/.ssh/known_hosts:7
debug1: ssh_ecdsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Trying private key: /home/username/.ssh/id_rsa
debug1: Trying private key: /home/username/.ssh/id_dsa
debug1: Trying private key: /home/username/.ssh/id_ecdsa
debug1: Trying private key: /home/username/.ssh/id_ed25519
debug1: Next authentication method: password
[email protected]'s password: 
debug1: Authentication succeeded (password).
Authenticated to 123.123.123.123 ([123.123.123.123]:22).
debug1: channel 0: new [client-session]
debug1: Requesting [email protected]
debug1: Entering interactive session.
Write failed: Broken pipe

答案1

就我而言,原因原来是 VPN 与具有外部 SSH 端口转发的不可靠的 DSL 调制解调器之间的交互。

设想

设置:

  • 192.168.0.0/24 是 LAN 网络
  • 192.168.1.0/24 是 VPN 客户端网络
  • server1(192.168.0.3)是VPN服务器
  • DSL 调制解调器 (192.168.0.10) 是所有主机的默认路由器
  • DSL 调制解调器具有静态路由,可将 VPN 流量(即目的地为 192.168.1.0/24)发送到服务器 1
  • 在 DSL 调制解调器配置中,TCP 端口 22 转发到服务器 1
  • 在 DSL 调制解调器配置中,VPN 端口转发至服务器 1
  • server2(192.168.0.223)是我正在尝试通过 SSH 连接的服务器

症状是,在建立连接期间,客户端在密码或密钥验证后总是显示“写入失败:管道损坏”。此情况发生在该debug1: Sending command: ...步骤之后。我在服务器上启用了详细日志记录,它显示客户端发送了 TCP 重置。

分析

我使用 Wireshark 进行了测试,发现发生了以下序列:

 23.002349   192.168.1.6 -> 192.168.0.223  TCP 56677 > ssh [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=643508643 TSER=0 WS=8
 23.080714  192.168.0.223 -> 192.168.1.6   TCP ssh > 56677 [SYN, ACK] Seq=0 Ack=1 Win=28960 Len=0 MSS=1369 TSV=1628354 TSER=643508643 WS=7
 23.080743   192.168.1.6 -> 192.168.0.223  TCP 56677 > ssh [ACK] Seq=1 Ack=1 Win=5888 Len=0 TSV=643508663 TSER=1628354
 23.399242  192.168.0.223 -> 192.168.1.6   SSH Server Protocol: SSH-2.0-OpenSSH_6.7p1 Debian-5+deb8u1\r
 23.399267   192.168.1.6 -> 192.168.0.223  TCP 56677 > ssh [ACK] Seq=1 Ack=40 Win=5888 Len=0 TSV=643508742 TSER=1628434
 23.399606   192.168.1.6 -> 192.168.0.223  SSH Client Protocol: SSH-2.0-OpenSSH_5.5p1 Debian-6+squeeze8\r
 23.479613  192.168.0.223 -> 192.168.1.6   TCP ssh > 56677 [ACK] Seq=40 Ack=42 Win=29056 Len=0 TSV=1628454 TSER=643508742
 23.479638   192.168.1.6 -> 192.168.0.223  SSHv2 Client: Key Exchange Init
 23.488855  192.168.0.223 -> 192.168.1.6   SSHv2 Server: Key Exchange Init
 23.528382   192.168.1.6 -> 192.168.0.223  TCP 56677 > ssh [ACK] Seq=890 Ack=960 Win=8960 Len=0 TSV=643508775 TSER=1628455
 23.607196  192.168.0.223 -> 192.168.1.6   TCP ssh > 56677 [ACK] Seq=960 Ack=890 Win=31872 Len=0 TSV=1628486 TSER=643508762
 23.607218   192.168.1.6 -> 192.168.0.223  SSHv2 Client: Diffie-Hellman GEX Request
 23.714323  192.168.0.223 -> 192.168.1.6   SSHv2 Server: Diffie-Hellman Key Exchange Reply
 23.714367   192.168.1.6 -> 192.168.0.223  TCP 56677 > ssh [ACK] Seq=914 Ack=1240 Win=10752 Len=0 TSV=643508821 TSER=1628512
 23.732326   192.168.1.6 -> 192.168.0.223  SSHv2 Client: Diffie-Hellman GEX Init
 23.837671  192.168.0.223 -> 192.168.1.6   SSHv2 Server: Diffie-Hellman GEX Reply
 23.876369   192.168.1.6 -> 192.168.0.223  TCP 56677 > ssh [ACK] Seq=1186 Ack=2088 Win=13568 L
 23.934571   192.168.1.6 -> 192.168.0.223  SSHv2 Client: New Keys
 24.052445  192.168.0.223 -> 192.168.1.6   TCP ssh > 56677 [ACK] Seq=2088 Ack=1202 Win=33664 Len=0 TSV=1628598 TSER=643508876
 24.052465   192.168.1.6 -> 192.168.0.223  SSHv2 Encrypted request packet len=52
 24.130296  192.168.0.223 -> 192.168.1.6   TCP ssh > 56677 [ACK] Seq=2088 Ack=1254 Win=33664 Len=0 TSV=1628617 TSER=643508906
 24.131032  192.168.0.223 -> 192.168.1.6   SSHv2 Encrypted response packet len=52
[...]
 29.775083   192.168.1.6 -> 192.168.0.223  SSHv2 Encrypted request packet len=136
 29.897679  192.168.0.223 -> 192.168.1.6   TCP ssh > 56677 [ACK] Seq=2728 Ack=2586 Win=39936 Len=0 TSV=1630059 TSER=643510336
 30.986259  192.168.0.223 -> 192.168.1.6   SSHv2 Encrypted response packet len=52
 30.986704   192.168.1.6 -> 192.168.0.223  SSHv2 Encrypted request packet len=136
 31.066976  192.168.0.223 -> 192.168.1.6   TCP ssh > 56677 [ACK] Seq=2780 Ack=2722 Win=41600 Len=0 TSV=1630351 TSER=643510639
 31.068851   192.168.0.10 -> 192.168.1.6   SSH Encrypted response packet len=88
 31.068874   192.168.1.6 -> 192.168.0.10   TCP 56677 > ssh [RST] Seq=1 Win=0 Len=0
 61.015948   192.168.1.6 -> 192.168.0.223  SSHv2 Encrypted request packet len=68
 61.094573  192.168.0.223 -> 192.168.1.6   TCP ssh > 56677 [RST] Seq=2780 Win=0 Len=0

这里发生的情况是,直到 31.066976 秒标记(server2 发送请求的 ACK)之前,一切都很好(跳过了一些细节)。但是,下一个数据包(在 31.068851)来自 DSL 调制解调器,这当然会使我的笔记本电脑向它发送 TCP RST(连接重置),告诉它它正在使用旧连接或其他东西。(我知道这是相关的,因为 RST 是从端口 56677 发送的。)

但是,DSL 调制解调器似乎将此重置转发回服务器 1,这当然会终止实际的 SSH 连接。因此,在 30 秒超时(在 61.015948)后,我的笔记本电脑尝试发送另一个请求,而实际的 TCP 连接没有响应 30.986704 的请求。自然,服务器 1 随后向它发送 TCP RST,因为它已经放弃了该连接。因此Write failed: Broken pipe我的笔记本电脑上出现错误。

结论

DSL 调制解调器正在查看一半的连接,即来自服务器 2 的回复数据包,并将其作为 VPN 流量转发到服务器 1。但至少其中一些数据包正在以某种方式被 DSL 调制解调器解释,因为它正在发送随机响应(顺便说一下,使用 SSHv1)。请注意,DSL 调制解调器看不到 30.986704 处的数据包,因为它来自服务器 1 上的隧道并通过 LAN 发送到服务器 2。所以我不太清楚发生了什么。

解决方法

我在服务器 2 上为 192.168.1.0/24 添加了一条静态路由,网关为 192.168.0.3(服务器 1),这避免了通过 DSL 调制解调器传输 VPN 客户端的回复流量。问题解决了。

PS——对于 TCP 新手,请记住,仅当在设定的时间间隔内没有可发送的回复数据时,才会发送单独的 ACK 消息;如果有,则仅在该数据消息上设置 ACK 标志。

相关内容