入侵防護
類似 fail2ban 的入侵防護:從日誌中辨識暴力破解,在沒有使用的連接埠上設誘餌,統計連接埠掃描,把惡意 IP 加入封鎖清單,並同步到系統防火牆(nftables),在核心層丟棄它的全部流量。
能力
- 日誌規則:讀取日誌檔案、systemd 日誌、命令輸出(如 OpenWrt 的
logread -f)或 Docker 容器日誌,用正規表示式找出失敗記錄,同一 IP 在統計視窗內達到次數即封鎖;內建 SSH、Dropbear、Nginx、Vaultwarden、Home Assistant、Proxmox VE 等範本,編輯規則時可貼上日誌樣例直接測試; - Gately 事件:管理後台登入失敗、WAF 攔截也可以作為規則來源,無需撰寫正規表示式;
- 誘餌連接埠:在本機沒有使用的連接埠上設下誘餌(預設 23、135、1433、3389、5900、6379 等),任何來源一連線就封鎖;
- 連接埠掃描偵測:同一來源每分鐘連線本機未開放連接埠的次數超過閾值即封鎖;
- 統一封鎖清單:手動封鎖(支援 CIDR 網段與永久封鎖)、Web 服務驗證失敗的自動封鎖都在這裡管理;封鎖會持久保存,重新啟動後恢復;
- 遞增封鎖:同一位址 30 天內再次被封鎖時時長加倍,直到上限;
- 白名單:預設忽略內網、迴環、100.64.0.0/10(Tailscale)與本機網卡所在的 IPv6 /64 網段(封鎖依 /64 進行,同一區域網路的公網 IPv6 裝置不會被連帶封鎖),可追加 IP 或網段;白名單中的單個 IPv6 位址會保護它所在的整個 /64。
生效範圍
| 環境 | 封鎖效果 | 誘餌連接埠 | 連接埠掃描偵測 |
|---|---|---|---|
Linux(root 或 CAP_NET_ADMIN,已安裝 nftables) | 核心層丟棄全部流量,包括 SSH、其他程式與轉發給 Docker 容器、內網裝置的流量 | 由核心處理,能發現只發 SYN 的掃描 | 可用 |
Docker(host 網路 + cap_add: NET_ADMIN) | 同上,規則寫入主機 | 同上 | 可用 |
| 飛牛 fnOS 安裝包、OpenWrt 22.03 以上 | 同上(以 root 執行,系統內建 nftables) | 同上 | 可用 |
| 其他情況(Windows、macOS、FreeBSD、沒有 nftables 或權限的 Linux) | 只對 Gately 自身的服務生效:連接埠轉發、Web 服務、STUN、WebDAV、FTP、管理後台 | 由 Gately 監聽,只能發現完成交握的連線 | 無法使用 |
頁面頂部會顯示防火牆同步狀態,無法使用時列出原因與處理方式。
防火牆規則
開啟「同步到系統防火牆」後,Gately 在 nftables 中建立獨立的 inet gately 表,不改動系統既有的規則(fw4、Docker、ufw 等):
prerouting鏈(優先級 -190,在連線追蹤之後、目的位址轉換之前)丟棄被封鎖位址發來的封包,發往本機、轉發給容器或內網裝置的流量都會被丟棄;本機主動發起的連線(例如存取 DNS、軟體來源)的回應照常放行,即使對方位址被封鎖也不受影響;IPv6 依 /64 網段封鎖;input鏈只統計發往本機的新連線,用於誘餌連接埠與掃描偵測,白名單位址不參與;- 關閉同步或停止 Gately 時整張表會被刪除;表被其他程式清除後 10 秒內自動重寫。
頁面上的「檢視規則」可以看到目前寫入的完整規則。
Docker 部署
需要 network_mode: host 並授予 NET_ADMIN,規則才會寫入主機:
network_mode: host
cap_add:
- NET_ADMIN未授予時封鎖仍對 Gately 自身的服務生效。讀取主機日誌需要把日誌目錄掛載進容器,例如 - /var/log:/var/log/host:ro,規則中填寫 /var/log/host/auth.log;systemd 日誌來源在容器中無法使用。
日誌規則
| 來源 | 填寫 | 說明 |
|---|---|---|
| 日誌檔案 | 檔案路徑,每行一個 | 從檔案末尾開始讀取新增內容,輪替(改名或截斷)後自動切換 |
| systemd 日誌 | 服務單元,如 ssh.service | 透過 journalctl -f 讀取 |
| 命令輸出 | 一條命令,如 logread -f | 命令結束後自動重新啟動 |
| Docker 容器 | 容器名稱 | 透過 Docker 管理模組連線的 Docker 讀取 |
| Gately 事件 | 管理後台登入失敗 / WAF 攔截 | 事件自帶來源 IP,不需要過濾規則 |
過濾規則是 Go 正規表示式(RE2 語法),每行一條,用 <HOST> 表示來源位址,例如:
Failed password for (?:invalid user )?\S* ?from <HOST>「排除規則」中相符的行不計數。統計視窗、失敗次數與封鎖時長可依規則設定,封鎖時長可選預設、自訂或永久。
連接埠掃描偵測的取捨
掃描偵測統計的是連線本機未在監聽的連接埠的新連線:正在監聽的 TCP 連接埠每 10 秒自動重新整理,視為開放;由其他防火牆規則轉發出去的連接埠不經過 input 鏈,不會被統計。閾值預設每分鐘 12 次,正常用戶端重試一個關閉的連接埠每分鐘約 5 次,不建議設得低於 10。
誘餌連接埠中正在被監聽的連接埠會被自動排除,避免誤封正常訪客。
與 Web 服務的關係
Web 服務「驗證失敗封鎖」產生的封鎖寫入同一份封鎖清單,因此開啟防火牆同步後會對整台主機生效,不再只限於 Web 站點。開啟「忽略內網位址」時,內網位址不會被自動封鎖。
Web 服務與 WAF 只透過 PROXY 協定辨識真實用戶端位址。站點經 CDN 回源、以請求標頭傳遞真實 IP 時,驗證失敗封鎖與「WAF 攔截」規則封鎖的會是 CDN 節點,這類站點不要啟用它們。
通知
封鎖會產生「入侵防護:IP 已被封鎖」事件,可在通知中心訂閱;誘餌連接埠與掃描偵測在同一輪檢查中封鎖的多個位址合併為一則通知。
驗證
在飛牛 fnOS(Debian 12,nftables 1.0.6)與 iStoreOS 24.10(nftables 1.1.1)的獨立網路命名空間中驗證:誘餌連接埠與掃描偵測(IPv4 與 IPv6)在核心層封鎖並匯入封鎖清單,日誌檔案(含輪替)、systemd 日誌、Docker 容器日誌與管理後台登入失敗都能觸發封鎖;手動網段與永久封鎖、解除封鎖、遞增時長、重新啟動後恢復、規則被外部刪除後重寫、停止時清理規則皆符合預期;Docker 容器在沒有 NET_ADMIN 時判定為權限不足並改用使用者態誘餌連接埠。