We want to set up a secure FTP server (let us call this 'the service', to avoid confusion). This service will receive
backups.
The service (and it's clients) don't need access to any unrelated commands. So we will make an empty PATH
and won't
let the users perform a normal login.
The service only needs to have access to one directory. We will attempt to restrict it to that directory by using the
chroot
utility ('change root') which will restrict the service's view of the server's filesystem. The service will
need to be able to find all it's dependencies as well. One complication is that this will entail having to place the
service and it's dependencies in a location that is not known to the normal system update service. I considered trying
to fix this by automatically copying the updated versions over the new versions and restarting the service, until I
realized a symlink would probably be much better.
As it turns out, there is a good but shallow tutorial over at
Debian Administration.
This tutorial shows the correct settings to set in /etc/ssh/sshd_config
.
These are 'Subsystem sftp internal-sftp' and
Match group sftponly
ChrootDirectory /home/%u
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
According to this tutorial, the system described there does not suffer from the mentioned update problems. We can use
this tutorial. Be sure to set 'AllowTcpForwarding no' so that your service cannot be used as a proxy.
Note that internal-sftp
is not the binary that we run, that is still the regular ssh server. It is an instruction to
use a version of the sftp service that can work in combination with chroot. Only that instruction will be run when a
user in sftponly
tries to use the service.
Unfortunately, there seems to be no way to have a user use a chrooted SFTP service while still allowing their accounts
to easily be used for other services. This is because one will want to let these other services store files in the
user's home directory, which the user will be able to access. This access is not always desired. The reason that one
cannot constrain the SFTP user to a specific directory in the home directory of the user, has to do with the proper
usage of access patterns when using chroot, and the access patterns enforced by sshd. If we want to use /home/%u
as
the chroot directory, we must allow only root to manipulate that directory. As a result, we need a directory that the
user has privileges in, let's make that /home/%u/sftp
. However, when the user connects to SFTP, they will be dropped
into their home directory, /home/%u
. We removed their privileges for this directory. To let the user be dropped into
/home/%u/sftp
instead, we need to make that their home directory. This makes it difficult to store files that should
not be accessible over SFTP.
Let's start setting up the service. First, we create a group sftponly
to which we will add the user accounts intended
for sftp. We remove the users from other groups /usr/sbin/sshd -d
which will give easy
access to debug logging. To allow the sshd to do it's work, we have to set chmod 755 /home/myuser/
and
chmod 755 /home/myuser/sftp
. Preferable I would only have let the owners interact with the intended directories,
using chmod -R o-rwx .
on /home/myuser. However, this will cause SFTP to malfunction; it cannot drop the user in the
user's directory, as it does not have access to it. We set the user's home directory to the files
directory inside
the user's SFTP root directory; usermod -d /sftp myuser
. At this point, the user will be dropped in
/home/%u/sftp/files
when they have succesfully connected. To stop the user from logging in over SSH, we disable
their shell; usermod -s /sbin/nologin myuser
. If the user tries to SSH, they will be told that 'This service allows
sftp connections only.'