Yes, SpamAssassin can perform DNSBL lookups against IP addresses taken from a message's Received: headers, not just the host that connected directly to your MX. However, whether a specific SpamHaus listing on the original client actually produces a score hit depends on which rules are enabled, which zone they query, and how your trusted_networks configuration classifies the relays in the message path.
Why postscreen missed it
postscreen only sees the SMTP peer — the server that opened the connection to your MX. If a listed client hands its mail to an unlisted relay, and that relay connects to you, postscreen evaluates the relay's address, not the client's. The client's address survives only inside the Received: headers the relay appended, which is territory where SpamAssassin picks up the slack.
How SpamAssassin picks which IP to test
SpamAssassin walks the received header chain and, for each DNSBL rule, selects which addresses to query. The upstream rules distinguish two behaviours:
RCVD_IN_SBLandRCVD_IN_SBL_CSSquery the combinedzenzone without restricting the lookup to the last external hop, so an untrusted intermediate relay's listed address can trigger them.RCVD_IN_XBLandRCVD_IN_PBLqueryzen-lastexternal, meaning only the external host that actually connected to your network is tested. A client listed in XBL two hops upstream will not match these rules, because the last external hop was the clean relay.
This explains the scenario exactly: an XBL hit on the originating client alone does not fire the last-external rules when a clean intermediary delivered the mail, while SBL/CSS listings can still register through the broader rules — provided the client's address appears in the parsed header chain. Also remember that rules shipped in 20_dnsbl_tests.cf are frequently updated; verify what is actually installed on your system rather than assuming upstream defaults.
Diagnosing a missed message
Take the complete original message with all headers and rescan it with debugging enabled, using the same configuration and user preferences your filtering service runs with:
spamassassin --lint
spamassassin -t -D < original.eml > checked.eml 2> sa-debug.log
Do not pass -L, which disables all network tests including DNSBL queries. In the debug output, check which relay IPs were extracted and queried, whether DNS responses came back at all, and which rules scored. Keep in mind that a rescan reflects today's DNSBL state, not what was listed when the message originally arrived.
Configuration checklist
- Confirm network checks are active:
skip_rbl_checks 0. - Ensure the relevant rules carry nonzero scores in your local configuration.
- Define
trusted_networksto cover only relays you genuinely operate. This is what tells SpamAssassin which addresses count as untrusted and worth checking. Do not add arbitrary outside relays just to steer which address gets tested. - Consider that DNSBL lookups require working DNS resolution from the filter host; a resolver timeout or rate limit from the DNSBL provider silently produces no hits.
Limits of header-based lookups
Two caveats deserve emphasis. First, Received: headers added by the sending side are supplied by parties you do not control, so an upstream address is not proof of the original client's identity — a hostile relay can claim any origin. Second, checking residential client IPs can backfire: legitimate mail from home users is relayed through their provider after SMTP authentication, and those residential ranges belong in SpamHaus's policy blocklist, which is designed for addresses that should never send mail directly. Scoring earlier-hop IPs too aggressively risks penalising normal client-relayed mail.
Finally, a DNSBL hit raises the message's SpamAssassin score; the separate decision to reject, quarantine, or tag happens in your MTA or filtering integration, so review those thresholds as well.
Frequently Asked Questions
Does SpamAssassin only check the connecting IP against DNSBLs?
No. It extracts addresses from the received header chain and queries the ones classified as untrusted, with some rules restricted to the last external relay and others covering the whole chain.
Why did an XBL-listed client not trigger a hit?
The XBL rules use a last-external variant of the zen zone, so only the host that connected to your network is tested. If a clean relay delivered the mail, the earlier client's listing does not match those specific rules.
Can I trust the client IP shown in Received headers?
Not fully. Headers added before the message reached a server you trust are supplied by the sending side and can be forged, so they are useful signals but not proof of origin.
How do I see which IPs SpamAssassin actually queried?
Run the message through spamassassin -t -D and inspect the debug log for parsed relay addresses, DNS queries and replies, and resulting rule hits.
Should I reject mail outright on any SpamHaus hit?
That is a policy decision. DNSBL results feed SpamAssassin's score; whether a score leads to rejection, quarantine, or delivery is configured separately in your mail-filter integration. Weigh the risk of false positives, especially for residential ranges on the policy blocklist.