-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
DKIM implementations #5620
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
base: main
Are you sure you want to change the base?
DKIM implementations #5620
Conversation
|
May I ask why you want to implement this on the client? By client I mean the mail client. vw server acts as a mail client (unless the sendmail binary is directly used). DKIM and SPF are usually handled by the mail server. Also, what happens if you use DKIM on the client and then on the server again? Or actually it's worse, when using DKIM on the client but not on the server. The server will add headers that in turn will render the DKIM signature created on the client invalid. |
|
@tessus, sendmail is nothing more then a client in our case. It's how the sendmail is configured which might make it differently |
|
Hello, Yes I know but some person might use DKIM on their own without their server and it would be wise to allow people to do it if they want to, because the implementation is minimal as you can see. It might not be useful for everyone, I fully agree and if the server already manages SPF/DKIM and so on, there is no need to implement anything more but it might not be the case and people should be able to implement it. I've not tested all combinations but rapid tests shows it can work if people are actually configuring it themselves before and wants to continue. |
|
@williamdes Sorry, I've forgot I can implement |
williamdes
left a comment
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.
Nice
|
Weird the changes I have made to put Rust 2024 has been pushed. Please just push changes to mail if you proceed. Sorry and thanks. |
stefan0xC
left a comment
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'm not sure I agree that this should be added but I added some comments. The way to specify the signing key should be better documented (and configuration options should also be added to the .env.template).
src/mail.rs
Outdated
| if let Some(sig) = dkim { | ||
| dkim_sign(&mut email, &sig); |
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.
| if let Some(sig) = dkim { | |
| dkim_sign(&mut email, &sig); | |
| if let Some(dkim_config) = dkim { | |
| dkim_sign(&mut email, &dkim_config); |
| /// Dkim algo (true if RSA else ed25519) | ||
| dkim_algo: bool, true, option; | ||
| /// Dkim infos (selector:domain) | ||
| dkim_infos: String, true, option; |
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.
Why not let users configure selector and domain separately?
| /// Dkim signature (type:privatekey). Private must be base64-encoded ed key or PKCS#1 format RSA key. | ||
| dkim_signature: String, true, option; |
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.
What does type:privatekey mean? Nothing indicates that this should be a path to a file. If you want to configure it via a file you should be able to configure a DKIM_SIGNATURE_FILE.
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.
Also this should probably called dkim_signing_key instead.
src/mail.rs
Outdated
| let sig = match fs::read_to_string(sig) { | ||
| Err(e) => { | ||
| debug!("Cannot read DKIM file. Err is {:?}", e); | ||
| None | ||
| }, |
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.
We also already have a mechanism for loading config values from files so this should not be necessary.
src/mail.rs
Outdated
| async fn send_email(address: &str, subject: &str, body_html: String, body_text: String) -> EmptyResult { | ||
| let smtp_from = &CONFIG.smtp_from(); | ||
|
|
||
| let dkim = match (CONFIG.dkim_signature(), CONFIG.dkim_infos()) { |
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.
The validation should be done at startup (in config.rs) instead of when sending a mail.
Cargo.toml
Outdated
| edition = "2024" | ||
| rust-version = "1.85.0" |
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.
Weird the changes I have made to put Rust 2024 has been pushed. Please just push changes to mail if you proceed. Sorry and thanks.
Why don't you remove those changes from your PR if you don't want them in it?
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.
Besides that, it this PR needs a rebase on main, and the edition should not be changed!
src/config.rs
Outdated
| /// Dkim algo (true if RSA else ed25519) | ||
| dkim_algo: bool, true, option; |
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.
Do we have to support both methods? Also the naming is wrong if this is a toggle to use an RSA key. (I would call it dkim_use_rsa instead (and say that the default is ed25519 otherwise).
|
Also you should probably run |
rustfmt.toml
Outdated
| @@ -1,4 +1,4 @@ | |||
| edition = "2021" | |||
| edition = "2024" | |||
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.
This should not be changed!
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.
This file should not be edited, and you probably want to rebase on our current main branch.
Cargo.toml
Outdated
| edition = "2024" | ||
| rust-version = "1.85.0" |
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.
Besides that, it this PR needs a rebase on main, and the edition should not be changed!
|
I am still a bit fuzzy on the why and how.
How do people use DKIM on their own? DKIM requires the DNS record to be updated with TXT entries. Do you expect the vw admin to update the mail server's DNS record? Or do you plan to send emails via a random mail server, but let people think they are coming from vaultwarden and add the DKIM TXT entries to the vw DNS record? |
|
Hello, Thanks everyone for your review, I have redo my changes in light of the new version. I've taken into account your comments.
TXT is the public key. You just need vaultwarden to get the private key and sign. However, depending on the MTA, it might be useless or wrong. However if the MTA does not implement it and does not change header, DKIM implementation by the client would work. It is for me really important as some people might need it in their configuration and email sending by Vaultwarden should pass filters to avoid issues and ensure security. By default, From/Subject/To/Date are signed. Those are headers that are unlikely to be changed by default MTA. |
My thought process went into another direction and maybe I did express myself poorly. Let me try to unpack this. You can derive the public key from the private key, but not the other way around. This means the person who setups vw to use DKIM, must be the person who has access to the private keys AND must add the public keys to the DNS record. This means you either have to be in control (the admin) of the mail server or know exactly how that mail server behaves (no mail body or header changes, transfer encoding, ...). If it is the former, why not setup DKIM on the mail server? Even if you have never done it before, it takes less than 15 minutes to do so. My question here is: what is the gain? 15 minutes? Let me remind you, the vw admin has to change the DNS record to add the public keys. So the only gain is not having to add dkim to the mail server - 15 minutes. If it is the latter, don't you think the group of people who have all this type of info is rather small? How many people would actually be able to use your PR? All I am saying is that this use case is very specific and the target audience probably small. Please don’t take this the wrong way, I do not want to belittle your PR or your use case. I just do not understand why it would warrant adding something that only a few people are able to use.
This is unfortunately not always the case. e.g. mail servers sometimes use the mail server's timestamp, instead of just forwarding the date: header. As mentioned before, if you were to use your local MTA to send email, you would have to use a smart host to submit the email via an SMTP relay. Once again, you have to know exactly how all the parts in the chain behave. |
|
Hello, I agree with nearly all your comments.
If you relay your mail like you say on a server that you don't control. Maybe that server don't do DKIM. Maybe you don't want this server to sign for you. Maybe it is not free to implement DKIM... Even this, if you use a relay that sends your email, you or this provider needs DNS access, unless you don't send mails from your domain.
The gain is where the person cannot or does not want to implement DKIM on the MTA but has domain control and can know headers signed (the one I've sent to you) are not altered by their MTA.
I don't take the wrong way at all and your comments are legitimate. The target audience might be small. This implementation is not optimal but it is a work-around for specific people and deliverability of emails sent by Vaultwarden is crucial for many reasons. As such, it is just an addition of a feature from a crate that already exists in mail. If necessary, we could also implement it as a feature. In conclusion, even if DKIM support should not be done from the client side, it has some applications for some people and the minimum changes required to achieve this should give us reasons to implement it. |
Ok, this makes sense, at least the "cannot implement" part. For me it was rather a given that people who had server control (for vw) and control over DNS, also had control over a mail server. But I guess it's possible tha this might not be the case. Weird, but legitimately ok. My question is answered. Thank you. As for the implementation I think the current approach is fine. It's not a huge change, the binary size wouldn't increase by a lot, and there are no performace implications, thus a feature is most likely an overkill. |
Hello,
I would like to implement DKIM on Rust emails, so SPF and DKIM can be fulfilled and allows better transmission of mails.
Thanks.