mirror of
https://github.com/thisisjaymehta/maddy.git
synced 2026-04-08 21:07:58 +00:00
[PR #1] [CLOSED] Add per-response-code DNSBL scoring with custom messages #1
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
thisisjaymehta/maddy#1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/thisisjaymehta/maddy/pull/1
Author: @Copilot
Created: 1/10/2026
Status: ❌ Closed
Base:
master← Head:copilot/improve-dnsbl-response-handling📝 Commits (8)
c39c921Initial planb66f114Implement per-response-code DNSBL scoring with custom messages3404ef6Fix config parsing to use node.Children instead of AllowUnknownfe91076Fix rule matching to count each rule only once11be667Improve documentation with clearer scoring behavior examples66339ddAddress upstream PR feedback: use cfg.Callback, extract function, remove version annotationc29208cAdd ResponseRules support for checkDomain (domain-based lookups)0d68e63Formatted files with goimports📊 Changes
5 files changed (+667 additions, -42 deletions)
View changed files
📝
docs/reference/checks/dnsbl.md(+85 -0)📝
internal/check/dnsbl/common.go(+122 -39)📝
internal/check/dnsbl/common_test.go(+101 -0)📝
internal/check/dnsbl/dnsbl.go(+80 -3)📝
internal/check/dnsbl/dnsbl_test.go(+279 -0)📄 Description
Implementation Plan for Per-Response-Code DNSBL Scoring
ListedErrstruct incommon.goto includeScoreandMessagefieldsResponseRulestruct todnsbl.goListstruct indnsbl.goto includeResponseRulesfieldcheckIPfunction incommon.goto handleResponseRulesand calculate scorescheckDomainfunction incommon.goto handleResponseRulesfor domain-based lookupsparseResponseRulefunction to parseresponseconfiguration blocksreadListCfgindnsbl.goto parseresponseblocks usingparseResponseRulecheckListsindnsbl.goto use score fromListedErrinstead of flatlist.ScoreAdjListedErr.Fields()method to use custom message when availabledocs/reference/checks/dnsbl.mdChanges Made
This PR adds support for per-response-code scoring in DNSBL checks, allowing administrators to assign different scores and custom rejection messages based on specific DNSBL return codes. This enables efficient use of combined DNSBLs like Spamhaus ZEN with granular control.
Key Features
responses+scoreconfiguration continues to workImplementation Details
cfg.Callbackfor response blocks - Uses the callback pattern for complex config parsing (preferred pattern in Maddy)matchResponseRulesfunction shared by bothcheckIPandcheckDomainfor consistencyresponseblocks andresponsesdirective are specifiedConfiguration Example
All tests pass and code follows Maddy conventions.
Original prompt
Problem
Currently, Maddy's DNSBL implementation treats all response codes within a configured range equally. When using combined DNSBLs like Spamhaus ZEN (
zen.spamhaus.org), different return codes indicate different listing types with different severity:127.0.0.2,127.0.0.3→ SBL (known spam sources) - high severity127.0.0.4-127.0.0.7→ XBL (exploited/compromised hosts) - high severity127.0.0.10,127.0.0.11→ PBL (policy block, dynamic IPs) - lower severityCurrently, Maddy:
127.0.0.1/24as a single "hit"127.0.0.3,127.0.0.11,127.0.0.4), they all count as one hit with one scoreThis means users who want different scores for different listing types must query separate lists (sbl.spamhaus.org, xbl.spamhaus.org, pbl.spamhaus.org), resulting in 3 DNS queries instead of 1.
Reference: https://docs.spamhaus.com/datasets/docs/source/40-real-world-usage/PublicMirrors/MTAs/020-Postfix.html
Proposed Solution
Add a new
responseconfiguration block that allows per-response-code scoring and custom messages:Implementation Details
1. Add new
ResponseRulestruct ininternal/check/dnsbl/dnsbl.go:2. Update
Liststruct to includeResponseRules:3. Update
ListedErrininternal/check/dnsbl/common.goto include score and message:4. Update
checkIPfunction ininternal/check/dnsbl/common.goto handle ResponseRules:ResponseRulesis configured, match each returned IP against rules and sum scoresResponsesis configured, use existing behavior for backwards compatibilityListedErrwith the total score from all matched response rules5. Update
checkListsininternal/check/dnsbl/dnsbl.goto use score fromListedErr:ListedErr.Scorewhen set (new behavior)list.ScoreAdjfor backwards compatibility6. Update
readListCfgininternal/check/dnsbl/dnsbl.goto parse newresponseblocks:parseResponseRulefunction to handle theresponseblockscoreandmessagedirectives from the block body7. Update
Fields()method onListedErrto use custom message if available8. Update documentation in
docs/reference/checks/dnsbl.mdto document the newresponseblock syntaxFiles to Modify
internal/check/dnsbl/dnsbl.go- Add ResponseRule struct, update List struct, update readListCfg, update checkListsinternal/check/dnsbl/common.go- Update ListedErr, update checkIP to handle ResponseRulesinternal/check/dnsbl/dnsbl_test.go- Add test cases for new functionalitydocs/reference/checks/dnsbl.md- Document new configuration syntaxTest Cases to Add
responseblocks → existing behavior preservedresponseblocks, some without) → both work correctlyBenefits
This pull request was created from Copilot chat.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.