Update: The code below has been updated to reflect the changes identified in the marked answer, and is therefore working as expected.

I am trying to establish SFTP-only users on my server, that are jailed to their home directory. When attempting to connect to the server, I receive a broken pipe error:

debug1: Authentication succeeded (password).
Authenticated to xxxx.xxxxxxxx.com ([XX.XX.XX.XX]:22).
debug2: fd 5 setting O_NONBLOCK
debug3: fd 6 is O_NONBLOCK
debug1: channel 0: new [client-session]
debug3: ssh_session2_open: channel_new: 0
debug2: channel 0: send open
debug3: send packet: type 90
debug1: Requesting [email protected]
debug3: send packet: type 80
debug1: Entering interactive session.
debug1: pledge: network
debug3: send packet: type 1
packet_write_wait: Connection to XX.XX.XX.XX port 22: Broken pipe
Couldn't read packet: Connection reset by peer

I have determined that this is related to my attempts to jail the user. My sshd_config includes:

Subsystem sftp internal-sftp
Match Group sftponly
        ForceCommand internal-sftp -d /%u
        PasswordAuthentication yes
        ChrootDirectory /home/sftp
        PermitTunnel no
        AllowAgentForwarding no
        AllowTcpForwarding no
        X11Forwarding no

sftponly is the name of the group I created for sftp users. The owner and group of /home/sftp is root with only write-permission for the owner (0711).

$  chown root:root /home/sftp
$  chmod 0711 /home/sftp

Here is how I'm creating users (in this example, batman) -- note that I'm doing this via a Perl script, hence my use of chpasswd:

$  adduser --quiet --disabled-password --shell /bin/false --no-create-home --gecos "User" batman
$  echo "batman:batman123" | chpasswd
$  usermod -a -G sftponly batman
$  install -d -m 0755 /home/sftp/batman -o batman -g sftponly

Note: I'm manually creating the users home directory rather than passing the --system arg for adduser, as I end up getting an error when I later try and change the directory ownership:

chown: invalid group: ‘batman:batman’

If I update my sshd_config, and change the chroot directory to:

ChrootDirectory /home/sftp

I can successfully access the server and no longer receive the broken pipe error. However, I land in /home/sftp upon login, where I see a list of all other user directories, rather than landing in /home/sftp/batman as I would expect to happen.

How can I improve/fix this, such that users:

  • only have access to their own directory (/home/sftp/batman)
  • upon login, will appear to be within / (which is actually /home/sftp/batman)
  • cannot navigate to /home/sftp (so that they cannot see a list of other users)

1 Answer 1


I have managed to accomplish this by applying these permissions:

$  chown batman:sftponly /home/sftp/batman
$  chmod 0755 /home/sftp/batman
$  chmod 0711 /home/sftp

Then changing the ChrootDirectory from /home/sftp/%u to /home/sftp,

And lastly moving the user into their home directory upon login:

ForceCommand internal-sftp -d /%u

Now, when batman logs in, they land in /home/sftp/batman, which appears as /batman to the user. More importantly, if they attempt to back out into /home/sftp, they receive an error (thereby preventing them from see other user directories):

Directory /: permission denied - Failed to retrieve directory listing

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .