Allow 與 Deny 名單
本頁說明兩份永久名單(白名單 Allow、黑名單 Deny)的載入、查詢、寫入與移除方式。
行為對照
| 項目 | Allow | Deny |
|---|---|---|
| 存取 | IPGuardian.Manager.Allow |
IPGuardian.Manager.Deny |
| 命中結果 | 200,跳過所有後續檢查 |
403,Device is banned, IP: {ip} |
| 優先序 | 最高;同時在 Block 或 Deny 也放行 | 在 Block 之後判定 |
| Redis key | allow:{ip},無過期 |
deny:{ip},無過期 |
| 名單檔 | Filepath.WhiteList,預設 ./whiteList.json |
Filepath.BlackList,預設 ./blackList.json |
| 新增後通知 | 無 | 有設定 Email 時非同步寄信,見 Email 通知 |
啟動載入
New() 讀取名單檔,每筆同時寫入記憶體快取與 Redis(pipeline):
| 情況 | 行為 |
|---|---|
| 檔案不存在 | 略過 |
| 讀取或 JSON 解析失敗 | 記錄錯誤,New() 仍成功 |
| Redis 寫入失敗 | 記錄錯誤,記憶體快取已載入 |
名單檔格式(IPItem 陣列):
[
{"ip": "203.0.113.10", "reason": "office gateway", "added_at": 1735689600}
]
查詢
Check(ip) 先查 Redis EXISTS;存在即回 true,不存在或 Redis 錯誤時再查記憶體快取。比對是字串完全相同,IPv6 的不同寫法(例如省略零)視為不同 IP。
新增
if err := sentry.Manager.Allow.Add("203.0.113.10", "office gateway"); err != nil {
log.Printf("allow: %v", err)
}
if err := sentry.Manager.Deny.Add("198.51.100.7", "credential stuffing"); err != nil {
log.Printf("deny: %v", err)
}
Add 依序寫入記憶體快取、Redis,再把本實例記憶體快取整份覆寫回名單檔。
移除
沒有提供移除 API。因為 Check 先查 Redis,只改檔案不會生效,需同時:
- 刪除 Redis key:
redis-cli DEL allow:203.0.113.10 - 從名單檔移除該筆
- 重啟所有實例以清除記憶體快取
多實例邊界
| 情境 | 行為 |
|---|---|
實例 A 呼叫 Add |
Redis 立即對所有實例生效;只有 A 的記憶體快取與名單檔有這筆 |
| 多個實例共用同一份名單檔 | 每次 Add 都以自己的快取覆寫整份檔案,會蓋掉其他實例新增的項目 |
| Redis 清空後重啟 | 只有寫進名單檔的項目會被載回 |
需要跨實例一致時,以 Redis 為準,名單檔只當單一實例的備份。