chrooted SFTP
Creating chroot
SFTP accounts
For
$DAYJOB
I had to create user accounts for customers
and give them access to
SFTP
files to/from secured areas of our server.
We wanted to use
chroot
functionality to ensure
that no customer could see other customers' data,
and prevent them from poking around
potentially sensitive areas of the server.
After a bit of trial-and-error,
I've listed the lessons-learned here
in a cook-book fashion
so that in case I ever have to do it again,
I have the steps documented.
This post was spurred to exist thanks to this Reddit post asking about creating an encrypted FTP server on OpenBSD so my reply there became the basis for this post.
Steps to reproduce
-
create the "sftp users" group,
which I'll refer to here as
customers
groupadd customers
-
create the new user,
the login-name for which I'll refer to as
$U
throughout the rest of this:adduser
and add them to thecustomers
group when prompted for the "other groups" or, if you have a pre-existing user, useusermod -Gcustomers $U
-
to put them in their own
chroot
we need to create a fake hierarchy in/home/$U/
so we'll end up with/home/$U/home/$U/
-
make a temporary "user" directory
and create the fake
/home
inside thatCHROOT="$(mktemp -d -p /home)" mkdir -p "${CHROOT}/home/"
-
set the permissions & ownership
on that fake hierarchy:
chown -R root:wheel "$CHROOT" chmod -R 0755 "$CHROOT"
-
move the user's old home directory under the chrooted
/home
mv -v "/home/$U" "$CHROOT"/home/
-
and then rename the chroot back to the original
/home/$U
directorymv -v "$CHROOT" "/home/$U"
-
while a bit confusing,
I found that some users expected to have
$SFTP
drop them in
/
and be able to do a relativecd home/$USER
while others expect to be dropped in their$HOME
so by adding a fakehome/$USER
that points to the right place, it allows for both of these. This might be optional, but helps me stave off customer script breakage:mkdir -p "/home/$U/home/$U/home" ln -s .. "/home/$U/home/$U/home/$U"
It might also stave off issues with the next step, since the home directory in/etc/passwd
can point to/home/$U/home/$U
regardless of whether in the chroot or not and still point to the right place. -
we've messed with their home directory,
so update
/etc/passwd
to reflect where things should find the home directory nowusermod -d "/home/$U/home/$U" "$U"
-
now the user is configured properly,
so let
sshd
know how to treat members of the customers group. Edit your/etc/ssh/sshd_config
to include this block at the end:Match Group customers ChrootDirectory /home/%u ForceCommand internal-sftp PermitTunnel no AllowTcpForwarding no AllowAgentForwarding no X11Forwarding no
I don't know whetherForceCommand
kills off the ability to doPermitTunnel
,AllowTcpForwarding
,AllowAgentForwarding
,X11Forwarding
, but I prefer to be explicit in my "just in case, no, you can't do that either". -
Send a
SIGHUP
tosshd
to pick up the new configuration:rcctl reload sshd
And with that, you should have chrooted SFTP access for $U
sftp user@hostname(if not, check the tail of your
/var/log/authlog
for hints).
However if you try to
ssh
,
scp
,
or
rsync
,
it should reject your efforts
at the point you've entered your credentials:
ssh user@hostname Password: Permission denied, please try again. ⋮ echo test > delme scp delme user@hostname: Password: Permission denied, please try again. ⋮
For additional customers,
you can repeat steps 2 through 9.
I've created a shell-script
to do those steps
as well as a bit of other administrivia for
$DAYJOB
but that should give you the basics.