-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
common/tls: Allow specifying SNI hostnames #7897
Conversation
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, Hope that makes sense! |
I think this is not the correct approach. We rather should add this option to the |
Huh, I didn't realize there was a common way to configure plugins' TLS client config. I'll look into it! |
b50911f
to
0e4e7bc
Compare
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.
0e4e7bc
to
43f6526
Compare
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 == "" { |
There was a problem hiding this comment.
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!?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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?
There was a problem hiding this 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.
Also get rid of the TODO, as I am fairly certain this behavior is the correct one.
@srebhan I think this should cover what we discussed above - lmk if you see any other things that need improving! |
There was a problem hiding this 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.
There was a problem hiding this 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.
plugins/common/tls/config_test.go
Outdated
client tls.ClientConfig | ||
expNil bool | ||
expErr bool | ||
serverName string |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
* 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)
* 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
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: