From 254562053b6e359fa7838251f3b59efac250a539 Mon Sep 17 00:00:00 2001 From: Mike Moein Date: Fri, 21 Jun 2019 15:25:45 -0400 Subject: [PATCH] Add TLS mutual auth supoort to jti_openconfig_telemetry plugin (#6027) --- etc/telegraf.conf | 9 ++-- .../inputs/jti_openconfig_telemetry/README.md | 9 ++-- .../openconfig_telemetry.go | 52 +++++++++++-------- 3 files changed, 43 insertions(+), 27 deletions(-) diff --git a/etc/telegraf.conf b/etc/telegraf.conf index cf2a0d9332919..03427e9131c5f 100644 --- a/etc/telegraf.conf +++ b/etc/telegraf.conf @@ -4772,9 +4772,12 @@ # "/interfaces", # ] # -# ## x509 Certificate to use with TLS connection. If it is not provided, an insecure -# ## channel will be opened with server -# ssl_cert = "/etc/telegraf/cert.pem" +# ## Optional TLS Config +# tls_ca = "/etc/telegraf/ca.pem" +# tls_cert = "/etc/telegraf/cert.pem" +# tls_key = "/etc/telegraf/key.pem" +# ## Use TLS but skip chain & host verification +# insecure_skip_verify = false # # ## Delay between retry attempts of failed RPC calls or streams. Defaults to 1000ms. # ## Failed streams/calls will not be retried if 0 is provided diff --git a/plugins/inputs/jti_openconfig_telemetry/README.md b/plugins/inputs/jti_openconfig_telemetry/README.md index 7c30aaa8d3460..c0cdf0168025a 100644 --- a/plugins/inputs/jti_openconfig_telemetry/README.md +++ b/plugins/inputs/jti_openconfig_telemetry/README.md @@ -41,9 +41,12 @@ This plugin reads Juniper Networks implementation of OpenConfig telemetry data f "/interfaces", ] - ## x509 Certificate to use with TLS connection. If it is not provided, an insecure - ## channel will be opened with server - ssl_cert = "/etc/telegraf/cert.pem" + ## Optional TLS Config + # tls_ca = "/etc/telegraf/ca.pem" + # tls_cert = "/etc/telegraf/cert.pem" + # tls_key = "/etc/telegraf/key.pem" + ## Use TLS but skip chain & host verification + # insecure_skip_verify = false ## Delay between retry attempts of failed RPC calls or streams. Defaults to 1000ms. ## Failed streams/calls will not be retried if 0 is provided diff --git a/plugins/inputs/jti_openconfig_telemetry/openconfig_telemetry.go b/plugins/inputs/jti_openconfig_telemetry/openconfig_telemetry.go index b721c4943777a..536383732ca6c 100644 --- a/plugins/inputs/jti_openconfig_telemetry/openconfig_telemetry.go +++ b/plugins/inputs/jti_openconfig_telemetry/openconfig_telemetry.go @@ -1,6 +1,7 @@ package jti_openconfig_telemetry import ( + "crypto/tls" "fmt" "log" "net" @@ -11,6 +12,7 @@ import ( "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/internal" + internaltls "github.com/influxdata/telegraf/internal/tls" "github.com/influxdata/telegraf/plugins/inputs" "github.com/influxdata/telegraf/plugins/inputs/jti_openconfig_telemetry/auth" "github.com/influxdata/telegraf/plugins/inputs/jti_openconfig_telemetry/oc" @@ -28,13 +30,17 @@ type OpenConfigTelemetry struct { Password string ClientID string `toml:"client_id"` SampleFrequency internal.Duration `toml:"sample_frequency"` - SSLCert string `toml:"ssl_cert"` StrAsTags bool `toml:"str_as_tags"` RetryDelay internal.Duration `toml:"retry_delay"` - sensorsConfig []sensorConfig + sensorsConfig []sensorConfig + + // GRPC settings grpcClientConns []*grpc.ClientConn - wg *sync.WaitGroup + EnableTLS bool `toml:"enable_tls"` + internaltls.ClientConfig + + wg *sync.WaitGroup } var ( @@ -74,10 +80,13 @@ var ( "/interfaces", ] - ## x509 Certificate to use with TLS connection. If it is not provided, an insecure - ## channel will be opened with server - ssl_cert = "/etc/telegraf/cert.pem" - + ## Optional TLS Config + # tls_ca = "/etc/telegraf/ca.pem" + # tls_cert = "/etc/telegraf/cert.pem" + # tls_key = "/etc/telegraf/key.pem" + ## Use TLS but skip chain & host verification + # insecure_skip_verify = false + ## Delay between retry attempts of failed RPC calls or streams. Defaults to 1000ms. ## Failed streams/calls will not be retried if 0 is provided retry_delay = "1000ms" @@ -343,21 +352,27 @@ func (m *OpenConfigTelemetry) collectData(ctx context.Context, } func (m *OpenConfigTelemetry) Start(acc telegraf.Accumulator) error { + + var tlscfg *tls.Config + var opts []grpc.DialOption + var err error + // Build sensors config if m.splitSensorConfig() == 0 { return fmt.Errorf("E! No valid sensor configuration available") } - // If SSL certificate is provided, use transport credentials - var err error - var transportCredentials credentials.TransportCredentials - if m.SSLCert != "" { - transportCredentials, err = credentials.NewClientTLSFromFile(m.SSLCert, "") - if err != nil { - return fmt.Errorf("E! Failed to read certificate: %v", err) + // Parse TLS config + if m.EnableTLS { + if tlscfg, err = m.ClientConfig.TLSConfig(); err != nil { + return err } + } + + if tlscfg != nil { + opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(tlscfg))) } else { - transportCredentials = nil + opts = append(opts, grpc.WithInsecure()) } // Connect to given list of servers and start collecting data @@ -373,12 +388,7 @@ func (m *OpenConfigTelemetry) Start(acc telegraf.Accumulator) error { continue } - // If a certificate is provided, open a secure channel. Else open insecure one - if transportCredentials != nil { - grpcClientConn, err = grpc.Dial(server, grpc.WithTransportCredentials(transportCredentials)) - } else { - grpcClientConn, err = grpc.Dial(server, grpc.WithInsecure()) - } + grpcClientConn, err = grpc.Dial(server, opts...) if err != nil { log.Printf("E! Failed to connect to %s: %v", server, err) } else {