Rspamd DBL checks disabled because of the use of an open DNS?

Hi,

Recently I noticed that more and more spam, especially phishing, weren’t detected by Rspamd anymore. Looking at the headers, I noticed that DBL_BLOCKED_OPENRESOLVER with score 0.00 was often reported, which implies that no DBL / URIBL URL reputation scoring is applied, even for clearly malicious or newly registered domains.

The root cause seems to be that Rspamd performs DBL lookups via the system DNS resolver, in my case the one provided by Hetzner. However, Spamhaus explicitly blocks DBL queries coming from shared resolvers or resolvers classified as open / non-compliant, hence the DBL_BLOCKED_OPENRESOLVER flag.

Additionally I can see this kind of line in the logs :

2025-12-16T11:23:51+01:00 [6:mail4:rspamd] (controller) <c9hxbz>; monitored; rspamd_monitored_dns_cb: DNS reply returned 'no error' for zen.spamhaus.org while 'no records with this name' was expected when querying for '1.0.0.127.zen.spamhaus.org'(likely DNS spoofing or BL internal issues)

It looks like the best practice is to provide a local recursive resolver (e.g. Unbound) to “proxy” the request.

Since that issue could potentially affect a lot of people I would like to have your insights about this issue. What do you think ?

Cheers !

Matthieu

1 Like

I don’t have that issue using Contabo and their DNS servers. Does it help to change the DNS servers?

It seems unbound is already used, see Code search results · GitHub

EDIT:

Maybe related:

1 Like

Spamhaus offers a data query service DQS (free for non-commercial use) that also works through public DNS resolvers. It however requires some configuration.

Did someone already try this on Nethserver, and is it working?

2 Likes

I’m trying Spamhaus DQS and going to report if it works.

Here are the changes I made, adapted from the Spamhaus docs:

Enter mail environment: (in this example mail1, adapt to your mail instance)

runagent -m mail1

Create or edit an override file:

podman exec -ti postfix vi /etc/postfix/main.cf.d/myoverride.cf

Add following content: (Replace MY_DQS_KEY with your DQS key that you can create after logging in to Spamhaus and my.mailserver.hostname with your mail server hostname)

rbl_reply_maps = lmdb:$config_directory/main.cf.d/dnsbl-reply-map
smtpd_recipient_restrictions =
  reject_rbl_client MY_DQS_KEY.zen.dq.spamhaus.net=127.0.0.[2..11],
  reject_rhsbl_sender MY_DQS_KEY.dbl.dq.spamhaus.net=127.0.1.[2..99],
  reject_rhsbl_helo MY_DQS_KEY.dbl.dq.spamhaus.net=127.0.1.[2..99],
  reject_rhsbl_reverse_client MY_DQS_KEY.dbl.dq.spamhaus.net=127.0.1.[2..99],
  reject_rhsbl_sender MY_DQS_KEY.zrd.dq.spamhaus.net=127.0.2.[2..24],
  reject_rhsbl_helo MY_DQS_KEY.zrd.dq.spamhaus.net=127.0.2.[2..24],
  reject_rhsbl_reverse_client MY_DQS_KEY.zrd.dq.spamhaus.net=127.0.2.[2..24],
  reject_non_fqdn_recipient,
  check_recipient_access inline:{{ my.mailsever.hostname.localhost = reject_unverified_recipient }},

Create the file dnsbl-reply-map in/etc/postfix/main.cf.d to include it in backup…

podman exec -ti postfix vi /etc/postfix/main.cf.d/dnsbl-reply-map

..with following content: (adapt “your_DQS_key” correctly)

your_DQS_key.zen.dq.spamhaus.net=127.0.0.[2..11]	554 $rbl_class $rbl_what blocked using ZEN - see https://www.spamhaus.org/query/ip/$client_address for details
your_DQS_key.dbl.dq.spamhaus.net=127.0.1.[2..99]	554 $rbl_class $rbl_what blocked using DBL - see $rbl_txt for details
your_DQS_key.zrd.dq.spamhaus.net=127.0.2.[2..24]	554 $rbl_class $rbl_what blocked using ZRD - domain too young
your_DQS_key.zen.dq.spamhaus.net			554 $rbl_class $rbl_what blocked using ZEN - see https://www.spamhaus.org/query/ip/$client_address for details
your_DQS_key.dbl.dq.spamhaus.net			554 $rbl_class $rbl_what blocked using DBL - see $rbl_txt for details
your_DQS_key.zrd.dq.spamhaus.net			554 $rbl_class $rbl_what blocked using ZRD - domain too young

Run postmap to create lmdb file:

podman exec postfix postmap /etc/postfix/main.cf.d/dnsbl-reply-map

Apply changes by restarting postfix:

systemctl --user restart postfix

Please check the logs if postfix is working and if something went wrong, just rename the override file:

podman exec -ti postfix mv /etc/postfix/main.cf.d/myoverride.cf /etc/postfix/main.cf.d/myoverride.cf.old

EDIT:

There’s an online blocklist tester from Spamhaus and I found that for blocking content via DQS a plugin for Rspamd could be installed, see also GitHub - spamhaus/rspamd-dqs: Spamhaus code for RSPAMD Plugin. See https://docs.spamhaustech.com/40-real-world-usage/Rspamd/000-intro.html for instructions

WARNING! The following didn’t work for me, the content test mails that shouldn’t be delivered were still delivered so it’s still a work in progress…don’t use it in production.

Additionally the following changes don’t survive a restart of rspamd.
It should work using the persistent rspamd volume, see also GitHub - NethServer/ns8-mail: NS8 Mail module with SMTP, IMAP, Spam/Virus filter
I’m going to test it asap…

Install git as root on the host system:

dnf install git

(For Debian systems use apt install git)

Clone the plugin config:

git clone https://github.com/spamhaus/rspamd-dqs

Go to plugin directory:

cd rspamd-dqs/3.x

Add your DQS key: (Replace “your_DQS_key”)

sed -i -e 's/your_DQS_key/aip7yig6sahg6ehsohn5shco3z/g' *.conf

This howto just covers the free key without HBL. If you have a Spamhaus subscription please refer to the documentation.

Copy the needed files to the mail1 environment (adapt mail1 to your mail app instance name)

cp rbl.conf rbl_group.conf /home/mail1/.config/state/
chown mail1: /home/mail1/.config/state/rbl*

Enter mail1 environment:

runagent -m mail1

Copy files to rspamd container:

podman cp rbl.conf rspamd:/etc/rspamd/local.d/
podman cp rbl_group.conf rspamd:/etc/rspamd/local.d/

Check Rspamd config syntax:

podman exec rspamd rspamadm configtest

Reload rspamd:

systemctl --user reload rspamd
1 Like

Thanks ! Trying this right now.

Why did you add those two lines, not present in DQS manual ?

1 Like

It worked for me to block most mails but the content tests failed, see previous post.

Because those lines are in the default NethServer configuration and would get overruled by the myoverride.cf file and therefore not applied.

To check the NethServer default config:

runagent -m mail1 podman exec -ti postfix postconf -n

See also GitHub - NethServer/ns8-mail: NS8 Mail module with SMTP, IMAP, Spam/Virus filter

EDIT:

Maybe just changing the DNS server instead of using DQS would be a simpler approach…

Indeed, same problem here.

However I think we’re on the right track with DQS since most if not all public DNS are being blacklisted by spamhaus :

NOTE: Other free/open DNS resolvers include Alternate DNS, Comodo Secure, DNS.Watch, DynDNS, FreeDNS, Hurricane, NeuStar DNS Advantage, Norton ConnectSafe, OpenNIC, OVH, Puncat, Quad9, SafeDNS, Uncensored, Verisign, Yandex.DNS, or large cloud/outsourced public DNS servers, such as the ones operated by Level3, Verizon or AT&T. There are many more; this is NOT a complete list.

FAQs | How you can use the free Spamhaus Blocklists

I’m surprised that nobody discovered this before, since it’s been in application for almost a year now.

Will investigate further tomorrow :slight_smile:

