caddywaf

package module
v0.0.0-...-cfe2188 Latest Latest
Warning

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

Go to latest
Published: May 7, 2026 License: AGPL-3.0 Imports: 31 Imported by: 0

README

Caddy WAF

For Testing only !

Documentation

Overview

Package caddywaf implements a Web Application Firewall (WAF) middleware for Caddy.

This package provides comprehensive security features including:

  • Regex-based filtering for URLs, data, and headers
  • IP and DNS blacklisting capabilities
  • Geographic access control
  • Rate limiting
  • Anomaly detection and scoring
  • Multi-phase request inspection
  • Real-time metrics and monitoring

The WAF integrates seamlessly with Caddy as an HTTP handler middleware and can be configured via Caddyfile or JSON configuration.

Module ID: http.handlers.waf

Package caddywaf provides Web Application Firewall (WAF) functionality as a Caddy module.

Module ID: http.handlers.waf Module type: HTTP handler middleware

This module implements comprehensive web security features including:

  • Regex-based request filtering
  • IP and DNS blacklisting
  • Geographic access control
  • Rate limiting with configurable windows
  • Anomaly detection and scoring
  • Multi-phase request inspection
  • Real-time metrics and monitoring
  • Custom response handling
  • Dynamic configuration reloading

Installation:

Option 1 - Using caddy add-package (recommended if Caddy is already installed):

caddy add-package github.com/RobinGru/caddy-waf

Option 2 - Building from source with xcaddy:

xcaddy build --with github.com/RobinGru/caddy-waf

Basic usage in Caddyfile:

waf {
    rule_file rules.json
    ip_blacklist_file blacklist.txt
    metrics_endpoint /waf_metrics
}

For complete documentation, see: https://github.com/RobinGru/caddy-waf

rules.go

Index

Constants

View Source
const (
	TargetMethod                = "METHOD"
	TargetRemoteIP              = "REMOTE_IP"
	TargetProtocol              = "PROTOCOL"
	TargetHost                  = "HOST"
	TargetArgs                  = "ARGS"
	TargetUserAgent             = "USER_AGENT"
	TargetPath                  = "PATH"
	TargetURI                   = "URI"
	TargetBody                  = "BODY"
	TargetHeaders               = "HEADERS"          // Full request headers
	TargetResponseHeaders       = "RESPONSE_HEADERS" // Full response headers
	TargetResponseBody          = "RESPONSE_BODY"    // Full response body
	TargetFileName              = "FILE_NAME"
	TargetFileMIMEType          = "FILE_MIME_TYPE"
	TargetCookies               = "COOKIES" // All cookies
	TargetURLParamPrefix        = "URL_PARAM:"
	TargetJSONPathPrefix        = "JSON_PATH:"
	TargetContentType           = "CONTENT_TYPE"
	TargetURL                   = "URL"
	TargetCookiesPrefix         = "COOKIES:"          // Dynamic cookie extraction prefix
	TargetHeadersPrefix         = "HEADERS:"          // Dynamic header extraction prefix
	TargetResponseHeadersPrefix = "RESPONSE_HEADERS:" // Dynamic response header extraction prefix
)

Extraction Target Constants - Improved Readability and Maintainability

Variables

View Source
var Assets embed.FS

Functions

func AddSensitiveKey

func AddSensitiveKey(key string)

Function to modify sensitiveKeys in thread-safe way

func NewResponseRecorder

func NewResponseRecorder(w http.ResponseWriter) *responseRecorder

NewResponseRecorder creates a new responseRecorder.

func RedactSensitiveData

func RedactSensitiveData(data map[string]interface{}) map[string]interface{}

func RemoveSensitiveKey

func RemoveSensitiveKey(key string)

Types

type ASNAccessFilter

type ASNAccessFilter struct {
	Enabled     bool     `json:"enabled"`
	BlockedASNs []string `json:"blocked_asns"`
	GeoIPDBPath string   `json:"geoip_db_path"`
	// contains filtered or unexported fields
}

