feat(security): fail2ban для HAProxy JSON reject и Zabbix 403.
This commit is contained in:
@@ -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 =
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user