Accessing files inside the directory of a virtual host, e.g. to troubleshoot code issues, is classically a domain of FTP. Since we don’t want to introduce the detriments of FTP in our setup, we will be using internal-sftp, a subsystem of the ssh-daemon.
We will want to allow sftp-Access to our server only when required and jail the users in the directory using change root. Using this approach users will not gain access to a shell via ssh, they will be restricted to sftp.
The first step is to activate the sftp functionality in
#Subsystem sftp /usr/lib/openssh/sftp-server Subsystem sftp internal-sftp -f LOCAL4 -l INFO
Since we want to enable sftp access for our users restrictively, we will use a matching rule for them in the ssh daemon’s configuration. The user vhost1 below will be allowed access to sftp, chrooted to a specific directory, but disallowed other functions of ssh:
# User-specific configuration for SFTP Match User vhost1 ForceCommand internal-sftp -f LOCAL4 -l INFO PasswordAuthentication yes ChrootDirectory /var/www/example.com/subdir PermitTunnel no AllowAgentForwarding no AllowTcpForwarding no X11Forwarding no
We need to make sure that all directories for the ChrootDirectory
are owned by root:
, otherwise ssh will refuse to change into the jail.
At session startup sshd(8) checks that all components of the pathname are root-owned directories which are not writable by any other user or group. After the chroot, sshd(8) changes the working directory to the user’s home directory.
Conversely setting root: permissions on our chroot directory may prevent applications such as WordPress from updating their core since they will not be able to write to their root directory.
rsyslog Configuration
There are some modifications required in order to enable syslog logging of chrooted process. We will add a new logging socket to our jail using
$AddUnixListenSocket /var/www/leuxner.net/kb/dev/log
The socket directory needs to be created manually:
mkdir -m2755 /var/www/leuxner.net/kb/dev
Finally we will add a specific rule to log the sftp-sessions to a separate file:
# internal-sftp local4.info -/var/log/sftp/sftp.info
Recent versions will allow for automatic socket creation. Please take note that there is a limitation on how many chrooted sockets the demon will handle.
input(type="imuxsock" Socket="/var/www/leuxner.net/kb/dev/log" CreatePath="on") local4.* -/var/log/sftp/sftp.log