fail2ban, інтеграція ipset
Встановлення fail2ban
apt install fail2ban
Вилізла якась фігня:
Setting up python3-pyasyncore (1.0.2-2) ...
Setting up fail2ban (1.0.2-3ubuntu0.1) ...
/usr/lib/python3/dist-packages/fail2ban/tests/fail2banregextestcase.py:224: SyntaxWarning: invalid escape sequence '\s'
"1490349000 test failed.dns.ch", "^\s*test <F-ID>\S+</F-ID>"
/usr/lib/python3/dist-packages/fail2ban/tests/fail2banregextestcase.py:435: SyntaxWarning: invalid escape sequence '\S'
'^'+prefix+'<F-ID>User <F-USER>\S+</F-USER></F-ID> not allowed\n'
/usr/lib/python3/dist-packages/fail2ban/tests/fail2banregextestcase.py:443: SyntaxWarning: invalid escape sequence '\S'
'^'+prefix+'User <F-USER>\S+</F-USER> not allowed\n'
/usr/lib/python3/dist-packages/fail2ban/tests/fail2banregextestcase.py:444: SyntaxWarning: invalid escape sequence '\d'
'^'+prefix+'Received disconnect from <F-ID><ADDR> port \d+</F-ID>'
/usr/lib/python3/dist-packages/fail2ban/tests/fail2banregextestcase.py:451: SyntaxWarning: invalid escape sequence '\s'
_test_variants('common', prefix="\s*\S+ sshd\[<F-MLFID>\d+</F-MLFID>\]:\s+")
/usr/lib/python3/dist-packages/fail2ban/tests/fail2banregextestcase.py:537: SyntaxWarning: invalid escape sequence '\['
'common[prefregex="^svc\[<F-MLFID>\d+</F-MLFID>\] connect <F-CONTENT>.+</F-CONTENT>$"'
/usr/lib/python3/dist-packages/fail2ban/tests/servertestcase.py:1375: SyntaxWarning: invalid escape sequence '\s'
"`{ nft -a list chain inet f2b-table f2b-chain | grep -oP '@addr-set-j-w-nft-mp\s+.*\s+\Khandle\s+(\d+)$'; } | while read -r hdl; do`",
/usr/lib/python3/dist-packages/fail2ban/tests/servertestcase.py:1378: SyntaxWarning: invalid escape sequence '\s'
"`{ nft -a list chain inet f2b-table f2b-chain | grep -oP '@addr6-set-j-w-nft-mp\s+.*\s+\Khandle\s+(\d+)$'; } | while read -r hdl; do`",
/usr/lib/python3/dist-packages/fail2ban/tests/servertestcase.py:1421: SyntaxWarning: invalid escape sequence '\s'
"`{ nft -a list chain inet f2b-table f2b-chain | grep -oP '@addr-set-j-w-nft-ap\s+.*\s+\Khandle\s+(\d+)$'; } | while read -r hdl; do`",
/usr/lib/python3/dist-packages/fail2ban/tests/servertestcase.py:1424: SyntaxWarning: invalid escape sequence '\s'
"`{ nft -a list chain inet f2b-table f2b-chain | grep -oP '@addr6-set-j-w-nft-ap\s+.*\s+\Khandle\s+(\d+)$'; } | while read -r hdl; do`",
Created symlink /etc/systemd/system/multi-user.target.wants/fail2ban.service → /usr/lib/systemd/system/fail2ban.service.
Setting up python3-pyinotify (0.9.6-2ubuntu1) ...
Processing triggers for man-db (2.12.0-4build2) ...
Scanning processes...
Scanning linux images...
Підтримка IPv6
Якщо сервер підтримує IPv6, то пропиши "allowipv6 = yes" у /etc/fail2ban/fail2ban.conf
:
# Option: allowipv6
# Notes.: Allows IPv6 interface:
# Default: auto
# Values: [ auto yes (on, true, 1) no (off, false, 0) ] Default: auto
allowipv6 = yes
Інакше буде вилазити попередження: "WARNING 'allowipv6' not defined in 'Definition'. Using default one: 'auto'"
Встановлюю правила iptables скриптом /root/adm/iptables_init/iptables_setup.sh (там же додаються наші сформовані ipset набори):
#!/bin/bash
echo "[+] Налаштування IPv4 фаєрвола..."
# --- IPv4 ---
# Очистити правила
iptables -F
iptables -X
iptables -Z
iptables -t nat -F
iptables -t nat -X
# --- IPSET блокування ботів IPv4 ---
if ! ipset list banned_inet4 &>/dev/null; then
ipset create banned_inet4 hash:ip family inet
echo "[+] Створено IPSET banned_inet4"
fi
iptables -I INPUT -m set --match-set banned_inet4 src -j DROP
# Політики за замовчуванням
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Дозволити loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Дозволити встановлені з'єднання
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# --- Відсікання некоректних пакетів ---
iptables -A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
# --- Захист від ping flood ---
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
# HTTP (80) — без ліміту
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# HTTPS (443) — без ліміту
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# SSH (2202) — з лімітом: 5 нових з'єднань/хв з одного IP
iptables -A INPUT -p tcp --dport 2202 -m conntrack --ctstate NEW \
-m hashlimit --hashlimit-name ssh_limit \
--hashlimit-above 5/minute --hashlimit-burst 5 \
--hashlimit-mode srcip --hashlimit-htable-expire 300000 \
-j DROP
iptables -A INPUT -p tcp --dport 2202 -j ACCEPT
# --- Поштова частина IPv4 ---
# SMTP (25) — для прийому пошти від інших серверів
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
# Submission (587)
iptables -A INPUT -p tcp --dport 587 -m conntrack --ctstate NEW \
-m hashlimit --hashlimit-name mail_submit_limit \
--hashlimit-above 20/minute --hashlimit-burst 20 \
--hashlimit-mode srcip --hashlimit-htable-expire 300000 \
-j DROP
iptables -A INPUT -p tcp --dport 587 -j ACCEPT
# SMTPS (465)
iptables -A INPUT -p tcp --dport 465 -j ACCEPT
# POP3S (995)
iptables -A INPUT -p tcp --dport 995 -j ACCEPT
# IMAPS (993)
iptables -A INPUT -p tcp --dport 993 -j ACCEPT
echo "[+] Налаштування IPv6 фаєрвола..."
# --- IPv6 ---
# Очистити правила
ip6tables -F
ip6tables -X
ip6tables -Z
# --- IPSET блокування ботів IPv6 ---
if ! ipset list banned_inet6 &>/dev/null; then
ipset create banned_inet6 hash:ip family inet6
echo "[+] Створено IPSET banned_inet6"
fi
ip6tables -I INPUT -m set --match-set banned_inet6 src -j DROP
# Політики за замовчуванням
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT ACCEPT
# Дозволити loopback
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT
# Дозволити встановлені з'єднання
ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# --- Відсікання некоректних пакетів ---
ip6tables -A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
ip6tables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
ip6tables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
ip6tables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
ip6tables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
ip6tables -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
# --- ICMPv6 ---
# Дозволити важливі типи ICMPv6
ip6tables -A INPUT -p icmpv6 -m icmp6 --icmpv6-type router-solicitation -j ACCEPT
ip6tables -A INPUT -p icmpv6 -m icmp6 --icmpv6-type router-advertisement -j ACCEPT
ip6tables -A INPUT -p icmpv6 -m icmp6 --icmpv6-type neighbor-solicitation -j ACCEPT
ip6tables -A INPUT -p icmpv6 -m icmp6 --icmpv6-type neighbor-advertisement -j ACCEPT
ip6tables -A INPUT -p icmpv6 -m icmp6 --icmpv6-type packet-too-big -j ACCEPT
ip6tables -A INPUT -p icmpv6 -m icmp6 --icmpv6-type time-exceeded -j ACCEPT
# Ліміт для echo-request (ping)
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j DROP
# HTTP (80)
ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT
# HTTPS (443)
ip6tables -A INPUT -p tcp --dport 443 -j ACCEPT
# SSH (2202) з лімітом
ip6tables -A INPUT -p tcp --dport 2202 -m conntrack --ctstate NEW \
-m hashlimit --hashlimit-name ssh_limit_v6 \
--hashlimit-above 5/minute --hashlimit-burst 5 \
--hashlimit-mode srcip --hashlimit-htable-expire 300000 \
-j DROP
ip6tables -A INPUT -p tcp --dport 2202 -j ACCEPT
echo "[+] Збереження правил..."
netfilter-persistent save
echo "[+] Готово. Поточні правила:"
iptables -L -n -v
ip6tables -L -n -v
(GPT постійно щось змінює, каже, в цілому - ок, але є зауваження. Це - останній варіант, каже ок)
Автоматичне додавання IP в ipset
Створюємо action для fail2ban - action.d/ipset-multi.conf
, який буде додавати IPv4 і IPv6 в один бан-сет.
nano /etc/fail2ban/action.d/ipset-multi.conf
на slava це ipset-dirtybots.conf
(і там зараз два окремих набори) !
[Definition]
# Додає/видаляє IP у правильний ipset залежно від типу адреси
# При старті jail створюємо набори (якщо їх ще нема)
actionstart = ipset create banned_inet4 hash:ip family inet -exist
ipset create banned_inet6 hash:ip family inet6 -exist
# При зупинці jail не видаляємо набори, тільки очищаємо
actionstop = ipset flush banned_inet4
ipset flush banned_inet6
# Перевірка наявності наборів
actioncheck = ipset list banned_inet4
ipset list banned_inet6
# Додаємо IP у набір IPv4/6
actionban = ipset add banned_<family> <ip> -exist
# Видаляємо IP з набору IPv4/6
actionunban = ipset del banned_<family> <ip> -exist
# fail2ban підставляє <ipversion> автоматично: "4" для IPv4, "6" для IPv6
[Init]
# Ніяких додаткових параметрів не треба
Тобто ми взяли стартові набори banned_ipv4.txt та banned_ipv6.txt і завантажили один раз у ipset під час першого запуску. Після цього їх редагувати не потрібно — всі нові IP з Fail2Ban автоматично додаються у ті ж набори.
на slava це /etc/fail2ban/action.d/ipset-dirtybots.conf
!
[Definition]
# Створення наборів, якщо їх ще нема
actionstart = ipset create dirtybots4 hash:ip timeout 0 -exist && \
ipset create dirtybots6 hash:ip family inet6 timeout 0 -exist
# Очистка наборів при зупинці fail2ban
actionstop = ipset flush dirtybots4 && \
ipset flush dirtybots6
# Додавання IP в потрібний набір
actionban = (ipset add dirtybots4 <ip> timeout 0 -exist 2>/dev/null || true) && \
(ipset add dirtybots6 <ip> timeout 0 -exist 2>/dev/null || true)
# Видалення IP з набору
actionunban = (ipset del dirtybots4 <ip> 2>/dev/null || true) && \
(ipset del dirtybots6 <ip> 2>/dev/null || true)
[Init]
Last updated