#! /bin/bash # Script Name: geoip_updater.sh # Description: This script checks for new GeoLite2 City database releases from # the specified GitHub repository, downloads the latest release # if it's not already present, and updates the local database # file. It ensures the destination directory is writable and # handles download and extraction of the database. # Usage: Execute without arguments. Designed to be run as a cron job or # manually as needed. # Exit immediately if a command exits with a non-zero status. set -e # Define variables DATE=${1:-$(date -I)} DEST_DIR="/usr/local/share/GeoIP" FN="GeoLite2-City-${DATE//-/}.tar.gz" URL="https://github.com/merkez/maxmind-databases/releases/download/${DATE}/${FN}" MMDB="GeoLite2-City.mmdb" DEST="${DEST_DIR}/GeoLite2-City-${DATE//-/}.mmdb" # Check if the target file is already downloaded check_if_file_is_already_downloaded() { if [ -e "$DEST" ]; then echo "File is already on the local filesystem" # ensure_symlink_exists exit 0 fi } # Verify destination directory is writable check_if_dest_dir_is_writable_by_user() { if [ ! -w "$DEST_DIR" ]; then echo "Destination directory is not writable: ${DEST_DIR}" >&2 exit 1 fi } # Check if the URL exists check_url_exists() { status_code=$(curl -o /dev/null -I -s -w "%{http_code}" "$URL") if [[ "$status_code" -eq 404 ]]; then echo "No new release for today!" exit 0 elif [[ "$status_code" -ge 400 && "$status_code" -lt 500 ]]; then echo "Client-side error detected: $status_code" >&2 exit 1 elif [[ "$status_code" -ge 500 && "$status_code" -lt 600 ]]; then echo "Server-side error detected: $status_code" >&2 exit 1 fi } # Download the GeoIP package download_geoip_package() { echo "Downloading ${URL}" wget -qO "/tmp/${FN}" "$URL" } # Extract the MMDB file from the downloaded package extract_mmdb() { # Ensure extraction occurs in a temporary directory to avoid leaving behind unwanted folders pushd /tmp >/dev/null MMDB_PATH=$(tar -tzf "${FN}" | grep "${MMDB}" || true) if [ -n "$MMDB_PATH" ]; then tar -xzf "${FN}" "${MMDB_PATH}" && mv "${MMDB_PATH}" "$DEST" else echo "Failed to find ${MMDB} in the tarball." >&2 popd >/dev/null exit 1 fi # Cleanup the temporary directory by removing any extracted directories rm -rf "$(dirname "${MMDB_PATH}")" popd >/dev/null } # Clean up the temporary files clean_up() { rm -rf "/tmp/${FN}" "/tmp/$(dirname "${MMDB_PATH}")" } # Ensure the symlink to the latest database exists ensure_symlink_exists() { ln -s -f "$DEST" "${DEST_DIR}/${MMDB}" } # Main execution flow echo "Checking for the GeoLite2 City database release for ${DATE}" check_if_file_is_already_downloaded check_if_dest_dir_is_writable_by_user check_url_exists download_geoip_package extract_mmdb ensure_symlink_exists clean_up echo "GeoLite2 City database update completed."