Skip to content

Commit 00845bf

Browse files
committed
dnslists: make valid lookup result addresses configurable. Bug 2631
This allows the Spamhaus error addresses to be considered an error, e.g.: dnslist_valid_addresses = ${if match{$dnslist_domain}{\N.spamhaus.org$\N}{!127.255.255.0/24 : }}127.0.0.0/8
1 parent 725900c commit 00845bf

File tree

11 files changed

+608
-128
lines changed

11 files changed

+608
-128
lines changed

doc/doc-docbook/spec.xfpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15814,6 +15814,20 @@ means that DNSSEC will not work with Exim on that platform either, unless Exim
1581415814
is linked against an alternative DNS client library.
1581515815

1581615816

15817+
.new
15818+
.option dnslist_valid_addresses main "host list&!!" &`127.0.0.0/8`&
15819+
.cindex "dnslists ACL condition" "valid addresses"
15820+
This option specifies IP addresses that are acceptable in dnslist responses.
15821+
15822+
Responses containing address records that do not match this list will be logged
15823+
as an error and ignored. This helps identify list domains that have been taken
15824+
over by a domain-parking registrar.
15825+
15826+
The variable &$dnslist_domain$& contains the name of the overall domain that
15827+
matched (for example, &`spamhaus.example`&).
15828+
.wen
15829+
15830+
1581715831
.option drop_cr main boolean false
1581815832
This is an obsolete option that is now a no-op. It used to affect the way Exim
1581915833
handled CR and LF characters in incoming messages. What happens now is
@@ -32368,6 +32382,12 @@ connection (assuming long-enough TTL).
3236832382
Exim does not share information between multiple incoming
3236932383
connections (but your local name server cache should be active).
3237032384