1 Like

NB : this thread was started because a customer complained for some weeks about increasing SPAMs in their inboxes. That’s a real world issue :slight_smile:

1 Like

Yes, the system DNS configuration is not used for DNSBL queries. Unbound handles DNSBL queries since NS7. A networking issue may prevent it from working properly. For example, you may check the mail log for name resolution errors.

Then check if your VPS has IPv6 disabled or not. Sometimes cloud providers enable IPv6 but it DNS resolution does not work over it.

sysctl net.ipv6.conf.all.disable_ipv6

Unbound query check command:

runagent -m mail1 podman exec rspamd unbound-host -dd -v www.example.org

Please attach the full output.

Can you attach the full flag list?

2 Likes

Indeed ipv6 is enabled and functional on this node. An I confirm that a similar config works in NS7 (even if there are some DNS errors too).

[root@mail ~]# runagent -m mail4 podman exec rspamd unbound-host -dd -v www.example.org
[1765967965] libunbound[2555:0] debug: switching log to stderr
[1765967965] libunbound[2555:0] debug: module config: "subnetcache validator iterator"
[1765967965] libunbound[2555:0] notice: init module 0: subnetcache
[1765967965] libunbound[2555:0] debug: subnetcache: option registered (8)
[1765967965] libunbound[2555:0] notice: init module 1: validator
[1765967965] libunbound[2555:0] notice: init module 2: iterator
[1765967965] libunbound[2555:0] debug: target fetch policy for level 0 is 0
[1765967965] libunbound[2555:0] debug: target fetch policy for level 1 is 0
[1765967965] libunbound[2555:0] debug: target fetch policy for level 2 is 0
[1765967965] libunbound[2555:0] debug: target fetch policy for level 3 is 0
[1765967965] libunbound[2555:0] debug: target fetch policy for level 4 is 0
[1765967965] libunbound[2555:0] debug: subnetcache[module 0] operate: extstate:module_state_initial event:module_event_new
[1765967965] libunbound[2555:0] info: subnetcache operate: query www.example.org. A IN
[1765967965] libunbound[2555:0] debug: validator[module 1] operate: extstate:module_state_initial event:module_event_pass
[1765967965] libunbound[2555:0] info: validator operate: query www.example.org. A IN
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_state_initial event:module_event_pass
[1765967965] libunbound[2555:0] info: resolving www.example.org. A IN
[1765967965] libunbound[2555:0] info: priming . IN NS
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_state_initial event:module_event_pass
[1765967965] libunbound[2555:0] info: iterator operate: query . NS IN
[1765967965] libunbound[2555:0] info: processQueryTargets: . NS IN
[1765967965] libunbound[2555:0] info: sending query: . NS IN
[1765967965] libunbound[2555:0] debug: sending to target: <.> 198.97.190.53#53
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1765967965] libunbound[2555:0] info: iterator operate: query . NS IN
[1765967965] libunbound[2555:0] info: response for . NS IN
[1765967965] libunbound[2555:0] info: reply from <.> 198.97.190.53#53
[1765967965] libunbound[2555:0] info: query response was ANSWER
[1765967965] libunbound[2555:0] debug: validator[module 1] operate: extstate:module_state_initial event:module_event_moddone
[1765967965] libunbound[2555:0] info: validator operate: query . NS IN
[1765967965] libunbound[2555:0] debug: subnetcache[module 0] operate: extstate:module_state_initial event:module_event_moddone
[1765967965] libunbound[2555:0] info: subnetcache operate: query . NS IN
[1765967965] libunbound[2555:0] info: priming successful for . NS IN
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_subquery event:module_event_pass
[1765967965] libunbound[2555:0] info: iterator operate: query www.example.org. A IN
[1765967965] libunbound[2555:0] info: resolving (init part 2):  www.example.org. A IN
[1765967965] libunbound[2555:0] info: resolving (init part 3):  www.example.org. A IN
[1765967965] libunbound[2555:0] info: processQueryTargets: www.example.org. A IN
[1765967965] libunbound[2555:0] debug: removing 2 labels
[1765967965] libunbound[2555:0] info: sending query: org. A IN
[1765967965] libunbound[2555:0] debug: sending to target: <.> 2001:dc3::35#53
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1765967965] libunbound[2555:0] info: iterator operate: query www.example.org. A IN
[1765967965] libunbound[2555:0] info: response for www.example.org. A IN
[1765967965] libunbound[2555:0] info: reply from <.> 2001:dc3::35#53
[1765967965] libunbound[2555:0] info: query response was REFERRAL
[1765967965] libunbound[2555:0] info: processQueryTargets: www.example.org. A IN
[1765967965] libunbound[2555:0] debug: removing 1 labels
[1765967965] libunbound[2555:0] info: sending query: example.org. A IN
[1765967965] libunbound[2555:0] debug: sending to target: <org.> 199.249.120.1#53
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1765967965] libunbound[2555:0] info: iterator operate: query www.example.org. A IN
[1765967965] libunbound[2555:0] info: response for www.example.org. A IN
[1765967965] libunbound[2555:0] info: reply from <org.> 199.249.120.1#53
[1765967965] libunbound[2555:0] info: query response was REFERRAL
[1765967965] libunbound[2555:0] info: processQueryTargets: www.example.org. A IN
[1765967965] libunbound[2555:0] info: new target mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: new target mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_state_initial event:module_event_pass
[1765967965] libunbound[2555:0] info: iterator operate: query mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: resolving mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: resolving (init part 2):  mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: resolving (init part 3):  mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: processQueryTargets: mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] debug: removing 3 labels
[1765967965] libunbound[2555:0] info: sending query: com. A IN
[1765967965] libunbound[2555:0] debug: sending to target: <.> 2001:500:2d::d#53
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_state_initial event:module_event_pass
[1765967965] libunbound[2555:0] info: iterator operate: query mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] info: resolving mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] info: resolving (init part 2):  mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] info: resolving (init part 3):  mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] info: processQueryTargets: mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] debug: removing 3 labels
[1765967965] libunbound[2555:0] info: sending query: com. A IN
[1765967965] libunbound[2555:0] debug: sending to target: <.> 2001:500:a8::e#53
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1765967965] libunbound[2555:0] info: iterator operate: query mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] info: response for mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] info: reply from <.> 2001:500:a8::e#53
[1765967965] libunbound[2555:0] info: query response was REFERRAL
[1765967965] libunbound[2555:0] info: processQueryTargets: mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] debug: removing 2 labels
[1765967965] libunbound[2555:0] info: sending query: cloudflare.com. A IN
[1765967965] libunbound[2555:0] debug: sending to target: <com.> 192.12.94.30#53
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1765967965] libunbound[2555:0] info: iterator operate: query mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: response for mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: reply from <.> 2001:500:2d::d#53
[1765967965] libunbound[2555:0] info: query response was REFERRAL
[1765967965] libunbound[2555:0] info: processQueryTargets: mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] debug: removing 2 labels
[1765967965] libunbound[2555:0] info: sending query: cloudflare.com. A IN
[1765967965] libunbound[2555:0] debug: sending to target: <com.> 2001:502:1ca1::30#53
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1765967965] libunbound[2555:0] info: iterator operate: query mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] info: response for mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] info: reply from <com.> 192.12.94.30#53
[1765967965] libunbound[2555:0] info: query response was REFERRAL
[1765967965] libunbound[2555:0] info: processQueryTargets: mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] debug: removing 1 labels
[1765967965] libunbound[2555:0] info: sending query: ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] debug: sending to target: <cloudflare.com.> 162.159.7.226#53
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1765967965] libunbound[2555:0] info: iterator operate: query mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: response for mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: reply from <com.> 2001:502:1ca1::30#53
[1765967965] libunbound[2555:0] info: query response was REFERRAL
[1765967965] libunbound[2555:0] info: processQueryTargets: mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] debug: removing 1 labels
[1765967965] libunbound[2555:0] info: sending query: ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] debug: sending to target: <cloudflare.com.> 162.159.4.8#53
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1765967965] libunbound[2555:0] info: iterator operate: query mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: response for mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: reply from <cloudflare.com.> 162.159.4.8#53
[1765967965] libunbound[2555:0] info: query response was ANSWER
[1765967965] libunbound[2555:0] info: processQueryTargets: mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: sending query: mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] debug: sending to target: <cloudflare.com.> 162.159.1.33#53
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1765967965] libunbound[2555:0] info: iterator operate: query mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] info: response for mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] info: reply from <cloudflare.com.> 162.159.7.226#53
[1765967965] libunbound[2555:0] info: query response was ANSWER
[1765967965] libunbound[2555:0] info: processQueryTargets: mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] info: sending query: mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] debug: sending to target: <cloudflare.com.> 2400:cb00:2049:1::a29f:21#53
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1765967965] libunbound[2555:0] info: iterator operate: query mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: response for mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: reply from <cloudflare.com.> 162.159.1.33#53
[1765967965] libunbound[2555:0] info: query response was ANSWER
[1765967965] libunbound[2555:0] info: processQueryTargets: mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: sending query: mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] debug: sending to target: <cloudflare.com.> 2400:cb00:2049:1::a29f:606#53

