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

common/tls: Allow specifying SNI hostnames #7897

Merged
merged 4 commits into from Dec 23, 2020

Conversation

antifuchs
Copy link
Contributor

This PR adds a new configration field sni_server_name that allows specifying the server name that'll be sent in the ClientHello when telegraf makes an HTTP request to TLS servers. This allows checking against load balancers responding to specific hostnames that otherwise wouldn't resolve to their addresses, or other more complex TLS configurations.

Fixes #7598.

Required for all PRs:

  • Signed CLA.
  • Associated README.md updated.
  • Has appropriate unit tests.

@antifuchs
Copy link
Contributor Author

The idea behind this PR is to test with something like the following setting:

[[inputs.http_response]]
insecure_skip_verify = false
response_string_match = "<title>Login</title>"
response_timeout = "10s"
urls = [
    "https://load-balancer-a.internal.example.com/login/",
    "https://load-balancer-b.internal.example.com/login/",
]
tls_ca = "/run/secrets/tls-cacert"
sni_server_name = "www.extremely-important-apex.com"
[inputs.http_response.headers]
Host = "www.extremely-important-apex.com"

In this example, load-balancer-a and -b are internal addresses and don't get resolved by www.extremely-important-apex.com; but they require the correct SNI server name to serve the content that they should serve (as well as the right Host header).

Hope that makes sense!

@sjwang90 sjwang90 added the feat Improvement on an existing feature such as adding a new setting/mode to an existing plugin label Aug 18, 2020
@sjwang90 sjwang90 added this to the Planned milestone Dec 9, 2020
@srebhan
Copy link
Contributor

srebhan commented Dec 11, 2020

I think this is not the correct approach. We rather should add this option to the tls.ClientConfig so it is available for all plugins using TLS.
@antifuchs are you willing to look into this!?

@srebhan srebhan self-assigned this Dec 11, 2020
@antifuchs
Copy link
Contributor Author

Huh, I didn't realize there was a common way to configure plugins' TLS client config. I'll look into it!

docs/TLS.md Outdated Show resolved Hide resolved
Add a new configration field `tls_server_name` that allows specifying
the server name that'll be sent in the ClientHello when telegraf makes
a request to TLS servers. This allows checking against load balancers
responding to specific hostnames that otherwise wouldn't resolve to
their addresses.

Add the setting to the documentation of common TLS options, as well as
to the http_response plugin.

Fixes influxdata#7598.
@antifuchs
Copy link
Contributor Author

Updated! What do you think, @srebhan? (I personally think it is much nicer, thanks for the suggestion!)

