вторник, 19 июля 2016 г.

Использование Phishtank в ufdbGuard при работе со свободными блоклистами

Как известно, ufdbGuard в своем коммерческом блоклисте содержит базу Phishtank, обновляемую на регулярной основе.

Сам ufdbGuard имеет открытый код и может быть использован с любым доступным в виде плоскотекстовых файлов (plain-text) блоклистами. Однако, в этом случае, о подключении базы Phishtank вам следует позаботиться самостоятельно.

Так как сам автор не может (ввиду конфликта интересов) давать советы о применении некоммерческих блоклистов, сделаю это за него.

Я достаточно давно применяю в своих инсталляциях прокси Shallalist. Хотя авторы коммерческих блоклистов отзываются о нем довольно пренебрежительно, опыт показывает, что он достаточно регулярно обновляется (хотя удаление неактуальных ссылок идет далеко не так активно, как добавление, что ведет к распуханию листа), достаточно эффективен в повседневном бизнес-применении и компилируется в весьма компактные и быстро работающие базы ufdbGuard. 

Сравнительно легко оказалось добавить в него поддержку Phishtank. Phishtank довольно активно поддерживается сообществом, в настоящее время бесплатен к любому применению, и содержит как фишинговые домены, так и URLы. При использовании ufdbGuard версии 1.32 (в настоящее время rc7, еще не выпущен релиз) и домены и URLы компилируются в единые базы в формате gZip, и весьма эффективно работают.

Итак, для начала нужно зарегистрироваться на Phishtank.

Регистрация необходима для получения Developer API key с целью автоматизированной скачки упакованного списка. Затем на этой странице надо выбрать нужный формат и сформировать для себя собственный URL для загрузки с собственным ключом, по этой ссылке ваш скрипт будет автоматически забирать список каждый час (обновления могут происходить достаточно часто, будете обновляться реже - снижается защита, чаще - задолбаете сервер Phishtank и вас в гневе могут побанить).

