security

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 9, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package security implements VORTEX's edge protection (build plan M3.7): an HTTP-layer token-bucket rate limiter keyed per client IP, an IP allowlist/blocklist with Tor-exit and auto-ban support, and an edge middleware that composes them. It is distinct from the M2.5 UDP rate limiter, which guards the UDP data plane. Standard library only.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AutoBanConfig

type AutoBanConfig struct {
	Threshold   int           // requests within Window before a ban triggers
	Window      time.Duration // rolling window for counting requests
	BanDuration time.Duration // how long a ban lasts
}

AutoBanConfig configures rolling-window automatic banning.

type Blocklist

type Blocklist struct {
	// contains filtered or unexported fields
}

Blocklist enforces IP allow/block decisions with optional Tor and auto-ban. It is safe for concurrent use.

func NewBlocklist

func NewBlocklist(cfg BlocklistConfig) (*Blocklist, error)

NewBlocklist parses the allow/block lists and, when BlockTor is set, fetches the Tor exit-node list (gracefully degrading to no Tor blocking on failure).

func (*Blocklist) IsAllowed

func (b *Blocklist) IsAllowed(ip string) (bool, string)

IsAllowed reports whether ip may proceed and a human-readable reason. The checks run in order: allowlist (if set), manual block, Tor exit, auto-ban.

func (*Blocklist) ManualBlock

func (b *Blocklist) ManualBlock(ip, reason string)

ManualBlock blocks ip at runtime with the given reason.

func (*Blocklist) ManualUnblock

func (b *Blocklist) ManualUnblock(ip string)

ManualUnblock removes a runtime manual block for ip.

func (*Blocklist) RecordRequest

func (b *Blocklist) RecordRequest(ip string)

RecordRequest tracks a request from ip for auto-ban accounting; if the count within the configured window exceeds the threshold, ip is auto-banned.

func (*Blocklist) StartTorRefresh

func (b *Blocklist) StartTorRefresh(ctx context.Context, url string)

StartTorRefresh refreshes the Tor exit list every 24h until ctx is cancelled. It is a no-op when Tor blocking is disabled.

func (*Blocklist) Stats

func (b *Blocklist) Stats() BlocklistStats

Stats returns a snapshot of current blocklist activity.

type BlocklistConfig

type BlocklistConfig struct {
	IPAllowlist []string // CIDRs or IPs; when non-empty, only these are allowed
	IPBlocklist []string // CIDRs or IPs to always block
	BlockTor    bool     // fetch and block Tor exit nodes
	TorListURL  string   // override the Tor list URL (default official)
	AutoBan     AutoBanConfig
}

BlocklistConfig configures a Blocklist.

type BlocklistStats

type BlocklistStats struct {
	ManualBlocks  int
	AutoBans      int
	TorBlocks     int
	AllowlistSize int
	TotalChecked  int64
}

BlocklistStats is a snapshot of blocklist activity.

type Edge

type Edge struct {
	// contains filtered or unexported fields
}

Edge composes IP blocking and rate limiting into one HTTP middleware. It resolves the real client IP (honouring X-Forwarded-For only from trusted proxies) and exposes it downstream via the X-Vortex-Client-IP header.

func NewEdge

func NewEdge(cfg EdgeConfig) *Edge

NewEdge builds an Edge from cfg. Invalid TrustedProxies entries are ignored (treated as no trusted proxy) so a misconfiguration fails closed — XFF is then never trusted.

func (*Edge) Middleware

func (e *Edge) Middleware() func(http.Handler) http.Handler

Middleware returns the edge security middleware. Pipeline per request:

  1. resolve the client IP (XFF if from a trusted proxy, else RemoteAddr)
  2. Blocklist.IsAllowed → 403 JSON if blocked
  3. Blocklist.RecordRequest (auto-ban accounting)
  4. RateLimit.Allow → 429 if limited
  5. next handler, with X-Vortex-Client-IP set to the resolved IP

func (*Edge) Stats

func (e *Edge) Stats() EdgeStats

Stats returns the edge's combined statistics.

type EdgeConfig

type EdgeConfig struct {
	Blocklist      *Blocklist       // may be nil to skip block checks
	RateLimit      *HTTPRateLimiter // may be nil to skip rate limiting
	TrustedProxies []string         // CIDRs/IPs whose X-Forwarded-For is trusted
}

EdgeConfig configures the edge security middleware.

type EdgeStats

type EdgeStats struct {
	Blocklist BlocklistStats
}

EdgeStats combines blocklist stats with edge-level counters.

type HTTPRateLimiter

type HTTPRateLimiter struct {
	// contains filtered or unexported fields
}

HTTPRateLimiter applies a token bucket per source IP. It is safe for concurrent use.

func NewHTTPRateLimiter

func NewHTTPRateLimiter(cfg HTTPRateLimiterConfig) *HTTPRateLimiter

NewHTTPRateLimiter builds a limiter from cfg. A non-positive Burst defaults to RPM (one minute's worth of tokens).

func (*HTTPRateLimiter) Allow

func (r *HTTPRateLimiter) Allow(ip string) bool

Allow reports whether a request from ip may proceed, consuming one token. When the limiter is disabled it always allows.

func (*HTTPRateLimiter) Middleware

func (r *HTTPRateLimiter) Middleware() func(http.Handler) http.Handler

Middleware returns an HTTP middleware that rejects over-limit requests with a 429 and a JSON body, setting the Retry-After header. It logs a WARN on each rejection. The client IP is read from the X-Vortex-Client-IP header set by the edge (see edge.go); absent that it falls back to RemoteAddr.

func (*HTTPRateLimiter) SetClock

func (r *HTTPRateLimiter) SetClock(now func() time.Time)

SetClock overrides the limiter's time source. It is intended for tests so rate-limit behaviour can be asserted deterministically without real waits.

func (*HTTPRateLimiter) StartCleanup

func (r *HTTPRateLimiter) StartCleanup(ctx context.Context)

StartCleanup periodically removes buckets that have been idle beyond bucketIdleTTL, bounding memory under churning client IPs. It returns when ctx is cancelled.

type HTTPRateLimiterConfig

type HTTPRateLimiterConfig struct {
	RPM     int  // requests per minute per IP
	Burst   int  // bucket capacity (max burst); defaults to RPM when <= 0
	Enabled bool // when false, Allow always returns true
}

HTTPRateLimiterConfig configures a per-IP HTTP rate limiter.

type PerRouteRateLimiter

type PerRouteRateLimiter struct {
	// contains filtered or unexported fields
}

PerRouteRateLimiter holds an independent HTTPRateLimiter per route name.

func NewPerRouteRateLimiter

func NewPerRouteRateLimiter(routes map[string]HTTPRateLimiterConfig) *PerRouteRateLimiter

NewPerRouteRateLimiter builds a limiter per route from the given configs.

func (*PerRouteRateLimiter) MiddlewareForRoute

func (p *PerRouteRateLimiter) MiddlewareForRoute(routeName string) func(http.Handler) http.Handler

MiddlewareForRoute returns the rate-limit middleware for routeName, or a pass-through when the route has no configured limiter.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL