< 自用文 OS 有關 > (續)發現正在被攻擊 后的自救 Fail2ban + IPset + UFW 工作流程詳解

繼上編:< 自用文 主機 USC 記錄:> 發現正在被攻擊 后的自救-CSDN博客

環境:

改進:

以下是把代碼,懶得寫,扔給了 AI ,讓它出的:

Fail2ban + IPset + UFW 工作流程詳解

工具概述

1. UFW (Uncomplicated Firewall)

  • 作用: iptables 的簡化前端
  • 功能: 基礎防火墻規則管理
  • 特點: 用戶友好的規則語法

2. IPset

  • 作用: IP地址集合管理工具
  • 功能: 高效存儲和匹配大量IP地址
  • 特點: 比傳統iptables規則更高效

3. Fail2ban

  • 作用: 入侵檢測和自動封禁系統
  • 功能: 分析日志、檢測攻擊、觸發封禁動作
  • 特點: 智能攻擊模式識別

完整工作流程

階段1: 初始化和基礎防護

[系統啟動] → [UFW啟動] → [建立基礎防火墻規則]↓
[IPset工具初始化] → [創建IP集合]↓
[Fail2ban啟動] → [讀取配置] → [開始監控日志]

階段2: 攻擊檢測流程

[攻擊者連接] → [服務日志記錄] → [Fail2ban監控]↓
[模式匹配] → [計數器增加] → [達到閾值?]↓              ↓              ↓[繼續監控]    [重置計數器]     [觸發封禁]

階段3: 封禁執行流程

[Fail2ban檢測到攻擊] ↓
[調用Action腳本]↓
[IPset添加惡意IP] → [ipset add fail2ban-ssh 192.168.1.100]↓
[UFW規則生效] → [DROP來自IPset集合的流量]↓
[攻擊者被阻斷]

技術架構圖

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   網絡流量      │────│   UFW/iptables  │────│   目標服務       │
│                 │    │                 │    │   (SSH/HTTP)    │
└─────────────────┘    └─────────────────┘    └─────────────────┘│                         ││                         │┌─────────────┐            ┌─────────────┐│   IPset     │            │   日志文件   ││  (IP集合)    │            │             │└─────────────┘            └─────────────┘│                         │└──────┬──────────────────┘│┌─────────────┐│  Fail2ban   ││  (監控分析)  │└─────────────┘

詳細配置示例

1. UFW基礎配置

# 啟用UFW
sudo ufw enable# 默認策略
sudo ufw default deny incoming
sudo ufw default allow outgoing# 允許SSH (在配置fail2ban之前)
sudo ufw allow ssh# 創建IPset規則 (UFW會自動處理)
# 實際在iptables中創建規則引用IPset

2. IPset配置

# 創建IP集合
sudo ipset create fail2ban-ssh hash:ip timeout 86400# 手動添加IP到集合 (通常由fail2ban自動執行)
sudo ipset add fail2ban-ssh 192.168.1.100# 查看集合內容
sudo ipset list fail2ban-ssh

3. Fail2ban配置 (/etc/fail2ban/jail.local)

