搭建自己的WEB應用防火墻
之前給客戶搭建的網站服務近期頻繁遭受惡意掃描、暴力破解攻擊,日志里記錄著各種奇葩的請求地址,導致Tomcat線程資源耗盡,最終nginx報504(網關超時),在服務器上curl本地請求依然卡死,即讓網站無法正常訪問,也存在著巨大的安全隱患。奈何沒米買WAF防火墻,咱只能發揮老一輩精神擼起袖子自己干,我決定在服務器上搭建 fail2ban 安全工具!!!
名稱 | 版本 | 備注 |
---|---|---|
操作系統 | CentOS 7.9 | |
fail2ban | 0.10.2 | 一個用于阻止暴力破解攻擊的安全工具 |
nginx | 1.6.3 | 代理訪問服務,域名端口轉發、靜態資源和證書等 |
tomcat | 8.0.53 | 網站實際部署的應用服務器 |
一、安裝 fail2ban
-
安裝 EPEL 源
sudo yum install epel-release -y
fail2ban 在 CentOS 默認源中不包含,需要添加 EPEL 源。
-
安裝 fail2ban
sudo yum install fail2ban -y
安裝很簡單,完成后系統會自動啟動和添加 fail2ban 相關服務及配置文件。
二、配置監控策略和過濾器
-
復制配置文件模板
安裝后有默認主配置文件 /etc/fail2ban/jail.conf,復制一份到 jail.local,避免直接修改官方配置文件,便于后續更新。sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
-
配置 jail.local 文件
sudo vi /etc/fail2ban/jail.local
jail.local作為用戶自定義的本地配置文件,用來覆蓋jail.conf的設置。Faile2ban會優先讀取并保留這個文件,Fail2ban升級時也不會被覆蓋。
示例,我希望監控Tomcat服務,配置如下:[tomcat-access] enabled = true filter = tomcat-access logpath = /opt/tomcat/logs/localhost_access_log.*.txt maxretry = 5 findtime = 300 bantime = 3600 backend = auto action = iptables-multiport[name=tomcat, port="80,443", protocol=tcp]
參數說明:
屬性 說明 enabled 啟用該規則,true啟用,false禁用或者注釋該屬性。 filter 指定使用哪個過濾器定義文件,對應文件名前綴。 logpath 指定需要監控的日志路徑,可以使用通配符(例如按日期命名的日志文件)。Fail2Ban 會自動掃描這些文件并實時讀取新增日志。 maxretry 在 findtime 指定的時間段內(例如 5 分鐘),同一個 IP 如果觸發了 failregex 規則 5 次,就會被封禁。 findtime 監控時間窗口,單位為秒。表示 Fail2Ban 會在過去 300 秒(即 5 分鐘)內累計每個 IP 的違規次數。 bantime 封禁時間,單位為秒(這里是 1 小時)。一個 IP 被封后,在 bantime 時間結束前不能再次訪問。可設置為:-1 永久封禁;0 不封 IP,但會執行其他 action(如發郵件)。 action 指定封禁方式和封禁哪些端口及協議。iptables-multiport 是 Fail2Ban 提供的一個內置 action 模板,表示用 iptables 拒絕多個端口的訪問。 -
配置攔截器filter
sudo vi /etc/fail2ban/filter.d/tomcat-access.conf
前面介紹的jail.local是用來配置應用場景,而filter是用來定義攔截規則。可以理解為:
- Filter = 你想攔截什么?(匹配什么日志內容)
- Jail = 你在哪兒攔截?多久內攔截?封多久?怎么封?
兩者配合使用,才能讓 Fail2Ban 正常工作。
示例,我希望攔截非法訪問(匹配404、嘗試非法路徑、異常請求等等):
[Definition] failregex = ^<HOST> -.*"(GET|POST|HEAD).*HTTP.*" 404^<HOST> -.*"(GET|POST).*wp-login.php.*HTTP.*"^<HOST> -.*"(GET|POST).*\.env.*HTTP.*"^<HOST> -.*"(GET|POST).*\.git.*HTTP.*" ignoreregex =
參數說明:
屬性 說明 Definition 這是 Fail2Ban 規則文件的標準節名,表示你要定義一個“過濾器規則”。 failregex 核心正則表達式,用于匹配目標日志文件中可疑/惡意行為的日志行。每行一個正則表達式;關鍵是識別出 IP 地址(用 占位);一旦匹配,就會記錄這個 IP 的一次“違規行為”;如果同一個 IP 在 jail 設定的 findtime 時間內達到 maxretry 次數,就觸發封禁。 ignoreregex 這里你可以寫入要排除的正則表達式。如果某些請求雖然匹配 failregex,但你認為是“白名單”,可以寫在這里;它會被優先執行;通常為空即可。 failregex正則表達式詳解,以上面示例說明如下:
^<HOST> -.*"(GET|POST|HEAD).*HTTP.*" 404
匹配如:
192.168.1.100 - - [時間] “GET /test.php HTTP/1.1” 404,表示這個 IP 請求了一個不存在的路徑(404)。^<HOST> -.*"(GET|POST).*wp-login.php.*HTTP.*"
匹配 WordPress 登錄頁面攻擊(即使你不用 WordPress,也有很多掃描器會試圖訪問)。
^<HOST> -.*"(GET|POST).*\.env.*HTTP.*"
.env 文件包含敏感環境變量,攻擊者掃描時常用路徑。
^<HOST> -.*"(GET|POST).*\.git.*HTTP.*"
.git 被誤暴露時會泄露源碼,掃描器會嘗試訪問。
<HOST>
這是 Fail2Ban 特定的占位符,代表被攔截 IP 的位置。它告訴 Fail2Ban “從這部分提取 IP 地址”,并用于計數和封禁。
例如日志文件內容如下:
192.168.1.10 - - [24/Jun/2025:11:03:01 +0800] "GET /.env HTTP/1.1" 404 987
Fail2Ban會提取 192.168.1.10,作為封禁目標。
這里只是舉了一個簡單示例,還有很多攔截器配置內容,大家可以根據需要防護的內容去配置,具體配置內容可以搜索或AI詢問即可。
三、配置 SSH 防護
- 啟用 SSH 保護
在 jail.local 文件中找到[sshd]
部分,設置enabled = true
。 - 自定義 SSH 端口防護(如果更改默認端口)
若服務器 SSH 端口非默認 22,需添加以下內容:
將 2222 替換為實際端口號。[sshd] port = 2222
四、啟動與管理
-
啟動 fail2ban
sudo systemctl start fail2ban
安裝完成系統已經自動啟動。
-
設置開機自啟
sudo systemctl enable fail2ban
-
重啟服務
sudo systemctl restart fail2ban
每次修改配置后需要重啟生效。
-
查看狀態
sudo fail2ban-client status
可以查看當前防護攔截器的列表。
-
查看攔截日志
sudo fail2ban-client status [攔截器名稱]
例如:
sudo fail2ban-client status tomcat-access
返回結果如下:
Status for the jail: tomcat-access |- Filter | |- Currently failed: 0 | |- Total failed: 0 | `- File list: /opt/tomcat/logs/localhost_access_log.2024-08-23.txt /opt/tomcat/logs/localhost_access_log.2025-06-02.txt 此處省略掉若干文件名稱...... `- Actions|- Currently banned: 0|- Total banned: 0`- Banned IP list:
參數說明:
屬性 說明 Status for the jail 顯示當前你查看的是名為 tomcat-access 的 jail(監控規則塊)。 Currently failed 當前時間窗口(findtime,如 300 秒)內,有“多少個 IP 正在違反規則”。這表示當前沒有 IP 正在被 Fail2Ban 判斷為惡意(匹配到 failregex)。 Total failed 自 Fail2Ban 啟動以來,這個 jail 觸發過多少次 failregex。為 0 表示從未匹配成功,注意檢查:1.failregex 正則沒匹配到日志內容;2.日志路徑不對;3.日志格式與正則不符;4.服務本身沒有被攻擊。 File list Fail2Ban 正在讀取并監控的日志文件列表。在你的配置中,它包括多個 localhost_access_log.YYYY-MM-DD.txt 文件(Tomcat 的訪問日志),用于分析是否存在異常訪問行為。 Currently failed 當前時間窗口(findtime,如 300 秒)內,有“多少個 IP 正在違反規則”。這表示當前沒有 IP 正在被 Fail2Ban 判斷為惡意(匹配到 failregex)。 Currently banned 當前被封禁的 IP 數量為 0。說明沒有 IP 正在被防火墻屏蔽。 Total banned 歷史上這個 jail 封過多少 IP。0 表示你這條規則還沒有成功攔過任何人。 Banned IP list 當前封禁列表。為空表示沒有 IP 被 ban。
五、進階配置
-
配置郵件報警
編輯 jail.local 文件,添加以下內容:destemail = your_email@example.com sender = fail2ban@example.com mta = sendmail action = %(action_mwl)s
替換為實際郵箱地址,并確保郵件服務正常運行。
-
添加自定義過濾規則
在/etc/fail2ban/filter.d/
目錄下創建自定義過濾文件,如custom-sshd.conf
,編寫正則表達式匹配日志中的攻擊行為。
六、注意事項與難點
- 文件權限
配置文件權限不要過于開放,建議保持默認權限,避免安全風險。 - 日志路徑準確性
確保 fail2ban 配置的日志路徑與實際服務日志路徑一致,否則無法正確識別攻擊。 - 誤封問題
合理設置參數,避免因網絡波動等正常情況導致自己被誤封,可設置白名單:[sshd] ignoreip = 192.168.1.100 10.0.0.0/24
七、下一步思考
目前配置已有效抵御暴力破解攻擊,但還可以進一步完善:
- 集成更多服務防護規則,如 Apache、Nginx 等 Web 服務。
- 探索與云防火墻聯動,實現更高級的防護策略。
- 定期分析 fail2ban 日志,優化過濾規則,提升防護精準度。
通過在 CentOS 7 上部署 fail2ban,服務器的安全防線得到了顯著加強,惡意攻擊行為得到了有效遏制。后續會持續優化配置,構建更穩固的安全體系。