If you want to setup an account on your system that will be used only to transfer files (and not to ssh to the system), you should setup SFTP Chroot Jail as explained in this article.
In a typical sftp scenario (when chroot sftp is not setup), if you use sftp, you can see root’s file as shown below.
If you want to give sftp access on your system to outside vendors to transfer files, you should not use standard sftp. Instead, you should setup Chroot SFTP Jail as explained below.
Non-Chroot SFTP Environment
In the following example (a typical sftp environment), john can sftp to the system, and view /etc folder and download the files from there.
# sftp john@thegeekstuff.com john@thegeekstuff's password: sftp> pwd Remote working directory: /home/john sftp> ls projects john.txt documents sftp> cd /etc sftp> ls -l passwd -rw-r--r-- 0 0 0 3750 Dec 29 23:09 passwd sftp> get passwd Fetching /etc/passwd to passwd /etc/passwd 100% 3750 3.7KB/s 00:00
Chroot SFTP Environment
In the following example, john can sftp to the system, and view only the directory that you’ve designated for john to perform sftp (i.e /incoming).
When john tries to perform ‘cd /etc’, it will give an error message. Since SFTP is setup in an chroot environment, john cannot view any other files in the system.
# sftp john@thegeekstuff.com john@thegeekstuff's password: sftp> pwd Remote working directory: /home/john sftp> ls sftp> cd /etc Couldn't canonicalise: No such file or directory
Now that you know what Chroot SFTP environment is, let us see how to set this up.
1. Create a New Group
Create a group called sftpusers. Only users who belong to this group will be automatically restricted to the SFTP chroot environment on this system.
# groupadd sftpusers
2. Create Users (or Modify Existing User)
Let us say you want to create an user guestuser who should be allowed only to perform SFTP in a chroot environment, and should not be allowed to perform SSH.
The following command creates guestuser, assigns this user to sftpusers group, make /incoming as the home directory, set /sbin/nologin as shell (which will not allow the user to ssh and get shell access).
# useradd -g sftpusers -d /incoming -s /sbin/nologin guestuser # passwd guestuser
Verify that the user got created properly.
# grep guestuser /etc/passwd guestuser:x:500:500::/incoming:/sbin/nologin
If you want to modify an existing user and make him an sftp user only and put him in the chroot sftp jail, do the following:
# usermod -g sftpusers -d /incoming -s /sbin/nologin john
On a related note, if you have to transfer files from windows to Linux, use any one of the sftp client mentioned in this top 7 sftp client list.
3. Setup sftp-server Subsystem in sshd_config
You should instruct sshd to use the internal-sftp for sftp (instead of the default sftp-server).
Modify the the /etc/ssh/sshd_config file and comment out the following line:
#Subsystem sftp /usr/libexec/openssh/sftp-server
Next, add the following line to the /etc/ssh/sshd_config file
Subsystem sftp internal-sftp
# grep sftp /etc/ssh/sshd_config #Subsystem sftp /usr/libexec/openssh/sftp-server Subsystem sftp internal-sftp
4. Specify Chroot Directory for a Group
You want to put only certain users (i.e users who belongs to sftpusers group) in the chroot jail environment. Add the following lines at the end of /etc/ssh/sshd_config
# tail /etc/ssh/sshd_config
Match Group sftpusers
ChrootDirectory /sftp/%u
ForceCommand internal-sftp
In the above:
- Match Group sftpusers – This indicates that the following lines will be matched only for users who belong to group sftpusers
- ChrootDirectory /sftp/%u – This is the path that will be used for chroot after the user is authenticated. %u indicates the user. So, for john, this will be /sftp/john.
- ForceCommand internal-sftp – This forces the execution of the internal-sftp and ignores any command that are mentioned in the ~/.ssh/rc file.
5. Create sftp Home Directory
Since we’ve specified /sftp as ChrootDirectory above, create this directory (which iw equivalent of your typical /home directory).
# mkdir /sftp
Now, under /sftp, create the individual directories for the users who are part of the sftpusers group. i.e the users who will be allowed only to perform sftp and will be in chroot environment.
# mkdir /sftp/guestuser
So, /sftp/guestuser is equivalent to / for the guestuser. When guestuser sftp to the system, and performs “cd /”, they’ll be seeing only the content of the directories under “/sftp/guestuser” (and not the real / of the system). This is the power of the chroot.
So, under this directory /sftp/guestuser, create any subdirectory that you like user to see. For example, create a incoming directory where users can sftp their files.
# mkdir /sftp/guestuser/incoming
6. Setup Appropriate Permission
For chroot to work properly, you need to make sure appropriate permissions are setup properly on the directory you just created above.
Set the owenership to the user, and group to the sftpusers group as shown below.
# chown guestuser:sftpusers /sftp/guestuser/incoming
The permission will look like the following for the incoming directory.
# ls -ld /sftp/guestuser/incoming drwxr-xr-x 2 guestuser sftpusers 4096 Dec 28 23:49 /sftp/guestuser/incoming
The permission will look like the following for the /sftp/guestuser directory
# ls -ld /sftp/guestuser drwxr-xr-x 3 root root 4096 Dec 28 23:49 /sftp/guestuser # ls -ld /sftp drwxr-xr-x 3 root root 4096 Dec 28 23:49 /sftp
7. Restart sshd and Test Chroot SFTP
Restart sshd:
# service sshd restart
Test chroot sftp environment. As you see below, when gusetuser does sftp, and does “cd /”, they’ll only see incoming directory.
# sftp guestuser@thegeekstuff.com guestuser@thegeekstuff's password: sftp> pwd Remote working directory: /incoming sftp> cd / sftp> ls incoming
When guestuser transfers any files to the /incoming directory from the sftp, they’ll be really located under /sftp/guestuser/incoming directory on the system.
Linux provides several powerful administrative tools and utilities which will help you to manage your systems effectively. If you don’t know what these tools are and how to use them, you could be spending lot of time trying to perform even the basic administrative tasks. The focus of this course is to help you understand system administration tools, which will help you to become an effective Linux system administrator.Get the Linux Sysadmin Course Now!
If you enjoyed this article, you might also like..
|
|
|
|