[1765967965] libunbound[2555:0] info: response for mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] info: reply from <cloudflare.com.> 2400:cb00:2049:1::a29f:21#53
[1765967965] libunbound[2555:0] info: query response was ANSWER
[1765967965] libunbound[2555:0] info: finishing processing for mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] debug: validator[module 1] operate: extstate:module_state_initial event:module_event_moddone
[1765967965] libunbound[2555:0] info: validator operate: query mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] debug: subnetcache[module 0] operate: extstate:module_state_initial event:module_event_moddone
[1765967965] libunbound[2555:0] info: subnetcache operate: query mitch.ns.cloudflare.com. A IN
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_subquery event:module_event_pass
[1765967965] libunbound[2555:0] info: iterator operate: query www.example.org. A IN
[1765967965] libunbound[2555:0] info: processQueryTargets: www.example.org. A IN
[1765967965] libunbound[2555:0] info: sending query: www.example.org. A IN
[1765967965] libunbound[2555:0] debug: sending to target: <example.org.> 172.64.33.208#53

[1765967965] libunbound[2555:0] info: iterator operate: query mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: response for mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] info: reply from <cloudflare.com.> 2400:cb00:2049:1::a29f:606#53
[1765967965] libunbound[2555:0] info: query response was ANSWER
[1765967965] libunbound[2555:0] info: finishing processing for mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] debug: validator[module 1] operate: extstate:module_state_initial event:module_event_moddone
[1765967965] libunbound[2555:0] info: validator operate: query mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] debug: subnetcache[module 0] operate: extstate:module_state_initial event:module_event_moddone
[1765967965] libunbound[2555:0] info: subnetcache operate: query mitch.ns.cloudflare.com. AAAA IN
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_pass
[1765967965] libunbound[2555:0] info: iterator operate: query www.example.org. A IN
[1765967965] libunbound[2555:0] info: processQueryTargets: www.example.org. A IN
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1765967965] libunbound[2555:0] info: iterator operate: query www.example.org. A IN
[1765967965] libunbound[2555:0] info: response for www.example.org. A IN
[1765967965] libunbound[2555:0] info: reply from <example.org.> 172.64.33.208#53
[1765967965] libunbound[2555:0] info: query response was ANSWER
[1765967965] libunbound[2555:0] info: finishing processing for www.example.org. A IN
[1765967965] libunbound[2555:0] debug: validator[module 1] operate: extstate:module_wait_module event:module_event_moddone
[1765967965] libunbound[2555:0] info: validator operate: query www.example.org. A IN
[1765967965] libunbound[2555:0] debug: subnetcache[module 0] operate: extstate:module_wait_module event:module_event_moddone
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_pass
[1765967965] libunbound[2555:0] info: iterator operate: query www.example.org. A IN
[1765967965] libunbound[2555:0] info: processQueryTargets: www.example.org. A IN
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1765967965] libunbound[2555:0] info: iterator operate: query www.example.org. A IN
[1765967965] libunbound[2555:0] info: response for www.example.org. A IN
[1765967965] libunbound[2555:0] info: reply from <example.org.> 172.64.33.208#53
[1765967965] libunbound[2555:0] info: query response was ANSWER
[1765967965] libunbound[2555:0] info: finishing processing for www.example.org. A IN
[1765967965] libunbound[2555:0] debug: validator[module 1] operate: extstate:module_wait_module event:module_event_moddone
[1765967965] libunbound[2555:0] info: validator operate: query www.example.org. A IN
[1765967965] libunbound[2555:0] debug: subnetcache[module 0] operate: extstate:module_wait_module event:module_event_moddone
[1765967965] libunbound[2555:0] info: subnetcache operate: query www.example.org. A IN
www.example.org has address 104.20.26.109 (insecure)
[1765967965] libunbound[2555:0] debug: subnetcache[module 0] operate: extstate:module_state_initial event:module_event_new
[1765967965] libunbound[2555:0] info: subnetcache operate: query www.example.org. AAAA IN
[1765967965] libunbound[2555:0] debug: validator[module 1] operate: extstate:module_state_initial event:module_event_pass
[1765967965] libunbound[2555:0] info: validator operate: query www.example.org. AAAA IN
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_state_initial event:module_event_pass
[1765967965] libunbound[2555:0] info: resolving www.example.org. AAAA IN
[1765967965] libunbound[2555:0] info: resolving (init part 2):  www.example.org. AAAA IN
[1765967965] libunbound[2555:0] info: resolving (init part 3):  www.example.org. AAAA IN
[1765967965] libunbound[2555:0] info: processQueryTargets: www.example.org. AAAA IN
[1765967965] libunbound[2555:0] info: processQueryTargets: www.example.org. AAAA IN
[1765967965] libunbound[2555:0] info: sending query: www.example.org. AAAA IN
[1765967965] libunbound[2555:0] debug: sending to target: <example.org.> 173.245.59.208#53
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1765967965] libunbound[2555:0] info: iterator operate: query www.example.org. AAAA IN
[1765967965] libunbound[2555:0] info: response for www.example.org. AAAA IN
[1765967965] libunbound[2555:0] info: reply from <example.org.> 173.245.59.208#53
[1765967965] libunbound[2555:0] info: query response was ANSWER
[1765967965] libunbound[2555:0] info: finishing processing for www.example.org. AAAA IN
[1765967965] libunbound[2555:0] debug: validator[module 1] operate: extstate:module_wait_module event:module_event_moddone
[1765967965] libunbound[2555:0] info: validator operate: query www.example.org. AAAA IN
[1765967965] libunbound[2555:0] debug: subnetcache[module 0] operate: extstate:module_wait_module event:module_event_moddone
[1765967965] libunbound[2555:0] info: subnetcache operate: query www.example.org. AAAA IN
[1765967965] libunbound[2555:0] debug: subnetcache[module 0] operate: extstate:module_state_initial event:module_event_new
[1765967965] libunbound[2555:0] info: subnetcache operate: query www.example.org. MX IN
[1765967965] libunbound[2555:0] debug: validator[module 1] operate: extstate:module_state_initial event:module_event_pass
[1765967965] libunbound[2555:0] info: validator operate: query www.example.org. MX IN
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_state_initial event:module_event_pass
[1765967965] libunbound[2555:0] info: resolving www.example.org. MX IN
[1765967965] libunbound[2555:0] info: resolving (init part 2):  www.example.org. MX IN
[1765967965] libunbound[2555:0] info: resolving (init part 3):  www.example.org. MX IN
[1765967965] libunbound[2555:0] info: processQueryTargets: www.example.org. MX IN
[1765967965] libunbound[2555:0] info: processQueryTargets: www.example.org. MX IN
[1765967965] libunbound[2555:0] info: sending query: www.example.org. MX IN
[1765967965] libunbound[2555:0] debug: sending to target: <example.org.> 2803:f800:50::6ca2:c1d0#53
[1765967965] libunbound[2555:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1765967965] libunbound[2555:0] info: iterator operate: query www.example.org. MX IN
[1765967965] libunbound[2555:0] info: response for www.example.org. MX IN
[1765967965] libunbound[2555:0] info: reply from <example.org.> 2803:f800:50::6ca2:c1d0#53
[1765967965] libunbound[2555:0] info: query response was nodata ANSWER
[1765967965] libunbound[2555:0] info: finishing processing for www.example.org. MX IN
[1765967965] libunbound[2555:0] debug: validator[module 1] operate: extstate:module_wait_module event:module_event_moddone
[1765967965] libunbound[2555:0] info: validator operate: query www.example.org. MX IN
[1765967965] libunbound[2555:0] debug: subnetcache[module 0] operate: extstate:module_wait_module event:module_event_moddone
[1765967965] libunbound[2555:0] info: subnetcache operate: query www.example.org. MX IN
www.example.org has address 172.66.157.88 (insecure)
www.example.org has IPv6 address 2606:4700:10::ac42:9d58 (insecure)
www.example.org has IPv6 address 2606:4700:10::6814:1a6d (insecure)
www.example.org has no mail handler record (insecure)

