Storing DKIM information in the database#308
Conversation
rimas-kudelis
left a comment
There was a problem hiding this comment.
In addition to stuff below:
- since this doesn't come with any UI, maybe it should wait until we get rid of the default admin panel?
- The table structure doesn't seem to protect against having duplicate records for the same domain, or having none. What happens in these cases?
| DKIM_CANON = relaxed | ||
| DKIM_STRICT = 0 | ||
| DKIM_TIMESTAMPS = 0 |
There was a problem hiding this comment.
Why are these hardcoded, especially DKIM_CANON which has its own column in the database?
Also, I don't like how you didn't define DKIM_SIGN_HEADERS on purpose, but kept the database column. IMO, a commented out macro with an explanation about why it's been commented out would fit here better.
There was a problem hiding this comment.
By the way, here's my DKIM_SIGN_HEADERS:
DKIM_SIGN_HEADERS = +Content-Type:+MIME-Version:+Date:+Message-ID:+To:+Subject:+From:+Sender:=Reply-To:+Cc:+Content-ID:+Content-Description:=Resent-Date:=Resent-From:=Resent-Sender:=Resent-To:=Resent-Cc:=Resent-Message-ID:+In-Reply-To:+References:=List-Id:=List-Help:=List-Unsubscribe:=List-Subscribe:=List-Post:=List-Owner:=List-Archive
I think it's been working nicely for me for quite a while now.
There was a problem hiding this comment.
Is there a reason to not use the default which conforms to RFC?
There was a problem hiding this comment.
I don't really remember what problem I was solving by editing these values myself. It's probably what I said here.
There was a problem hiding this comment.
Mainly it's as it is to start a discussion on what is needed/wanted.
We hard code them at work because we have a lot of email accounts and reducing sql look ups is never a bad thing (you can set the canon via sql if you really wanted, hence it's there).
Same with DKIM sign headers, those are left to Exims defaults but if people want to change them per domain they can?
You have to remember there was no activity on this repo, I had no idea what direction you wanted to go with it.
The table structure doesn't seem to protect against having duplicate records for the same domain, or having none. What happens in these cases?
Why would it? How do you rotate secrets if you just delete the old one? Any mail in transit that hasn't caught up with the new key in the dns would fail?
As for having no key, it would fail. That's a personal preference, in todays world of email not having a dkim key and trying to send email is kind of pointless.
You could do something like
DKIM_SELECTOR = ${lookup mysql {SELECT d.selector FROM dkim d JOIN domains dom ON d.domain_id = dom.domain_id WHERE dom.domain = '${quote_mysql:DKIM_DOMAIN}' AND d.enabled = 1}{$value}{}}
DKIM_PRIVATE_KEY = ${lookup mysql {SELECT d.private_key FROM dkim d JOIN domains dom ON d.domain_id = dom.domain_id WHERE dom.domain = '${quote_mysql:DKIM_DOMAIN}' AND d.enabled = 1}{$value}{}}
And have in the transports have something that looks something like:
dkim_selector = ${if def:DKIM_SELECTOR {DKIM_SELECTOR}{}}
dkim_private_key = ${if def:DKIM_PRIVATE_KEY {DKIM_PRIVATE_KEY}{}}
Which wouldn't sign the email if it didn't have a key (in theory, currently untested)
There was a problem hiding this comment.
How do you rotate the public keys on your DNS servers? Automaded/Manual?
There was a problem hiding this comment.
Fully automated (thousands of domains would take days!), every 3 months a new one gets generated, dns runs off a sql backend (pdns) so it's dead simple. Generate key, update the dns sql and add the new key to email database. A week later the old key gets deleted. The old key is kept so dns propagation isn't an issue.
There was a problem hiding this comment.
Forgot to mention, the keys get a new selector when they are rotated so it would be jan2026 for one and the new one would be jun2026 for example.
| DKIM_TIMESTAMPS = 0 | ||
|
|
||
| # Disable DKIM verification for incoming mail (since we don't want to verify inbound) | ||
| DKIM_VERIFY_DOMAIN = ${if match_domain{$sender_address_domain}{+local_domains}{0}{1}} |
There was a problem hiding this comment.
Is this a new macro? I don't see it being used on Bookworm.
There was a problem hiding this comment.
Didn't actually mean to leave that in there..
Was working on an acl that uses it
acl_smtp_dkim:
# Only verify external senders
condition = ${if eq {DKIM_VERIFY_DOMAIN}{1}}
# If verification fails, set a variable
warn
dkim_status = fail
set acl_m_dkim_fail = yes
log_message = DKIM failure from $sender_address_domain: $dkim_verify_reason
# Accept otherwise
accept
But exim does (at least on trixie) have this on the check_rcpt acl
.ifdef DISABLE_DKIM_VERIFY
So it seemed kinda pointless
There was a problem hiding this comment.
If we ship with this functionality, then this file should go to docs/setup/migrations, and if not, maybe all of this could just go to the Wiki?
There was a problem hiding this comment.
I think in 2026 it needs some kind of dkim in the core vexim setup, DKIM has been around since the mid 00s.
DKIM keys stored in the vexim database, been running this for years (been a couple of sql updates over the years). Forgot to update the issue I posted almost 10 years ago about it.
Left dkim_sign_headers up to Exims standard signing because despite many hours of testing, could never get a stable dkim result with it.. Exims built in has worked fine for it (it's a busy mailserver).
The SQL is basic but leaves in the option to add sign_headers if you so want.
Cf #97