My name is Ramesh Natarajan. I will be posting instruction guides, how-to, troubleshooting tips and tricks on Linux, database, hardware, security and web. My focus is to write articles that will either teach you or help you resolve a problem. Read more about
{ 33 comments… read them below or add one }
Hi,
Nice post Ramesh Natarajan.
It helps for single sftp user environment … we can do like below in easy way also.
and also it works for multiple users also.
If we are using (openssh-server-4.3p2-30.el5) which is shipped in Red Hat enterprise Linux 5.4
1.Create a specific chrooted directory.
#mkdir /chroot/home
2.Mount it to /home as follows:
mount -o bind /home /chroot/home
3.Edit /etc/ssh/sshd_config as follows:
ChrootDirectory /chroot
Subsystem sftp internal-sftp
4.Save & Exit
4.service sshd restart
Regards,
Suresh
Hi,
Take into account that the match keyword is not supported in older versions (<5) on SSH so your solution will not work on for example RHEL 5.7 which has version 4.X installed. An upgrade of openssh will be necessary.
Kind regards,
Eric
To increase security just a little bit more: Add the rssh shell to this setup.
Hi,
Very Nice post
Thanks a lot for your nice topics….
Thanks for the post. Helped a lot
Very nice post, just in time to help me set up precisely this kind of access at my company.
Thank you!
nice post. But what does the acronmym “chroot” stand for. If you explain that it will make it easier to recall it in a few months.
chroot = change root directory, a chrooted service doesn’t ‘see’ the rest of the filesystem (well, roughly, there’s the headache of running binaries in a chrooted environment and whatnot, but that’s another story!)
good document and easy.thank
Great post !!!!!
Hi,
I am trying with server CentOS 6.2 with openssh 5.3 (Eric is right) and WinSCP client.
I have did everything exactly how it’s written here, but I am getting this error on the WinSCP client:
Error listing directory ‘incoming’
Permission denied.
Error code: 3
Error message from server: Permission denied
Request code: 11
Any ideas?
Hi Itamar..
I’m facing the same problem to not so long ago.. it turn out SELinux was the culprit. I did:
# setenforce 0 (press enter)
for more details here. and it works!! hope the same goes for you…..
Hi Soultani,
Thanks for the replay.
The Selinux is not the issue in my case, it is disabled.
FYI,I created a sub directory (under the user root-home) and gave the user full permissions, there the user is able to put his files. fine by me for now.
Hi Soultani,
Thanks for the replay. I have spend 3 days to resolve this issue thanks for your help
I sucessfully followed the instructions and it worked fine. Now I need to set the sftp user to connect without password, using certificates, but it doesn’t work. Any ideas?
Thanks
Marcos,
Make sure the following ownership and permissions are set for your chroot sFTP account (Example is based on the user information in Ramesh’s artical above). It’s important that the guestusers home is owned by root. The permissions are also important especially for the home dir, .ssh dir, and authorized_keys file.
# ls -ld ~guestuser
drwxr-x-r-x 5 root root 4096 Sep 25 17:11 /sftp/guestuser
#ls -al ~guestuser
drwxr-x-r-x 5 root root 4096 Sep 25 17:11 .
drwxr-x-r-x 5 root root 4096 Sep 25 17:11 ..
drwx——- 5 guestuser sftpusers 4096 Sep 25 17:11 .ssh
drwxr-x-r-x 5 guestuser sftpusers 126976 Sep 25 17:11 incoming
# ls -l ~ddtocai/.ssh
-rw——– 1 guestuser sftpusers 5522 Sep 25 17:11 authorized_keys
NOTE: To further troubleshoot your access issue, use the sftp command with the -v flag set to enable verbose mode of the command. This will show you all the intraction between the sftp site and the user attempting access. You can also startup another sshd daemon on your sftp site in debug mode to listen on another port without interruption to your current running sshd daemons. Do the following to accomplish this.
On the sftp device (you do not have to use port 3377, any open port will do):
# /usr/local/sbin/sshd -p 3377 -d
On the device attempting access:
# sftp -P 3377 -v guestuser@sftpdevice
The sshd daemon on port 3377 should exit after the first access attempt. If not use ctrl-c to exit.
Hi,
My requirement is like.. allow the user to sftp only but not SSH and want to share secure files eventually (either through hard liks/ soft links/ mount). I am fresh bee to RHEL with internal sftp, Please point me with the guidelines or solution ASAP.
Thanks. Had a problem with sftp. This solved it.
Thank you . Very clear and helpful.
Hi
I followed the instructions but on the ssh restart i got:
Starting sshd: /etc/ssh/sshd_config: line 131: Bad configuration option: Match
/etc/ssh/sshd_config: line 132: Bad configuration option: ChrootDirectory
/etc/ssh/sshd_config: line 133: Bad configuration option: ForceCommand
/etc/ssh/sshd_config: terminating, 3 bad configuration options
Do I need to upgrade ssh as suggested?
James,
Yes you have to upgrade your ssh version to at least 5.9 if I’m not mistaken.
Hi,
I used sshpass tool to connect to remote sshd service. its connecting to that when I run it from command line but not get connecting when I run the same command through shell script. It shown command not found. what might be the issue?
Raghav
Raghava,
Your script runs in a seperate shell from your user account. You’ll need to add the path to the sshpass app in your script.
Here is an example using tnsping. Just replace tnsping with sshpass for your use.
# which tnsping
/opt/oracle/bin/tnsping
Add the following line somewhere at the top of your script.
export PATH=$PATH:/opt/oracle/bin
NOTE: You’ll be replaceing /opt/oracle/bin with the path where sshpass was installed on your device.
Very nice tutorial, I only have one question; What is the /incoming folder for and what is the sftp/$user/incoming from? Why are we setting the newly created user’s home folder to /incoming in step 2 (“useradd -g sftpusers -d /incoming -s /sbin/nologin guestuser”) but then creating a sftp folder in step 5 (“mkdir /sftp/guestuser/incoming”). Are steps 2 and 5 alternatives? Or what is /incoming folder in step2 the just somehow linked to the /sftp/guestuser/incoming? I appologize if that should be obvious, I’m just a poor rails programmer forced to do server admin stuff
Ok, things seem to be working even without me understanding how the /income folder gets mapped to /sftp/$user/income as the user’s home directory, but now I have another question, about allowing (possibly even only) public key access. Where do I now put the .ssh/authorized_keys? Again, maybe a stupid question, moderator if you feel like other people find it too stupid to ask, would you maybe just throw me a quick answer to my email?
Also, one thing I had to change. Instead of using /sbin/nologin as user’s terminal, I had to change it to /usr/sbin/nologin, then it started working. I am on Ubuntu 10.04.
Works great. Thanks a lot for this.
For Ubuntu 12.04 I also had to use /usr/sbin/nologin for step 2
hi Ramesh, would like to ask. How about if we allow both sftp and ssh?
Hi
with the set up i have created a user and its is working fine, but my requirement is i have to share the user say Kumar’s directory for another user Raja so that they both will be sharing the file.ie /sftp/kumar ‘s directory for raja too so that they can share files. How to do this.
Fyi, setting the shell to /sbin/nologin doesn’t seem to matter. The internal-sftp bit seems to take care of restricting ssh, but it seems like best practice anyway.
Works great. Thanks a lot for this.
Linux 3.4.28-2.20-desktp
openSUSE 12.2 (x86_64) – KDE 4.10.00 “release 550″ openSSH 6.0p1-2.3.3-x86_64
Guys,
I think one of you found a similar problem:
[root@ippbxtest ~]# service sshd restart
Stopping sshd: [ OK ]
Starting sshd: /etc/ssh/sshd_config: line 121: Bad configuration option: Match
/etc/ssh/sshd_config: terminating, 1 bad configuration options
[FAILED]
[root@ippbxtest ~]# service sshd restart
Stopping sshd: [FAILED]
Starting sshd: /etc/ssh/sshd_config: line 121: Bad configuration option: Match
/etc/ssh/sshd_config: terminating, 1 bad configuration options
[FAILED]
[root@ippbxtest ~]# service sshd start
Starting sshd: /etc/ssh/sshd_config: line 121: Bad configuration option: Match
/etc/ssh/sshd_config: terminating, 1 bad configuration options
[FAILED]
[root@ippbxtest ~]# service sshd start
Starting sshd: /etc/ssh/sshd_config: line 121: Bad configuration option: Match
/etc/ssh/sshd_config: terminating, 1 bad configuration options
[FAILED]
[root@ippbxtest ~]# service sshd stop
Stopping sshd: [FAILED]
[root@ippbxtest ~]# service sshd start
Starting sshd: /etc/ssh/sshd_config: line 121: Bad configuration option: Match
/etc/ssh/sshd_config: terminating, 1 bad configuration options
[FAILED]
[root@ippbxtest ~]# service sshd stop
Stopping sshd: [FAILED]
[root@ippbxtest ~]# service sshd start
Starting sshd: /etc/ssh/sshd_config: line 121: Bad configuration option: Match
/etc/ssh/sshd_config: terminating, 1 bad configuration options
[FAILED]
I am using CentOS 5.8. I have no idea on what version of openssh comes with this CentOS version so openssh must be in older versions (<5).
Any suggestion apart from upgrading openssh?
Hi Pascual
rpm -qa | grep openssh
BTW whats in your /etc/ssh/sshd_config on line 121 ?
there a slightly differences in naming of sftp, s maybe u have to change it a bit.
@all , setenforce 0 is not really a solution it’s a dirty workaround.
you should set the policies accordingly
Not so long ago, I told you to disabled the SELinux…. well, not anymore.. Just now I found a good tutorial about it here. for more detail and sample about SELinux, you can watch this RedHat Summit . Hopefully this is clear up what we need to enable sftp withoud disabled the SELinux.