Skip to content

Commit

Permalink
Disable keystore for beats in FIPS mode (#42846) (#42929)
Browse files Browse the repository at this point in the history
Disable keystore functionality when in FIPS mode.

(cherry picked from commit c4054ad)

Co-authored-by: Michel Laterman <82832767+michel-laterman@users.noreply.github.com>
  • Loading branch information
mergify[bot] and michel-laterman authored Feb 26, 2025
1 parent 2821138 commit fcda890
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 34 deletions.
21 changes: 8 additions & 13 deletions libbeat/cmd/instance/beat.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,10 @@ func NewBeatReceiver(settings Settings, receiverConfig map[string]interface{}, u

if settings.DisableConfigResolver {
config.OverwriteConfigOpts(obfuscateConfigOpts())
} else {
} else if store != nil {
// TODO: Allow the options to be more flexible for dynamic changes
config.OverwriteConfigOpts(configOpts(store))
// note that if the store is nil it should be excluded as an option
config.OverwriteConfigOpts(configOptsWithKeystore(store))
}

b.Beat.Info.Monitoring.Namespace = monitoring.GetNamespace(b.Info.Beat + "-" + b.Info.ID.String())
Expand Down Expand Up @@ -1005,9 +1006,10 @@ func (b *Beat) configure(settings Settings) error {

if settings.DisableConfigResolver {
config.OverwriteConfigOpts(obfuscateConfigOpts())
} else {
} else if store != nil {
// TODO: Allow the options to be more flexible for dynamic changes
config.OverwriteConfigOpts(configOpts(store))
// note that if the store is nil it should be excluded as an option
config.OverwriteConfigOpts(configOptsWithKeystore(store))
}

instrumentation, err := instrumentation.New(cfg, b.Info.Beat, b.Info.Version)
Expand Down Expand Up @@ -1668,9 +1670,9 @@ func (b *Beat) logSystemInfo(log *logp.Logger) {
}
}

// configOpts returns ucfg config options with a resolver linked to the current keystore.
// configOptsWithKeystore returns ucfg config options with a resolver linked to the current keystore.
// Refactor to allow insert into the config option array without having to redefine everything
func configOpts(store keystore.Keystore) []ucfg.Option {
func configOptsWithKeystore(store keystore.Keystore) []ucfg.Option {
return []ucfg.Option{
ucfg.PathSep("."),
ucfg.Resolve(keystore.ResolverWrap(store)),
Expand All @@ -1688,13 +1690,6 @@ func obfuscateConfigOpts() []ucfg.Option {
}
}

// LoadKeystore returns the appropriate keystore based on the configuration.
func LoadKeystore(cfg *config.C, name string) (keystore.Keystore, error) {
keystoreCfg, _ := cfg.Child("keystore", -1)
defaultPathConfig := paths.Resolve(paths.Data, fmt.Sprintf("%s.keystore", name))
return keystore.Factory(keystoreCfg, defaultPathConfig, common.IsStrictPerms())
}

func InitKibanaConfig(beatConfig beatConfig) *config.C {
var esConfig *config.C
if isElasticsearchOutput(beatConfig.Output.Name()) {
Expand Down
30 changes: 30 additions & 0 deletions libbeat/cmd/instance/keystore_fips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

//go:build requirefips

package instance

import (
"github.com/elastic/elastic-agent-libs/config"
"github.com/elastic/elastic-agent-libs/keystore"
)

// LoadKeystore returns nil in FIPS mode
func LoadKeystore(cfg *config.C, name string) (keystore.Keystore, error) {
return nil, nil
}
36 changes: 36 additions & 0 deletions libbeat/cmd/instance/keystore_fips_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

//go:build requirefips

package instance

import (
"testing"

"github.com/elastic/elastic-agent-libs/config"
)

func TestLoadKeystore(t *testing.T) {
ks, err := LoadKeystore(config.NewConfig(), "test")
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
if ks != nil {
t.Error("keystore is not nil.")
}
}
36 changes: 36 additions & 0 deletions libbeat/cmd/instance/keystore_nofips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

//go:build !requirefips

package instance

import (
"fmt"

"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/elastic-agent-libs/config"
"github.com/elastic/elastic-agent-libs/keystore"
"github.com/elastic/elastic-agent-libs/paths"
)

// LoadKeystore returns the appropriate keystore based on the configuration.
func LoadKeystore(cfg *config.C, name string) (keystore.Keystore, error) {
keystoreCfg, _ := cfg.Child("keystore", -1)
defaultPathConfig := paths.Resolve(paths.Data, fmt.Sprintf("%s.keystore", name))
return keystore.Factory(keystoreCfg, defaultPathConfig, common.IsStrictPerms())
}
20 changes: 0 additions & 20 deletions libbeat/cmd/keystore.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,6 @@ func getKeystore(settings instance.Settings) (keystore.Keystore, error) {
return b.Keystore(), nil
}

// genKeystoreCmd initialize the Keystore command to manage the Keystore
// with the following subcommands:
// - create
// - add
// - remove
// - list
func genKeystoreCmd(settings instance.Settings) *cobra.Command {
keystoreCmd := cobra.Command{
Use: "keystore",
Short: "Manage secrets keystore",
}

keystoreCmd.AddCommand(genCreateKeystoreCmd(settings))
keystoreCmd.AddCommand(genAddKeystoreCmd(settings))
keystoreCmd.AddCommand(genRemoveKeystoreCmd(settings))
keystoreCmd.AddCommand(genListKeystoreCmd(settings))

return &keystoreCmd
}

func genCreateKeystoreCmd(settings instance.Settings) *cobra.Command {
var flagForce bool
command := &cobra.Command{
Expand Down
31 changes: 31 additions & 0 deletions libbeat/cmd/keystore_fips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

//go:build requirefips

package cmd

import (
"github.com/spf13/cobra"

"github.com/elastic/beats/v7/libbeat/cmd/instance"
)

// genKeystoreCmd returns nil in fips mode as the keystore is disabled.
func genKeystoreCmd(_ instance.Settings) *cobra.Command {
return nil
}
46 changes: 46 additions & 0 deletions libbeat/cmd/keystore_nofips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

//go:build !requirefips

package cmd

import (
"github.com/spf13/cobra"

"github.com/elastic/beats/v7/libbeat/cmd/instance"
)

// genKeystoreCmd initialize the Keystore command to manage the Keystore
// with the following subcommands:
// - create
// - add
// - remove
// - list
func genKeystoreCmd(settings instance.Settings) *cobra.Command {
keystoreCmd := cobra.Command{
Use: "keystore",
Short: "Manage secrets keystore",
}

keystoreCmd.AddCommand(genCreateKeystoreCmd(settings))
keystoreCmd.AddCommand(genAddKeystoreCmd(settings))
keystoreCmd.AddCommand(genRemoveKeystoreCmd(settings))
keystoreCmd.AddCommand(genListKeystoreCmd(settings))

return &keystoreCmd
}
4 changes: 3 additions & 1 deletion libbeat/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ func GenRootCmdWithSettings(beatCreator beat.Creator, settings instance.Settings
rootCmd.AddCommand(rootCmd.CompletionCmd)
rootCmd.AddCommand(rootCmd.ExportCmd)
rootCmd.AddCommand(rootCmd.TestCmd)
rootCmd.AddCommand(rootCmd.KeystoreCmd)
if rootCmd.KeystoreCmd != nil {
rootCmd.AddCommand(rootCmd.KeystoreCmd)
}

return rootCmd
}

0 comments on commit fcda890

Please sign in to comment.