Updated: 12 October 2026 · Applies to: OpenSSH 10.2p1 with rsyslog 8.2512 on Ubuntu 26.04 (tested), OpenSSH 9.9p1 with rsyslog 8.2510 on AlmaLinux 10.2 (configuration tested); the same steps apply to Rocky Linux and RHEL 9 and 10, Ubuntu 24.04 and Debian 13
There is no separate SFTP log file by default. SFTP logins are logged together with SSH logins: in /var/log/auth.log on Ubuntu, in /var/log/secure on AlmaLinux, Rocky Linux and RHEL, and in the systemd journal everywhere (journalctl -u ssh, or -u sshd on the RHEL family). The files that users upload, download, rename or delete are not logged at all until you add -l INFO to the SFTP subsystem. The steps below turn that on and write the transfers to their own file, /var/log/sftp.log.
Where SFTP logins are logged by default
- Ubuntu:
/var/log/auth.log. rsyslog is part of a normal install (theubuntu-minimalpackage recommends it on 24.04 and 26.04). - Debian 12 and 13: according to Debian's release notes, rsyslog is no longer installed by default, so there is no auth.log. Use
sudo journalctl -u ssh. - AlmaLinux, Rocky Linux, RHEL:
/var/log/secure. sshd logs withSyslogFacility AUTHPRIV(set in/etc/ssh/sshd_config.d/50-redhat.conf), and rsyslog writesauthpriv.*to that file. Or usesudo journalctl -u sshd.
This is what one SFTP session looked like in auth.log on our Ubuntu 26.04 test server (timestamps removed, key fingerprint shortened):
sshd-session[1111]: Accepted publickey for alice from 127.0.0.1 port 51784 ssh2: ED25519 SHA256:9jAH... sshd-session[1111]: pam_unix(sshd:session): session opened for user alice(uid=1001) by root(uid=0) sshd-session[1123]: Received disconnect from 127.0.0.1 port 51784:11: disconnected by user sshd-session[1123]: Disconnected from user alice 127.0.0.1 port 51784 sshd-session[1111]: pam_unix(sshd:session): session closed for user alice
Nothing shows that this was SFTP rather than a shell, and no file names appear. Since OpenSSH 9.8 the login lines come from sshd-session, so search with grep sshd, which matches both names. With LogLevel VERBOSE in the sshd configuration you also get a line that names the subsystem: Starting session: subsystem 'sftp' for alice from 127.0.0.1 port 51788 id 0.
1. Log every SFTP file operation
- Create
/etc/ssh/sshd_config.d/10-sftp-logging.confwith the line for your system:# AlmaLinux, Rocky Linux, RHEL Subsystem sftp /usr/libexec/openssh/sftp-server -l INFO -f LOCAL3 # Ubuntu, Debian Subsystem sftp /usr/lib/openssh/sftp-server -l INFO -f LOCAL3
-l INFOlogs each operation (the default level is ERROR, which logs no transfers).-f LOCAL3uses the syslog facility local3, so the lines can go to their own file. Without-fthe facility is AUTH: the lines end up in auth.log on Ubuntu, and in/var/log/messageson AlmaLinux and Rocky Linux, because rsyslog there writes only authpriv to/var/log/secure. - Check and apply it. sshd uses the first
Subsystemline it reads, and theIncludeofsshd_config.dcomes before the default line, so you do not need to edit/etc/ssh/sshd_config:sudo sshd -t sudo sshd -T | grep subsystem sudo systemctl restart ssh # Ubuntu, Debian sudo systemctl restart sshd # AlmaLinux, Rocky Linux, RHEL
sshd -tprints nothing when the file is fine, andsshd -Tshould show your line:subsystem sftp /usr/lib/openssh/sftp-server -l INFO -f LOCAL3. - Write local3 to its own file. Create
/etc/rsyslog.d/10-sftp.conf:local3.* /var/log/sftp.log & stop
& stopkeeps these lines out of syslog and messages. Check and restart rsyslog:sudo rsyslogd -N1 sudo systemctl restart rsyslog
- Upload a test file and watch the log:
sudo tail -f /var/log/sftp.log.
On Debian without rsyslog, skip step 3 and read the same lines from the journal: sudo journalctl -t sftp-server (or install rsyslog with sudo apt install rsyslog).
2. Read the SFTP log
One session on our test server: upload, download, rename, new folder, delete (timestamps removed):
sftp-server[1186]: session opened for local user alice from [127.0.0.1] sftp-server[1186]: sent status No such file sftp-server[1186]: open "/home/alice/report.txt" flags WRITE,CREATE,TRUNCATE mode 0644 sftp-server[1186]: close "/home/alice/report.txt" bytes read 0 written 6 sftp-server[1186]: open "/home/alice/report.txt" flags READ mode 0666 sftp-server[1186]: close "/home/alice/report.txt" bytes read 6 written 0 sftp-server[1186]: posix-rename old "/home/alice/report.txt" new "/home/alice/report-old.txt" sftp-server[1186]: mkdir name "/home/alice/backups" mode 0777 sftp-server[1186]: remove name "/home/alice/report-old.txt" sftp-server[1186]: rmdir name "/home/alice/backups" sftp-server[1186]: session closed for local user alice from [127.0.0.1]
- Upload:
openwithWRITEflags, thenclosewith the bytes written. - Download:
openwithREAD, thenclosewith the bytes read. sent status No such filebefore an upload is the client checking whether the file already exists, not an error.- To see who it was, match the process number with the login lines in auth.log or secure.
-l VERBOSE adds every stat, lstat and realpath request, which makes the file much longer without telling you more about transfers. INFO is enough for an audit trail.
3. Chrooted SFTP users (internal-sftp)
Users locked into a folder with ChrootDirectory and ForceCommand internal-sftp (see how to create an SFTP-only chroot user) do not use the Subsystem line. They need two changes:
- Add the options to their ForceCommand, for example in the
Match Group sftponlyblock:ForceCommand internal-sftp -l INFO -f LOCAL3
- Give syslog a socket inside the chroot. In our test, step 1 alone logged nothing, because the chrooted process cannot reach
/dev/log; the sftp-server manual says the same. With rsyslog, create/etc/rsyslog.d/09-sftp-chroot.confwith one line per chroot folder:input(type="imuxsock" Socket="/srv/sftp/bob/dev/log" CreatePath="on")
Do not add amodule(load="imuxsock")line: the main configuration already loads it, and rsyslogd -N1 reports "module 'imuxsock' already in this config". Runsudo rsyslogd -N1, restart rsyslog, then sshd.
The lines then appear as internal-sftp, with paths seen from inside the chroot:
internal-sftp[1403]: session opened for local user bob from [127.0.0.1] internal-sftp[1403]: open "/upload/report.txt" flags WRITE,CREATE,TRUNCATE mode 0644 internal-sftp[1403]: close "/upload/report.txt" bytes read 0 written 6
4. Rotate the SFTP log
Create /etc/logrotate.d/sftp so the file does not grow forever, and test it with sudo logrotate -d /etc/logrotate.d/sftp:
/var/log/sftp.log {
weekly
rotate 8
compress
missingok
notifempty
postrotate
systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true
endscript
}
Client side: debug an SFTP connection
To see what your own sftp client does, add -v: sftp -v alice@203.0.113.10 prints debug lines such as debug1: Sending subsystem: sftp and, at the end, the bytes transferred. For sftp commands and keys, see how to use SFTP to transfer files securely; for other log files on a server, see common log file locations and the journalctl cheat sheet.
Official documentation: sftp-server manual, sshd_config manual and rsyslog imuxsock module.
Ucartz services for this topic
- KVM VPS hosting: NVMe SSD and full root access, with Free Basic Managed Support.
- Unmanaged dedicated servers: full root access and free IPMI KVM, with Free Basic Managed Support.
- Linux server management: hardening, patching, monitoring and automation for Ubuntu, Debian, RHEL and AlmaLinux.
