From c8fa19e6bd2b6b1c1ebe8ba32f06d85ffff6d2ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Nu=C3=B1ez?= <10672208+mind-ar@users.noreply.github.com> Date: Sat, 1 Oct 2022 23:51:19 -0300 Subject: [PATCH] feat(notification): add disable_starttls option (#3855) This adds a boolean option to SMTP which disables StartTLS for SMTP servers that ignore standards. --- .../en/configuration/notifications/smtp.md | 15 ++++++++++++++- internal/configuration/schema/keys.go | 1 + internal/configuration/schema/notifier.go | 1 + internal/configuration/validator/const.go | 1 + internal/configuration/validator/notifier.go | 4 ++++ internal/notification/smtp_notifier.go | 6 ++++++ 6 files changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/content/en/configuration/notifications/smtp.md b/docs/content/en/configuration/notifications/smtp.md index c29dede50..20cd93a5d 100644 --- a/docs/content/en/configuration/notifications/smtp.md +++ b/docs/content/en/configuration/notifications/smtp.md @@ -31,6 +31,7 @@ notifier: subject: "[Authelia] {title}" startup_check_address: test@authelia.com disable_require_tls: false + disable_starttls: false disable_html_emails: false tls: server_name: smtp.example.com @@ -60,7 +61,7 @@ The port the SMTP service is listening on. A connection is securely established with TLS after a succesful STARTTLS negotiation. -[Port 465 is an exception][docs-security-smtp-port] when supported by the mail server as a `submissions` service port. +[Port 465 is an exception][docs-security-smtp-port] when supported by the mail server as a `submissions` service port. STARTTLS negotiation is not required for this port, the connection is implicitly established with TLS. [docs-security-smtp-port]: ../../overview/security/measures.md#smtp-ports @@ -132,6 +133,18 @@ to leave this as is, but you can customize it if you have issues or you desire t For security reasons the default settings for Authelia require the SMTP connection is encrypted by TLS. See [security] for more information. This option disables this measure (not recommended). +### disable_starttls + +{{< confkey type="boolean" default="false" required="no" >}} + +Some SMTP servers ignore SMTP specifications and claim to support STARTTLS when they in fact do not. +For security reasons Authelia refuses to send messages to these servers. +This option disables this measure and is enabled *__AT YOUR OWN RISK__*. It's *__strongly recommended__* +that instead of enabling this option you either fix the issue with the SMTP server's configuration or +have the administrators of the server fix it. If the issue can't be fixed by configuration we recommend +lodging an issue with the authors of the SMTP server. +See [security] for more information. + ### disable_html_emails {{< confkey type="boolean" default="false" required="no" >}} diff --git a/internal/configuration/schema/keys.go b/internal/configuration/schema/keys.go index 89622968a..d3cbdc8d6 100644 --- a/internal/configuration/schema/keys.go +++ b/internal/configuration/schema/keys.go @@ -166,6 +166,7 @@ var Keys = []string{ "notifier.smtp.startup_check_address", "notifier.smtp.disable_require_tls", "notifier.smtp.disable_html_emails", + "notifier.smtp.disable_starttls", "notifier.smtp.tls.minimum_version", "notifier.smtp.tls.skip_verify", "notifier.smtp.tls.server_name", diff --git a/internal/configuration/schema/notifier.go b/internal/configuration/schema/notifier.go index 00c45e8f7..159a90dea 100644 --- a/internal/configuration/schema/notifier.go +++ b/internal/configuration/schema/notifier.go @@ -23,6 +23,7 @@ type SMTPNotifierConfiguration struct { StartupCheckAddress mail.Address `koanf:"startup_check_address"` DisableRequireTLS bool `koanf:"disable_require_tls"` DisableHTMLEmails bool `koanf:"disable_html_emails"` + DisableStartTLS bool `koanf:"disable_starttls"` TLS *TLSConfig `koanf:"tls"` } diff --git a/internal/configuration/validator/const.go b/internal/configuration/validator/const.go index a41c65420..bc66dba8b 100644 --- a/internal/configuration/validator/const.go +++ b/internal/configuration/validator/const.go @@ -56,6 +56,7 @@ const ( errFmtNotifierTemplatePathUnknownError = "notifier: option 'template_path' refers to location '%s' which couldn't be opened: %w" errFmtNotifierFileSystemFileNameNotConfigured = "notifier: filesystem: option 'filename' is required" errFmtNotifierSMTPNotConfigured = "notifier: smtp: option '%s' is required" + errFmtNotifierStartTlsDisabled = "Notifier SMTP connection has opportunistic STARTTLS explicitly disabled which means all emails will be sent insecurely over plain text and this setting is only necessary for non-compliant SMTP servers which advertise they support STARTTLS when they actually don't support STARTTLS" ) // Authentication Backend Error constants. diff --git a/internal/configuration/validator/notifier.go b/internal/configuration/validator/notifier.go index 61676848d..ea37f972e 100644 --- a/internal/configuration/validator/notifier.go +++ b/internal/configuration/validator/notifier.go @@ -89,4 +89,8 @@ func validateSMTPNotifier(config *schema.SMTPNotifierConfiguration, validator *s if config.TLS.ServerName == "" { config.TLS.ServerName = config.Host } + + if config.DisableStartTLS { + validator.PushWarning(fmt.Errorf(errFmtNotifierStartTlsDisabled)) + } } diff --git a/internal/notification/smtp_notifier.go b/internal/notification/smtp_notifier.go index de58dcba9..cd7fa501d 100644 --- a/internal/notification/smtp_notifier.go +++ b/internal/notification/smtp_notifier.go @@ -156,6 +156,12 @@ func (n *SMTPNotifier) dial() (err error) { // Do startTLS if available (some servers only provide the auth extension after, and encryption is preferred). func (n *SMTPNotifier) startTLS() error { + // Skips STARTTLS if is disabled in configuration. + if n.config.DisableStartTLS { + n.log.Warn("Notifier SMTP connection has opportunistic STARTTLS explicitly disabled which means all emails will be sent insecurely over plain text and this setting is only necessary for non-compliant SMTP servers which advertise they support STARTTLS when they actually don't support STARTTLS") + return nil + } + // Only start if not already encrypted. if _, ok := n.client.TLSConnectionState(); ok { n.log.Debugf("Notifier SMTP connection is already encrypted, skipping STARTTLS")