[DEFAULT]
# 使用ipset作為封禁后端
banaction = iptables-ipset-proto6[name=fail2ban-ssh][sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
findtime = 600# 使用ipset action
action = iptables-ipset-proto6[name=fail2ban-ssh, port=ssh, protocol=tcp]

數據流詳解

1. 正常流量處理

外部請求 → UFW檢查 → 基礎規則匹配 → 允許通過 → 到達服務↓檢查IPset集合↓IP不在黑名單 → 繼續處理

2. 惡意流量處理

攻擊流量 → UFW檢查 → IPset集合匹配 → 發現惡意IP → 直接丟棄↓記錄封禁日志

3. 新攻擊檢測

新攻擊 → 到達服務 → 認證失敗 → 寫入日志↓Fail2ban監控 → 模式匹配 → 計數增加↓達到閾值 → 調用action → 添加IP到IPset↓下次請求 → UFW/IPset阻斷

性能優勢分析

傳統iptables方式

# 每個被封IP都要一條規則
iptables -I INPUT -s 192.168.1.100 -j DROP
iptables -I INPUT -s 192.168.1.101 -j DROP
iptables -I INPUT -s 192.168.1.102 -j DROP
# ... 可能有數千條規則

問題: 規則數量多時,匹配效率低下

IPset優化方式

# 只需一條規則引用整個集合
iptables -I INPUT -m set --match-set fail2ban-ssh src -j DROP# 所有IP存儲在高效的哈希表中
ipset add fail2ban-ssh 192.168.1.100
ipset add fail2ban-ssh 192.168.1.101
ipset add fail2ban-ssh 192.168.1.102

優勢: O(1) 時間復雜度查找,支持數萬IP

實際工作示例

場景:SSH暴力破解攻擊

  1. 攻擊開始

    攻擊者IP: 203.0.113.100
    連續嘗試SSH登錄,密碼錯誤
    
  2. 日志記錄

    /var/log/auth.log:
    Failed password for root from 203.0.113.100 port 22 ssh2
    Failed password for admin from 203.0.113.100 port 22 ssh2
    Failed password for user from 203.0.113.100 port 22 ssh2
    
  3. Fail2ban檢測

    fail2ban監控到3次失敗
    達到maxretry=3的閾值
    觸發封禁action
    
  4. IPset執行

    # Fail2ban執行命令
    ipset add fail2ban-ssh 203.0.113.100
    
  5. UFW/iptables生效

    # 現有規則開始匹配IPset
    iptables -I INPUT -m set --match-set fail2ban-ssh src -j DROP
    
  6. 結果

    攻擊者IP被立即阻斷
    后續請求直接在內核層面丟棄
    不再到達SSH服務
    

監控和管理

查看當前狀態

# 查看fail2ban狀態
sudo fail2ban-client status sshd# 查看IPset內容
sudo ipset list fail2ban-ssh# 查看UFW狀態
sudo ufw status verbose# 查看iptables規則
sudo iptables -L INPUT -n -v

手動管理

# 手動解封IP
sudo fail2ban-client set sshd unbanip 203.0.113.100# 直接從IPset移除
sudo ipset del fail2ban-ssh 203.0.113.100# 查看封禁歷史
sudo tail -f /var/log/fail2ban.log

優勢總結

  1. 高效性: IPset提供O(1)查找效率,支持大規模IP封禁
  2. 自動化: Fail2ban自動檢測和響應,減少人工干預
  3. 靈活性: UFW提供簡單的規則管理界面
  4. 可擴展: 支持多種服務和攻擊模式檢測
  5. 持久化: IPset支持超時和持久化存儲
  6. 資源節約: 比傳統方法消耗更少系統資源

這種組合為Linux系統提供了一套完整、高效的自動化安全防護解決方案。

代碼:僅 fail2ban+ipset?

這是我自用的裝機 bash script, 之前有分享過,因為有兩個 V 沒過審核,留著自已來。

主要功能:

現在這個腳本?15千行:

這里包含幾個 filter,測試腳本 ,還有硬寫的日志文件名(這需要替換),參考時要記得修改。

# 13. Install Fail2Ban
install_fail2ban() {log_function_start "Installing Fail2Ban with IPSet integration"log_info "Installing Fail2Ban with IPSet and UFW integration for enhanced security..."# Verify nobody user exists for service isolationverify_nobody_user || log_warning "Nobody user not available for service isolation"# Safe to stop and disable Fail2Ban if already runningsafe_stop_and_disable_service "fail2ban" "Fail2Ban service"# Remove any existing Fail2Ban packageslog_info "Removing any existing Fail2Ban packages..."apt remove --purge -y fail2ban || truelog_success "Existing Fail2Ban packages removed"# Clean up orphaned dependencieslog_info "Cleaning up orphaned dependencies..."apt autoremove -y || trueapt autoclean -y || truelog_success "Orphaned dependencies cleaned up"# Remove any existing Fail2Ban configuration fileslog_info "Removing any existing Fail2Ban configuration files..."rm -rf /etc/fail2ban/* 2>/dev/null || truelog_info "Removed existing Fail2Ban configuration files"rm -rf /var/lib/fail2ban/* 2>/dev/null || truelog_info "Removed existing Fail2Ban data files"rm -rf /var/log/fail2ban.log 2>/dev/null || truelog_info "Removed existing Fail2Ban log file"log_success "Existing Fail2Ban configuration files removed"# Check system requirements for Fail2Banlog_info "Checking system requirements for Fail2Ban..."# Check log filesif [ ! -f /var/log/auth.log ]; thenlog_warning "Auth log file not found at /var/log/auth.log"touch /var/log/auth.logchmod 640 /var/log/auth.logchown root:adm /var/log/auth.logsleep 1log_info "Created missing auth log file at /var/log/auth.log with correct permissions"log_success "Auth log file created successfully"elselog_success "Auth log file found at /var/log/auth.log"fi# Check UFW statusif ! command -v ufw >/dev/null; thenlog_error "UFW is not installed. Installing it now..."if configure_ufw; thenlog_success "UFW installed and configured successfully"elselog_error "Failed to install UFW. Fail2Ban installation cannot proceed."log_function_end "Installing Fail2Ban" 1return 1fielselog_success "UFW is installed and available"fi# Install and configure IPSetlog_info "Installing IPSet package..."if apt install -y ipset; thenlog_success "IPSet installed successfully"elselog_error "Failed to install IPSet"log_function_end "Installing Fail2Ban with IPSet" 1return 1fi# Clean up any existing ipsetslog_info "Cleaning up any existing fail2ban ipsets..."ipset destroy fail2ban-banned 2>/dev/null || trueipset destroy fail2ban-recidive 2>/dev/null || truelog_info "Existing fail2ban ipsets cleaned up"# Create IPSet for fail2banlog_info "Creating IPSet for fail2ban..."if ipset create fail2ban-banned hash:ip timeout 0 2>/dev/null; thenlog_success "Created IPSet 'fail2ban-banned'"elselog_error "Failed to create IPSet 'fail2ban-banned'"log_function_end "Creating IPSet for fail2ban" 1return 1fi# Create additional IPSet for recidive (repeat offenders)log_info "Creating IPSet for repeat offenders..."if ipset create fail2ban-recidive hash:ip timeout 0 2>/dev/null; thenlog_success "Created IPSet 'fail2ban-recidive'"elselog_warning "Failed to create IPSet 'fail2ban-recidive' (may already exist)"fi# Create the initial persistent file for IPSet ruleslog_info "Creating the initial persistent file for IPSet rules..."if ipset save > /etc/ipset.rules; thenlog_success "Created the initial persistent file for IPSet rules"elselog_error "Failed to create the initial persistent file for IPSet rules"log_function_end "Creating the initial persistent file for IPSet rules" 1return 1fi# Create IPSet persistence servicelog_info "Creating IPSet persistence service..."cat > /etc/systemd/system/ipset-persistent.service << 'EOF'
[Unit]
Description=IPSet persistent rule service
Before=netfilter-persistent.service network-pre.target ufw.service fail2ban.service
ConditionFileNotEmpty=/etc/ipset.rules[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/ipset restore -exist -file /etc/ipset.rules
ExecStop=/sbin/ipset save -file /etc/ipset.rules
ExecReload=/sbin/ipset save -file /etc/ipset.rules[Install]
WantedBy=multi-user.target
EOFlog_success "Created IPSet persistence service"# Enable IPSet persistencesystemctl daemon-reloadsystemctl enable ipset-persistent.servicelog_success "Enabled IPSet persistence via systemd"# Create IPSet save script for graceful shutdownlog_info "Creating IPSet save script..."cat > /etc/systemd/system/ipset-save.service << 'EOF'
[Unit]
Description=Save IPSet rules on shutdown
DefaultDependencies=false
Before=shutdown.target reboot.target halt.target[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/sbin/ipset save -file /etc/ipset.rules
TimeoutStopSec=30[Install]
WantedBy=multi-user.target
EOFsystemctl enable ipset-save.servicelog_success "Created IPSet save script for graceful shutdown"# Replace /etc/ufw/before.rules to integrate with IPSetlog_info "Updating /etc/ufw/before.rules to integrate with IPSet..."cp /etc/ufw/before.rules /etc/ufw/before.rules.backup.$(date +%s)log_info "Backed up existing /etc/ufw/before.rules"cat > /etc/ufw/before.rules << 'EOF'
#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-before-input
#   ufw-before-output
#   ufw-before-forward
## Don't delete these required lines, otherwise there will be errors
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]# Fail2Ban IPSet integration
# Block all traffic from fail2ban banned IPs
-A ufw-before-input -m set --match-set fail2ban-banned src -j DROP
-A ufw-before-input -m set --match-set fail2ban-recidive src -j DROP# End required lines# allow all on loopback
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-output -o lo -j ACCEPT# quickly process packets for which we already have a connection
-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-output -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT# drop INVALID packets (logs these in loglevel medium and higher)
-A ufw-before-input -m conntrack --ctstate INVALID -j ufw-logging-deny
-A ufw-before-input -m conntrack --ctstate INVALID -j DROP# ok icmp codes for INPUT
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT# ok icmp code for FORWARD
-A ufw-before-forward -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type echo-request -j ACCEPT# allow dhcp client to work
-A ufw-before-input -p udp --sport 67 --dport 68 -j ACCEPT#
# ufw-not-local
#
-A ufw-before-input -j ufw-not-local# if LOCAL, RETURN
-A ufw-not-local -m addrtype --dst-type LOCAL -j RETURN# if MULTICAST, RETURN
-A ufw-not-local -m addrtype --dst-type MULTICAST -j RETURN# if BROADCAST, RETURN
-A ufw-not-local -m addrtype --dst-type BROADCAST -j RETURN# all other non-local packets are dropped
-A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny
-A ufw-not-local -j DROP# allow MULTICAST mDNS for service discovery (be sure the MULTICAST line above
# is uncommented)
-A ufw-before-input -p udp -d 224.0.0.251 --dport 5353 -j ACCEPT# allow MULTICAST UPnP for service discovery (be sure the MULTICAST line above
# is uncommented)
-A ufw-before-input -p udp -d 239.255.255.250 --dport 1900 -j ACCEPT# don't delete the 'COMMIT' line or these rules won't be processed
COMMIT
EOFlog_success "Updated /etc/ufw/before.rules with IPSet integration"# Install Fail2Banlog_info "Installing Fail2Ban package..."if apt install -y fail2ban; thenlog_success "Fail2Ban installed successfully"elselog_error "Failed to install Fail2Ban"log_function_end "Installing Fail2Ban" 1return 1fi# Create /etc/fail2ban/action.d/ipset-block.conflog_info "Creating Persistent /etc/fail2ban/action.d/ipset-block.conf"cat > /etc/fail2ban/action.d/ipset-block.conf << 'EOF'
# Fail2Ban action file for ipset
#
# This action blocks/unblocks an IP address using ipset.
#
[INCLUDES]before =[Definition]# The name of the ipset set to use.
setname = fail2ban-banned# Action startup (creates the set if it doesn't exist)
actionstart = /usr/sbin/ipset create <setname> hash:ip timeout 0 exist# Action shutdown (flushes the set when Fail2Ban stops)
#actionstop = ipset flush <setname>
actionstop = # Action to ban an IP
actionban = /usr/sbin/ipset add <setname> <ip> timeout 0 exist# Action to unban an IP
actionunban = /usr/sbin/ipset del <setname> <ip> exist[Init]
EOFlog_success "Created /etc/fail2ban/action.d/ipset-block.conf"# Create IPSet action for fail2banlog_info "Creating Fail2Ban IPSet action configuration..."mkdir -p /etc/fail2ban/action.dcat > /etc/fail2ban/action.d/ipset-ban.conf << 'EOF'
[INCLUDES]
before = iptables-common.conf[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
actionstart = ipset create <ipmset> hash:ip timeout <default-timeout> <family># Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
actionstop = ipset destroy <ipmset># Option: actionban
# Notes.: command executed when banning an IP.
actionban = ipset add <ipmset> <ip> timeout <timeout> -exist# Option: actionunban
# Notes.: command executed when unbanning an IP.
actionunban = ipset del <ipmset> <ip> -exist[Init]
# Default name of the ipset
ipmset = fail2ban-<name># Option: timeout
# Notes.: timeout for the ban, in seconds
timeout = 0# Option: default-timeout  
# Notes.: default timeout for ipset creation
default-timeout = 0# Option: family
# Notes.: IP family, can be inet or inet6
family = inet
EOF# Create enhanced IPSet action for permanent banscat > /etc/fail2ban/action.d/ipset-persistent.conf << 'EOF'
[INCLUDES]
before = iptables-common.conf[Definition]
actionstart = ipset create <ipmset> hash:ip timeout 0 -existipset restore -file /etc/ipset.rules -existactionstop = ipset save -file /etc/ipset.rulesipset destroy <ipmset>actionban = ipset add <ipmset> <ip> timeout 0 -existipset save -file /etc/ipset.rulesactionunban = ipset del <ipmset> <ip> -existipset save -file /etc/ipset.rules[Init]
ipmset = fail2ban-banned
EOF# Create recidive action for repeat offenderscat > /etc/fail2ban/action.d/ipset-recidive.conf << 'EOF'
[INCLUDES]
before = iptables-common.conf[Definition]
actionstart = ipset create <ipmset> hash:ip timeout 0 -existactionstop = ipset save -file /etc/ipset.rulesactionban = ipset add <ipmset> <ip> timeout 0 -existipset save -file /etc/ipset.rulesactionunban = ipset del <ipmset> <ip> -existipset save -file /etc/ipset.rules[Init]
ipmset = fail2ban-recidive
EOFlog_success "Created Fail2Ban IPSet action configurations"# Create jail configurationlog_info "Configuring Fail2Ban jails with IPSet integration..."cat > /etc/fail2ban/jail.local << EOF
[DEFAULT]
# Ban settings
bantime = -1
findtime = 1800
maxretry = 3
backend = auto# IPSet integration
banaction = ipset-persistent
banaction_allports = ipset-persistent# Network settings
allowipv6 = auto
ignoreip = 127.0.0.1/8 ::1usw.daven.us jpt.daven.us bjn.daven.us bjt.daven.us usc.daven.us# Email settings (optional)
# destemail = admin@yourdomain.com
# sendername = Fail2Ban
# mta = sendmail[recidive]
enabled = true
logpath = /var/log/fail2ban.log
banaction = ipset-recidive
bantime = -1
findtime = 86400
maxretry = 3
filter = recidive[sshd]
enabled = true
port = $SSH_PORT
filter = sshd
logpath = /var/log/auth.log
backend = auto
bantime = 72000
findtime = 600
maxretry = 5[ssh-scanner]
enabled = true
port = $SSH_PORT
filter = ssh-scanner
logpath = /var/log/auth.log
maxretry = 5
bantime = 72000
findtime = 600[nginx-scan]
enabled = true
port = http,https,6033
logpath = /var/log/nginx/access.log/var/log/nginx/*.access.log
filter = nginx-scan
maxretry = 5
bantime = -1
findtime = 600[nginx-404-scan]
enabled = true
port = http,https,6033
logpath = /var/log/nginx/access.log/var/log/nginx/*.access.log
filter = nginx-404-scan
maxretry = 20
bantime = -1
findtime = 600[nginx-login-bruteforce]
enabled = true
port = http,https,6033
logpath = /var/log/nginx/access.log
filter = nginx-login-bruteforce
maxretry = 5
bantime = -1
findtime = 600[nginx-bad-useragent]
enabled = true
port = http,https,6033
logpath = /var/log/nginx/access.log
filter = nginx-bad-useragent
maxretry = 5
bantime = -1
findtime = 600[nginx-ray-abuse]
enabled = true
port = http,https,6033
logpath = /var/log/nginx/access.log
filter = nginx-ray-abuse
maxretry = 12
bantime = -1
findtime = 60[nginx-status-abuse]
enabled = true
port = http,https,6033
logpath = /var/log/nginx/access.log/var/log/nginx/*.access.log
filter = nginx-status-abuse
maxretry = 30
bantime = -1
findtime = 600[nginx-attacks]
enabled = true
port = http,https
filter = nginx-attack
logpath = /var/log/nginx/access.log
maxretry = 3
bantime = -1
findtime = 60[nginx-web-attacks]
enabled = true
port = http,https
filter = nginx-web-attacks
logpath = /var/log/nginx/*.daven.us.access.log
maxretry = 12
bantime = -1
findtime = 600
EOFlog_success "Created /etc/fail2ban/jail.local configuration file"# fail2ban for sshd and ssh-scanner local filterlog_success "Fail2Ban jails configured successfully"mkdir -p /etc/fail2ban/filter.dlog_info "Creating Fail2Ban filter for sshd and ssh-scanner..."# Create sshd local filter configurationlog_info "Creating sshd.local filter configuration..."cat > /etc/fail2ban/filter.d/sshd.local << 'EOF'
[Definition]
allowipv6 = auto
failregex = ^<HOST> .* "[^"]*" .*" "(?:Go-http-client|wget|curl|python-requests|masscan|zgrab|sqlmap|nikto|dirb|gobuster)" .*$^<HOST> .* "[^"]*" .*" ".*(?:Mozi\.m|scamanje|stresserit)" .*$^<HOST> .* "[^"]*" .*" "xfa1" .*$
ignoreregex = ^<HOST> .* "[^"]*" .*" ".*(?:Googlebot|Bingbot|YandexBot|DuckDuckBot)" .*$
EOFlog_success "sshd.local filter configuration created"# Create ssh-scanner filterlog_info "Creating Fail2Ban filter for SSH scanner..."cat > /etc/fail2ban/filter.d/ssh-scanner.conf << 'EOF'
[INCLUDES]
before = common.conf
[Definition]
_daemon = sshd
allowipv6 = auto
failregex = ^%(__prefix_line)sConnection from <HOST> port \d+ on \S+ port \d+$^%(__prefix_line)sConnection closed by <HOST> port \d+ \[preauth\]$^%(__prefix_line)sConnection closed by authenticating user .* <HOST> port \d+ \[preauth\]$^%(__prefix_line)sDisconnected from .* <HOST> port \d+ \[preauth\]$^%(__prefix_line)sReceived disconnect from <HOST> port \d+:\d+: .* \[preauth\]$^%(__prefix_line)sbanner exchange: Connection from <HOST> port \d+: invalid format$
ignoreregex =
EOFlog_success "ssh-scanner filter created"# Create Fail2Ban jail for nginx scanners# Create nginx-scan filterlog_info "Creating Fail2Ban filter for Nginx scanner..."cat > /etc/fail2ban/filter.d/nginx-scan.conf << 'EOF'
[Definition]
allowipv6 = auto
failregex = ^<HOST> .* "(GET|POST|PUT) [^"]*(?:\.env|\.git|phpinfo|eval-stdin\.php|shell\?|admin/login\.asp|boaform/admin|login\.cgi)" .*$^<HOST> .* "(GET|POST) [^"]*(?:wget\+|chmod\+|/tmp/|Mozi\.m|scamanje\.stresserit\.pro)" .*$^<HOST> .* "(GET|POST) [^"]*(?:/SDK/webLanguage|/actuator|/console|/geoserver|/solr/admin)" .*$^<HOST> .* "(GET|POST) [^"]*(?:phpunit|vendor/phpunit|_ignition)" .*$^<HOST> .* "[^"]*(?:27;wget|mstshash=)" .*$
ignoreregex = ^<HOST> .* "GET /(?:favicon\.ico|robots\.txt|sitemap\.xml) .*$
EOFlog_success "nginx-scan filter created"# Create nginx-404-scan filterlog_info "Creating Fail2Ban filter for Nginx 404 scanner..."cat > /etc/fail2ban/filter.d/nginx-404-scan.conf << 'EOF'
[Definition]
allowipv6 = auto
failregex = ^<HOST> - - \[.*\] "(?:GET|POST) /(?:admin|wp-admin|\.php|\.asp|phpinfo|\.env|config|backup|uploads|test|debug|system_info|diagnostics)" .*" 404 .*$^<HOST> - - \[.*\] "(?:GET|POST) [^"]*/(?:partymgr|jasperserver|solr|owncloud|geoserver|WebInterface)" .*" 404 .*$^<HOST> - - \[.*\] "(?:GET|POST|HEAD|OPTIONS|PUT|DELETE|CONNECT|TRACE|PATCH) /[a-zA-Z0-9]{4,8}(?:\s|/|$)" .*" 404 .*$
ignoreregex = ^<HOST> - - \[.*\] "GET /(?:favicon\.ico|robots\.txt|sitemap\.xml|apple-touch-icon|\.well-known/)" .*" 404 .*$
EOFlog_success "nginx-404-scan filter created"# Create login scanner filterlog_info "Creating Fail2Ban filter for nginx login bruteforce scanner..."cat > /etc/fail2ban/filter.d/nginx-login-bruteforce.conf << 'EOF'
[Definition]
allowipv6 = auto
failregex = ^<HOST> .* "(?:GET|POST) /login\.cgi\?username=.*&psd=" .*$^<HOST> .* "POST /boaform/admin/formLogin" .*$^<HOST> .* "GET /boaform/admin/formLogin\?username=.*&psd=" .*$^<HOST> .* "POST /admin/login\." .*$
ignoreregex =
EOFlog_success "nginx-login-bruteforce filter created"# Create nginx bad User-Agent filterlog_info "Creating Fail2Ban filter for Nginx bad User-Agent..."cat > /etc/fail2ban/filter.d/nginx-bad-useragent.conf << 'EOF'
[Definition]
allowipv6 = auto
failregex = ^<HOST> .* "[^"]*" .*" "(?:Go-http-client|wget|curl|python-requests|masscan|zgrab|sqlmap|nikto|dirb|gobuster)" .*$^<HOST> .* "[^"]*" .*" ".*(?:Mozi\.m|scamanje|stresserit)" .*$^<HOST> .* "[^"]*" .*" "xfa1" .*$
ignoreregex = ^<HOST> .* "[^"]*" .*" ".*(?:Googlebot|Bingbot|YandexBot|DuckDuckBot)" .*$
EOFlog_success "nginx-bad-useragent filter created"# Create nginx ray abuse filterlog_info "Creating Fail2Ban filter for Nginx Ray abuse..."cat > /etc/fail2ban/filter.d/nginx-ray-abuse.conf << 'EOF'
[Definition]
allowipv6 = auto
failregex = ^<HOST> .* "GET /api HTTP/1\.1" 101 .*$
ignoreregex =
EOFlog_success "nginx-ray-abuse filter created"# Create nginx status abuse filterlog_info "Creating Fail2Ban filter for Nginx status abuse..."cat > /etc/fail2ban/filter.d/nginx-status-abuse.conf << 'EOF'
[Definition]
allowipv6 = auto
failregex = ^<HOST> - - \[.*\] "(?:GET|POST|HEAD) .* HTTP/1\.[01]" 40[0-3] \d+ ".*" ".*"$
ignoreregex = ^<HOST> .* "GET /(?:favicon\.ico|robots\.txt)" 40[0-3] .*$
EOFlog_success "nginx-status-abuse filter created"# Create nginx status abuse filterlog_info "Creating Fail2Ban filter for Nginx attack abuse..."cat > /etc/fail2ban/filter.d/nginx-attack.conf << 'EOF'
[Definition]
allowipv6 = auto
failregex = ^<HOST> -.*"GET .*(.env|.git|.well-known/security\.txt|\/phpmyadmin|\/wp-login\.php|\/wp-admin|\/cgi-bin|\/phpinfo|\.sql|\.log|\.ini|\.conf|\.bak).* HTTP.*" (40[0-4]|444|499|500)^<HOST> -.*"GET .*(?:\x09hink|\x09pp).*shell_exec.*wget.*" 400.*
ignoreregex =
EOFlog_success "nginx-attack filter created"# Create nginx status abuse filterlog_info "Creating Fail2Ban filter for Nginx web attacks abuse..."cat > /etc/fail2ban/filter.d/nginx-web-attacks.conf << 'EOF'
[Definition]
allowipv6 = auto
failregex = ^<HOST> -.*"GET .*(?:\.env|\.git|\.well-known/security\.txt|\/phpmyadmin|\/wp-admin|\/cgi-bin|\/webui|\/geoserver|\/remote/login|onvif|PSIA|boaform|owa/auth/logon\.aspx|PROPFIND|\+CSCOE\+).*HTTP.*" (40[0-4]|444|499|500)^<HOST> -.*"GET .*(?:\x09hink|\x07pp).*shell_exec.*wget.*" 400.*^<HOST> -.*"POST .*cgi-bin/(\.\./).*bin/sh HTTP.*" (400|404|301|302)^<HOST> -.*"GET .*HTTP.*" (40[0-4]|444|499).*"(?:zgrab|CMS-Checker|libredtail-http|WanScannerBot|Odin|GenomeCrawlerd)"
ignoreregex =
EOFlog_success "nginx-web-attacks filter created"# Disable conflicting default configuration fileslog_info "Disabling conflicting default configuration files..."if [ -f /etc/fail2ban/jail.d/defaults-debian.conf ]; thenif mv /etc/fail2ban/jail.d/defaults-debian.conf /etc/fail2ban/jail.d/defaults-debian.disabled; thenlog_success "Conflicting default configuration files disabled"elselog_warning "Failed to disable conflicting default configuration files"fifi# Restart services in proper orderlog_info "Starting services in proper order..."# Start IPSet persistence firstsystemctl start ipset-persistent.service# Reload UFW to pick up the new before.ruleslog_info "Reloading UFW to apply IPSet integration..."ufw --force reloadlog_success "UFW reloaded with IPSet integration"# Enable and start Fail2Bansystemctl enable fail2bansystemctl start fail2banlog_info "Fail2Ban service started"# Wait for fail2ban to initializesleep 3# Verify IPSet integrationlog_info "Verifying IPSet integration..."if ipset list fail2ban-banned >/dev/null 2>&1; thenlog_success "IPSet 'fail2ban-banned' is active"elselog_error "IPSet 'fail2ban-banned' is not active"fi# Verify UFW integrationif iptables -L ufw-before-input -n | grep -q fail2ban-banned; thenlog_success "UFW is integrated with IPSet"elselog_warning "UFW integration with IPSet may not be working"fi# Create management toolscreate_ipset_management_tools# Create fail2ban-tester.shlog_info "Creating /usr/bin/fail2ban-tester.sh..."cat > /usr/bin/fail2ban-tester.sh << 'EOF'
#!/bin/bash
# A script to automatically test all enabled Fail2ban jails using fail2ban-regex.
# It fetches the filter and logpath for each active jail and runs the test.
# By Dave Nian on 25Aug25# --- Configuration ---
# Colors for better readability
C_RESET='\033[0m'
C_RED='\033[0;31m'
C_GREEN='\033[0;32m'
C_YELLOW='\033[0;33m'
C_BLUE='\033[0;34m'
C_CYAN='\033[0;36m'
C_BOLD='\033[1m'# --- Pre-flight Checks ---
# Check if running as root
if [[ $EUID -ne 0 ]]; thenecho -e "${C_RED}This script must be run as root.${C_RESET}"exit 1
fi# Check if fail2ban-client is available
if ! command -v fail2ban-client &> /dev/null; thenecho -e "${C_RED}Error: 'fail2ban-client' command not found.${C_RESET}"echo "Please ensure Fail2ban is installed and you are running this on the correct server."exit 1
fi# --- Main Logic ---
echo -e "${C_BOLD}${C_BLUE}--- Starting Fail2ban Filter Test ---${C_RESET}"# Get the list of enabled jails from fail2ban-client
# The sed command cleans up the output to get just the jail names
ENABLED_JAILS=$(fail2ban-client status | grep "Jail list:" | sed -e 's/.*Jail list:\s*//' -e 's/,//g')if [ -z "$ENABLED_JAILS" ]; thenecho -e "${C_RED}Could not find any enabled jails. Exiting.${C_RESET}"exit 1
fiecho -e "Found enabled jails: ${C_YELLOW}${ENABLED_JAILS}${C_RESET}\n"# Loop through each enabled jail
for jail in $ENABLED_JAILS; doecho -e "${C_BOLD}${C_CYAN}========================================${C_RESET}"echo -e "${C_BOLD}${C_CYAN} Testing Jail: [${jail}] ${C_RESET}"echo -e "${C_BOLD}${C_CYAN}========================================${C_RESET}"# Get the filter name for the current jail.# Redirect stderr to /dev/null to keep the output clean.filter_name=$(fail2ban-client get "$jail" filter 2>/dev/null)# ** FIX **: Check if the command failed or returned a known error message.# Some versions of fail2ban-client output this error to stdout.# If it fails, we assume the filter name is the same as the jail name.if [ $? -ne 0 ] || [[ "$filter_name" == *"Invalid command"* ]] || [ -z "$filter_name" ]; thenecho -e "  ${C_YELLOW}Warning: Could not dynamically get filter for [${jail}].${C_RESET}"echo -e "  ${C_YELLOW}Assuming filter name matches jail name.${C_RESET}"filter_name=$jailfifilter_file="/etc/fail2ban/filter.d/${filter_name}.conf"# ** FIX **: Get the log path(s) and parse the multi-line output correctly.# This command now specifically extracts lines that are file paths.log_paths_output=$(fail2ban-client get "$jail" logpath)log_paths=$(echo "$log_paths_output" | grep -E '^[|`]-' | sed -E 's/^[|`]- //')# If the above fails (for single-line outputs), use the raw output but clean it.if [ -z "$log_paths" ]; thenlog_paths=$(echo "$log_paths_output" | sed 's/Current monitored log file(s)://g' | tr -d '`-' | tr -d '|')fi# Check if the filter file actually existsif [ ! -f "$filter_file" ]; thenecho -e "  ${C_RED}Filter file not found:${C_RESET} ${filter_file}"# Try to find it with a .local extension as a fallbackfilter_file_local="/etc/fail2ban/filter.d/${filter_name}.local"if [ -f "$filter_file_local" ]; thenecho -e "  ${C_YELLOW}Found fallback filter:${C_RESET} ${filter_file_local}"filter_file=$filter_file_localelseecho -e "  ${C_RED}Skipping jail [${jail}] as no valid filter was found.${C_RESET}\n"continuefifiecho -e "  ${C_BOLD}Filter:${C_RESET} ${filter_file}"echo -e "  ${C_BOLD}Log(s):${C_RESET}\n${log_paths}" # Print the cleaned listecho ""# Loop through each log path (a jail can have multiple)for log_path in $log_paths; do# Expand wildcards in log pathsexpanded_logs=$(eval echo $log_path)for expanded_log_path in $expanded_logs; do# Check if the log file exists and is readableif [ ! -r "$expanded_log_path" ]; thenecho -e "  -> Testing log: ${C_YELLOW}${expanded_log_path}${C_RESET}"echo -e "     ${C_RED}Result: Log file not found or not readable. Skipping.${C_RESET}\n"continuefiecho -e "  -> Testing log: ${C_GREEN}${expanded_log_path}${C_RESET}"# Run the fail2ban-regex command and capture the outputtest_output=$(fail2ban-regex "$expanded_log_path" "$filter_file")# ** FIX **: More robustly extract the number of matched lines.# This specifically finds the number preceding "matched".matches=0 # Default to 0matches_line=$(echo "$test_output" | grep "Lines:")if [[ -n "$matches_line" ]]; then# Use grep with Perl-compatible regex to extract the numbermatches=$(echo "$matches_line" | grep -oP '\d+(?=\s+matched)')fi# Print the summaryif [ "$matches" -gt 0 ]; thenecho -e "     ${C_GREEN}${C_BOLD}Result: Found ${matches} matching lines!${C_RESET}"elseecho -e "     ${C_YELLOW}Result: Found 0 matching lines.${C_RESET}"fiecho ""donedone
doneecho -e "${C_BOLD}${C_BLUE}--- Test Complete ---${C_RESET}"EOFif [ -f "/usr/bin/fail2ban-tester.sh" ];then log_info "fail2ban-tester.sh created in /usr/bin/"elselog_warning "fail2ban-tester.sh didn't exist in /usr/bin/"return 1fiif chmod 777 /usr/bin/fail2ban-tester.sh;thenlog_info "/usr/bin/fail2ban-tester.sh has been given execute permission"elselog_warning "Ran chmode on /usr/bin/fail2ban-tester.sh failed"return 1fiif ln -s /usr/bin/fail2ban-tester.sh /usr/bin/fail2ban-tester;thenlog_info "Linked /usr/bin/fail2ban-tester.sh to /usr/bin/fail2ban-tester"elselog_warning "Failed to link /usr/bin/fail2ban-tester"return 1fi# Fixing the WARNING 'allowipv6' not defined in 'Definition'if fail2ban_sshd_local_allowipv6; thenlog_success "'allowipv6' configuration fixed in sshd.local"elselog_warning "'allowipv6' configuration not fixed in sshd.local"fi# Final restart to apply all changeslog_info "Performing final restart of services..."systemctl daemon-reloadsystemctl restart fail2banif systemctl is-active --quiet fail2ban; thenlog_success "Fail2Ban restarted successfully with IPSet integration"elselog_error "Failed to restart Fail2Ban"systemctl status fail2ban --no-pager -l || truelog_function_end "Installing Fail2Ban with IPSet" 1return 1fi# Create Fail2Ban management toolslog_info "Creating Fail2Ban management tools..."    create_fail2ban_tools# Verify installationif verify_fail2ban_installation; thenlog_success "🎉 Fail2Ban with IPSet integration completed successfully!"show_fail2ban_summarylog_function_end "Installing Fail2Ban with IPSet" 0return 0elselog_warning "??  Fail2Ban with IPSet installed but some issues detected"show_fail2ban_troubleshootinglog_function_end "Installing Fail2Ban with IPSet" 1return 1fi
}# Function to create IPSet management tools
create_ipset_management_tools() {log_info "Creating IPSet management tools..."# Create IPSet status scriptcat > /usr/local/bin/ipset-status << 'EOF'
#!/bin/bash
# IPSet Status Display Scriptecho "=== IPSet Status ==="
echo "Active IPSets:"
ipset list -nameecho ""
echo "=== Fail2Ban IPSets ==="
for set in $(ipset list -name | grep fail2ban); doecho "--- $set ---"echo "Members: $(ipset list $set | grep -c '^[0-9]')"ipset list $set | head -20echo ""
doneecho "=== IPSet Rules in iptables ==="
iptables -L ufw-before-input -n | grep set
EOFchmod +x /usr/local/bin/ipset-statuslog_success "Created IPSet status script"# Create IPSet backup scriptcat > /usr/local/bin/ipset-backup << 'EOF'
#!/bin/bash
# IPSet Backup ScriptBACKUP_DIR="/etc/ipset-backups"
mkdir -p "$BACKUP_DIR"BACKUP_FILE="$BACKUP_DIR/ipset-backup-$(date +%Y%m%d-%H%M%S).rules"
ipset save > "$BACKUP_FILE"echo "IPSet rules backed up to: $BACKUP_FILE"# Keep only last 10 backups
ls -t "$BACKUP_DIR"/ipset-backup-*.rules | tail -n +11 | xargs rm -f 2>/dev/null
EOFchmod +x /usr/local/bin/ipset-backuplog_success "Created IPSet backup script"
}fail2ban_sshd_local_allowipv6() {local source_file="/etc/fail2ban/filter.d/sshd.conf"local local_file="/etc/fail2ban/filter.d/sshd.local"if [ -f "$source_file" ]; thenlog_info "Setting up sshd.local filter configuration..."# Backup existing sshd.local if it existsif [ -f "$local_file" ]; thenlog_info "Backing up existing sshd.local..."cp "$local_file" "${local_file}.backup.$(date +%s)"fi# Copy and set permissionsif cp -f "$source_file" "$local_file"; thenchmod 644 "$local_file"# Verify copy resultif [ -s "$local_file" ]; thenlog_success "sshd.conf copied to sshd.local successfully"elselog_error "Copied file is empty"return 1fielselog_error "Failed to copy sshd.conf to sshd.local"return 1fi# Fix 'allowipv6' configurationlog_info "Fixing 'allowipv6' warning in sshd.local..."if sed -n '/^\[Definition\]/,/^\[/p' "$local_file" | grep -q "^[[:space:]]*allowipv6[[:space:]]*=[[:space:]]*\(auto\|yes\)"; thenlog_success "'allowipv6' already correctly configured in sshd.local"elseif sed -n '/^\[Definition\]/,/^\[/p' "$local_file" | grep -q "^[[:space:]]*allowipv6[[:space:]]*="; thenlog_info "Updating existing 'allowipv6' configuration to 'auto'"sed -i '/^\[Definition\]/,/^\[/{ s/^[[:space:]]*allowipv6[[:space:]]*=.*/allowipv6 = auto/; }' "$local_file"elselog_info "Adding 'allowipv6 = auto' to sshd.local"sed -i '/^\[Definition\]/a allowipv6 = auto' "$local_file"fi# Verify modification resultif grep -A 5 "^\[Definition\]" "$local_file" | grep -q "^allowipv6[[:space:]]*=[[:space:]]*auto"; thenlog_success "? allowipv6 successfully configured in sshd.local"elselog_warning "??  allowipv6 configuration may not be correct"fifielselog_error "Source file does not exist: $source_file"return 1fi
}# Unified verification function that handles both standard and IPSet installations
verify_fail2ban_installation() {log_info "Verifying Fail2Ban installation and configuration..."local verification_passed=truelocal tools_dir="/usr/local/bin/fail2ban-tools"local has_ipset=false# Detect if IPSet integration is being usedif command -v ipset >/dev/null 2>&1 && ipset list fail2ban-banned >/dev/null 2>&1; thenhas_ipset=truelog_info "IPSet integration detected, performing enhanced verification..."elselog_info "Standard Fail2Ban installation detected..."fi# 1. Check Fail2Ban service statusif systemctl is-active --quiet fail2ban; thenlog_success "? Fail2Ban service is running"elselog_error "? Fail2Ban service is not running"verification_passed=falsefi# 2. IPSet-specific checks (only if IPSet integration detected)if [ "$has_ipset" = true ]; then# Check IPSet persistence serviceif systemctl is-active --quiet ipset-persistent; thenlog_success "? IPSet persistence service is active"elselog_warning "??  IPSet persistence service may not be active"fi# Check IPSets existif ipset list fail2ban-banned >/dev/null 2>&1; thenlog_success "? IPSet 'fail2ban-banned' exists"elselog_error "? IPSet 'fail2ban-banned' does not exist"verification_passed=falsefi# Check for recidive IPSet (optional)if ipset list fail2ban-recidive >/dev/null 2>&1; thenlog_success "? IPSet 'fail2ban-recidive' exists"elselog_info "??  IPSet 'fail2ban-recidive' not found (optional)"fi# Check UFW integration with IPSetif iptables -L ufw-before-input -n | grep -q fail2ban-banned; thenlog_success "? UFW is integrated with IPSet"elselog_error "? UFW is not integrated with IPSet"verification_passed=falsefi# Check IPSet action fileslocal ipset_actions=("/etc/fail2ban/action.d/ipset-ban.conf""/etc/fail2ban/action.d/ipset-persistent.conf""/etc/fail2ban/action.d/ipset-recidive.conf")for action_file in "${ipset_actions[@]}"; doif [ -f "$action_file" ]; thenlog_success "? IPSet action file exists: $(basename "$action_file")"elselog_warning "??  IPSet action file missing: $action_file"fidone# Check IPSet rules fileif [ -f "/etc/ipset.rules" ]; thenlog_success "? IPSet rules file exists: /etc/ipset.rules"elselog_warning "??  IPSet rules file missing: /etc/ipset.rules"fifi# 3. Check jail statuslocal active_jails=$(fail2ban-client status 2>/dev/null | grep "Jail list:" | cut -d: -f2 | tr ',' '\n' | wc -w)if [ "$active_jails" -gt 0 ]; thenlog_success "? $active_jails jail(s) active"# Check specific jailsfor jail in sshd ssh-scanner; doif fail2ban-client status "$jail" >/dev/null 2>&1; thenlog_success "? $jail jail is active"elselog_warning "??  $jail jail is not active"fidoneelselog_error "? No active jails found"verification_passed=falsefi# 4. Check configuration fileslocal config_files=("/etc/fail2ban/jail.local""/etc/fail2ban/filter.d/sshd.local""/etc/fail2ban/filter.d/ssh-scanner.conf""/etc/fail2ban/filter.d/nginx-scan.conf""/etc/fail2ban/filter.d/nginx-404-scan.conf""/etc/fail2ban/filter.d/nginx-login-bruteforce.conf""/etc/fail2ban/filter.d/nginx-bad-useragent.conf""/etc/fail2ban/filter.d/nginx-ray-abuse.conf""/etc/fail2ban/filter.d/nginx-status-abuse.conf""/etc/fail2ban/filter.d/nginx-attack.conf""/etc/fail2ban/filter.d/nginx-web-attacks.conf")local missing_configs=0for config_file in "${config_files[@]}"; doif [ -f "$config_file" ]; thenlog_success "? Configuration file exists: $(basename "$config_file")"elselog_error "? Configuration file missing: $config_file"verification_passed=false((missing_configs++))fidoneif [ "$missing_configs" -eq 0 ]; thenlog_success "? All configuration files are present"elselog_error "? $missing_configs configuration file(s) missing"fi# 5. Check log fileif [ -f "/var/log/fail2ban.log" ]; thenlocal recent_errors=$(tail -50 /var/log/fail2ban.log 2>/dev/null | grep -c "ERROR" || echo "0")if [ "$recent_errors" -eq 0 ]; thenlog_success "? No recent errors in Fail2Ban log"elselog_warning "??  Found $recent_errors recent errors in Fail2Ban log"fielselog_warning "??  Fail2Ban log file not found at /var/log/fail2ban.log"fi# 6. Check tool filesif [ -d "$tools_dir" ]; thenlog_success "? Fail2Ban tools directory exists ($tools_dir)"if [ -f "$tools_dir/fail2ban-checking.sh" ]; thenlog_success "? Fail2Ban check script exists"if [ -f "$tools_dir/fail2ban-status.sh" ]; thenlog_success "? Fail2Ban status script exists"elselog_error "? Fail2Ban status script missing"verification_passed=falsefielselog_error "? Fail2Ban check script missing"verification_passed=falsefielselog_error "? Fail2Ban tools directory missing"verification_passed=falsefi# 7. Check tool symlinksif [ -f "/usr/local/bin/fail2ban-checking" ]; thenlog_success "? Fail2Ban checking symlink exists"if [ -f "/usr/local/bin/fail2ban-status" ]; thenlog_success "? Fail2Ban status symlink exists"elselog_error "? Fail2Ban status symlink missing"verification_passed=falsefielselog_error "? Fail2Ban checking symlink missing"verification_passed=falsefi# 8. Check fail2ban-tester scriptif [ -f "/usr/bin/fail2ban-tester.sh" ] && [ -f "/usr/bin/fail2ban-tester" ]; thenlog_success "? Fail2Ban tester script exists"elselog_warning "??  Fail2Ban tester script missing"fi# 9. Additional IPSet management tools check (if IPSet detected)if [ "$has_ipset" = true ]; thenif [ -f "/usr/local/bin/ipset-status" ]; thenlog_success "? IPSet status script exists"elselog_warning "??  IPSet status script missing"fiif [ -f "/usr/local/bin/ipset-backup" ]; thenlog_success "? IPSet backup script exists"elselog_warning "??  IPSet backup script missing"fifi# Summaryif [ "$has_ipset" = true ]; thenlog_info "Verification completed for Fail2Ban with IPSet integration"elselog_info "Verification completed for standard Fail2Ban installation"fireturn $([ "$verification_passed" = true ] && echo 0 || echo 1)
}show_fail2ban_summary() {local has_ipset=false# Detect if IPSet integration is being usedif command -v ipset >/dev/null 2>&1 && ipset list fail2ban-banned >/dev/null 2>&1; thenhas_ipset=truefiechoif [ "$has_ipset" = true ]; thenlog_info "📋 Fail2Ban with IPSet Integration Summary"echo "============================================="echo "🔐 SSH Port: $SSH_PORT"echo "🚫 Ban Policy: Permanent bans via IPSet"echo "🕒 SSH Attempts: 3 failures in 30 minutes"echo "🕒 Scanner Detection: 2 connections in 5 minutes"echo "🔧 Firewall Integration: UFW + IPSet"echo "💾 IPSet Persistence: Enabled"echoecho "📁 Key Configuration Files:"echo "  ? Main config: /etc/fail2ban/jail.local"echo "  ? IPSet actions: /etc/fail2ban/action.d/ipset-*.conf"echo "  ? IPSet rules: /etc/ipset.rules"echo "  ? UFW before rules: /etc/ufw/before.rules"echo "  ? SSH filter: /etc/fail2ban/filter.d/sshd.local"echo "  ? Scanner filter: /etc/fail2ban/filter.d/ssh-scanner.conf"echo "  ? Nginx filters: /etc/fail2ban/filter.d/nginx-*.conf"echoecho "🔧 Management Commands:"echo "  ? Fail2Ban status: fail2ban-client status"echo "  ? IPSet status: ipset-status"echo "  ? IPSet backup: ipset-backup"echo "  ? View banned IPs: ipset list fail2ban-banned"echo "  ? Unban IP: fail2ban-client set <jail> unbanip <IP>"echo "  ? Manual IPSet ban: ipset add fail2ban-banned <IP>"echo "  ? Manual IPSet unban: ipset del fail2ban-banned <IP>"echoecho "🔧 Service Management:"echo "  ? Restart Fail2Ban: systemctl restart fail2ban"echo "  ? Reload UFW: ufw reload"echo "  ? Save IPSet: ipset save > /etc/ipset.rules"echo "============================================="elselog_info "📋 Fail2Ban Configuration Summary"echo "=================================="echo "🔐 SSH Port: $SSH_PORT"echo "🚫 Ban Policy: Permanent bans"echo "🕒 SSH Attempts: 3 failures in 30 minutes"echo "🕒 Scanner Detection: 2 connections in 5 minutes"  echo "🔧 Firewall Integration: UFW"echoecho "📁 Configuration Files:"echo "  ? Main config: /etc/fail2ban/jail.local"echo "  ? SSH filter: /etc/fail2ban/filter.d/sshd.local"echo "  ? Scanner filter: /etc/fail2ban/filter.d/ssh-scanner.conf"echo "  ? Nginx filters: /etc/fail2ban/filter.d/nginx-*.conf"echoecho "🔧 Management Commands:"echo "  ? Check status: fail2ban-client status"echo "  ? Check SSH jail: fail2ban-client status sshd"echo "  ? View logs: tail -f /var/log/fail2ban.log"echo "  ? Unban IP: fail2ban-client set sshd unbanip <IP>"echo "  ? Restart service: systemctl restart fail2ban"echo "=================================="fiechoecho "🔧 Additional Tools:"echo "  ? Security check: fail2ban-checking"echo "  ? Status display: fail2ban-status" echo "  ? Filter tester: fail2ban-tester"echoecho "🔧 Troubleshooting:"echo "  ? Check service status: systemctl status fail2ban"echo "  ? View logs: journalctl -u fail2ban -f"echo "  ? Test configuration: fail2ban-client -d"echo "  ? Check log files: tail -f /var/log/fail2ban.log"echo "  ? Manual restart: systemctl restart fail2ban"echo "  ? Check UFW integration: ufw status"if [ "$has_ipset" = true ]; thenecho "  ? Check IPSet rules: ipset list"echo "  ? Check firewall rules: iptables -L ufw-before-input -n"elseecho "  ? Check firewall rules: iptables -L -n"fiecho "=================================="
}

