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