文件 v1.0.0

快速開始

本頁說明安裝 go-ip-sentry、啟動 Redis,並以 net/http 跑出第一個受保護的伺服器。

前置需求

項目 需求
Go 1.24.3 以上(go.mod)
Redis 任一可連線的實例;所有計數、名單與快取都存在 Redis
HTTPS Session 與裝置 Cookie 帶 Secure,瀏覽器在純 HTTP 下不回傳,每個請求都會變成新 Session
GeoLite2(選用) GeoLite2-City.mmdb,啟用地理偵測時才需要,見 地理偵測

安裝

go get github.com/pardnchiu/golang-ip-sentry

模組路徑是 github.com/pardnchiu/golang-ip-sentry,套件名稱是 golangIPSentry,與目錄名不同,import 時明確指定別名。

啟動 Redis

docker run -d --name redis -p 6379:6379 redis:7-alpine

第一個伺服器

package main

import (
    "log"
    "net/http"
    "time"

    golangIPSentry "github.com/pardnchiu/golang-ip-sentry"
)

func main() {
    sentry, err := golangIPSentry.New(golangIPSentry.Config{
        Redis: golangIPSentry.Redis{Host: "localhost", Port: 6379},
        Parameter: golangIPSentry.Parameter{
            // 必填:0 會讓封鎖紀錄永不過期
            BlockTimeMin: 5 * time.Minute,
            BlockTimeMax: 24 * time.Hour,
        },
    })
    if err != nil {
        log.Fatal(err)
    }
    defer sentry.Close()

    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("OK"))
    })

    log.Fatal(http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", sentry.HTTPMiddleware(mux)))
}

New() 會先 PING Redis,連不上即回傳錯誤;成功時同時載入 Allow/Deny 名單檔(不存在則略過)。

驗證速率限制

curl 預設不保存 Cookie,每個請求都是新 Session,正好能觀察預設的每分鐘上限:

for i in $(seq 1 100); do
  curl -sk -o /dev/null -w "%{http_code}\n" https://localhost:8443/
done | sort | uniq -c

預設 RateLimitNormal 為 100,計數包含當前請求且以 >= 比較,同一分鐘內第 100 個請求回 403:

{"error":"Device is reached rate limit (Normal), IP: 127.0.0.1"}

執行期產生的檔案

檔案 時機
.sessionSecret 第一次簽發 Session 時於工作目錄建立(權限 0600)
./logs/mysqlPool* Log 未設定時的預設日誌路徑
./whiteList.json/./blackList.json 呼叫 Allow.Add/Deny.Add 時寫入

.sessionSecret 應加入 .gitignore;多實例部署時所有實例必須共用同一份,見 Session 與指紋。

下一步

EN