diff --git a/command/operator_diagnose.go b/command/operator_diagnose.go index 246142b954..0d1a59b249 100644 --- a/command/operator_diagnose.go +++ b/command/operator_diagnose.go @@ -387,6 +387,52 @@ func (c *OperatorDiagnoseCommand) offlineDiagnostics(ctx context.Context) error return nil }) + diagnose.Test(ctx, "seal-transit-tls-checks", func(ctx context.Context) error { + var checkSealTransit bool + for _, seal := range config.Seals { + if seal.Type == "transit" { + checkSealTransit = true + + tlsSkipVerify, _ := seal.Config["tls_skip_verify"] + if tlsSkipVerify == "true" { + diagnose.Warn(ctx, "TLS verification is Skipped! Using this option is highly discouraged and decreases the security of data transmissions to and from the Vault server.") + return nil + } + + // Checking tls_client_cert and tls_client_key + tlsClientCert, ok := seal.Config["tls_client_cert"] + if !ok { + diagnose.Warn(ctx, "Missing tls_client_cert in the config") + return nil + } + tlsClientKey, ok := seal.Config["tls_client_key"] + if !ok { + diagnose.Warn(ctx, "Missing tls_client_key in the config") + return nil + } + _, err := diagnose.TLSFileChecks(tlsClientCert, tlsClientKey) + if err != nil { + return fmt.Errorf("TLS file check failed for tls_client_cert and tls_client_key with the following error: %w", err) + } + + // checking tls_ca_cert + tlsCACert, ok := seal.Config["tls_ca_cert"] + if !ok { + diagnose.Warn(ctx, "Mising tls_ca_cert in the config") + return nil + } + _, err = diagnose.TLSCAFileCheck(tlsCACert) + if err != nil { + return fmt.Errorf("TLS file check failed for tls_ca_cert with the following error: %w", err) + } + } + } + if !checkSealTransit { + diagnose.Skipped(ctx, "No transit seal found!") + } + return nil + }) + sealcontext, sealspan := diagnose.StartSpan(ctx, "create-seal") var seals []vault.Seal var sealConfigError error diff --git a/command/operator_diagnose_test.go b/command/operator_diagnose_test.go index b6948153f3..1acd2079e4 100644 --- a/command/operator_diagnose_test.go +++ b/command/operator_diagnose_test.go @@ -320,6 +320,19 @@ func TestOperatorDiagnoseCommand_Run(t *testing.T) { }, }, }, + { + "diagnose_seal_transit_tls_check_fail", + []string{ + "-config", "./server/test-fixtures/diagnose_seal_trasit_tls_check.hcl", + }, + []*diagnose.Result{ + { + Name: "seal-transit-tls-checks", + Status: diagnose.ErrorStatus, + Message: "Found at least one intermediate cert in a root CA cert", + }, + }, + }, { "diagnose_invalid_https_sr", []string{ diff --git a/command/server/test-fixtures/diagnose_seal_trasit_tls_check.hcl b/command/server/test-fixtures/diagnose_seal_trasit_tls_check.hcl new file mode 100644 index 0000000000..a51c27b37a --- /dev/null +++ b/command/server/test-fixtures/diagnose_seal_trasit_tls_check.hcl @@ -0,0 +1,56 @@ +disable_cache = true +disable_mlock = true + +ui = true + +listener "tcp" { + address = "127.0.0.1:1024" + tls_disable = true +} + +backend "consul" { + address = "127.0.0.1:8500" + foo = "bar" + advertise_addr = "foo" +} + +seal "transit" { + + // TLS Configuration + tls_ca_cert = "./../vault/diagnose/test-fixtures/chain.crt.pem" + tls_client_cert = "./../vault/diagnose/test-fixtures/goodcertwithroot.pem" + tls_client_key = "./../vault/diagnose//test-fixtures/goodkey.pem" + tls_server_name = "vault" + tls_skip_verify = "false" +} + +ha_backend "consul" { + address = "127.0.0.1:8500" + bar = "baz" + advertise_addr = "https://127.0.0.1:8500" + disable_clustering = "true" +} + +service_registration "consul" { + address = "127.0.0.1:8500" + foo = "bar" +} + +telemetry { + statsd_address = "bar" + usage_gauge_period = "5m" + maximum_gauge_cardinality = 100 + + statsite_address = "foo" + dogstatsd_addr = "127.0.0.1:7254" + dogstatsd_tags = ["tag_1:val_1", "tag_2:val_2"] + metrics_prefix = "myprefix" +} + +max_lease_ttl = "10h" +default_lease_ttl = "10h" +cluster_name = "testcluster" +pid_file = "./pidfile" +raw_storage_endpoint = true +disable_sealwrap = true +disable_printable_check = true diff --git a/vault/diagnose/tls_verification.go b/vault/diagnose/tls_verification.go index d273fe76f4..15b2afa9d3 100644 --- a/vault/diagnose/tls_verification.go +++ b/vault/diagnose/tls_verification.go @@ -95,6 +95,18 @@ func outputError(ctx context.Context, newWarnings, listenerWarnings []string, ne // TLSFileChecks returns an error and warnings after checking TLS information func TLSFileChecks(certpath, keypath string) ([]string, error) { + warnings, err := TLSCertCheck(certpath) + if err != nil { + return warnings, err + } + + // Utilize the native TLS Loading mechanism to ensure we have missed no errors + _, err = tls.LoadX509KeyPair(certpath, keypath) + return warnings, err +} + +// TLSCertCheck returns an error and warning after checking TLS information on the given cert +func TLSCertCheck(certpath string) ([]string, error) { // Parse TLS Certs from the certpath leafCerts, interCerts, rootCerts, err := ParseTLSInformation(certpath) if err != nil { @@ -111,9 +123,6 @@ func TLSFileChecks(certpath, keypath string) ([]string, error) { if err = TLSErrorChecks(leafCerts, interCerts, rootCerts); err != nil { return warnings, err } - - // Utilize the native TLS Loading mechanism to ensure we have missed no errors - _, err = tls.LoadX509KeyPair(certpath, keypath) return warnings, err } @@ -287,11 +296,15 @@ func TLSClientCAFileCheck(l *configutil.Listener) ([]string, error) { } else if !l.TLSRequireAndVerifyClientCert { return nil, nil } + return TLSCAFileCheck(l.TLSClientCAFile) +} +// TLSCAFileCheck checks the validity of a TLS CA file +func TLSCAFileCheck(CAFilePath string) ([]string, error) { var warningsSlc []string // Parse TLS Certs from the tls config - leafCerts, interCerts, rootCerts, err := ParseTLSInformation(l.TLSClientCAFile) + leafCerts, interCerts, rootCerts, err := ParseTLSInformation(CAFilePath) if err != nil { return nil, err }