14 October 2012

Config ftp server trigger upload file to call external script

In some previous, I can do post action on an http server, which means make a call to an external script after user has download a file, no matter success or failed of downloaded. Now I need to do the same thing but this time is with an ftp server. This time, after user has uploaded a file, the ftp server will execute an script corresponding. I have searched many time and found alot of ftp server but no one has kind of this function, include from vsftpd to proftpd.

Fortunately, at last I found something called "upload script" looks like the same the function that I need. Very thanks to pureftpd with this function. Pureftpd is an ftp server like vsftpd or proftpd but having a cool funtion named upload script which can be used to trigger upload file to call an external script after a file has been uploaded. I want this function to build up a virus/spyware scanner station and my intranet users just upload the untrusted file to the server by ftp.

I download and install pureftpd by yum/rpm command as usual, config it like other ftp server. By default pureftpd does use PAM authentication and not UnixAuthentication, if you want to use it with local account (/etc/passwd), you need to change the default configuration. Remember to restart the service for apply the change.

Server# vim /etc/pure-ftpd/pure-ftpd.conf

# PAMAuthentication yes
# If you want simple Unix (/etc/passwd) authentication, uncomment this
UnixAuthentication yes

Next I will enable the CallUploadScript function, by default this feature is not used. Take a look at the configuration file and enable it. Restart the service again.

Server# vim /etc/pure-ftpd/pure-ftpd.conf

CallUploadScript yes

I need to make a script which will be executed after a file has been uploaded. I will make a simple script named uploadscript.sh which will echo some string to an ftp.log file. This log will show what file has been uploaded. This is just an example one so the script is simple, in reality you can use it for more complex task, as call to other web service or take futher action.
Server# vim /tmp/uploadscript.sh

#!/bin/bash
echo "$1 has been uploaded" >> /tmp/ftp.log

$1 is an argurment represents for the filename which pure-uploadscript daemon will transfer to. Remember to set it with execution permission.

Server# chmod 755 /tmp/uploadscript.sh
Server# ls -al /tmp/uploadscript.sh 

-rwxr-xr-x 1 root root 56 Sep 26 15:01 /tmp/uploadscript.sh

pureftpd need to run a background proccess to trigger the upload file, take a look on man page to see how to daemon this. Run it with the argurment is the external script.

Server# man pure-uploadscript
Server# pure-uploadscript -B -r /tmp/uploadscript.sh

Check to see if the proccess is running background.

Server# ps aux | grep pure-upload

root 9798 0.0 0.0 13368 752 ? Ss pure-uploadscript -B -r /tmp/uploadscript.sh

Now I will upload some test file and see the result in the /var/log/message and ftp.log file.

Client# lftp ftpuser@10.254.10.33

Password: lftp ftpuser@10.254.10.33:~> put somefile.dat
52428800 bytes transferred

Server# tail /var/log/message

Sep 26 15:11:36 localhost pure-ftpd: (?@10.254.10.29) [INFO] New connection from 10.254.10.29
Sep 26 15:11:36 localhost pure-ftpd: (?@10.254.10.29) [INFO] ftpuser is now logged in
Sep 26 15:11:36 localhost pure-ftpd: (ftpuser@10.254.10.29) [NOTICE] /home/ftpuser//somefile.dat uploaded (52428800 bytes, 109268.39KB/sec)

Server# cat /tmp/ftp.log

/home/ftpuser/somefile.dat has been uploaded

As you see, the information of uploaded file ($1) has been writen to ftp.log file.