Skip to content

[RAM] Add support for self-signed SSL certificate auth in webhook connector - #161894

Merged
Zacqary merged 51 commits into
elastic:mainfrom
Zacqary:160812-webhook-selfsigned
Aug 3, 2023
Merged

Zacqary merged 51 commits into
elastic:mainfrom
Zacqary:160812-webhook-selfsigned

Conversation

@Zacqary

@Zacqary Zacqary commented Jul 13, 2023 •

Copy link
Copy Markdown
Contributor

Summary

Closes #160812

Adds UI for CA and client-side SSL certificate auth to webhook connector, and adds these properties to the webhook's HttpsAgent on execution:

Screenshot 2023-07-18 at 11 59 33 AM

When Editing

Screenshot 2023-07-14 at 3 34 57 PM

Also creates a Field helper for EuiFilePicker

Checklist

@Zacqary Zacqary added Team:ResponseOps Platform ResponseOps team (formerly the Cases and Alerting teams) t// release_note:feature Makes this part of the condensed release notes Feature:Alerting/RulesManagement Issues related to the Rules Management UX v8.10.0 labels Jul 13, 2023
@ghost

ghost commented Jul 13, 2023

Copy link
Copy Markdown

🤖 GitHub comments

Expand to view the GitHub comments

Just comment with:

  • /oblt-deploy : Deploy a Kibana instance using the Observability test environments.
  • run elasticsearch-ci/docs : Re-trigger the docs validation. (use unformatted text in the comment!)

@cnasikas

Copy link
Copy Markdown
Member

Unfortunately no. HTML File inputs cannot be set to anything manually, it's a browser security issue. We might be able to modify the EUI File input element to display some kind of a fake placeholder file but that's a deeper EUI level change and out of scope for this issue.

Make sense. A solution would be to hide the file picker if there is a CA and show our own custom component (unrelated to file inputs) where the user can see a fake file name and an "X" icon to remove the CA. Pressing the "X" will show the file picker. Nevertheless, I don't think is ideal and it may be more confusing. We can leave it as it is and enhance it later if needed.

I allowed this so that the user is able to select Verification Mode: none without adding a CA file, but I can require the CA file if the verification mode is set to certificate or full

I found it confusing to press the Add certificate authority and then set the Verification mode to None. Does having the Add certificate authority set to off equals not uploading a CA file + setting the Verification mode to None? If yes, then I think we should not allow users to choose None and require a CA file.

@Zacqary

Zacqary commented Jul 26, 2023

Copy link
Copy Markdown
Contributor Author

Does having the Add certificate authority set to off equals not uploading a CA file + setting the Verification mode to None?

No it defaults to Full

Zacqary Xeper added 2 commits July 26, 2023 11:21

@pmuellr pmuellr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not finished reviewing, but I hit a few things early that I think we'll need to get resolved.

  • undefined-able values in config/secrets
  • hasAuth: false vs authType: None

We also need to get tests added, similar to what is currently in https://github.com/elastic/kibana/blob/main/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts - would be fine to re-org that if it's getting a bit big - perhaps even just have tests for the new combinations of ssl-ish options in a separate module.

const secretSchemaProps = {
user: schema.nullable(schema.string()),
password: schema.nullable(schema.string()),
user: schema.maybe(schema.string()),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can use maybe() here - unless we finally fixed the partial update issue, but I'd guess not. Anything in config / schema can never be undefined. schema.nullable() accepts an undefined value (or value not preset for the property), and return null.

See: https://docs.elastic.dev/reops/developer-guide/best-practices-connectors#undefined-config--secrets--params-properties

const agentSSLOptions = getNodeSSLOptions(logger, generalSSLSettings.verificationMode);
const agentSSLOptions = getNodeSSLOptions(
logger,
sslOverrides?.verificationMode ?? generalSSLSettings.verificationMode,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the webhook settings should override kibana.yml settings.

I'm wondering if there's cases where somehow they would be mixed - would that make sense? Is it even possible? I'd think we wouldn't want that, as it might be difficult to figure out what settings would actually be used.

@@ -54,6 +55,25 @@ const configSchemaProps = {
}),
headers: nullableType(HeadersSchema),
hasAuth: schema.boolean({ defaultValue: true }),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the intention of having both hasAuth - which was the way we determined whether to require a user/pass - and authType: NONE? I assume they "mean" the same thing. But if we leave it like this, there are lots of potential combinations we'll have to verify; hasAuth: false and authType: Basic should be an error, right?

Would it be better to not have authType: NONE at all? Cuts down on some of the invalid combinations. So the validation would be !hasAuth && !authType or hasAuth && authType, or whatever.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hasAuth seems to be a property common to several connector types, attempting to remove it broke a lot of tests at a deeper level.

It would also be a major breaking change for existing connectors, I'm not quite sure how to handle that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like hasAuth used by email and cases, but should just be a config, so independent of any other connectors.

But I'm not suggesting we remove it - though that IS a possibility - change 2-state hasAuth to 3-state authType. That would require a migration, so ... not a happy path for me :-)

My suggestion is to remove the NONE choice of authType. Since that's already covered by hasAuth. So you could only set authType if hasAuth is true, otherwise it would need to be null.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had some difficulty getting the form to correctly load saved connectors with hasAuth: false but it should be working now. Connector API will now throw an error if hasAuth is false and authType is anything but null or undefined.

@spong spong left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Solution changes LGTM! Thanks for the added auth support here @Zacqary 🙂 🎉

@pmuellr pmuellr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm no expert on client-side certs, but seems like the integration_tests that got added need to be changed to be able to start the server in a mode where it requires the client-side certs.

});

test('it works with cert, key, and ca in SSL overrides', async () => {
const { url, server } = await createServer({ useHttps: true });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this isn't going to test the client-side certificate stuff. We'll need to add another option to createServer() to have it pass requestCert in the TLS options when creating the server. Otherwise, the server is just going to ignore those.

To make sure this is working, we should have a negative test as well. Make a request to a client-side enabled server WITHOUT any of the client-side stuff, and it should fail. If we had that test in now, presumably the request would succeed, so the test would fail.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding requestCert and getting socket hang up errors. This seems like what Node does when you're sending it an invalid client certificate but I'm not sure, docs are very unclear. I'm still investigating.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Figured it out, server wasn't being configured with the Kibana CA by default. Tests are pushed and working now.

@kibana-ci

Copy link
Copy Markdown

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
esUiShared 230 232 +2
stackConnectors 203 204 +1
total +3

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
stackConnectors 439.3KB 447.6KB +8.2KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
esUiShared 154.8KB 156.4KB +1.6KB

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@pmuellr pmuellr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Realized we should probably have a function test for this as well, in https://github.com/elastic/kibana/blob/main/x-pack/test/alerting_api_integration/spaces_only/tests/actions/connector_types/stack/webhook.ts - we don't have to test all the possibilities, but it would be good to test all the way through with at least one set of good parameters - and probably a negative test as well for the client-side cert (don't send one on the request).

Fine to do this is as a follow-on PR before feature freeze ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting Feature:Alerting/RulesManagement Issues related to the Rules Management UX release_note:feature Makes this part of the condensed release notes Team:ResponseOps Platform ResponseOps team (formerly the Cases and Alerting teams) t// v8.10.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Webhook connector self-signed certificates

10 participants