feat(security): fail2ban для HAProxy JSON reject и Zabbix 403.

This commit is contained in:
PTah
2026-06-15 15:03:30 +10:00
parent 2ce71df1f8
commit cd14f0a1c4
8 changed files with 115 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
#!/usr/bin/env bash
# Установка fail2ban filter/jail для HAProxy JSON-лога.
# sudo bash fail2ban-install.sh
# sudo bash fail2ban-install.sh --test # только fail2ban-regex
set -Eeuo pipefail
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
F2B_DIR="$SCRIPT_DIR/fail2ban"
TEST_ONLY=0
die() { echo "error: $*" >&2; exit 1; }
log() { echo "[*] $*"; }
while [[ $# -gt 0 ]]; do
case "$1" in
--test) TEST_ONLY=1; shift ;;
-h | --help)
echo "Usage: fail2ban-install.sh [--test]"
exit 0
;;
*) die "unknown option: $1" ;;
esac
done
[[ -d $F2B_DIR ]] || die "missing $F2B_DIR"
command -v fail2ban-client >/dev/null 2>&1 || die "install fail2ban first (apt install fail2ban)"
install -m 0644 "$F2B_DIR/haproxy-json-reject.conf" /etc/fail2ban/filter.d/haproxy-json-reject.conf
install -m 0644 "$F2B_DIR/haproxy-zabbix-403.conf" /etc/fail2ban/filter.d/haproxy-zabbix-403.conf
install -m 0644 "$F2B_DIR/haproxy.local" /etc/fail2ban/jail.d/haproxy.local
log "fail2ban-regex haproxy-json-reject"
fail2ban-regex /var/log/haproxy.log /etc/fail2ban/filter.d/haproxy-json-reject.conf | tail -8
if [[ $TEST_ONLY -eq 1 ]]; then
log "test only — jail not restarted"
exit 0
fi
fail2ban-client -t
systemctl enable fail2ban
systemctl restart fail2ban
sleep 1
fail2ban-client status
fail2ban-client status haproxy-reject
log "done"
@@ -0,0 +1,6 @@
[Definition]
# Сканеры и reject на fe_https_sni (неизвестный SNI, allowlist, мусор)
failregex = ^.*haproxy\[(?:\d+|master)\]: \{"time":"[^"]*","client":"<HOST>".*"fe":"fe_https_sni","be":"fe_https_sni","srv":"<NOSRV>"
ignoreregex =
@@ -0,0 +1,5 @@
[Definition]
failregex = ^.*haproxy\[(?:\d+|master)\]: <HOST>:\d+ \[[^\]]+\] fe_http_zabbix .* 403
ignoreregex =
+22
View File
@@ -0,0 +1,22 @@
[DEFAULT]
banaction = ufw
banaction_allports = ufw
allowipv6 = no
[haproxy-reject]
enabled = true
filter = haproxy-json-reject
logpath = /var/log/haproxy.log
maxretry = 15
findtime = 600
bantime = 86400
ignoreip = 127.0.0.1/8 192.168.160.0/24 192.168.128.0/17 5.100.81.121
[haproxy-zabbix-403]
enabled = true
filter = haproxy-zabbix-403
logpath = /var/log/haproxy.log
maxretry = 10
findtime = 600
bantime = 86400
ignoreip = 127.0.0.1/8 192.168.160.0/24 192.168.128.0/17 5.100.81.121
+5
View File
@@ -38,6 +38,7 @@ source "$ENV_FILE"
SSH_ALLOWED=${SSH_ALLOWED:-}
INBOUND_TCP=${INBOUND_TCP:-80 443}
LAN_BACKENDS_CIDR=${LAN_BACKENDS_CIDR:-192.168.160.0/24}
STATS_TCP=${STATS_TCP:-8404}
UFW_IPV6=${UFW_IPV6:-no}
@@ -73,6 +74,10 @@ for port in $INBOUND_TCP; do
run ufw allow "$port/tcp" comment "haproxy service $port"
done
if [[ -n ${LAN_BACKENDS_CIDR:-} ]]; then
run ufw allow from "$LAN_BACKENDS_CIDR" comment 'LAN backends return'
fi
if [[ $APPLY -eq 1 ]]; then
ufw --force enable
ufw status verbose
+1
View File
@@ -6,6 +6,7 @@ SSH_ALLOWED="5.100.81.121 192.168.128.0/17"
# С периметра (MikroTik DNAT) — для всех
INBOUND_TCP="80 443"
LAN_BACKENDS_CIDR="192.168.160.0/24"
# HAProxy stats (если fe_stats включён в haproxy.cfg)
STATS_TCP="8404"