Skip to content

Instantly share code, notes, and snippets.

@fabriziosalmi
Last active January 9, 2025 22:30
Show Gist options
  • Save fabriziosalmi/22fe88f72769faf96d09c69a3caa42e2 to your computer and use it in GitHub Desktop.
Save fabriziosalmi/22fe88f72769faf96d09c69a3caa42e2 to your computer and use it in GitHub Desktop.
Caddy WAF suite (caddy-mib, caddy-mlf, caddy-waf)

Caddy WAF suite

Caddyfile

{
	# Disable the admin API for security (optional)
	admin off

	# Disable automatic HTTPS for testing purposes
	auto_https off

	# Enable debug-level logging for detailed troubleshooting
	log {
		level debug
		output stdout
		format json
	}
}

# Define a server block listening on port 8080
:8080 {
	# Define routing rules for incoming requests
	route {
		# Configure the ML WAF module
		ml_waf {
			# Thresholds
			anomaly_threshold 0.8 # Anomaly score above which traffic is marked as suspicious
			blocking_threshold 0.95 # Anomaly score above which traffic is blocked

			# Normal ranges for request attributes
			normal_request_size_range 50 2000 # Min and max size (in bytes) of a normal request
			normal_header_count_range 3 30 # Min and max number of headers in a normal request
			normal_query_param_count_range 0 10 # Min and max number of query parameters in a normal request
			normal_path_segment_count_range 1 5 # Min and max number of path segments in a normal request

			# Weights for anomaly score calculation
			request_size_weight 0.2 # Weight given to deviations in request size
			header_count_weight 0.1 # Weight given to deviations in header count
			query_param_count_weight 0.2 # Weight given to deviations in query parameter count
			path_segment_count_weight 0.1 # Weight given to deviations in path segment count

			# Additional attributes (new)
			normal_http_methods GET POST # Allowed HTTP methods (e.g., GET, POST)
			normal_user_agents Chrome Firefox Mozilla # Allowed User-Agent strings (e.g., Chrome, Firefox)
			normal_referrers http://localhost # Allowed Referrer headers (e.g., trusted domains)
			http_method_weight 0.1 # Weight given to deviations in HTTP method
			user_agent_weight 0.1 # Weight given to deviations in User-Agent
			referrer_weight 0.1 # Weight given to deviations in Referrer

			# Request history settings
			history_window 10m # Time window for considering past requests (e.g., 5m, 1h)
			max_history_entries 100 # Maximum number of past requests to keep in history
		}

		# Configure the MIB (Malicious IP Blocker) module
		caddy_mib {
			error_codes 404 # HTTP error codes to monitor (e.g., 404, 403)
			max_error_count 5 # Maximum number of errors before banning an IP
			ban_duration 10m # Duration for which an IP is banned
			ban_duration_multiplier 2 # Multiplier for increasing ban duration on repeated offenses
			output stdout # Output logs to stdout
			whitelist 10.0.0.0/24 # Whitelist specific IPs or subnets
		}

		# Configure the WAF (Web Application Firewall) module
		waf {
			# Set a threshold for detecting anomalies
			anomaly_threshold 10

			# Block requests originating from specific countries (Russia, China, North Korea)
			block_countries GeoLite2-Country.mmdb RU CN KP

			# Rate limit requests to 1000 requests per minute, with a 5-minute ban for violators
			rate_limit 1000 1m 5m

			# Load WAF rules from a JSON file
			rule_file rules.json

			# Load a list of blacklisted IPs from a file
			ip_blacklist_file ip_blacklist.txt

			# Load a list of blacklisted DNS entries from a file
			dns_blacklist_file dns_blacklist.txt

			# Set the log severity level for WAF events
			log_severity info

			# Log WAF events in JSON format
			log_json

			# Log path for WAF events
			log_path debug.json

			# Redact sensitive data in logs (optional)
			# redact_sensitive_data
		}

		# Serve static files from a directory
		file_server {
			root /var/www/html
		}

		# Respond to all requests with "Hello, world!" and a 200 status code
		respond "Hello, world!" 200
	}

	# Add HTTP headers for enhanced security
	header {
		# Enforce HTTPS for the next year and include subdomains
		Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

		# Prevent the page from being embedded in frames or iframes
		X-Frame-Options "DENY"

		# Prevent MIME type sniffing
		X-Content-Type-Options "nosniff"

		# Disable referrer information in requests
		Referrer-Policy "no-referrer"

		# Restrict access to geolocation, microphone, and camera APIs
		Permissions-Policy "geolocation=(), microphone=(), camera=()"

		# Define a Content Security Policy to restrict resource loading
		Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'"

		# Disallow cross-domain policies
		X-Permitted-Cross-Domain-Policies "none"

		# Clear cached data, cookies, and storage when the response is sent
		Clear-Site-Data "\"cache\", \"cookies\", \"storage\""

		# Require cross-origin isolation for embedded resources
		Cross-Origin-Embedder-Policy "require-corp"

		# Restrict cross-origin window interactions to the same origin
		Cross-Origin-Opener-Policy "same-origin"

		# Restrict cross-origin resource access to the same origin
		Cross-Origin-Resource-Policy "same-origin"
	}
}

Quick Start

go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
go clean -modcache
xcaddy build --with github.com/fabriziosalmi/caddy-mib --with github.com/fabriziosalmi/caddy-mlf --with github.com/fabriziosalmi/caddy-waf
caddy fmt --overwrite
./caddy run

Enjoy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment