Issues to fix email breakages caused by upgrades (regression)

Hello yunohost devs.

I attempt to triage and formulate the issues that are the root cause(s) for my problems with the email system that surfaced while upgrading from Yunohost 11 to 12. And for which I also found some other prior reports about.

I currently suspect things may boil down to two issues and causes, but as email is not an easy topic for me I hope you can help to nail down proper fixes, to continue yunohost’s fabulous “just works” email setup.

The problems I see:

  • Email reception (local delivery) now fails for all secondary-domains, producing error “loops back to myself”, unless feature.mail_in is enabled for the main-domain.
  • Emails are not sent to the current external MX of a configured (main/secondary) domain when mail_in and mail_out are both disabled for that domain (e.g. installations with some domains configured just for “webserver-only” usage.)

Presumed Causes:

  1. /etc/postfix/main.cf switched from using LDAP to using the file /etc/postfix/virtual-mailbox-domains.
    The file now only lists the main-domain if it has feature.mail_in enabled, it could be that the LDAP may always (have) contain(ed) the main-domain and thus using LDAP had kept the local mailboxes working even if feature.mail_in was disabled for the main-domain.

  2. The /etc/dnsmasq.d/<main-domain>file always redirects to localhost unconditionally.
    But dnsmasq shouldn’t also unconditinally override the email records SPF (always honor legitimately configured other smtp-out servers) nor MX (only override if feature.mail_in is ‘on’).

It seems:

  1. Enabling mail_in for the main-domain is at least a workaround for 1) , so just always adding the main-domain to the virtual-mailbox-domains file may solve the problem, all the while still allowing to properly disable feature.mail_in for the actual main-domain (without breaking other domains). However, it could also be that the proper fix might be to always add the main-domain e.g. to ‘mydestinations’ instead, or something else. (I don’t really have a clue here, not sure what exactly changed since using the domain list from LDAP.)

  2. The DNS response from dnsmasq that unconditionally points to the local Yunohost is what causes the actual “loop error” when feature.mail_in is disabled, but emails should rather get sent and delivered to the actual MX configured and resolved from the global DNS in this case.

The original context where I hit the email problems: Spinning up a test install of my running server to experiment, but getting none of the email notifications, and noticing that every change in the settings seemed to produce a new combination of problems.

General idea/expectation: global DNS configures routing, mail_in/out configures local acceptance.

Now I went through the combinations (posting the listing later), found two additional issues, and think I can describe the four issues a bit more precisely.

  1. Issue A: Dnsmasq should never auto-override valid “production” MX/SPF/DMARC email-records from the public DNS. However, as a safety measure, it should still generate local overrides (even if mail_in and/or out is disabled) until the related DNS diagnosis items pass (or were manually checked to be good and the failing “diagnosis” set to ‘ignored’), i.e. set local overrides to direct and accept local domain emails at the localhost server as long as the own DKIM key and SPF IP is not in the public DNS records yet, and thus no suitable “production” configuration exists. This is a safeguard to prevent locally auto-generated notification emails to trigger blacklisting of the own IP upon their external or local MX reception while they would still fail the email spam-checks (without local overrides). (Adding commented-out configuration suggestions, even with “production” DNS settings in place, would still be good: To document/show how to persist ‘mx-host …’ records etc. in /etc/dnsmasq.d/, i.e. to make overrides readily available for local-only email testing or even for authoritative nameserver configurations. YNH-Diagnosis may detect the authoritative DNS case by looking at NS records, and point to, or even auto-uncomment, the generated /etc/dnsmasq.d/ settings in that specific case.)
  2. Issue B: The imap maildir for users with a secondary-domain address (in /var/mail/) is only created upon first email reception, and only functional if mail_in is ‘on’ for their secondary-domain and the main-domain. (->send initial “welcome” emails?)
  3. Issue C: “overreceptive” local maildir? Once a maildir is created, it sometimes continues to receive email for domains that have their mail_in setting disabled.
  4. Issue D: Sending an email to <user>@localhost completely broke all further dovecot maildir delivery. It corrupted the maildir unter /var/spool/mail/, /var/log/mail.log saying: ‘renamed bogus “/var/mail/” into “/var/mail/BOGUS..”’ storing the email in a newly created a mbox file instead (which is not recongnized by dovecot).

(list continued in posts below)

Issue D was seen by testing for a possible idea to reject emails to non-existing local users (instead of producing “loop errors”) by expanding local emails (without any @domain) to its own domain @localhost instead of using the @main-domain also for local emails. The triggered /var/mail/BOGUS...<random> corruption, though, was already seen in [Solved] Mail loops back to myself - probably related to 12.1 upgrade - #2 by peer so maybe @peer knows how that BOGUS.alice.f4A5 maildir came to be?


It seems devs already foresaw parts of the problems when committing the related code in: [fix] Send mail to external mailbox of a managed domain by zamentur · Pull Request #2075 · YunoHost/yunohost · GitHub
(The corresponding issue isn’t closed yet either: Error sending mail from an internal domain to another domain · Issue #2275 · YunoHost/issues · GitHub)

The problematic mx-host override records actually already get removed from dnsmasq if feature.mail_in is disabled. (Only the SPF override is never removed.) However, to really avoid the problems, all generated email records in the dnsmasq config must probably be completely removed or commented-out (if the public SPF+DKIM config is correct and allows the local server-IP to send), unless that very specific use-case is explicitly configured or precisely detected for sure:

@ljf:
here we have our dnsmasq lying […]
i think [the SPF record] is only here for the usecase where DNSmasq is configured as the authority DNS server… [and still missing DMARC and DKIM]

So we can say, the “authoritatve DNS” mode

  • needs more records
  • needs to be permanently configurable (adjustable SPF/DMARC etc.)
  • must not override anything when external authoritative DNS is used

That seems to require that the use-case is either precisely detected (diagnosis?) or configured very precisely (auto/manual).

A minimal viable support for the “authoritative DNS” usecase might consist of just:

  • yunohost tools regen-conf? to never overwrite any modified /etc/dnsmasq.d/* files (persistance)
  • dnsmasq never returning private LAN or loopback IPs to external requests (only for localhost/lan)
  • only generate configs with MX, SPF, DMARC and DKIM commented out (especially disable the current default MX override)
    Diagnosis will then detect the missing MX etc. and request to configure the (self-hosted) DNS, which is then as simple as enabling the records.
    (Or, generate the records dynamicaly if a domains’s name server record (NS) points to a local yunohost’s public IP?)

So, the question for you to solve issue A: Is there something standing against a first simple fix here, to just remove the MX and SPF records from the current /etc/dnsmasq.d/ generation, to never have any (non-authoritative) dnsmasq email overrides by default? (They just seem to prepare for email problems.)

Removing the default email overrides definetely seems like a very simple and central fix for several problem cases below.

The only drawback I see, would seem insignificant for current “authoritative DNS” users: They would need to also make their MX config explicit (but probably already did that anyway, together with their SPF,DKIM,DMARC configuration, any authoritative DNS config really). While the current default MX and SPF override cause email bugs lurking for every user.

I think an “overreceptive” local maildir override option could actually be a positive feature:
It could avoid sending out emails to accounts set up on the local yunohost, but not existing at the external MX. It could allow for “local first” email between local accounts, and only send out to the external MX for users unknown locally.
But the current MX override (loop to self errors) may actually prevent/cover up part of that feature.


These are the use-cases I had in mind with my tests below:

  • external email
    • email_in disabled for domains
    • email_out enabled for notifications etc. (and allowance added to global SPF)
      The “overreceptive” local maildirs might collect admin emails in a local mailbox, and avoid sending out email to “yunohost only” accounts, but users may need to disable this “feature” to set up and use external mailboxes.
  • backup yunohost
    • accounts must be synced (import/export, backup, whatever)
    • email_in and out enabled and set up completely for domains, to start working as soon as the MX is switched over in the DNS
    • Unsure if preconfiguring a local MX override to avoid the DNS update propagation time would make sense here. The “overreceptive” local maildirs could be enough to make client requests work already before the DNS MX update propagates to this server? (Emails enter local IMAP.)
  • experimental yunohost (test installation/replication)
    • Mostly identical configuration to main server, but not necesarrily configured with all the same apps and users.
    • MX pointing to main server, so if not in need to test local email delivery, mail_in disabled for the local domains in order to make all email going to the admin’s usual IMAP inbox at main server.
      The “overreceptive” local maildirs seem a problem here. Because email to root@main-domain does not reach the admin at the main-domain server.

However, unfortunately the current results from testing the available combinations of options don’t seem useful for any of the use cases.

The MX override seems a central problem, but I hope my experiments can help you to identify the further causes of the problems, and thus find the simplest true solutions in the implementation of underlying options.

Testing Results:

I. Global DNS settings “production”: main-domain MX set to public ynh IP, and secondary-domain MX pointing elswhere)

with mail_in settings: main-domain on, secondary-domain on

→ email to main-domain should be delivered locally
(+) delivered to main-domain mailbox

→ email to enabled secondary-domain should be delivered to external MX (only optionally to existing local mailbox)
(-) delivered to existing user
(-) not sent to extrnal MX (“user unknown”)
Current behavior is not the optionally desireable “to local mailbox if one exists” either.

with mail_in settings: main-domain off, secondary-domain on

→ email to mail_in disabled main-domain should be rejected (optionally accept locally to existing local mailbox)
(+) email to the main-domain and local emails (without @domain) fail with “local loop”

Though, it’s currently not ok to reject, because the main-domain is used for local email. It will only become ok to reject, once local email (not using any domain, or @localhost) works independent of an enabled main-domain, i.e. after according adaptions.

The loop error message may or may not be helpful/correct (as either redirecting the public primary-domain MX record, or enabling mail_in can solve the problem).

Solution?: Expansion of local emails to @localhost instead of the main-domain?
That could likely also distinguish between local “accept/unknown” and a main-domain MX loop. It would have to make sure to never send out any email from @localhost, and that all domains still use the main-domain as email-hostname (“ehlo”) when sending (to match the IPs rDNS).

Note, current “Issue D” (@localhost emails breaking inboxes).

→ email to enabled secondary-domain should go to external MX (optionally to existing local mailbox)
(-) email to existing user/alias fails “local loop”
(-) email to unknown user/alias is bounced “unknown” (and the following mailer-daemon message to the local sender fails with “local loop”, as above)

(Loop probably fixable by issue A removing mx-host lines from dnsmasq.)
Current behavior is not the optionally desireable “to local mailbox if one exists” either.

with mail_in settings: main-domain off, secondary-domain off

→ email sent to disabled secondary-domain should go to external MX
(-) email to existing username/alias addresses fails “local loop”
(Issue C: “overreceptive” local maildir?)
(+) email to non-existing username/alias address gets sent to MX


II. Global DNS settings “spare”: main-domain MX and secondary-domain MX pointing elswhere)
[separate test install of the main-domain server]

with mail_in settings: main-domain on, secondary-domain on

→ email to main-domain should be delivered to external MX (optionally to existing local mailbox)
(-) delivered to main-domain mailbox

→ email to enabled secondary-domain should be delivered to external MX (optionally to existing local mailbox)
(-) delivered to existing user
(-) not sent to external MX (“user unknown”)
Current behavior is not the optionally desireable “to local mailbox if one exists” either.

with mail_in settings: main-domain off, secondary-domain on

→ local delivery to disabled main-domain should go to external MX,
(-) local emails (without domain) and to the main-domain fail “local loop”

(Loop not fixable by issue A removing mx-host lines from dnsmasq.)
(Because locally, the external MX of the main-domain (i.e. the main-domain) will still resolve to local IPs [on a separate test install of the main-domain server])

Solution?: Expansion of local emails to @localhost instead of the main-domain? To have those work locally and independent from the main-domain.
Also not possible: Explicitly overriding the MX with dnsmasq also in this very special case (MX with local domain name but foreign public IP), letting it point to the external MX by referencing the IPs rDNS result? becuse it would (ideally) be the same domain.

Possibly?: A way to disable the webserver for the main-domain and with that also the dnsmasq domain->IP override.

→ email to enabled secondary-domain should go to external MX (only optionally to existing local mailbox), local delivery only once corresponding MX propagated
(-) email to known user/alias succeeds (delivered to local inbox)
(Issue C: “overreceptive” local maildir?)
(-) email to unknown user/alias is bounced “unknown” (and the following mailer-daemon info-reply to the local sender fails with “local loop”, as above)

(Loop probably fixable by issue A removing mx-host lines from dnsmasq.)
Current behavior is not the optionally desireable “to local mailbox if one exists” either.

with mail_in settings: main-domain off, secondary-domain off

→ email sent to disabled secondary-domain should go to external MX
(-) email to existing username/alias addresses fails “local loop”
This happens even though there is no dnsmasq override with mail_in off, and the secondary-domain does not have a MX that resolves to a local IP, they are external servers!
(Issue C: “overreceptive” local maildir?)

(+) email to non-existing username/alias address gets sent to MX

BTW: Once the dovecot IMAP maildir became “bogus” (after some user/app has sent @localhost):
(+) email to existing username/alias addresses got sent to external MX
(+) email to non-existing username/alias address got sent to external MX
However, local delivery to the dovecot maildir @main-domain was broken.

Identified another root cause with simple solution, besides removing some harmful overrides!:slight_smile:

Issue E: Simply adapt Yunohost’s diagnosis to verify that the MX host in the DNS entry of configured domains is:
10 mx.domain.tld (instead of using just: domain.tld)

(The hostname mx.domain.tld is usually already resolvable by the public *.domain.tld wildcard.)

This will prevent the local dnsmasq IP overrides for configured website domains from messing with the public email routing configuration. (While still allowing for manual local /etc/dnsmasq.d/ overrides of the mx-host, if desired.)

A secondary yunohost (e.g. testing) install with the same domain.tld and maybe www.domain.tld configured (with local IP overrides), can still resolve the mx.domain.tld as pointing to the primary yunohost server (from the public DNS).

Just to say that i had not took time to read all for now, but we definitely need to transpose your work into tickets and prioritize in some way.

Thanks for leaving your message!
(And of course thanks for the implementation in the first place!)

I suspect the trivial fixes for “Issue A” and “Issue E” would really be fruitful to make good parts of the email feature configuration work. (And open up better testing of/dealing with the other issues listed, which might even turn out to be features after all.)

Random find, unsure and untested if it can solve the “issue D” of breaking mailboxes as “BOGUS”, but Postfix Virtual Domain Hosting Howto suggests:

virtual_mailbox_base = /var/mail/vhosts

Related, but unsure if an issue of its own or just a symptom only showing up in an undesired way due to above issues: “Subdomain emails are redirected to main domain ”.

I suspect that the permanent local-only SPF overrides in /etc/dnsmasq.d/*

  • mx a -all (for all domains, only SPF-allowing the localhost, nothing else)

will cause the local server to contribute to spam-reputatation/blacklisting other current and legit email sending IPs one has configured, e.g small r-pi server.

(Once the public MX points to the local yunohost, all incoming email from other domain locations are seen as non-legit.)

I think the local overrides should (only) exist for stand-alone operation as long as the diagnosis fails, and as a safeguard against local email notifications causing local and thus global spam reports for own IPs before the domain’s public DNS MX,SPF,DKIM and DMARC records have been adjusted. (by sending out local mail to external MX from a not yet published SPF IP, or when receiving local mail from unconfigured spf host)

(Edit: Adjusted “issue A” above.)