32385+
.new
32386+
DNS list responses are filtered using the &%dnslist_valid_addresses%& host list
32387+
before use to protect against list domains that have been taken over by a
32388+
domain-parking registrar and no longer return values in the 127.0.0.0/8 range.
32389+
.wen
32390+
3237132391
There are a number of DNS lists to choose from, some commercial, some free,
3237232392
or free for small deployments. An overview can be found at
3237332393
&url(https://en.wikipedia.org/wiki/Comparison_of_DNS_blacklists).

src/src/dnsbl.c

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ if (cb->rc == DNS_SUCCEED)
239239
{
240240
int address[4];
241241
int mask = 0;
242+
uschar *orig_dnslist_domain = dnslist_domain;
243+
244+
/* Make dnslist_domain available to dnslist_valid_addresses expansion. */
245+
dnslist_domain = domain_txt;
242246

243247
/* At present, all known DNS blocking lists use A records, with
244248
IPv4 addresses on the RHS encoding the information they return. I
@@ -248,14 +252,21 @@ if (cb->rc == DNS_SUCCEED)
248252
We change this only for IPv4 addresses in the list. */
249253

250254
if (host_aton(da->address, address) == 1)
251-
if ((address[0] & 0xff000000) != 0x7f000000) /* 127.0.0.0/8 */
252-
log_write(0, LOG_MAIN,
253-
"DNS list lookup for %s at %s returned %s;"
254-
" not in 127.0/8 and discarded",
255-
keydomain, domain, da->address);
255+
{
256+
if (verify_check_this_host(&dnslist_valid_addresses, NULL, US"", da->address, NULL) == OK)
257+
{
258+
mask = address[0];
259+
}
260+
else
261+
{
262+
log_write(0, LOG_MAIN,
263+
"DNS list lookup for %s at %s returned %s;"
264+
" invalid address discarded",
265+
keydomain, domain, da->address);
266+
}
267+
}
256268

257-
else
258-
mask = address[0];
269+
dnslist_domain = orig_dnslist_domain;
259270

260271
/* Scan the returned addresses, skipping any that are IPv6 */
261272

@@ -315,20 +326,33 @@ if (cb->rc == DNS_SUCCEED)
315326
else
316327
{
317328
BOOL ok = FALSE;
329+
uschar *orig_dnslist_domain = dnslist_domain;
330+
331+
/* Make dnslist_domain available to dnslist_valid_addresses expansion. */
332+
dnslist_domain = domain_txt;
333+
318334
for (da = cb->rhs; da; da = da->next)
319335
{
320336
int address[4];
321337

322-
if ( host_aton(da->address, address) == 1 /* ipv4 */
323-
&& (address[0] & 0xff000000) == 0x7f000000 /* 127.0.0.0/8 */
324-
)
325-
ok = TRUE;
326-
else
327-
log_write(0, LOG_MAIN,
328-
"DNS list lookup for %s at %s returned %s;"
329-
" not in 127.0/8 and discarded",
330-
keydomain, domain, da->address);
338+
if (host_aton(da->address, address) == 1)
339+
{
340+
if (verify_check_this_host(&dnslist_valid_addresses, NULL, US"", da->address, NULL) == OK)
341+
{
342+
ok = TRUE;
343+
}
344+
else
345+
{
346+
log_write(0, LOG_MAIN,
347+
"DNS list lookup for %s at %s returned %s;"
348+
" invalid address discarded",
349+
keydomain, domain, da->address);
350+
}
351+
}
331352
}
353+
354+
dnslist_domain = orig_dnslist_domain;
355+
332356
if (!ok) return FAIL;
333357
}
334358

src/src/globals.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,7 @@ int dns_use_edns0 = -1; /* <0 = not coerced */
886886
uschar *dnslist_domain = NULL;
887887
uschar *dnslist_matched = NULL;
888888
uschar *dnslist_text = NULL;
889+
const uschar *dnslist_valid_addresses = US"127.0.0.0/8";
889890
uschar *dnslist_value = NULL;
890891
tree_node *domainlist_anchor = NULL;
891892
int domainlist_count = 0;

src/src/globals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,7 @@ extern int dns_use_edns0; /* Coerce EDNS0 support on/off in resolve
554554
extern uschar *dnslist_domain; /* DNS (black) list domain */
555555
extern uschar *dnslist_matched; /* DNS (black) list matched key */
556556
extern uschar *dnslist_text; /* DNS (black) list text message */
557+
extern const uschar *dnslist_valid_addresses; /* DNS list IP addresses that are considered valid (127.0.0.0/8) */
557558
extern uschar *dnslist_value; /* DNS (black) list IP address */
558559
extern tree_node *domainlist_anchor; /* Tree of defined domain lists */
559560
extern int domainlist_count; /* Number defined */

src/src/readconf.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ static optionlist optionlist_config[] = {
140140
{ "dns_retry", opt_int, {&dns_retry} },
141141
{ "dns_trust_aa", opt_stringptr, {&dns_trust_aa} },
142142
{ "dns_use_edns0", opt_int, {&dns_use_edns0} },
143+
{ "dnslist_valid_addresses", opt_stringptr, {&dnslist_valid_addresses} },
143144
/* This option is now a no-op, retained for compatibility */
144145
{ "drop_cr", opt_bool, {&drop_cr} },
145146
/*********************************************************/

test/confs/0139

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@
88
domainlist local_domains = exim.test.ex
99
trusted_users = CALLER
1010

11+
.ifdef DNSBL_127_255
12+
# Split into two /9s so that it's visible in the debug output
13+
dnslist_valid_addresses = ${if eq{$dnslist_domain}{rbl.test.ex}{!127.255.255.0/24 : 127.0.0.0/9 : 127.128.0.0/9}{127.0.0.0/8}}
14+
.endif
15+
16+
.ifdef DNSBL_FAIL
17+
# Expansion failure
18+
dnslist_valid_addresses = ${if eq{intentional_expansion_failure
19+
.endif
20+
1121
acl_smtp_helo = check_helo
1222
acl_smtp_rcpt = check_recipient
1323
acl_smtp_mail = check_mail

test/dnszones-src/db.test.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ TTL=2 14.12.11.V4NET.rbl A 127.0.0.2
212212
105.13.13.V4NET.rbl A 255.255.255.255
213213
A 255.255.255.254
214214
215+
; Configuration to consider 127.255.255.0/24 as invalid
216+
217+
106.13.13.V4NET.rbl A 127.255.255.255
218+
215219
; -------- Testing MX records --------
216220
217221
mxcased MX 5 ten-99.TEST.EX.

test/log/0509

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
1999-03-02 09:44:33 rbl.test.ex/<;1.2.3.4;V4NET.11.12.13
2-
1999-03-02 09:44:33 DNS list lookup for ten-1 at test.ex returned V4NET.0.0.1; not in 127.0/8 and discarded
2+
1999-03-02 09:44:33 DNS list lookup for ten-1 at test.ex returned V4NET.0.0.1; invalid address discarded
33
1999-03-02 09:44:33 test.ex/a.b.c.d::ten-1::localhost
44
1999-03-02 09:44:33 U=CALLER rejected connection in "connect" ACL

test/scripts/0000-Basic/0139

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,20 @@ exim -bh V4NET.13.13.105
6565
vrfy a@b
6666
quit
6767
****
68+
exim -bh V4NET.13.13.106
69+
vrfy a@b
70+
quit
71+
****
72+
exim -DDNSBL_127_255 -bh V4NET.13.13.2
73+
vrfy a@b
74+
quit
75+
****
76+
exim -DDNSBL_127_255 -bh V4NET.13.13.106
77+
vrfy a@b
78+
quit
79+
****
80+
exim -DDNSBL_FAIL -bh V4NET.13.13.2
81+
vrfy a@b
82+
quit
83+
****
6884
no_msglog_check

0 commit comments

Comments
 (0)