From daf5a62e83c6d97f0ad495314ee20b6699e1379b Mon Sep 17 00:00:00 2001 From: "github@kiekerjan.isdronken.nl" Date: Sun, 11 Apr 2021 20:45:24 +0200 Subject: [PATCH] Merge changes from kiekerjan special --- conf/fail2ban/filter.d/nginx-geoipblock.conf | 12 ++++ conf/fail2ban/filter.d/ssh-geoipblock.conf | 10 +++ conf/fail2ban/jail.d/nginx-general.conf | 9 +++ conf/geoiplookup.conf | 3 + conf/nginx-primaryonly.conf | 24 +++++++ conf/nginx/conf.d/10-geoblock.conf | 22 ++++++ setup/geoipfilter.sh | 41 +++++++++++ setup/geoiptoolssetup.sh | 76 ++++++++++++++++++++ setup/start.sh | 1 + setup/system.sh | 10 +-- setup/web.sh | 9 +++ 11 files changed, 213 insertions(+), 4 deletions(-) create mode 100644 conf/fail2ban/filter.d/nginx-geoipblock.conf create mode 100644 conf/fail2ban/filter.d/ssh-geoipblock.conf create mode 100644 conf/fail2ban/jail.d/nginx-general.conf create mode 100644 conf/geoiplookup.conf create mode 100644 conf/nginx/conf.d/10-geoblock.conf create mode 100644 setup/geoipfilter.sh create mode 100644 setup/geoiptoolssetup.sh diff --git a/conf/fail2ban/filter.d/nginx-geoipblock.conf b/conf/fail2ban/filter.d/nginx-geoipblock.conf new file mode 100644 index 00000000..11dccbcc --- /dev/null +++ b/conf/fail2ban/filter.d/nginx-geoipblock.conf @@ -0,0 +1,12 @@ +# Fail2Ban filter Mail-in-a-Box geo ip block + +[INCLUDES] + +before = common.conf + +[Definition] + +_daemon = mailinabox + +failregex = .* - Geoip blocked +ignoreregex = diff --git a/conf/fail2ban/filter.d/ssh-geoipblock.conf b/conf/fail2ban/filter.d/ssh-geoipblock.conf new file mode 100644 index 00000000..d35e0d95 --- /dev/null +++ b/conf/fail2ban/filter.d/ssh-geoipblock.conf @@ -0,0 +1,10 @@ +# Fail2Ban filter sshd ip block according to https://www.axllent.org/docs/ssh-geoip/ + +[INCLUDES] + +before = common.conf + +[Definition] + +failregex = .* DENY geoipblocked connection from +ignoreregex = diff --git a/conf/fail2ban/jail.d/nginx-general.conf b/conf/fail2ban/jail.d/nginx-general.conf new file mode 100644 index 00000000..ca1afa71 --- /dev/null +++ b/conf/fail2ban/jail.d/nginx-general.conf @@ -0,0 +1,9 @@ +[nginx-badbots] +enabled = true +port = http,https +filter = nginx-badbots +logpath = /var/log/nginx/access.log +maxretry = 2 + +[nginx-http-auth] +enabled = true diff --git a/conf/geoiplookup.conf b/conf/geoiplookup.conf new file mode 100644 index 00000000..4a709520 --- /dev/null +++ b/conf/geoiplookup.conf @@ -0,0 +1,3 @@ +# UPPERCASE space-separated country codes to ACCEPT +# See e.g. https://dev.maxmind.com/geoip/legacy/codes/iso3166/ for allowable codes +ALLOW_COUNTRIES="" diff --git a/conf/nginx-primaryonly.conf b/conf/nginx-primaryonly.conf index 31e50d5b..aaaf6947 100644 --- a/conf/nginx-primaryonly.conf +++ b/conf/nginx-primaryonly.conf @@ -9,6 +9,30 @@ rewrite ^/admin$ /admin/; rewrite ^/admin/munin$ /admin/munin/ redirect; location /admin/ { + # By default not blocked + set $block_test 1; + + # block the continents + if ($allowed_continent = no) { + set $block_test 0; + } + + # in addition, block the countries + if ($denied_country = no) { + set $block_test 0; + } + + # allow some countries + if ($allowed_country = yes) { + set $block_test 1; + } + + # if 0, then blocked + if ($block_test = 0) { + access_log /var/log/nginx/geoipblock.log geoipblock; + return 444; + } + proxy_pass http://127.0.0.1:10222/; proxy_set_header X-Forwarded-For $remote_addr; add_header X-Frame-Options "DENY"; diff --git a/conf/nginx/conf.d/10-geoblock.conf b/conf/nginx/conf.d/10-geoblock.conf new file mode 100644 index 00000000..c977d366 --- /dev/null +++ b/conf/nginx/conf.d/10-geoblock.conf @@ -0,0 +1,22 @@ +# GeoIP databases +geoip_country /usr/share/GeoIP/GeoIP.dat; +geoip_city /usr/share/GeoIP/GeoIPCity.dat; + +# map the list of denied countries +# see e.g. https://dev.maxmind.com/geoip/legacy/codes/iso3166/ for allowable +# countries +map $geoip_country_code $denied_country { + default yes; + } + +# map the list of allowed countries +map $geoip_country_code $allowed_country { + default no; + } + +# map the continents to allow +map $geoip_city_continent_code $allowed_continent { + default yes; + } + +log_format geoipblock '[$time_local] - Geoip blocked $remote_addr'; diff --git a/setup/geoipfilter.sh b/setup/geoipfilter.sh new file mode 100644 index 00000000..8647f048 --- /dev/null +++ b/setup/geoipfilter.sh @@ -0,0 +1,41 @@ +#!/bin/bash +CONFIG_FILE=/etc/geoiplookup.conf +GEOIPLOOKUP=/usr/local/bin/goiplookup + +# Check existence of configuration +if [ -f "$CONFIG_FILE" ]; then + source $CONFIG_FILE + + # Check required variable exists and is non-empty + if [ -z "$ALLOW_COUNTRIES" ]; then + echo "variable ALLOW_COUNTRIES is not set or empty. No countries are blocked." + exit 0 + fi +else + echo "Configuration $CONFIG_FILE does not exist. No countries are blocked." + exit 0 +fi + +# Check existence of binary +if [ ! -x "$GEOIPLOOKUP" ]; then + echo "Geoip lookup binary $GEOIPLOOKUP does not exist. No countries are blocked." + exit 0 +fi + +if [ $# -ne 1 -a $# -ne 2 ]; then + echo "Usage: `basename $0` " 1>&2 + exit 0 # return true in case of config issue +fi + +COUNTRY=`$GEOIPLOOKUP $1 | awk -F ": " '{ print $2 }' | awk -F "," '{ print $1 }' | head -n 1` + +[[ $COUNTRY = "IP Address not found" || $ALLOW_COUNTRIES =~ $COUNTRY ]] && RESPONSE="ALLOW" || RESPONSE="DENY" + +logger "$RESPONSE geoipblocked connection from $1 ($COUNTRY) $2" + +if [ $RESPONSE = "ALLOW" ] +then + exit 0 +else + exit 1 +fi diff --git a/setup/geoiptoolssetup.sh b/setup/geoiptoolssetup.sh new file mode 100644 index 00000000..6e01a880 --- /dev/null +++ b/setup/geoiptoolssetup.sh @@ -0,0 +1,76 @@ +source setup/functions.sh + +echo Installing geoip packages... + +# Install some packages +apt_install geoip-database-extra libgeoip1 libnginx-mod-http-geoip + +# geo ip filtering of ssh entries, based on https://www.axllent.org/docs/ssh-geoip/#disqus_thread + +# Install geo ip lookup tool +gunzip -c tools/goiplookup.gz > /usr/local/bin/goiplookup +chmod +x /usr/local/bin/goiplookup + +# check that geoipdb is older then 2 months, to not hit the server too often +if [[ ! -d /usr/share/GeoIP || ! -f /usr/share/GeoIP/GeoIP.dat || $(find "/usr/share/GeoIP/GeoIP.dat" -mtime +60 -print) ]]; then + echo updating goiplookup database + goiplookup db-update +else + echo skipping goiplookup database update +fi + +# Install geo ip filter script +cp -f setup/geoipfilter.sh /usr/local/bin/ + +# Install only if not yet exists, to keep user config +if [ ! -f /etc/geoiplookup.conf ]; then + cp -f conf/geoiplookup.conf /etc/ +fi + +# Add sshd entries for hosts.deny and hosts.allow +if grep -Fxq "sshd: ALL" /etc/hosts.deny +then + echo hosts.deny already configured +else + sed -i '/sshd: /d' /etc/hosts.deny + echo "sshd: ALL" >> /etc/hosts.deny +fi + +if grep -Fxq "sshd: ALL: aclexec /usr/local/bin/geoipfilter.sh %a %s" /etc/hosts.allow +then + echo hosts.allow already configured +else + # Make sure all sshd lines are removed + sed -i '/sshd: /d' /etc/hosts.allow + echo "sshd: ALL: aclexec /usr/local/bin/geoipfilter.sh %a %s" >> /etc/hosts.allow +fi + +# geo ip filtering of nginx access log, based on +# https://guides.wp-bullet.com/blocking-country-and-continent-with-nginx-geoip-on-ubuntu-18-04/ + +## Install geo ip lookup files + +# Move old file away if it exists +if [ -f "/usr/share/GeoIP/GeoIP.dat" ]; then + mv -f /usr/share/GeoIP/GeoIP.dat /usr/share/GeoIP/GeoIP.dat.bak +fi + +hide_output wget -P /usr/share/GeoIP/ https://dl.miyuru.lk/geoip/maxmind/country/maxmind.dat.gz + +if [ -f "/usr/share/GeoIP/maxmind.dat.gz" ]; then + gunzip -c /usr/share/GeoIP/maxmind.dat.gz > /usr/share/GeoIP/GeoIP.dat +else + echo Did not correctly download maxmind geoip database +fi + +# If new file is not created, move the old file back +if [ ! -f "/usr/share/GeoIP/GeoIP.dat" ]; then + echo GeoIP.dat was not created + + if [ -f "/usr/share/GeoIP/GeoIP.dat.bak" ]; then + mv /usr/share/GeoIP/GeoIP.dat.bak /usr/share/GeoIP/GeoIP.dat + fi +fi + +# Restart nginx +restart_service nginx diff --git a/setup/start.sh b/setup/start.sh index 06349e3e..6f6cf309 100755 --- a/setup/start.sh +++ b/setup/start.sh @@ -118,6 +118,7 @@ source setup/nextcloud.sh #source setup/zpush.sh source setup/management.sh source setup/munin.sh +source setup/geoiptoolssetup.sh source setup/additionals.sh # Wait for the management daemon to start... diff --git a/setup/system.sh b/setup/system.sh index e09a1846..137919e4 100755 --- a/setup/system.sh +++ b/setup/system.sh @@ -239,9 +239,6 @@ if [ -z "${DISABLE_FIREWALL:-}" ]; then # Install `ufw` which provides a simple firewall configuration. apt_install ufw - # Allow incoming connections to SSH. - ufw_limit ssh; - # ssh might be running on an alternate port. Use sshd -T to dump sshd's #NODOC # settings, find the port it is supposedly running on, and open that port #NODOC # too. #NODOC @@ -251,8 +248,13 @@ if [ -z "${DISABLE_FIREWALL:-}" ]; then echo Opening alternate SSH port $SSH_PORT. #NODOC ufw_limit $SSH_PORT #NODOC - + else + # Allow incoming connections to SSH. + ufw_limit ssh; fi + else + # Allow incoming connections to SSH. + ufw_limit ssh; fi ufw --force enable; diff --git a/setup/web.sh b/setup/web.sh index 0c0b5ba4..d3bda6f7 100755 --- a/setup/web.sh +++ b/setup/web.sh @@ -145,6 +145,15 @@ if [ ! -f $STORAGE_ROOT/www/default/index.html ]; then fi chown -R $STORAGE_USER $STORAGE_ROOT/www +# Copy geoblock config file, but only if it does not exist to keep user config +if [ ! -f /etc/nginx/conf.d/10-geoblock.conf ]; then + cp -f conf/nginx/conf.d/10-geoblock.conf /etc/nginx/conf.d/ +fi + +# touch logfiles that might not exist +touch /var/log/nginx/geoipblock.log +chown www-data /var/log/nginx/geoipblock.log + # Start services. restart_service nginx restart_service php$(php_version)-fpm