diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 94dadb5f63c4..45d389fd5141 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -162,6 +162,7 @@ https://github.com/elastic/beats/compare/v6.2.3...master[Check the HEAD diff] - Add Syslog input to ingest RFC3164 Events via TCP and UDP {pull}6842[6842] - Support MySQL 5.7.19 by mysql/slowlog {pull}6969[6969] - Correctly join partial log lines when using `docker` input. {pull}6967[6967] +- Add support for TLS with client authentication to the TCP input {pull}7056[7056] *Heartbeat* diff --git a/filebeat/docs/inputs/input-common-tcp-options.asciidoc b/filebeat/docs/inputs/input-common-tcp-options.asciidoc index c82dd7ee4f0f..d4d08872abc3 100644 --- a/filebeat/docs/inputs/input-common-tcp-options.asciidoc +++ b/filebeat/docs/inputs/input-common-tcp-options.asciidoc @@ -27,3 +27,12 @@ Specify the characters used to split the incoming events. The default is '\n'. ==== `timeout` The number of seconds of inactivity before a remote connection is closed. The default is `300s`. + +[float] +[id="{beatname_lc}-input-{type}-tcp-ssl"] +===== `ssl` + +Configuration options for SSL parameters like the certificate, key and the certificate authorities +to use. + +See <> for more information. diff --git a/filebeat/inputsource/network.go b/filebeat/inputsource/network.go index 699a26f20fe4..34563ffdca4b 100644 --- a/filebeat/inputsource/network.go +++ b/filebeat/inputsource/network.go @@ -14,6 +14,15 @@ type Network interface { type NetworkMetadata struct { RemoteAddr net.Addr Truncated bool + TLS *TLSMetadata +} + +// TLSMetadata defines information about the current SSL connection. +type TLSMetadata struct { + TLSVersion string + CipherSuite string + ServerName string + PeerCertificates []string } // NetworkFunc defines callback executed when a new event is received from a network source. diff --git a/filebeat/inputsource/network_metadata.go b/filebeat/inputsource/network_metadata.go deleted file mode 100644 index e283490e5be9..000000000000 --- a/filebeat/inputsource/network_metadata.go +++ /dev/null @@ -1 +0,0 @@ -package inputsource diff --git a/filebeat/inputsource/tcp/client.go b/filebeat/inputsource/tcp/client.go index 7d2e0aa124d5..6a0119f8cfff 100644 --- a/filebeat/inputsource/tcp/client.go +++ b/filebeat/inputsource/tcp/client.go @@ -2,12 +2,15 @@ package tcp import ( "bufio" + "crypto/tls" + "crypto/x509" "net" "time" "github.com/pkg/errors" "github.com/elastic/beats/filebeat/inputsource" + "github.com/elastic/beats/libbeat/common/transport/tlscommon" "github.com/elastic/beats/libbeat/logp" ) @@ -33,7 +36,7 @@ func newClient( ) *client { client := &client{ conn: conn, - log: log.With("address", conn.RemoteAddr()), + log: log.With("remote_address", conn.RemoteAddr()), callback: callback, done: make(chan struct{}), splitFunc: splitFunc, @@ -41,8 +44,10 @@ func newClient( timeout: timeout, metadata: inputsource.NetworkMetadata{ RemoteAddr: conn.RemoteAddr(), + TLS: extractSSLInformation(conn), }, } + extractSSLInformation(conn) return client } @@ -63,13 +68,21 @@ func (c *client) handle() error { } // This is a user defined limit and we should notify the user. if IsMaxReadBufferErr(err) { - c.log.Errorw("client errors", "error", err) + c.log.Errorw("client error", "error", err) } return errors.Wrap(err, "tcp client error") } r.Reset() c.callback(scanner.Bytes(), c.metadata) } + + // We are out of the scanner, either we reached EOF or another fatal error occured. + // like we failed to complete the TLS handshake or we are missing the client certificate when + // mutual auth is on, which is the default. + if err := scanner.Err(); err != nil { + return err + } + return nil } @@ -77,3 +90,27 @@ func (c *client) close() { close(c.done) c.conn.Close() } + +func extractSSLInformation(c net.Conn) *inputsource.TLSMetadata { + if tls, ok := c.(*tls.Conn); ok { + state := tls.ConnectionState() + return &inputsource.TLSMetadata{ + TLSVersion: tlscommon.ResolveTLSVersion(state.Version), + CipherSuite: tlscommon.ResolveCipherSuite(state.CipherSuite), + ServerName: state.ServerName, + PeerCertificates: extractCertificate(state.PeerCertificates), + } + } + return nil +} + +func extractCertificate(certificates []*x509.Certificate) []string { + strCertificate := make([]string, len(certificates)) + for idx, c := range certificates { + // Ignore errors here, problematics cert have failed + //the handshake at this point. + b, _ := x509.MarshalPKIXPublicKey(c.PublicKey) + strCertificate[idx] = string(b) + } + return strCertificate +} diff --git a/filebeat/inputsource/tcp/config.go b/filebeat/inputsource/tcp/config.go index afce4d1940af..3da5ba284509 100644 --- a/filebeat/inputsource/tcp/config.go +++ b/filebeat/inputsource/tcp/config.go @@ -5,6 +5,7 @@ import ( "time" "github.com/elastic/beats/libbeat/common/cfgtype" + "github.com/elastic/beats/libbeat/common/transport/tlscommon" ) // Name is the human readable name and identifier. @@ -14,10 +15,11 @@ type size uint64 // Config exposes the tcp configuration. type Config struct { - Host string `config:"host"` - LineDelimiter string `config:"line_delimiter" validate:"nonzero"` - Timeout time.Duration `config:"timeout" validate:"nonzero,positive"` - MaxMessageSize cfgtype.ByteSize `config:"max_message_size" validate:"nonzero,positive"` + Host string `config:"host"` + LineDelimiter string `config:"line_delimiter" validate:"nonzero"` + Timeout time.Duration `config:"timeout" validate:"nonzero,positive"` + MaxMessageSize cfgtype.ByteSize `config:"max_message_size" validate:"nonzero,positive"` + TLS *tlscommon.ServerConfig `config:"ssl"` } // Validate validates the Config option for the tcp input. diff --git a/filebeat/inputsource/tcp/server.go b/filebeat/inputsource/tcp/server.go index 66bccc1d16f2..28f93cd0477e 100644 --- a/filebeat/inputsource/tcp/server.go +++ b/filebeat/inputsource/tcp/server.go @@ -3,12 +3,15 @@ package tcp import ( "bufio" "bytes" + "crypto/tls" "fmt" "net" "sync" "github.com/elastic/beats/filebeat/inputsource" + "github.com/elastic/beats/libbeat/common/transport/tlscommon" "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs/transport" ) // Server represent a TCP server @@ -22,6 +25,7 @@ type Server struct { done chan struct{} splitFunc bufio.SplitFunc log *logp.Logger + tlsConfig *transport.TLSConfig } // New creates a new tcp server @@ -34,6 +38,11 @@ func New( return nil, fmt.Errorf("empty line delimiter") } + tlsConfig, err := tlscommon.LoadTLSServerConfig(config.TLS) + if err != nil { + return nil, err + } + sf := splitFunc([]byte(config.LineDelimiter)) return &Server{ config: config, @@ -42,13 +51,14 @@ func New( done: make(chan struct{}), splitFunc: sf, log: logp.NewLogger("tcp").With("address", config.Host), + tlsConfig: tlsConfig, }, nil } // Start listen to the TCP socket. func (s *Server) Start() error { var err error - s.Listener, err = net.Listen("tcp", s.config.Host) + s.Listener, err = s.createServer() if err != nil { return err } @@ -86,7 +96,7 @@ func (s *Server) run() { s.config.Timeout, ) - s.log.Debugw("New client", "address", conn.RemoteAddr(), "total", s.clientsCount()) + s.log.Debugw("New client", "remote_address", conn.RemoteAddr(), "total", s.clientsCount()) s.wg.Add(1) go func() { defer logp.Recover("recovering from a tcp client crash") @@ -101,7 +111,13 @@ func (s *Server) run() { s.log.Debugw("Client error", "error", err) } - s.log.Debugw("Client disconnected", "address", conn.RemoteAddr(), "total", s.clientsCount()) + s.log.Debugw( + "Client disconnected", + "remote_address", + conn.RemoteAddr(), + "total", + s.clientsCount(), + ) }() } } @@ -142,6 +158,15 @@ func (s *Server) allClients() []*client { return currentClients } +func (s *Server) createServer() (net.Listener, error) { + if s.tlsConfig != nil { + t := s.tlsConfig.BuildModuleConfig(s.config.Host) + s.log.Info("Listening over TLS") + return tls.Listen("tcp", s.config.Host, t) + } + return net.Listen("tcp", s.config.Host) +} + func (s *Server) clientsCount() int { s.RLock() defer s.RUnlock() diff --git a/filebeat/tests/system/config/certificates/beats1.crt b/filebeat/tests/system/config/certificates/beats1.crt new file mode 100644 index 000000000000..4030d82007ba --- /dev/null +++ b/filebeat/tests/system/config/certificates/beats1.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICpDCCAYwCCQDgN4JA8Sp4TzANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls +b2NhbGhvc3QwHhcNMTgwNTAzMjA0NDQxWhcNMTkwNTAzMjA0NDQxWjAUMRIwEAYD +VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCt +cIgOk6on3kfqqUMaw9l4UUH1kX4d7ocNVbz0UcqazCoo0dXoBcUlL+6wE8RLwKgY +eTJQslTPb8XC3mcoU2pFUUXZ3xOk8Wmq9fT9KHtKQRuiAzsw3xQnA+ofhC9vCU7f +pdDbzp1e42Ixni4ajqvOOqWIAdbsP+janLfGR4n62NDmLDYDbpEzKLzcHaOd5u6B +kMSGhDe4Oq8H4WGrj1C8SZzMH2kPYMr9uMXVAHj3m7q1A6qRcJoS4AD5Rkr+cXgn +AsRLxgWU6l6+2g4MJhjx7GphNueLoZiXV3pKMWOqeBrDWbYg+c07aZWnF9O8YBGx +c8vtp4awm+A0OWfMqpXjAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAHh1wBn3vKXH +Fqc85GCfko2aFy7UYFaXjNTati3RW77yhsHn2PIJzTpPu4BaTms5JTup4hmDfPr1 +IJu2ZZ6b+BwdQGngIg6Mx6zA3+4h+JEDiZiJh/v/63EX+4MdasmlBomcrBOo3OWJ +jDIFUJIxsdGtWdR1nsQml77pQf2ECo3u3yV1qvKl2QP8UrJmyU5Vr23Gz9WOCt46 +3kejega+bnsOLNcfHBvrv31zwPBzpA6lfCaCc0SURrBmWPM37/8zZZQIFBMYN30M +id2iUSr+0zZ2O0vrzsET/wsWcLBxRDuxEK3iOjE70/ljBMc/RvhfiUpU7pAmyMOc +8DHX1eqqPM4= +-----END CERTIFICATE----- diff --git a/filebeat/tests/system/config/certificates/beats1.key b/filebeat/tests/system/config/certificates/beats1.key new file mode 100644 index 000000000000..c5a50d2ec336 --- /dev/null +++ b/filebeat/tests/system/config/certificates/beats1.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCtcIgOk6on3kfq +qUMaw9l4UUH1kX4d7ocNVbz0UcqazCoo0dXoBcUlL+6wE8RLwKgYeTJQslTPb8XC +3mcoU2pFUUXZ3xOk8Wmq9fT9KHtKQRuiAzsw3xQnA+ofhC9vCU7fpdDbzp1e42Ix +ni4ajqvOOqWIAdbsP+janLfGR4n62NDmLDYDbpEzKLzcHaOd5u6BkMSGhDe4Oq8H +4WGrj1C8SZzMH2kPYMr9uMXVAHj3m7q1A6qRcJoS4AD5Rkr+cXgnAsRLxgWU6l6+ +2g4MJhjx7GphNueLoZiXV3pKMWOqeBrDWbYg+c07aZWnF9O8YBGxc8vtp4awm+A0 +OWfMqpXjAgMBAAECggEAU0EYXn7th/PAa9lSN+/ZXVMMKXfspSuRson8iP8WFVZ5 +ylxnpNfYObCXj/f9GyvgxNawm2HvKiAKOy+NLyNTePC5agsWH/Aue/1S247qF8vH +Gu8YI66BuvS7FuPZ7R/3t42eA1Vb32ehBBZdJSxlNjqaqP3REFjhSsc9xDUk+777 +O6wHVSest5cfwmhqhIlbyr5nYcrw6q1WEGc/lbwC5lDJNXrw3JbkMAatadQYNiCx +7BsH8JJBQeNKrKGVXC37ny1wrR3aYnQJFAsPGlRykMhwDHy/wpmFyKgPbDyMyjNp +hDK3L7lKDlwXDexFRTI18alVARI7SIyOaVlT0XvU+QKBgQDikNv09jx5uK/NBg6C ++nIGOKkUfv101aWKfgNtkSqPX0djj6EpKpICq5RCqKcc5GL5ZcZ81/6hnvoY2xX6 +QDG7DfFOOsaMzNm/K9pUjtbF1eABUgLaadO+o+dU2K3TsVBekAUx4O2IrJHrWFK6 +Tcq+ruohkKcgqLwTnDDtdLS9TQKBgQDD+MuWUMlMC4SSHINGlZuGj09LUTF5RH3p +fHx9aJdAgIxMNgGcl70gMwBQGQKSdOn/zseS8VtdoESO9IOcmG5NsXXITNqIASFd +u4G0cvyn5rb7xbkAQWynLdvnRRloUiVm59YBuEsCo2m9USS48ODU6TxceasW5xsC +LjsAtGPH7wKBgBxXTox3+NypE6Sr60jLF1Rb5hqgQAhLaWfHl5ovHInOu1li8B/8 +KUOYPvWPr0fX8eGMr6WSR1HkVxig30DsosvpVJQamhem0F4vmCIXtBoPRPQlVCIK +NuiUDC365NOkTI9nqJ6yqkP8gkxUQhT4AjKUIsmMFLvrH4u8cApkHO/JAoGAaOgn +vAj1KWNFDZ572+48unS/IveM/3jd2n7MeanixiHKeQW0KSrFkJYcxcQNr28s0MbV +6WCQ43bnHIviZJLpAWhNP/N8TLAmN3IoBfxEKnGEZRU8atmbG4eeH5jK+CB5azQS +SQtqBDiMY08r1GEGSpOsv2hWYUVIHQu4hDEM9TsCgYEAgxvDd/gSHkanGPR3mqXt +u8IDUWBw4ORkQ0ncYqmDV6jed3v7uCAM2DHaA4ckK91nGdy05EkpTyKin3b0iRxT +TSjwO+wUlwuqQMXYEESJ5XDxy5WSDlYuvKGUcyxLDYo7OMg0UWM6JpH3c2sRy4pU +XztmTa6m0GXerVSyFgx81M8= +-----END PRIVATE KEY----- diff --git a/filebeat/tests/system/config/certificates/beats2.crt b/filebeat/tests/system/config/certificates/beats2.crt new file mode 100644 index 000000000000..c5963aa9d399 --- /dev/null +++ b/filebeat/tests/system/config/certificates/beats2.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICpDCCAYwCCQDGVhMwcBRF9TANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls +b2NhbGhvc3QwHhcNMTgwNTAzMjA0NDQzWhcNMTkwNTAzMjA0NDQzWjAUMRIwEAYD +VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDG +8KkEAd+2Oi6QlQOQPy9DREP92iVJcRNESYnTloy3mP/iK1vPeNCvjnPWSAeiuqzm +3iOXIWiV98hk3cAXAg0Gdi/FoNzCJCJqumVu8REBTNbdHlGspMxIyAL+WNdOtTER +21G1BExjjtGki71FR2Z3wdV898zf7yEfJgGhhxCSwQ9NT1C1R++7kWb+HP/TlXWN +4XEM4TF6Czv65+x3HRA0lRVSK6I0Wy0Ct/+Du4RUCAjtOBLj6WkeMw239Wr7jqaw +3vufORWO/qqEXcpdM7LWaSV14Dh+IpQm+Px0q45gZpT93Y3jYEfwBp+QyU4ICHRw +hkBzH0kBEKsxoi3epL1tAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADNfS5ESaEwg +rQ6DBjujxnVwydWLjvkNlByyJ1WTCAsGDRUltzhLK4jIDrvV/xonAnLsVpDIEiFI +O7O1UZ0Z1sLp1Mh9CHma01qmKtLSOC2w7hOKZXdG6wJxrN9s3pmu/K37BhdHZewL +gdaSc3mogsAL852cIVIgjrQjIkbo7Fs9wiD2u1nnpgthUzCE9PvlbRkTu3GJZguy +T50rHoDNJbwsm5MADjH3yCISm+94pJIlxzl/vHvYIa0YLVEG6Hm5t2+6VRr3b7FH +kNbgX7a3Vvn+NDCWnJYXmq57FdgMGHzpmMR7hgBTxQyxu1eEQ0aCkckguyF90vFi +BlGLYh2BmDA= +-----END CERTIFICATE----- diff --git a/filebeat/tests/system/config/certificates/beats2.key b/filebeat/tests/system/config/certificates/beats2.key new file mode 100644 index 000000000000..e72bf24901b4 --- /dev/null +++ b/filebeat/tests/system/config/certificates/beats2.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDG8KkEAd+2Oi6Q +lQOQPy9DREP92iVJcRNESYnTloy3mP/iK1vPeNCvjnPWSAeiuqzm3iOXIWiV98hk +3cAXAg0Gdi/FoNzCJCJqumVu8REBTNbdHlGspMxIyAL+WNdOtTER21G1BExjjtGk +i71FR2Z3wdV898zf7yEfJgGhhxCSwQ9NT1C1R++7kWb+HP/TlXWN4XEM4TF6Czv6 +5+x3HRA0lRVSK6I0Wy0Ct/+Du4RUCAjtOBLj6WkeMw239Wr7jqaw3vufORWO/qqE +XcpdM7LWaSV14Dh+IpQm+Px0q45gZpT93Y3jYEfwBp+QyU4ICHRwhkBzH0kBEKsx +oi3epL1tAgMBAAECggEBAItBXN4cPa++TGgSlxr6z6ejeoCQmfctutHbNCozQS8n +Xz6/IRY6uMGa0sUVSJsFVxCIQJuC3EXV26WXf+XbHqj+Q/Rv5PfU+W6CKYyeHEwv +sFu55GwYM5Nixo2qPJSwyrd4MVqntp0eFOu8kXGUSEreGQXQI85BAotePFgIRnai +hXPSBDJxccPclOutntIieZdGatrRtKU6+Jq5O95oktJRh0NJ/7h6eVF9+zPhf1Kn +AztRjsn1Y9TrIfop9eLAUt2hG9MTdLp8cxqpfCnL9+zIWhWpQeOMfC4yKn3aHBJh +OJw1Z801XXPkqRXGg8KV9IavfzDFnAfPcSWoIJktmOECgYEA/XQh8HHq70W/9SUo +oNunqBzTyCmq+CQPDGi52wWc8or6r7jPH2VLPGrKLA+Vl/J/aLRy6ent+7s586lh +eLXqc7MIB2hMMsYqGTZlsi4LkgGyVRCEA8t8o7TAo053BNS516Ka+L+noukkgBc8 +FClUcdT+/nS3iF0eKyCngE59eiUCgYEAyPBSckeVhMwZnfQPoNt+xtpCn1UmHznC +/OLYY6T108A/EKqrlb2LW06rB9CwdIfB507yoN+p/+GNlF8l1u9zhKCRvliZ84ru +h6IVoeUxkmHEk3VGBVDfS8EQOh9Jq62VyaGEWldZm2elf3AtyZHc5xCVEeaKAvX+ +M9rAy/3AP6kCgYANekh3vccNdDsR8Sjo7OVMdkP4x+Z0jY5TTZpcgD7pUuSjxYMW +G0/V5aPclfORge6uhbH6qFrkYP9i6qXpQls2TdXmdvBeXtVMQ+1CfVpWKErwZRFw +FjkJh4oa5QhFNH6xbc8p3R8v9Y/gU9v5An2gFAB/TXuY/8Kj7neZxhK8FQKBgAGw +e5D4ZxppuOFqFuOMVOGJHjxGs/5ZNvl3Ushrr6FrIVybgrvMjypiW+/B4mnoZkny +kPmnR7+d/tm7fw7yjm8UBoWqKwkwJtc/Fp141tTbO5Ldzovm5Sm24tMKRk1KNVMv +p3Q2/crfsTWEFO536nqK2iX/YTOrK8r10N8mMAKZAoGANGgsdIrOwZO1aTxEpzto +33dtZljvONfpvhiQ7Bytj/H1nvGYTvdPmStwEQdXd/1vE4EZri93ihWAeWeSinfr +5ROWKuor0jZvzAbVUAuISV04+agQ48CDZICsk/srnPvPTJhC/YpJ8ihG2QlH2VZ0 +AIArT7DcZYLwM5m+oJrlQFY= +-----END PRIVATE KEY----- diff --git a/filebeat/tests/system/config/certificates/cacert.cfg b/filebeat/tests/system/config/certificates/cacert.cfg new file mode 100644 index 000000000000..8994ffdace28 --- /dev/null +++ b/filebeat/tests/system/config/certificates/cacert.cfg @@ -0,0 +1,22 @@ +[req] +distinguished_name = dname +[dname] +[ extensions ] +basicConstraints = critical, CA:TRUE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always, issuer:always +keyUsage = critical, cRLSign, digitalSignature, keyCertSign + +[ client ] +basicConstraints = critical, CA:FALSE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always, issuer:always +keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment, keyAgreement +#extendedKeyUsage = critical, serverAuth + +[ server ] +basicConstraints = critical, CA:FALSE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always, issuer:always +keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment +#kextendedKeyUsage = critical, clientAuth diff --git a/filebeat/tests/system/config/certificates/cacert.crt b/filebeat/tests/system/config/certificates/cacert.crt new file mode 100644 index 000000000000..d36407a580bb --- /dev/null +++ b/filebeat/tests/system/config/certificates/cacert.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID6jCCAtKgAwIBAgIJAOPYgOhthM8ZMA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNV +BAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMQ4wDAYD +VQQKDAViZWF0czENMAsGA1UECwwEcm9vdDAeFw0xODA1MDMyMDQ0NDdaFw0xOTA1 +MDMyMDQ0NDdaMFAxCzAJBgNVBAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNV +BAcMCE1vbnRyZWFsMQ4wDAYDVQQKDAViZWF0czENMAsGA1UECwwEcm9vdDCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMunCRWeX8FyHmW5rkTItJiAICBq +ru1uMLLg/XUs5OmCJ6goYFX1yuRVrxPoKsblIX7zLfLX3hQSbQWSEzELaufn7jsQ +pW4PUxesEuTqOW7PA3lTfamJ6Hr+IH4Ja3GYX0FZOZOcTBaKB6bd2H1MSg2CzjIi +UYnXlgTULbVmnkpB1UdyBLI9Z2WbqnoiGiB/D1Oko8VXzkA3xT9pgCAXHhxqK5t7 +ostCLYt7AzbSVeU6K6c+4i0VyPcxFZMdB1lcRrLkUuYeUwh/tGXXi6j6iHjS54O1 +hyJjEc79wChOqQewLSgvMj3ASdA3pqvXvQB2NTa5wzznoEx83N3DkkIfjN8CAwEA +AaOBxjCBwzAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSjmGSd3zYagxM07hjS +e2KIJfYuGzCBgAYDVR0jBHkwd4AUo5hknd82GoMTNO4Y0ntiiCX2LhuhVKRSMFAx +CzAJBgNVBAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFs +MQ4wDAYDVQQKDAViZWF0czENMAsGA1UECwwEcm9vdIIJAOPYgOhthM8ZMA4GA1Ud +DwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEAQ+CNwnchjhHRkp5mEkWVOysU +H4ajfpsrOOyBsSgIEWW9Wg+uRglm39fgODscUTpTmFId9Y3qy317e8NU0WwhEVBd +JwO1M4s2PHUcQImnf4h8oeun0qhlxZdS8MC8ac6/jfqwqFfuvsdfub8R/o4zvuEL +ZlziVxjrAWqwuj9YtOV4Rnlivy4tEfJlpS0tAXqbEBN2PWwEmJ408Qkv3L9m1Dvs +6FsBEUoO36sPylSzyAfJQcEWlWW+j9YOnDPM40Iefcxgo4dqgL6uepvoYYERKXpR +JDvDF773yo/rZpjyWws8NJsBBt/341TJqejE/NQq5edludYcesummreMLXI16A== +-----END CERTIFICATE----- diff --git a/filebeat/tests/system/config/certificates/cacert.key b/filebeat/tests/system/config/certificates/cacert.key new file mode 100644 index 000000000000..8eddea50b368 --- /dev/null +++ b/filebeat/tests/system/config/certificates/cacert.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAy6cJFZ5fwXIeZbmuRMi0mIAgIGqu7W4wsuD9dSzk6YInqChg +VfXK5FWvE+gqxuUhfvMt8tfeFBJtBZITMQtq5+fuOxClbg9TF6wS5Oo5bs8DeVN9 +qYnoev4gfglrcZhfQVk5k5xMFooHpt3YfUxKDYLOMiJRideWBNQttWaeSkHVR3IE +sj1nZZuqeiIaIH8PU6SjxVfOQDfFP2mAIBceHGorm3uiy0Iti3sDNtJV5Torpz7i +LRXI9zEVkx0HWVxGsuRS5h5TCH+0ZdeLqPqIeNLng7WHImMRzv3AKE6pB7AtKC8y +PcBJ0Demq9e9AHY1NrnDPOegTHzc3cOSQh+M3wIDAQABAoIBAHZljNWBtp/LTbrM +QXGB0eSbEJJoE3y7xBoqzY/S4t6SqaWMm7094Y/v9JI5Nq1dRqT8kekN8PFwaOuF +Kh0oSyW54/l4ywR6ak9n3bAyL+Oo/JcLoBHxuDPRDGjZ5xoqgK6IRf34LxAnfR1Y ++mSV9rN2KZRh+U+PA4uZI13D5CC8rYE7MO3v+5Wb9ItAJBGkyQXJAdPRpPKxitPy +UMCb86xYOOQ8UQyMUg9Cb1SI3gLCMFoz+tmzu+ooiqhU4S06DBUr8y/XDfzXfMCh +uxXSJ0q6u7oZnTpklpqRjUTwLtPIxcMxf/DfF20QG9JyZNGs4ITnYup2f2M16xoe +1pFGQPkCgYEA8D6H4L8TSMA7Zrx9vbAYYbj3kgd/8Z/pdsnO6QCbNVQJxTfGTMJx +cai3A6eAlswGE51OdR2WGl2YtZYARLIncy28kL+9PZmXmc5DBGNrFptCjMRbpt0R +Z2cgJUYUny5tomKOi49uuiOUnrPBaruYKV8xo49H0w1+H2nftjAWtN0CgYEA2QIq +ANehdyvdxjH4TJje2XLOLtzhuhMtU4I/fxHMp/njs2SG00pnUoqrcXJi1EXBd6CO +b52rJJsw9t1GMWNUZYyPNUtn6wfJh0w5Od2FoKn7aWVeP3cdWE4vRMUYzR2yCjmA +Wh9ReM1JmiuiP8ckzy19AwJjXZCpio5et+bCPusCgYEAmXMXTxI8uwct6d0TY4mK +yUBfwUJREoBVmq4kHudoO5PF+dY6LuUzmKlu3EKs+6StbPHZHy0apxSJadK5sScp +04OvIbWWpjXogzEf1Tm7OOFKjKcO83HYn/darPQqT9JT7JiO+81NqE75qrSeIhJY +inRnPFVURxYjLOVvIutsVXECgYAS1Lw+XHfXdogFJdrtEqrr5al8qZAw7G8Xewr1 +hN7kiKu4qnWEqkUzBXOBIbLvxqnWLqmNh/oM8CaclXD84ii1sy/OKR/4ZjGXuwaQ +PefVnEqDx9cY3MZAHnC9n/jZ+8SyXHEF4QfZ2r6TUUwACtDn5YOemjtzKBV+P4J6 +pNygRwKBgDzXrxQV0lOZnH9dpDDE/cE6XlyVcfrYWyj51Wa0TMTxGvIdBGuS9af1 +9Et/iyH7zCzWq0QEDcKX1G8gAk9UQr/+NXXkgpKRbVikEN7sOf2OaV9TLP0SNDa2 +Da6LQs8LtH1N2ucX4OpJPrlx/YHOqWFjRsXQAAtNH2JFMdCnlEKe +-----END RSA PRIVATE KEY----- diff --git a/filebeat/tests/system/config/certificates/cacert.srl b/filebeat/tests/system/config/certificates/cacert.srl new file mode 100644 index 000000000000..43b5cde02ed3 --- /dev/null +++ b/filebeat/tests/system/config/certificates/cacert.srl @@ -0,0 +1 @@ +A3655E382A7345FD diff --git a/filebeat/tests/system/config/certificates/client1.crt b/filebeat/tests/system/config/certificates/client1.crt new file mode 100644 index 000000000000..723363c6e3fe --- /dev/null +++ b/filebeat/tests/system/config/certificates/client1.crt @@ -0,0 +1,47 @@ +-----BEGIN CERTIFICATE----- +MIID/TCCAuWgAwIBAgIJAKNlXjgqc0X8MA0GCSqGSIb3DQEBBQUAMFAxCzAJBgNV +BAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMQ4wDAYD +VQQKDAViZWF0czENMAsGA1UECwwEcm9vdDAeFw0xODA1MDMyMDQ0NDlaFw0xOTA1 +MDMyMDQ0NDlaMGYxCzAJBgNVBAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNV +BAcMCE1vbnRyZWFsMQ4wDAYDVQQKDAViZWF0czEPMA0GA1UECwwGc2VydmVyMRIw +EAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDDTkETmyViX+kRQsYDZvAjTo6bVhTUHdWaBj4V+VOImMMtGRayBTn3CKdkMm2L +eWAOv7lgWrccq5Ab1e2XyYxhinAf0ArUyVHhg9PI7Mt08wIJ7o5CmBU6MQ62b7W1 +FgcRVCazaVhTJ2RjQQjVUpgTvxCKv8FVFzfF4sY2WxZOejetdfb08/1oUsIGJbAM +9nB5xnuazKJ3HWUjPWgqOtB2xOakTKU0rqq//0Sv1XbpQVUDjImnPjptPz8RdWfE +h1i3k9m3NXbj/UDKSKX3sNwEkWU89rLx+GaXwsQlL6YA7fkrGMJ23V8FiYG0BySD +AI8k7gVCL0X0B7GWAHZNTC1bAgMBAAGjgcMwgcAwDAYDVR0TAQH/BAIwADAdBgNV +HQ4EFgQUpGf8kXJhEMfgSv0sYCB5seDtdIowgYAGA1UdIwR5MHeAFKOYZJ3fNhqD +EzTuGNJ7Yogl9i4boVSkUjBQMQswCQYDVQQGEwJDQTEPMA0GA1UECAwGUXVlYmVj +MREwDwYDVQQHDAhNb250cmVhbDEOMAwGA1UECgwFYmVhdHMxDTALBgNVBAsMBHJv +b3SCCQDj2IDobYTPGTAOBgNVHQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEB +AHo7QxfZyh2FvN8nVW/X51QjdgpzMvN7W8DkMfWKy6cp/vhIsZIqLA3qV1MvAHLh +xWAY1yVoJI5PC1XXVprVNVuh+LyvJPR92TLl5SNMT5kFUQzOZ4DqfnsOjVqaXOq6 +WXsSIxqXXpvDtG+Yy8o2l5djoLFvEUukLz6Vdre43tkZNTDzSbksz9nJv0VztYRm +rQ9c4Xchx9Gew+uW3QSIlFEwMJlw9mEts3+tM4zY0A+o/vBkVIAe75omfBM67LT5 +iKbRFtM7tgKTWWSoZ9qZmUUHgU+ffuG/0eqHklaCAQiEYN0scJSNSB4THh/CJyLz +BIU6Y+m1XCtfVsmApqj6uYM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID6jCCAtKgAwIBAgIJAOPYgOhthM8ZMA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNV +BAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMQ4wDAYD +VQQKDAViZWF0czENMAsGA1UECwwEcm9vdDAeFw0xODA1MDMyMDQ0NDdaFw0xOTA1 +MDMyMDQ0NDdaMFAxCzAJBgNVBAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNV +BAcMCE1vbnRyZWFsMQ4wDAYDVQQKDAViZWF0czENMAsGA1UECwwEcm9vdDCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMunCRWeX8FyHmW5rkTItJiAICBq +ru1uMLLg/XUs5OmCJ6goYFX1yuRVrxPoKsblIX7zLfLX3hQSbQWSEzELaufn7jsQ +pW4PUxesEuTqOW7PA3lTfamJ6Hr+IH4Ja3GYX0FZOZOcTBaKB6bd2H1MSg2CzjIi +UYnXlgTULbVmnkpB1UdyBLI9Z2WbqnoiGiB/D1Oko8VXzkA3xT9pgCAXHhxqK5t7 +ostCLYt7AzbSVeU6K6c+4i0VyPcxFZMdB1lcRrLkUuYeUwh/tGXXi6j6iHjS54O1 +hyJjEc79wChOqQewLSgvMj3ASdA3pqvXvQB2NTa5wzznoEx83N3DkkIfjN8CAwEA +AaOBxjCBwzAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSjmGSd3zYagxM07hjS +e2KIJfYuGzCBgAYDVR0jBHkwd4AUo5hknd82GoMTNO4Y0ntiiCX2LhuhVKRSMFAx +CzAJBgNVBAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFs +MQ4wDAYDVQQKDAViZWF0czENMAsGA1UECwwEcm9vdIIJAOPYgOhthM8ZMA4GA1Ud +DwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEAQ+CNwnchjhHRkp5mEkWVOysU +H4ajfpsrOOyBsSgIEWW9Wg+uRglm39fgODscUTpTmFId9Y3qy317e8NU0WwhEVBd +JwO1M4s2PHUcQImnf4h8oeun0qhlxZdS8MC8ac6/jfqwqFfuvsdfub8R/o4zvuEL +ZlziVxjrAWqwuj9YtOV4Rnlivy4tEfJlpS0tAXqbEBN2PWwEmJ408Qkv3L9m1Dvs +6FsBEUoO36sPylSzyAfJQcEWlWW+j9YOnDPM40Iefcxgo4dqgL6uepvoYYERKXpR +JDvDF773yo/rZpjyWws8NJsBBt/341TJqejE/NQq5edludYcesummreMLXI16A== +-----END CERTIFICATE----- diff --git a/filebeat/tests/system/config/certificates/client1.csr b/filebeat/tests/system/config/certificates/client1.csr new file mode 100644 index 000000000000..fdf01b3aaecc --- /dev/null +++ b/filebeat/tests/system/config/certificates/client1.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICqzCCAZMCAQAwZjELMAkGA1UEBhMCQ0ExDzANBgNVBAgMBlF1ZWJlYzERMA8G +A1UEBwwITW9udHJlYWwxDjAMBgNVBAoMBWJlYXRzMQ8wDQYDVQQLDAZzZXJ2ZXIx +EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAMNOQRObJWJf6RFCxgNm8CNOjptWFNQd1ZoGPhX5U4iYwy0ZFrIFOfcIp2Qy +bYt5YA6/uWBatxyrkBvV7ZfJjGGKcB/QCtTJUeGD08jsy3TzAgnujkKYFToxDrZv +tbUWBxFUJrNpWFMnZGNBCNVSmBO/EIq/wVUXN8XixjZbFk56N6119vTz/WhSwgYl +sAz2cHnGe5rMoncdZSM9aCo60HbE5qRMpTSuqr//RK/VdulBVQOMiac+Om0/PxF1 +Z8SHWLeT2bc1duP9QMpIpfew3ASRZTz2svH4ZpfCxCUvpgDt+SsYwnbdXwWJgbQH +JIMAjyTuBUIvRfQHsZYAdk1MLVsCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQCn +ibx1rSgV7GNkeCpUiUwWtOTZJmSe3UVKU/zwsz/FHHIbNpx1tQZt/q+j5SksbDd0 +IY/TBEeVcDR344z6RWRAjVln7UuTsD7B+oQn4Q62Ocu7BFPKQ/TRTP8chywqFU2n +iErvzoAcVicrl9EvU5olyZswnLWVZZW3U63ymA+2zqcPqj3HtXQGFBpGziVmTeCh +UOJ9q8i9iwgeZ2xoCkfnd4KkX8fYYzgUVGSgfmnZOs/gQ8eUkt85UBLZbmGOaOxr ++Pj4svxgwG5zVGzF1s1Qe1Basf1axGajJVRNIPNL88jLIhdt41hK/K1GXMFhIZwp +ys2NJfXl94R/hdvVSBhV +-----END CERTIFICATE REQUEST----- diff --git a/filebeat/tests/system/config/certificates/client1.key b/filebeat/tests/system/config/certificates/client1.key new file mode 100644 index 000000000000..6cb0f05fd135 --- /dev/null +++ b/filebeat/tests/system/config/certificates/client1.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAw05BE5slYl/pEULGA2bwI06Om1YU1B3VmgY+FflTiJjDLRkW +sgU59winZDJti3lgDr+5YFq3HKuQG9Xtl8mMYYpwH9AK1MlR4YPTyOzLdPMCCe6O +QpgVOjEOtm+1tRYHEVQms2lYUydkY0EI1VKYE78Qir/BVRc3xeLGNlsWTno3rXX2 +9PP9aFLCBiWwDPZwecZ7msyidx1lIz1oKjrQdsTmpEylNK6qv/9Er9V26UFVA4yJ +pz46bT8/EXVnxIdYt5PZtzV24/1Aykil97DcBJFlPPay8fhml8LEJS+mAO35KxjC +dt1fBYmBtAckgwCPJO4FQi9F9AexlgB2TUwtWwIDAQABAoIBADd00/OuPRpG45Yc +IL+8jfloiAPBmJ52bj2TAjQZHMgPoHQAyLn50/C6S1WfIA3XhBgMBqY+e/ovGPde +cl2ERFE6DwZpe3naRF7FoPBPlKH7kpuhWlG8f2KLpYLWC4GE5LLd8zNEeWj7KX0p +bUmtbzNEMH1FX686rYKKFwA+MwJLINhmYityv6Fcz+gsgRULsdpfVRgzYIMJtKLr +BffK/CTcb8dD5Ai0Z2UIU+J/81rY1dPsnVkEyrA7DuqZAcjhxxyNDfOeatlRq+lp +dU90Pg6vb4i0y5kWXZiLUsjfCJnu/KiadOrtgccY5LlN+7zVW4SR+hnG6ZCL/KWB +dDuhNwkCgYEA5SSK0huS8yw3NXpAUaF+sb+kyiQ+kyQ6IXqRO17j+wfG9hOQbwhe +W3uspCGcPVe/a9YnyVsOVsWBVxHrlv2DrDibaNblCn8nefBmYpEvkqwVlJYlx9Uq +w1daFzVxtVOqLLBUKVyvEk/aybVgEX1J+PFjBeu1Oz+VM402JjfBHq0CgYEA2jJt +LdIk5OzEIntayxA1VCN6gCbF2PqQ8ruezhFOjZH7MXzcd5eYyvK4qZGRljIS8/5T +VNImEiqnpU9euVnjRtQtfnHlqhG1nDe6P6VhMtqy1tOTfXx+943t8l1DIHfk6Pm6 +TQIZw8s66qT9bNC8Cxf+vN5Pn/y3wUxZNUjnpScCgYAb4VRauCwrFkgpY5SL2iB2 +NCEyzzIl6RSBmk4tcSBAHPQiYMMEH3qLmwKofcZq2FBcKJRytXeLK0DPfUiy+Gma +/NA781mu60W8Wnm6qHunVvTRPWufYtpvJiO6CzCopWNhSJsU5UgP7FNsk3r65cmo +VoZ74/ALI3Nd8GKUR9hhiQKBgHPSeKnt9q+eDq7PE+7ed7Bl9My5yCPZPb/bX/y6 +qxvy9YfbY5wH2I9CMEuyfblgczcZNVq9AoB6K+tQKlPxJveeAVgxVVvlcqWt3yuR +ufqopG3seUoPH8aAjGIup0dA3T3d8cqW5t5LrsaHNg7g7jBlWE8hItsl5tSwlln2 +jR/ZAoGBAJfbbBce/uCrtVFyYOMCa/Oi6nTso3JKd7xR2syqnTLtjLfmkGLADgsq +GTgxy/8RPqzhMhwitMPA25ASvpuVtTSMMqRi4Eg9Agqv97A37Bjcfs8aYcveLMNj +EzSjPpSMgY/E6EERhFZmd5HMrhWRv4dFkLb5sca9tEGpmwZOV/ot +-----END RSA PRIVATE KEY----- diff --git a/filebeat/tests/system/config/certificates/client2.crt b/filebeat/tests/system/config/certificates/client2.crt new file mode 100644 index 000000000000..fc2ead580eb5 --- /dev/null +++ b/filebeat/tests/system/config/certificates/client2.crt @@ -0,0 +1,47 @@ +-----BEGIN CERTIFICATE----- +MIID/TCCAuWgAwIBAgIJAKNlXjgqc0X9MA0GCSqGSIb3DQEBBQUAMFAxCzAJBgNV +BAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMQ4wDAYD +VQQKDAViZWF0czENMAsGA1UECwwEcm9vdDAeFw0xODA1MDMyMDQ0NTBaFw0xOTA1 +MDMyMDQ0NTBaMGYxCzAJBgNVBAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNV +BAcMCE1vbnRyZWFsMQ4wDAYDVQQKDAViZWF0czEPMA0GA1UECwwGY2xpZW50MRIw +EAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDB6ofNCj9bALQSutD2OiXicMbmSUuwD7XQ/rk6XRXL/LwgC2VpBHf5maIgoTXe +2jA/x1I8STwbvQVXCtQbGXJQjBhEBj1PWLfJQDXrbuLNgHrGJ29rIRvrLDWW26Sj +q7W6J69KFoL8Sc6EPmBaqzrTm/JxSp6Z+z6XlyX5l7AauEOjdHOhJIdku6D6gwZX +gs+C4lxNGtWR/MFyGoswtXP1JfyKsmTab3joX8Mj6KmDG9gzMSAOVrNULYsVxJNF +8Cp5NLeqtsEV2wRkB454HsR8RXgCF4UIjYf/n81poxsFiOKTA0ySpKKDC++nio1k +c/Tz9boaOHwE77w3D0d6wAmDAgMBAAGjgcMwgcAwDAYDVR0TAQH/BAIwADAdBgNV +HQ4EFgQUcprOFjrv86fFjeOb/+RgHT3Uh0AwgYAGA1UdIwR5MHeAFKOYZJ3fNhqD +EzTuGNJ7Yogl9i4boVSkUjBQMQswCQYDVQQGEwJDQTEPMA0GA1UECAwGUXVlYmVj +MREwDwYDVQQHDAhNb250cmVhbDEOMAwGA1UECgwFYmVhdHMxDTALBgNVBAsMBHJv +b3SCCQDj2IDobYTPGTAOBgNVHQ8BAf8EBAMCA+gwDQYJKoZIhvcNAQEFBQADggEB +ALxW4VSHf16NbkX3PQsscNBOJ144Q3ZDbVQVG15dH9p/CDj6r16bJ2y8yqIgZLUP +deObu3d4NVQEsNhemy/OVbjCDclrxsswBhLvuM78mBGFTIHnaUB/UUyn0BYE5aG+ +OBfRfGB5oDkgwzgtNpp/mLDI8uIuiTu1ijMPcFXFH907yNf96LXAlGXjDhM8qzfI +lQYTq+WWwP6iKbK9HFcYrMI1G1TPVcsbNSjuEBVuWTBT7Ufc+f2bmZgY1tc6ryRd +RPTWER/7auv07wZlyarGvW8+760Qv/ffhjVa3qxZcxJ+2YHBkUKN1Ly2ZRhmN0BR +d6VLK1FLCr9vHKVvZQ26hEg= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID6jCCAtKgAwIBAgIJAOPYgOhthM8ZMA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNV +BAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMQ4wDAYD +VQQKDAViZWF0czENMAsGA1UECwwEcm9vdDAeFw0xODA1MDMyMDQ0NDdaFw0xOTA1 +MDMyMDQ0NDdaMFAxCzAJBgNVBAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNV +BAcMCE1vbnRyZWFsMQ4wDAYDVQQKDAViZWF0czENMAsGA1UECwwEcm9vdDCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMunCRWeX8FyHmW5rkTItJiAICBq +ru1uMLLg/XUs5OmCJ6goYFX1yuRVrxPoKsblIX7zLfLX3hQSbQWSEzELaufn7jsQ +pW4PUxesEuTqOW7PA3lTfamJ6Hr+IH4Ja3GYX0FZOZOcTBaKB6bd2H1MSg2CzjIi +UYnXlgTULbVmnkpB1UdyBLI9Z2WbqnoiGiB/D1Oko8VXzkA3xT9pgCAXHhxqK5t7 +ostCLYt7AzbSVeU6K6c+4i0VyPcxFZMdB1lcRrLkUuYeUwh/tGXXi6j6iHjS54O1 +hyJjEc79wChOqQewLSgvMj3ASdA3pqvXvQB2NTa5wzznoEx83N3DkkIfjN8CAwEA +AaOBxjCBwzAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSjmGSd3zYagxM07hjS +e2KIJfYuGzCBgAYDVR0jBHkwd4AUo5hknd82GoMTNO4Y0ntiiCX2LhuhVKRSMFAx +CzAJBgNVBAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFs +MQ4wDAYDVQQKDAViZWF0czENMAsGA1UECwwEcm9vdIIJAOPYgOhthM8ZMA4GA1Ud +DwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEAQ+CNwnchjhHRkp5mEkWVOysU +H4ajfpsrOOyBsSgIEWW9Wg+uRglm39fgODscUTpTmFId9Y3qy317e8NU0WwhEVBd +JwO1M4s2PHUcQImnf4h8oeun0qhlxZdS8MC8ac6/jfqwqFfuvsdfub8R/o4zvuEL +ZlziVxjrAWqwuj9YtOV4Rnlivy4tEfJlpS0tAXqbEBN2PWwEmJ408Qkv3L9m1Dvs +6FsBEUoO36sPylSzyAfJQcEWlWW+j9YOnDPM40Iefcxgo4dqgL6uepvoYYERKXpR +JDvDF773yo/rZpjyWws8NJsBBt/341TJqejE/NQq5edludYcesummreMLXI16A== +-----END CERTIFICATE----- diff --git a/filebeat/tests/system/config/certificates/client2.csr b/filebeat/tests/system/config/certificates/client2.csr new file mode 100644 index 000000000000..879a8a728ecc --- /dev/null +++ b/filebeat/tests/system/config/certificates/client2.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICqzCCAZMCAQAwZjELMAkGA1UEBhMCQ0ExDzANBgNVBAgMBlF1ZWJlYzERMA8G +A1UEBwwITW9udHJlYWwxDjAMBgNVBAoMBWJlYXRzMQ8wDQYDVQQLDAZjbGllbnQx +EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAMHqh80KP1sAtBK60PY6JeJwxuZJS7APtdD+uTpdFcv8vCALZWkEd/mZoiCh +Nd7aMD/HUjxJPBu9BVcK1BsZclCMGEQGPU9Yt8lANetu4s2AesYnb2shG+ssNZbb +pKOrtbonr0oWgvxJzoQ+YFqrOtOb8nFKnpn7PpeXJfmXsBq4Q6N0c6Ekh2S7oPqD +BleCz4LiXE0a1ZH8wXIaizC1c/Ul/IqyZNpveOhfwyPoqYMb2DMxIA5Ws1QtixXE +k0XwKnk0t6q2wRXbBGQHjngexHxFeAIXhQiNh/+fzWmjGwWI4pMDTJKkooML76eK +jWRz9PP1uho4fATvvDcPR3rACYMCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQCD +vvLJ906nOKvDEr+Fn3VXGI/IBn1MK94fQuWxc/+gVOYseXlH5wB2+PCMkhUOqNWD +s7WLGtCoOC19iPNtcRA5jntWFZZBkxh4d4IGOBrfdqHTRgMG0JBQbf6A11XxVDy0 +a2pADeM3G4ns6OQZqiu74mpXlRo4uqsDmP/M2z4S7TSkPhyq20sVQCIYO3wZgVbH +35vV8UP7OfUccUYOxcIxp/G+bS6TVaSU+3UFX6IZiScThunNw8L/xLrMWjo7jmXg +5Sr0Iq6XNf1thi7QjVezDb9bAQPpwj0YLJlMi2JcASgprwtaKPdZ1LxNsM0t9aAl +H3ncz4+aPMNNXksr4NcB +-----END CERTIFICATE REQUEST----- diff --git a/filebeat/tests/system/config/certificates/client2.key b/filebeat/tests/system/config/certificates/client2.key new file mode 100644 index 000000000000..2809dc7b18d5 --- /dev/null +++ b/filebeat/tests/system/config/certificates/client2.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAweqHzQo/WwC0ErrQ9jol4nDG5klLsA+10P65Ol0Vy/y8IAtl +aQR3+ZmiIKE13towP8dSPEk8G70FVwrUGxlyUIwYRAY9T1i3yUA1627izYB6xidv +ayEb6yw1ltuko6u1uievShaC/EnOhD5gWqs605vycUqemfs+l5cl+ZewGrhDo3Rz +oSSHZLug+oMGV4LPguJcTRrVkfzBchqLMLVz9SX8irJk2m946F/DI+ipgxvYMzEg +DlazVC2LFcSTRfAqeTS3qrbBFdsEZAeOeB7EfEV4AheFCI2H/5/NaaMbBYjikwNM +kqSigwvvp4qNZHP08/W6Gjh8BO+8Nw9HesAJgwIDAQABAoIBAAR9FkmjvBWyLXjl +hCK+89OLAr+f4LWhl3bP/p+gOfnvzrb7LIzCwrgvWzZgJOwUpttDFN86Xr7RoEcE +hCZgb2n35DPm5RJqHk71QopBldRl7fGaRhT3vjqyWkc0rFnxhpJZitAvNzb5ymL7 +QqW2ovT0/iarMIKl8yv1HrbpUPU9VlMLgtUuQrVRt+YqswEzAbPJaQw+y9cemWCJ +dMMnu4gkXsvTSrGej6N5vr8craorfYFifYMmoBf6VVH/zRjCLPpsGZwOaFs2JdZB +Q3w5KwKn2CMgJWZvEjWdulUFf83srdWTuFMUT1ylpNfGE8VBDR0YFas5WBZOGpB7 +e12+yFECgYEA8KLzcUQnLUS8Q6c36wZCzOWgPPPr51TyJb5CG6tQiIXbYKXBLnnD +JrE8Infndo4RAc4qKue4Gqgso1PCMwjiwhjne4A4tselAIUq55Tf8M44ApwanrqQ +CyqR/74jK786R5ONnevepn+cmVTT44R+MtC/+qHIazTOQ1FcdCGTPcsCgYEAzkv2 +/S8SokEAVxnQ5liBKnmh1X3/fwsvUBPlCqv0lQ3EoOyFdazoL3Ija+A/K2OM1TwF +SZamJieg1XnuRyseU9skOO7rUsPqkuf1KkPUz1JxkJKo8Ktmg0w0dPKS3VCwL6CG +vjXwRGqK7iGem8/1W9kX6yAtWvSMpzSq63Ec7CkCgYEAg6p1j40d7owEgvP1CbjU +Ri6CfbdtZZc6I2K141PabcjoHzqyuA5RtFMXtzhqQpk7PwSiV/WP664HNpq20JvV +DyT3S8D9xyz34I/8yNfRrH35cZweiKlF9YYmeot7zQ0GA3H98+HCYtHCSrd6dKvj +LUTBNo7dDaPIFFdpQfW5Df8CgYAS9Lv/S8IEksB7QG4HnH5R7tdGDMvbWqXAT/Ot +5VsWDyvQNauVwoubQHusv/BOBlm8hkVeG6+stdt7gja452dkATD04k9RTZtSYGoQ +tibp3gN9a1yGsNk8m1X+oQOJvo5R8ggvljk7sCaP9xrh6lv7Upl2C4DfaLU78AT8 +mWo08QKBgA09UuoM2Xg2eRmhNq10wcmnR+zoPYktE92GmxXCSUnPLf3lKzhPaZkl +vrzV4QMZ9laDikQfXGappyE2RozFqYsPlO8SqKdM5rN86eCQR6lzb1AjvaOfBW6y +p8xlMHvevnp00dtzKyYwcWzYyWfYOp9+biHgOvNiOpemi9d/qKn1 +-----END RSA PRIVATE KEY----- diff --git a/filebeat/tests/system/config/certificates/generate_certificate.sh b/filebeat/tests/system/config/certificates/generate_certificate.sh new file mode 100755 index 000000000000..771f68233c8a --- /dev/null +++ b/filebeat/tests/system/config/certificates/generate_certificate.sh @@ -0,0 +1,40 @@ +#!/bin/bash +set -x +# +rm -rf *.key *.crt *.csr cacert.srl +echo "Generate simple self signed CA" +openssl req -x509 -batch -nodes -newkey rsa:2048 -keyout beats1.key \ + -out beats1.crt -days 365 -subj /CN=localhost + +openssl req -x509 -batch -nodes -newkey rsa:2048 -keyout beats2.key \ + -out beats2.crt -days 365 -subj /CN=localhost + +# Generate CA for mutual auth +echo "----" +echo "Generate CACert without a passphrase" +openssl genrsa -out cacert.key 2048 +openssl req -sha256 -config cacert.cfg -extensions extensions -new -x509 -days 365 -key cacert.key -out cacert.crt \ + -subj "/C=CA/ST=Quebec/L=Montreal/O=beats/OU=root" + +echo "----" +echo "Generate client1" +openssl genrsa -out client1.key 2048 +openssl req -sha256 -new -key client1.key -out client1.csr \ + -subj "/C=CA/ST=Quebec/L=Montreal/O=beats/OU=server/CN=localhost" +openssl x509 -req -days 365 -in client1.csr -CA cacert.crt -CAkey cacert.key -CAcreateserial \ + -out client1.crt\ + -extfile cacert.cfg -extensions server + +echo "----" +echo "Generate client2" +openssl genrsa -out client2.key 2048 +openssl req -sha256 -new -key client2.key -out client2.csr \ + -subj "/C=CA/ST=Quebec/L=Montreal/O=beats/OU=client/CN=localhost" +openssl x509 -req -days 365 -in client2.csr -CA cacert.crt -CAkey cacert.key -CAserial cacert.srl\ + -out client2.crt \ + -extfile cacert.cfg -extensions client + +echo "----" +echo "create the certificate chains" +cat cacert.crt >> client1.crt +cat cacert.crt >> client2.crt diff --git a/filebeat/tests/system/test_tcp_tls.py b/filebeat/tests/system/test_tcp_tls.py new file mode 100644 index 000000000000..f7ea32e41491 --- /dev/null +++ b/filebeat/tests/system/test_tcp_tls.py @@ -0,0 +1,273 @@ +from filebeat import BaseTest +import socket +import ssl +from os import path +from nose.tools import raises, assert_raises + +NUMBER_OF_EVENTS = 2 + +CURRENT_PATH = path.dirname(__file__) +CERTPATH = path.abspath(path.join(CURRENT_PATH, "config/certificates")) + + +# Self signed certificate used without mutual and failling scenario. +CERTIFICATE1 = path.join(CERTPATH, "beats1.crt") +KEY1 = path.join(CERTPATH, "beats1.key") + +CERTIFICATE2 = path.join(CERTPATH, "beats2.crt") +KEY2 = path.join(CERTPATH, "beats2.key") + + +# Valid self signed certificate used for mutual auth. +CACERT = path.join(CERTPATH, "cacert.crt") + +CLIENT1 = path.join(CERTPATH, "client1.crt") +CLIENTKEY1 = path.join(CERTPATH, "client1.key") + +CLIENT2 = path.join(CERTPATH, "client2.crt") +CLIENTKEY2 = path.join(CERTPATH, "client2.key") + + +class Test(BaseTest): + """ + Test filebeat TCP input with TLS + """ + + def test_tcp_over_tls_and_verify_valid_server_without_mutual_auth(self): + """ + Test filebeat TCP with TLS with valid cacert without client auth. + """ + input_raw = """ +- type: tcp + host: "{host}:{port}" + enabled: true + ssl.certificate_authorities: {cacert} + ssl.certificate: {certificate} + ssl.key: {key} + ssl.client_authentication: optional +""" + config = { + "host": "127.0.0.1", + "port": 8080, + "cacert": CERTIFICATE1, + "certificate": CERTIFICATE1, + "key": KEY1 + } + + input_raw = input_raw.format(**config) + + self.render_config_template( + input_raw=input_raw, + inputs=False, + ) + + filebeat = self.start_beat() + + self.wait_until(lambda: self.log_contains( + "Started listening for TCP connection")) + + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP + tls = ssl.wrap_socket(sock, cert_reqs=ssl.CERT_REQUIRED, + ca_certs=CERTIFICATE1, do_handshake_on_connect=True) + tls.connect((config.get('host'), config.get('port'))) + + for n in range(0, NUMBER_OF_EVENTS): + tls.send("Hello World: " + str(n) + "\n") + + self.wait_until(lambda: self.output_count( + lambda x: x >= NUMBER_OF_EVENTS)) + + filebeat.check_kill_and_wait() + + output = self.read_output() + + self.assert_output(output) + + sock.close() + + @raises(ssl.SSLError) + def test_tcp_over_tls_and_verify_invalid_server_without_mutual_auth(self): + """ + Test filebeat TCP with TLS with an invalid cacert and not requiring mutual auth. + """ + input_raw = """ +- type: tcp + host: "{host}:{port}" + enabled: true + ssl.certificate_authorities: {cacert} + ssl.certificate: {certificate} + ssl.key: {key} + ssl.client_authentication: optional +""" + config = { + "host": "127.0.0.1", + "port": 8080, + "cacert": CERTIFICATE1, + "certificate": CERTIFICATE1, + "key": KEY1 + } + + input_raw = input_raw.format(**config) + + self.render_config_template( + input_raw=input_raw, + inputs=False, + ) + + filebeat = self.start_beat() + + self.wait_until(lambda: self.log_contains( + "Started listening for TCP connection")) + + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP + tls = ssl.wrap_socket(sock, cert_reqs=ssl.CERT_REQUIRED, + ca_certs=CERTIFICATE2, do_handshake_on_connect=True) + tls.connect((config.get('host'), config.get('port'))) + + @raises(ssl.SSLError) + def test_tcp_over_tls_mutual_auth_fails(self): + """ + Test filebeat TCP with TLS when enforcing client auth with bad client certificates. + """ + input_raw = """ +- type: tcp + host: "{host}:{port}" + enabled: true + ssl.certificate_authorities: {cacert} + ssl.certificate: {certificate} + ssl.key: {key} + ssl.client_authentication: required +""" + config = { + "host": "127.0.0.1", + "port": 8080, + "cacert": CERTIFICATE1, + "certificate": CERTIFICATE1, + "key": KEY1 + } + + input_raw = input_raw.format(**config) + + self.render_config_template( + input_raw=input_raw, + inputs=False, + ) + + filebeat = self.start_beat() + + self.wait_until(lambda: self.log_contains( + "Started listening for TCP connection")) + + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + tls = ssl.wrap_socket(sock, cert_reqs=ssl.CERT_REQUIRED, + ca_certs=CERTIFICATE1, do_handshake_on_connect=True) + tls.connect((config.get('host'), config.get('port'))) + + def test_tcp_over_tls_mutual_auth_succeed(self): + """ + Test filebeat TCP with TLS when enforcing client auth with good client certificates. + """ + input_raw = """ +- type: tcp + host: "{host}:{port}" + enabled: true + ssl.certificate_authorities: {cacert} + ssl.certificate: {certificate} + ssl.key: {key} + ssl.client_authentication: required +""" + config = { + "host": "127.0.0.1", + "port": 8080, + "cacert": CACERT, + "certificate": CLIENT1, + "key": CLIENTKEY1, + } + + input_raw = input_raw.format(**config) + + self.render_config_template( + input_raw=input_raw, + inputs=False, + ) + + filebeat = self.start_beat() + + self.wait_until(lambda: self.log_contains( + "Started listening for TCP connection")) + + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) + context.verify_mode = ssl.CERT_REQUIRED + context.load_verify_locations(CACERT) + context.load_cert_chain(certfile=CLIENT2, keyfile=CLIENTKEY2) + + tls = context.wrap_socket(sock, server_side=False) + + tls.connect((config.get('host'), config.get('port'))) + + for n in range(0, NUMBER_OF_EVENTS): + tls.send("Hello World: " + str(n) + "\n") + + self.wait_until(lambda: self.output_count( + lambda x: x >= NUMBER_OF_EVENTS)) + + filebeat.check_kill_and_wait() + + output = self.read_output() + + self.assert_output(output) + + sock.close() + + def test_tcp_tls_with_a_plain_text_socket(self): + """ + Test filebeat TCP with TLS with a plain text connection. + """ + input_raw = """ +- type: tcp + host: "{host}:{port}" + enabled: true + ssl.certificate_authorities: {cacert} + ssl.certificate: {certificate} + ssl.key: {key} + ssl.client_authentication: required +""" + config = { + "host": "127.0.0.1", + "port": 8080, + "cacert": CERTIFICATE1, + "certificate": CERTIFICATE1, + "key": KEY1 + } + + input_raw = input_raw.format(**config) + + self.render_config_template( + input_raw=input_raw, + inputs=False, + ) + + filebeat = self.start_beat() + + self.wait_until(lambda: self.log_contains( + "Started listening for TCP connection")) + + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP + sock.connect((config.get('host'), config.get('port'))) + + # The TLS handshake will close the connection, resulting in a broken pipe. + # no events should be written on disk. + with assert_raises(IOError): + for n in range(0, 100000): + sock.send("Hello World: " + str(n) + "\n") + + filebeat.check_kill_and_wait() + + assert path.isfile(path.join(self.working_dir, "output/" + self.beat_name)) is False + + def assert_output(self, output): + assert len(output) == 2 + assert output[0]["prospector.type"] == "tcp" + assert output[0]["input.type"] == "tcp" diff --git a/libbeat/docs/shared-ssl-config.asciidoc b/libbeat/docs/shared-ssl-config.asciidoc index e813bedf909e..dfa9733ce5e6 100644 --- a/libbeat/docs/shared-ssl-config.asciidoc +++ b/libbeat/docs/shared-ssl-config.asciidoc @@ -168,3 +168,13 @@ are `never`, `once`, and `freely`. The default value is never. * `never` - Disables renegotiation. * `once` - Allows a remote server to request renegotiation once per connection. * `freely` - Allows a remote server to repeatedly request renegotiation. + +[float] +==== `client_authentication` + +This configures what types of client authentication are supported. The valid options +are `none`, `optional`, and `required`. The default value is required. + +* `none` - Disables client authentification. +* `optional` - When a client certificate is given, the server will verify it. +* `required` - Will require clients to provide a valid certificate.