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

[actions] email action broken in 7.11.0 for mail servers that don't support TLS #91686

Closed
pmuellr opened this issue Feb 17, 2021 · 5 comments · Fixed by #91760
Closed

[actions] email action broken in 7.11.0 for mail servers that don't support TLS #91686

pmuellr opened this issue Feb 17, 2021 · 5 comments · Fixed by #91760
Assignees
Labels
bug Fixes for quality problems that affect the customer experience Feature:Actions Team:ResponseOps Label for the ResponseOps team (formerly the Cases and Alerting teams)

Comments

@pmuellr
Copy link
Member

pmuellr commented Feb 17, 2021

Kibana version: 7.11.0 - worked on releases up to this though

Describe the bug:

Email servers that don't support TLS cannot be used with Kibana 7.11.0, but worked in previous versions. The best example is using the maildev npm package. If you run via npx maildev (no need to install anything), it will launch a mail server and a web client to read the emails that get sent.

$ npx maildev
npx: installed 118 in 6.567s
MailDev webapp running at http://0.0.0.0:1080
MailDev SMTP Server running at 0.0.0.0:1025

When sending an email through this server in 7.11.0, you'll see the following error:

error sending email: self signed certificate

We are seeing a similar issue with a cloud email proxy, not clear if it's the same, but sounds like it is, as it also does not support TLS AFAIK.

Steps to reproduce:

I have a pre-configured action for maildev in my kibana.dev.yml file, but you can also create the same one manually:

xpack.actions.preconfigured:
  maildev-no-auth:
    name: 'email: maildev no auth'
    actionTypeId: '.email'
    config:
      from: 'from@example.com'
      host: 'localhost'
      port: '1025'

From the Kibana UI, find this connector, and then go to the test tab. Fill in the To / Subject / Message fields, and click the Run button. You should see the error message in the Results section.

@pmuellr pmuellr added bug Fixes for quality problems that affect the customer experience Feature:Actions Team:ResponseOps Label for the ResponseOps team (formerly the Cases and Alerting teams) labels Feb 17, 2021
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-alerting-services (Team:Alerting Services)

@pmuellr pmuellr self-assigned this Feb 17, 2021
@pmuellr
Copy link
Member Author

pmuellr commented Feb 17, 2021

So it turns out, if you set the global Kibana config xpack.actions.rejectUnauthorized to false, it works.

I added some debug logging in the email action for it's "transport" settings, and this is what it prints, when not setting that to false (not configuring it at all):

email action maildev-no-auth sending mail with transport: {
  "host":"localhost","port":1025,"secure":false,"tls":{"rejectUnauthorized":true}
}

Here's what it looks like when I set the config value to false:

email action maildev-no-auth sending mail with transport: {
  "host":"localhost","port":1025,"secure":false,"tls":{"rejectUnauthorized":false}
}

In 7.10.0, if xpack.actions.rejectUnauthorized is not set (and so defaults to true), this is used for the transport config:

{"host":"localhost","port":1025,"secure":false,"tls":{"rejectUnauthorized": undefined}}

The rejectUnauthorized parameter passed to this function (as part of the options) is always undefined, it's never set in the caller. That seems like a bug itself, and I'd guess that the undefined is being treated as false by nodemailer, so we were never rejecting invalid certs before.

I'm tempted to use the secure action setting to also influence the tls.rejectUnauthorized value nodemailer setting, but that's a bit dangerous. It would mean that for servers that REQUIRE the secure false setting (eg, office365), they would be running without the tls auth check, which would be not good.

It may be though that we could be a little more precise in applying that. The two known servers this is a problem with both do not accept user/pass values - so they are already somewhat insecure. Could we use something like this to set the value?

if (user == null && password == null && secure === false) {
    tls.rejectUnauthorized = false
}

If that's not acceptable, we could add a new rejectUnauthorized: boolean property explicitly to the email config, but I really hate to do that as it's already a complicated set of config values to deal with, unless you are intimately familiar with SMTP.

Long-term, the resolution of this issue should be the real fix: #80120

pmuellr added a commit to pmuellr/kibana that referenced this issue Feb 17, 2021
resolves elastic#91686

The poor email action has not had great success in setting TLS options
correctly.  Prior to 7.11, it was basically always setting `rejectUnauthorized`
to false, so was never validating certificates.  Starting in 7.11.0, it
started respecting TLS certificates, but there are some simple/test servers
in use that use self-signed certificates.