ASNAccessFilter struct

type ASNRecord

type ASNRecord struct {
	AutonomousSystemOrganization string `maxminddb:"autonomous_system_organization"`
	AutonomousSystemNumber       uint   `maxminddb:"autonomous_system_number"`
}

ASNRecord struct

type BlacklistLoader

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

BlacklistLoader handles loading IP and DNS blacklists from files.

func NewBlacklistLoader

func NewBlacklistLoader(logger *zap.Logger) *BlacklistLoader

NewBlacklistLoader creates a new BlacklistLoader with the provided logger.

func (*BlacklistLoader) LoadDNSBlacklistFromFile

func (bl *BlacklistLoader) LoadDNSBlacklistFromFile(path string, dnsBlacklist map[string]struct{}) error

LoadDNSBlacklistFromFile loads DNS entries from a file into the provided map.

func (*BlacklistLoader) LoadIPBlacklistFromFile

func (bl *BlacklistLoader) LoadIPBlacklistFromFile(path string, ipBlacklist map[string]struct{}) error

LoadIPBlacklistFromFile loads IP addresses from a file into the provided map.

type ConfigLoader

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

ConfigLoader structure to encapsulate loading and parsing logic

func NewConfigLoader

func NewConfigLoader(logger *zap.Logger) *ConfigLoader

func (*ConfigLoader) UnmarshalCaddyfile

func (cl *ConfigLoader) UnmarshalCaddyfile(d *caddyfile.Dispenser, m *Middleware) error

UnmarshalCaddyfile is the primary parsing function for the middleware configuration.

type ContextKeyLogId

type ContextKeyLogId string

type ContextKeyRule

type ContextKeyRule string

type CountryAccessFilter

type CountryAccessFilter struct {
	Enabled     bool     `json:"enabled"`
	CountryList []string `json:"country_list"`
	GeoIPDBPath string   `json:"geoip_db_path"`
	// contains filtered or unexported fields
}

CountryAccessFilter struct

type CustomBlockResponse

type CustomBlockResponse struct {
	StatusCode int
	Headers    map[string]string
	Body       string
}

CustomBlockResponse struct

type GeoIPHandler

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

GeoIPHandler struct

func NewGeoIPHandler

func NewGeoIPHandler(logger *zap.Logger) *GeoIPHandler

NewGeoIPHandler creates a new GeoIPHandler with a given logger

func (*GeoIPHandler) GetASN

func (gh *GeoIPHandler) GetASN(remoteAddr string, geoIP *maxminddb.Reader) string

GetASN extracts the ASN for logging purposes

func (*GeoIPHandler) GetCountryCode

func (gh *GeoIPHandler) GetCountryCode(remoteAddr string, geoIP *maxminddb.Reader) string

getCountryCode extracts the country code for logging purposes

func (*GeoIPHandler) IsASNInList

func (gh *GeoIPHandler) IsASNInList(remoteAddr string, blockedASNs []string, geoIP *maxminddb.Reader) (bool, error)

IsASNInList checks if an IP belongs to a list of blocked ASNs

func (*GeoIPHandler) IsCountryInList

func (gh *GeoIPHandler) IsCountryInList(remoteAddr string, countryList []string, geoIP *maxminddb.Reader) (bool, error)

IsCountryInList checks if an IP belongs to a list of countries

func (*GeoIPHandler) LoadGeoIPDatabase

func (gh *GeoIPHandler) LoadGeoIPDatabase(path string) (*maxminddb.Reader, error)

LoadGeoIPDatabase opens the geoip database

func (*GeoIPHandler) WithGeoIPCache

func (gh *GeoIPHandler) WithGeoIPCache(ttl time.Duration)

WithGeoIPCache enables GeoIP lookup caching.

func (*GeoIPHandler) WithGeoIPLookupFallbackBehavior

func (gh *GeoIPHandler) WithGeoIPLookupFallbackBehavior(behavior string)

