#!/bin/sh # Shell Script for Installing the Nginx Bad Bot Blocker # Copyright - https://github.com/mitchellkrogza # Project Url: https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker # Version 2.2017.07 # Install script & Alpine Linux package by Stuart Cardall: https://github.com/itoffshore # PLEASE READ CONFIGURATION INSTRUCTIONS BEFORE USING THIS - THIS IS ONLY A PARTIAL INSTALLER # FOR COPYING THE FILES CORRECTLY TO THE NGINX FOLDERS: # https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/blob/master/CONFIGURATION.md # Use this script for a new install or to update to a new release (which has a new configuration # file structure) and thereafter use the Auto Update Shell Script update-ngxblocker to update # the blacklist in /etc/nginx/conf.d/globalblacklist.conf # THIS INSTALL SCRIPT ONLY COPIES THE NECESSARY FILES FOR NGINX DIRECTLY FROM THE REPO ### The installer script does not carry out STEP 6 of the configuration instructions for you. ### You must manually edit any vhost files with the includes in STEP 6 or it will not actually be protecting any sites. ### READ: https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/blob/master/CONFIGURATION.md ### You can also now use a setup script contributed by Stuart Cardall to automatically insert the includes for you ### See - https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/setup-ngxblocker # Save this file as /usr/local/sbin/install-ngxblocker # sudo wget https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/install-ngxblocker -O /usr/local/sbin/install-ngxblocker # Make it Executable: # chmod 700 /usr/local/sbin/install-ngxblocker # Run it from the command line: # sudo /usr/local/sbin/install-ngxblocker [ -h ] ######## LETS INSTALL NOW ############################### CONF_DIR=/etc/nginx/conf.d BOTS_DIR=/etc/nginx/bots.d SCRIPT_DIR=/usr/local/sbin REPO=https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master ####### end user configuration ########################## OS=$(uname -s) usage() { local script=$(basename $0) cat <" \ "[REPO]/$remote_path" \ "[TO]=> $local_file" tmp=$(mktemp) url=$REPO/$remote_path curl --fail --connect-timeout 60 --retry 10 --retry-delay 5 -so $tmp $url retval=$? case "$retval" in 0) printf "...OK\n" mv $tmp $local_file ;; 22) printf "...ERROR 404: $url\n";; 28) printf "...ERROR TIMEOUT: $url\n";; *) printf "...ERROR CURL: ($retval)\n";; esac else printf "%-21s %-$(( $col_size +8 ))s %s\n" \ "Downloading [FROM]=>" \ "[REPO]/$remote_path" \ "[TO]=> $local_file" fi fi done else print_message "Nothing to update for directory: $local_dir\n" fi } set_mode() { local mode=$1 dir=$2 file= local file_list="$(echo $@ | awk '{$1=$2=""; print}' | sed -e 's/^[ \t]*//')" for file in $file_list; do print_message "Setting mode: $mode => $dir/$file\n" chmod $mode $dir/$file done } check_config() { local x= dirs="$*" for x in $dirs; do if [ ! -d $x ]; then printf "Creating directory: $x\n" if [ "$DRY_RUN" = "N" ]; then mkdir -p $x fi fi done } 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)}' } 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 ;; 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 } print_message() { local msg="$@" if [ "$VERBOSE" != "N" ]; then printf "$msg" fi } get_options() { local arg= opts= while getopts :b:c:s:r:xvqh opts "$@" do if [ -n "${OPTARG}" ]; then case "$opts" in r) arg=$(sanitize_url ${OPTARG});; *) arg=$(sanitize_path ${OPTARG});; esac fi case "$opts" in b) BOTS_DIR=$arg; check_args $opts path $arg ;; c) CONF_DIR=$arg; check_args $opts path $arg ;; s) SCRIPT_DIR=$arg; check_args $opts path $arg ;; r) REPO=$arg; check_args $opts url $arg ;; x) DRY_RUN=N ;; v) check_version ;; q) VERBOSE=N ;; h) usage ;; \?) usage ;; :) check_args $OPTARG none none ;; esac done } wget_opts() { local opts= # GNU wget / Busybox 1.26.2 if wget --help 2>&1 | grep "\--spider" >/dev/null 2>&1; then opts="--spider" else # Busybox wget < 1.26.2 opts="-s" fi echo $opts } find_binary() { local x= path= binary=$1 bin_paths='/bin /usr/bin /usr/local/bin /sbin /usr/sbin /usr/local/sbin /root/bin /root/.bin' for x in $bin_paths; do path="$x/$binary" if [ -x $path ]; then echo $path return fi done } check_depends() { # some distros do not have these tools installed by default local x= depends_list="wget curl" for x in $depends_list; do if [ -z $(find_binary $x) ]; then printf "$0 requires: '$x' \n" exit 1 fi done case $OS in Linux) # give a helpful message for missing pidof if [ -z $(find_binary pidof) ]; then printf "$0 requires 'pidof' \n\n" printf "In Debian: apt install sysvinit-utils\n" printf "In Centos: yum install sysvinit-tools\n" exit 1 fi ;; *BSD) # give a helpful message for missing gsed if [ -z $(find_binary gsed) ]; then printf "$0 requires 'gsed' \n\n" printf "In FreeBSD: 'pkg install textproc/gsed' or 'portmaster textproc/gsed'\n" exit 1 fi ;; esac } check_online() { local url=$1 options=$(wget_opts) if wget $options $url >/dev/null 2>&1; then echo "true" fi } main() { local include_url= # 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 $@ include_url=$REPO/include_filelist.txt # check repo is online & source includes print_message "Checking url: $include_url\n" if [ -n "$(check_online $include_url)" ]; then local tmp=$(mktemp) wget -q $include_url -O $tmp # use period not source in POSIX shell . $tmp 2>/dev/null rm -f $tmp else printf "Repo down or missing: $include_url\n" exit 1 fi # double check we have some files sourced if [ -z "$CONF_FILES" ] || [ -z "$BOT_FILES" ] || [ -z "$SCRIPT_FILES" ]; then printf "Error sourcing variables from: $include_url\n" exit 1 fi # by default do not change any files if [ -z "$DRY_RUN" ]; then printf "\n** Dry Run ** | not updating files | run as '$(basename $0) -x' to install files.\n\n" else printf "\n" fi check_config $CONF_DIR $BOTS_DIR $SCRIPT_DIR download_files conf.d $CONF_DIR $CONF_FILES download_files bots.d $BOTS_DIR $BOT_FILES download_files / $SCRIPT_DIR $SCRIPT_FILES # ensures scripts are executable if [ "$DRY_RUN" = "N" ]; then set_mode 700 $SCRIPT_DIR $SCRIPT_FILES fi } ## START ## main $@ exit $? # PLEASE READ CONFIGURATION INSTRUCTIONS # https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/blob/master/CONFIGURATION.md # PLEASE ALSO SEE THE SETUP SCRIPT TO INSERT THE NECESSARY INCLUDES FOR YOU ### You can now use a setup script contributed by Stuart Cardall to automatically add the includes for you ### See - https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/setup-ngxblocker