Type: Bug
checkMX() takes the first record of the MX answer without looking at its preference:
|
mxRecords = resolver.query(domain, "MX") |
|
mxDomain = mxRecords[0].exchange # Mail-domain of domain |
|
res["mxDomain"] = str(mxDomain) |
mxRecords = resolver.query(domain, "MX")
mxDomain = mxRecords[0].exchange # Mail-domain of domain
res["mxDomain"] = str(mxDomain)
DNS makes no promise about the order of records within an RRset, and resolvers are free to return them in any order. For a domain with a primary and a backup MX, for example
example.com. MX 10 mail.example.com.
example.com. MX 20 backup.mx.example.net.
the check therefore tests the primary on some calls and the backup provider on others. When it lands on the backup, externalDNS, internalDNS and reverseLookup all describe the provider's host rather than the grommunio server, and the MX chip in admin-web is scored against the wrong machine, for an unchanged zone.
We see both orders on one server: the local resolver returned the preference-20 record first, the public resolvers 1.1.1.1 and 9.9.9.9 returned the preference-10 record first, and a direct call of checkMX() a few minutes later picked the primary.
Suggested fix: sort by preference, with the exchange name as a tie-breaker, before picking:
mxRecords = sorted(resolver.query(domain, "MX"),
key=lambda r: (r.preference, str(r.exchange)))
mxDomain = mxRecords[0].exchange # Mail-domain of domain
The second key matters when several records share the lowest preference: sorted() is stable, so on preference alone it would simply keep the resolver's own order — which is the thing that varies. With the name as a tie-breaker the same host is picked on every call, whatever order the answer arrives in.
That still checks only one host. Testing every record at the lowest preference would be the complete answer, but it needs a change in the response format; a stable single pick at least stops the chip from changing colour on an unchanged zone.
(preference and exchange as in dnspython 2.6.1, the version shipped with Ubuntu 24.04.)
Present on current master (3077150) and in the Ubuntu 24.04 community package 1.21.7.m3077150.
Type: Bug
checkMX()takes the first record of the MX answer without looking at its preference:admin-api/tools/dnsHealth.py
Lines 119 to 121 in 3077150
DNS makes no promise about the order of records within an RRset, and resolvers are free to return them in any order. For a domain with a primary and a backup MX, for example
the check therefore tests the primary on some calls and the backup provider on others. When it lands on the backup,
externalDNS,internalDNSandreverseLookupall describe the provider's host rather than the grommunio server, and the MX chip in admin-web is scored against the wrong machine, for an unchanged zone.We see both orders on one server: the local resolver returned the preference-20 record first, the public resolvers 1.1.1.1 and 9.9.9.9 returned the preference-10 record first, and a direct call of
checkMX()a few minutes later picked the primary.Suggested fix: sort by preference, with the exchange name as a tie-breaker, before picking:
The second key matters when several records share the lowest preference:
sorted()is stable, so on preference alone it would simply keep the resolver's own order — which is the thing that varies. With the name as a tie-breaker the same host is picked on every call, whatever order the answer arrives in.That still checks only one host. Testing every record at the lowest preference would be the complete answer, but it needs a change in the response format; a stable single pick at least stops the chip from changing colour on an unchanged zone.
(
preferenceandexchangeas in dnspython 2.6.1, the version shipped with Ubuntu 24.04.)Present on current master (
3077150) and in the Ubuntu 24.04 community package1.21.7.m3077150.