總結:

因為我使用的 -1 永久封,造成內存中有幾百條 iptables 記錄,嚴重影響性能。 現在使用 IPset 做為一個池來集中管理。 也在修改之前的策略改為封20小時,這個腳本中可改。

這三個工具構成了一套層次化的網絡安全防護體系,它們的協同工作過程如下:

角色分工

UFW (Uncomplicated Firewall):作為 iptables 的簡化前端,負責基礎防火墻規則管理和流量過濾的最終執行。

IPset:高效的 IP 地址集合管理工具,使用哈希表存儲大量 IP 地址,提供 O(1) 時間復雜度的查找效率。

Fail2ban:智能入侵檢測系統,監控日志文件、分析攻擊模式、觸發自動封禁動作。

核心工作流程

檢測階段

  1. 攻擊者嘗試連接服務(如SSH)
  2. 服務記錄認證失敗日志到 /var/log/auth.log
  3. Fail2ban 實時監控日志文件,使用正則表達式匹配攻擊模式
  4. 計數器跟蹤每個IP的失敗次數

封禁階段

  1. 當失敗次數達到閾值(如 maxretry=3),Fail2ban 觸發封禁動作
  2. 執行 IPset 命令:ipset add fail2ban-ssh 攻擊者IP
  3. IP被添加到預先創建的IPset集合中
  4. UFW/iptables 規則立即生效:iptables -I INPUT -m set --match-set fail2ban-ssh src -j DROP

