From 8866e547d36b408b7c7264de1a37e9d7b78dc153 Mon Sep 17 00:00:00 2001 From: Dheeraj Dwivedi Date: Wed, 14 Jun 2017 02:12:11 +0530 Subject: [PATCH] Add secure connection support to graphite output (#2602) --- etc/telegraf.conf | 7 +++++ plugins/outputs/graphite/README.md | 25 +++++++++++++++++ plugins/outputs/graphite/graphite.go | 42 +++++++++++++++++++++++++++- 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/etc/telegraf.conf b/etc/telegraf.conf index 5c105a30aa869..8aa9427c48c9f 100644 --- a/etc/telegraf.conf +++ b/etc/telegraf.conf @@ -270,6 +270,13 @@ # template = "host.tags.measurement.field" # ## timeout in seconds for the write connection to graphite # timeout = 2 +# +# ## 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 # # Send telegraf metrics to graylog(s) diff --git a/plugins/outputs/graphite/README.md b/plugins/outputs/graphite/README.md index 3e2369e214be7..1b173962f8bbd 100644 --- a/plugins/outputs/graphite/README.md +++ b/plugins/outputs/graphite/README.md @@ -19,6 +19,13 @@ via raw TCP. template = "host.tags.measurement.field" ## timeout in seconds for the write connection to graphite timeout = 2 + + ## 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 ``` Parameters: @@ -28,9 +35,27 @@ Parameters: Timeout int Template string + // Path to CA file + SSLCA string + // Path to host cert file + SSLCert string + // Path to cert key file + SSLKey string + // Skip SSL verification + InsecureSkipVerify bool + +### Required parameters: + * `servers`: List of strings, ["mygraphiteserver:2003"]. * `prefix`: String use to prefix all sent metrics. * `timeout`: Connection timeout in seconds. * `template`: Template for graphite output format, see https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md for more details. + +### Optional parameters: + +* `ssl_ca`: SSL CA +* `ssl_cert`: SSL CERT +* `ssl_key`: SSL key +* `insecure_skip_verify`: Use SSL but skip chain & host verification (default: false) diff --git a/plugins/outputs/graphite/graphite.go b/plugins/outputs/graphite/graphite.go index 8d4447cdd4d20..180217214fd32 100644 --- a/plugins/outputs/graphite/graphite.go +++ b/plugins/outputs/graphite/graphite.go @@ -1,6 +1,7 @@ package graphite import ( + "crypto/tls" "errors" "io" "log" @@ -9,6 +10,7 @@ import ( "time" "github.com/influxdata/telegraf" + "github.com/influxdata/telegraf/internal" "github.com/influxdata/telegraf/plugins/outputs" "github.com/influxdata/telegraf/plugins/serializers" ) @@ -20,6 +22,18 @@ type Graphite struct { Template string Timeout int conns []net.Conn + + // Path to CA file + SSLCA string `toml:"ssl_ca"` + // Path to host cert file + SSLCert string `toml:"ssl_cert"` + // Path to cert key file + SSLKey string `toml:"ssl_key"` + // Skip SSL verification + InsecureSkipVerify bool + + // tls config + tlsConfig *tls.Config } var sampleConfig = ` @@ -34,6 +48,13 @@ var sampleConfig = ` template = "host.tags.measurement.field" ## timeout in seconds for the write connection to graphite timeout = 2 + + ## 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 (g *Graphite) Connect() error { @@ -44,10 +65,29 @@ func (g *Graphite) Connect() error { if len(g.Servers) == 0 { g.Servers = append(g.Servers, "localhost:2003") } + + // Set tls config + var err error + g.tlsConfig, err = internal.GetTLSConfig( + g.SSLCert, g.SSLKey, g.SSLCA, g.InsecureSkipVerify) + if err != nil { + return err + } + // Get Connections var conns []net.Conn for _, server := range g.Servers { - conn, err := net.DialTimeout("tcp", server, time.Duration(g.Timeout)*time.Second) + // Dialer with timeout + d := net.Dialer{Timeout: time.Duration(g.Timeout) * time.Second} + + // Get secure connection if tls config is set + var conn net.Conn + if g.tlsConfig != nil { + conn, err = tls.DialWithDialer(&d, "tcp", server, g.tlsConfig) + } else { + conn, err = d.Dial("tcp", server) + } + if err == nil { conns = append(conns, conn) }