Files
reverse-proxy/scripts/haproxy_ru_ipdeny_lib.sh
T

102 lines
2.9 KiB
Bash

#!/usr/bin/env bash
# Shared helpers: ipdeny ru.zone -> HAProxy src -f allowlist (bash, no pip).
# Логика из Answer.and.other.shit/scripts/mikrotik-ru-ipdeny/mikrotik_ru_ipdeny_lib.sh
set -Eeuo pipefail
DEFAULT_ZONE_URL="${IPDENY_ZONE_URL:-https://www.ipdeny.com/ipblocks/data/countries/ru.zone}"
DEFAULT_MIN_LINES="${HAPROXY_MIN_ENTRIES:-8000}"
die() {
echo "error: $*" >&2
exit 1
}
fetch_zone() {
local url=$1
local dest=$2
curl -fsSL --max-time 120 -A "haproxy-ru-ipdeny/1.0" "$url" -o "$dest"
}
count_subnets_in_zone() {
local zone_file=$1
local count=0
local line
while IFS= read -r line || [[ -n $line ]]; do
line="${line//$'\r'/}"
line="${line#"${line%%[![:space:]]*}"}"
line="${line%"${line##*[![:space:]]}"}"
[[ -z $line || $line == \#* ]] && continue
[[ $line != */* ]] && continue
count=$((count + 1))
done <"$zone_file"
printf '%s' "$count"
}
write_zone_allowlist() {
local zone_file=$1
local output_path=$2
{
while IFS= read -r line || [[ -n $line ]]; do
line="${line//$'\r'/}"
line="${line#"${line%%[![:space:]]*}"}"
line="${line%"${line##*[![:space:]]}"}"
[[ -z $line || $line == \#* ]] && continue
[[ $line != */* ]] && continue
printf '%s\n' "$line"
done <"$zone_file"
} >"$output_path"
}
append_static_allowlist() {
local static_file=$1
local output_path=$2
[[ -f $static_file ]] || return 0
while IFS= read -r line || [[ -n $line ]]; do
line="${line//$'\r'/}"
line="${line#"${line%%[![:space:]]*}"}"
line="${line%"${line##*[![:space:]]}"}"
[[ -z $line || $line == \#* ]] && continue
printf '%s\n' "$line"
done <"$static_file" >>"$output_path"
}
generate_allowlist_bundle() {
local zone_url=${1:-$DEFAULT_ZONE_URL}
local output_path=${2:-}
local static_file=${3:-}
local min_lines=${4:-$DEFAULT_MIN_LINES}
[[ -n $output_path ]] || die "output path required"
local tmp_zone merged
tmp_zone=$(mktemp)
merged=$(mktemp)
trap "rm -f '${tmp_zone}' '${merged}'" RETURN
fetch_zone "$zone_url" "$tmp_zone"
local zone_entries
zone_entries=$(count_subnets_in_zone "$tmp_zone")
if [[ $zone_entries -lt $min_lines ]]; then
die "too few subnets: ${zone_entries} (expected at least ${min_lines})"
fi
write_zone_allowlist "$tmp_zone" "$merged"
append_static_allowlist "$static_file" "$merged"
sort -u "$merged" >"$output_path"
local total_entries bytes
total_entries=$(wc -l <"$output_path" | tr -d '[:space:]')
bytes=$(wc -c <"$output_path" | tr -d '[:space:]')
rm -f "$tmp_zone" "$merged"
trap - RETURN
GENERATED_ZONE_ENTRIES=$zone_entries
GENERATED_ENTRIES=$total_entries
GENERATED_BYTES=$bytes
GENERATED_OUTPUT=$output_path
}