[RFC] Add xferlog line for each file transmitted

Holger Kiehl Holger.Kiehl at dwd.de
Fri May 1 20:49:46 AEST 2026


Hello,

since this is my first message to this list, I would like to
express my sincere gratitude to all the people that contributed
to this software, which I use every day since it was released.
Many thanks, it is a very valuable piece of software.

One aspect that I did not find a solution is to see who has
down- or uploaded files via SFTP. One could search for the ' close '
phrase in the log, but it is missing the IP/DNS. One can
search backwards for the pid, to then get the IP/DNS. However,
some transmitting process keep the connection open, even after
sending all files and wait for more files to come. So it could
have connected days back.

The solution I am using is that I change the openssh code to add
a line [xferlog] (a format used by many FTP servers) to easily get
all the information (IP/DNS, file, user + date) in one line,
see attachment (it patches successful to openssh-10.3p1).

It would be nice if I no longer need to always patch my openssh
server and this could be integrated in one form or another
to the current code.

Regards,
Holger
-------------- next part --------------
--- openssh-7.4p1/sftp-server.c.original	2016-12-19 05:59:41.000000003 +0100
+++ openssh-7.4p1/sftp-server.c	2018-01-12 14:39:24.191854122 +0100
@@ -439,11 +439,26 @@ static void
 handle_log_close(int handle, char *emsg)
 {
 	if (handle_is_ok(handle, HANDLE_FILE)) {
+		unsigned long long bytes_read = (unsigned long long)handle_bytes_read(handle),
+				   bytes_write = (unsigned long long)handle_bytes_write(handle);
+		char buf[64];
+		time_t t = time(NULL);
+
+		strftime(buf, sizeof(buf), "%a %b %d %H:%M:%S %Y", localtime(&t));
+
 		logit("%s%sclose \"%s\" bytes read %llu written %llu",
 		    emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ",
 		    handle_to_name(handle),
-		    (unsigned long long)handle_bytes_read(handle),
-		    (unsigned long long)handle_bytes_write(handle));
+		    bytes_read,
+		    bytes_write);
+		logit("[xferlog] %s 1 %s %llu %s b _ %c r %s 2 * %c",
+		    buf,
+		    client_addr == NULL ? "unknown" : client_addr,
+		    bytes_read != 0 ? bytes_read : bytes_write,
+		    handle_to_name(handle),
+		    (handle_to_flags(handle) & O_ACCMODE) != O_RDONLY ? 'o' : 'i',
+		    pw == NULL ? "?" : pw->pw_name,
+		    emsg == NULL ? 'c' : 'i');
 	} else {
 		logit("%s%sclosedir \"%s\"",
 		    emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ",


More information about the openssh-unix-dev mailing list