I'm running a production server (Debian 10, standard OpenSSH package) that has Pure-FTPD running for legacy connections and SFTP for all our current connections. The SFTP server is setup with a chroot jail that logs via a bound device in the user's chroot jail. This is picked up by rsyslog and sent to /var/log/sftp.log, after which I am using logstash to parse that file and forward everything to a visualization server for our superusers. The superusers log into the visualization to see all SFTP and FTP/FTPS logs in one place.
The pure-ftpd logs are formatted in a way that our superusers like:
pure-ftpd: (testuser@hostname) [NOTICE] /home/ftpusers/testuser//outbound/testfile.pdf downloaded (1765060 bytes, 5989.55KB/sec)
This is great, because in a single line it shows the exact user and exact file that they uploaded or downloaded. However, for SFTP the situation is not as nice:
internal-sftp[8848]: session opened for local user testuser from [{ip_address}]
internal-sftp[8848]: opendir "/inbound"
internal-sftp[8848]: realpath "/inbound/."
internal-sftp[8848]: open "/inbound/testfile.pdf" flags WRITE,CREATE,TRUNCATE mode 0666
internal-sftp[8848]: close "/inbound/testfile.pdf" bytes read 0 written 1734445
In this case, the logs are easy to follow. testuser logs in, writes file, done. BUT we have many users logging in at a time, and logs from multiple instances of internal-sftp can occur at once. If this happens, the only way to track the activity for a user is to search for the username testuser, find the process ID that is logged (8848 in the example above) then find any messages that have that process ID. Many users are logging in via a cronjob, so this happens every 2 minutes or so...when we have 300 users logging in at regular intervals, you can imagine that hunting through this many process ID's would be a pain.
My Question
Is there a way to preface each log message from sftp-internal with the name of the user that is generating the log? This would have to work in a chroot jail. I cannot find anything about how to modify the message that rsyslog generates to include the username.
I would like to see something similar from my SFTP logs:
internal-sftp[8848]: (testuser) open "/inbound/testfile.pdf" flags WRITE,CREATE,TRUNCATE mode 0666
internal-sftp[8848]: (testuser) close "/inbound/testfile.pdf" bytes read 0 written 1734445
Current State of Configuration
My process chain goes:
ssh -> sftp-internal -> rsyslog (on local3.*) -> file /var/log/sftp.log -> logstash -> export to visualization server
Excerpt from my chroot group in /etc/ssh/sshd_config
Match Group sftpusers
ChrootDirectory %h
AuthorizedKeysFile %h/.ssh/authorized_keys
ForceCommand internal-sftp -f local3 -l INFO
# ForceCommand internal-sftp -l VERBOSE
AllowTcpForwarding no
X11Forwarding no
and my /etc/rsyslog.d/sftp.conf
local3.* -/var/log/sftp.log
Similar Questions:
This question is about SFTP logging to separate files, but it mentions this waybackmachine entry for an old article that included pretty-formatting SFTP log entries to look like standard xferlogs. The article mentions a Perl script (holy grail) that will format it for you, but alas, the link is dead. I could write a Python or Perl script that finds the specific message for transfers, grabs the process id, and reverse searches to find the user, then prints a reformatted xfer message with the username out to a file. But surely someone has solved this problem before and has a better solution.
Thank you for any help.