#!/bin/sh # Shell Script for Auto Updating the Nginx Bad Bot Blocker # Copyright: https://github.com/mitchellkrogza # Project Url: https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker # Update script & Alpine Linux package by Stuart Cardall: https://github.com/itoffshore # MAKE SURE you have all the following files in /etc/nginx/bots.d/ folder # *********************************************************************** # whitelist-ips.conf # whitelist-domains.conf # blacklist-user-agents.conf # bad-referrer-words.conf # custom-bad-referrers.conf # blacklist-ips.conf # A major change to using include files was introduced in # https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/commit/7e3ab02172dafdd524de5dd450a9732328622779 # ************************************************************************** # Nginx will fail a reload with [EMERG] without the presence of these files. # PLEASE READ UPDATED CONFIGURATION INSTRUCTIONS BEFORE USING THIS # Save this file as /usr/sbin/update-ngxblocker # cd /usr/sbin # sudo wget https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/update-ngxblocker -O update-ngxblocker # Make it Executable chmod 700 /usr/sbin/update-ngxblocker # RUN THE UPDATE # Here our script runs, pulls the latest update, reloads nginx and emails you a notification EMAIL="me@myemail.com" SEND_EMAIL="Y" CONF_DIR=/etc/nginx/conf.d ##### end user configuration ############################################################## BOLDGREEN="\033[1m\033[32m" BOLDMAGENTA="\033[1m\033[35m" BOLDRED="\033[1m\033[31m" BOLDYELLOW="\033[1m\033[33m" BOLDWHITE="\033[1m\033[37m" RESET="\033[0m" usage() { local script=$(basename $0) cat < $BOLDMAGENTA$remote_ver$RESET\n\n" else printf "\nLatest Blacklist installed: $BOLDGREEN$version$RESET\n\n" fi else printf "Missing '$file' (pass -c \$path before -v)\n" fi exit 0 } service_cmd() { # arch linux does not have a 'service' command local svc= svc_list="service systemctl rc-service" for svc in $svc_list; do svc=$(which $svc 2>/dev/null) if [ -n "$svc" ]; then echo $svc exit 0 fi done } wget_opts() { local opts= # Busybox wget gives less verbose output by default if [ -n "$(wget --help 2>/dev/null | grep "\-nv")" ]; then opts="-nv" fi echo $opts } sanitize_path() { echo $1 |tr -cd '[:alnum:] [=@=] [=.=] [=-=] [=/=] [=_=]' \ |tr -s '@.-/_' |awk '{print tolower($0)}' } sanitize_url() { echo $1 |tr -cd '[:alnum:] [=:=] [=.=] [=-=] [=/=]' \ |tr -s ':.-' |awk '{print tolower($0)}' } sanitize_email() { echo $1 |tr -cd '[:alnum:] [=@=] [=.=] [=-=] [=_=]' \ |tr -s '@-_.' |awk '{print tolower($0)}' } check_args() { local option=$1 type=$2 arg=$3 local msg="ERROR: option '-$option' argument '$arg' requires:" case "$type" in path) if ! echo $arg | grep ^/ 1>/dev/null; then printf "$msg absolute path.\n" exit 1 fi ;; email) if ! echo $arg | grep -E ^[-_[:alnum:]]+@[-_[:alnum:]]+[\.][\.a-z]+ 1>/dev/null; then printf "$msg email@domain.com\n" exit 1 fi ;; url) if ! echo $arg | grep -E ^http[s]?://[0-9a-zA-Z-]+[.]+[/0-9a-zA-Z.]+ 1>/dev/null; then printf "$msg url => http[s]://the.url\n" exit 1 fi ;; none) printf "$msg argument.\n"; exit 1;; esac } check_mail_depends() { if [ ! -f /usr/bin/mail ]; then # mailx + ssmtp are enough to send emails printf "${BOLDYELLOW}WARN${RESET}: missing /usr/bin/mail => ${BOLDWHITE}disabling emails${RESET}.\n\n" SEND_EMAIL="N" fi } check_depends() { # centos does not have wget installed by default if ! wget --help >/dev/null 2>&1; then printf "$0 requires: wget => cannot download files.\n" exit 1 fi # centos also does not have which by default if [ ! -x /usr/bin/curl ]; then printf "$0 requires: curl => cannot check remote version.\n" exit 1 fi } get_options() { local arg= opts= while getopts :c:r:e:nvh opts "$@" do if [ -n "${OPTARG}" ]; then case "$opts" in r) arg=$(sanitize_url ${OPTARG});; e) arg=$(sanitize_email ${OPTARG});; *) arg=$(sanitize_path ${OPTARG});; esac fi case "$opts" in c) CONF_DIR=$arg; check_args $opts path $arg ;; r) REPO=$arg; check_args $opts url $arg ;; e) EMAIL=$arg; check_args $opts email $arg ;; n) SEND_EMAIL=N ;; v) check_version ;; h) usage ;; \?) usage ;; :) check_args $OPTARG none none ;; esac done } main() { local email_report=$(mktemp) file=globalblacklist.conf local REPO=https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master local remote_dir=conf.d url= output= update= status= # default to service (centos does not have 'which' by default) local service=${service_cmd:-"service"} # require root if [ "$(id -u)" != "0" ]; then echo "This script must be run as root" 1>&2 exit 1 fi check_depends # parse command line get_options $@ url=$REPO/$remote_dir/$file output=$CONF_DIR/$file # check for updated blacklist update=$(check_version | tail -n 2) printf "\n$update\n\n" | tee $email_report if echo $update | grep ^Update 1>/dev/null; then # download update mkdir -p $CONF_DIR wget $url $(wget_opts) -O $output 2>&1 | tee -a $email_report # re-read nginx configuration if ! grep "Not Found" $email_report; then $service nginx reload if [ $? = 0 ]; then status="${BOLDGREEN}[OK]${RESET}" else status="${BOLDRED}[FAILED]${RESET}" fi printf "\nReloading NGINX configuration...$status\n" | tee -a $email_report else printf "\n${BOLDRED}Download failed${RESET}: not reloading NGINX config\n" | tee -a $email_report fi fi # email report check_mail_depends case "$SEND_EMAIL" in y*|Y*) printf "Emailing report to: ${BOLDWHITE}$EMAIL${RESET}\n\n"; # remove ansi colour codes sed -i 's/\x1b\[[0-9;]*m//g' $email_report cat $email_report | mail -s "Nginx Bad Bot Blocker Updated" $EMAIL ;; esac rm -f $email_report } ## start ## main $@ exit $? # Add this as a cron to run daily / weekly as you like # Here's a sample CRON entry to update every day at 10pm # 00 22 * * * /usr/sbin/update-ngxblocker # better logging for cron jobs: # https://serverfault.com/questions/137468/better-logging-for-cronjobs-send-cron-output-to-syslog