Rate limiting, гео-блокировка, blacklist/whitelist, комбинированные ACL
Продвинутые техники ACL: rate limiting, гео-блокировка, комбинированные условия, защита от атак.
frontend http_front
bind *:80
# Stick table для отслеживания запросов
stick-table type ip size 100k expire 30s store http_req_rate(10s)
# Отслеживаем IP клиента
http-request track-sc0 src
# ACL для проверки rate limit
acl is_rate_limited sc_http_req_rate(0) gt 100
# Deny если превышен лимит
http-request deny deny_status 429 if is_rate_limited
default_backend web_serversПараметры stick-table:
type ip — ключ по IP адресуsize 100k — 100,000 записейexpire 30s — запись удаляется через 30s без активностиstore http_req_rate(10s) — счётчик запросов за 10 секундfrontend http_front
bind *:80
# Stick table по URL
stick-table type string size 50k expire 30s store http_req_rate(10s)
# Отслеживаем URL
http-request track-sc1 path
# Блокируем частые запросы на один URL
acl url_rate_limited sc_http_req_rate(1) gt 50
http-request deny deny_status 429 if url_rate_limited
default_backend web_serversЗащита от:
frontend http_front
bind *:80
# Whitelist IP
acl is_whitelist src -f /etc/haproxy/whitelist.txt
# Stick table
stick-table type ip size 100k expire 30s store http_req_rate(10s)
http-request track-sc0 src
# Rate limit только для не-whitelist
acl is_rate_limited sc_http_req_rate(0) gt 100
http-request deny deny_status 429 if is_rate_limited !is_whitelist
default_backend web_serversfrontend http_front
bind *:80
stick-table type ip size 100k expire 30s store http_req_rate(10s),http_req_rate(1m)
http-request track-sc0 src
# Строгий лимит на коротком окне
acl burst_rate_limited sc_http_req_rate(0) gt 100
# Мягкий лимит на длинном окне
avg_rate_limited sc_http_req_rate(0,1m) gt 30
http-request deny deny_status 429 if burst_rate_limited
http-request deny deny_status 429 if avg_rate_limited
default_backend web_servers# Загрузка GeoIP баз (требуется внешний скрипт для обновления)
acl blocked_countries src -f /etc/haproxy/geo/blocked_countries.txt
http-request deny deny_status 403 if blocked_countriesГенерация файла (внешний скрипт):
# Пример: блокировка стран по кодам
# blocked_countries.txt содержит IP диапазоны
RU 192.168.0.0/16
CN 10.0.0.0/8# Использование GeoIP базы данных
acl is_europe src -m geoip -f /usr/share/GeoIP/GeoIP.dat EU
acl is_north_america src -m geoip -f /usr/share/GeoIP/GeoIP.dat US CA
use_backend eu_servers if is_europe
use_backend na_servers if is_north_america
default_backend global_serversТребования:
# Если за HAProxy стоит Cloudflare
acl blocked_country hdr(CF-IPCountry) CN RU KP
http-request deny deny_status 403 if blocked_countryЗаголовки Cloudflare:
CF-IPCountry — код страны клиентаfrontend http_front
bind *:80
# Загрузка blacklist
acl is_blacklisted src -f /etc/haproxy/blacklist_ips.txt
# Логирование блокировок
http-request set-header X-Blocked-Reason blacklist if is_blacklisted
http-request deny deny_status 403 if is_blacklisted
default_backend web_serversblacklist_ips.txt:
# Known bad actors
192.168.1.100
10.0.0.0/8
172.16.0.0/12
frontend http_front
bind *:80
# Блокировка сканеров и ботов
acl bad_bot hdr_sub(User-Agent) -i -f /etc/haproxy/bad_bots.txt
http-request deny deny_status 403 if bad_bot
default_backend web_serversbad_bots.txt:
scanner
crawler
spider
bot
curl
wget
python-requests
frontend http_front
bind *:80
# Блокировка опасных path
acl dangerous_path path_sub -i -f /etc/haproxy/dangerous_paths.txt
http-request deny deny_status 403 if dangerous_path
default_backend web_serversdangerous_paths.txt:
/wp-admin
/phpmyadmin
/.env
/.git
/config.php
frontend http_front
bind *:80
# API доступ только с авторизацией
acl is_api path_beg /api
acl has_auth hdr(Authorization) -m found
# Блокируем API без авторизации
http-request deny deny_status 401 if is_api !has_auth
# Admin доступ только из внутренней сети
acl is_admin path_beg /admin
acl is_internal src 10.0.0.0/8 172.16.0.0/12
http-request deny deny_status 403 if is_admin !is_internal
default_backend web_serversfrontend http_front
bind *:80
# Бизнес часы
acl business_hours hour 9-18
acl weekday day 2-6 # 2 = понедельник, 6 = пятница
# Ограниченный доступ вне бизнес часов
acl is_read_only method GET HEAD
http-request deny deny_status 403 if !business_hours weekday !is_read_only
default_backend web_serversfrontend http_front
bind *:80
# SQL injection patterns
acl sql_injection url_param -m regex "(union|select|insert|update|delete|drop|exec|script)"
acl sql_injection_body body -m regex "(union|select|insert|update|delete|drop)"
http-request deny deny_status 400 if sql_injection or sql_injection_body
default_backend web_serversfrontend http_front
bind *:80
# XSS patterns
acl xss_attack url_param -m regex "<script|javascript:|onerror=|onload="
http-request deny deny_status 400 if xss_attack
# Security headers
http-response set-header X-XSS-Protection "1; mode=block"
http-response set-header X-Content-Type-Options "nosniff"
default_backend web_serversfrontend http_front
bind *:80
# Path traversal
acl path_traversal path_sub ..
acl path_traversal path_sub %2e%2e
acl path_traversal path_sub %252e
http-request deny deny_status 400 if path_traversal
default_backend web_serversfrontend http_front
bind *:80
# Ограничение времени на отправку запроса
timeout http-request 5s
# Ограничение размера заголовков
tune.bufsize 16384
# Rate limiting
stick-table type ip size 100k expire 30s store http_req_rate(10s)
http-request track-sc0 src
acl is_rate_limited sc_http_req_rate(0) gt 100
http-request deny deny_status 429 if is_rate_limited
default_backend web_serversfrontend api_front
bind *:80
# Versioning через header
acl is_v1 hdr(X-API-Version) 1
acl is_v2 hdr(X-API-Version) 2
# Versioning через path
acl path_v1 path_beg /api/v1
acl path_v2 path_beg /api/v2
# Маршрутизация
use_backend api_v1_servers if is_v1 or path_v1
use_backend api_v2_servers if is_v2 or path_v2
default_backend api_v1_serversfrontend api_front
bind *:80
# Tenant из header
acl tenant_acme hdr(X-Tenant-ID) acme
acl tenant_globex hdr(X-Tenant-ID) globex
# Tenant из subdomain
acl tenant_acme hdr_sub(Host) acme.
acl tenant_globex hdr_sub(Host) globex.
use_backend acme_servers if tenant_acme
use_backend globex_servers if tenant_globex
default_backend default_serversfrontend api_front
bind *:80
# Canary для 10% трафика
acl is_canary src -m random 10
# Canary для конкретных пользователей
acl canary_users hdr(X-User-ID) -f /etc/haproxy/canary_users.txt
use_backend api_canary_servers if is_canary or canary_users
default_backend api_stable_servers# Показать ACL
echo "show acl" | socat /var/run/haproxy/admin.sock stdio
# Обновить ACL из файла
echo "update acl /etc/haproxy/blacklist_ips.txt" | socat /var/run/haproxy/admin.sock stdio
# Добавить запись в ACL
echo "add acl /etc/haproxy/blacklist_ips.txt 192.168.1.200" | socat /var/run/haproxy/admin.sock stdio# ACL с онлайн обновлением
acl dynamic_blacklist src -f /etc/haproxy/dynamic_blacklist.txt
frontend http_front
bind *:80
stick-table type ip size 100k expire 30s store http_req_rate(10s)
http-request track-sc0 src
# Автоблокировка при rate limit
acl is_rate_limited sc_http_req_rate(0) gt 100
http-request deny deny_status 429 if is_rate_limited
# Добавление в blacklist при повторном нарушении
http-request add-acl /etc/haproxy/dynamic_blacklist.txt %[src] if is_rate_limited
default_backend web_serversfrontend https_front
bind *:443 ssl crt /etc/haproxy/certs/site.pem
# === Security ACLs ===
acl is_blacklisted src -f /etc/haproxy/blacklist_ips.txt
acl bad_bot hdr_sub(User-Agent) -i -f /etc/haproxy/bad_bots.txt
acl dangerous_path path_sub -i -f /etc/haproxy/dangerous_paths.txt
# === Rate Limiting ===
stick-table type ip size 100k expire 30s store http_req_rate(10s)
http-request track-sc0 src
acl is_rate_limited sc_http_req_rate(0) gt 100
# === API ACLs ===
acl is_api path_beg /api
acl has_auth hdr(Authorization) -m found
acl is_admin path_beg /admin
acl is_internal src 10.0.0.0/8 172.16.0.0/12
# === Блокировки ===
http-request deny deny_status 403 if is_blacklisted
http-request deny deny_status 403 if bad_bot
http-request deny deny_status 400 if dangerous_path
http-request deny deny_status 429 if is_rate_limited
http-request deny deny_status 401 if is_api !has_auth
http-request deny deny_status 403 if is_admin !is_internal
# === Security Headers ===
http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains"
http-response set-header X-Frame-Options "SAMEORIGIN"
http-response set-header X-Content-Type-Options "nosniff"
http-response set-header X-XSS-Protection "1; mode=block"
default_backend web_serversИзучим stickiness и сессии: cookie-based sessions, source IP persistence, stick-tables.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.