diff --git a/machines/ns1/configuration.nix b/machines/ns1/configuration.nix index e3f268c..32cc1fc 100644 --- a/machines/ns1/configuration.nix +++ b/machines/ns1/configuration.nix @@ -58,8 +58,8 @@ in # ACME DNS-01, dedicated mx1 key. A *separate* TSIG key (acme_mx1) that only # mx1 holds, rendered from the shared secret (generator dns-acme-mx1-secret, # imported above). acl_acme_mx1 scopes it to TXT updates at exactly - # _acme-challenge.mx1 and _acme-challenge.mta-sts (the mail cert and its - # MTA-STS SAN), and it is attached only to the cnx.email zone below — so this + # _acme-challenge.{mx1,mta-sts,mail} (the mail cert and its MTA-STS + client- + # alias SANs), and it is attached only to the cnx.email zone below — so this # credential can write nothing but mx1's own cert challenges. clan.core.vars.generators.dns-acme-mx1-knot = { files."acme.conf" = { @@ -99,6 +99,7 @@ in "update-owner-name" = [ "_acme-challenge.mx1" "_acme-challenge.mta-sts" + "_acme-challenge.mail" ]; } ]; diff --git a/modules/dns/zones/cnx.email.zone b/modules/dns/zones/cnx.email.zone index 5d93dd0..c6d37bb 100644 --- a/modules/dns/zones/cnx.email.zone +++ b/modules/dns/zones/cnx.email.zone @@ -14,6 +14,10 @@ $TTL 3600 ; ---- Mail ---- mx1 IN A 5.223.65.38 mx1 IN AAAA 2a01:4ff:2f0:1963::1 +; Client-facing alias for IMAP/submission (Thunderbird etc.); the cert carries +; mail.cnx.email as a SAN. The MX must never point here (CNAMEs are illegal MX +; targets) — server-to-server delivery and DANE stay on mx1.cnx.email. +mail IN CNAME mx1.cnx.email. @ IN MX 10 mx1.cnx.email. @ IN TXT "v=spf1 mx -all" _dmarc IN TXT "v=DMARC1; p=quarantine; rua=mailto:postmaster@cnx.email" diff --git a/modules/mail.nix b/modules/mail.nix index 9b1f4e2..2b55389 100644 --- a/modules/mail.nix +++ b/modules/mail.nix @@ -19,6 +19,9 @@ let hosts = import ./hosts.nix; fqdn = "mx1.cnx.email"; mtaStsHost = "mta-sts.cnx.email"; + # Client-facing alias (CNAME -> mx1) so Thunderbird etc. can use mail.cnx.email + # for submission/IMAP; added as a cert SAN so TLS validates against that name. + clientHost = "mail.cnx.email"; # MTA-STS policy served at https://mta-sts.cnx.email/.well-known/mta-sts.txt. # enforce = a sending MTA that fetched this must use a valid, MX-matching TLS @@ -94,7 +97,10 @@ in # web server and no inbound HTTP needed, so port 80 stays closed. Add the # MTA-STS host as a SAN so the one cert also covers the policy endpoint. certificateScheme = "acme"; - certificateDomains = [ mtaStsHost ]; + certificateDomains = [ + mtaStsHost + clientHost + ]; dkimSelector = "mail"; };