mirror of
https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker.git
synced 2025-04-16 14:59:11 +00:00
* Amazon Linux puts pidof under /sbin fixes https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/issues/399
361 lines
10 KiB
Bash
Executable file
361 lines
10 KiB
Bash
Executable file
#!/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 <<EOF
|
|
$script: INSTALL Nginx Bad Bot Blocker configuration to: [ $CONF_DIR ] [ $BOTS_DIR ]
|
|
|
|
Usage: $script [OPTIONS]
|
|
[ -b ] : Bot rules directory (default: $BOTS_DIR)
|
|
[ -c ] : NGINX conf directory (default: $CONF_DIR)
|
|
[ -s ] : Script directory (default: $SCRIPT_DIR)
|
|
[ -r ] : Change repo url (default: $REPO)
|
|
[ -x ] : Actually change the files (default: don't change anything)
|
|
[ -q ] : Suppress non error messages
|
|
[ -v ] : Print blacklist version
|
|
[ -h ] : this help message
|
|
|
|
Examples:
|
|
$script (Don't change anything: display results on stdout)
|
|
$script -x (Download / update config files)
|
|
$script -q (Less verbose messages for cron)
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
check_version() {
|
|
local file=$CONF_DIR/globalblacklist.conf
|
|
|
|
if [ -f $file ]; then
|
|
grep Version $file
|
|
grep 'Updated:' $file
|
|
else
|
|
printf "Missing '$file' (pass -c \$path before -v)\n"
|
|
fi
|
|
|
|
exit 0
|
|
}
|
|
|
|
longest_str() {
|
|
echo $@ | tr " " "\n" | awk '{print length ($0)}' | sort -nr | head -n1
|
|
}
|
|
|
|
check_if_updating() {
|
|
local x= local_file= local_dir=$1
|
|
local file_list="$(echo $@ | awk '{$1=""; print}' | sed -e 's/^[ \t]*//')"
|
|
|
|
for x in $file_list; do
|
|
local_file=$local_dir/$x
|
|
|
|
if [ ! -f $local_file ]; then
|
|
echo "true"
|
|
break
|
|
fi
|
|
done
|
|
}
|
|
|
|
download_files() {
|
|
local url= x= local_file= remote_path= remote_dir=$1 local_dir=$2 tmp= retval=
|
|
local file_list="$(echo $@ | awk '{$1=$2=""; print $0}' | sed -e 's/^[ \t]*//')" # rm leading whitespace
|
|
local col_size=$(( $(longest_str $file_list) + $(echo $remote_dir | wc -m) ))
|
|
|
|
if [ -n "$(check_if_updating $local_dir $file_list)" ]; then
|
|
printf "\nREPO = $REPO\n\n"
|
|
|
|
for x in $file_list; do
|
|
local_file=$local_dir/$x
|
|
|
|
if [ ! -f $local_file ] || [ ! -s $local_file ]; then
|
|
if [ "$remote_dir" = "/" ]; then
|
|
remote_path=$x
|
|
else
|
|
remote_path="$remote_dir/$x"
|
|
fi
|
|
|
|
if [ "$DRY_RUN" = "N" ]; then
|
|
printf "%-21s %-$(( $col_size +8 ))s %s" \
|
|
"Downloading [FROM]=>" \
|
|
"[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
|