2

I have a private postfix server that uses dovecot sasl to optionally authenticate submission clients, and I'm trying to set it up to also accept client certificates to allow it to act as a relay host for certain specific origin servers.

I've got it mostly working, but ran into a hiccup where the opendkim milter doesn't recognize the certificate-authenticated relay connections as internal or authenticated, so it does not add a DKIM signature.

in main.cf:

milter_default_action = accept
smtpd_milters = inet:opendkim:8891
non_smtpd_milters = inet:opendkim:8891

smtpd_tls_CAfile = /path/to/private-ca-cert.pem
tls_append_default_CA = no
smtpd_recipient_restrictions = permit_mynetworks,permit_sasl_authenticated,permit_tls_all_clientcerts,reject_unauth_destination
smtpd_relay_restrictions = permit_mynetworks,permit_sasl_authenticated,permit_tls_all_clientcerts,reject_unauth_destination

and in master.cf under submission/inet:

-o smtpd_client_restrictions=permit_sasl_authenticated,permit_tls_all_clientcerts,reject
-o smtpd_tls_ask_ccert=yes

All of the above is working, and connections that present a valid cert signed by my private CA are allowed relay access.

However, these relayed emails are not signed by opendkim - instead, the opendkim milter logs this:

external host [host.that.connected.with.cert] attempted to send as [mydomain.com]

I know I could use the opendkim ExternalIgnoreList config, but since these hosts are on dynamic IPs, that's not an ideal solution, and I'm looking for a solution that accepts any host just like it accepts mail sent through a SASL-authenticated submission connection from any mail client.

I believe I've traced it to the {auth_authen} macro that the milter uses to determine whether the mail came from an authenticated connection... postfix is only setting that macro to the sasl username.

Is there any way I can expand the functionality of {auth_authen} or add a new macro (using opendkim's MacroList config) in order to indicate that a valid client certificate was used?

jcsanyi
  • 123
  • 5
  • the smtp server is also open on port 25 to accept regular incoming mail for my domain - so opendkim is seeing both incoming and outgoing mail, and deciding whether to sign or verify. – jcsanyi Apr 17 '21 at 04:56

1 Answers1

2

Because you only accept authenticated mail anyway, you do not need to pass information about which method was used to opendkim - only the (boolean) distinction between ports that have mandatory authentication (sign) and ports that do not offer authentication (verify).

You can set -o milter_macro_daemon_name=whatever in master.cf to let opendkim know which mail should be signed. That macro would otherwise default to $myhostname, but by using (arbitrary, opendkim does not care) different values for verifying-only and for mandatory-auth ports you can distinguish them.

Docs recommend using ORIGINATING and VERIFYING to make it super obvious. MacroList in your opendkim.conf can then check whether daemon_name is equal to whatever you set.

anx
  • 6,875
  • 4
  • 22
  • 45
  • Interesting - so by overriding `daemon_name` to a known value on my submission port (which is always authenticated via either sasl or client certs), I can then check for that value in opendkim using `MacroList`.... I can leave the rest of the configs unchanged, and it'll still properly sign localhost-originating mail, or mail that comes in on port 25 with sasl auth. – jcsanyi Apr 17 '21 at 05:00
  • Could I also set something like `-o milter_macro_auth_authen=yes` on my submission port and not need any changes to the opendkim config? – jcsanyi Apr 17 '21 at 05:04
  • Sorry, I do not remember why I did not do that in a similar case, I *think* any otherwise unused macro works, though. In any case, drop a comment for the poor soul who later has to read this config and figure out why someone manually changed macro names. – anx Apr 17 '21 at 05:07
  • I got this to work using `daemon_name`, but I had to use the `MTA` opendkim config, not `MacroList`. It looks like daemon_name is treated specially, and matched against the `MTA` config... but not included in the more general `MacroList` check. – jcsanyi Apr 17 '21 at 06:12