From 30ee576ccae6d993cb7462d541b7414be7903abd Mon Sep 17 00:00:00 2001 From: Bob Shannon Date: Sat, 3 Jun 2017 15:25:37 -0400 Subject: [PATCH 1/3] Add SSL/TLS support to nginx input plugin Import required packages --- CHANGELOG.md | 1 + plugins/inputs/nginx/README.md | 7 ++++++ plugins/inputs/nginx/nginx.go | 46 ++++++++++++++++++++++++++-------- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 128da4e446633..1b29f7be044b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - [#2773](https://github.com/influxdata/telegraf/pull/2773): Add support for self-signed certs to InfluxDB input plugin - [#2581](https://github.com/influxdata/telegraf/pull/2581): Add Docker container environment variables as tags. Only whitelisted - [#2817](https://github.com/influxdata/telegraf/pull/2817): Added timeout option to IPMI sensor plugin +- [#2883](https://github.com/influxdata/telegraf/pull/2883): Add support for an optional SSL/TLS configuration to nginx input plugin ### Bugfixes diff --git a/plugins/inputs/nginx/README.md b/plugins/inputs/nginx/README.md index dab54329ba99c..b2c47d332a18b 100644 --- a/plugins/inputs/nginx/README.md +++ b/plugins/inputs/nginx/README.md @@ -7,6 +7,13 @@ [[inputs.nginx]] ## An array of Nginx stub_status URI to gather stats. urls = ["http://localhost/server_status"] + + ## Optional SSL Config + # ssl_ca = "/etc/telegraf/ca.pem" + # ssl_cert = "/etc/telegraf/cert.pem" + # ssl_key = "/etc/telegraf/key.pem" + ## Use SSL but skip chain & host verification + # insecure_skip_verify = false ``` ### Measurements & Fields: diff --git a/plugins/inputs/nginx/nginx.go b/plugins/inputs/nginx/nginx.go index f439c1eeb23b2..0f96c316a6634 100644 --- a/plugins/inputs/nginx/nginx.go +++ b/plugins/inputs/nginx/nginx.go @@ -12,16 +12,33 @@ import ( "time" "github.com/influxdata/telegraf" + "github.com/influxdata/telegraf/internal" "github.com/influxdata/telegraf/plugins/inputs" ) type Nginx struct { + // List of status URLs Urls []string + // Path to CA file + SSLCA string `toml:"ssl_ca"` + // Path to client cert file + SSLCert string `toml:"ssl_cert"` + // Path to cert key file + SSLKey string `toml:"ssl_key"` + // Use SSL but skip chain & host verification + InsecureSkipVerify bool } var sampleConfig = ` ## An array of Nginx stub_status URI to gather stats. urls = ["http://localhost/status"] + + ## Optional SSL Config + # ssl_ca = "/etc/telegraf/ca.pem" + # ssl_cert = "/etc/telegraf/cert.pem" + # ssl_key = "/etc/telegraf/key.pem" + ## Use SSL but skip chain & host verification + # insecure_skip_verify = false ` func (n *Nginx) SampleConfig() string { @@ -35,6 +52,22 @@ func (n *Nginx) Description() string { func (n *Nginx) Gather(acc telegraf.Accumulator) error { var wg sync.WaitGroup + tlsCfg, err := internal.GetTLSConfig( + n.SSLCert, n.SSLKey, n.SSLCA, n.InsecureSkipVerify) + if err != nil { + return err + } + + var tr = &http.Transport{ + ResponseHeaderTimeout: time.Duration(3 * time.Second), + TLSClientConfig: tlsCfg, + } + + var client = &http.Client{ + Transport: tr, + Timeout: time.Duration(4 * time.Second), + } + for _, u := range n.Urls { addr, err := url.Parse(u) if err != nil { @@ -44,7 +77,7 @@ func (n *Nginx) Gather(acc telegraf.Accumulator) error { wg.Add(1) go func(addr *url.URL) { defer wg.Done() - acc.AddError(n.gatherUrl(addr, acc)) + acc.AddError(n.gatherUrl(addr, acc, client)) }(addr) } @@ -52,16 +85,7 @@ func (n *Nginx) Gather(acc telegraf.Accumulator) error { return nil } -var tr = &http.Transport{ - ResponseHeaderTimeout: time.Duration(3 * time.Second), -} - -var client = &http.Client{ - Transport: tr, - Timeout: time.Duration(4 * time.Second), -} - -func (n *Nginx) gatherUrl(addr *url.URL, acc telegraf.Accumulator) error { +func (n *Nginx) gatherUrl(addr *url.URL, acc telegraf.Accumulator, client *http.Client) error { resp, err := client.Get(addr.String()) if err != nil { return fmt.Errorf("error making HTTP request to %s: %s", addr.String(), err) From 5eb122fa46ad44e4b2dd9acb06df47292fabb0d2 Mon Sep 17 00:00:00 2001 From: Bob Shannon Date: Tue, 6 Jun 2017 21:20:47 -0400 Subject: [PATCH 2/3] Re-use http client; make response timeout configurable --- plugins/inputs/nginx/README.md | 3 ++ plugins/inputs/nginx/nginx.go | 75 ++++++++++++++++++++++------------ 2 files changed, 52 insertions(+), 26 deletions(-) diff --git a/plugins/inputs/nginx/README.md b/plugins/inputs/nginx/README.md index b2c47d332a18b..819501ea7f005 100644 --- a/plugins/inputs/nginx/README.md +++ b/plugins/inputs/nginx/README.md @@ -14,6 +14,9 @@ # ssl_key = "/etc/telegraf/key.pem" ## Use SSL but skip chain & host verification # insecure_skip_verify = false + + ## HTTP response timeout (default: 5s) + response_timeout = "5s" ``` ### Measurements & Fields: diff --git a/plugins/inputs/nginx/nginx.go b/plugins/inputs/nginx/nginx.go index 0f96c316a6634..5bbd8912cdde8 100644 --- a/plugins/inputs/nginx/nginx.go +++ b/plugins/inputs/nginx/nginx.go @@ -27,18 +27,26 @@ type Nginx struct { SSLKey string `toml:"ssl_key"` // Use SSL but skip chain & host verification InsecureSkipVerify bool + // HTTP client + client *http.Client + // Response timeout + ResponseTimeout internal.Duration } var sampleConfig = ` - ## An array of Nginx stub_status URI to gather stats. - urls = ["http://localhost/status"] - - ## Optional SSL Config - # ssl_ca = "/etc/telegraf/ca.pem" - # ssl_cert = "/etc/telegraf/cert.pem" - # ssl_key = "/etc/telegraf/key.pem" - ## Use SSL but skip chain & host verification - # insecure_skip_verify = false + # Read Nginx's basic status information (ngx_http_stub_status_module) + [[inputs.nginx]] + # An array of Nginx stub_status URI to gather stats. + urls = ["http://localhost/server_status"] + + # TLS/SSL configuration + ssl_ca = "var/security/ca.pem" + ssl_cert = "var/security/cert.cer" + ssl_key = "var/security/key.key" + insecure_skip_verify = false + + # HTTP response timeout (default: 5s) + response_timeout = "10s" ` func (n *Nginx) SampleConfig() string { @@ -52,20 +60,14 @@ func (n *Nginx) Description() string { func (n *Nginx) Gather(acc telegraf.Accumulator) error { var wg sync.WaitGroup - tlsCfg, err := internal.GetTLSConfig( - n.SSLCert, n.SSLKey, n.SSLCA, n.InsecureSkipVerify) - if err != nil { - return err - } - - var tr = &http.Transport{ - ResponseHeaderTimeout: time.Duration(3 * time.Second), - TLSClientConfig: tlsCfg, - } - - var client = &http.Client{ - Transport: tr, - Timeout: time.Duration(4 * time.Second), + // Create an HTTP client that is re-used for each + // collection interval + if n.client == nil { + client, err := n.createHttpClient() + if err != nil { + return err + } + n.client = client } for _, u := range n.Urls { @@ -77,7 +79,7 @@ func (n *Nginx) Gather(acc telegraf.Accumulator) error { wg.Add(1) go func(addr *url.URL) { defer wg.Done() - acc.AddError(n.gatherUrl(addr, acc, client)) + acc.AddError(n.gatherUrl(addr, acc)) }(addr) } @@ -85,8 +87,29 @@ func (n *Nginx) Gather(acc telegraf.Accumulator) error { return nil } -func (n *Nginx) gatherUrl(addr *url.URL, acc telegraf.Accumulator, client *http.Client) error { - resp, err := client.Get(addr.String()) +func (n *Nginx) createHttpClient() (*http.Client, error) { + tlsCfg, err := internal.GetTLSConfig( + n.SSLCert, n.SSLKey, n.SSLCA, n.InsecureSkipVerify) + if err != nil { + return nil, err + } + + if n.ResponseTimeout.Duration < time.Second { + n.ResponseTimeout.Duration = time.Second * 5 + } + + client := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: tlsCfg, + }, + Timeout: n.ResponseTimeout.Duration, + } + + return client, nil +} + +func (n *Nginx) gatherUrl(addr *url.URL, acc telegraf.Accumulator) error { + resp, err := n.client.Get(addr.String()) if err != nil { return fmt.Errorf("error making HTTP request to %s: %s", addr.String(), err) } From 01dd046248972c58e9ab31584f0236b2b738ad96 Mon Sep 17 00:00:00 2001 From: Bob Shannon Date: Wed, 7 Jun 2017 20:29:35 -0400 Subject: [PATCH 3/3] Fix formatting --- plugins/inputs/nginx/nginx.go | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/plugins/inputs/nginx/nginx.go b/plugins/inputs/nginx/nginx.go index 5bbd8912cdde8..d389997e2ca3b 100644 --- a/plugins/inputs/nginx/nginx.go +++ b/plugins/inputs/nginx/nginx.go @@ -34,19 +34,17 @@ type Nginx struct { } var sampleConfig = ` - # Read Nginx's basic status information (ngx_http_stub_status_module) - [[inputs.nginx]] - # An array of Nginx stub_status URI to gather stats. - urls = ["http://localhost/server_status"] - - # TLS/SSL configuration - ssl_ca = "var/security/ca.pem" - ssl_cert = "var/security/cert.cer" - ssl_key = "var/security/key.key" - insecure_skip_verify = false - - # HTTP response timeout (default: 5s) - response_timeout = "10s" + # An array of Nginx stub_status URI to gather stats. + urls = ["http://localhost/server_status"] + + # TLS/SSL configuration + ssl_ca = "/etc/telegraf/ca.pem" + ssl_cert = "/etc/telegraf/cert.cer" + ssl_key = "/etc/telegraf/key.key" + insecure_skip_verify = false + + # HTTP response timeout (default: 5s) + response_timeout = "5s" ` func (n *Nginx) SampleConfig() string {