File: //bigscoots/wpo/security/blocklist_client.sh
#!/bin/bash
# Config paths
CENTRAL_CONF_URL="https://restracted.bigscoots-sys.com/blocklists/map_blockip_central.conf"
BLOCK_CONF="/usr/local/nginx/conf/map_blockip.conf"
BLOCK_CHECK_CONF="/usr/local/nginx/conf/block_check.conf"
NGINX_INCLUDE_LINE="include /usr/local/nginx/conf/map_blockip.conf;"
# Source common functions (includes ngxreload_t, send_slack_alert, etc.)
source /bigscoots/includes/common.sh
ACTION=$1
SKIP_NGINX=false
[[ "$2" == "--skip-nginx" ]] && SKIP_NGINX=true
# Helpers
send_json_response() {
local status=$1
local message=$2
local result=$3
echo "{\"errors\":[],\"messages\":[],\"success\":$status,\"result\":$result,\"message\":\"$message\"}" | jq '.'
}
# Ensure nginx.conf includes the map file
ensure_nginx_includes() {
if ! grep -qF "$NGINX_INCLUDE_LINE" /usr/local/nginx/conf/nginx.conf; then
last_map_hash_line=$(grep -n '^\s*map_hash_' /usr/local/nginx/conf/nginx.conf | tail -n1 | cut -d: -f1)
if [[ -n "$last_map_hash_line" ]]; then
insert_line=$((last_map_hash_line + 1))
sed -i "${insert_line}i $NGINX_INCLUDE_LINE" /usr/local/nginx/conf/nginx.conf
else
sed -i "/http {/a $NGINX_INCLUDE_LINE" /usr/local/nginx/conf/nginx.conf
fi
fi
}
# Ensure block_check.conf exists and is included in all ssl.conf vhosts
ensure_block_check() {
local include_line="include $BLOCK_CHECK_CONF;"
if [[ ! -s "$BLOCK_CHECK_CONF" ]]; then
echo -e 'if ($block_reason != "") {\n return 444;\n}' > "$BLOCK_CHECK_CONF"
fi
for file in /usr/local/nginx/conf/conf.d/*.ssl.conf; do
if grep -qF "$include_line" "$file"; then
continue
fi
if grep -q '^\s*root ' "$file"; then
sed -i "/^\s*root /a\ $include_line" "$file"
fi
done
}
case "$ACTION" in
sync)
tmpfile=$(mktemp)
trap "rm -f $tmpfile" EXIT
# 1. Ensure infra exists (always, regardless of --skip-nginx)
ensure_nginx_includes
ensure_block_check
# 2. Fetch the new list
if ! curl -sSf "$CENTRAL_CONF_URL" -o "$tmpfile"; then
send_json_response false "Failed to fetch central blocklist conf." "{}"
exit 1
fi
# Sanity check
if ! grep -q 'geo \$remote_addr' "$tmpfile"; then
send_json_response false "Downloaded file does not look like a valid nginx geo block." "{}"
exit 1
fi
# 3. Check for changes
# Note: If ensure_block_check just created a file, nginx still needs a reload
# but only if nginx -t passes.
if [[ -f "$BLOCK_CONF" ]] && cmp -s "$tmpfile" "$BLOCK_CONF"; then
# If the files match, we check if nginx is happy.
# If it's not (e.g. we just created block_check.conf), we reload.
if [[ "$SKIP_NGINX" == false ]] && ! nginx -t >/dev/null 2>&1; then
ngxreload_t "Blocklist infra fixed, reloading nginx"
fi
send_json_response true "Blocklist up to date." "{\"reloaded\": false}"
exit 0
fi
# 4. If changed, move and reload
mv "$tmpfile" "$BLOCK_CONF"
if [[ "$SKIP_NGINX" == false ]]; then
ngxreload_t "Blocklist sync updated on $(hostname)"
send_json_response true "Blocklist synced and nginx reloaded." "{\"reloaded\": true}"
else
send_json_response true "Blocklist synced. Nginx reload skipped." "{\"reloaded\": false}"
fi
;;
*)
send_json_response false "Invalid action. Use: sync [--skip-nginx]" "{}"
exit 1
;;
esac