How can I chroot sftp-only SSH users into their homes?
Solution 1
All this pain is thanks to several security issues as described here. Basically the chroot directory has to be owned by root
and can't be any group-write access. Lovely. So you essentially need to turn your chroot into a holding cell and within that you can have your editable content.
sudo chown root /home/bob
sudo chmod go-w /home/bob
sudo mkdir /home/bob/writable
sudo chown bob:sftponly /home/bob/writable
sudo chmod ug+rwX /home/bob/writable
And bam, you can log in and write in /writable
.
Solution 2
To chroot an SFTP directory, you must
-
Create a user and force root to be owner of it
sudo mkdir /home/john useradd -d /home/john -M -N -g users john sudo chown root:root /home/john sudo chmod 755 /home/john
-
Change the subsystem location on
/etc/ssh/sshd_config
:#Subsystem sftp /usr/lib/openssh/sftp-server Subsystem sftp internal-sftp
and create a user section at the end of the file (ssh can die respawning if placed after Subsystem line):
Match User john ChrootDirectory %h ForceCommand internal-sftp AllowTCPForwarding no X11Forwarding no
Solution 3
I spent the whole day trying to get a network share on my raspberry. I wanted to lock the user so that it would not be able to navigate through the whole file system, no ssh login access and I wanted to have write access to the network share.
And here is how I got it working:
First I created a user:
sudo useradd netdrive
Then edited /etc/passwd
and made sure it has /bin/false
for the user so the line was:
netdrive:x:1001:1004:Net Drive User,,,:/home/netdrive:/bin/false
I edited /etc/ssh/sshd_config
to include:
Match User netdrive
ChrootDirectory /home/netdrive
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
Changed home directory owner and permissions:
sudo chown root:root /home/netdrive/
sudo chmod 755 /home/netdrive/
Ok so after all this I was able to connect using sshfs
but in read only mode. What I had to do to get a writable folder:
sudo mkdir -p /home/netdrive/home/netdrive/
sudo chown netdrive:netdrive /home/netdrive/home/netdrive/
sudo chmod 755 /home/netdrive/home/netdrive/
That was it, it worked without any further changes. Note that I have only writable permissions to the user, not to the group as many other solutions online. I was able to create/delete/edit/rename files/folders without problems.
When accessing using sshfs
with the netdrive user because of chroot configuration I would only see things stored inside server's /home/netdrive/
directory, perfect. The repeated /home/netdrive/home/netdrive/
directory structure is what made it work for me in having a clean chroot ssh writable solution.
Now I am going to explain below the problems I had:
You should probably not execute the following paragraphs:
After looking at the above solutions (and many others on the net which even used acl (access control lists)) I was still not able to get it working because what I did next was:
The following did NOT work for me:
sudo mkdir /home/netdrive/writable/
sudo chown netdrive:netdrive /home/netdrive/writable/
sudo chmod 755 /home/netdrive/writable/
Because the netdrive user was still not able to write in that /home/netdrive/writable/
directory despite owning the folder and having the permissions. Then I did:
sudo chmod 775 /home/netdrive/writable/
And now I could create a directory and delete it but I was not able to edit it because it was being created without group writable permissions. Here from what I saw on the net people use acl
to fix it. But I was not happy with that since it I had to install acl
, then configure mount points, etc. Also I have no idea why I would need group permission to write to a folder owned by the same user.
It seems that for some reason creating /home/netdrive/home/netdrive
and giving ownership to the last netdrive
folder I was able to make everything work without messing with group permissions.
Solution 4
I followed this article but it didnt work. It started working after I made this change (suggested in above answers):
#Subsystem sftp /usr/lib/openssh/sftp-server
Subsystem sftp internal-sftp
Plus made the root ownable home directory under which I had user writable sub directory (as described above).
The new and useful thing I want to add with this answer is that you can simplify the configuration simply by specifying %h as user home directory:
ChrootDirectory %h
I have discovered it thanks to this link.
Related videos on Youtube
Oli
Hi, I'm Oli and I'm a "full-stack" web-dev-op. Eurgh. I'm also allergic to jargon BS. I spend most of my professional time writing Django websites and webapps for SMEs. I write a lot of Python outside of Django sites too. I administer various Linux servers for various tasks. I contribute to the open source projects that I use when I can. I'm a full-time Linux user and that has lead to helping other people live the dream. I am an official Ubuntu Member and I earnt my ♦ on SE's own Ask Ubuntu in 2011's moderator election. That's probably where I spend most of my unpaid time. I also run thepcspy.com which has been my place to write for the last decade or so. If you need to contact me for extended help, you can do so via my website, just remember that I have bills so if I feel your request is above and beyond normal duty, I might ask for remuneration for one-on-one support. For more social contact, you can usually find me (or just my computer) lurking in the Ask Ubuntu General Chat Room and on Freenode in #ubuntu and #ubuntu-uk under the handle Oli or Oli``.
Updated on September 18, 2022Comments
-
Oli almost 2 years
I want to give a client access to my server, but I want to limit those users to their home directories. I will bind-mount in any files I want them to be able to see.
I've created a user called
bob
and added him to a new group calledsftponly
. They have a home directory at/home/bob
. I've changed their shell to/bin/false
to stop SSH logins. Here is their/etc/passwd
line:bob:x:1001:1002::/home/bob:/bin/false
I've also changed the
/etc/ssh/sshd_config
to include the following:Match Group sftponly ChrootDirectory /home/%u ForceCommand internal-sftp AllowTcpForwarding no
When I try to log in as them, here's what I see
$ sftp bob@server bob@server's password: Write failed: Broken pipe Couldn't read packet: Connection reset by peer
If I comment out the
ChrootDirectory
line I can SFTP in but then they have free rein over the server. I have found thatChrootDirectory /home
works, but it still gives them access to any home directory. I have explicitly triedChrootDirectory /home/bob
but that doesn't work either.What am I doing wrong? How can I limit
bob
to/home/bob/
?----EDIT-----
Okay so I just had a look at
/var/log/auth.log
and saw this:May 9 14:45:48 nj sshd[5074]: pam_unix(sshd:session): session opened for user bob by (uid=0) May 9 14:45:48 nj sshd[5091]: fatal: bad ownership or modes for chroot directory component "/home/bob/" May 9 14:45:48 nj sshd[5074]: pam_unix(sshd:session): session closed for user bob
I'm not entirely sure what's going on there, but it suggests something is wrong with the user directory. Here is the
ls -h /home
output:drwxr-xr-x 26 oli oli 4096 2012-01-19 17:19 oli drwxr-xr-x 3 bob bob 4096 2012-05-09 14:11 bob
-
Admin over 8 yearsI believe
ChrootDirectory /home/%u
can be replacedChrootDirectory %h
.
-
-
shaunshd about 12 yearsThank you really useful. Two problems though. 1.) Even though I can't write, I can still browse the whole filesystem. 2.) Changing shell to /bin/false prevents SFTP completely. Am I doing something wrong?
-
Tom Harrison Jr almost 12 yearsThank you! Many other articles on this topic miss this detail, and some make it so the server cannot accept ssh connections (which kind of sucks when you're on EC2 and ... that's the only way).
-
Evan Plaice about 11 years@kim3er did you set your user's group to sftponly? If you don't, the ssh server won't match and chroot it. Try "usermod sftponly $USER". Also, /bin/false just removes SSH access. If you want a chrooted user to have ssh access there are more steps you'll need to take.
-
user134442 about 11 yearskim3er: this is because you need to set the user's shell to /sbin/nologin -- /bin/false disables any sort of access.
-
Shiki over 10 yearsI'd also like to note that all folders that lead to your chroot folder should be owned by
root
. In this example,/home
should also be owned by root. -
partofthething almost 9 yearsOn 14.04, I also had to change the
Subsystem sftp /usr/lib/openssh/sftp-server
line toSubsystem sftp internal-sftp -f AUTH -l VERBOSE
before this worked. -
Daniel almost 8 yearsthis doesn't seem to work. in your example, the user
john
is locked to the/home/john
directory. you have granted755
permissions to the directory. so the owner has read(4), write(2) and execute(1), and the group has read(4) and execute(1). you've also set the owner and group asroot
, sojohn
belongs to other. he also has read and execute (4+1=5) then. so you've locked john into a directory where he has no write privileges. how to fix this? changing privileges to757
or even777
breaks the login. changing the group or owner to john also breaks login. -
rwenz3l about 7 yearsalso to note: in /etc/ssh/sshd_config the configs are read in order. So if you have a rule for users in General and you want to overwrite one of them, just place the user-specific rule on top.
-
Primoz Rome almost 7 yearsI want to chroot an SFTP directory in some other user's home folder. I have userx at
/home/userx/sftproot/uploads
and sftpuser at /home/sftpuse. I have set chroot at/home/usex/sftproot
to be owned by root:root and chmod 755. The/home/usex/sftproot/uploads
is chown-ed by sftpuser:sftpuser. I get the same error as the initial question above. Does the chroot and all parent folders need to be owned by root:root in order for sftp to work? -
Andy Mercer over 6 yearsThis was the best description of this issue that I've found after about an hour spent trying and then Googling.
-
baramuse over 5 yearsSo it means there is no way of chrooting a user in a writeable directory : you have to have a subfolder with write permissions ?
-
warbi over 4 years@baramuse you could then "move" the user to the writable directory after login by using
ForceCommand internal-sftp -d /writable
in/etc/ssh/sshd_config
. They would still be able to browse back up to the read-only chroot dir though. Source -
rubo77 over 4 yearsThis is how you add the user
bob
to the group sftponly:adduser bob sftponly
-
rubo77 over 4 yearsOnce you are done, you can bind other directories into the home folder of the jail user with
mkdir /home/bob/localdir/; mount --bind /original/path /home/bob/localdir/
-
leonheess about 4 years+1 for
%h
............. -
Torxed about 4 yearsNot sure, but it feels like this answer is missing
chmod 750 /home/bob
, as bob still needs read permission after connecting, otherwise he won't see anything ifChrootDirectory /home/%u
is set. -
user1034912 almost 4 yearshow do you add john's password?
-
josircg almost 4 years@user1034912 "john" is a regular linux user. sudo passwd john