Skip to content

Add blocked request access logging#140

Open
JasonLovesDoggo wants to merge 5 commits into
mainfrom
defender-blocked-access-log
Open

Add blocked request access logging#140
JasonLovesDoggo wants to merge 5 commits into
mainfrom
defender-blocked-access-log

Conversation

@JasonLovesDoggo
Copy link
Copy Markdown
Owner

@JasonLovesDoggo JasonLovesDoggo commented May 14, 2026

Summary

Adds an access_log option to defender so blocked requests can be routed to a named Caddy access logger.

Blocked access log entries also include defender.blocked, defender.action, defender.client_ip, and defender.reason fields.

Example Caddyfile
example.com {
	log defender_blocked {
		output file /var/log/caddy/defender-blocked.log
		format json
	}

	defender block {
		ranges openai aws
		access_log defender_blocked
	}

	respond "Human-friendly content"
}
Closes #132

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new access_log configuration option to the defender HTTP handler so that blocked requests can be routed to one or more named Caddy access loggers, and enriches blocked-request access logs with defender.* structured fields.

Changes:

  • Added access_log config (AccessLogNames) to route blocked requests to named access logger(s).
  • Mark blocked requests with extra structured log fields: defender.blocked, defender.action, defender.client_ip, defender.reason.
  • Updated documentation and added unit + E2E test coverage for access-log routing and log field enrichment.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
README.md Documents the new access_log option in the directive syntax.
plugin.go Adds the AccessLogNames field to the module configuration struct.
config.go Parses access_log from Caddyfile into AccessLogNames.
middleware.go Sets access logger names for blocked requests and injects extra log fields.
middleware_test.go Unit test verifying blocked requests are routed to configured logger(s).
config_test.go Tests parsing access_log via Caddyfile and JSON config.
docs/examples.md Adds a “Log Blocked Requests” example and describes new defender.* fields.
docs/config.md Documents the access_log option in Caddyfile/JSON config docs.
access_log_e2e_test.go E2E test validating blocked requests hit the configured access logger and include defender.* fields.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread middleware.go
Comment on lines +88 to +93
existing, _ := caddyhttp.GetVar(ctx, caddyhttp.AccessLoggerNameVarKey).([]any)
names := make([]any, 0, len(existing)+len(defenderLogNames))
names = append(names, existing...)
for _, name := range defenderLogNames {
names = append(names, name)
}
Comment thread config.go
Comment on lines +99 to +101
m.AccessLogNames = append(m.AccessLogNames, d.Val())
for d.NextArg() {
m.AccessLogNames = append(m.AccessLogNames, d.Val())
Comment thread access_log_e2e_test.go
Comment on lines +20 to +35
defer tester.InitServer(`{
admin localhost:2999
}`, "caddyfile")

tester.InitServer(fmt.Sprintf(`{
admin localhost:2999
order defender after header
servers {
trusted_proxies static 127.0.0.1/32 ::1/128
client_ip_headers X-Forwarded-For
}
}

http://localhost:9080 {
log defender_blocked {
output net %q {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Simple way to log caddy defender blocked requests?

2 participants