Так как прямое использование скачанного списка невозможно, потребуется некоторое преобразование полученных данных в вид, пригодный для компиляции в базу ufdbGuard. Напишем для этой задачи скрипт update_phishtank.sh:

 #!/sbin/sh  
   
 # By accepting this notice, you agree to be bound by the following  
 # agreements:  
 #  
 # This script written by Yuri Voinov (C) 2010,2016  
 #  
 # This program is free software; you can redistribute it and/or modify it  
 # under the terms of the GNU General Public License (version 2) as  
 # published by the Free Software Foundation. It is distributed in the  
 # hope that it will be useful, but WITHOUT ANY WARRANTY; without even the  
 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  
 # PURPOSE. See the GNU General Public License (GPL) for more details.  
 #  
 # You should have received a copy of the GNU General Public License  
 # (GPL) along with this program.  
   
 #  
 # ufdbGuard phishtank update  
 #  
 # Based on shalla_update.sh, v 0.3.1 20080403  
 # and update_blocklist.sh, v 1.1-1.9 by Y.Voinov.  
 #  
 # ident  "@(#)update_phishtank.sh   1.0   28/06/16 YV"  
 #  
   
 #############  
 # Variables #  
 #############  
   
 # Key  
 KEY="94e1ed31858910e63d0c5e344a5672254037421f27ad5b4636f6d1420dea13b4"  
   
 # Modify PATH for SFW directory use  
 PATH=/usr/sfw/bin:$PATH  
   
 # List name  
 LIST_NAME="online-valid.csv.gz"  
   
 # Servers for downloading blacklist  
 SERVER1="http://data.phishtank.com/data/$KEY/$LIST_NAME"  
 SERVER2=""  
   
 SERVER_LIST="$SERVER1 $SERVER2"  
 TEMP_DIR="/tmp"  
 WORK_DIR="$TEMP_DIR/phishtank"  
   
 # Connection timeout for downloading  
 TIMEOUT=30  
   
 # Redirector user name  
 RDR_USER="ufdb"  
 RDR_GROUP="ufdb"  
   
 # Installation base dir  
 BASE="/usr/local"  
 # Redirector dir base  
 BASE2=$BASE"/ufdbguard"  
 # Redirector blacklist base  
 BASE3=$BASE2"/blacklists"  
   
 DIR_CUSTOM2=$BASE3"/phishtank"  
   
 # OS utilities  
 AWK=`which awk`  
 CAT=`which cat`  
 CHMOD=`which chmod`  
 CHOWN=`which chown`  
 CUT=`which cut`  
 ECHO=`which echo`  
 FIND=`which find`  
 GREP=`which grep`  
 GZCAT=`which gzcat`  
 ID=`which id`  
 MKDIR=`which mkdir`  
 PRINTF=`which printf`  
 RM=`which rm`  
 SED=`which sed`  
 SORT=`which sort`  
 TAIL=`which tail`  
 TOUCH=`which touch`  
 UNIQ=`which uniq`  
 WGET=`which wget`  
   
 ###############  
 # Subroutines #  
 ###############  
   
 root_check ()  
 {  
  if [ ! `$ID | $CUT -f1 -d" "` = "uid=0(root)" ]; then  
  $ECHO "ERROR: You must be super-user to run this script."  
  exit 1  
  fi  
 }  
   
 checkuser ()  
 {  
 # Check redirector user  
  username=$1  
  if [ ! -z "`$CAT /etc/passwd | $GREP $username`" ]; then  
  $ECHO "1"  
  else  
  $ECHO "0"  
  fi  
 }  
   
 check_clean ()  
 {  
 # Check that everything is clean before we start  
  if [ -f $WORK_DIR/$LIST_NAME ]; then  
  $PRINTF "Old blacklist file found in ${WORK_DIR}..."  
  $RM $WORK_DIR/$LIST_NAME  
  $ECHO "Deleted."  
  fi  
 }  
   
 set_permission ()  
 {  
 # Setting files permissions  
  if [ "`checkuser $RDR_USER`" = "1" ]; then  
  $PRINTF "\nSetting files permissions..."  
  $CHOWN -R $RDR_USER:$RDR_GROUP $BASE3  
  $CHMOD 755 $BASE3  
  cd $BASE3  
  $FIND . -type f -exec $CHMOD 644 {} \;  
  $FIND . -type d -exec $CHMOD 755 {} \;  
  else  
  $ECHO "ERROR: User $RDR_USER does not exists. Exiting..."  
  exit 5  
  fi  
 }  
   
 download_list ()  
 {  
  # Make working directory  
  if [ ! -d $WORK_DIR ]; then  
  $PRINTF "Make working directory..."  
  $MKDIR -p $WORK_DIR  
  $ECHO "Done."  
  fi  
  # Get list from one server using server list  
  $PRINTF "List downloading..."  
  for S in $SERVER_LIST; do  
  $WGET -T $TIMEOUT -q -O $WORK_DIR/$LIST_NAME $S  
  retcode=`$ECHO $?`  
  case "$retcode" in  
   0)  
   $ECHO "List downloaded successfully."  
   break  
   ;;  
   4)  
   $ECHO "Unable to resolve host address. Exiting..."  
   exit 4  
   ;;  
   *)  
   $ECHO "Error downloading list from `$ECHO $S|$CUT -f1 -d '/'`. Try another server..."  
   continue  
   ;;  
  esac  
  done  
   
  if [ "$retcode" != "0" ]; then  
  $ECHO "Error downloading list from all servers. Exiting..."  
  exit 1  
  fi  
   
  # If destination directory not exists, lets create it  
  if [ ! -d "$DIR_CUSTOM2" ]; then  
  $MKDIR -p $DIR_CUSTOM2  
  fi  
   
  # List transformation  
  $GZCAT $WORK_DIR/$LIST_NAME | $TAIL -n +2 | $AWK -F',' '{ print $2 }'| $SED -e 's/"//' | $SED -e 's/^https\?:\/\///' | $SORT | $UNIQ -u > $DIR_CUSTOM2/domains  
  # Update time for file  
  $TOUCH $DIR_CUSTOM2/domains  
  # Set permissions  
  set_permission  
 }  
   
 clean_up ()  
 {  
 # Clean up file and directories  
  $PRINTF "Clean up downloaded file and directories..."  
  $RM -rf $WORK_DIR  
  $ECHO "Done."  
 }  
   
 ##############  
 # Main block #  
 ##############  
   
 # Root check  
 root_check  
   
 # Check working directory clean  
 check_clean  
   
 # Download list  
 download_list  
   
 # Clean up  
 clean_up  
   
 exit 0  
 #####  

