Re: [exim-dev] DKIM Signing and renewing DKIM certificates

Αρχική Σελίδα
Delete this message
Reply to this message
Συντάκτης: Mark Elkins
Ημερομηνία:  
Προς: Exim Dev
Αντικείμενο: Re: [exim-dev] DKIM Signing and renewing DKIM certificates
Thank you for the comprehensive reply. OK - so this tells me that
receiving MTA's will look for a DKIM record with correct selector (taken
from the received email) and simply use that. There can therefore only
ever be one record with that selector (I re-watched Highlander last
night - There can only be One). If there are multiple, the MTA may not
check that any one of the replies works (as opposed to DNSSEC - where
any one chain that works means Success).

Thus one should use a selector which must be unique in the DNS to
specify the Key that the originating/signing MTA used.

So the Keys should change once a month (as an example of good key
management).

Does Exim know the current month? Is there a Variable for the current
month in Exim? (Can I run the unix 'date' command to get the month?)

Could I then use something like...

dkim_selector = $Month

(I'd assume that EXIM works on UTC time, does it?)

If so - then I simply create new DKIM Keys for the domain say on the
24th of every month for the following month (and put the necessary into
the DNS) and then around the 8th of the month, do a clean-up of old
information. Just need to check that any new domains that appear after
the 24th are appropriately taken care of, such as, create this and next
months DKIM keys.

dkim_selector = $Month
... is simply way more readable than....
dkim_selector = ${sg{${sg{${lookup
{$dkim_domain}cdb{CDBMAILTABLES/dkim.selectors.hermes.cdb}
{$value}{OOPS}}}{\N=\w+\N}{}}}{\N\s+\N}{:}}

Having a selector of YYYYMM would also work for me - and provide a
better History.

ps - it was a cut'n'paste plus anticipation that put a double '_' into
my previous email. I only really have one '_'.

On 2020/11/01 01:10, Phil Pennock via Exim-dev wrote:
> On 2020-10-31 at 18:34 +0200, Mark Elkins via Exim-dev wrote:
>> [quoting:]
>> Of course, when you change your DKIM key pair, the public key in the DKIM
>> record needs to be changed as well.
>
> That is very poorly phrased.
>
> One selector corresponds to one DNS record. There is no way to safely
> change the public key in a given selector's DNS record: there will
> always be races.
>
> If you wish to change the public key, then you use a new selector.
>
> Anyone advocating for changing which key one selector corresponds to,
> without a major downtime/rest-period between values, does not understand
> distributed caching or distributed coherency. If you read such advice,
> run away from it.
>
> You pre-publish the new selector and wait for at least the zone SOA's
> TTL field to expire: this is because if you use a predictable naming
> scheme, then someone could pre-populate caches with the NXDOMAIN for
> your new record, so you need to wait for negative cache entries to
> expire.
>
> Once your public key has been in DNS, in the new selector, for longer
> than the previous update's SOA record's TTL, it's safe to start using.
>
> You then need to wait for long enough for all mails stuck in queues
> elsewhere to make their way through, for the validation to happen.
>
>>     create the domain.pem & domain.pub parts, create and publish the
>>     DKIM DNS record with the PUB data as "mail.__domainkey" (where
>>     "mail" is my selector).

>
> No, single underscore for "_domainkey", not two.
>
> [snip system based upon poorly worded advice]
>> Is this fine?
>
> No.
>
>> If I have to have a different selector for a new DKIM key pair - and I'm
>> signing about 40 domains - is there a suggested way to manage the currently
>> hard coded line in exim.conf of:-
>
> There are two fundamental approaches to rotating selectors:
>
> 1. Date-stamp
> 2. Set of candidates (typically three)
>
>
> ### Date-stamp
>
> I use the date-stamp approach: if this were coming with a From: of my
> spodhuis.org domain, it would be dual-signed with the "d202008" and
> "d202008e2" selectors (RSA, Ed25519). A week from today, as the first
> Saturday of "every three months", I have a calendar reminder to go ahead
> and generate the d202011 family of keys for my domains, and publish them
> in DNS. Then on Monday, I should go ahead and switch the selector used
> by Exim for signing email.
>
> As a very complicated example, the SMTP Transport in Exim has:
>
>    dkim_domain   = ${domain:$acl_m_dkim_sender_address}
>    # CDB has: domain.tld: dYYYYMM=rsa dYYYYMMe2=ed25519
>    dkim_selector = ${sg{${sg{${lookup {$dkim_domain}cdb{CDBMAILTABLES/dkim.selectors.hermes.cdb} {$value}{OOPS}}}{\N=\w+\N}{}}}{\N\s+\N}{:}}
>    dkim_private_key = ${if eq{$dkim_selector}{OOPS}{false}{DKKEYDIR/${extract{$dkim_selector}{${lookup {$dkim_domain}cdb{CDBMAILTABLES/dkim.selectors.hermes.cdb}}}}.private.$dkim_selector.$dkim_domain}}
>    dkim_strict   = ${if eq{$dkim_selector}{OOPS}{0}{1}}
>    dkim_sign_headers = SPODHUIS_DKIM_SIGNHEADERS
> # timestamps are Exim 4.92+; seconds to add to current time; 2 weeks == 1209600 seconds
>    dkim_timestamps = 1209600

>
> This is way overkill for you, but that's about as complicated as it
> gets, and that's handling extracting two different selectors from the
> value of a CDB lookup. Very _very_ few people dual-sign with two
> algorithms. You can write something simpler.
>
>
> ### Set of candidates
>
> I don't use this, but you see this used by mail service providers who
> provide mail-sending for various companies, where they want to be able
> to DKIM sign for their customers.
>
> The MSP declares that three selectors may exist; to avoid the risk of
> collisions, the sensible ones use a prefix which varies by MSP. Thus
> Fastmail have "fm1", "fm2", "fm3". Mailchimp uses "k1", "k2", "k3".
> (Some providers willing to vary selector per-customer let the customer
> choose the selectors).
>
> Assume "x1"/"x2"/"x3":
>
>   1. Your customer sets up CNAMEs for all three inside their domain, so
>      that they have to touch DNS once, to set up the CNAMEs, then never
>      have to change DNS again.  You can rotate freely without having to
>      coordinate with different DNS zones.
>   2. You start with x1.  You publish it.  You use s=x1 in the DKIM
>      signatures.  Leave x1/x2 empty, perhaps a TXT record `""`.  As long
>      as no mails are sent using those selectors, no validators will look
>      them up in DNS, so you don't need to care.  Just have something so
>      that DNS control panels which check for "something exists for this
>      CNAME" won't make life hard for your customers.
>   3. Later, you publish x2 in DNS.  After a TTL wait, you can start using
>      s=x2 in signatures.
>   4. You leave x1 in DNS.  Let older signatures continue to validate.
>   5. Somewhere between "some time later" and "when you publish x3", you
>      stop publishing x1 in DNS.  Signatures made with that will no longer
>      validate.
>   6. You publish x3.  You unpublish x1 if it's still published.  Follow
>      the usual dance.
>   7. After x3, circle back around to x1.

>
> The three selectors form a ring, which conceptually have pointers:
> "previous", "current", "next". Only "current" has to exist normally;
> "previous" should be left existing for some time afterwards. (Maybe two
> weeks, maybe three months, it depends upon your rotation frequency).
> "next" should exist for a DNS zone SOA TTL period, or longer, before it
> becomes the current.
>
>
> You should not ever try to change the key which an actively used
> selector is pointing to. The ring approach provides a compromise to
> avoid the number of changes needed in DNS: there are static CNAMEs from
> the various zones to your published records. The date-stamped approach
> means that things never expire, and if someone years later tries to
> figure out "wait, why doesn't this signature validate" on a leaked
> email, they can see the datestamp and know that it was probably
> withdrawn.
>
> -Phil
>


--
Mark James ELKINS  -  Posix Systems - (South) Africa
mje@???       Tel: +27.826010496 <tel:+27826010496>
For fast, reliable, low cost Internet in ZA: https://ftth.posix.co.za
<https://ftth.posix.co.za>