防護階段

  1. 后續來自該IP的所有請求在內核層面被直接丟棄
  2. 不再消耗應用服務資源
  3. 根據配置的 bantime 自動解封或永久封禁

關鍵性能優勢

傳統方式的問題是每個被封IP需要單獨的 iptables 規則,當封禁IP數量達到數千個時,規則匹配效率急劇下降。

IPset 優化方式只需要一條 iptables 規則引用整個IP集合,無論集合中有多少IP,查找效率都保持恒定。這種方式可以高效處理數萬個封禁IP而不影響網絡性能。

實際數據流

正常流量:外部請求 → UFW檢查 → IPset查詢(未命中) → 通過基礎規則 → 到達服務

惡意流量:攻擊請求 → UFW檢查 → IPset查詢(命中) → 直接丟棄數據包

這種架構的核心優勢是將被動防護(UFW/iptables)與主動檢測(Fail2ban)相結合,同時通過IPset解決了大規模IP封禁的性能瓶頸問題。整個系統實現了從攻擊檢測到自動響應的完全自動化,大大降低了管理員的工作負擔。

收到 CSDN 消息:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/96081.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/96081.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/96081.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux —— 虛擬進程地址空間

&#x1f381;個人主頁&#xff1a;工藤新一 &#x1f50d;系列專欄&#xff1a;C面向對象&#xff08;類和對象篇&#xff09; &#x1f31f;心中的天空之城&#xff0c;終會照亮我前方的路 &#x1f389;歡迎大家點贊&#x1f44d;評論&#x1f4dd;收藏?文章 文章目錄虛…