The real fix for this will be the resolution of issue
elastic#80120 , but until then, this PR
does a special-case check if the `secure` option is off (so the email client
connects with a plain socket and then upgrades to TLS via STARTTLS) and both
the user and password for the server are not set, then it will use
`rejectUnauthorized: false`.  Otherwise, it uses the global configured value
of this setting.

This also changes some other cases, where `secure: true` often did not
set any `rejectUnauthorized` property at all, and so did not get verified.
Now in all cases, `rejectUnauthorized` will be set, and the value will
correspond to the globally configured value, except for the special case
checked here, and when a proxy is in use (that logic did not change).

So it is possible this would break customers, who were using insecure servers
and email action worked, but with this fix the connections will be rejected.
They should have been rejected all this time though.

The work-around for this problem, if we don't implement a fix like this, is
that customers will need to set the global `rejectUnauthorized` to `false`,
which means NONE of their TLS connections for any actions will be verified.
Which seems extreme.
@pmuellr
Copy link
Member Author

pmuellr commented Feb 17, 2021

PR #91760 seems to fix this, but we'll need to think about the ramifications.

Not sure how to go about testing this on cloud. I'm thinking I used to create deployments with nightly images, so we'd need to promote this to master and wait till then to test it.

@trengrj
Copy link
Contributor

trengrj commented Feb 17, 2021

Thanks @pmuellr, looking at nodemailer TLS options https://nodemailer.com/smtp/#tls-options, the connection is always upgraded to TLS via STARTTLS if the SMTP server supports it (even when secure is set to false). The ignoreTLS option would need to be used to fully disable STARTTLS.

Watcher decided to use two separate config options https://www.elastic.co/guide/en/elasticsearch/reference/current/notification-settings.html#email-notification-settings starttls.enabled and starttls.required.

@pmuellr
Copy link
Member Author

pmuellr commented Feb 18, 2021

Thx for that info @trengrj ! We should include that option in issue #80120 (I'll add to the design doc I'm working on).

At least for the cloud proxy and nodemailer, also implementing a way to ignore cert verification checks would work here, as that's how it worked in the past. The current logic in 7.11.0 doesn't give us a way to do that though. And perhaps that's better, than not using TLS at all - at least you'd get on-the-wire encryption for that.

pmuellr added a commit to pmuellr/kibana that referenced this issue Feb 19, 2021
resolves elastic#91686

The poor email action has not had great success in setting TLS options
correctly.  Prior to 7.11, it was basically always setting `rejectUnauthorized`
to false, so was never validating certificates.  Starting in 7.11.0, it
started respecting TLS certificates, but there are some simple/test servers
in use that use self-signed certificates.

The real fix for this will be the resolution of issue
elastic#80120 , but until then, this PR
does a special-case check if the `secure` option is off (so the email client
connects with a plain socket and then upgrades to TLS via STARTTLS) and both
the user and password for the server are not set, then it will use
`rejectUnauthorized: false`.  Otherwise, it uses the global configured value
of this setting.

This also changes some other cases, where `secure: true` often did not
set any `rejectUnauthorized` property at all, and so did not get verified.
Now in all cases, `rejectUnauthorized` will be set, and the value will
correspond to the globally configured value, except for the special case
checked here, and when a proxy is in use (that logic did not change).

So it is possible this would break customers, who were using insecure servers
and email action worked, but with this fix the connections will be rejected.
They should have been rejected all this time though.

