When adding a new domain, only set up RSA DKIM keys, not ed25519.

We'll need RSA DKIM keys for a long time to come because many systems don't
support ed25519 DKIM signatures. We've been adding both types of keys when
adding a new domain, and adding both two DKIM signatures to outgoing messages.
This works fine in practice, other mail servers are correctly ignoring the
ed25519 signature if they don't understand it. Unfortunately, it causess noise
in DMARC reports: Systems will warn that a DKIM check failed.  Sometimes with a
vague message about a missing key, or a 0-bit key. Sometimes they leave the
selector out of the report, making it hard to understand what's going on.  This
causes postmasters to investigate because they think something is wrong, only
to eventually find out it's all fine. So we're causing needless chores for
postmasters. By having only an RSA DKIM signature, we skip that noise. This
also reduces the number of DNS records postmasters have to add for a domain.

The small ed25519 DKIM DNS TXT records would make them preferrable over the
long multi-string RSA DKIM DNS TXT records (which are often hard to add
correctly through DNS operator web interfaces), but as mentioned, we'll have to
add the RSA DKIM keys anyway.

Another reason why RSA keys _may_ be preferrable over ed25519 keys is that with
RSA, signing is more computationally expensive than verifying, while it's the
other way around for ed25519 keys.

Admins can always add an ed25519 DKIM key to their domain. And we can always
switch back to adding them to new domains by default in the future.

For issue #299.
This commit is contained in:
Mechiel Lukkien 2025-03-07 10:51:53 +01:00
parent d78aa9d1d7
commit 2fc75b5b7b
No known key found for this signature in database
2 changed files with 2 additions and 23 deletions

View File

@ -192,14 +192,6 @@ func MakeDomainConfig(ctx context.Context, domain, hostname dns.Domain, accountN
return nil
}
addEd25519 := func(name string) error {
key, err := MakeDKIMEd25519Key(dns.Domain{ASCII: name}, domain)
if err != nil {
return fmt.Errorf("making dkim ed25519 private key: %s", err)
}
return addSelector("ed25519", name, key)
}
addRSA := func(name string) error {
key, err := MakeDKIMRSAKey(dns.Domain{ASCII: name}, domain)
if err != nil {
@ -208,23 +200,17 @@ func MakeDomainConfig(ctx context.Context, domain, hostname dns.Domain, accountN
return addSelector("rsa2048", name, key)
}
if err := addEd25519(year + "a"); err != nil {
if err := addRSA(year + "a"); err != nil {
return config.Domain{}, nil, err
}
if err := addRSA(year + "b"); err != nil {
return config.Domain{}, nil, err
}
if err := addEd25519(year + "c"); err != nil {
return config.Domain{}, nil, err
}
if err := addRSA(year + "d"); err != nil {
return config.Domain{}, nil, err
}
// We sign with the first two. In case they are misused, the switch to the other
// keys is easy, just change the config. Operators should make the public key field
// of the misused keys empty in the DNS records to disable the misused keys.
confDKIM.Sign = []string{year + "a", year + "b"}
confDKIM.Sign = []string{year + "a"}
confDomain := config.Domain{
ClientSettingsDomain: "mail." + domain.Name(),

View File

@ -1046,12 +1046,7 @@ EOF
defer wg.Done()
var missing []string
var haveEd25519 bool
for sel, selc := range domConf.DKIM.Selectors {
if _, ok := selc.Key.(ed25519.PrivateKey); ok {
haveEd25519 = true
}
_, record, txt, _, err := dkim.Lookup(ctx, log.Logger, resolver, selc.Domain, domain)
if err != nil {
missing = append(missing, sel)
@ -1090,8 +1085,6 @@ EOF
}
if len(domConf.DKIM.Selectors) == 0 {
addf(&r.DKIM.Errors, "No DKIM configuration, add a key to the configuration file, and instructions for DNS records will appear here.")
} else if !haveEd25519 {
addf(&r.DKIM.Warnings, "Consider adding an ed25519 key: the keys are smaller, the cryptography faster and more modern.")
}
instr := ""
for _, sel := range missing {