升级到 openssh 7.8p1 后 ssh 连接报错 packet_write_wait: Broken pipe

今天升级 macOS VMware 里的 Fedora 28 虚拟机后 ssh 连接出现下面报错:

$ ssh -v 192.168.1.11
......
debug1: Next authentication method: publickey
debug1: Offering public key: RSA SHA256:emH3b5VRiPrFjzd1 /home/user/.ssh/id_rsa
debug1: Server accepts key: pkalg rsa-sha2-512 blen 535
debug1: Authentication succeeded (publickey).            # <-- 认证成功
Authenticated to 192.168.1.11 ([192.168.1.11]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug1: Sending env XMODIFIERS = @im=ibus
debug1: Sending env LANGUAGE =
packet_write_wait: Connection to 192.168.1.11 port 22: Broken pipe

debug 显示已经成功认证,但最后连接被断开。

开始以为是 ~/.ssh/config 配置文件有问题,重命名配置文件后还是一样无法连接。

在 macOS 下测试 ssh 是正常的,说明服务端没有问题。

google 搜索了一下报错信息,有位用 ArchLinux 的大哥升级到 openssh 7.8p1 后遭遇类似问题:

FS#59826 - [openssh] cannot connect, read from master failed: broken pipe 2018-08-27

Note that this is a client issue, not a server issue. To fix it, add:

Host *
    IPQoS lowdelay throughput

to ~/.ssh/config ( not sshd_config ).

OpenSSH 7.8p1 drops SSH connection with “Broken Pipe” IMMEDIATELY after successful login 2018-08-29

If the VM host is VMWare Fusion, see

https://lists.mindrot.org/pipermail/openssh-unix-dev/2018-August/037145.html

wherein it appears to have a bug in its networking stack that chokes
on the new default (valid) DSCP markings. If so you can work around
it by overriding the defaults, but the problem is within VMWare (maybe
in general, or maybe just the Fusion product).

sshd 7.8p1 close connection from VMware Fusion NAT Port Forwarding 2018-08-28

上面几篇文章提到是 VMware NAT 网络模式 的锅。

手动指定 ssh 参数 -o 'IPQoS=lowdelay throughput' 测试能修复连接失败的问题:

$ ssh -v -o 'IPQoS=lowdelay throughput' root@192.168.1.11
......
debug1: Next authentication method: publickey
debug1: Offering public key: RSA SHA256:emH3b5VRiPrFjzd1 /home/user/.ssh/id_rsa
debug1: Server accepts key: pkalg rsa-sha2-512 blen 535
debug1: Authentication succeeded (publickey).
Authenticated to 192.168.1.11 ([192.168.1.11]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug1: Sending env XMODIFIERS = @im=ibus
debug1: Sending env LANGUAGE =
Last login: Fri Aug 31 10:06:06 2018 from 10.20.3.5
[root@centos ~]#

用户 ~/.ssh/config 配置文件添加 IPQoS lowdelay throughput 选项:

$ head -n 3 ~/.ssh/config
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
IPQoS lowdelay throughput

针对全局 ssh 客户端可以修改 /etc/ssh/ssh_config.d/05-redhat.conf 配置:

# emacs -nw /etc/ssh/ssh_config.d/05-redhat.conf

Host *
        GSSAPIAuthentication yes

# Fix openssh 7.8p1 under VMware VM with NAT network caused "packet_write_wait: Connection to IP port 22: Broken pipe"
        IPQoS lowdelay throughput
        .....

ssh 客户端的问题算是解决了。

sshd 服务也有类似的问题,在 /etc/ssh/sshd_config 添加 IPQoS lowdelay throughput 选项即可。


本文标题升级到 openssh 7.8p1 后 ssh 连接报错 packet_write_wait: Broken pipe
原始链接https://lvii.github.io/system/2018-08-31-openssh-7.8p1-broken-pipe-under-vmware-vm-with-nat-port-forward/