簡單聊一聊js

JavaScript 是一種高級的、解釋型的編程語言。它是現代 Web 開發的三大核心基石之一&#xff0c;與 HTML 和 CSS 并列。?HTML?&#xff1a;負責網頁的結構和內容?&#xff08;如標題、段落、圖片&#xff09;。?CSS?&#xff1a;負責網頁的樣式和布局?&#xff08;如顏色…

造粒機cad+設計說明書

摘要 隨著現代化工業的快速發展&#xff0c;生產出大量的固體廢棄物。這些廢棄物對環境造成了很大的污染&#xff0c;因此需要采取有效的措施進行處理。機械強壓式造粒機就是一種非常有效的處理工具&#xff0c;它可以將廢渣、廢料、飼料和化肥等材料通過機械強力擠壓&#xff…

第五課 C#語言基本元素概覽,初始類型,變量與方法,算法簡介

熟悉C#語言要求&#xff1a;對構成C#語言的基本元素&#xff0c;隨便拿出一個你都認識&#xff0c;對于常見基本元素&#xff0c;都能正確使用它 精通C#語言要求&#xff1a;對于構成C#語言的基本元素&#xff0c;隨便拿出一個都會使用&#xff0c;對于常用基本元素&#xff0…

LLM學習:大模型基礎——視覺大模型以及autodl使用