Can you attach the full flag list?

Sure, here are the headers.

X-Fbl : 1_27_756_0_66726564657269632E666F75726E6573406C6562726173732E6265
Auto-Submitted : auto-generated
List-Unsubscribe : <mailto:unsubscribe@vetreriaeugubina.com>
X-Rspamd-Queue-Id : 4265B1302203
X-Rspamd-Server : mail
X-Beenthere : abuse@vetreriaeugubina.com
List-Owner : <mailto:owner@vetreriaeugubina.com>
Return-Path : <contact@vetreriaeugubina.com>
X-Originating-Ip : [127.0.0.1]
X-Rspamd-Flag-Threshold : 6
X-Auto-Response-Suppress : All
Mime-Version : 1.0
X-Dce : true
X-Rspamd-Action : no action
X-Campaign : DON
Precedence : bulk
<NZIXMDU.MTA5NZA2MA.75605612161808202528975287204@vetreriaeugubina.com>
Dkim-Signature : v=1; a=rsa-sha256; c=relaxed/relaxed; s=out-vmta; d=vetreriaeugubina.com; h=Content-Type:Mime-Version:Date:Subject:From:List-Unsubscribe:List-Id: List-Owner:Message-ID:To; bh=sWH2nKebUeRsvwJ+uLdNz4iSqTEriPngkVRF39GK4a4=; b=F97+HxY12xr6eLjzC4RR7XrhiIhJW3F+jP8SkIuSV9ZbdwoscXByOUoIHJLDRrl6UciXu4+9aZti ZEWcNV9DixILXmmUCrXMsJ6zAe8zLSrpevV+dQT3pSFXQiwWdZrCWSTrPPccEdcWk6SQ25boy4jU q8Mvlwxd1QCFZNHf9FI=
List-Id : "Newsletter" <newsletter.vetreriaeugubina.com>
X-Spamd-Result : default: False [3.73 / 20.00]; R_MIXED_CHARSET(1.76)[]; ZERO_FONT(1.00)[195]; MANY_INVISIBLE_PARTS(1.00)[10]; DMARC_POLICY_ALLOW(-0.50)[vetreriaeugubina.com,reject]; MV_CASE(0.50)[]; MX_INVALID(0.50)[]; R_DKIM_ALLOW(-0.20)[vetreriaeugubina.com:s=out-vmta]; R_SPF_ALLOW(-0.20)[+a:vetreriaeugubina.com:c]; MAILLIST(-0.13)[generic]; ONCE_RECEIVED(0.10)[]; MIME_GOOD(-0.10)[multipart/alternative,text/plain]; HAS_LIST_UNSUB(-0.01)[]; SUSPICIOUS_AUTH_ORIGIN(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; TO_DN_ALL(0.00)[]; RCPT_COUNT_ONE(0.00)[1]; ARC_NA(0.00)[]; DKIM_TRACE(0.00)[vetreriaeugubina.com:+]; FROM_HAS_DN(0.00)[]; ASN(0.00)[asn:49981, ipnet:185.100.232.0/22, country:NL]; HAS_XOIP(0.00)[]; PRECEDENCE_BULK(0.00)[]; FROM_EQ_ENVFROM(0.00)[]; MISSING_XM_UA(0.00)[]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_COUNT_ZERO(0.00)[0]; NEURAL_HAM(0.00)[-0.999]; MIME_TRACE(0.00)[0:+,1:+,2:~]; DBL_BLOCKED_OPENRESOLVER(0.00)[ecoledespatrons.com:url,vetreriaeugubina.com:mid,vetreriaeugubina.com:dkim,vetreriaeugubina.com:helo,vetreriaeugubina.com:rdns]
Importance : High
Content-Type : multipart/alternative; boundary="------------000501050203040005080002"
Delivered-To : mycustomer@domain.ltd.localhost
Received : from mail.omain.ltdby mail.your-server.de with LMTP id GGfFMxKSQWm2MwgACApylw (envelope-from <contact@vetreriaeugubina.com>) for <mycustomer@domain.ltd.localhost>; Tue, 16 Dec 2025 17:08:34 +0000
Received : from vetreriaeugubina.com (vetreriaeugubina.com [185.100.233.16]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mail.omain.ltd(Postfix) with ESMTPS id 4265B1302203 for <mycustomer@domain.ltd>; Tue, 16 Dec 2025 17:08:34 +0000 (UTC)
1 Like

Referring to the mentioned “Spamhaus DNS Blocklists Fair Use Policy” your server should fall into this category, unless more Hetzner-specific policies apply…

A private DNS server with a correct, attributable host name can also be used.

… because Unbound does not forward queries to other resolvers, it queries authoritative DNS servers directly.

The fair use policy states that users cannot query via DNS resolvers where there is no attributable reverse DNS

Just to be sure, is a PTR record registered for the server IP? – Mail — NS8 documentation

1 Like

Definitively, ipv6 and v4

Nice ! Hetzner looks like a particular problem Email Security | Query our DNSBLs via Hetzner's infrastructure? Move to free Data Query Service | Resources but does it apply since unbound looks like it works as expected ? :thinking:

Should I try another DNS provider ?

Did you try https://blt.spamhaus.com/ ? Plugins, and special config apart, their tester could provide more insights about how they see requests coming from your server.

:slight_smile: …Or another VPS provider? Jokes apart, since public DNS servers shouldn’t be involved, I don’t think it helps. But I can be wrong!

Without DQS (as per @mrmarkuz ‘s first instructions), the SMTP (connection) test and Content test are failing - all their junk emails are passing the filter.

SMTP test :

  • Their logs :
C: <Establish TCP connection>
S: 220-mail.redacted.be ESMTP Postfix
S: 220 mail.redacted.be ESMTP Postfix
C: EHLO pbl-pub.blt.spamhaus.net
S: 250-mail.redacted.be
S: 250-PIPELINING
S: 250-SIZE 100000000
S: 250-VRFY
S: 250-ETRN
S: 250-STARTTLS
S: 250-ENHANCEDSTATUSCODES
S: 250-8BITMIME
S: 250-DSN
S: 250 CHUNKING
C: MAIL FROM:<test@pbl-pub.blt.spamhaus.net>
S: 250 2.1.0 Ok
C: RCPT TO:<matthieu@redacted.be>
S: 250 2.1.5 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: Content-Type: text/plain; charset="utf-8"
C: Content-Transfer-Encoding: 7bit
C: MIME-Version: 1.0
C: Date: Wed, 17 Dec 2025 12:54:31 +0000
C: Message-ID: <176597607165.198160.13477353149981201691@blt.spamhaus.net>
C: Subject: BLT Public SMTP Test Email (65871:797868:pbl-pub-ip)
C: From: Spamhaus Blocklist Tester <test@pbl-pub.blt.spamhaus.net>
C: To: matthieu@redacted.be
C: 
C: This is a Spamhaus BLT public SMTP-test email which has been crafted
C: to be blocked by properly configured mail systems. If you're reading
C: this then your MX is not properly configured for the pbl-pub-ip test;
C: please see the BLT documentation at https://blt.spamhaus.com/docs for
C: tips on configuring your MX.
C: 
C: Description of this test:
C: 
C: This is a test of src IP blocking via the Public Mirrors Policy Blocklist (PBL):
C: https://docs.spamhaus.com/datasets/docs/source/10-data-type-documentation/datasets/030-datasets.html
C: 
C: You can view more information about this test email at
C: https://blt.spamhaus.com/test/65871/email/797868
C: 
C: Test parameters:
C: - MX:        mail.redacted.be
C: - MX IP:     168.119.140.207
C: - SRC IP:    199.168.89.86
C: - EHLO:      pbl-pub.blt.spamhaus.net
C: - MAIL FROM: test@pbl-pub.blt.spamhaus.net
C: - RCPT TO:   matthieu@redacted.be
C: - TEST ID:   65871
C: - EMAIL ID:  797868
C: - TIER:      public
C: 
C: .
S: 250 2.0.0 Ok: queued as 35EC12228A1
C: QUIT
S: 221 2.0.0 Bye
C: <Close TCP connection>
  • Our logs (filtered on their IP) :
2025-12-17T13:54:31+01:00 [1:mail1:postfix/postscreen] CONNECT from [199.168.89.86]:35117 to [myp.IP]:25
2025-12-17T13:54:33+01:00 [1:mail1:redis-persistent] DB saved on disk
2025-12-17T13:54:33+01:00 [1:mail1:redis-persistent] Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB
2025-12-17T13:54:33+01:00 [1:mail1:redis-persistent] Background saving terminated with success
2025-12-17T13:54:35+01:00 [1:mail1:postfix/smtpd] connect from 177.218-201-80.adsl-dyn.isp.belgacom.be[80.201.218.177]
2025-12-17T13:54:35+01:00 [1:mail1:rspamd] (rspamd_proxy) <be9987>; proxy; proxy_accept_socket: accepted milter connection from 127.0.0.1 port 37604
2025-12-17T13:54:35+01:00 [1:mail1:postfix/smtpd] Anonymous TLS connection established from 177.218-201-80.adsl-dyn.isp.belgacom.be[80.201.218.177]: TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256
2025-12-17T13:54:36+01:00 [1:mail1:rspamd] (rspamd_proxy) <be9987>; milter; rspamd_milter_process_command: got connection from 80.201.218.177:38658
2025-12-17T13:54:36+01:00 [1:mail1:postfix/smtpd] disconnect from 177.218-201-80.adsl-dyn.isp.belgacom.be[80.201.218.177] ehlo=2 starttls=1 quit=1 commands=4
2025-12-17T13:54:36+01:00 [1:mail1:rspamd] (rspamd_proxy) <be9987>; proxy; proxy_milter_finish_handler: finished milter connection
2025-12-17T13:54:37+01:00 [1:mail1:postfix/postscreen] PASS NEW [199.168.89.86]:35117
2025-12-17T13:54:37+01:00 [1:mail1:postfix/smtpd] connect from pbl-pub.blt.spamhaus.net[199.168.89.86]
2025-12-17T13:54:37+01:00 [1:mail1:rspamd] (rspamd_proxy) <e9d3e2>; proxy; proxy_accept_socket: accepted milter connection from 127.0.0.1 port 37612
2025-12-17T13:54:38+01:00 [1:mail1:postfix/smtpd] 35EC12228A1: client=pbl-pub.blt.spamhaus.net[199.168.89.86]
2025-12-17T13:54:38+01:00 [1:mail1:rspamd] (rspamd_proxy) <e9d3e2>; milter; rspamd_milter_process_command: got connection from 199.168.89.86:35117
2025-12-17T13:54:38+01:00 [1:mail1:postfix/cleanup] 35EC12228A1: message-id=<176597607165.198160.13477353149981201691@blt.spamhaus.net>
2025-12-17T13:54:38+01:00 [1:mail1:rspamd] (normal) <54710a>; task; rspamd_worker_body_handler: accepted connection from ::1 port 43022, task ptr: 00007F9B4A8C5058
2025-12-17T13:54:38+01:00 [1:mail1:rspamd] (normal) <35EC12>; task; rspamd_message_parse: loaded message; id: <176597607165.198160.13477353149981201691@blt.spamhaus.net>; queue-id: <35EC12228A1>; size: 1286; checksum: <ae3983f72c591afdfd0b6f491eefecfd>
2025-12-17T13:54:38+01:00 [1:mail1:rspamd] (normal) <35EC12>; task; rspamd_mime_part_detect_language: detected part language: en
2025-12-17T13:54:38+01:00 [1:mail1:rspamd] (normal) <35EC12>; lua; clamav.lua:131: clamav: message or mime_part is clean
2025-12-17T13:54:38+01:00 [1:mail1:rspamd] (normal) <35EC12>; task; rspamd_spf_maybe_return: stored SPF record for pbl-pub.blt.spamhaus.net (0x1ce2977d59eb1173) in LRU cache for 3600 seconds, 128/2000 elements in the cache
2025-12-17T13:54:39+01:00 [1:mail1:rspamd] (normal) <35EC12>; task; finalize_item: slow asynchronous rule: URIBL_MULTI(569): 519.00 ms; no idle timer is needed
2025-12-17T13:54:39+01:00 [1:mail1:rspamd] (normal) <35EC12>; task; finalize_item: slow synchronous rule: RBL_CALLBACK(581): 519.00 ms; enable 100ms idle timer to allow other rules to be finished
2025-12-17T13:54:39+01:00 [1:mail1:rspamd] (normal) <35EC12>; task; finalize_item: slow synchronous rule: NEURAL_CHECK(449): 1091.68 ms; idle timer has already been activated for this scan
2025-12-17T13:54:39+01:00 [1:mail1:rspamd] (normal) <35EC12>; task; finalize_item: slow asynchronous rule: HISTORY_SAVE(404): 1092.68 ms; no idle timer is needed
2025-12-17T13:54:39+01:00 [1:mail1:rspamd] (normal) <35EC12>; task; finalize_item: slow synchronous rule: MILTER_HEADERS(411): 1092.68 ms; idle timer has already been activated for this scan
2025-12-17T13:54:39+01:00 [1:mail1:rspamd] (normal) <35EC12>; task; finalize_item: slow asynchronous rule: NEURAL_LEARN(452): 1092.68 ms; no idle timer is needed
2025-12-17T13:54:39+01:00 [1:mail1:rspamd] (normal) <35EC12>; task; finalize_item: slow synchronous rule: RATELIMIT_UPDATE(464): 1092.68 ms; idle timer has already been activated for this scan
2025-12-17T13:54:39+01:00 [1:mail1:rspamd] (normal) <35EC12>; task; finalize_item: slow asynchronous rule: REPLIES_SET(582): 1092.68 ms; no idle timer is needed
2025-12-17T13:54:39+01:00 [1:mail1:rspamd] (normal) <35EC12>; task; rspamd_task_write_log: id: <176597607165.198160.13477353149981201691@blt.spamhaus.net>, qid: <35EC12228A1>, ip: 199.168.89.86, from: <test@pbl-pub.blt.spamhaus.net>, (default: F (no action): [-0.95/15.00] [BAYES_HAM(-1.25){89.72%;},MX_INVALID(0.50){},R_SPF_ALLOW(-0.20){+ip4:199.168.89.86/32;},MIME_GOOD(-0.10){text/plain;},ONCE_RECEIVED(0.10){},ARC_NA(0.00){},ASN(0.00){asn:54054, ipnet:199.168.88.0/22, country:US;},DBL_BLOCKED_OPENRESOLVER(0.00){spamhaus.com:url;redacted.be:url;redacted.be:email;spamhaus.net:url;spamhaus.net:email;pbl-pub.blt.spamhaus.net:helo;pbl-pub.blt.spamhaus.net:rdns;},DMARC_NA(0.00){spamhaus.net;},FROM_EQ_ENVFROM(0.00){},FROM_HAS_DN(0.00){},MID_RHS_MATCH_FROMTLD(0.00){},MIME_TRACE(0.00){0:+;},MISSING_XM_UA(0.00){},RCPT_COUNT_ONE(0.00){1;},RCVD_COUNT_ZERO(0.00){0;},R_DKIM_NA(0.00){},TO_DN_NONE(0.00){},TO_MATCH_ENVRCPT_ALL(0.00){}]), len: 1286, time: 1091.449ms, dns req: 43, digest: <ae3983f72c591afdfd0b6f491eefecfd>, rcpts: <matthieu@redacted.be>, mime_rcpts: <matthieu@redacted.be>
2025-12-17T13:54:39+01:00 [1:mail1:rspamd] (normal) <35EC12>; task; rspamd_protocol_http_reply: regexp statistics: 0 pcre regexps scanned, 2 regexps matched, 179 regexps total, 50 regexps cached, 0B scanned using pcre, 3.37KiB scanned total
2025-12-17T13:54:39+01:00 [1:mail1:postfix/qmgr] 35EC12228A1: from=<test@pbl-pub.blt.spamhaus.net>, size=1528, nrcpt=1 (queue active)
2025-12-17T13:54:39+01:00 [1:mail1:dovecot] lmtp(166998): Connect from local
2025-12-17T13:54:39+01:00 [1:mail1:postfix/smtpd] disconnect from pbl-pub.blt.spamhaus.net[199.168.89.86] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5

Content test

  • Their logs :
C: <Establish TCP connection>
S: 220 mail.redacted.be ESMTP Postfix
C: EHLO unlisted.blt.spamhaus.net
S: 250-mail.redacted.be
S: 250-PIPELINING
S: 250-SIZE 100000000
S: 250-VRFY
S: 250-ETRN
S: 250-STARTTLS
S: 250-ENHANCEDSTATUSCODES
S: 250-8BITMIME
S: 250-DSN
S: 250 CHUNKING
C: MAIL FROM:<test@unlisted.blt.spamhaus.net>
S: 250 2.1.0 Ok
C: RCPT TO:<matthieu@redacted.be>
S: 250 2.1.5 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: Content-Type: text/plain; charset="utf-8"
C: Content-Transfer-Encoding: 7bit
C: MIME-Version: 1.0
C: Date: Wed, 17 Dec 2025 13:24:51 +0000
C: Message-ID: <176597789131.198160.18132445613854290703@blt.spamhaus.net>
C: Subject: BLT DQS Content Test Email (65874:797892:sbl-dqs-body-ip)
C: From: Spamhaus Blocklist Tester <test@unlisted.blt.spamhaus.net>
C: To: matthieu@redacted.be
C: 
C: This is a Spamhaus BLT DQS content-test email which has been
C: crafted to be flagged as spam by properly configured mail systems. If
C: your MX is correctly configured to do content filtering for the
C: sbl-dqs-body-ip test, then this email should be flagged as spam (check the
C: headers) or rejected outright. If this email was delivered, and not
C: classified as spam, then your MX is not correctly configured for the
C: sbl-dqs-body-ip test; please see the BLT documentation at
C: https://blt.spamhaus.com/docs for tips on configuring your MX.
C: 
C: Description of this test:
C: 
C: This is a test of bad-IP-in-body blocking
C: via the DQS Spamhaus Blocklist (SBL):
C: https://docs.spamhaus.com/datasets/docs/source/10-data-type-documentation/datasets/030-datasets.html
C: 
C: The bad IP address is http://199.168.89.88.
C: 
C: You can view more information about this test email at
C: https://blt.spamhaus.com/test/65874/email/797892
C: 
C: Test parameters (some parameters omitted here to avoid accidental
C: flagging when the email body is scanned):
C: - MX:        mail.redacted.be
C: - MX IP:     My IP
C: - RCPT TO:   matthieu@redacted.be
C: - TEST ID:   65874
C: - EMAIL ID:  797892
C: - TIER:      DQS
C: 
C: .
S: 250 2.0.0 Ok: queued as BE3222228A1
C: QUIT
S: 221 2.0.0 Bye
C: <Close TCP connection>
  • Our logs :
2025-12-17T14:24:51+01:00 [1:mail1:postfix/postscreen] CONNECT from [199.168.89.101]:43629 to [My.IP]:25
2025-12-17T14:24:51+01:00 [1:mail1:postfix/postscreen] PASS OLD [199.168.89.101]:43629
2025-12-17T14:24:51+01:00 [1:mail1:postfix/smtpd] connect from unlisted.blt.spamhaus.net[199.168.89.101]
2025-12-17T14:24:51+01:00 [1:mail1:rspamd] (rspamd_proxy) <75648b>; proxy; proxy_accept_socket: accepted milter connection from 127.0.0.1 port 40316
2025-12-17T14:24:51+01:00 [1:mail1:postfix/smtpd] BE3222228A1: client=unlisted.blt.spamhaus.net[199.168.89.101]
2025-12-17T14:24:51+01:00 [1:mail1:rspamd] (rspamd_proxy) <75648b>; milter; rspamd_milter_process_command: got connection from 199.168.89.101:43629
2025-12-17T14:24:52+01:00 [1:mail1:postfix/smtpd] lost connection after AUTH from unknown[119.96.209.119]
2025-12-17T14:24:52+01:00 [1:mail1:postfix/smtpd] disconnect from unknown[119.96.209.119] ehlo=1 auth=0/1 commands=1/2
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (rspamd_proxy) <866547>; milter; rspamd_milter_process_command: got connection from 119.96.209.119:52780
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (rspamd_proxy) <866547>; proxy; proxy_milter_finish_handler: finished milter connection
2025-12-17T14:24:52+01:00 [1:mail1:postfix/cleanup] BE3222228A1: message-id=<176597789131.198160.18132445613854290703@blt.spamhaus.net>
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <da044e>; task; rspamd_worker_body_handler: accepted connection from ::1 port 48410, task ptr: 00007F9B4B5E1098
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; task; rspamd_message_parse: loaded message; id: <176597789131.198160.18132445613854290703@blt.spamhaus.net>; queue-id: <BE3222228A1>; size: 1541; checksum: <936c50f85fc6c9327127c4a5a4c92854>
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; task; rspamd_mime_part_detect_language: detected part language: en
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; lua; spf.lua:163: use cached record for unlisted.blt.spamhaus.net (0xde7b60e403cd5031) in LRU cache for 1738 seconds
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; lua; rbl.lua:289: error looking up 101.89.168.199.bl.blocklist.de: server fail
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; lua; clamav.lua:131: clamav: message or mime_part is clean
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; task; finalize_item: slow asynchronous rule: URIBL_MULTI(569): 321.00 ms; no idle timer is needed
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; task; finalize_item: slow asynchronous rule: RSPAMD_URIBL(516): 364.00 ms; no idle timer is needed
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; task; finalize_item: slow synchronous rule: RBL_CALLBACK(581): 364.00 ms; idle timer has already been activated for this scan
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; task; finalize_item: slow synchronous rule: NEURAL_CHECK(449): 365.00 ms; idle timer has already been activated for this scan
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; task; finalize_item: slow asynchronous rule: HISTORY_SAVE(404): 365.00 ms; no idle timer is needed
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; task; finalize_item: slow synchronous rule: MILTER_HEADERS(411): 365.00 ms; idle timer has already been activated for this scan
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; lua; neural.lua:355: skip ham sample to keep spam/ham balance; probability 0.6458333333333333; 51 spam and 143 ham vectors stored
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; task; finalize_item: slow asynchronous rule: NEURAL_LEARN(452): 366.00 ms; no idle timer is needed
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; task; finalize_item: slow synchronous rule: RATELIMIT_UPDATE(464): 366.00 ms; idle timer has already been activated for this scan
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; task; finalize_item: slow asynchronous rule: REPLIES_SET(582): 366.00 ms; no idle timer is needed
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; task; rspamd_task_write_log: id: <176597789131.198160.18132445613854290703@blt.spamhaus.net>, qid: <BE3222228A1>, ip: 199.168.89.101, from: <test@unlisted.blt.spamhaus.net>, (default: F (no action): [-1.31/15.00] [BAYES_HAM(-1.61){92.54%;},MX_INVALID(0.50){},R_SPF_ALLOW(-0.20){+ip4:199.168.89.101/32:c;},MIME_GOOD(-0.10){text/plain;},ONCE_RECEIVED(0.10){},ARC_NA(0.00){},ASN(0.00){asn:54054, ipnet:199.168.88.0/22, country:US;},BLOCKLISTDE_FAIL(0.00){199.168.89.101:server fail;},DBL_BLOCKED_OPENRESOLVER(0.00){unlisted.blt.spamhaus.net:helo;unlisted.blt.spamhaus.net:rdns;blt.spamhaus.net:mid;redacted.be:url;redacted.be:email;spamhaus.com:url;},DMARC_NA(0.00){spamhaus.net;},FROM_EQ_ENVFROM(0.00){},FROM_HAS_DN(0.00){},MID_RHS_MATCH_FROMTLD(0.00){},MIME_TRACE(0.00){0:+;},MISSING_XM_UA(0.00){},RCPT_COUNT_ONE(0.00){1;},RCVD_COUNT_ZERO(0.00){0;},R_DKIM_NA(0.00){},TO_DN_NONE(0.00){},TO_MATCH_ENVRCPT_ALL(0.00){}]), len: 1541, time: 364.938ms, dns req: 37, digest: <936c50f85fc6c9327127c4a5a4c92854>, rcpts: <matthieu@redacted.be>, mime_rcpts: <matthieu@redacted.be>
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (normal) <BE3222>; task; rspamd_protocol_http_reply: regexp statistics: 0 pcre regexps scanned, 2 regexps matched, 179 regexps total, 50 regexps cached, 0B scanned using pcre, 4.10KiB scanned total
2025-12-17T14:24:52+01:00 [1:mail1:postfix/qmgr] BE3222228A1: from=<test@unlisted.blt.spamhaus.net>, size=1786, nrcpt=1 (queue active)
2025-12-17T14:24:52+01:00 [1:mail1:dovecot] lmtp(167211): Connect from local
2025-12-17T14:24:52+01:00 [1:mail1:postfix/smtpd] disconnect from unlisted.blt.spamhaus.net[199.168.89.101] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
2025-12-17T14:24:52+01:00 [1:mail1:rspamd] (rspamd_proxy) <bf0250>; proxy; proxy_milter_finish_handler: finished milter connection
2025-12-17T14:24:52+01:00 [1:mail1:dovecot] lmtp(matthieu)<167211><mKeoHCSvQmkrjQIA/2Rcwg>: save: box=INBOX, uid=83193, msgid=<176597789131.198160.18132445613854290703@blt.spamhaus.net>, from=Spamhaus Blocklist Tester <test@unlisted.blt.spamhaus.net>, subject=BLT DQS Content Test Email (65874:797892:sbl-dqs-body-ip), flags=()

I should take more time to analyse this but can’t right now.

1 Like

A friend with a VPS on Hetzner provided this test[1] for us, confirming that direct Unbound queries are working, while forwarded queries are restricted.

[root@ns8node ~]# runagent -m mail1 podman exec -ti rspamd ash -l
ns8node:/# unbound-host 2.0.0.127.zen.spamhaus.org
2.0.0.127.zen.spamhaus.org has address 127.0.0.4
2.0.0.127.zen.spamhaus.org has address 127.0.0.2
2.0.0.127.zen.spamhaus.org has address 127.0.0.10
ns8node:/# cat /etc/resolv.conf 
nameserver 185.12.64.1
nameserver 185.12.64.2
ns8node:/# getent hosts 2.0.0.127.zen.spamhaus.org
127.255.255.254   2.0.0.127.zen.spamhaus.org  2.0.0.127.zen.spamhaus.org

Note Hetzner’s nameservers in /etc/resolv.conf.

Could you run the same test? I guess the result will be different…


  1. Public Mirrors to DQS Migration — Spamhaus Technology Documentation 2.0 documentation ↩︎

1 Like

Same results except search ``your-server.de.

ns8:/# unbound-host 2.0.0.127.zen.spamhaus.org
2.0.0.127.zen.spamhaus.org has address 127.0.0.4
2.0.0.127.zen.spamhaus.org has address 127.0.0.2
2.0.0.127.zen.spamhaus.org has address 127.0.0.10
ns8:/# cat /etc/resolv.conf
search your-server.de
nameserver 185.12.64.1
nameserver 185.12.64.2
ns8:/# getent hosts 2.0.0.127.zen.spamhaus.org
127.255.255.254   2.0.0.127.zen.spamhaus.org  2.0.0.127.zen.spamhaus.org

NB / I’m running a VM on a proxmox running on dedicated hardware @ Hetzner, not a VPS.

1 Like

The test is ok. Please check Rspamd configuration. It should be like this

[root@ns8 ~]# runagent -m mail1 podman exec rspamd rspamadm configdump options.dns
*** Section options.dns ***
timeout = 1.0;
sockets = 16;
retransmits = 5;
nameserver [
    "127.0.0.1:11336:1",
]

*** End of section options.dns ***

Can you exclude that DNS queries originating from it are proxied? For example, compare the output of these commands:

runagent -m mail1 podman exec rspamd unbound-host  -t TXT o-o.myaddr.l.google.com
runagent -m mail1 podman exec rspamd unbound-host -r -t TXT o-o.myaddr.l.google.com
host -t TXT o-o.myaddr.l.google.com

Google DNS server reply should contain the query source IP address. If it doesn’t correspond to the server public IP, your server is proxied.

1 Like

Thanks again @davidep

Your tests showed that I’m proxied but also that my ipv6 address wasn’t set correctly. It turned out that apparently and contrary to ipv4, IPv6 SLAAC and Router Advertisements takes precedence over the manually configured IPv6 address, so outbound traffic (including DNS) used the SLAAC-derived address instead of the static one :frowning: - I’m quite new to ipv6 and that was totally unexpected.

That’s really misleading since the configuration looked correct in cockpit :

I’m extremely sorry to discover that so lately, I should have checked.

Thank to both of you @mrmarkuz and @davidep :-/ I’ll fix the config tonight and will report back.

Matthieu

1 Like

Update. I fixed my IPc6 config but that wasn’t the problem actually :frowning:

After extend tests, I believe my config is ok; my DNS queries are not proxied. Proof :

While doing runagent -m mail1 podman exec rspamd unbound-host -dd -v ``www.example.org:

# tcpdump -ni ens18 '(udp port 53 or tcp port 53)'
listening on ens18, link-type EN10MB (Ethernet), snapshot length 262144 bytes
13:40:23.767096 IP 168.119.140.207.11345 > 193.0.14.129.domain: 56082% [1au] NS? . (28)
13:40:23.796953 IP 193.0.14.129.domain > 168.119.140.207.11345: 56082*- 14/0/27 NS l.root-servers.net., NS a.root-servers.net., NS c.root-servers.net., NS f.root-servers.net., NS b.root-servers.net., NS e.root-servers.net., NS d.root-servers.net., NS g.root-servers.net., NS k.root-servers.net., NS h.root-servers.net., NS j.root-servers.net., NS i.root-servers.net., NS m.root-servers.net., RRSIG (1109)
13:40:23.797217 IP 168.119.140.207.47235 > 192.33.4.12.domain: 48740% [1au] A? org. (32)
13:40:23.807588 IP 192.33.4.12.domain > 168.119.140.207.47235: 48740- 0/8/13 (772)
13:40:23.807714 IP 168.119.140.207.45527 > 199.19.56.1.domain: 12917% [1au] A? example.org. (40)
13:40:23.818665 IP 199.19.56.1.domain > 168.119.140.207.45527: 12917- 0/5/1 (358)
13:40:23.818841 IP6 2a01:4f8:251:52c::20.54701 > 2001:503:ba3e::2:30.domain: 15575% [1au] A? com. (32)
13:40:23.818900 IP 168.119.140.207.21117 > 193.0.14.129.domain: 47410% [1au] A? com. (32)
13:40:23.824762 IP6 2001:503:ba3e::2:30.domain > 2a01:4f8:251:52c::20.54701: 15575- 0/15/27 (1163)
13:40:23.824909 IP 168.119.140.207.26320 > 192.52.178.30.domain: 52117% [1au] A? cloudflare.com. (43)
13:40:23.836247 IP 192.52.178.30.domain > 168.119.140.207.26320: 52117- 0/7/21 (720)
13:40:23.836368 IP 168.119.140.207.65091 > 162.159.1.33.domain: 44883% [1au] A? ns.cloudflare.com. (46)
13:40:23.842079 IP 162.159.1.33.domain > 168.119.140.207.65091: 44883*- 3/0/1 A 173.245.58.100, A 173.245.59.100, RRSIG (188)
13:40:23.842176 IP 168.119.140.207.35490 > 162.159.1.33.domain: 14889% [1au] A? katelyn.ns.cloudflare.com. (54)
13:40:23.847801 IP 193.0.14.129.domain > 168.119.140.207.21117: 47410- 0/15/27 (1163)
13:40:23.847977 IP6 2a01:4f8:251:52c::20.30527 > 2001:502:1ca1::30.domain: 56155% [1au] A? cloudflare.com. (43)
13:40:23.848475 IP 162.159.1.33.domain > 168.119.140.207.35490: 14889*- 4/0/1 A 172.64.34.235, A 162.159.38.235, A 108.162.194.235, RRSIG (212)
13:40:23.848563 IP6 2a01:4f8:251:52c::20.24232 > 2400:cb00:2049:1::a29f:837.domain: 64886% [1au] AAAA? katelyn.ns.cloudflare.com. (54)
13:40:23.856602 IP6 2400:cb00:2049:1::a29f:837.domain > 2a01:4f8:251:52c::20.24232: 64886*- 4/0/1 AAAA 2803:f800:50::6ca2:c2eb, AAAA 2a06:98c1:50::ac40:22eb, AAAA 2606:4700:50::a29f:26eb, RRSIG (248)
13:40:23.856816 IP6 2a01:4f8:251:52c::20.26632 > 2803:f800:50::6ca2:c2eb.domain: 40245% [1au] A? www.example.org. (44)
13:40:23.863769 IP6 2803:f800:50::6ca2:c2eb.domain > 2a01:4f8:251:52c::20.26632: 40245*- 3/0/1 A 104.18.2.24, A 104.18.3.24, RRSIG (183)
13:40:23.864562 IP 168.119.140.207.45538 > 162.159.38.235.domain: 508% [1au] AAAA? www.example.org. (44)
13:40:23.868381 IP6 2001:502:1ca1::30.domain > 2a01:4f8:251:52c::20.30527: 56155- 0/7/21 (720)
13:40:23.877957 IP 162.159.38.235.domain > 168.119.140.207.45538: 508*- 3/0/1 AAAA 2606:4700::6812:218, AAAA 2606:4700::6812:318, RRSIG (207)
13:40:23.878633 IP6 2a01:4f8:251:52c::20.57424 > 2606:4700:50::a29f:26eb.domain: 19508% [1au] MX? www.example.org. (44)
13:40:23.885178 IP6 2606:4700:50::a29f:26eb.domain > 2a01:4f8:251:52c::20.57424: 19508*- 0/4/1 (368)

Neither 185.12.64.1 nor 2a01:4f8:0:a231::add:1 (or similar, those are Hetzner’s DNS) are queried.

:warning: I believe Spamhaus DBL legacy is walled-gardened for my server’s source IP (and the whole Hetzner ASN), therefore returning 127.255.255.254 for real DBL queries while canary queries still return NXDOMAIN. This is expected behaviour per Spamhaus documentation and not a misconfiguration, as explained in this blog post : Email Security | Query our DNSBLs via Hetzner's infrastructure? Move to free Data Query Service | Resources

Therefore I believe that the strategy that was in use since NS7 (using unbound) is not valid anymore and should be replaced by the DQS strategy.

@davidep what do you think ?

I tried your proposed solution and I believe it works !

Indeed the BLT tool content test “fails” since the test emails are delivered, but that’s only because the computed score is not high enough : see the headers : SPAMHAUS_SBL_URL(6.50)[88.89.168.199:url]shows it works perfectly.

Return-Path: <test@unlisted.blt.spamhaus.net>
Delivered-To: matthieu@mail.gaillet.be.localhost
Received: from mail.gaillet.be
	by ns8.toucheatout.be with LMTP
	id 6PrdOdD5R2kmCgAA/2Rcwg
	(envelope-from <test@unlisted.blt.spamhaus.net>)
	for <matthieu@mail.gaillet.be.localhost>; Sun, 21 Dec 2025 13:44:48 +0000
Received: from unlisted.blt.spamhaus.net (unlisted.blt.spamhaus.net [199.168.89.101])
	by mail.gaillet.be (Postfix) with ESMTP id 97151221CDA
	for <matthieu@gaillet.be>; Sun, 21 Dec 2025 13:44:47 +0000 (UTC)
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
MIME-Version: 1.0
Date: Sun, 21 Dec 2025 13:44:47 +0000
Message-ID: <176632468719.198160.17472072351645493008@blt.spamhaus.net>
Subject: BLT DQS Content Test Email (66055:800937:sbl-dqs-body-ip)
From: Spamhaus Blocklist Tester <test@unlisted.blt.spamhaus.net>
To: matthieu@gaillet.be
X-Rspamd-Server: ns8
X-Rspamd-Flag-Threshold: 6
X-Rspamd-Queue-Id: 97151221CDA
X-Spamd-Result: default: False [5.48 / 15.00];
	SPAMHAUS_SBL_URL(6.50)[88.89.168.199:url];
	BAYES_HAM(-1.62)[92.55%];
	MX_INVALID(0.50)[];
	ONCE_RECEIVED(0.10)[];
	MIME_GOOD(-0.10)[text/plain];
	BAD_REP_POLICIES(0.10)[];
	TO_DN_NONE(0.00)[];
	ARC_NA(0.00)[];
	FROM_HAS_DN(0.00)[];
	ASN(0.00)[asn:54054, ipnet:199.168.88.0/22, country:US];
	MIME_TRACE(0.00)[0:+];
	MISSING_XM_UA(0.00)[];
	TO_MATCH_ENVRCPT_ALL(0.00)[];
	R_SPF_ALLOW(0.00)[+ip4:199.168.89.101/32:c];
	R_DKIM_NA(0.00)[];
	DMARC_NA(0.00)[spamhaus.net];
	RCVD_COUNT_ZERO(0.00)[0];
	FROM_EQ_ENVFROM(0.00)[];
	RCPT_COUNT_ONE(0.00)[1];
	MID_RHS_MATCH_FROMTLD(0.00)[]
X-Rspamd-Action: no action

This is a Spamhaus BLT DQS content-test email which has been
crafted to be flagged as spam by properly configured mail systems. If
your MX is correctly configured to do content filtering for the
sbl-dqs-body-ip test, then this email should be flagged as spam (check the
headers) or rejected outright. If this email was delivered, and not
classified as spam, then your MX is not correctly configured for the
sbl-dqs-body-ip test; please see the BLT documentation at
https://blt.spamhaus.com/docs for tips on configuring your MX.

Description of this test:

This is a test of bad-IP-in-body blocking
via the DQS Spamhaus Blocklist (SBL):
https://docs.spamhaus.com/datasets/docs/source/10-data-type-documentation/datasets/030-datasets.html

The bad IP address is http://199.168.89.88.


EDIT / The SMTP test fails but I believe that’s expected since there is no mechanism at postfix level.

1 Like