On 1/26/25 2:51 PM, Antonios Chariton (daknob) wrote:
Thanks for getting back to me so quickly! Here are some thoughts below:

On 26 Jan 2025, at 10:48, Philipp <phil...@bureaucracy.de> wrote:

I’ll either have to create a filter chain and sign every e-mail with every key, 
or rely on filter-dkimsign’s support for multiple “-d”s, which has its own 
issues[1]. Both of these options aren’t great.

[1]: This requires all domains to have the same private key, and does not work 
well with SRS as it fails to identify the correct domain and uses the first one 
always.

Why is the same private key for every domain a problem? I know
Mailprovider which simply cname the domainkey selector to one master.
Then sign with the host specific key and set the domain in the dkim
field according to the sender-domain.

Keep in mind that DKIM is designed to identify the sender's mailserver.
Also your server already needs to have access to all private keys. So
it's not a problem to share a private key for every domain.

It’s not a problem, and of course I can live with it, but I was just 
considering cryptographic key agility. It’s usually beneficial to rotate keys 
often, and I didn’t want to depend on one domain being too slow to update DNS 
to hold back all of the others. Interesting point on the CNAME, however, that 
would solve this issue. Reading the DKIM RFC I saw a TXT record would be 
needed, but probably CNAME works in real life despite not being standardized :)

Microsoft 365, Me and others are using CNAMEs to share DKIM keys, it definitely 
works.
 Giovanni

I don't get what you mean with does not work well with SRS. The SRS
implementation is completly independent from filters.

My scenario where it failed is the following: a mail server that has no local 
mailboxes, it receives mail and via an alias or virtual table it forwards it to a 
bunch of @gmail.com / @outlook.com / […] addresses depending on the user. So 
i...@example.org goes to these 5, secur...@example.org to the other 10, and so on. If 
someone from e.g. @gmail.com sends a message, then the various sender fields (From, 
Envelope-From, etc.) would be a mix of @gmail.com or <SRS>@example.org. What I 
expected to happen was for filter-dkimsign to identify the correct domain 
(example.org) and sign with that key, but instead unless I configured it with “-d 
gmail.com” (which is incorrect), it used the first domain given instead of that.

I guess this would be an issue with the dkimsign tool, however, and not 
OpenSMTPD.

Interestingly, I notice this mailing list, which does SRS, does not use DKIM. Perhaps 
it’s good enough to just do SPF for "forward-only” domains. In this case however, 
I’d need a different mail server for "forward-only”, and “send-only” / proper inbox 
domains, as I’d have to apply conditional filters for DKIM signing (don’t sign / sign).

Another alternative would be to outsource DKIM signing to rspamd, which is 
slightly smarter, but this requires using rspamd even when the server is an 
outgoing-only relay.

Ingress filtering might also be a good idea, but this depends an how
many users you have.

This is for a mail server with a bunch of service accounts, for example, for various 
in-host SMTP servers, applications, Prometheus alert-managers, etc. to use as a 
relay, so it can do SPF / DKIM / DMARC in a centralized space for a single domain. 
Each outgoing-only address gets a u...@example.org <mailto:u...@example.org>, 
and all incoming mail is rejected. As these are e-mails going to a single or a few 
recipients, there’s little need for outgoing spam filtering. Another use case would 
be a mail server only for outgoing transactional e-mails (password resets, etc.) from 
a noreply@.

- - - -

I figured out a solution for conditional filtering, but it’s a bit messy. 
Sending it here for future reference, in case anyone needs it:

You have your default “:: / 0.0.0.0” listener with no filters, which then uses a 
bunch of “match” statements to redirect to other listeners on “[::1]:2000, 
[::1]:2001, …” depending on the situation with “relay". Since you now have n 
listeners, you can apply n different “filter” statements. The public listener is 
configured as a relay, and then the message moves internally to the various places 
it has to go, until it arrives at the final instance. I don’t really like the 
configuration, but it’s an option if you really have to use it. It allows for the 
creation of internal pipelines of practically any complexity and number of stages.

Antonis

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to