107 lines
3.5 KiB
Bash
Executable File
107 lines
3.5 KiB
Bash
Executable File
#!/bin/bash -e
|
|
|
|
# Free but less accurate GeoLite2 data created by MaxMind: https://www.maxmind.com . Requires license key.
|
|
# Updated twice weekly, every Tuesday and Friday.
|
|
# Each account (license key) is limited to 2000 total direct downloads in a 24 hour period.
|
|
|
|
: ${VAR_D:="/usr/local/psa/var/modules/firewall/geoip/`basename "$0"`.d"}
|
|
: ${EDITION_TYPE:="GeoLite2"}
|
|
EDITION_ID="$EDITION_TYPE-Country-CSV"
|
|
|
|
die()
|
|
{
|
|
echo "`basename "$0"`: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
load_settings()
|
|
{
|
|
[ ! -s "$VAR_D/settings.sh" ] || . "$VAR_D/settings.sh"
|
|
}
|
|
|
|
save_settings()
|
|
{
|
|
cat > "./settings.sh" <<-EOT
|
|
: \${DOWNLOAD_TIMEOUT:=$DOWNLOAD_TIMEOUT}
|
|
: \${LICENSE_KEY:=$LICENSE_KEY}
|
|
EOT
|
|
}
|
|
|
|
exists()
|
|
{
|
|
[ -s "$VAR_D/db.sqlite3" ]
|
|
}
|
|
|
|
fetch()
|
|
{
|
|
load_settings
|
|
|
|
[ "$EDITION_TYPE" = "GeoLite2" -o "$EDITION_TYPE" = "GeoIP2" ] ||
|
|
die "Unsupported MaxMind EDITION_TYPE='$EDITION_TYPE'"
|
|
[ -n "$LICENSE_KEY" ] ||
|
|
die "Missing MaxMind LICENSE_KEY"
|
|
|
|
rm -rf "$VAR_D".*
|
|
mkdir -p "`dirname "$VAR_D"`"
|
|
|
|
local tgt_d=
|
|
tgt_d="`mktemp -d "$VAR_D.XXXXXX"`"
|
|
chmod 700 "$tgt_d"
|
|
cd "$tgt_d"
|
|
|
|
# Database structure: https://dev.maxmind.com/geoip/docs/databases/city-and-country
|
|
local url="https://download.maxmind.com/app/geoip_download?edition_id=$EDITION_ID&license_key=$LICENSE_KEY&suffix=zip"
|
|
date --utc --rfc-3339=seconds > updated-at
|
|
save_settings
|
|
curl ${DOWNLOAD_TIMEOUT:+-m "$DOWNLOAD_TIMEOUT"} -fsSL "$url" -o dbip-csv.zip
|
|
unzip -jq dbip-csv.zip
|
|
sqlite3 db.sqlite3 <<-EOT
|
|
-- CentOS 7 has SQLite 3.7.17, which doesn't auto-create tables based on CSV header
|
|
CREATE TABLE blocks_ipv4 (network TEXT, geoname_id TEXT, registered_country_geoname_id TEXT,
|
|
represented_country_geoname_id TEXT, is_anonymous_proxy TEXT, is_satellite_provider TEXT);
|
|
CREATE TABLE blocks_ipv6 (network TEXT, geoname_id TEXT, registered_country_geoname_id TEXT,
|
|
represented_country_geoname_id TEXT, is_anonymous_proxy TEXT, is_satellite_provider TEXT);
|
|
CREATE TABLE locations_en(geoname_id TEXT, locale_code TEXT, continent_code TEXT,
|
|
continent_name TEXT, country_iso_code TEXT, country_name TEXT, is_in_european_union TEXT);
|
|
CREATE INDEX blocks_ipv4_geoname_id ON blocks_ipv4 (geoname_id);
|
|
CREATE INDEX blocks_ipv6_geoname_id ON blocks_ipv6 (geoname_id);
|
|
CREATE INDEX locations_en_code_geoname_id ON locations_en (country_iso_code, geoname_id);
|
|
.mode csv
|
|
.import $EDITION_TYPE-Country-Blocks-IPv4.csv blocks_ipv4
|
|
.import $EDITION_TYPE-Country-Blocks-IPv6.csv blocks_ipv6
|
|
.import $EDITION_TYPE-Country-Locations-en.csv locations_en
|
|
-- Since the tables already existed on import, header is also imported as data, remove it
|
|
DELETE FROM blocks_ipv4 WHERE geoname_id = 'geoname_id';
|
|
DELETE FROM blocks_ipv6 WHERE geoname_id = 'geoname_id';
|
|
DELETE FROM locations_en WHERE geoname_id = 'geoname_id';
|
|
EOT
|
|
for table in blocks_ipv4 blocks_ipv6 locations_en; do
|
|
[ "`sqlite3 db.sqlite3 "SELECT count(*) FROM $table;"`" -gt 0 ] ||
|
|
die "Table '$table' in the downloaded DB is empty"
|
|
done
|
|
rm -f dbip-csv.zip *.csv
|
|
|
|
rm -rf "$VAR_D"
|
|
mv -fT "$tgt_d" "$VAR_D"
|
|
}
|
|
|
|
list()
|
|
{
|
|
local country="$1"
|
|
[ -n "$country" ] || die "--list requires a single 2-letter ISO country code argument"
|
|
|
|
sqlite3 "$VAR_D/db.sqlite3" "
|
|
SELECT network FROM blocks_ipv4 b INNER JOIN locations_en l ON b.geoname_id = l.geoname_id
|
|
WHERE l.country_iso_code = '$country';
|
|
SELECT network FROM blocks_ipv6 b INNER JOIN locations_en l ON b.geoname_id = l.geoname_id
|
|
WHERE l.country_iso_code = '$country';
|
|
"
|
|
}
|
|
|
|
case "$1" in
|
|
--exists) exists ;;
|
|
--fetch) fetch ;;
|
|
--list) list "$2" ;;
|
|
*) die "Unknown command: '$1'" ;;
|
|
esac
|