Все необходимые редактируемые параметры находятся в начале скрипта. Предполагается, что выгрузка и преобразование листа производится в директорию /usr/local/ufdbguard/blacklists/phishtank. Вы можете изменить это по своему усмотрению. В переменную KEY впишете ваш собственный полученный ранее API key.

Обратите внимание - данный скрипт скачивает, трансформирует в плоский файл и записывает список Phishtank, устанавливает правильные права для редиректора. Но и только. Ни компиляции листа в формат ufdbGuard, ни перезапуска редиректора он не производит.

Лично я не использую вышеприведенный скрипт непосредственно, а вызываю его из написанного несколько лет назад скрипта, используемого для автоматизированного обновления списка Shallalist update_blocklist.sh:

 #!/sbin/sh  
   
 # By accepting this notice, you agree to be bound by the following  
 # agreements:  
 #  
 # This script written by Yuri Voinov (C) 2010,2016  
 #  
 # This program is free software; you can redistribute it and/or modify it  
 # under the terms of the GNU General Public License (version 2) as  
 # published by the Free Software Foundation. It is distributed in the  
 # hope that it will be useful, but WITHOUT ANY WARRANTY; without even the  
 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  
 # PURPOSE. See the GNU General Public License (GPL) for more details.  
 #  
 # You should have received a copy of the GNU General Public License  
 # (GPL) along with this program.  
   
 #  
 # ufdbGuard blocklist update  
 #  
 # Based on shalla_update.sh, v 0.3.1 20080403  
 # and update_blocklist.sh, v 1.1-1.9 by Y.Voinov.  
 #  
 # ident  "@(#)update_blocklist.sh   2.0   28/06/16 YV"  
 #  
   
 ## NOTE: You can select redirector compilation categories by edit CATEGORIES variable for compilation.  
   
 #############  
 # Variables #  
 #############  
   
 # ------------- Blacklist options ------------------  
 CATEGORIES="adv anonvpn costtraps dating drugs fortunetelling gamble hacking hobby/games-misc hobby/games-online models movies music porn redirector sex/lingerie socialnet spyware tracker updatesites urlshortener warez webradio webtv"  
 # ------------- Blacklist options ------------------  
   
 # Modify PATH for SFW directory use  
 PATH=/usr/sfw/bin:$PATH  
   
 # List name  
 LIST_NAME="shallalist.tar.gz"  
   
 # Servers for downloading blacklist  
 SERVER1="http://www.shallalist.de/Downloads/$LIST_NAME"  
 SERVER2=""  
   
 SERVER_LIST="$SERVER1 $SERVER2"  
 TEMP_DIR="/tmp"  
 WORK_DIR="$TEMP_DIR/shalla"  
   
 # Connection timeout for downloading  
 TIMEOUT=30  
   
 # SMF name  
 SMF_NAME="svc:/network/ufdbguard:default"  
   
 # Redirector user name  
 RDR_USER="ufdb"  
 RDR_GROUP="ufdb"  
   
 # Installation base dir  
 BASE="/usr/local"  
 # Redirector dir base  
 BASE2=$BASE"/ufdbguard"  
 # Redirector blacklist base  
 BASE3=$BASE2"/blacklists"  
   
 # Redirector convert tool location  
 RDR_GUARD_DB_TOOL=$BASE2"/bin/ufdbConvertDB"  
 # Redirector daemon  
 RDR_BIN_FILE="ufdbguardd"  
   
 DIR_ALLOW=$BASE3"/alwaysallow"  
 DIR_DENY=$BASE3"/alwaysdeny"  
 DIR_CUSTOM=$BASE3"/yoyo"  
 DIR_CUSTOM2=$BASE3"/phishtank"  
   
 # OS utilities  
 AWK=`which awk`  
 BASENAME=`which basename`  
 CAT=`which cat`  
 CD=`which cd`  
 CHOWN=`which chown`  
 CHMOD=`which chmod`  
 CP=`which cp`  
 CUT=`which cut`  
 ECHO=`which echo`  
 EXPRT=`which expr`  
 FIND=`which find`  
 GETOPT=`which getopt`  
 GREP=`which grep`  
 GZCAT=`which gzcat`  
 ID=`which id`  
 KILL=`which kill`  
 MKDIR=`which mkdir`  
 NEWTASK=`which newtask`  
 PRINTF=`which printf`  
 PS=`which ps`  
 RM=`which rm`  
 SVCADM=`which svcadm`  
 TOUCH=`which touch`  
 GTAR=`which gtar`  
 UNAME=`which uname`  
 WGET=`which wget`  
   
 ###############  
 # Subroutines #  
 ###############  
   
 usage_note ()  
 {  
 # Script usage note  
  $ECHO "Usage: `$BASENAME $0` [-h][-f][-a]"  
  $ECHO  
  $ECHO "No args - default mode. Full update and recompilation."  
  $ECHO "a - Ads & phishtank & always lists recompilation (whenever updated/exists or not)"  
  $ECHO "f - full update and recompilation."  
  $ECHO "h - this screen."  
  $ECHO "Beware: Categories with .notused file in dir will never be compiled."  
  exit 0  
 }  
   
 root_check ()  
 {  
  if [ ! `$ID | $CUT -f1 -d" "` = "uid=0(root)" ]; then  
  $ECHO "ERROR: You must be super-user to run this script."  
  exit 1  
  fi  
 }  
   
 checkuser ()  
 {  
 # Check redirector user  
  username=$1  
  if [ ! -z "`$CAT /etc/passwd | $GREP $username`" ]; then  
  $ECHO "1"  
  else  
  $ECHO "0"  
  fi  
 }  
   
 check_clean ()  
 {  
 # Check that everything is clean before we start  
  if [ -f $WORK_DIR/$LIST_NAME -o -f $WORK_DIR/shallalist.tar ]; then  
  $PRINTF "Old blacklist file found in ${WORK_DIR}..."  
  $RM $WORK_DIR/shallalist.*  
  $ECHO "Deleted."  
  fi  
   
  if [ -d $WORK_DIR/BL ]; then  
  $PRINTF "Old blacklist directory found in ${WORK_DIR}..."  
  $RM -rf $WORK_DIR/BL  
  $ECHO "Deleted."  
  fi  
 }  
   
 download_ads ()  
 {  
  # If Yoyo adblock script exists, run it first  
  [ -x $BASE/bin/create_filter_ad_servers.sh ] && $ECHO "Ads download script exists." && $BASE/bin/create_filter_ad_servers.sh  
 }  
   
 download_phishtank ()  
 {  
  # If Phishtank script exists, run it first  
  [ -x $BASE/bin/update_phishtank.sh ] && $ECHO "Phishtank download script exists." && $BASE/bin/update_phishtank.sh  
 }  
   
 download_list ()  
 {  
  # Make working directory  
  if [ ! -d $WORK_DIR ]; then  
  $PRINTF "Make working directory..."  
  $MKDIR -p $WORK_DIR  
  $ECHO "Done."  
  fi  
  # Get list from one server using server list  
  $PRINTF "Shalla list downloading..."  
  for S in $SERVER_LIST; do  
  $WGET -T $TIMEOUT -q -O $WORK_DIR/$LIST_NAME $S  
  retcode=`$ECHO $?`  
  case "$retcode" in  
   0)  
   $ECHO "Shalla list downloaded successfully."  
   break  
   ;;  
   4)  
   $ECHO "Unable to resolve host address. Exiting..."  
   exit 4  
   ;;  
   *)  
   $ECHO "Error downloading list from `$ECHO $S|$CUT -f1 -d '/'`. Try another server..."  
   continue  
   ;;  
  esac  
  done  
   
  if [ "$retcode" != "0" ]; then  
  $ECHO "Error downloading list from all servers. Exiting..."  
  exit 1  
  fi  
 }  
   
 compile_always ()  
 {  
 # Compile alwaysallow & alwaysdeny & custom databases if they exists  
  $PRINTF "Compile always and custom databases..."  
  if [ -d $DIR_ALLOW ]; then  
  $PRINTF "allow exists..."  
  $RDR_GUARD_DB_TOOL -d $DIR_ALLOW >/dev/null 2>&1  
  $PRINTF "Done..."  
  fi  
   
  if [ -d $DIR_DENY ]; then  
  $PRINTF "deny exists..."  
  $RDR_GUARD_DB_TOOL -d $DIR_DENY >/dev/null 2>&1  
  $PRINTF "Done..."  
  fi  
   
  if [ -d $DIR_CUSTOM ]; then  
  $PRINTF "custom exists..."  
  $RDR_GUARD_DB_TOOL -d $DIR_CUSTOM >/dev/null 2>&1  
  $PRINTF "Done..."  
  fi  
   
  if [ -d $DIR_CUSTOM2 ]; then  
  $PRINTF "custom 2 exists..."  
  $RDR_GUARD_DB_TOOL -d $DIR_CUSTOM2 >/dev/null 2>&1  
  $PRINTF "Done..."  
  fi  
 }  
   
 set_permission ()  
 {  
 # Setting files permissions  
  if [ "`checkuser $RDR_USER`" = "1" ]; then   
  $PRINTF "\nSetting files permissions..."  
  $CHOWN -R $RDR_USER:$RDR_GROUP $BASE3  
  $CHMOD 755 $BASE3  
  cd $BASE3  
  $FIND . -type f -exec $CHMOD 644 {} \;  
  $FIND . -type d -exec $CHMOD 755 {} \;  
  else  
  $ECHO "ERROR: User $RDR_USER does not exists. Exiting..."  
  exit 5  
  fi  
 }  
   
 fast_list_compilation ()  
 {  
  # First download ads if script exists  
  download_ads  
  # Then download phishtank if script exists  
  download_phishtank  
  # Ads & phishtank & always lists compilation if they exists  
  $PRINTF "Ads & phishtank & always lists compilation only..."  
  compile_always  
  # Set files permissions  
  set_permission  
  $ECHO "Done."  
 }  
   
 full_list_compilation ()  
 {  
  # First download ads if script exists  
  download_ads  
  # Then download phishtank if script exists  
  download_phishtank  
  # Then download blocklist  
  download_list  
  # Unpack list  
  $PRINTF "List unpacking..."  
  $GZCAT $WORK_DIR/$LIST_NAME | $GTAR -x -C $WORK_DIR  
  $CP -rp $WORK_DIR/BL $BASE3  
  $ECHO "Done."  
  # Call recompilation for categories defined in list  
  $PRINTF "Databases compiling..."  
  for cat in $CATEGORIES  
  do  
  # Update date and time to current to be compiled  
  $TOUCH $BASE3/BL/${cat}/domains >/dev/null 2>&1  
  $TOUCH $BASE3/BL/${cat}/urls >/dev/null 2>&1  
  $RDR_GUARD_DB_TOOL -d $BASE3/BL/${cat} >/dev/null 2>&1  
  done  
  $ECHO "Done."  
  compile_always  
  # Set files permissions  
  set_permission  
  $ECHO "Done."  
 }  
   
 reconfiguration ()  
 {  
  os=`$UNAME`  
  if [ "$os" = "SunOS" ]; then  
  $PRINTF "Redirector daemon restart..."  
  # Redirector restart on Solaris-based boxes  
  $SVCADM -v restart $SMF_NAME  
  else  
  $PRINTF "Redirector daemon reconfiguration..."  
  # Redirector reconfiguration  
  program=$1  
  pid=`$PS -ef|$GREP $program|$GREP -v grep|$AWK '{ print $2 }'`  
  $KILL -HUP $pid  
  fi;  
  $ECHO "Done."  
 }  
   
 clean_up ()  
 {  
 # Clean up file and directories  
  $PRINTF "Clean up downloaded file and directories..."  
  $RM -rf $WORK_DIR  
  $ECHO "Done."  
 }  
   
 ##############  
 # Main block #  
 ##############  
   
 # Root check  
 root_check  
   
 # Check clean working dir  
 check_clean  
   
 # BL download, unpack and compilation  
 # Check command-line arguments  
 if [ "x$*" = "x" ]; then  
 # If arguments list empty, make compilation by default  
  full_list_compilation  
 else  
  arg_list=$*  
  # Parse command line  
  set -- `$GETOPT aAfFhH: $arg_list` || {  
  usage_note 1>&2  
  }  
   
  # Read arguments  
  for i in $arg_list  
  do  
   case $i in  
   -a | -A) fast_list_compilation;;  
   -f | -F) full_list_compilation;;  
   -h | -H | \?) usage_note;;  
   esac  
   break  
  done  
   
  # Remove trailing --  
  #shift `$EXPR $OPTIND - 1`  
 fi  
   
 # Redirector reconfiguration  
 reconfiguration $RDR_BIN_FILE  
   
 # Finally cleanup all downloaded files  
 clean_up  
   
 exit 0  
 ####  

