Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Per-domain TLS certificates #58

Closed
foxcpp opened this issue May 1, 2019 · 16 comments · Fixed by #59
Closed

Per-domain TLS certificates #58

foxcpp opened this issue May 1, 2019 · 16 comments · Fixed by #59
Assignees
Labels
new feature New feature. ready-for-release Feature is implemented and available for testing in dev branch. It will be included in the next rele
Milestone

Comments

@foxcpp
Copy link
Owner

foxcpp commented May 1, 2019

Rationale and possible alternative: #58 (comment)

Guidance for contributors

Make it possible to specify multiple cert-key pairs in the tls directive:

tls <cert> <key> <cert> <key>

Load them all then call tls.Config.BuildNameToCertificate.

The relevant code is in internal/config/tls_server.go in the readTLSBlock function.
Documentation to update: docs/man/maddy-imap.5.scd, docs/man/maddy-smtp.5.scd and probably docs/man/maddy-tls.5.scd.

Original post

Perhaps something like that:

tls perdomain {
  <domain> <cert_file> <key_file>
  _default cert_file key_file
}

Possible using GetCertificate or GetConfigForClient callbacks in tls.Config.

@foxcpp foxcpp added the new feature New feature. label May 1, 2019
@foxcpp
Copy link
Owner Author

foxcpp commented May 1, 2019

Or perhaps we can take a step forward and also extend TLS directive in general

tls {
  cert <file>
  key <file>

  //other options, such as TLS client certs handling and stuff
}
tls perdomain {
  <domain> {
    cert <file>
    key <file>
    //other options, such as TLS client certs handling and stuff
  }
}

@foxcpp
Copy link
Owner Author

foxcpp commented May 1, 2019

Another way: allow to specify multiple cert/key and do the matching using CN/SAN.

@emersion
Copy link
Collaborator

emersion commented May 1, 2019

Why wouldn't you specify it in a imap or smtp block?

@foxcpp
Copy link
Owner Author

foxcpp commented May 1, 2019

My friend asked for code me to help him with maddy configuration for multiple domains. I totally forgot how MX records work and the domain in MX record is the one being used for verification. E.g. even if you are working with multiple domains, you can add MX records such that they will point to the same server domain and it will be used for certification verification.

@foxcpp foxcpp closed this as completed May 1, 2019
@foxcpp foxcpp mentioned this issue May 23, 2019
@foxcpp
Copy link
Owner Author

foxcpp commented May 23, 2019

Reopening add there probably a use case for initially proposed idea.

@foxcpp foxcpp reopened this May 23, 2019
@foxcpp
Copy link
Owner Author

foxcpp commented Jun 8, 2019

Given that MTA-STS is a thing it would be nice to have support for multi-tenant systems for those cases as well.

Originally posted by @Avamander in #72 (comment).

@foxcpp
Copy link
Owner Author

foxcpp commented Jun 8, 2019

@Avamander, so what you want here is that single maddy instance should be able to serve multiple different domains and provide them with separate storage and etc., right?

auth_perdomain and storage_perdomain introduced in #74 enable this for authentication and storage.
With auth_perdomain, used authentication provider will not strip domain part before checking it with database. Also it will require users to authenticate using full e-mail rather than just mailbox-name.

With configuration like that:

auth_domains example.com example.org
auth_perdomain
storage_perdomain

sql { 
  ...
}
submission ... {
  auth sql
  destination example.org example.com {
    deliver sql
  }
  ...
}
imap ... {
  auth sql
  storage sql
}

foxcpp@example.org and foxcpp@example.com will be different accounts.

@foxcpp
Copy link
Owner Author

foxcpp commented Jun 8, 2019

One possible reason for supporting SNI here is that email client should be able to autodiscover configuration by trying to connect to (imap.)example.org:imaps or (imap.)example.com:imaps.

I think for these cases more sophisticated auto-discovery protocols should be used (see #67).

@chaoticryptidz
Copy link
Contributor

I think supporting per-domain TLS would be quite beneficial.

I host a few websites for different users and right now they have to put up with having to log in using @kitteh.pw and manually changing their address to @example.com.
They also cant recieve their mail most of the time using TLS either with the way stuff is managed.
People who provide hosting for other users and for people who own multiple domains but don't have the money to buy multiple VPSes would like this feature too.
I own namedkitten.pw and kitteh.pw and a few more domains and only host them off of one server, this just causes way more of a hassle then if we where to support multiple domains and per-domain TLS.

@Avamander
Copy link
Contributor

so what you want here is that single maddy instance should be able to serve multiple different domains and provide them with separate storage and etc., right?

Preferably also do MTA-STS with matching domain certificates, if possible.

@foxcpp
Copy link
Owner Author

foxcpp commented Jun 26, 2019

@NamedKitten

Consider this:
Set MX record for all domains to point to one domain (kitteh.pw, for example). Enable per-domain authentication and storage (note that it requires users to specify the full address in login credentials). Then consider deploying autodiscovery protocols mentioned above or just tell users to use kitteh.pw as IMAP/SMTP server when connecting.

This issue basically boils down to autodiscovery protocols support in clients. Research is needed.
Without it - SNI makes (a lot) sense. I doubt many clients support autodiscovery.

I think we can merge a PR to support it anyway, I'm not sure about config syntax though. Are there better options than one I described (and implemented but removed before merging in #59)? Somebody can just send a patch to revert the commit that removed it.

@tracker1
Copy link

Use letsencrypt to request multi-cert for all configured domains... use SNI for per-host web (theming/domain on address) .. other protocols just answer on appropriate port(s)

@foxcpp
Copy link
Owner Author

foxcpp commented Jun 29, 2019

Webmail is out of scope though. The problem is that clients will try to probe for standard continuations, like imap.domain. So it makes sense to be able to accept connections and provide the TLS certificate valid for that domain.

@foxcpp foxcpp added the good first issue Easy to do, good for newcomers. label Jan 2, 2020
@foxcpp
Copy link
Owner Author

foxcpp commented Jan 2, 2020

Added "good first issue" label, it should be easy to implement if somebody thinks it is needed.

@foxcpp foxcpp added this to the X.Y - "Eventually" milestone Feb 10, 2020
@foxcpp foxcpp self-assigned this Jul 16, 2020
@foxcpp foxcpp removed the good first issue Easy to do, good for newcomers. label Jul 16, 2020
@foxcpp
Copy link
Owner Author

foxcpp commented Jul 16, 2020

Implemented in cee8bbd.

tls file certA.pem keyA.pem certB.pem keyB.pem

@foxcpp foxcpp modified the milestones: X.Y - "Eventually", 0.4 Jul 16, 2020
@Avamander
Copy link
Contributor

Awesome, thanks!

@foxcpp foxcpp added the ready-for-release Feature is implemented and available for testing in dev branch. It will be included in the next rele label Aug 3, 2020
@foxcpp foxcpp closed this as completed Aug 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature New feature. ready-for-release Feature is implemented and available for testing in dev branch. It will be included in the next rele
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants