improvements to outgoing dmarc reports and displaying evaluations

- more eagerly report about overrides, so domain owners can better tell that
  switching from p=none to p=reject will not cause trouble for these messages.
- report multiple reasons, e.g. mailing list and sampled out
- in dmarc analysis for rejects from first-time senders (possibly spammers),
  fix the conditional check on nonjunk messages.
- in evaluations view in admin, show unaligned spf pass in yellow too and a few
  more small tweaks.
This commit is contained in:
Mechiel Lukkien
2023-11-02 17:54:24 +01:00
parent 79e522887e
commit 481a25f294
2 changed files with 19 additions and 18 deletions

View File

@ -1148,7 +1148,7 @@ const dmarcEvaluationsDomain = async (domain) => {
const authStatus = (v) => inlineBox(v ? '' : yellow, v ? 'pass' : 'fail')
const formatDKIMResults = (results) => results.map(r => dom.div('selector '+r.Selector+(r.Domain !== domain ? ', domain '+r.Domain : '') + ': ', inlineBox(r.Result === "pass" ? '' : yellow, r.Result)))
const formatSPFResults = (results) => results.map(r => dom.div(''+r.Scope+(r.Domain !== domain ? ', domain '+r.Domain : '') + ': ', inlineBox(r.Result === "pass" ? '' : yellow, r.Result)))
const formatSPFResults = (alignedpass, results) => results.map(r => dom.div(''+r.Scope+(r.Domain !== domain ? ', domain '+r.Domain : '') + ': ', inlineBox(r.Result === "pass" && alignedpass ? '' : yellow, r.Result)))
const sourceIP = (ip) => {
const r = dom.span(ip, attr({title: 'Click to do a reverse lookup of the IP.'}), style({cursor: 'pointer'}), async function click(e) {
@ -1198,7 +1198,7 @@ const dmarcEvaluationsDomain = async (domain) => {
dom.th('Policy', attr({title: 'Summary of the policy as encountered in the DMARC DNS record of the domain, and used for evaluation.'})),
dom.th('IP', attr({title: 'IP address of delivery attempt that was evaluated, relevant for SPF.'})),
dom.th('Disposition', attr({title: 'Our decision to accept/reject this message. It may be different than requested by the published policy. For example, when overriding due to delivery from a mailing list or forwarded address.'})),
dom.th('DKIM/SPF', attr({title: 'Whether DKIM and SPF had an aligned pass, where strict/relaxed alignment means whether the domain of an SPF pass and DKIM pass matches the exact domain (strict) or optionally a subdomain (relaxed). A DMARC pass requires at least one pass.'})),
dom.th('Aligned DKIM/SPF', attr({title: 'Whether DKIM and SPF had an aligned pass, where strict/relaxed alignment means whether the domain of an SPF pass and DKIM pass matches the exact domain (strict) or optionally a subdomain (relaxed). A DMARC pass requires at least one pass.'})),
dom.th('Envelope to', attr({title: 'Domain used in SMTP RCPT TO during delivery.'})),
dom.th('Envelope from', attr({title: 'Domain used in SMTP MAIL FROM during delivery.'})),
dom.th('Message from', attr({title: 'Domain in "From" message header.'})),
@ -1228,13 +1228,13 @@ const dmarcEvaluationsDomain = async (domain) => {
dom.td(addresses),
dom.td(policy),
dom.td(sourceIP(e.SourceIP)),
dom.td(inlineBox(e.Disposition === 'none' ? '' : 'red', e.Disposition), (e.OverrideReasons || []).length > 0 ? ' ('+e.OverrideReasons.map(r => r.Type).join(', ')+')' : ''),
dom.td(inlineBox(e.Disposition === 'none' ? '' : red, e.Disposition), (e.OverrideReasons || []).length > 0 ? ' ('+e.OverrideReasons.map(r => r.Type).join(', ')+')' : ''),
dom.td(authStatus(e.AlignedDKIMPass), '/', authStatus(e.AlignedSPFPass)),
dom.td(e.EnvelopeTo),
dom.td(e.EnvelopeFrom),
dom.td(e.HeaderFrom),
dom.td(formatDKIMResults(e.DKIMResults || [])),
dom.td(formatSPFResults(e.SPFResults || [])),
dom.td(formatSPFResults(e.AlignedSPFPass, e.SPFResults || [])),
)
}),
evaluations.length === 0 ? dom.tr(dom.td(attr({colspan: '14'}), 'No evaluations.')) : [],