Замечание. Обратите внимание вот на что. Скрипт update_phishtank.sh - ОС-неспецифичный, в отличие от скрипта update_blocklist.sh, который содержит соляризмы, в частности, используется SMF для рестарта сервиса ufdbGuard. Вы можете переписать подпрограмму рестарта сервиса под вашу собственную ОС. Так как я в основном применяю Solaris, я, разумеется, не буду делать этого за вас. :)

После первоначальной скачки и компиляции списка, вы можете его добавить в конфигурацию ufdbGuard.conf:

Сначала создадим категорию:

 category phishtank {  
     domainlist "phishtank/domains"  
      redirect "http://cthulhu.localdomain:8080/cgi-bin/URLblocked.cgi?clientgroup=%s&clientaddr=%a&category=%t&url=%u"  
 }  
   

Понятно, да, что ссылка для редиректа будет ваша собственная и, вообще говоря, редиректы уже должны быть настроены? :) Не спрашивайте меня, как это делать - курите маны.

Теперь можно добавить категорию в ACL редиректора:

 default {  
    ### NOTE: depending on the other ACLs, "pass none" may be more appropriate to use  
    ### EDIT THE NEXT LINE FOR LOCAL CONFIGURATION:  
           pass !security !alwaysdeny updatesites !adv !phishtank !drugs !gamble !fortunetelling  
                !porn !sex !dating !spyware !hacking  
                !anonvpn !redirector !costtraps !social  
                !games !games2 !tracker !movies !music  
                !models !urlshortener !webtv !webradio !warez  
                any  
    #!adv2  
    # pass none  
     redirect "http://cthulhu.localdomain:8080/cgi-bin/URLblocked.cgi?clientgroup=%s&clientaddr=%a&category=%t&url=%u"  
   }  
 }  
   

и перезапустить его. That's all, folks! Теперь ваши хомячки в некоторой (относительной!) безопасности.

DISCLAMER. Я в курсе, что не существует стопроцентной защиты. Я в курсе, что в борьбе щита и меча обычно побеждает меч. Я в курсе, что жульё плодится быстрее, чем вымирают лохи. Однако все это позволяет еще немного уменьшить площадь поражения ваших неразумных подопечных - да и вас вместе с ними. Безопасности вам и вашим пользователям!