-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Finer SMTP TLS certificate control #4385
base: main
Are you sure you want to change the base?
Conversation
Very interesting feature! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine by me. This would even work if we want to switch to rustls
instead of native.
Just a few comments.
src/mail.rs
Outdated
static SMTP_ADDITIONAL_ROOT_CERTS: Lazy<Option<Vec<Certificate>>> = Lazy::new(|| { | ||
Some( | ||
CONFIG | ||
.smtp_additional_root_certs()? | ||
.split(';') | ||
.filter(|path| !path.is_empty()) | ||
.map(|path| { | ||
let cert = std::fs::read(path) | ||
.unwrap_or_else(|e| panic!("Error loading additional SMTP root certificate file {path}.\n{e}")); | ||
Certificate::from_pem(&cert).unwrap_or_else(|e| panic!("Error decoding certificate file {path}.\n{e}")) | ||
}) | ||
.collect(), | ||
) | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to have this checked in config.rs
.
There it should check upon loading the config if those certs exists or not and and there it may panic.
Causing a panic here is probably not really wanted in my opinion.
Same goes for validating of those certs are valid certs.
So best to move this to the validate_config
function there i think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that panicing only upon sending the first mail is not appropriate.
I'm not sure if I understand you correctly. I'm not familiar with Vaultwarden's codebase, but how should I proceed? I currently see three different options. Which do you prefer? Do you have something else in mind?
SMTP_ADDITIONAL_ROOT_CERTS
remains remain a static global variable, just that it is moved intoconfig.rs
and thatverify_config
reads it first, such that theLazy
evaluates instantly upon config verification. I dislike this option since (a) it uses a global variable and (b) any calls toupdate_config
never actually reload the certificate (something that I missed in this pull request, too).- I can also move the reading and parsing into
verify_config
and store the resulting certificate list in an internalOption
config item upon success. That's fine considering thatSMTP_ADDITIONAL_ROOT_CERTS
is anOption
anyway. The only disadvantage is that the nameverify_config
becomes misleading as a verification function typically has no side effects. - I can also create a new internal
gen
config option of typeResult<Option<Vec<Certificate>>, Box<dyn Error>>
in which the generating function read and parse the certificates. Any errors that occur there are then stored as anBox<dyn Error>
which is then caught invalidate_config
. The disadvantage of this approach is that the config is of typeResult
, yet it is neverErr
during runtime, so any uses of this config option will always need an additional call tounwrap
first.
What is your opinion on that matter? Am I missing something totally obvious?
@JosefSchoenberger any interest in following up on the questions? Else i tend to close this PR as it also is possible to add/overwrite allowed certificates as a whole within a container for example. If you want to continue, then i think it would even make sense to add this same kind of functionality to the This could help with company wide transparent proxies maybe. But again, someone can also add custom certs and use the |
Yes, I do. I thought I ended this conversation with a question, hence no further work from me. Anyway, I'm trying the third option now, but there might by some difficulties with complex types in the configuration.
I think its still better to have these configuration options, setting it up that way is far easier (just setting one or two envs and ro-bind-mounting the certificate file into the container – both works fine in a compose file, for example).
I don't have a lot of time right now. For now, I'd just like to finish the SMTP part. They should have separate configuration variables (the certificates might differ between the mail server and other servers) and the internal setup for |
f0366d0
to
8399c54
Compare
Alright. Option 3 did not work, as lettre's |
This PR adds two new SMTP configurations regarding TLS:
SMTP_ADDITIONAL_ROOT_CERTS
allows an admin to add new root certificates that Vaultwarden accepts for the SMTP server. This can be useful if the SMTP server only offers a self-signed certificate. Example:SMTP_ADDITIONAL_ROOT_CERTS=/etc/ssl/certs/mail1.pem;/etc/ssl/certs/mail2.pem
SMTP_USE_SYSTEM_ROOT_CERTS
disables the system's root certificate store for TLS. This can be used in combination withSMTP_ADDITIONAL_ROOT_CERTS
for certificate pinning.