DEV Community

邱敬幃 Pardn Chiu
邱敬幃 Pardn Chiu

Posted on

IP 威脅防護 (Golang)

#go

cover

一個 Go 語言 IP 安全防護套件,提供即時威脅檢測、動態風險評分、設備指紋識別和多層安全機制。

三大主軸

多層安全防護

  • 白名單管理:信任清單自動跳過安全檢查,支援檔案同步
  • 黑名單系統:永久封鎖惡意 IP,整合 Email 通知機制
  • 動態封鎖:暫時封鎖可疑活動,採用指數時間增長
  • 自動升級:重複封鎖自動升級為永久禁用

智慧威脅檢測

  • 設備指紋:SHA256 加密唯一設備識別,365 天追蹤
  • 行為分析:請求模式、時間間隔、工作階段追蹤
  • 地理位置監控:跨國跳躍、快速位置變化、高風險地區檢測
  • 關聯分析:多設備、多 IP、多工作階段異常檢測
  • 登入行為:登入失敗次數和 404 錯誤頻率監控

動態評分系統 (可自行設置閾值)

  • 即時計算:多維度風險因子平行計算
  • 適應調整:基於威脅等級的動態速率限制
  • 閾值管理:可疑、危險、封鎖三層分級
  • 自動限速:正常、可疑、危險 三層限制

依賴套件

使用方法

安裝

go get github.com/pardnchiu/go-ip-sentry
Enter fullscreen mode Exit fullscreen mode

基本初始化

package main

import (
  "log"
  "net/http"

  is "github.com/pardnchiu/go-ip-sentry"
)

func main() {
  config := is.Config{
    Redis: is.Redis{
      Host:     "localhost",
      Port:     6379,
      Password: "",
      DB:       0,
    },
    Log: &is.Log{
      Path:    "./logs/ip-sentry",
      Stdout:  false,
      MaxSize: 16 * 1024 * 1024,
    },
    Filepath: is.Filepath{
      CityDB:    "./GeoLite2-City.mmdb",
      CountryDB: "./GeoLite2-Country.mmdb",
      WhiteList: "./whiteList.json",
      BlackList: "./blackList.json",
    },
    Parameter: is.Parameter{
      BlockToBan:             3,
      BlockTimeMin:           30 * time.Minute,
      BlockTimeMax:           1800 * time.Minute,
      RateLimitNormal:        100,
      RateLimitSuspicious:    50,
      RateLimitDangerous:     20,
      ScoreSuspicious:        50,
      ScoreDangerous:         80,
    },
  }

  guardian, err := is.New(config)
  if err != nil {
    log.Fatal(err)
  }
  defer guardian.Close()

  // HTTP 中間件
  handler := guardian.HTTPMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    w.Write([]byte("歡迎訪問"))
  }))

  http.Handle("/", handler)
  log.Println("伺服器啟動:8080")
  log.Fatal(http.ListenAndServe(":8080", nil))
}
Enter fullscreen mode Exit fullscreen mode

Gin 框架整合

package main

import (
  "github.com/gin-gonic/gin"
  is "github.com/pardnchiu/go-ip-sentry"
)

func main() {
  config := is.Config{
    // 配置同上
  }

  guardian, err := is.New(config)
  if err != nil {
    panic(err)
  }
  defer guardian.Close()

  r := gin.Default()

  // 使用 IP Sentry 中間件
  r.Use(guardian.GinMiddleware())

  r.GET("/", func(c *gin.Context) {
    c.JSON(200, gin.H{
      "message": "歡迎訪問",
    })
  })

  r.Run(":8080")
}
Enter fullscreen mode Exit fullscreen mode

配置介紹

type Config struct {
  Redis     Redis        `json:"redis"`     // Redis 連線配置
  Email     *EmailConfig `json:"email"`     // Email 通知配置
  Log       *Log         `json:"log"`       // 日誌配置
  Filepath  Filepath     `json:"filepath"`  // 檔案路徑配置
  Parameter Parameter    `json:"parameter"` // 參數配置
}

