Getting Started
This page installs go-ip-sentry, starts Redis, and runs a first protected server with net/http.
Prerequisites
| Item | Requirement |
|---|---|
| Go | 1.24.3 or higher (go.mod) |
| Redis | Any reachable instance; every counter, list, and cache lives in Redis |
| HTTPS | Session and device cookies carry Secure, so browsers drop them over plain HTTP and every request becomes a new session |
| GeoLite2 (optional) | GeoLite2-City.mmdb, only for geo detection; see Geo Detection |
Installation
go get github.com/pardnchiu/golang-ip-sentry
The module path is github.com/pardnchiu/golang-ip-sentry and the package name is golangIPSentry, which differs from the directory name, so import it with an explicit alias.
Start Redis
docker run -d --name redis -p 6379:6379 redis:7-alpine
First Server
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{
// required: 0 makes block records never expire
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() pings Redis first and returns an error when it cannot connect; on success it also loads the Allow and Deny list files (skipped when absent).
Verify the Rate Limit
curl keeps no cookies by default, so every request is a new session, which makes the default per-minute limit easy to observe:
for i in $(seq 1 100); do
curl -sk -o /dev/null -w "%{http_code}\n" https://localhost:8443/
done | sort | uniq -c
RateLimitNormal defaults to 100; the count includes the current request and compares with >=, so the 100th request within the same minute returns 403:
{"error":"Device is reached rate limit (Normal), IP: 127.0.0.1"}
Files Created at Runtime
| File | When |
|---|---|
.sessionSecret |
Created in the working directory on the first signed session (mode 0600) |
./logs/mysqlPool* |
Default log path when Log is unset |
./whiteList.json / ./blackList.json |
Written by Allow.Add / Deny.Add |
Add .sessionSecret to .gitignore; in multi-instance deployments every instance must share the same file, see Session and Fingerprint.
Next Steps
- Request Lifecycle: when
Checkpasses and when it returns403 - Middleware: Gin integration and skipping health-check paths
- Parameters: tune thresholds and scores