1、常見的VLM 在大模型中,VLM 是視覺語言模型(Vision-Language Model)的縮寫,是一種多模態、生成式 AI 模型,能夠理解和處理視頻、圖像和文本。 VLM 通過將大語言模型(LLM)與視覺編碼器相結合構建而成,使 LLM 具有 “看” 的能力,從而可以處理并提供對提示中的…

Vue—路由配置中設置了meta.title,但頁面標題仍然顯示為“Vite App“?【讓我來看看~】

路由配置中明明設置了meta.title&#xff0c;但是頁面標題仍然顯示為"Vite App"&#xff1f;這是因為僅僅在路由配置中設置meta.title是不夠的&#xff0c;還需要在路由守衛中動態設置頁面標題。需要做以下幾件事來正確設置頁面標題&#xff1a;1.首先更新HTML文件的…

【機器學習】綜合實訓(二)

項目五 電影評分預測【教學內容】使用 MovieLens 數據集&#xff0c;訓練一個模型預測用戶對電影的評分。主要有以下幾個知識點&#xff1a;&#xff08;1&#xff09;數據加載與探索性分析&#xff08;EDA&#xff09;。&#xff08;2&#xff09;處理稀疏數據&#xff08;如用…

STM32 UART + DMA + 空閑中斷使用中的幀錯誤(FE)問題及解決方案