WithGeoIPLookupFallbackBehavior configures the fallback behavior for GeoIP lookups.

type GeoIPRecord

type GeoIPRecord struct {
	Country struct {
		ISOCode string `maxminddb:"iso_code"`
	} `maxminddb:"country"`
}

GeoIPRecord struct

type HitCount

type HitCount int

Define custom types for rule hits

type LogEntry

type LogEntry struct {
	Level   zapcore.Level
	Message string
	Fields  []zap.Field
}

LogEntry represents a single log entry to be processed asynchronously.

type Middleware

type Middleware struct {
	RuleFiles        []string            `json:"rule_files"`
	IPBlacklistFile  string              `json:"ip_blacklist_file"`
	DNSBlacklistFile string              `json:"dns_blacklist_file"`
	AnomalyThreshold int                 `json:"anomaly_threshold"`
	CountryBlacklist CountryAccessFilter `json:"country_blacklist"`
	CountryWhitelist CountryAccessFilter `json:"country_whitelist"`
	BlockASNs        ASNAccessFilter     `json:"block_asns"`
	Rules            map[int][]Rule      `json:"-"`

	LogSeverity string `json:"log_severity,omitempty"`
	LogJSON     bool   `json:"log_json,omitempty"`

	CustomResponses     map[int]CustomBlockResponse `json:"custom_responses,omitempty"`
	LogFilePath         string
	LogBuffer           int   `json:"log_buffer,omitempty"` // Add the LogBuffer field
	RedactSensitiveData bool  `json:"redact_sensitive_data,omitempty"`
	MaxRequestBodySize  int64 `json:"max_request_body_size,omitempty"`
	GeoIPFailOpen       bool  `json:"geoip_fail_open,omitempty"`

	MetricsEndpoint string `json:"metrics_endpoint,omitempty"`

	RateLimit RateLimit

	Tor TorConfig `json:"tor,omitempty"`

	IPBlacklistBlockCount int64 `json:"ip_blacklist_hits"`

	DNSBlacklistBlockCount int64 `json:"dns_blacklist_hits"`
	// contains filtered or unexported fields
}

Middleware is the main WAF middleware struct that implements Caddy's Module, Provisioner, Validator, and MiddlewareHandler interfaces.

It provides comprehensive web application firewall functionality including:

  • Rule-based request filtering
  • IP and DNS blacklisting
  • Geographic access control
  • Rate limiting
  • Anomaly detection
  • Custom response handling
  • Real-time metrics and monitoring

The middleware can be configured via Caddyfile or JSON and integrates seamlessly into Caddy's request processing pipeline.

func (*Middleware) CaddyModule

func (*Middleware) CaddyModule() caddy.ModuleInfo

func (*Middleware) DebugRequest

func (m *Middleware) DebugRequest(r *http.Request, state *WAFState, msg string)

DebugRequest logs detailed information about a request for debugging

func (*Middleware) DumpRulesToFile

func (m *Middleware) DumpRulesToFile(path string) error

DumpRulesToFile dumps the loaded rules to a file for inspection

func (*Middleware) Provision

func (m *Middleware) Provision(ctx caddy.Context) error

func (*Middleware) ReloadConfig

func (m *Middleware) ReloadConfig() error

func (*Middleware) ReloadRules

func (m *Middleware) ReloadRules() error

func (*Middleware) ServeHTTP

