快速開始
本頁說明安裝 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 與指紋。