type Redis struct {
  Host     string `json:"host"`     // Redis 主機
  Port     int    `json:"port"`     // Redis 埠
  Password string `json:"password"` // Redis 密碼
  DB       int    `json:"db"`       // Redis 資料庫
}

type EmailConfig struct {
  Host     string                                 `json:"host"`     // SMTP 主機
  Port     int                                    `json:"port"`     // SMTP 埠
  Username string                                 `json:"username"` // SMTP 用戶名
  Password string                                 `json:"password"` // SMTP 密碼
  From     string                                 `json:"from"`     // 寄件者
  To       []string                               `json:"to"`       // 收件者
  CC       []string                               `json:"cc"`       // 副本收件者
  Subject  *func(ip string, reason string) string `json:"-"`        // 自定義主旨
  Body     *func(ip string, reason string) string `json:"-"`        // 自定義內容
}

type Log struct {
  Path      string // 日誌目錄路徑 (預設: ./logs/mysqlPool)
  Stdout    bool   // 啟用控制台輸出 (預設: false)
  MaxSize   int64  // 檔案輪轉前的最大大小 (預設: 16*1024*1024)
  MaxBackup int    // 保留的日誌檔案數量 (預設: 5)
  Type      string // 輸出格式:"json" 為 slog 標準,"text" 為樹狀格式(預設:"text")
}

type Filepath struct {
  CityDB    string `json:"city_db"`    // GeoLite2-City.mmdb
  CountryDB string `json:"country_db"` // GeoLite2-Country.mmdb
  WhiteList string `json:"trust_list"` // 白名單檔案
  BlackList string `json:"ban_list"`   // 黑名單檔案
}

type Parameter struct {
  HighRiskCountry        []string       `json:"high_risk_country"`         // 高風險國家列表
  BlockToBan             int            `json:"block_to_ban"`              // 封鎖到禁用的次數
  BlockTimeMin           time.Duration  `json:"block_time_min"`            // 最小封鎖時間
  BlockTimeMax           time.Duration  `json:"block_time_max"`            // 最大封鎖時間
  RateLimitNormal        int            `json:"rate_limit_normal"`         // 正常請求速率限制
  RateLimitSuspicious    int            `json:"rate_limit_suspicious"`     // 可疑請求速率限制
  RateLimitDangerous     int            `json:"rate_limit_dangerous"`      // 危險請求速率限制
  SessionMultiIP         int            `json:"session_multi_ip"`          // 單一會話允許的最大 IP 數
  IPMultiDevice          int            `json:"ip_multi_device"`           // 單一 IP 允許的最大設備數
  DeviceMultiIP          int            `json:"device_multi_ip"`           // 單一設備允許的最大 IP 數
  LoginFailure           int            `json:"login_failure"`             // 單一會話允許的最大登入失敗次數
  NotFound404            int            `json:"not_found_404"`             // 單一會話允許的最大 404 請求數
  ScoreSuspicious        int            `json:"score_suspicious"`          // 可疑請求閾值
  ScoreDangerous         int            `json:"score_dangerous"`           // 危險請求閾值
  ScoreSessionMultiIP    int            `json:"score_session_multi_ip"`    // 單一會話多 IP 風險分數
  ScoreIPMultiDevice     int            `json:"score_ip_multi_device"`     // 單一 IP 多設備風險分數
  ScoreDeviceMultiIP     int            `json:"score_device_multi_ip"`     // 單一設備多 IP 風險分數
  ScoreFpMultiSession    int            `json:"score_fp_multi_session"`    // 單一指紋多會話風險分數
  ScoreGeoHighRisk       int            `json:"score_geo_high_risk"`       // 高風險地理位置分數
  ScoreGeoHopping        int            `json:"score_geo_hopping"`         // 地理位置跳躍分數
  ScoreGeoFrequentSwitch int            `json:"score_geo_frequent_switch"` // 地理位置頻繁切換分數
  ScoreGeoRapidChange    int            `json:"score_geo_rapid_change"`    // 地理位置快速變化分數
  ScoreIntervalRequest   int            `json:"score_interval_request"`    // 短時間內請求分數
  ScoreFrequencyRequest  int            `json:"score_frequency_request"`   // 請求頻率分數
  ScoreLongConnection    int            `json:"score_long_connection"`     // 長連接分數
  ScoreLoginFailure      int            `json:"score_login_failure"`       // 登入失敗分數
  ScoreNotFound404       int            `json:"score_not_found_404"`       // 404 請求分數
}
Enter fullscreen mode Exit fullscreen mode

