Script to email if upload/download/delete files over FTP

Status
Not open for further replies.

marian78

Patron
Joined
Jun 30, 2011
Messages
210
hi,
i want ask for help with my script, that email me, if somebody upload/download/delete files over FTP. For now i testing it, but want some critique, that i can tune up it.

How it works:

1. in Freenas box - FTP advanced tab, set this to make transfer log:
Code:
#FTP transfer file log - add to advanced ftp service this:
TransferLog /mnt/volume0/logs/transfer.log
LogFormat default "%a %h %l %u %t \\"%r\\" %s %b"
LogFormat auth "%v [%P] %h %t \\"%r\\" %s"
LogFormat write "%h %l %u %t \\"%r\\" %s %b"


2. next i wrote small script, that use "tail" for monitoring transfer log. If in transfer log is new line, script looking into this line and search for known names of ftp folders. If it find, add to this folder name email adress and posted this line to this email.
I have two groups of ftp folders - by send to email adress.
If script find folder but no email is defined for that folder, email is set to default.

Here is my script, that i will set as startup script after testing (FreeNAS-9.10-STABLE-201604261518 (881b70d)) and tuning (for now is setup as disabled cron jod and manually run) :
Code:
#!/bin/sh
#FTP transfer file log - add to advanced ftp service this:
#   TransferLog /mnt/volume0/logs/transfer.log
#   LogFormat default "%a %h %l %u %t \\"%r\\" %s %b"
#   LogFormat auth "%v [%P] %h %t \\"%r\\" %s"
#   LogFormat write "%h %l %u %t \\"%r\\" %s %b"

#case sensitive
#names of ftp dirs on ftp root are equal to ftp user names
users="dir1 dir2 dir3 dir4 dir5 dir6 dir7"

#dirs of ftpusers1 that email to tomail1
ftpusers1="dir1 dir2 dir3"

#dirs of ftpusers2 that email to tomail2
ftpusers2="dir4 dir5 dir6"

#ftpusers1 email adress
tomail1="test1@yourdomain.com"

#ftpusers2 email adress
tomail2="test2@yourdomain.com"

#default email if not exist any "users" in "ftpuser1" or "ftpuser2"
tomail3="test3@yourdomain.com"

#email from
frommail="from@yourdomain.com"

#subject prefix
subjectpre="my ftp server detect transport on:"

#ftp root dir
rootdir="/mnt/volume0/"

#FTP transfer file log - add to advanced ftp service this:
logfile="/mnt/volume0/logs/transfer.log"

#temp file
tmpfile="/mnt/volume0/scripts/ftpsendmail.tmp"


#start
#delete and backup transfer log after start script (start with clean transfer log file)
if test -f "$logfile";then
cp -p "$logfile" "$logfile".`date +%H.%M.%S_%d.%m.%Y.bak`
rm "$logfile";
fi

#wait for transferlog creation
while ! test -s "$logfile"; do
   sleep 60
done

while true; do
   #find changes in transferlog
   tail -F -n 0 $logfile | while read line; do
	
   #find ftpuser from line in transerlog and send email
   for user in $users; do	
	   if echo "$line" | grep -q $rootdir${user}; then

		 #assotiate mailto - "ftp user" vs "mail to"
		 if echo "$ftpusers1" | grep -q ${user}; then
		   tomail="$tomail1";
		 else
		   if echo "$ftpusers2" | grep -q ${user}; then
			 tomail="$tomail2";
		   else
			 tomail="$tomail3";
		   fi
		 fi

		 #temp file delete
		 if test -f "$tmpfile";then rm "$tmpfile"; fi
	
		 #prepare mail to temp file
		 (
		   echo "To: $tomail"
		   echo "From: $frommail"
		   echo "Subject: $subjectpre ${user}"
		   echo "Content-Type: text/html"
		   echo "MIME-Version: 1.0"
		   echo -e "\r\n"
		   echo "<pre style=\"font-size:14px\">"
		   echo "$line"
		 ) > $tmpfile
		 #send mail
		 sendmail -t < $tmpfile;
		 #delete temp file
		 rm "$tmpfile"
	   fi
	 done
   done