@@ -49,7 +50,7 @@ func (c *ClientConfig) TLSConfig() (*tls.Config, error) {
// want TLS, this will require using another option to determine. In the
// case of an HTTP plugin, you could use `https`. Other plugins may need
// the dedicated option `TLSEnable`.
if c.TLSCA == "" && c.TLSKey == "" && c.TLSCert == "" && !c.InsecureSkipVerify {
if c.TLSCA == "" && c.TLSKey == "" && c.TLSCert == "" && !c.InsecureSkipVerify && c.ServerName == "" {
Copy link
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 this is correct. If you neither specify a CA nor a KEY or CERT but a ServerName then this check will not trigger but I doubt it makes sense to check the servername without validating the certificate!?

Copy link
Contributor Author

@antifuchs antifuchs Dec 14, 2020

Choose a reason for hiding this comment

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

The ServerName directive does not affect only the host name in certificate checking: It's also the hostname requested via SNI in the TLS ClientHello message - that's the thing that I need to customize that prompted me to submit the PR in the first place (:

Even if that weren't the case, an empty TLS Config is documented to use the host's root CA set if no root CAs are provided, so setting the ServerName value on an otherwise-empty TLS config would be meaningful.

Copy link
Contributor

@srebhan srebhan Dec 14, 2020

Choose a reason for hiding this comment

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

Could you please put a comment there linking to the docu you mentioned. Just for the next one asking himself why this should make sense!? Thanks for the explanation!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm, so I re-read the TODO comment above & started auditing our code's usage of TLSConfig(), where I found out that the only case where a nil tls.Config matters (because the stdlib function tls.Client requires a non-nil value) is the x509_cert.go code... where we override the ServerName based on a configuration setting (incompatibly with the "common" ServerName setting now)!

So I'll have to fix the ServerName usage in x509_cert.go, but more importantly: I think we should remove that TODO, as it could be a pretty meaningful distinction in terms of "were there any settings that the operator customized" (but ultimately, it looks like there's not much of a difference). What do you think?

Copy link
Contributor

@srebhan srebhan left a comment

Choose a reason for hiding this comment

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

One question in the code and a request to add a test-case for only adding a server-name but no other TLS configuration... :-)

This plugin has been using ServerName previously, and will have to
deal with the new setting, too: Extract the server-name choosing into
a method & add a test to ensure we choose the right value (and error
under the right circumstances). Also document that the two settings
are mutually exclusive.
@antifuchs antifuchs changed the title http_response: Allow specifying SNI hostnames common/tls: Allow specifying SNI hostnames Dec 15, 2020
Also get rid of the TODO, as I am fairly certain this behavior is the
correct one.
@antifuchs
Copy link
Contributor Author

@srebhan I think this should cover what we discussed above - lmk if you see any other things that need improving!

Copy link
Contributor

@srebhan srebhan left a comment

Choose a reason for hiding this comment

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

Nice catch with the x509 plugin! Looks good to me.

@srebhan srebhan added the ready for final review This pull request has been reviewed and/or tested by multiple users and is ready for a final review. label Dec 16, 2020
Copy link
Contributor

@sspaink sspaink left a comment

Choose a reason for hiding this comment

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

Great work @antifuchs ! I just added a minor comment.

client tls.ClientConfig
expNil bool
expErr bool
serverName string
Copy link
Contributor

Choose a reason for hiding this comment

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

serverName doesn't seem to be used in this test. Can you remove it please?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, vestige of a previous idea for a test - Removing it now.

@sspaink sspaink merged commit 3c9c013 into influxdata:master Dec 23, 2020
@antifuchs antifuchs deleted the use-sni-in-http-response branch December 28, 2020 00:08
ssoroka pushed a commit that referenced this pull request Jan 27, 2021
* tls_config: Allow specifying SNI hostnames

Add a new configration field `tls_server_name` that allows specifying
the server name that'll be sent in the ClientHello when telegraf makes
a request to TLS servers. This allows checking against load balancers
responding to specific hostnames that otherwise wouldn't resolve to
their addresses.

Add the setting to the documentation of common TLS options, as well as
to the http_response plugin.

Fixes #7598.

* Adjust the x509_cert to allow usage of tls_server_name

This plugin has been using ServerName previously, and will have to
deal with the new setting, too: Extract the server-name choosing into
a method & add a test to ensure we choose the right value (and error
under the right circumstances). Also document that the two settings
are mutually exclusive.

* Improve documentation on what we try to accomplish in the nil return

Also get rid of the TODO, as I am fairly certain this behavior is the
correct one.

* Remove unused struct field in tests

(cherry picked from commit 3c9c013)
arstercz pushed a commit to arstercz/telegraf that referenced this pull request Mar 5, 2023
* tls_config: Allow specifying SNI hostnames

Add a new configration field `tls_server_name` that allows specifying
the server name that'll be sent in the ClientHello when telegraf makes
a request to TLS servers. This allows checking against load balancers
responding to specific hostnames that otherwise wouldn't resolve to
their addresses.

Add the setting to the documentation of common TLS options, as well as
to the http_response plugin.

Fixes influxdata#7598.

* Adjust the x509_cert to allow usage of tls_server_name

This plugin has been using ServerName previously, and will have to
deal with the new setting, too: Extract the server-name choosing into
a method & add a test to ensure we choose the right value (and error
under the right circumstances). Also document that the two settings
are mutually exclusive.

* Improve documentation on what we try to accomplish in the nil return

Also get rid of the TODO, as I am fairly certain this behavior is the
correct one.

* Remove unused struct field in tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat Improvement on an existing feature such as adding a new setting/mode to an existing plugin ready for final review This pull request has been reviewed and/or tested by multiple users and is ready for a final review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Override IP address in http_response
4 participants