I'm trying to use goaccess log analysis tool, to analyse vsftpd FTP server's logs. I'm aware that being a web server log analyser, goaccess is not the best tool for this. That being said, it's flexible enough with the log format and we're already using it to analyse the web server's log, so I decided to give it a try.
By default vsftpd has a very chatty log:
Mon Mar 23 06:00:00 2020 [pid 11111] CONNECT: Client "1.1.1.1"
Mon Mar 23 06:00:00 2020 [pid 11111] [ftp] OK LOGIN: Client "1.1.1.1", anon password "blablabla"
Mon Mar 23 06:00:00 2020 [pid 11111] [ftp] FAIL DOWNLOAD: Client "1.1.1.1", "/file1", 0.00Kbyte/sec
Mon Mar 23 06:00:00 2020 [pid 11111] [ftp] OK DOWNLOAD: Client "1.1.1.1", "/file2", 17500 bytes, 203.15Kbyte/sec
As modern servers —usually— have single a line of log for a particular request, my first step was to change the logging to xferlog
format, which gives a single line per transfer.
# /etc/vsftpd.conf
xferlog_enable=YES
xferlog_std_format=YES
xferlog_file=/var/log/vsftpd.log
Now I have log lines like the following.
Sat Mar 28 06:00:00 2020 1 1.1.1.1 17500 /file1 b _ o a anonymous ftp 0 * c
Sat Mar 28 06:00:00 2020 1 1.1.1.1 0 /file2 b _ o a anonymous@host ftp 0 * i
As this is a download server only getting anonymous & passive FTP requests, I can assume the anonymous
and anonymous@host
are whatever the client provides for anonymous FTP.
How can I analyse this log with goaccess?
As mentioned in the vsftpd documentation, the xferlog format is shared among various server software. proftpd documents have a description of the format.
In a nutshell the fields in each line are called:
So your example,
corresponds to these fields:
Now we can try mapping the various log fields to what goaccess accepts, taking a close look at the units, and ignoring anything that is not applicable with the %^ format specifier:
date-format %a %b %d
andtime-format %H:%M:%S
.transfer-time
is logged in seconds, while goaccess only supports micro- or milli-second resolution, so we'll have to ignore it.remote-host
is one of the mandatory goaccess options, and is %hfile-size
maps cleanly to %b in bytes.filename
is the raw URL path(%U), as the full http request %r won't be usefulusername
is random junk, but we'll match to %e for completenesscompletion-status
would have been nice to use this as status, but goaccess expects HTTP status codes, so ignoredtransfer-type
,special-action-flag
,direction
,access-mode
,service-name
,authentication-method
,authenticated-user-id
won't be usedThe combined config for parsing the xferlog in goaccess will be:
Save these lines in a file(
~/.goaccessrc
) and pass it to goaccess with: