From d686b9be828e8424a7d723c37e34b69799dbf994 Mon Sep 17 00:00:00 2001 From: ph Date: Fri, 4 May 2018 13:38:54 -0400 Subject: [PATCH] Features: Allow the TCP Input to receive events over a TLS connection We can now receive events on the TCP input with a TLS connection, the input uses existing type to make sure we have the same naming convention and code used by outputs that support TLS communication (Elasticsearch and Logstash). The configuration will look like this: ``` host: "localhost:9000" ssl.enabled: true ssl.verification_mode: full # default ssl.supported_protocols: [TLSv1.1] ssl.cipher_suites: [] ssl.certificate_authorities: ["/etc/cacert"] ssl.certificate: /etc/mycert.crt ssl.key: /etc/mycert.key ssl.client_authentication: required ``` One added configuration is `client_authentication`, this option is only used in the context of server and define how we will force the authentification, it support the three following options: - `required`: Assume that the client will provide a certificate and we will verify it. (default) - `optional`: If a certificate is given by the client. - `none`: We don't validate client certificate. *Note: This commit contains a script to generate certs from a self signed CA. Fixes: #6873 --- CHANGELOG.asciidoc | 1 + .../inputs/input-common-tcp-options.asciidoc | 9 + filebeat/inputsource/network.go | 9 + filebeat/inputsource/network_metadata.go | 1 - filebeat/inputsource/tcp/client.go | 41 ++- filebeat/inputsource/tcp/config.go | 10 +- filebeat/inputsource/tcp/server.go | 31 +- .../system/config/certificates/beats1.crt | 17 ++ .../system/config/certificates/beats1.key | 28 ++ .../system/config/certificates/beats2.crt | 17 ++ .../system/config/certificates/beats2.key | 28 ++ .../system/config/certificates/cacert.cfg | 22 ++ .../system/config/certificates/cacert.crt | 23 ++ .../system/config/certificates/cacert.key | 27 ++ .../system/config/certificates/cacert.srl | 1 + .../system/config/certificates/client1.crt | 47 +++ .../system/config/certificates/client1.csr | 17 ++ .../system/config/certificates/client1.key | 27 ++ .../system/config/certificates/client2.crt | 47 +++ .../system/config/certificates/client2.csr | 17 ++ .../system/config/certificates/client2.key | 27 ++ .../certificates/generate_certificate.sh | 40 +++ filebeat/tests/system/test_tcp_tls.py | 273 ++++++++++++++++++ libbeat/docs/shared-ssl-config.asciidoc | 10 + 24 files changed, 760 insertions(+), 10 deletions(-) delete mode 100644 filebeat/inputsource/network_metadata.go create mode 100644 filebeat/tests/system/config/certificates/beats1.crt create mode 100644 filebeat/tests/system/config/certificates/beats1.key create mode 100644 filebeat/tests/system/config/certificates/beats2.crt create mode 100644 filebeat/tests/system/config/certificates/beats2.key create mode 100644 filebeat/tests/system/config/certificates/cacert.cfg create mode 100644 filebeat/tests/system/config/certificates/cacert.crt create mode 100644 filebeat/tests/system/config/certificates/cacert.key create mode 100644 filebeat/tests/system/config/certificates/cacert.srl create mode 100644 filebeat/tests/system/config/certificates/client1.crt create mode 100644 filebeat/tests/system/config/certificates/client1.csr create mode 100644 filebeat/tests/system/config/certificates/client1.key create mode 100644 filebeat/tests/system/config/certificates/client2.crt create mode 100644 filebeat/tests/system/config/certificates/client2.csr create mode 100644 filebeat/tests/system/config/certificates/client2.key create mode 100755 filebeat/tests/system/config/certificates/generate_certificate.sh create mode 100644 filebeat/tests/system/test_tcp_tls.py 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.