SFTP chroot

How to Setup Chroot SFTP in Linux (Allow Only SFTP, not SSH)

How to Setup Chroot SFTP in Linux (Allow Only SFTP, not SSH)

by Ramesh Natarajan on March 28, 2012

 
 
 

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.

—–

http://wiki.centos.org/HowTos/sftp

This SFTP setup is NOT chrooted, nor otherwise restricted against root connections

A minimal initial install was spun up. Then, the packages were installed beyond a minimal base install: rsync man and openssh-clients

[root@host-172-16-1-198 ~]# reset  [root@host-172-16-1-198 ~]# cat sftp-setup.txt       5  yum install rsync man      6  yum install openssh-clients     11  grep sftp /etc/services         12  cd /etc/sysconfig/              13  joe iptables                    14  vi iptables                     15  service iptables restart        18  passwd                          19  sftp localhost                  20  ssh localhost                   21  history > sftp-setup.txt     

We explicitly open the sftp port; it is not clear that this is required:

# Firewall configuration written by system-config-firewall  # Manual customization of this file is not recommended.    *filter                                                    :INPUT ACCEPT [0:0]                                        :FORWARD ACCEPT [0:0]                                      :OUTPUT ACCEPT [0:0]                                       -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT    -A INPUT -p icmp -j ACCEPT                                 -A INPUT -i lo -j ACCEPT                                   -A INPUT -i eth1 -j ACCEPT                                 -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport sftp -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited              -A FORWARD -j REJECT --reject-with icmp-host-prohibited            COMMIT 

This is the list of services running:

acpid           0:off   1:off   2:on    3:on    4:on    5:on    6:off  atd             0:off   1:off   2:off   3:on    4:on    5:on    6:off auditd          0:off   1:off   2:on    3:on    4:on    5:on    6:off crond           0:off   1:off   2:on    3:on    4:on    5:on    6:off ip6tables       0:off   1:off   2:on    3:on    4:on    5:on    6:off iptables        0:off   1:off   2:on    3:on    4:on    5:on    6:off netfs           0:off   1:off   2:off   3:on    4:on    5:on    6:off network         0:off   1:off   2:on    3:on    4:on    5:on    6:off restorecond     0:off   1:off   2:on    3:on    4:on    5:on    6:off rsyslog         0:off   1:off   2:on    3:on    4:on    5:on    6:off sendmail        0:off   1:off   2:on    3:on    4:on    5:on    6:off snmpd           0:off   1:off   2:on    3:on    4:on    5:on    6:off udev-post       0:off   1:on    2:on    3:on    4:on    5:on    6:off 

And proof of concept — note that we did NOT alter /etc/ssh/sshd_config in this example:

[roothost-172-16-1-198 ~]# sftp localhost  Connecting to localhost... root@localhost's password: sftp> ls sftp-setup.txt sftp> ls -l -rw-r--r--    1 root     root         1830 Oct 15 08:31 sftp-setup.txt sftp> quit [root@host-172-16-1-198 ~]# 

and ssh access:

[root@host-172-16-1-198 ~]# ssh localhost  root@localhost's password: Last login: Mon Oct 15 08:30:29 2012 from 10.16.1.106 [root@host-172-16-1-198 ~]# logout Connection to localhost closed. [root@host-172-16-1-198 ~]# 

Both ‚keyed ssh‘ authentication, and password based authentication will work. From a remote host, when the key is present, we are NOT challenged for the password. Then after an edit to disable the key from being offered remotely, we are then prompted for the password:

[herrold@centos-6 ~]$ # keyed ssh set up  [herrold@centos-6 ~]$ date Mon Oct 15 12:57:07 EDT 2012 [herrold@centos-6 ~]$ sftp root@10.16.1.194 Connecting to 10.16.1.194... sftp> ls sftp-setup.txt sftp> quit [herrold@centos-6 ~]$ # remove the key [herrold@centos-6 ~]$ sftp root@10.16.1.194 Connecting to 10.16.1.194... root@10.16.1.194's password: sftp> ls sftp-setup.txt sftp> quit [herrold@centos-6 ~]$ date Mon Oct 15 12:57:33 EDT 2012 [herrold@centos-6 ~]$ 

We do not address hardening issues here such as wrappers or more restrictive iptables rules, as they are out of scope of this article.