done
 
Last edited:

marian78

Patron
Joined
Jun 30, 2011
Messages
210
Today i little tune up, and wrote new script based on old one.
The difference are, that i delete some variables. Script use user preferences in freenas box for settings "tomail" email adresses.

So, all ftp users must have setup email adres in user preferences in FreeNAS box.
If there are some ftp folders (notftpusers) without setup ftp users, it will use as to-mail adres of default user (mailtoex).


Code:
#!/bin/sh
#how to generate FTP transfer log file - add this to advanced ftp service:
#   TransferLog /mnt/volume0/logs/transfer.log
#   LogFormat default "%a %h %l %u %t \\"%r\\" %s %b"
#   LogFormat auth "%v [%P] %h %t \\"%r\\" %s"
#   LogFormat write "%h %l %u %t \\"%r\\" %s %b"
#
#home folder of the ftp users must have same name as user name (ftp user "aaaa" have defined in user preferences "Home Directory" with name "aaaa" - "/mnt/your_volume/aaaa")
#user must have defined in preferences "E-mail" - Freenas box - "Account/Users/your_user"
#rootdir is path, where is ftp user home folder (if homefolder is "aaaa" then full path is "/mnt/your_volume/aaaa" and than rootdir is "/mnt/your_volume"
#rootdir is dataset
#if there are some ftp folders (notftpusers) without setup ftp users, it will use as to-mail adres of default user (mailtoex).


#all are case sensitive

#exclude from emailing
notftpusers="dir8 dir20 dir80"

#exclude send email to this user
mailtoex="defaultusername"

#mail from
frommail="from@yourdomain.com"

#subject prefix
subjectpre="my freenas ftp transfer in: "

#ftp root dir, with "/" on last place in path
rootdir="/mnt/your_volume/"

#FTP transfer file log - add to advanced ftp service this:
logfile="/mnt/your_volume/your_dataset_for_logs/transfer.log"

#temp files
tmpfile="/mnt/your_volume/your_dataset_for_scripts/ftpsendmail.tmp"

#start
#delete transfer log after post mails (prevent send duplicated mails if script start again)
if test -f "$logfile";then
   cp -p "$logfile" "$logfile".`date +%H.%M.%S_%d.%m.%Y.bak`
   rm "$logfile";
fi

#wait for transferlog creation
while ! test -s "$logfile"; do
   sleep 3
done

