tl;dr: bad ssh config - check to see if you set ChrootDirectory in your global configuration settings and remove it
I spent a good 45mins on this problem and had to figure it out myself, so I figured I'd share with the world.
I was trying to ssh in to my home server and kept getting:
client_loop: send disconnect: Broken pipe
Looking this up online yielded no useful results - the most common reason that you encounter this message is that ssh killed the connection after a certain timeout. That was not my problem. I was getting this message immediately after connecting, and journalctl also gave me nothing useful, even with verbose or debug logging enabled.
It turns out that I had a bad configuration from setting up an sftp site. My ssh_config
file looked something like this:
ChrootDirectory %h
Subsystem sftp internal-sftp
Match User sftp_user
ChrootDirectory %h/uploads/
ForceCommand internal-sftp
AllowTcpForwarding no
This initial ChrootDirectory %h
was leftover from some previous editing. I was able to connect to my sftp site (but not regular ssh sessions) because the sftp_user settings were overriding the original ChrootDirectory.
The clue came when I tried to ssh in to root instead. I got:
Linux [My Hostname Here] #1 SMP PREEMPT_DYNAMIC [OS info here]
/bin/bash: No such file or directory
Connection to [hostname] closed.
/bin/bash definitely existed. That's when it clicked that ssh couldn't find /bin/bash because I had chroot'd to my home directory. I'm not sure why root gave me this message, while my regular user just gave me broken pipe
.
The solution was to remove that global-level ChrootDirectory
line, but keep the sftp settings. After that, I was able to ssh in just fine.
Hope this helps someone else with the same issue as me in the future