mjl- / mox

modern full-featured open source secure mail server for low-maintenance self-hosted email
https://www.xmox.nl
MIT License
3.55k stars 100 forks source link

Periodic DKIM key rotation to avoid non-repudiation #171

Open DanielG opened 4 months ago

DanielG commented 4 months ago

Hi Mechiel,

Thanks for working on mox! This is such a breath of fresh air in the email space I'm just completely flabbergasted :D

In reviewing it's feature set I did find one singular item on my requirements list missing: DKIM key rotation.

As I'm sure you're aware signing emails with keys published in the DNS means anyone can verify the "authenticity" of an email. This can however hurt users who did not intend to make binding statements. The solution for this problem is key rotation with short intervals, say on the order of a week (and optionally revealing the private keys after they are rotated out) see Matthew Green’s Ok Google: please publish your DKIM secret keys.

In Debian we have an existing implementation of the idea thanks to Ian Jackson's dkim-rotate (web) if you're interested and need some inspiration.

Is this something you could see mox do? I feel like the feature would fit in perfectly. Failing that is there an API I could use to automate key rotation using a cron job or some such?

Thanks, --Daniel

mjl- commented 4 months ago

Yes, automated DKIM rotation is welcome, including publishing the private keys after the last signatures have "expired".

DNS updates are a stumbling block. I saw you found issue #126 related to updating DNS records.

I would probably also like a DNS client library that can do a fresh authoritative lookup (ignoring any cache), and get the TTLs on the current authoritative records, and possibly the TTL we are currently getting through the cache. This would also be helpful during the DNS self-check admin pages. I don't know of a Go DNS client library that does this (certainly not including DNSSEC verification), so the prerequisites may be quite a bit of work. An alternative is a direct connection to the DNS master, perhaps with AXFR to fetch the latest current zone.

Mox will need new code for scheduling DNS changes. Like waiting for old TTLs/records to be expired after enabling new policies, and publishing old DKIM private keys after a while. To me that sounds like the easy part.

I'll put in a comment on issue #126 in a moment about updating DNS.

mjl- commented 4 months ago

Failing that is there an API I could use to automate key rotation using a cron job or some such?

Since mox v0.0.11, the webadmin has a UI to add/remove/update DKIM keys, which use relatively easy to use HTTP/JSON API calls:

$ go doc webadmin.Admin | grep -i dkim
func (Admin) DomainDKIMAdd(ctx context.Context, domainName, selector, algorithm, hash string, ...)
func (Admin) DomainDKIMRemove(ctx context.Context, domainName, selector string)
func (Admin) DomainDKIMSave(ctx context.Context, domainName string, selectors map[string]config.Selector, ...)

See http://localhost:1080/admin/#domains/localhost on a mox localserve.

The mox cli doesn't currently have commands to add/remove/update dkim keys for a domain, but it's on a todo list. The internal functionality exists (for the webadmin), the cli tool would just be frontend. Could bump it up on the list if you're interested in using it. Or you could give implementing it a try if you have time/interest in that. I'm happy to give pointers.