Logging Chrooted SFTP user activity

Solution 1:

Your assumption that /dev/log is a file that can be shared via bind-mounting /dev is incorrect for most modern linux distributions using systemd. Therefore, mounting your systems /dev into your chroot has little value.

$ file /dev/log
/dev/log: symbolic link to /run/systemd/journal/dev-log

Since /run is not available like that in the chroot (and should not be), sftp-server trying to write to /dev/log will consider that a broken symlink.

Instead, use input(type="imuxsock" Socket="/opt/bindmount/dev/log") to create an additional socket (which you can then bind-mount such that all chroots see it at /dev/log).

You generally should not share full /dev access to chroot anyway, the whole point of chroot is limiting attack surface.


Bonus: You can write your /etc/rsyslog.d/10-sftp.conf config like this (filter by "host name", which you can arbitrarily choose)

input(type="imuxsock" Socket="/opt/bindmount/dev/log", HostName="sftp")
if $hostname == 'sftp' then /var/log/sftp.log
&stop

This means that if you deploy other chroots, limited to other commands (such as a git-shell), you can still have all messages from chroot in the same spot, even if other programs write to /dev/log.

Solution 2:

If you do not use rsyslogd and use only journald from systemd, you can do the following (source https://wiki.archlinux.org/index.php/SFTP_chroot#Logging)

(Please replace <OPENSSH_CHROOT_PATH> with the chroot path configured in openssh, ie: in your case : /home/sftp/%u)

# mkdir /<OPENSSH_CHROOT_PATH>/dev
# chmod 755 /<OPENSSH_CHROOT_PATH>/dev
# touch /<OPENSSH_CHROOT_PATH>/dev/log

And bind-mount journald socket with :

# mount --bind /run/systemd/journal/dev-log /<OPENSSH_CHROOT_PATH>/dev/log

And If you need it permanently, do not forget to add this bind-mount in your /etc/fstab with :

/etc/fstab:

(…)
/run/systemd/journal/dev-log /<OPENSSH_CHROOT_PATH>/dev/log none bind   0   0
(…)

You can now see internal-sftp logging with journalctl :

# journalctl -f