diff --git a/CHANGELOG.md b/CHANGELOG.md index ce283d6d..832e25d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ All notable changes to this project will be documented in this file. The format - **Fail2ban**: - Ensure a secure connection, when downloading the fail2ban package ([#4080](https://github.com/docker-mailserver/docker-mailserver/pull/4080)) +### Added + +- **Internal:** + - Add password confirmation to several `setup.sh` commands ([#4072](https://github.com/docker-mailserver/docker-mailserver/pull/4072)) ### Updates diff --git a/docs/content/config/best-practices/dkim_dmarc_spf.md b/docs/content/config/best-practices/dkim_dmarc_spf.md index d035556f..d6ba06b7 100644 --- a/docs/content/config/best-practices/dkim_dmarc_spf.md +++ b/docs/content/config/best-practices/dkim_dmarc_spf.md @@ -33,6 +33,21 @@ When DKIM is enabled: DKIM requires a public/private key pair to enable **signing (_via private key_)** your outgoing mail, while the receiving end must query DNS to **verify (_via public key_)** that the signature is trustworthy. +??? info "Verification expiry" + + Unlike your TLS certificate, your DKIM keypair does not have a fixed expiry associated to it. + + + Instead, an expiry may be included in your DKIM signature for each mail sent, where a receiver will [refuse to validate the signature for an email after that expiry date][dkim-verification-expiry-refusal]. This is an added precaution to mitigate malicious activity like "DKIM replay attacks", where an already delivered email from a third-party with a trustworthy DKIM signature is leveraged by a spammer when sending mail to an MTA which verifies the DKIM signature successfully, enabling the spammer to bypass spam protections. + + Unlike a TLS handshake where you are authenticating trust with future communications, with DKIM once the mail has been received and trust of the signature has been verified, the value of verifying the signature again at a later date is less meaningful since the signature was to ensure no tampering had occurred during delivery through the network. + +??? tip "DKIM key rotation" + + You can rotate your DKIM keypair by switching to a new DKIM selector (_and DNS updates_), while the previous key and selector remains valid for verification until the last mail signed with that key reaches it's expiry. + + DMS does not provide any automation or support for key rotation, [nor is it likely to provide a notable security benefit][gh-discussion::dkim-key-rotation-expiry] to the typical small scale DMS deployment. + ### Generating Keys You'll need to repeat this process if you add any new domains. @@ -72,7 +87,7 @@ You should have: According to [RFC 8301][rfc-8301], keys are preferably between 1024 and 2048 bits. Keys of size 4096-bit or larger may not be compatible to all systems your mail is intended for. - You [should not need a key length beyond 2048-bit][github-issue-dkimlength]. If 2048-bit does not meet your security needs, you may want to instead consider adopting key rotation or switching from RSA to ECC keys for DKIM. + You [should not need a key length beyond 2048-bit][gh-issue::dkim-length]. If 2048-bit does not meet your security needs, you may want to instead consider adopting key rotation or switching from RSA to ECC keys for DKIM. ??? note "You may need to specify mail domains explicitly" @@ -352,7 +367,8 @@ volumes: [docs-rspamd-config-dropin]: ../security/rspamd.md#manually [cloudflare-dkim-dmarc-spf]: https://www.cloudflare.com/learning/email-security/dmarc-dkim-spf/ [rfc-8301]: https://datatracker.ietf.org/doc/html/rfc8301#section-3.2 -[github-issue-dkimlength]: https://github.com/docker-mailserver/docker-mailserver/issues/1854#issuecomment-806280929 +[gh-discussion::dkim-key-rotation-expiry]: https://github.com/orgs/docker-mailserver/discussions/4068#discussioncomment-9784263 +[gh-issue::dkim-length]: https://github.com/docker-mailserver/docker-mailserver/issues/1854#issuecomment-806280929 [rspamd-docs-dkim-checks]: https://www.rspamd.com/doc/modules/dkim.html [rspamd-docs-dkim-signing]: https://www.rspamd.com/doc/modules/dkim_signing.html [dns::example-webui]: https://www.vultr.com/docs/introduction-to-vultr-dns/ @@ -360,6 +376,7 @@ volumes: [dns::wikipedia-zonefile]: https://en.wikipedia.org/wiki/Zone_file [dns::webui-dkim]: https://serverfault.com/questions/763815/route-53-doesnt-allow-adding-dkim-keys-because-length-is-too-long [dkim-ed25519-support]: https://serverfault.com/questions/1023674/is-ed25519-well-supported-for-the-dkim-validation/1074545#1074545 +[dkim-verification-expiry-refusal]: https://mxtoolbox.com/problem/dkim/dkim-signature-expiration [mxtoolbox-dkim-verifier]: https://mxtoolbox.com/dkim.aspx [dmarc-howto-configtags]: https://github.com/internetstandards/toolbox-wiki/blob/master/DMARC-how-to.md#overview-of-dmarc-configuration-tags [dmarc-tool-gca]: https://dmarcguide.globalcyberalliance.org diff --git a/target/bin/adddovecotmasteruser b/target/bin/adddovecotmasteruser index 41041db2..d327478d 100755 --- a/target/bin/adddovecotmasteruser +++ b/target/bin/adddovecotmasteruser @@ -7,8 +7,7 @@ function _main() { _require_n_parameters_or_print_usage 1 "${@}" local MAIL_ACCOUNT="${1}" - shift - local PASSWD="${*}" + local PASSWD="${2}" _manage_accounts_dovecotmaster_create "${MAIL_ACCOUNT}" "${PASSWD}" } diff --git a/target/bin/addmailuser b/target/bin/addmailuser index 15691c89..0eee9d82 100755 --- a/target/bin/addmailuser +++ b/target/bin/addmailuser @@ -7,8 +7,7 @@ function _main() { _require_n_parameters_or_print_usage 1 "${@}" local MAIL_ACCOUNT="${1}" - shift - local PASSWD="${*}" + local PASSWD="${2}" _manage_accounts_create "${MAIL_ACCOUNT}" "${PASSWD}" diff --git a/target/bin/addsaslpassword b/target/bin/addsaslpassword index 9461c112..7cb82dc2 100755 --- a/target/bin/addsaslpassword +++ b/target/bin/addsaslpassword @@ -8,8 +8,7 @@ function _main() { local DOMAIN="${1}" local RELAY_ACCOUNT="${2}" - shift 2 - local PASSWD="${*}" + local PASSWD="${3}" _validate_parameters _add_relayhost_credentials diff --git a/target/bin/updatedovecotmasteruser b/target/bin/updatedovecotmasteruser index eeff21a5..cc1ae930 100755 --- a/target/bin/updatedovecotmasteruser +++ b/target/bin/updatedovecotmasteruser @@ -7,8 +7,7 @@ function _main() { _require_n_parameters_or_print_usage 1 "${@}" local MAIL_ACCOUNT="${1}" - shift - local PASSWD="${*}" + local PASSWD="${2}" _manage_accounts_dovecotmaster_update "${MAIL_ACCOUNT}" "${PASSWD}" } diff --git a/target/bin/updatemailuser b/target/bin/updatemailuser index ce45533e..be1b981c 100755 --- a/target/bin/updatemailuser +++ b/target/bin/updatemailuser @@ -7,8 +7,7 @@ function _main() { _require_n_parameters_or_print_usage 1 "${@}" local MAIL_ACCOUNT="${1}" - shift - local PASSWD="${*}" + local PASSWD="${2}" _manage_accounts_update "${MAIL_ACCOUNT}" "${PASSWD}" } diff --git a/target/scripts/helpers/database/manage/postfix-accounts.sh b/target/scripts/helpers/database/manage/postfix-accounts.sh index 987254fc..e92b2555 100644 --- a/target/scripts/helpers/database/manage/postfix-accounts.sh +++ b/target/scripts/helpers/database/manage/postfix-accounts.sh @@ -98,9 +98,14 @@ function __account_already_exists() { # Also used by addsaslpassword function _password_request_if_missing() { + local PASSWD_CONFIRM if [[ -z ${PASSWD} ]]; then read -r -s -p 'Enter Password: ' PASSWD echo [[ -z ${PASSWD} ]] && _exit_with_error 'Password must not be empty' + + read -r -s -p 'Confirm Password: ' PASSWD_CONFIRM + echo + [[ ${PASSWD} != "${PASSWD_CONFIRM}" ]] && _exit_with_error 'Passwords do not match!' fi }