phpdisk虽说也能够限制用户上传文件的类型。但总有那么些自作聪明的主,把文件扩展名改了,然后上传。是故,魔高一尺,道高一丈。我写了这个脚本。目的就是赶尽杀绝!使用者注意杀伤力,以免波及无辜。
另外,脚本使用了最新版本的file-5.13命令,centos系统自带的file命令无法识别office 2007+的文档格式。所以,自己编译好文件再用我的脚本哦
#!/bin/bash # # # check-forbidden-files.sh - 一个检查用户上传文件格式的小脚本。每天5分钟 #执行一次。用于防止用户通过修改后缀名的形式上传非法文件。 # # 作者: 刘西洋 66954 # <locke@honliv.com> <xiyangliu1987@gmail.com> # http://www.xiyang-liu.com # # 软件自由,版权没有 # 创建时间:2013年2月26日一个阳光明媚的上午 # #¥¥¥¥¥¥¥¥¥¥程序设计思路¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥# # phpdisk通过限制文件选择框的形式限制用户上传文件爱你的格式。然而,比较 #聪明的用户会想到通过修改文件后缀名上传被禁止的文件。 #linux的file命令通过分析文件内容,而不是只看后缀名来判断文件类型。通过 #file命令依次检查当日用户上传的文件。凡是不合规范的都会被移动到特定的文件夹 #并以日志的形式记录用户ID和Email地址。并且在数据库中删除相应文件记录。 #$$$$$$$$$$$$$$$$$$$$$结束$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$# ##设置全局变量 DB_HOSTNAME="localhost" DB_PORT="3306" DB_USERNAME="phpdisk" DB_PASSWORD="PASS0D" DB_NAME="phpdisk" FILE_POOL_PATH=/srv/www/filestores/`date +%Y/%m/%d` FILE_CMD_PATH=/srv/file/bin/ TMP_DIR=/srv/tmp/ LOG_FILE=/srv/forbidden.log ##允许的文件类型列表:Office 1997-2003文件 Office 2007以上文档,PDF文档,jpeg,png,bmp格式照片,纯文本文件 declare permit_file_type=("Composite Document File V2 Document" "Microsoft Word 2007+" "Microsoft PowerPoint 2007+" "Microsoft Excel 2007+" "PDF document" "JPEG image data" "PC bitmap" "PNG image data" "text") ##输出所有文件的检测结果到临时文件中 cd $FILE_POOL_PATH $FILE_CMD_PATH/file `ls $FILE_POOL_PATH` > $TMP_DIR/file_cmd_output.txt ##循环检测,删除在允许文件列表中的条目。 type_i=0 type_len=${#permit_file_type[@]} while [ $type_i -lt $type_len ] do /bin/sed -i -e "/${permit_file_type[$type_i]}/d" $TMP_DIR/file_cmd_output.txt let type_i++ done ##输出过滤后剩余的文件条目,也就是非法文件类型的条目到 forbidden_file_name.txt cat $TMP_DIR/file_cmd_output.txt | /bin/cut -d ":" -f 1 >> $TMP_DIR/forbidden_file_name.txt ##根据不合法文件内容,从mysql中查询文件属主。记录到文件中。并把文件移动到特定目录 declare forbidden_file_name=(`cat $TMP_DIR/forbidden_file_name.txt | cut -d "." -f 1 | xargs` ) name_i=0 name_len=${#forbidden_file_name[@]} while [ $name_i -lt $name_len ] do SQL_GET_UID="select userid from pd_files where file_real_name='${forbidden_file_name[$name_i]}';" SQL_GET_USER_EMAIL="select email from pd_users where userid='$OWNER_ID';" SQL_DEL_FILE="delete from pd_files where file_real_name='${forbidden_file_name[$name_i]}';" OWNER_ID=`/usr/bin/mysql -sN -h $DB_HOSTNAME -P $DB_PORT -u $DB_USERNAME -p$DB_PASSWORD $DB_NAME -e "$SQL_GET_UID"` OWNER_EMAIL=`/usr/bin/mysql -sN -h $DB_HOSTNAME -P $DB_PORT -u $DB_USERNAME -p$DB_PASSWORD $DB_NAME -e "$SQL_GET_USER_EMAIL"` FULLNAME_FILE_NAME=`/bin/grep ${forbidden_file_name[$name_i]} $TMP_DIR/forbidden_file_name.txt` FULLNAME_FILE_TYPE=`$FILE_CMD_PATH/file -b $FULLNAME_FILE_NAME` mv `grep ${forbidden_file_name[$name_i]} $TMP_DIR/forbidden_file_name.txt ` /srv/forbidden_files/ echo "`date +%Y-%m-%d %H:%M` `grep ${forbidden_file_name[$name_i]} $TMP_DIR/forbidden_file_name.txt` $OWNER_ID $OWNER_EMAIL $FULLNAME_FILE_TYPE " >> /srv/forbidden.log mysqldump -h $DB_HOSTNAME -P $DB_PORT -u $DB_USERNAME -p$DB_PASSWORD $DB_NAME pd_files | sed -e 's#),(#)n(#g' | grep ${forbidden_file_name[$name_i]} >> $TMP_DIR/restore_deleted_file.sql /usr/bin/mysql -sN -h $DB_HOSTNAME -P $DB_PORT -u $DB_USERNAME -p$DB_PASSWORD $DB_NAME -e "$SQL_DEL_FILE" let name_i++ done ##移动记录文件列表,以备后查。 > $TMP_DIR/forbidden_file_name.txt mv $TMP_DIR/file_cmd_output.txt $TMP_DIR/`date +%Y%m%d%H%M`-file_cmd_output.txt echo ok
检查后,如果有误杀。或者领导介入了。你还可以通过移动文件回原位置,插入导出的条目到数据库来还原操作。具体我就不说了。相信你懂的。
大西洋
转载好歹著名出处。我表示深深的鄙视!