Skip to content

Commit

Permalink
[filebeat] Add intermediary support for ssl.verification_mode (#42368)
Browse files Browse the repository at this point in the history
* [filebeat] Add intermediary support for `ssl.verification_mode` on ES config translation layer

---------

Co-authored-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
  • Loading branch information
khushijain21 and mauri870 authored Jan 28, 2025
1 parent 8406c86 commit 3e18a38
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 16 deletions.
63 changes: 50 additions & 13 deletions libbeat/otelbeat/oteltranslate/tls_otel.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"crypto/tls"
"errors"
"fmt"
"reflect"
"strings"

"github.com/mitchellh/mapstructure"
Expand All @@ -34,7 +35,6 @@ import (
// ssl.curve_types
// ssl.ca_sha256
// ssl.ca_trustred_fingerprint

// ssl.supported_protocols -> partially supported
// ssl.restart_on_cert_change.*
// ssl.renegotiation
Expand Down Expand Up @@ -77,6 +77,15 @@ func TLSCommonToOTel(tlscfg *tlscommon.Config) (map[string]any, error) {
return nil, err
}

//unpacks -> ssl.verification_mode
// not fully supported yet
switch tlscfg.VerificationMode {
case tlscommon.VerifyNone:
insecureSkipVerify = true
default:
// Handle all other cases, including VerifyFull, VerifyCertificate, or VerifyStrict
}

// unpacks -> ssl.certificate_authorities
// The OTel exporter accepts either single CA file or CA string. However,
// Beats support any combination and number of files and certificates
Expand Down Expand Up @@ -129,29 +138,57 @@ func TLSCommonToOTel(tlscfg *tlscommon.Config) (map[string]any, error) {
}

otelTLSConfig := map[string]any{
"insecure_skip_verify": insecureSkipVerify, // ssl.verirication_mode,

// Config
"insecure_skip_verify": insecureSkipVerify, // ssl.verification_mode:none
"include_system_ca_certs_pool": includeSystemCACertsPool,
"ca_pem": strings.Join(caCerts, ""), // ssl.certificate_authorities
"cert_pem": certPem, // ssl.certificate
"key_pem": certKeyPem, // ssl.key
"cipher_suites": ciphersuites, // ssl.cipher_suites
}

// For type safety check only
setIfNotNil(otelTLSConfig, "ca_pem", strings.Join(caCerts, "")) // ssl.certificate_authorities
setIfNotNil(otelTLSConfig, "cert_pem", certPem) // ssl.certificate
setIfNotNil(otelTLSConfig, "key_pem", certKeyPem) // ssl.key
setIfNotNil(otelTLSConfig, "cipher_suites", ciphersuites) // ssl.cipher_suites"

if err := typeSafetyCheck(otelTLSConfig); err != nil {
return nil, err
}
return otelTLSConfig, nil
}

// For type safety check
func typeSafetyCheck(value map[string]any) error {
// the returned valued should match `clienttls.Config` type.
// it throws an error if non existing key name is used in the returned map structure
// it throws an error if non existing key names are set
var result configtls.ClientConfig
d, _ := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Squash: true,
Result: &result,
ErrorUnused: true,
})

if err := d.Decode(otelTLSConfig); err != nil {
return nil, err
err := d.Decode(value)
if err != nil {
return err
}
return err
}

return otelTLSConfig, nil
// Helper function to conditionally add fields to the map
func setIfNotNil(m map[string]any, key string, value any) {
if value == nil {
return
}

v := reflect.ValueOf(value)

switch v.Kind() {
case reflect.String:
if v.String() != "" {
m[key] = value
}
case reflect.Map, reflect.Slice:
if v.Len() > 0 {
m[key] = value
}
default:
m[key] = value
}
}
18 changes: 15 additions & 3 deletions libbeat/otelbeat/oteltranslate/tls_otel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package oteltranslate

import (
"crypto/tls"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -57,7 +58,18 @@ func TestTLSCommonToOTel(t *testing.T) {
err: true,
},
{
name: "when ca, cert, key and key_passphrase is provided",
name: "when ssl.verification_mode:none ",
input: &tlscommon.Config{
VerificationMode: tlscommon.VerifyNone,
},
want: map[string]any{
"insecure_skip_verify": true,
"include_system_ca_certs_pool": true,
},
err: false,
},
{
name: "when ca, cert, key and key_passphrase, cipher_suites is provided",
input: &tlscommon.Config{
CAs: []string{
"testdata/certs/rootCA.crt",
Expand Down Expand Up @@ -85,6 +97,7 @@ sxSmbIUfc2SGJGCJD4I=
Key: "testdata/certs/client.key",
Passphrase: "changeme",
},
CipherSuites: []tlscommon.CipherSuite{tlscommon.CipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)},
},
want: map[string]any{
"ca_pem": `-----BEGIN CERTIFICATE-----
Expand Down Expand Up @@ -183,12 +196,11 @@ m8TtceUhSOnXNrrO5agyMRmL0aYf8D425ot/uwTiSkOd4bdFeEaYs0ahHosxHq2N
me1zqwZ6EX7XHaa6j1mx9tcX
-----END RSA PRIVATE KEY-----
`,
"cipher_suites": []string{},
"insecure_skip_verify": false,
"include_system_ca_certs_pool": false,
"cipher_suites": []string{"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"},
},
err: false,
// TODO: Add more scenarios
},
}

Expand Down

0 comments on commit 3e18a38

Please sign in to comment.