STM32 UART + DMA + IDLE中斷使用中的幀錯誤(FE)問題及解決方案 在我調試STM32H7串口空閑中斷DMA接受時遇到了一個bug,這個現象發生在系統剛上電時,有個串口由于幀錯誤FE掛起了中斷,之后在HAL_UART_IRQHandler這個全局中斷處理函數結束后,所有的中斷使能標志位都被清除了,經過…

TDengine 選擇函數 BOTTOM() 用戶手冊

BOTTOM() 函數用戶手冊 函數定義 BOTTOM(expr, k)功能說明 BOTTOM() 函數統計表/超級表中某列的值最小 k 個非 NULL 值。如果多條數據取值一樣&#xff0c;全部取用又會超出 k 條限制時&#xff0c;系統會從相同值中隨機選取符合要求的數量返回。 返回值 數據類型: 同應用…

西門子 S7-200 SMART PLC 實現星三角降壓啟動控制:原理、案例與完整程序

在工業控制場景中&#xff0c;中型異步電機直接啟動時會產生遠超額定電流的沖擊電流&#xff08;通常為額定電流的 5-7 倍&#xff09;&#xff0c;不僅會影響電網穩定性&#xff0c;還可能對機械設備造成損傷。星三角&#xff08;Y-Δ&#xff09;降壓啟動是解決這一問題的經典…

