stalwartlabs / mail-server

Secure & Modern All-in-One Mail Server (IMAP, JMAP, POP3, SMTP)
https://stalw.art
3.55k stars 136 forks source link

[enhancement]: SMTP Client Certificate (for the stalwart smtp client) #277

Open luzidd opened 4 months ago

luzidd commented 4 months ago

Which feature or improvement would you like to request?

Support for SMTP client certificates. This is the most secure and recommended way to connect an on premise SMTP Relay to Microsoft 365.

Code of Conduct

williamdes commented 4 months ago

That's funny I discussed about this with @mdecimus some days ago

Can you share more about your setup and how clients need to be configured

luzidd commented 3 months ago

My question is about using a client certificate for the stalwart smtp client, not about enforcing client certificate verification for smtp clients connecting to the stalwart smtp server. The latter could also be useful though.

Problem

I have services/clients in an internal network that should be able to send mails with smtp through Microsoft 365/Exchange Online without needing a mailbox per client (since every mailbox needs a license). The mails could be addressed to recipients of the organizations domain or external domains. These services could be something like Nextcloud, Gitlab/Gitea, Uptime Kuma or some custom PHP or Go app, you get the point.

The services should use stalwart as a relay to send the mails to Microsoft 365.

Solution

The clients use standard SMTP username & password authentication to connect to stalwart on ports 465/tcp (TLS), 587/tcp (STARTTLS) or 25/tcp. Stalwart has the M365 connector configured as a relay host.

Stalwart is configured with a domain that the organization has registered in Microsoft 365 and uses a TLS client certificate to connect to a Microsoft365 Connector.

This should be the way it is implemented in Postfix.

The stalwart server would present it's own client certificate to the M365 connector with a CN or SAN matching the mail domain that's configured in M365. The private key would of course be present on the stalwart server.

The stalwart config could look something like this:

[remote."relay".tls]
client-cert-path = "/opt/stalwart-mail/etc/certs/client-cert.pem"
client-key-path = "/opt/stalwart-mail/etc/certs/client-key.pem"
luzidd commented 3 months ago

Just FYI:

When using a client certificate on an smtp connector in M365, it is possible for the client (of M365, in this case stalwart) to use arbitrary sender addresses of the certificates domain because M365 implicitly trusts whoever uses the certificate. The address of the sender doesn't even need to exist on M365. So stalwart would enforce that nextcloud is using nextcloud@example.com as the FROM and not joe@example.com.

luzidd commented 3 months ago

I read some more of the documentation and came to the conclusion that the certificate file would probably be defined like it is here:

https://stalw.art/docs/server/tls/certificates

Or maybe it could even be set in the database and only be referenced by name.