diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index b2d051abf8e..b76c1256e86 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -64,6 +64,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix missing output in dockerlogbeat {pull}15719[15719] - Fix logging target settings being ignored when Beats are started via systemd or docker. {issue}12024[12024] {pull}15422[15442] - Do not load dashboards where not available. {pull}15802[15802] +- Fix issue where TLS settings would be ignored when a forward proxy was in use. {pull}15516{15516} *Auditbeat* diff --git a/heartbeat/monitors/active/http/http.go b/heartbeat/monitors/active/http/http.go index b033058b4a2..ef6c43b9c58 100644 --- a/heartbeat/monitors/active/http/http.go +++ b/heartbeat/monitors/active/http/http.go @@ -138,6 +138,7 @@ func newRoundTripper(config *Config, tls *transport.TLSConfig) (*http.Transport, Proxy: proxy, Dial: dialer.Dial, DialTLS: tlsDialer.Dial, + TLSClientConfig: tls.ToConfig(), DisableKeepAlives: true, }, nil } diff --git a/heartbeat/monitors/active/http/http_test.go b/heartbeat/monitors/active/http/http_test.go index 9066306de86..8d64dbd4025 100644 --- a/heartbeat/monitors/active/http/http_test.go +++ b/heartbeat/monitors/active/http/http_test.go @@ -39,6 +39,7 @@ import ( "github.com/elastic/beats/libbeat/beat" "github.com/elastic/beats/libbeat/common" "github.com/elastic/beats/libbeat/common/file" + "github.com/elastic/beats/libbeat/outputs/transport" btesting "github.com/elastic/beats/libbeat/testing" "github.com/elastic/go-lookslike" "github.com/elastic/go-lookslike/isdef" @@ -498,3 +499,31 @@ func TestRedirect(t *testing.T) { event.Fields, ) } + +func TestNewRoundTripper(t *testing.T) { + configs := map[string]Config{ + "Plain": {Timeout: time.Second}, + "With Proxy": {Timeout: time.Second, ProxyURL: "http://localhost:1234"}, + } + + for name, config := range configs { + t.Run(name, func(t *testing.T) { + transp, err := newRoundTripper(&config, &transport.TLSConfig{}) + require.NoError(t, err) + + if config.ProxyURL == "" { + require.Nil(t, transp.Proxy) + } else { + require.NotNil(t, transp.Proxy) + } + + // It's hard to compare func types in tests + require.NotNil(t, transp.Dial) + require.NotNil(t, transport.TLSDialer) + + require.Equal(t, (&transport.TLSConfig{}).ToConfig(), transp.TLSClientConfig) + require.True(t, transp.DisableKeepAlives) + }) + } + +} diff --git a/libbeat/common/transport/tlscommon/tls_config.go b/libbeat/common/transport/tlscommon/tls_config.go index 44331b08c74..a7e69ea3ab4 100644 --- a/libbeat/common/transport/tlscommon/tls_config.go +++ b/libbeat/common/transport/tlscommon/tls_config.go @@ -66,11 +66,11 @@ type TLSConfig struct { ClientAuth tls.ClientAuthType } -// BuildModuleConfig takes the TLSConfig and transform it into a `tls.Config`. -func (c *TLSConfig) BuildModuleConfig(host string) *tls.Config { +// ToConfig generates a tls.Config object. Note, you must use BuildModuleConfig to generate a config with +// ServerName set, use that method for servers with SNI. +func (c *TLSConfig) ToConfig() *tls.Config { if c == nil { - // use default TLS settings, if config is empty. - return &tls.Config{ServerName: host} + return &tls.Config{} } minVersion, maxVersion := extractMinMaxVersion(c.Versions) @@ -80,7 +80,6 @@ func (c *TLSConfig) BuildModuleConfig(host string) *tls.Config { } return &tls.Config{ - ServerName: host, MinVersion: minVersion, MaxVersion: maxVersion, Certificates: c.Certificates, @@ -93,3 +92,15 @@ func (c *TLSConfig) BuildModuleConfig(host string) *tls.Config { ClientAuth: c.ClientAuth, } } + +// BuildModuleConfig takes the TLSConfig and transform it into a `tls.Config`. +func (c *TLSConfig) BuildModuleConfig(host string) *tls.Config { + if c == nil { + // use default TLS settings, if config is empty. + return &tls.Config{ServerName: host} + } + + config := c.ToConfig() + config.ServerName = host + return config +} diff --git a/libbeat/kibana/client.go b/libbeat/kibana/client.go index a690180d6bc..c5154dd2bba 100644 --- a/libbeat/kibana/client.go +++ b/libbeat/kibana/client.go @@ -136,8 +136,9 @@ func NewClientWithConfig(config *ClientConfig) (*Client, error) { Password: password, HTTP: &http.Client{ Transport: &http.Transport{ - Dial: dialer.Dial, - DialTLS: tlsDialer.Dial, + Dial: dialer.Dial, + DialTLS: tlsDialer.Dial, + TLSClientConfig: tlsConfig.ToConfig(), }, Timeout: config.Timeout, }, diff --git a/libbeat/outputs/elasticsearch/client.go b/libbeat/outputs/elasticsearch/client.go index 5692fe12a7d..10541f08013 100644 --- a/libbeat/outputs/elasticsearch/client.go +++ b/libbeat/outputs/elasticsearch/client.go @@ -213,9 +213,10 @@ func NewClient( Headers: s.Headers, http: &http.Client{ Transport: &http.Transport{ - Dial: dialer.Dial, - DialTLS: tlsDialer.Dial, - Proxy: proxy, + Dial: dialer.Dial, + DialTLS: tlsDialer.Dial, + TLSClientConfig: s.TLS.ToConfig(), + Proxy: proxy, }, Timeout: s.Timeout, }, diff --git a/metricbeat/helper/http.go b/metricbeat/helper/http.go index a65678325c5..1dde8cd3a62 100644 --- a/metricbeat/helper/http.go +++ b/metricbeat/helper/http.go @@ -96,9 +96,10 @@ func newHTTPFromConfig(config Config, name string, hostData mb.HostData) (*HTTP, hostData: hostData, client: &http.Client{ Transport: &http.Transport{ - Dial: dialer.Dial, - DialTLS: tlsDialer.Dial, - Proxy: http.ProxyFromEnvironment, + Dial: dialer.Dial, + DialTLS: tlsDialer.Dial, + TLSClientConfig: tlsConfig.ToConfig(), + Proxy: http.ProxyFromEnvironment, }, Timeout: config.Timeout, }, diff --git a/x-pack/filebeat/input/httpjson/input.go b/x-pack/filebeat/input/httpjson/input.go index 577b7a05c44..b62c6e0c490 100644 --- a/x-pack/filebeat/input/httpjson/input.go +++ b/x-pack/filebeat/input/httpjson/input.go @@ -260,6 +260,7 @@ func (in *httpjsonInput) run() error { Transport: &http.Transport{ Dial: dialer.Dial, DialTLS: tlsDialer.Dial, + TLSClientConfig: tlsConfig.ToConfig(), DisableKeepAlives: true, }, Timeout: in.config.HTTPClientTimeout,