func (m *Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error

ServeHTTP implements caddyhttp.Handler. handler.go

func (*Middleware) Shutdown

func (m *Middleware) Shutdown(ctx context.Context) error

func (*Middleware) StartLogWorker

func (m *Middleware) StartLogWorker()

StartLogWorker initializes the background logging worker.

func (*Middleware) StopLogWorker

func (m *Middleware) StopLogWorker()

StopLogWorker stops the background logging worker.

func (*Middleware) UnmarshalCaddyfile

func (m *Middleware) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

func (*Middleware) Validate

func (m *Middleware) Validate() error

Validate implements caddy.Validator.

type RateLimit

type RateLimit struct {
	Requests        int              `json:"requests"`
	Window          time.Duration    `json:"window"`
	CleanupInterval time.Duration    `json:"cleanup_interval"`
	Paths           []string         `json:"paths,omitempty"` // Optional paths to apply rate limit
	PathRegexes     []*regexp.Regexp `json:"-"`               // Compiled regexes for the given paths
	MatchAllPaths   bool             `json:"match_all_paths,omitempty"`
}

RateLimit struct

type RateLimiter

type RateLimiter struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

RateLimiter struct

func NewRateLimiter

func NewRateLimiter(config RateLimit) (*RateLimiter, error)

NewRateLimiter creates a new RateLimiter instance.

func (*RateLimiter) GetBlockedRequests

func (rl *RateLimiter) GetBlockedRequests() int64

GetBlockedRequests returns the total number of requests blocked by this rate limiter.

func (*RateLimiter) GetTotalRequests

func (rl *RateLimiter) GetTotalRequests() int64

GetTotalRequests returns the total number of requests received by this rate limiter.

type RequestValueExtractor

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

RequestValueExtractor struct

func NewRequestValueExtractor

func NewRequestValueExtractor(logger *zap.Logger, redactSensitiveData bool, maxBodySize int64) *RequestValueExtractor

NewRequestValueExtractor creates a new RequestValueExtractor with a given logger

func (*RequestValueExtractor) ExtractValue

func (rve *RequestValueExtractor) ExtractValue(target string, r *http.Request, w http.ResponseWriter) (string, error)

ExtractValue extracts values based on the target, handling comma separated targets

func (*RequestValueExtractor) RedactValueIfSensitive

func (rve *RequestValueExtractor) RedactValueIfSensitive(target string, value string) string

Helper function to redact value if target is sensitive

type Rule

type Rule struct {
	ID          string   `json:"id"`
	Phase       int      `json:"phase"`
	Pattern     string   `json:"pattern"`
	Targets     []string `json:"targets"`
	Severity    string   `json:"severity"` // Used for logging only
	Score       int      `json:"score"`
	Action      string   `json:"mode"` // CRITICAL FIX: This should map to the "mode" field in JSON
	Description string   `json:"description"`

	Priority int // New field for rule priority
	// contains filtered or unexported fields
}

Rule struct

type RuleCache

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

RuleCache caches compiled regex patterns for rules.

func NewRuleCache

func NewRuleCache() *RuleCache

NewRuleCache creates a new RuleCache.

func (*RuleCache) Get

func (rc *RuleCache) Get(ruleID string) (*regexp.Regexp, bool)

Get retrieves a compiled regex pattern from the cache.

func (*RuleCache) Set

func (rc *RuleCache) Set(ruleID string, regex *regexp.Regexp)

Set stores a compiled regex pattern in the cache.

type RuleID

type RuleID string

Define custom types for rule hits

type TorConfig

type TorConfig struct {
	Enabled              bool   `json:"enabled,omitempty"`
	CustomTORExitNodeURL string `json:"custom_tor_exit_node_url"`
	TORIPBlacklistFile   string `json:"tor_ip_blacklist_file,omitempty"`
	UpdateInterval       string `json:"update_interval,omitempty"`
	RetryOnFailure       bool   `json:"retry_on_failure,omitempty"` // Enable/disable retries
	RetryInterval        string `json:"retry_interval,omitempty"`   // Retry interval (e.g., "5m")
	// contains filtered or unexported fields
}

func (*TorConfig) Provision

func (t *TorConfig) Provision(ctx caddy.Context) error

Provision sets up the Tor blocking configuration.

type WAFState

type WAFState struct {
	TotalScore      int
	Blocked         bool
	StatusCode      int
	ResponseWritten bool
}

WAFState struct

Jump to

Keyboard shortcuts

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