The work-around for this problem, if we don't implement a fix like this, is
that customers will need to set the global `rejectUnauthorized` to `false`,
which means NONE of their TLS connections for any actions will be verified.
Which seems extreme.
pmuellr added a commit that referenced this issue Mar 1, 2021
…se (#91760)

resolves #91686

The poor email action has not had great success in setting TLS options
correctly.  Prior to 7.11, it was basically always setting `rejectUnauthorized`
to false, so was never validating certificates.  Starting in 7.11.0, it
started respecting TLS certificates, but there are some simple/test servers
in use that use self-signed certificates.

The real fix for this will be the resolution of issue
#80120 , but until then, this PR
does a special-case check if the `secure` option is off (so the email client
connects with a plain socket and then upgrades to TLS via STARTTLS) and both
the user and password for the server are not set, then it will use
`rejectUnauthorized: false`.  Otherwise, it uses the global configured value
of this setting.

This also changes some other cases, where `secure: true` often did not
set any `rejectUnauthorized` property at all, and so did not get verified.
Now in all cases, `rejectUnauthorized` will be set, and the value will
correspond to the globally configured value, except for the special case
checked here, and when a proxy is in use (that logic did not change).

So it is possible this would break customers, who were using insecure servers
and email action worked, but with this fix the connections will be rejected.
They should have been rejected all this time though.

The work-around for this problem, if we don't implement a fix like this, is
that customers will need to set the global `rejectUnauthorized` to `false`,
which means NONE of their TLS connections for any actions will be verified.
Which seems extreme.
pmuellr added a commit to pmuellr/kibana that referenced this issue Mar 1, 2021
…se (elastic#91760)

resolves elastic#91686

The poor email action has not had great success in setting TLS options
correctly.  Prior to 7.11, it was basically always setting `rejectUnauthorized`
to false, so was never validating certificates.  Starting in 7.11.0, it
started respecting TLS certificates, but there are some simple/test servers
in use that use self-signed certificates.

The real fix for this will be the resolution of issue
elastic#80120 , but until then, this PR
does a special-case check if the `secure` option is off (so the email client
connects with a plain socket and then upgrades to TLS via STARTTLS) and both
the user and password for the server are not set, then it will use
`rejectUnauthorized: false`.  Otherwise, it uses the global configured value
of this setting.

This also changes some other cases, where `secure: true` often did not
set any `rejectUnauthorized` property at all, and so did not get verified.
Now in all cases, `rejectUnauthorized` will be set, and the value will
correspond to the globally configured value, except for the special case
checked here, and when a proxy is in use (that logic did not change).

So it is possible this would break customers, who were using insecure servers
and email action worked, but with this fix the connections will be rejected.
They should have been rejected all this time though.

The work-around for this problem, if we don't implement a fix like this, is
that customers will need to set the global `rejectUnauthorized` to `false`,
which means NONE of their TLS connections for any actions will be verified.
Which seems extreme.
pmuellr added a commit to pmuellr/kibana that referenced this issue Mar 1, 2021
…se (elastic#91760)

resolves elastic#91686

The poor email action has not had great success in setting TLS options
correctly.  Prior to 7.11, it was basically always setting `rejectUnauthorized`
to false, so was never validating certificates.  Starting in 7.11.0, it
started respecting TLS certificates, but there are some simple/test servers
in use that use self-signed certificates.

The real fix for this will be the resolution of issue
elastic#80120 , but until then, this PR
does a special-case check if the `secure` option is off (so the email client
connects with a plain socket and then upgrades to TLS via STARTTLS) and both
the user and password for the server are not set, then it will use
`rejectUnauthorized: false`.  Otherwise, it uses the global configured value
of this setting.

This also changes some other cases, where `secure: true` often did not
set any `rejectUnauthorized` property at all, and so did not get verified.
Now in all cases, `rejectUnauthorized` will be set, and the value will
correspond to the globally configured value, except for the special case
checked here, and when a proxy is in use (that logic did not change).

So it is possible this would break customers, who were using insecure servers
and email action worked, but with this fix the connections will be rejected.
They should have been rejected all this time though.

The work-around for this problem, if we don't implement a fix like this, is
that customers will need to set the global `rejectUnauthorized` to `false`,
which means NONE of their TLS connections for any actions will be verified.
Which seems extreme.
pmuellr added a commit to pmuellr/kibana that referenced this issue Mar 1, 2021
…se (elastic#91760)

resolves elastic#91686

The poor email action has not had great success in setting TLS options
correctly.  Prior to 7.11, it was basically always setting `rejectUnauthorized`
to false, so was never validating certificates.  Starting in 7.11.0, it
started respecting TLS certificates, but there are some simple/test servers
in use that use self-signed certificates.

The real fix for this will be the resolution of issue
elastic#80120 , but until then, this PR
does a special-case check if the `secure` option is off (so the email client
connects with a plain socket and then upgrades to TLS via STARTTLS) and both
the user and password for the server are not set, then it will use
`rejectUnauthorized: false`.  Otherwise, it uses the global configured value
of this setting.

This also changes some other cases, where `secure: true` often did not
set any `rejectUnauthorized` property at all, and so did not get verified.
Now in all cases, `rejectUnauthorized` will be set, and the value will
correspond to the globally configured value, except for the special case
checked here, and when a proxy is in use (that logic did not change).

So it is possible this would break customers, who were using insecure servers
and email action worked, but with this fix the connections will be rejected.
They should have been rejected all this time though.

The work-around for this problem, if we don't implement a fix like this, is
that customers will need to set the global `rejectUnauthorized` to `false`,
which means NONE of their TLS connections for any actions will be verified.
Which seems extreme.
pmuellr added a commit that referenced this issue Mar 1, 2021
…se (#91760) (#93133)

resolves #91686

The poor email action has not had great success in setting TLS options
correctly.  Prior to 7.11, it was basically always setting `rejectUnauthorized`
to false, so was never validating certificates.  Starting in 7.11.0, it
started respecting TLS certificates, but there are some simple/test servers
in use that use self-signed certificates.

The real fix for this will be the resolution of issue
#80120 , but until then, this PR
does a special-case check if the `secure` option is off (so the email client
connects with a plain socket and then upgrades to TLS via STARTTLS) and both
the user and password for the server are not set, then it will use
`rejectUnauthorized: false`.  Otherwise, it uses the global configured value
of this setting.

This also changes some other cases, where `secure: true` often did not
set any `rejectUnauthorized` property at all, and so did not get verified.
Now in all cases, `rejectUnauthorized` will be set, and the value will
correspond to the globally configured value, except for the special case
checked here, and when a proxy is in use (that logic did not change).

So it is possible this would break customers, who were using insecure servers
and email action worked, but with this fix the connections will be rejected.
They should have been rejected all this time though.

The work-around for this problem, if we don't implement a fix like this, is
that customers will need to set the global `rejectUnauthorized` to `false`,
which means NONE of their TLS connections for any actions will be verified.
Which seems extreme.
pmuellr added a commit that referenced this issue Mar 1, 2021
…se (#91760) (#93131)

resolves #91686

The poor email action has not had great success in setting TLS options
correctly.  Prior to 7.11, it was basically always setting `rejectUnauthorized`
to false, so was never validating certificates.  Starting in 7.11.0, it
started respecting TLS certificates, but there are some simple/test servers
in use that use self-signed certificates.

The real fix for this will be the resolution of issue
#80120 , but until then, this PR
does a special-case check if the `secure` option is off (so the email client
connects with a plain socket and then upgrades to TLS via STARTTLS) and both
the user and password for the server are not set, then it will use
`rejectUnauthorized: false`.  Otherwise, it uses the global configured value
of this setting.

This also changes some other cases, where `secure: true` often did not
set any `rejectUnauthorized` property at all, and so did not get verified.
Now in all cases, `rejectUnauthorized` will be set, and the value will
correspond to the globally configured value, except for the special case
checked here, and when a proxy is in use (that logic did not change).

So it is possible this would break customers, who were using insecure servers
and email action worked, but with this fix the connections will be rejected.
They should have been rejected all this time though.

The work-around for this problem, if we don't implement a fix like this, is
that customers will need to set the global `rejectUnauthorized` to `false`,
which means NONE of their TLS connections for any actions will be verified.
Which seems extreme.
pmuellr added a commit that referenced this issue Mar 1, 2021
…se (#91760) (#93132)

resolves #91686

The poor email action has not had great success in setting TLS options
correctly.  Prior to 7.11, it was basically always setting `rejectUnauthorized`
to false, so was never validating certificates.  Starting in 7.11.0, it
started respecting TLS certificates, but there are some simple/test servers
in use that use self-signed certificates.

The real fix for this will be the resolution of issue
#80120 , but until then, this PR
does a special-case check if the `secure` option is off (so the email client
connects with a plain socket and then upgrades to TLS via STARTTLS) and both
the user and password for the server are not set, then it will use
`rejectUnauthorized: false`.  Otherwise, it uses the global configured value
of this setting.

This also changes some other cases, where `secure: true` often did not
set any `rejectUnauthorized` property at all, and so did not get verified.
Now in all cases, `rejectUnauthorized` will be set, and the value will
correspond to the globally configured value, except for the special case
checked here, and when a proxy is in use (that logic did not change).

So it is possible this would break customers, who were using insecure servers
and email action worked, but with this fix the connections will be rejected.
They should have been rejected all this time though.

The work-around for this problem, if we don't implement a fix like this, is
that customers will need to set the global `rejectUnauthorized` to `false`,
which means NONE of their TLS connections for any actions will be verified.
Which seems extreme.
@kobelb kobelb added the needs-team Issues missing a team label label Jan 31, 2022
@botelastic botelastic bot removed the needs-team Issues missing a team label label Jan 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Fixes for quality problems that affect the customer experience Feature:Actions Team:ResponseOps Label for the ResponseOps team (formerly the Cases and Alerting teams)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants