Add TLS support to socket_writer and socket_listener plugins (#4021)

This commit is contained in:
Bob Shannon 2018-04-17 20:02:04 -04:00 committed by Daniel Nelson
parent 97c7ea5dca
commit 86933ebb7f
11 changed files with 314 additions and 14 deletions

View File

@ -112,9 +112,10 @@ func RandomString(n int) string {
return string(bytes) return string(bytes)
} }
// GetTLSConfig gets a tls.Config object from the given certs, key, and CA files. // GetTLSConfig gets a tls.Config object from the given certs, key, and CA files
// you must give the full path to the files. // for use with a client.
// If all files are blank and InsecureSkipVerify=false, returns a nil pointer. // The full path to each file must be provided.
// Returns a nil pointer if all files are blank and InsecureSkipVerify=false.
func GetTLSConfig( func GetTLSConfig(
SSLCert, SSLKey, SSLCA string, SSLCert, SSLKey, SSLCA string,
InsecureSkipVerify bool, InsecureSkipVerify bool,
@ -155,6 +156,50 @@ func GetTLSConfig(
return t, nil return t, nil
} }
// GetServerTLSConfig gets a tls.Config object from the given certs, key, and one or more CA files
// for use with a server.
// The full path to each file must be provided.
// Returns a nil pointer if all files are blank.
func GetServerTLSConfig(
TLSCert, TLSKey string,
TLSAllowedCACerts []string,
) (*tls.Config, error) {
if TLSCert == "" && TLSKey == "" && len(TLSAllowedCACerts) == 0 {
return nil, nil
}
t := &tls.Config{}
if len(TLSAllowedCACerts) != 0 {
caCertPool := x509.NewCertPool()
for _, cert := range TLSAllowedCACerts {
c, err := ioutil.ReadFile(cert)
if err != nil {
return nil, errors.New(fmt.Sprintf("Could not load TLS CA: %s",
err))
}
caCertPool.AppendCertsFromPEM(c)
}
t.ClientCAs = caCertPool
t.ClientAuth = tls.RequireAndVerifyClientCert
}
if TLSCert != "" && TLSKey != "" {
cert, err := tls.LoadX509KeyPair(TLSCert, TLSKey)
if err != nil {
return nil, errors.New(fmt.Sprintf(
"Could not load TLS client key/certificate from %s:%s: %s",
TLSKey, TLSCert, err))
}
t.Certificates = []tls.Certificate{cert}
}
t.BuildNameToCertificate()
return t, nil
}
// SnakeCase converts the given string to snake case following the Golang format: // SnakeCase converts the given string to snake case following the Golang format:
// acronyms are converted to lower-case and preceded by an underscore. // acronyms are converted to lower-case and preceded by an underscore.
func SnakeCase(in string) string { func SnakeCase(in string) string {

View File

@ -35,6 +35,13 @@ This is a sample configuration for the plugin.
## 0 (default) is unlimited. ## 0 (default) is unlimited.
# read_timeout = "30s" # read_timeout = "30s"
## Optional TLS configuration.
## Only applies to stream sockets (e.g. TCP).
# tls_cert = "/etc/telegraf/cert.pem"
# tls_key = "/etc/telegraf/key.pem"
## Enables client authentication if set.
# tls_allowed_cacerts = ["/etc/telegraf/clientca.pem"]
## Maximum socket buffer size in bytes. ## Maximum socket buffer size in bytes.
## For stream sockets, once the buffer fills up, the sender will start backing up. ## For stream sockets, once the buffer fills up, the sender will start backing up.
## For datagram sockets, once the buffer fills up, metrics will start dropping. ## For datagram sockets, once the buffer fills up, metrics will start dropping.

View File

@ -12,6 +12,7 @@ import (
"time" "time"
"crypto/tls"
"github.com/influxdata/telegraf" "github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/internal" "github.com/influxdata/telegraf/internal"
"github.com/influxdata/telegraf/plugins/inputs" "github.com/influxdata/telegraf/plugins/inputs"
@ -122,9 +123,9 @@ func (ssl *streamSocketListener) read(c net.Conn) {
} }
if err := scnr.Err(); err != nil { if err := scnr.Err(); err != nil {
if err, ok := err.(net.Error); ok && err.Timeout() { if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
log.Printf("D! Timeout in plugin [input.socket_listener]: %s", err) log.Printf("D! Timeout in plugin [input.socket_listener]: %s", err)
} else if !strings.HasSuffix(err.Error(), ": use of closed network connection") { } else if netErr != nil && !strings.HasSuffix(err.Error(), ": use of closed network connection") {
ssl.AddError(err) ssl.AddError(err)
} }
} }
@ -159,11 +160,14 @@ func (psl *packetSocketListener) listen() {
} }
type SocketListener struct { type SocketListener struct {
ServiceAddress string ServiceAddress string `toml:"service_address"`
MaxConnections int MaxConnections int `toml:"max_connections"`
ReadBufferSize int ReadBufferSize int `toml:"read_buffer_size"`
ReadTimeout *internal.Duration ReadTimeout *internal.Duration `toml:"read_timeout"`
KeepAlivePeriod *internal.Duration TLSAllowedCACerts []string `toml:"tls_allowed_cacerts"`
TLSCert string `toml:"tls_cert"`
TLSKey string `toml:"tls_key"`
KeepAlivePeriod *internal.Duration `toml:"keep_alive_period"`
parsers.Parser parsers.Parser
telegraf.Accumulator telegraf.Accumulator
@ -198,6 +202,13 @@ func (sl *SocketListener) SampleConfig() string {
## 0 (default) is unlimited. ## 0 (default) is unlimited.
# read_timeout = "30s" # read_timeout = "30s"
## Optional TLS configuration.
## Only applies to stream sockets (e.g. TCP).
# tls_cert = "/etc/telegraf/cert.pem"
# tls_key = "/etc/telegraf/key.pem"
## Enables client authentication if set.
# tls_allowed_cacerts = ["/etc/telegraf/clientca.pem"]
## Maximum socket buffer size in bytes. ## Maximum socket buffer size in bytes.
## For stream sockets, once the buffer fills up, the sender will start backing up. ## For stream sockets, once the buffer fills up, the sender will start backing up.
## For datagram sockets, once the buffer fills up, metrics will start dropping. ## For datagram sockets, once the buffer fills up, metrics will start dropping.
@ -242,7 +253,21 @@ func (sl *SocketListener) Start(acc telegraf.Accumulator) error {
switch spl[0] { switch spl[0] {
case "tcp", "tcp4", "tcp6", "unix", "unixpacket": case "tcp", "tcp4", "tcp6", "unix", "unixpacket":
l, err := net.Listen(spl[0], spl[1]) var (
err error
l net.Listener
)
tlsCfg, err := internal.GetServerTLSConfig(sl.TLSCert, sl.TLSKey, sl.TLSAllowedCACerts)
if err != nil {
return nil
}
if tlsCfg == nil {
l, err = net.Listen(spl[0], spl[1])
} else {
l, err = tls.Listen(spl[0], spl[1], tlsCfg)
}
if err != nil { if err != nil {
return err return err
} }
@ -313,6 +338,14 @@ func (uc unixCloser) Close() error {
return err return err
} }
func (uc unixCloser) Accept() (net.Conn, error) {
return uc.closer.(net.Listener).Accept()
}
func (uc unixCloser) Addr() net.Addr {
return uc.closer.(net.Listener).Addr()
}
func init() { func init() {
inputs.Add("socket_listener", func() telegraf.Input { return newSocketListener() }) inputs.Add("socket_listener", func() telegraf.Input { return newSocketListener() })
} }

View File

@ -2,12 +2,14 @@ package socket_listener
import ( import (
"bytes" "bytes"
"crypto/tls"
"log" "log"
"net" "net"
"os" "os"
"testing" "testing"
"time" "time"
"github.com/influxdata/telegraf/internal"
"github.com/influxdata/telegraf/testutil" "github.com/influxdata/telegraf/testutil"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -25,6 +27,52 @@ func testEmptyLog(t *testing.T) func() {
} }
} }
func TestSocketListener_tcp_tls(t *testing.T) {
defer testEmptyLog(t)()
sl := newSocketListener()
sl.ServiceAddress = "tcp://127.0.0.1:0"
sl.TLSCert = "testdata/server.pem"
sl.TLSKey = "testdata/server.key"
sl.TLSAllowedCACerts = []string{"testdata/ca.pem"}
acc := &testutil.Accumulator{}
err := sl.Start(acc)
require.NoError(t, err)
defer sl.Stop()
tlsCfg, err := internal.GetTLSConfig("testdata/client.pem", "testdata/client.key", "testdata/ca.pem", true)
require.NoError(t, err)
secureClient, err := tls.Dial("tcp", sl.Closer.(net.Listener).Addr().String(), tlsCfg)
require.NoError(t, err)
testSocketListener(t, sl, secureClient)
}
func TestSocketListener_unix_tls(t *testing.T) {
defer testEmptyLog(t)()
sl := newSocketListener()
sl.ServiceAddress = "unix:///tmp/telegraf_test.sock"
sl.TLSCert = "testdata/server.pem"
sl.TLSKey = "testdata/server.key"
sl.TLSAllowedCACerts = []string{"testdata/ca.pem"}
acc := &testutil.Accumulator{}
err := sl.Start(acc)
require.NoError(t, err)
defer sl.Stop()
tlsCfg, err := internal.GetTLSConfig("testdata/client.pem", "testdata/client.key", "testdata/ca.pem", true)
require.NoError(t, err)
secureClient, err := tls.Dial("unix", "/tmp/telegraf_test.sock", tlsCfg)
require.NoError(t, err)
testSocketListener(t, sl, secureClient)
}
func TestSocketListener_tcp(t *testing.T) { func TestSocketListener_tcp(t *testing.T) {
defer testEmptyLog(t)() defer testEmptyLog(t)()

View File

@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFVTCCAz2gAwIBAgIJAOhLvwv6zUf+MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
BAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG
A1UECgwEVGVzdDAeFw0xODA0MTcwNDIwNDZaFw0yMTAyMDQwNDIwNDZaMEExCzAJ
BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEN
MAsGA1UECgwEVGVzdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKwE
Xy814CDH03G3Fg2/XSpYZXVMzwp6oq/bUe3iLhkOpA6C4+j07AxAAa22qEPlvYkb
W7oxVJiL0ih1od2FeAxvroBTmjG54j/Syb8OeQsZaJLNp1rRmwYGBIVi284ScaIc
dn+2bfmfpSLjK3SbU5XygtwIE3gh/B7x02UJRNJmJ1faRT2CfTeg/56xnTE4bcR5
HRrlojoN5laJngowLWAEAvWljCR8oge+ciNYB3xoK8Hgc9+WgTy95G1RBCNkaFFI
73nrcHl6dGOH9UgIqfbHJYxNEarI3o/JAr8DIBS0W4r8r4aY4JQ4LoN3bg4mLHQq
THKkVW5hyBeWe47qmlL0m4F6/+mzVi95NAWG2BQDCZJAWJNc+PbSRHi81838m7ff
O4rixd/F53LUUas8/zVca3vtv+XjOHZzIQLIy1bM4MhzpHlRcSmS9kqxxZ3S70e3
ZIWFdM0iRrtlBbJeoHIJRDpgPRYIWdRc6XotljTTi6/lN4Bj/0NK4E3iONcDsscN
kiqEHRAWZ4ptCqdVPgYR0S096Fx6OaC3ASODE0Cjb18ylZQRsQi8TiYSihGzuoio
wJwSLdIifDbbSUkjT1384cA/HsOjFQ9xHXYa6cQnAg3TUZyG1lAMJyFWYke+rxmG
srfL/EtIzgbzmEOC5anQjA2pdgUO9Pk2SinJaMApAgMBAAGjUDBOMB0GA1UdDgQW
BBQNJctDLjj8bVKNCYANaOcboPQnmzAfBgNVHSMEGDAWgBQNJctDLjj8bVKNCYAN
aOcboPQnmzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQATSr26Kc8g
3l2zuccoKWM57DQcgRmzSYwEOKA2jn3FWmrAdwozEIkLaTK0OXz0zh2dZxh9V3GR
w0WFCynbGNy/9s33MSi+zIWJOU/MZvt6zGE5CTcTgZ+u5IZyvSubMkPcwQi3Yvcg
AHmWzpF42kT2J5C5MfrSU65hrhPX7hT/CUoV3gN7oxFzj+/ED4kgNorO8SUUJCmq
DJNFbjgsD63EhnvAhn1AeM35GmKdl2enEKqcZsRkE4ZLpU7ibrThEm1aOQuJUtHk
gDAx49QMdQpWnxWxnfoiwpLu7ufR7ls8O9oA8ZJux/SVHEmtkOdRsuMtY5MElFZg
dANlQsdFWDko4ixaxFYzppuPNnRlqjGNnaEFJrNc2KR0Dxgmp28Yh2VyLd4r3fLT
nLVBYF8KzFchUdXYYPNBXwAf/N52jGfugDx8snLxOfzxoUZ4y64qMCpYhntGgBJ1
Rrk2trcn3Dw19gi8p3ylbdoz/Ch1INDDrO35pd0bZpcwASc/UNU72W5v2kGL0H7o
nJzgtrqeHcoIzNBmBhHlMlnTF5GMfrYGsf5d30KyKv7UL6qJTvT641dpKpB/FFrk
y3AQbKmKRDI+aVzeOlwdy/eJAwt7FikD4bR9GZ4PBX9n9jd4u/PHZNfxtgzplqo1
oy7kJv0cB/vRKOblmn/vPUfTFtAX7M3GkQ==
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAmRuY+9Gg5V4e9hCd2mYek1jKeoaZijz89EPvox78XzoGdxPf
RoukUcTVS9VWN7HyJBjRA9P+KuHI9dX47skxyxH53uXZvRmGQAJBY4cE07JHvGkZ
eK1heXoWlBzYtivckha7bLBfn1ttAzcFCblUfJdzsn9XDuC4Jfn4oSaKn1o8Rzy1
KRvyLgvsYxMA/XzhyBzVMyoUOulye7EZx4f+AwSNmNHD4OgtxxPofrrMOtXZ2tC6
xNOexIZXbsB9dyrUW+4pWXYaadU7fl2V+arAJj+NVxV+3tmGGjmd1MiIypPx6BbP
g7xH20nJ/Y0U6V7gklZpYO1i84RbtR/kqBgi9QIDAQABAoIBAEONJJM+KyHnw/tG
246HbcgO7c7fYhDW1bgj3S/4NNsC6+VP1Dv40nftQzphFtgd37rDZDyvJL3gvlyQ
mnMoO5rgBIGuocHH6C6HkDgMUznft7zOFhnjTVVeY2XX0FmXwoqGEw1iR940ZUV8
2fEvXrJV1AsWGeALj9PZlTPsoE6rv5sUk9Lh3wCD73m7GSg7DzBRE+6bBze8Lmwn
ZzTvmimhgPJw8LR5rRpYbDbhAJLAfgA7/yPgYEPxA/ffry6Ba4epj8tVNUNOAcOf
PURF+uuIF7RceI2PkdvoNuQyVR5oxQUPUfidfVK5ClUmnHECSgb/FFnYC+nU2vSi
IAnmC6ECgYEAyrUFHyxxuIQAiinjBxa0OQ3ynvMxDnF/+zvWe8536Y61lz9dblKb
0xvFhpOEMfiG/zFdZdWJ+xdq7VQVNMHu4USoskG8sZs5zImMTu50kuDNln7xYqVf
SUuN1U7cp7JouI1qkZAOsytPfAgZN/83hLObd07lAvL44jKYaHVeMmkCgYEAwVxZ
wKXpboHwQawA+4ubsnZ36IlOk21/+FlGJiDg/LB643BS+QhgVNxuB2gL1gOCYkhl
6BBcIhWMvZOIIo5uwnv4fQ+WfFwntU9POFViZgbZvkitQtorB7MXc/NU2BDrNYx2
TBCiRn/9BaZ4fziW8I3Fx3xQ3rKDBXrexmrJQq0CgYEAvYGQYT12r47Qxlo0gcsL
AA/3E/y9jwgzItglQ6eZ2ULup5C4s0wNm8Zp2s+Mlf8HjgpDi9Gf5ptU/r1N+f2Y
awd6QvRMCSraVUr+Xkh1uV7rNNhGqPd75pT460OH7EtRtb+XsrAf3gcOjyEvGnfC
GpCjNl4OobwvS6ELdRTM1IkCgYAHUGX4uo3k5zdeVJJI8ZP3ITIR8retLfQsQbw8
jvvTsx1C4ynQT7fNHfVvhEkGVGWnMBPivlOt2mDTfvQkUnzwEF5q5J8NnzLFUfWu
LNSnBVVRNFCRec0s4mJduXOZJLKw+No0sGBjCE5a21wte8eB2+sCS7qHYftAxtAM
c1eflQKBgQDGTFsMvpM8BEPTreinTllFBdjeYchcdY/Ov9DZ3mMVopjAWRD81MKM
zM1RCqwLkgv9FvF79B1FLJ1Inr8e/XIGdcrhE1a4sZdIWdqTWQ4xFrlDgxCquq66
da09WVBRdvq2kVLAMaBViH2/GP1G4ZV9a8+JHuWKj+Arrr52Qeazjw==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEEjCCAfoCCQCmcronmMSqXTANBgkqhkiG9w0BAQsFADBBMQswCQYDVQQGEwJV
UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNVBAoM
BFRlc3QwHhcNMTgwNDE3MDQyNDMwWhcNNDUwOTAyMDQyNDMwWjBVMQswCQYDVQQG
EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xITAfBgNV
BAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAJkbmPvRoOVeHvYQndpmHpNYynqGmYo8/PRD76Me/F86BncT
30aLpFHE1UvVVjex8iQY0QPT/irhyPXV+O7JMcsR+d7l2b0ZhkACQWOHBNOyR7xp
GXitYXl6FpQc2LYr3JIWu2ywX59bbQM3BQm5VHyXc7J/Vw7guCX5+KEmip9aPEc8
tSkb8i4L7GMTAP184cgc1TMqFDrpcnuxGceH/gMEjZjRw+DoLccT6H66zDrV2drQ
usTTnsSGV27AfXcq1FvuKVl2GmnVO35dlfmqwCY/jVcVft7Zhho5ndTIiMqT8egW
z4O8R9tJyf2NFOle4JJWaWDtYvOEW7Uf5KgYIvUCAwEAATANBgkqhkiG9w0BAQsF
AAOCAgEACJkccOvBavtagiMQc9OLsbo0PkHv7Qk9uTm5Sg9+LjLGUsu+3WLjAAmj
YScHyGbvQzXlwpgo8JuwY0lMNoPfwGuydlJPfOBCbaoAqFp6Vpc/E49J9YovCsqa
2HJUJeuxpf6SiH1Vc1SECjzwzKo03t8ul7t7SNVqA0r9fV4I936FlJOeQ4d5U+Wv
H7c2LmAqbHi2Mwf+m+W6ziOvzp+szspcP2gJDX7hsKEtIlqmHYm2bzZ4fsCuU9xN
3quewBVQUOuParO632yaLgzpGmfzzxLmCPO84lxarJKCxjHG2Q2l30TO/wA44m+r
Wd17HpCT3PkCDG5eSNCSnYqfLm8DE1hLGfHiXxKmrgU94q4wvwVGOlcYa+CQeP9Q
ZW3Tj0Axz0Mqlg1iLLo12+Z/yocSY2nFnFntBFT4qBKNCeD0xH3PxC0HJdK66xBv
MVDE/OE2hBtTTts+vC9yjx4W8thtMSA4VCOgtt5sHjt3ZekiYYh5VZK47Bx/a0uc
8CouRdyppWyPp/cNC+PcGW3YnXpAkxe/bSY/qgfK5kmbeOf+HzvZAIwAH/d9VK0g
AoLNp46eP6U2E2lVvtc/HJ1C/gsiC/1TSIq/kBbYtuIJjhhH3u6IVet7WSD22Akv
o5gOpcoKwy8IPDRC5lJEAAVYUKt7ORo2en3OVg6I4FaQmeBFp5s=
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAzkEDLijGOqXNQPAqUjOz5TLuM28SENauknLtcfIyEN/N6PwZ
re5DjokxtDPp+c9yP/9qtn7+dBfdUXg2Mu7HQz8lAKniir2ZH+axkjp5LUE6vYJd
I1W8lOOc0kXDjozBetgriE0jkgc3v9oDBbLhN5waKR86jpQaNkfnI7/4U3yrlymK
yaT3uD6L1ldUJubdQ/xc1HxdmX8VewBnkK1urYyiRbju2iL9YmtSM72yWXvFsD1O
I4fP/XuiaymicBmXKL4cu6KYdfn1qeLAV3U35xG597M031WmR5o67rc63sqs+Q//
V3dbGqnFXRMkLhoOnuKK0DD28ujY1kctbNQWVQIDAQABAoIBAHFxFJy41H7BXulO
rxhTU6jGoHktqBQW4CGwkKTRf3QEhK6WqlEd8Y5eKzZgL1q1HLPSehEyPCYCUjpT
EgxlhLeZ7XI1/mIs8iG3swconimj7Pj60Nt0dqq1njWRJYQsKua0Kw1m0B+rVKBy
+qKRxondlA32HTD6iIg+eAUTuzO/KzimZcyL9hiT/g6aN9k0H5+qURi8dO7VV8fD
zvP8Y+oOGLwW2ccp+ZjFQizjTOkL4lgldr0hsGQXZJNHL94fA7jPdAxAUbnTicMJ
oXM++L3eCwIVabipGxxlqCMj9Dn8yfbQvRGzP2e76QDeROYZHX4osH6vLcZEjx9i
tJ4J+ekCgYEA82kKzkSKmFo4gZxnqAywlfZ2X2PADuMmHdqdiDFwt54orlMlKf/b
wVSvN/djLXwvFHuyzFmJeMFSHKFkYVTOsh8kPSETAIGkcJEMHD3viYn7DwjkQudY
vB/FpBWSiDT0T7qDUCzW3iMbx/JvTUSp7uO4ZuwOu6t6v3PEZwIChQ8CgYEA2Ov9
FXHmm7sS54HgvZd6Wk8zLMLIDnyMmECjtYOasJ9c40yQHpRlXsb+Dzn/2xhMMwth
Bln2hIiJ/e+G0bzFu4x0cItRPOQeRNyz5Pal8EsATeUwcX4KRKOZaUpDkV6XV1L0
r/HSk/wed+90B74sGoJY1qsFflOATIUVs7SIllsCgYEAwhGSB/sl9WqZet1U1+um
LyqeHlfNnREGJu9Sgm/Iyt1S2gp4qw/QCkiWmyym6nEEqHQnjj4lGR4pdaJIAkI3
ulSR9BsWp2S10voSicHn5eUZQld4hs8lNHiwf66jce2mjJrMb3QQrHOZhsWIcDa6
tjjhoU28QWzrJRIMGYTEtYkCgYA17NSJlDsj06mra5oXB6Ue9jlekz1wfH3nC4qn
AQRfi/5ncw0QzQs2OHnIBz8XlD69IcMI9SxXXioPuo/la+wr54q6v6d+X6c2rzb5
YGd4CO0WcDdOv2qGDbWBezi41q8AwlqZsqAKsc5ROnG5ywjjviufkfxXnyJx41O1
zNd3qQKBgGEy+EwUXD5iGeQxdCDnd6iVu14SoBscHO5SpIeDu3DIhnu+7gPq2VMg
Vp9j/iNVtEA3HyYCOeXc2rz9Di1wwt3YijED4birLAkC5YW6YB9rmLMfCNc1EyLh
BKAkUQN3D+XCN4pXdbKvbkOcfYRUHoD+pPBjRYH020OtPBUc6Wkl
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIEJjCCAg4CCQCmcronmMSqXDANBgkqhkiG9w0BAQsFADBBMQswCQYDVQQGEwJV
UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNVBAoM
BFRlc3QwHhcNMTgwNDE3MDQyNDAwWhcNNDUwOTAyMDQyNDAwWjBpMQswCQYDVQQG
EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xITAfBgNV
BAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJMTI3LjAuMC4x
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzkEDLijGOqXNQPAqUjOz
5TLuM28SENauknLtcfIyEN/N6PwZre5DjokxtDPp+c9yP/9qtn7+dBfdUXg2Mu7H
Qz8lAKniir2ZH+axkjp5LUE6vYJdI1W8lOOc0kXDjozBetgriE0jkgc3v9oDBbLh
N5waKR86jpQaNkfnI7/4U3yrlymKyaT3uD6L1ldUJubdQ/xc1HxdmX8VewBnkK1u
rYyiRbju2iL9YmtSM72yWXvFsD1OI4fP/XuiaymicBmXKL4cu6KYdfn1qeLAV3U3
5xG597M031WmR5o67rc63sqs+Q//V3dbGqnFXRMkLhoOnuKK0DD28ujY1kctbNQW
VQIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQCVgzqFrehoRAMFLMEL8avfokYtsSYc
50Yug4Es0ISo/PRWGeUnv8k1inyE3Y1iR/gbN5n/yjLXJKEflan6BuqGuukfr2eA
fRdDCyPvzQLABdxCx2n6ByQFxj92z82tizf35R2OMuHHWzTckta+7s5EvxwIiUsd
rUuXp+0ltJzlYYW9xTGFiJO9hAbRgMgZiwL8F7ayic8GmLQ1eRK/DfKDCOH3afeX
MNN5FulgjqNyhXHF33vwgIJynGDg2JEhkWjB1DkUAxll0+SMQoYyVGZVrQSGbGw1
JhOLc8C8bTzfK3qcJDuyldvjiut+To+lpu76R0u0+sn+wxQFL1uCWuAbMJgGsJgM
ARavu2XDeae9X+e8MgJuN1FYS3tihBplPjMJD3UYRybRvHAvQh26BZ7Ch3JNSNST
AL2l5T7JKU+XaWWeo+crV+AnGIJyqyh9Su/n97PEoZoEMGH4Kcl/n/w2Jms60+5s
K0FK2OGNL42ddUfQiVL9CwYQQo70hydjsIo1x8S6+tSFLMAAysQEToSjfAA6qxDu
fgGVMuIYHo0rSkpTVsHVwru08Z5o4m+XDAK0iHalZ4knKsO0lJ+9l7vFnQHlzwt7
JTjDhnyOKWPIANeWf3PrHPWE7kKpFVBqFBzOvWLJuxDu5NlgLo1PFahsahTqB9bz
qwUyMg/oYWnwqw==
-----END CERTIFICATE-----

View File

@ -19,6 +19,13 @@ It can output data in any of the [supported output formats](https://github.com/i
# address = "unix:///tmp/telegraf.sock" # address = "unix:///tmp/telegraf.sock"
# address = "unixgram:///tmp/telegraf.sock" # address = "unixgram:///tmp/telegraf.sock"
## 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
## Period between keep alive probes. ## Period between keep alive probes.
## Only applies to TCP sockets. ## Only applies to TCP sockets.
## 0 disables keep alive probes. ## 0 disables keep alive probes.

View File

@ -6,6 +6,7 @@ import (
"net" "net"
"strings" "strings"
"crypto/tls"
"github.com/influxdata/telegraf" "github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/internal" "github.com/influxdata/telegraf/internal"
"github.com/influxdata/telegraf/plugins/outputs" "github.com/influxdata/telegraf/plugins/outputs"
@ -13,8 +14,12 @@ import (
) )
type SocketWriter struct { type SocketWriter struct {
Address string Address string
KeepAlivePeriod *internal.Duration KeepAlivePeriod *internal.Duration
SSLCA string
SSLCert string
SSLKey string
InsecureSkipVerify bool
serializers.Serializer serializers.Serializer
@ -39,6 +44,13 @@ func (sw *SocketWriter) SampleConfig() string {
# address = "unix:///tmp/telegraf.sock" # address = "unix:///tmp/telegraf.sock"
# address = "unixgram:///tmp/telegraf.sock" # address = "unixgram:///tmp/telegraf.sock"
## 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
## Period between keep alive probes. ## Period between keep alive probes.
## Only applies to TCP sockets. ## Only applies to TCP sockets.
## 0 disables keep alive probes. ## 0 disables keep alive probes.
@ -58,12 +70,26 @@ func (sw *SocketWriter) SetSerializer(s serializers.Serializer) {
} }
func (sw *SocketWriter) Connect() error { func (sw *SocketWriter) Connect() error {
var (
c net.Conn
err error
)
spl := strings.SplitN(sw.Address, "://", 2) spl := strings.SplitN(sw.Address, "://", 2)
if len(spl) != 2 { if len(spl) != 2 {
return fmt.Errorf("invalid address: %s", sw.Address) return fmt.Errorf("invalid address: %s", sw.Address)
} }
c, err := net.Dial(spl[0], spl[1]) tlsCfg, err := internal.GetTLSConfig(sw.SSLCert, sw.SSLKey, sw.SSLCA, sw.InsecureSkipVerify)
if err != nil {
return err
}
if tlsCfg == nil {
c, err = net.Dial(spl[0], spl[1])
} else {
c, err = tls.Dial(spl[0], spl[1], tlsCfg)
}
if err != nil { if err != nil {
return err return err
} }