SA Bugzilla – Bug 6862
Allow a DNS resolver to use EDNS - UDP packets larger than 512 bytes (configurable)
Last modified: 2013-02-21 11:54:04 UTC
Now that google.com went overboard with switching to DKIM signatures signed with a 2048-bit key, a DNS query for a public key comes close to an old DNS/UDP limit of 512 bytes. Depending on a recursive DNS server in use, the google's public key comes back either just below the 512 byte limit (when there are no additional answer sections, like with an 'unbound' resolver), or somewhat above this limit (with 'bind'), in which case the Net::DNS::Resolver on seeing a truncated response retries the query using TCP. The issue could be avoided if Net::DNS::Resolver were allowed to form an extended query (EDNS0, RFC 2671, RFC 2671bis draft), which can tell that a client is willing to accept UDP packets larger than the ancient 512 limit. Here is an example: perl -le 'use Net::DNS; $r=Net::DNS::Resolver->new; $r->udppacketsize(4096); print $r->send("20120113._domainkey.google.com","TXT")->print' ( the above text is from my enhancement request to Mail::DKIM, https://rt.cpan.org/Public/Bug/Display.html?id=80425 ) There should be a configurable way for SpamAssassin to enable EDNS option in Net::DNS::Resolver. The attached patch adds an option 'EDNS' to dns_options configuration setting. It also passes the resolver object to the DKIM plugin for the benefit of a Mail::DKIM module, so that it can use the same settings as the rest of SpamAssassin (just like the SPF plugin). As some of the DNS resolver settings are now configurable, I had to postpone the call to DnsResolver::load_resolver in SpamAssassin.pm until after a config is read. This is from a new documentation: =item dns_options opts (default: empty) Provides a (whitespace or comma -separated) list of options applying to DNS resolving. Available options are 'rotate', 'dns0x20' and 'edns' (without quotes). Option name may be negated by prepending a 'no' (e.g. 'norotate', 'noEDNS') to counteract previously enabled option. Option names are not case-sensitive. The last setting in configuration files prevails. By default options 'rotate', 'dns0x20' and 'edns' are disabled. Option 'edns' may take a value which specifies a requestor's UDP payload size according to EDNS0 specifications (RFC 2671bis draft), e.g. edns=4096. When the option is enabled but a value is not provided, a conservative default of 1280 bytes is implied. It is recommended to enable 'edns' when using a local recursive DNS server which supports EDNS0 (like most modern DNS servers do). This may avoid a need for a DNS query to fail-over to a TCP query when an answer DNS UDP packet would exceed 512 bytes. The option should remain disabled when a recursive DNS resolver is only reachable through some old-fashioned firewall which cannot cope with DNS UDP packets longer than 512 bytes or which discards IP fragments. [...]
Created attachment 5109 [details] The suggested patch, implementing: dns_options EDNS Bug 6862 - Allow a DNS resolver to use EDNS - UDP packets larger than 512 bytes (configurable) Sending lib/Mail/SpamAssassin/Conf.pm Sending lib/Mail/SpamAssassin/Dns.pm Sending lib/Mail/SpamAssassin/DnsResolver.pm Sending lib/Mail/SpamAssassin/Plugin/DKIM.pm Sending lib/Mail/SpamAssassin.pm Committed revision 1406272.
Bug 6862 (one detail fixed): Sending lib/Mail/SpamAssassin.pm Committed revision 1406273.
Allow a DNS resolver to use EDNS: Let it apply to queries prepared by our DnsResolver.pm too Sending lib/Mail/SpamAssassin/DnsResolver.pm Committed revision 1407194.
I declare this resolved.
Just some tweaks for the record: r1446278 | mmartinec | 2013-02-14 18:28:05 +0100 (Thu, 14 Feb 2013) | 9 lines - change description of a dns_options EDNS option, add alias EDNS0 - ignore trailing dot in a domain name which sometimes still creep in - change word 'response' -> 'reply' in DNS debugging messages (RFC 1035) - test for truncated DNS reply, issue an info-level warning - debugging: trying to track down a bug in Net::DNS which can return a DNS packet with an empty question section The current description of the 'dns_options EDNS' option is: =item dns_options opts ... [...] Option 'edns' (or 'edsn0') may take a value which specifies a requestor's acceptable UDP payload size according to EDNS0 specifications (RFC 2671bis draft), e.g. edns=4096. In absence of an 'edns' option a traditional implied UDP payload size is 512 bytes. When the option is specified but a value is not provided, a conservative default of 1240 bytes is implied. It is recommended to enable 'edns' when using a local recursive DNS server which supports EDNS0 (like most modern DNS servers do), a suitable setting in this case is edns=4096. Allowing packets larger than 512 bytes can avoid truncation of answer resource records in large DNS responses (like in TXT records of some SPF and DKIM responses, or when an unreasonable number of A records is published by some domain). The option should remain disabled when a recursive DNS server is only reachable through some old-fashioned firewall which bans DNS UDP packets larger than 512 bytes. A suitable value when a non-local recursive DNS server is used and a firewall allows EDNS0 but blocks fragmented IP packets is perhaps 1240 bytes, allowing a DNS UDP packet to fit within a single IP packet in most cases.
> The current description of the 'dns_options EDNS' option is: Btw, see Bug 6910, the default is changed to 'dns_options edns=4096'.