#!/bin/bash

### 2022-08-22 - Updated with basic logging [LOGFILE]
### Exaga - sarpi.penthux.net

### Sample download script for https://mailfud.org/geoip-legacy/
### - Adjust FILES below for specific GeoIP DBs
### - Adjust XTABLES and XT_GEOIP_BUILD if needed
### - Copy script to /etc/cron.weekly or similar for your OS,
###   note that /etc/cron.* filename MUST NOT HAVE .sh extension,
###   rename to /etc/cron.weekly/geoip_update
### Contact: admin@mailfud.org

# Database directory [~# whereis GeoIP]
DBDIR=/usr/share/GeoIP
#DBDIR=/var/lib/GeoIP

# GeoIP DB files to verify [.dat.gz suffix not required]
#FILES="GeoIP GeoIPv6"
FILES="GeoIP GeoIPv6 GeoIPCity GeoIPCityv6 GeoIPASNum GeoIPASNumv6 GeoIPOrg GeoIPISP"

# Log file [LOGFILE]
LOGFILE="/var/log/GeoIP.log"

# If http proxy needed
#https_proxy="http://foo.bar:3128"

# Uncomment XTABLES to enable iptables xt_geoip updating
# Must contain filename for legacy IPv4/IPv6 CSV file (GeoIP-legacy.csv)
# 
# xtables-addons needs to be installed
# (apt-get linux-headers-generic xtables-addons-dkms)
# More info: https://inai.de/projects/xtables-addons/
#
#XTABLES="GeoIP-legacy.csv"
# Standard distribution location for xtables script, change if using custom
#XT_GEOIP_BUILD=/usr/lib/xtables-addons/xt_geoip_build

### v0.24
### - add support for Ubuntu 22.04 /usr/libexec/xtables-addons/xt_geoip_build
### v0.23
### - fix xtables 3.8+, requires dbip-country-lite.csv
### v0.22
### - fix xtables stuff
### v0.21
### - added GeoIPCityv6, GeoIPASNumv6, fix https_proxy export

# GeoIP installed check
if ! command -v geoiplookup >/dev/null 2>&1
then
  echo "ERROR: GeoIP must be installed first, before running an update!" 
  exit 0 
fi

# LOGFILE function
function log {
  echo "$(date +"%F %T") [$$] $1"
  echo "$(date +"%F %T") [$$] $1" >> "${LOGFILE}"
}

# Start logging [LOGFILE]
# Sleep 1-3 minutes if executed via cron
if [ ! -t 0 ]; then 
  log "? Scheduled GeoIP DB update ... pending"
  sleep $(shuf -i 60-180 -n 1)
  log "# Initiating automated GeoIP DB update ... [cron job scheduler]"
else
  log "# Initiating manual GeoIP DB update ... [user: $(whoami)]"
fi

# Verify DBDIR status
test -w $DBDIR && cd $DBDIR 2>/dev/null || { log "! ERROR: Invalid directory: $DBDIR"; log "! Stopping GeoIP DB update ... exit [1]"; log "---"; echo >> ${LOGFILE}; exit 1; }

if [ "$XTABLES" != "" ]; then
	FILES="$FILES $XTABLES"
fi

export https_proxy
for f in $FILES; do
	# Make sure .gz is stripped
	f=${f%*.gz}
	# Make sure .dat exists
	if [[ ! "$f" =~ \.csv ]]; then f=${f%*.dat}.dat; fi
	# .gz files are kept on disk to compare timestamps (-N)
	wget -nv -N -T 30 --max-redirect 0 https://mailfud.org/geoip-legacy/$f.gz
	RET=$?
	if [ $RET -ne 0 ]; then
		log "! ERROR: wget $f.gz failed: $RET" >&2
		continue
	fi
	# Unpack and replace files accordingly
	if gzip -dc $f.gz >$f.tmp; then
		if ! diff $f $f.tmp >/dev/null 2>&1; then
		    log "> Processing $f ... "
			if [ "$f" = "$XTABLES" ]; then XUPD=1; fi
			chmod 644 $f.tmp
			/bin/mv -f $f.tmp $f
			log "+ Updated $f"
		else
			log "- $f is up to date"
		fi
	else
		log "! ERROR: gunzip $f failed" >&2
		rm -f $f.gz
	fi
	rm -f $f.tmp
done

if [ "$XTABLES" != "" ]; then
	if [ -z "$XT_GEOIP_BUILD" ]; then
		if [ -f /usr/lib/xtables-addons/xt_geoip_build ]; then
			XT_GEOIP_BUILD=/usr/lib/xtables-addons/xt_geoip_build
		else
			XT_GEOIP_BUILD=/usr/libexec/xtables-addons/xt_geoip_build
		fi
	fi
	if [ ! -f "$XT_GEOIP_BUILD" ]; then
		log "! ERROR: xt_geoip_build not found, xtables-addons-common package not installed?" >&2
		log "! Stopping GeoIP DB update ... exit [0]"
        log "---" && echo >> ${LOGFILE}
		exit 0
	fi
	if [ ! -f "GeoIP-legacy.csv" ]; then
		log "! ERROR: GeoIP-legacy.csv not found, cannot update xt_geoip" >&2
		log "! Stopping GeoIP DB update ... exit [0]"
		log "---" && echo >> ${LOGFILE}
		exit 0
	fi
	if [ ! -z "$XUPD" -o "$(find /usr/share/xt_geoip -name 'US.*' -mtime -14 2>/dev/null)" = "" ]; then
		mkdir -m 755 /usr/share/xt_geoip 2>/dev/null
		# Convert to dbip-country-lite format if needed (xtables-addons 3.8+)
		if grep dbip-country-lite $XT_GEOIP_BUILD >/dev/null; then
			cat $DBDIR/GeoIP-legacy.csv | tr -d '"' | cut -d, -f1,2,5 >$DBDIR/dbip-country-lite.csv.tmp &&
			/bin/mv -f $DBDIR/dbip-country-lite.csv.tmp $DBDIR/dbip-country-lite.csv
			XCMD="perl $XT_GEOIP_BUILD -D /usr/share/xt_geoip -S $DBDIR"
		else
			XCMD="perl $XT_GEOIP_BUILD -D /usr/share/xt_geoip $DBDIR/GeoIP-legacy.csv"
		fi
		RET=$($XCMD 2>/dev/null | tail -1)
		if [[ "$RET" =~ (Zimbabwe|ZW) ]]; then
			log "+ Updated xt_geoip"
		else
			log "! ERROR: something went wrong with xt_geoip update ..." >&2
			log "! Do you have perl module Text::CSV_XS / libtext-csv-xs-perl installed?" >&2
			log "! Try running the command manually:" >&2
			log "  $XCMD" >&2
		fi
	else
		log "- xt_geoip is up to date"
	fi
fi

# end of logging
log "# GeoIP DB update complete!"
echo "---" >> ${LOGFILE}

# done
exit

# EOF<*>

