Skip to content

Commit

Permalink
Update: Improvements on test suite of syslog input plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
leodido committed May 23, 2018
1 parent b2647ed commit 1c27f07
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 280 deletions.
23 changes: 0 additions & 23 deletions plugins/inputs/syslog/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,6 @@ This plugin listens for syslog messages following RFC5424 format. When received

### Configuration:

#### TCP

The minimal configuration is the following:

```toml
[[inputs.syslog]]
address = ":6514"
```

This starts this plugins as a syslog receiver over TCP protocol on port 6514.

#### TLS

To configure it as a TLS syslog receiver as recommended by RFC5425 give it the following configuration:

```toml
Expand All @@ -31,16 +18,6 @@ To configure it as a TLS syslog receiver as recommended by RFC5425 give it the f
tls_key = "/etc/telegraf/key.pem"
```

#### UDP

To configure this plugin as per RFC5426 give it the following configuration:

```toml
[[inputs.syslog]]
protocol = "udp"
address = ":6514"
```

#### Other configs

Other available configurations are:
Expand Down
263 changes: 57 additions & 206 deletions plugins/inputs/syslog/rfc5425_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
package syslog

import (
"bytes"
"crypto/tls"
"crypto/x509"
"fmt"
"io"
"io/ioutil"
"log"
"net"
"sync"
"testing"
"time"

Expand All @@ -20,81 +14,11 @@ import (
)

const (
serviceRootPEM = `-----BEGIN CERTIFICATE-----
MIIBxzCCATCgAwIBAgIJAJb7HqN2BzWWMA0GCSqGSIb3DQEBCwUAMBYxFDASBgNV
BAMMC1RlbGVncmFmIENBMB4XDTE3MTEwNDA0MzEwN1oXDTI3MTEwMjA0MzEwN1ow
FjEUMBIGA1UEAwwLVGVsZWdyYWYgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
AoGBANbkUkK6JQC3rbLcXhLJTS9SX6uXyFwl7bUfpAN5Hm5EqfvG3PnLrogfTGLr
Tq5CRAu/gbbdcMoL9TLv/aaDVnrpV0FslKhqYmkOgT28bdmA7Qtr539aQpMKCfcW
WCnoMcBD5u5h9MsRqpdq+0Mjlsf1H2hSf07jHk5R1T4l8RMXAgMBAAGjHTAbMAwG
A1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBANSrwvpU
t8ihIhpHqgJZ34DM92CZZ3ZHmH/KyqlnuGzjjpnVZiXVrLDTOzrA0ziVhmefY29w
roHjENbFm54HW97ogxeURuO8HRHIVh2U0rkyVxOfGZiUdINHqsZdSnDY07bzCtSr
Z/KsfWXM5llD1Ig1FyBHpKjyUvfzr73sjm/4
-----END CERTIFICATE-----`
serviceCertPEM = `-----BEGIN CERTIFICATE-----
MIIBzzCCATigAwIBAgIBATANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDDAtUZWxl
Z3JhZiBDQTAeFw0xNzExMDQwNDMxMDdaFw0yNzExMDIwNDMxMDdaMBQxEjAQBgNV
BAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsJRss1af
XKrcIjQoAp2kdJIpT2Ya+MRQXJ18b0PP7szh2lisY11kd/HCkd4D4efuIkpszHaN
xwyTOZLOoplxp6fizzgOYjXsJ6SzbO1MQNmq8Ch/+uKiGgFwLX+YxOOsGSDIHNhF
vcBi93cQtCWPBFz6QRQf9yfIAA5KKxUfJcMCAwEAAaMvMC0wCQYDVR0TBAIwADAL
BgNVHQ8EBAMCBSAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQAD
gYEAiC3WI4y9vfYz53gw7FKnNK7BBdwRc43x7Pd+5J/cclWyUZPdmcj1UNmv/3rj
2qcMmX06UdgPoHppzNAJePvMVk0vjMBUe9MmYlafMz0h4ma/it5iuldXwmejFcdL
6wWQp7gVTileCEmq9sNvfQN1FmT3EWf4IMdO2MNat/1If0g=
-----END CERTIFICATE-----`
serviceKeyPEM = `-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCwlGyzVp9cqtwiNCgCnaR0kilPZhr4xFBcnXxvQ8/uzOHaWKxj
XWR38cKR3gPh5+4iSmzMdo3HDJM5ks6imXGnp+LPOA5iNewnpLNs7UxA2arwKH/6
4qIaAXAtf5jE46wZIMgc2EW9wGL3dxC0JY8EXPpBFB/3J8gADkorFR8lwwIDAQAB
AoGBAJaFHxfMmjHK77U0UnrQWFSKFy64cftmlL4t/Nl3q7L68PdIKULWZIMeEWZ4
I0UZiFOwr4em83oejQ1ByGSwekEuiWaKUI85IaHfcbt+ogp9hY/XbOEo56OPQUAd
bEZv1JqJOqta9Ug1/E1P9LjEEyZ5F5ubx7813rxAE31qKtKJAkEA1zaMlCWIr+Rj
hGvzv5rlHH3wbOB4kQFXO4nqj3J/ttzR5QiJW24STMDcbNngFlVcDVju56LrNTiD
dPh9qvl7nwJBANILguR4u33OMksEZTYB7nQZSurqXsq6382zH7pTl29ANQTROHaM
PKC8dnDWq8RGTqKuvWblIzzGIKqIMovZo10CQC96T0UXirITFolOL3XjvAuvFO1Q
EAkdXJs77805m0dCK+P1IChVfiAEpBw3bKJArpAbQIlFfdI953JUp5SieU0CQEub
BSSEKMjh/cxu6peEHnb/262vayuCFKkQPu1sxWewLuVrAe36EKCy9dcsDmv5+rgo
Odjdxc9Madm4aKlaT6kCQQCpAgeblDrrxTrNQ+Typzo37PlnQrvI+0EceAUuJ72G
P0a+YZUeHNRqT2pPN9lMTAZGGi3CtcF2XScbLNEBeXge
-----END RSA PRIVATE KEY-----`
clientRootPEM = serviceRootPEM
clientCertPEM = `-----BEGIN CERTIFICATE-----
MIIBzjCCATegAwIBAgIBAjANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDDAtUZWxl
Z3JhZiBDQTAeFw0xNzExMDQwNDMxMDdaFw0yNzExMDIwNDMxMDdaMBMxETAPBgNV
BAMMCHRlbGVncmFmMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDP2IMqyOqI
sJjwBprrz8WPzmlrpyYikQ4XSCSJB3DSTIO+igqMpBUTj3vLlOzsHfVVot1WRqc6
3esM4JE92rc6S73xi4g8L/r8cPIHW4hvFJdMti4UkJBWim8ArSbFqnZjcR19G3tG
LUOiXAUG3nWzMzoEsPruvV1dkKRbJVE4MwIDAQABoy8wLTAJBgNVHRMEAjAAMAsG
A1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOB
gQCHxMk38XNxL9nPFBYo3JqITJCFswu6/NLHwDBXCuZKl53rUuFWduiO+1OuScKQ
sQ79W0jHsWRKGOUFrF5/Gdnh8AlkVaITVlcmhdAOFCEbeGpeEvLuuK6grckPitxy
bRF5oM4TCLKKAha60Ir41rk2bomZM9+NZu+Bm+csDqCoxQ==
-----END CERTIFICATE-----`
clientKeyPEM = `-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDP2IMqyOqIsJjwBprrz8WPzmlrpyYikQ4XSCSJB3DSTIO+igqM
pBUTj3vLlOzsHfVVot1WRqc63esM4JE92rc6S73xi4g8L/r8cPIHW4hvFJdMti4U
kJBWim8ArSbFqnZjcR19G3tGLUOiXAUG3nWzMzoEsPruvV1dkKRbJVE4MwIDAQAB
AoGAFzb/r4+xYoMXEfgq5ZvXXTCY5cVNpR6+jCsqqYODPnn9XRLeCsdo8z5bfWms
7NKLzHzca/6IPzL6Rf3vOxFq1YyIZfYVHH+d63/9blAm3Iajjp1W2yW5aj9BJjTb
nm6F0RfuW/SjrZ9IXxTZhSpCklPmUzVZpzvwV3KGeVTVCEECQQDoavCeOwLuqDpt
0aM9GMFUpOU7kLPDuicSwCDaTae4kN2rS17Zki41YXe8A8+509IEN7mK09Vq9HxY
SX6EmV1FAkEA5O9QcCHEa8P12EmUC8oqD2bjq6o7JjUIRlKinwZTlooMJYZw98gA
FVSngTUvLVCVIvSdjldXPOGgfYiccTZrFwJAfHS3gKOtAEuJbkEyHodhD4h1UB4+
hPLr9Xh4ny2yQH0ilpV3px5GLEOTMFUCKUoqTiPg8VxaDjn5U/WXED5n2QJAR4J1
NsFlcGACj+/TvacFYlA6N2nyFeokzoqLX28Ddxdh2erXqJ4hYIhT1ik9tkLggs2z
1T1084BquCuO6lIcOwJBALX4xChoMUF9k0IxSQzlz//seQYDkQNsE7y9IgAOXkzp
RaR4pzgPbnKj7atG+2dBnffWfE+1Mcy0INDAO6WxPg0=
-----END RSA PRIVATE KEY-----`
address = ":6514"
)

var (
initServiceCertFiles sync.Once
serviceCAFile string
serviceCertFile string
serviceKeyFile string
pki = testutil.NewPKI("../../../testutil/pki")
)

type testCase5425 struct {
Expand Down Expand Up @@ -446,96 +370,50 @@ func newTCPSyslogReceiver(keepAlive *internal.Duration, maxConn int, bestEffort
return s
}

func newTLSSyslogReceiver(keepAlive *internal.Duration, maxConn int, bestEffort bool) *Syslog {
initServiceCertFiles.Do(func() {
scaf, err := ioutil.TempFile("", "serviceCAFile.crt")
if err != nil {
panic(err)
}
defer scaf.Close()
_, err = io.Copy(scaf, bytes.NewReader([]byte(serviceRootPEM)))
serviceCAFile = scaf.Name()

scf, err := ioutil.TempFile("", "serviceCertFile.crt")
if err != nil {
panic(err)
}
defer scf.Close()
_, err = io.Copy(scf, bytes.NewReader([]byte(serviceCertPEM)))
serviceCertFile = scf.Name()

skf, err := ioutil.TempFile("", "serviceKeyFile.crt")
if err != nil {
panic(err)
}
defer skf.Close()
_, err = io.Copy(skf, bytes.NewReader([]byte(serviceKeyPEM)))
serviceKeyFile = skf.Name()
})

receiver := newTCPSyslogReceiver(keepAlive, maxConn, bestEffort)
receiver.TLSAllowedCACerts = append(receiver.TLSAllowedCACerts, serviceCAFile)
receiver.TLSCert = serviceCertFile
receiver.TLSKey = serviceKeyFile

return receiver
}

func getTLSSyslogSender() net.Conn {
cas := x509.NewCertPool()
cas.AppendCertsFromPEM([]byte(serviceRootPEM))
clientCert, err := tls.X509KeyPair([]byte(clientCertPEM), []byte(clientKeyPEM))
if err != nil {
panic(err)
}

config := &tls.Config{
RootCAs: cas,
Certificates: []tls.Certificate{clientCert},
MinVersion: tls.VersionTLS12,
MaxVersion: tls.VersionTLS12,
Renegotiation: tls.RenegotiateNever,
InsecureSkipVerify: false,
ServerName: "localhost",
}

c, err := tls.Dial("tcp", address, config)
if err != nil {
log.Println(err)
panic(err)
}

return c
}

func testStrict(t *testing.T, acc *testutil.Accumulator, tls bool) {
func testStrictRFC5425(t *testing.T, wantTLS bool, keepAlive *internal.Duration) {
for _, tc := range getTestCasesForRFC5425() {
t.Run(tc.name, func(t *testing.T) {
// Creation of a strict mode receiver
receiver := newTCPSyslogReceiver(keepAlive, 0, false)
require.NotNil(t, receiver)
if wantTLS {
receiver.ServerConfig = *pki.TLSServerConfig()
}
require.Equal(t, receiver.KeepAlivePeriod, keepAlive)
acc := &testutil.Accumulator{}
require.NoError(t, receiver.Start(acc))
defer receiver.Stop()

// Connect
var conn net.Conn
var err error
if tls {
conn = getTLSSyslogSender()

if wantTLS {
config, e := pki.TLSClientConfig().TLSConfig()
require.NoError(t, e)
config.ServerName = "localhost"
conn, err = tls.Dial("tcp", address, config)
} else {
conn, err = net.Dial("tcp", address)
defer conn.Close()
}
require.NotNil(t, conn)
require.Nil(t, err)
require.NoError(t, err)

// Clear
acc.ClearMetrics()
acc.Errors = make([]error, 0)

// Write
conn.Write(tc.data)

// Wait that the the number of data points is accumulated
// Since the receiver is running concurrently
if tc.wantStrict != nil {
acc.Wait(len(tc.wantStrict))
}
// Wait the parsing error
acc.WaitError(tc.werr)

// Verify
if len(acc.Errors) != tc.werr {
t.Fatalf("Got unexpected errors. want error = %v, errors = %v\n", tc.werr, acc.Errors)
Expand All @@ -551,31 +429,49 @@ func testStrict(t *testing.T, acc *testutil.Accumulator, tls bool) {
}
}

func testBestEffort(t *testing.T, acc *testutil.Accumulator, tls bool) {
func testBestEffortRFC5425(t *testing.T, wantTLS bool, keepAlive *internal.Duration) {
for _, tc := range getTestCasesForRFC5425() {
t.Run(tc.name, func(t *testing.T) {
// Creation of a best effort mode receiver
receiver := newTCPSyslogReceiver(keepAlive, 0, true)
require.NotNil(t, receiver)
if wantTLS {
receiver.ServerConfig = *pki.TLSServerConfig()
}
require.Equal(t, receiver.KeepAlivePeriod, keepAlive)
acc := &testutil.Accumulator{}
require.NoError(t, receiver.Start(acc))
defer receiver.Stop()

// Connect
var conn net.Conn
var err error
if tls {
conn = getTLSSyslogSender()
require.NotNil(t, conn)
if wantTLS {
config, e := pki.TLSClientConfig().TLSConfig()
require.NoError(t, e)
config.ServerName = "localhost"
conn, err = tls.Dial("tcp", address, config)
} else {
conn, err = net.Dial("tcp", address)
require.NoError(t, err)
defer conn.Close()
}
require.NotNil(t, conn)
require.NoError(t, err)

// Clear
acc.ClearMetrics()
acc.Errors = make([]error, 0)

// Write
conn.Write(tc.data)

// Wait that the the number of data points is accumulated
// Since the receiver is running concurrently
if tc.wantBestEffort != nil {
acc.Wait(len(tc.wantBestEffort))
}

// Verify
var got []testutil.Metric
for _, metric := range acc.Metrics {
got = append(got, *metric)
Expand All @@ -587,71 +483,26 @@ func testBestEffort(t *testing.T, acc *testutil.Accumulator, tls bool) {
}
}

func TestTCPInStrictMode(t *testing.T) {
receiver := newTCPSyslogReceiver(nil, 0, false)

acc := &testutil.Accumulator{}
require.NoError(t, receiver.Start(acc))
defer receiver.Stop()

testStrict(t, acc, false)
func TestStrict_tcp(t *testing.T) {
testStrictRFC5425(t, false, nil)
}

func TestTCPInBestEffort(t *testing.T) {
receiver := newTCPSyslogReceiver(nil, 0, true)

acc := &testutil.Accumulator{}
require.NoError(t, receiver.Start(acc))
defer receiver.Stop()

testBestEffort(t, acc, false)
func TestBestEffort_tcp(t *testing.T) {
testBestEffortRFC5425(t, false, nil)
}

func TestTLSInStrictMode(t *testing.T) {
receiver := newTLSSyslogReceiver(nil, 0, false)

acc := &testutil.Accumulator{}
require.NoError(t, receiver.Start(acc))
defer receiver.Stop()

testStrict(t, acc, true)
func TestStrict_tcp_tls(t *testing.T) {
testStrictRFC5425(t, true, nil)
}

func TestTLSInBestEffortOn(t *testing.T) {
receiver := newTLSSyslogReceiver(nil, 0, true)
require.True(t, receiver.BestEffort)

acc := &testutil.Accumulator{}
require.NoError(t, receiver.Start(acc))
defer receiver.Stop()

testBestEffort(t, acc, true)
func TestBestEffort_tcp_tls(t *testing.T) {
testBestEffortRFC5425(t, true, nil)
}

func TestTLSWithKeepAliveInStrictMode(t *testing.T) {
keepAlivePeriod := &internal.Duration{
Duration: time.Minute,
}
receiver := newTLSSyslogReceiver(keepAlivePeriod, 0, false)
require.Equal(t, receiver.KeepAlivePeriod, keepAlivePeriod)

acc := &testutil.Accumulator{}
require.NoError(t, receiver.Start(acc))
defer receiver.Stop()

testStrict(t, acc, true)
func TestStrictWithKeepAlive_tcp_tls(t *testing.T) {
testStrictRFC5425(t, true, &internal.Duration{Duration: time.Minute})
}

func TestTLSWithZeroKeepAliveInStrictMode(t *testing.T) {
keepAlivePeriod := &internal.Duration{
Duration: 0,
}
receiver := newTLSSyslogReceiver(keepAlivePeriod, 0, false)
require.Equal(t, receiver.KeepAlivePeriod, keepAlivePeriod)

acc := &testutil.Accumulator{}
require.NoError(t, receiver.Start(acc))
defer receiver.Stop()

testStrict(t, acc, true)
func TestStrictWithZeroKeepAlive_tcp_tls(t *testing.T) {
testStrictRFC5425(t, true, &internal.Duration{Duration: 0})
}
Loading

0 comments on commit 1c27f07

Please sign in to comment.