while true; do
   #find changes in transferlog and post mail
   tail -F -n 0 $logfile | while read line; do

	 #find all ftpdirs in ftp root folder
	 find $rootdir -maxdepth 1 -type d -exec echo {} \; | while read users; do

	   #for one dir from all dirs send email
	   for user in $users; do
		 #exclude rootdir path from testing (false positive)
		 if ! test $user = $rootdir; then
		   #find ftp dir/ftp user in line transfer log
		   if echo "$line" | grep -q ${user}; then
			 #only for ftp dir/ftp user with defined email in Freenas box
			 if ! echo "$notftpusers" | grep $user; then
			   #remove ftp root path from variable
			   to=${user#${rootdir}}
			 else
			   #email to default adress
			   to=$mailtoex
			 fi		
			 #temp file delete
			 if test -f "$tmpfile";then rm "$tmpfile"; fi		
			 #prepare mail to temp file
			 (
			   echo "To: $to"
			   echo "From: $frommail"
			   echo "Subject: $subjectpre $to"
			   echo "Content-Type: text/html"
			   echo "MIME-Version: 1.0"
			   echo -e "\r\n"
			   echo "<pre style=\"font-size:14px\">"
			   echo "$line"
			 ) > $tmpfile
			 #send mail
			 sendmail -t < $tmpfile;
			 #delete temp file
			 rm "$tmpfile"	
		   fi
		 fi	
	   done	
	 done
   done
done
 
Last edited:

marian78

Patron
Joined
Jun 30, 2011
Messages
210
Today i wrote some changes. Now you do not need define manually in script, if FTP datasets/FTP users, have defined email adresses in FreeNAS box. Script is look in to the file "/etc/mail/aliases", and search owner of FTP dataset (dataset name is equal to FTP user name that is his owner).

Code:
#!/bin/sh
#how to generate FTP transfer log file - add this to advanced ftp service:
#   TransferLog /mnt/volume0/logs/transfer.log
#   LogFormat default "%a %h %l %u %t \\"%r\\" %s %b"
#   LogFormat auth "%v [%P] %h %t \\"%r\\" %s"
#   LogFormat write "%h %l %u %t \\"%r\\" %s %b"
#
#home folder (datasets in volume) of the ftp users must have same name as user name (ftp user "aaaa" have defined in user preferences "Home Directory" with name "aaaa" - "/mnt/your_volume/aaaa")
#user must have defined in preferences "E-mail" - Freenas box - "Account/Users/your_user". If not, email is send to default user "mailtoex"
#rootdir is path, where is ftp users home folders (if homefolder is "aaaa" then full path is "/mnt/your_volume/aaaa" and than rootdir is "/mnt/your_volume"


#all are case sensitive

#email to default user "mailtoex" if they have defined emal adresses in "mailaliases"
notftpusers="user25 user60"

#default user - must have defined email adress in user preferences
mailtoex="root"

#mail from
frommail="from@yourdomain.com"

#subject prefix
subjectpre="My FreeNas box FTP transfer in: "

#ftp root dir, with "/" on last place in path
rootdir="/mnt/volume0/"

#FTP transfer file log - add to advanced ftp service this:
logfile="/mnt/volume0/logs/transfer.log"

#temp files
tmpfile="/mnt/volume0/scripts/ftpsendmail.tmp"

#where is stored FrreNAS box users email adresses
mailaliases="/etc/mail/aliases"

#start
#delete transfer log (prevent send duplicated mails if script start again)
if test -f "$logfile";then
   cp -p "$logfile" "$logfile".`date +%H.%M.%S_%d.%m.%Y.bak`
   rm "$logfile";
fi

#wait for transferlog creation
while ! test -s "$logfile"; do
   echo "FTP sendmail sleep"
   sleep 120
done

while true; do
   #find changes in transferlog and post mail
   tail -F -n 0 $logfile | while read line; do

	 #find all ftp datasets in ftp root folder
	 find $rootdir -maxdepth 1 -type d -exec echo {} \; | while read users; do

	   #for one dataset from all datasets
	   for user in $users; do
		 #exclude rootdir path from testing (false positive)
		 if ! test $user = $rootdir; then
		   #find ftp dataset/ftp user in line transfer log
		   if echo "$line" | grep -q ${user}; then
			 echo "find ftp dataset $user"
			 #remove ftp root path from variable
			 to=${user#${rootdir}}
			 #only for ftp dataset/ftp user with defined email in Freenas box
			 if grep $to $mailaliases; then
			   #if user have defined email adress but it is on exclude list
			   if echo "$notftpusers" | grep $to; then
				 to=$mailtoex
			   fi
			 else
			   #email to default adress if not have email adress
			   to=$mailtoex
			 fi		 
			 echo "email will be send to ${to}"
			 #temp file delete
			 if test -f "$tmpfile";then rm "$tmpfile"; fi
		 
			 #prepare mail to temp file
			 (
			   echo "To: $to"
			   echo "From: $frommail"
			   echo "Subject: $subjectpre $to"
			   echo "Content-Type: text/html"
			   echo "MIME-Version: 1.0"
			   echo -e "\r\n"
			   echo "<pre style=\"font-size:14px\">"
			   echo "$line"
			 ) > $tmpfile
			 echo "sending email"
			 #send mail
			 sendmail -t < $tmpfile;
			 #delete temp file
			 rm "$tmpfile"	   
		   fi
		 fi	   
	   done	   
	 done
   done
done
 
Status
Not open for further replies.
Top