Originally published November 8, 2016 @ 11:19 pm

I have an FTPS server running VSFTP and below is collection of commands useful for monitoring activity and analyzing the logs.

Watching user connection processes:

watch -n 5 "ps -C vsftpd -o user,pid,stime,cmd | grep '[0-9]/'"

Watching user network connections:
watch -n 5 "netstat -tunapT | egrep --line-buffered 'ESTABLISHED.*vsftpd'"

Show process name, PID, and file descriptor for each open FTP connection:
ss --processes --numeric --resolve --options state established not dst $(ip -o -f inet addr show | awk '/scope global/ {print $4}') and not dst 127.0.0.1 | sed -re "s/[[:space:]]\+/ /g" -e 's/::ffff://g' -e 's/timer:\([0-9a-z,]{1,}\)//g' | awk '{print $3,$4,$5}' | grep -v ^Local | grep vsftpd | column -t

Show output of ps -ef for each user connection process:
ss --processes --numeric --resolve --options state established not dst $(ip -o -f inet addr show | awk '/scope global/ {print $4}') and not dst 127.0.0.1 | sed -re "s/[[:space:]]\+/ /g" -e 's/::ffff://g' -e 's/timer:\([0-9a-z,]{1,}\)//g' | awk '{print $3,$4,$5}' | grep -v ^Local | column -t | egrep -o ",[0-9]{1,}," | sed -e 's/,//g' | sort -u | while read pid ; do ps -ef | grep ${pid} | grep -v grep | egrep "vsftpd:.*[0-9]\/"; done | sort -u

Checking per-user bandwidth utilization:
u=$(ps -C vsftpd -o user,pid,stime,cmd | egrep -o '\.[0-9]{1,3}/[[:alnum:]]+' | awk -F'/' '{print $NF}' | sort -u | sed ':a;N;$!ba;s/\n/|/g')
if [ ! -z "${u}" ]; then
watch -n 4 "nethogs -d 2 -c 1 -t -v 0 2>/dev/null | egrep \"/(${u}):\sRETR\" | sed -r 's/\s([0-9]{1,}\.[0-9]{1,})\s([0-9]{1,}\.[0-9]{1,})/,,/g' | (echo ".,,,DOWN KB/s,UP KB/s" && cat) | column -s ',' -t"; fi

Get VSFTP server login and transfer statistics:
log="/var/log/vsftpd.log" ; k=0 ; array=( "OK LOGIN" "FAIL LOGIN" "OK DOWNLOAD" "FAIL DOWNLOAD" "OK UPLOAD" "FAIL UPLOAD" ) ; for d in {7..0}; do date -d "`date +'%Y-%m-%d'` - $d days" +'%b %-d'; done | while read d ; do if [ ${k} -eq 0 ] ; then echo -ne "PERIOD," ; printf "%s," "${array[@]}" | sed 's/,$//g' ; echo "" ; k=1 ; fi; j=1 ; for i in "${array[@]}" ; do p="\] ${i}"; eval "$(echo c${j})"=$(zgrep -E "${p}" "${log}"* | tr -s ' ' | cut -d: -f2- | grep -c "${d} ") ; (( j = j + 1 )) ; done; echo -ne "`date -d "${d}" +'%Y-%m-%d'`," ; for j in $(seq 1 `echo "${#array[@]}"`) ; do eval echo -ne $(echo $`eval echo "c${j},"`); done | sed 's/,$//g' ; echo "" ; done | column -s ',' -t

Sample output:
PERIOD      OK LOGIN  FAIL LOGIN  OK DOWNLOAD  FAIL DOWNLOAD  OK UPLOAD  FAIL UPLOAD
2016-11-01  0         0           0            0              0          0
2016-11-02  0         0           0            0              0          0
2016-11-03  0         0           0            0              0          0
2016-11-04  0         0           0            0              0          0
2016-11-05  0         0           0            0              0          0
2016-11-06  0         0           0            0              0          0
2016-11-07  1         0           0            0              0          0
2016-11-08  15        0           6            1              0          0

For more VSFTP log analysis examples, read Log Event Time Distribution