【Android】View 的基礎知識

【Android】View 的基礎知識 1. 什么是 View&#xff1f; View 是 Android 中所有UI組件的基礎類。它表示屏幕上的一個矩形區域&#xff0c;負責繪制內容和處理用戶交互事件。所有的 UI 組件&#xff08;如按鈕、文本框等&#xff09;都是 View 的子類&#xff0c;而 ViewGroup…

西門子 S7-200 SMART PLC 實現電機點動與連續運行綜合控制

在工業生產中&#xff0c;電機控制并非單一模式&#xff1a;調試設備時需要 “按動即轉、松開即停” 的點動功能&#xff0c;正常生產時則需要 “一鍵啟動、持續運行” 的連續控制。本文以西門子 S7-200 SMART PLC 為載體&#xff0c;詳細講解電機點動控制原理&#xff0c;并設…

如何解決pip安裝報錯ModuleNotFoundError: No module named ‘sphinx-rtd-theme’問題

【Python系列Bug修復PyCharm控制臺pip install報錯】如何解決pip安裝報錯ModuleNotFoundError: No module named ‘sphinx-rtd-theme’問題 摘要 在使用 PyCharm 開發 Python 項目時&#xff0c;pip install 報錯是常見痛點。特別是在構建文檔或引入第三方庫時&#xff0c;開…

HakcMyVM-Literal

目錄信息搜集漏洞利用權限提升信息搜集 主機發現 ┌──(kali?kali)-[~] └─$ nmap -sn 192.168.21.0/24 Nmap scan report for 192.168.21.5端口掃描 ┌──(kali?kali)-[~] └─$ nmap -sS -sV -O -p- 192.168.21.5 Starting Nmap 7.95 ( https://nmap.org ) a…

0904 類的繼承

Part 1.梳理思維導圖一.繼承中的特殊成員函數1.構造函數父類的構造函數會被繼承到子類中&#xff0c;在構造的順序中&#xff0c;是先構造父類&#xff0c;再構造子類#include <iostream>using namespace std;class Father { public:string name; protected:int *age; pr…

PDF教程|如何把想要的網頁保存下來?

前段時間有個小伙伴咨詢了小白&#xff1a;領導想要某個網頁的整個頁面&#xff0c;有沒有比較好的方法把它保存下來&#xff1f; 在他找到小白之前&#xff0c;這種事情他已經接到好幾次了&#xff0c;每次都是怎么解決的呢&#xff1f;其實很簡單&#xff0c;就是打開Word&a…

【bash】命令查看當前目錄下文件個數

要用 ls 查看當前目錄下的文件個數&#xff0c;可以結合 wc -l 來統計行數&#xff1a; ls -1 | wc -l說明&#xff1a; ls -1&#xff1a;以一行一個文件的方式列出。wc -l&#xff1a;統計行數&#xff0c;也就是文件/目錄的數量。 ?? 需要注意&#xff1a; 這個方法會把文…

「日拱一碼」081 機器學習——梯度增強特征選擇GBFS

目錄 什么是梯度增強特征選擇&#xff08;GBFS&#xff09; 為什么 GBM 適合做特征選擇 GBFS 的一般步驟 代碼示例 什么是梯度增強特征選擇&#xff08;GBFS&#xff09; GBFS 并非一個像 Lasso 或隨機森林那樣有嚴格標準定義的獨立算法&#xff0c;而是一種基于梯度提升機…

解構匯編, 萬物起源

匯編的誕生匯編全景圖核心主干: CPU架構主要分支: 語法和工具共同的地貌: 核心概念延伸: 跨平臺 & 跨架構跨平臺跨架構總結以 GAS vs. NASM 為例NASM 不支持跨架構 ≠ 無法在ARM架構上的系統安裝匯編的誕生 機器語言的困境 早期的程序員直接使用機器語言進行編程機器語言由…

廣州旅游網站系統 - 純靜態旅游展示平臺

&#x1f31f; 廣州旅游網站系統 - 純靜態旅游展示平臺觀世界才有世界觀 - 一個集景區展示、旅游攻略、文化傳播于一體的精美旅游網站&#x1f4cb; 項目概述 這是一個專注于廣州旅游文化的純靜態網站系統&#xff0c;采用現代化的前端技術棧&#xff0c;為游客提供全方位的廣州…