#!/usr/bin/env bash # Deploy fe_http + fail2ban fix on HAProxy host. Preserves stats auth from live config. set -euo pipefail NEW_CFG="${1:-/tmp/haproxy.cfg.new}" F2B_FILTER="${2:-/tmp/haproxy-zabbix-403.conf}" LIVE_CFG="/etc/haproxy/haproxy.cfg" TS="$(date +%Y%m%d-%H%M%S)" if [[ ! -f "$NEW_CFG" ]]; then echo "Missing $NEW_CFG" >&2 exit 1 fi STATS_AUTH="$(grep -E '^[[:space:]]+stats auth ' "$LIVE_CFG" | head -1 | sed 's/^[[:space:]]*//')" if [[ -z "$STATS_AUTH" ]]; then echo "Could not read stats auth from $LIVE_CFG" >&2 exit 1 fi MERGED="/tmp/haproxy.cfg.merged-${TS}" cp "$NEW_CFG" "$MERGED" # Replace placeholder; stats line has no spaces in password sed -i "s|stats auth admin:CHANGEME|${STATS_AUTH}|" "$MERGED" echo "Backup: ${LIVE_CFG}.bak-${TS}" cp "$LIVE_CFG" "${LIVE_CFG}.bak-${TS}" echo "=== merged checks ===" grep 'Config version' "$MERGED" grep -E 'frontend fe_http|fe_http_zabbix|be_exchange_http' "$MERGED" grep -E '^[[:space:]]+stats auth ' "$MERGED" haproxy -c -f "$MERGED" cp "$MERGED" "$LIVE_CFG" systemctl reload haproxy echo "HAProxy reloaded OK" if [[ -f "$F2B_FILTER" ]]; then cp "$F2B_FILTER" /etc/fail2ban/filter.d/haproxy-zabbix-403.conf systemctl reload fail2ban || fail2ban-client reload echo "fail2ban filter updated" fi for jail in haproxy-zabbix-403 haproxy-reject sshd; do if fail2ban-client status "$jail" >/dev/null 2>&1; then banned="$(fail2ban-client status "$jail" | sed -n 's/.*Banned IP list:[[:space:]]*//p')" if [[ -n "${banned// }" ]]; then for ip in $banned; do fail2ban-client set "$jail" unbanip "$ip" echo "unbanned $ip from $jail" done fi fi done if fail2ban-client unban --all >/dev/null 2>&1; then fail2ban-client unban --all echo "fail2ban-client unban --all done" fi echo "=== final ===" grep 'Config version' "$LIVE_CFG" fail2ban-client status haproxy-zabbix-403 | grep -E 'Currently banned|Banned IP' fail2ban-client status haproxy-reject | grep -E 'Currently banned|Banned IP'