可用函式

實例管理

  • New - 建立新的實例
  pool err := is.New(config)
Enter fullscreen mode Exit fullscreen mode
  • Close - 關閉實例
  err := pool.Close()
Enter fullscreen mode Exit fullscreen mode

IP 管理

  • Check - IP 檢查
  result := guardian.Check(r, w)
Enter fullscreen mode Exit fullscreen mode
  • Allow.Add - 加入白名單
  err := guardian.Manager.Allow.Add("192.168.1.100", "內部伺服器")
Enter fullscreen mode Exit fullscreen mode
  • Deny.Add - 加入黑名單
  err := guardian.Manager.Deny.Add("1.2.3.4", "惡意攻擊")
Enter fullscreen mode Exit fullscreen mode
  • Block.Add - 加入封鎖名單
  err := guardian.Manager.Block.Add("5.6.7.8", "可疑行為")
Enter fullscreen mode Exit fullscreen mode
  • LoginFailure - 登入失敗
  err := guardian.LoginFailure(w, r)
Enter fullscreen mode Exit fullscreen mode
  • NotFound404 - 登入失敗
  err := guardian.NotFound404(w, r)
Enter fullscreen mode Exit fullscreen mode

中間件使用

// HTTP 標準中間件
handler := guardian.HTTPMiddleware(yourHandler)

// Gin 中間件
router.Use(guardian.GinMiddleware())
Enter fullscreen mode Exit fullscreen mode

名單格式

whiteList.json

[
  {
    "ip": "192.168.1.100",
    "reason": "內部伺服器",
    "added_at": 1703980800
  }
]
Enter fullscreen mode Exit fullscreen mode

blackList.json

[
  {
    "ip": "1.2.3.4",
    "reason": "惡意攻擊",
    "added_at": 1703980800
  }
]
Enter fullscreen mode Exit fullscreen mode

風險評分系統

基本檢查

  • 會話多 IP 檢查:單一會話使用多個 IP
  • IP 多設備檢查:單一 IP 對應多個設備指紋
  • 設備多 IP 檢查:單一設備使用多個 IP
  • 登入失敗監控:記錄失敗次數,超過閾值觸發風險
  • 404 錯誤追蹤:監控異常路徑探測行為

地理位置分析

  • 高風險國家:可配置高風險地區列表
  • 地理跳躍:1 小時內超過 4 個國家觸發警報
  • 頻繁切換:1 小時內城市切換超過 4 次
  • 快速變化:移動速度超過 800 km/h 或 30 分鐘內跨越 500 km
  • 距離計算:使用 Haversine 公式計算地球表面距離

行為分析

  • 請求間隔規律性檢測:變異數 < 1000 且間隔規律
  • 長連接時間監控:超過 1/2/4 小時分級警報
  • 頻繁請求模式識別:500ms 內超過 16 次請求
  • 極端規律性檢測:變異數 < 100 且樣本 ≥ 8

指紋分析

  • 同指紋多會話檢測:1 分鐘內單一指紋超過 2 個會話
  • 分鐘級統計保護:使用時間戳分段避免誤判

授權條款

此源碼專案採用 MIT 授權條款。


©️ 2025 邱敬幃 Pardn Chiu

Top comments (0)