Skip to content

Commit 4a2a1dc

Browse files
kruskall1pkg
andauthored
feat(fips): remove keystore subcommand and config handling (#15545)
* feat(fips): remove keystore subcommand and config handling the keystore is providing obfuscation of data on disk by using an empty password by default. This fails in fips only mode with the following error: crypto/hmac: use of keys shorter than 112 bits is not allowed in FIPS 140-only mode Disable the keystore subcommand and do not try to create one when loading the config. * Update config_nofips_test.go --------- Co-authored-by: Kostiantyn Masliuk <[email protected]>
1 parent c24a1cb commit 4a2a1dc

8 files changed

+163
-48
lines changed

internal/beatcmd/cmd.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ func NewRootCommand(beatParams BeatParams) *cobra.Command {
7474
// Register subcommands.
7575
rootCommand.AddCommand(runCommand)
7676
rootCommand.AddCommand(exportCommand)
77-
rootCommand.AddCommand(keystoreCommand)
77+
if keystoreCommand != nil {
78+
rootCommand.AddCommand(keystoreCommand)
79+
}
7880
rootCommand.AddCommand(versionCommand)
7981
rootCommand.AddCommand(genTestCmd(beatParams))
8082

internal/beatcmd/config.go

+5-9
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323

2424
"github.com/elastic/beats/v7/libbeat/cfgfile"
2525
"github.com/elastic/beats/v7/libbeat/cloudid"
26-
"github.com/elastic/beats/v7/libbeat/common"
2726
"github.com/elastic/beats/v7/libbeat/pprof"
2827
"github.com/elastic/elastic-agent-libs/config"
2928
libkeystore "github.com/elastic/elastic-agent-libs/keystore"
@@ -94,10 +93,14 @@ func LoadConfig(opts ...LoadConfigOption) (*Config, *config.C, libkeystore.Keyst
9493
configOpts = append(configOpts, ucfg.ResolveNOOP)
9594
} else {
9695
configOpts = append(configOpts,
97-
ucfg.Resolve(libkeystore.ResolverWrap(keystore)),
9896
ucfg.ResolveEnv,
9997
ucfg.VarExp,
10098
)
99+
if keystore != nil {
100+
configOpts = append(configOpts,
101+
ucfg.Resolve(libkeystore.ResolverWrap(keystore)),
102+
)
103+
}
101104
}
102105
config.OverwriteConfigOpts(configOpts)
103106

@@ -138,13 +141,6 @@ func WithMergeConfig(cfg ...*config.C) LoadConfigOption {
138141
}
139142
}
140143

141-
// loadKeystore returns the appropriate keystore based on the configuration.
142-
func loadKeystore(cfg *config.C) (libkeystore.Keystore, error) {
143-
keystoreCfg, _ := cfg.Child("keystore", -1)
144-
defaultPathConfig := paths.Resolve(paths.Data, "apm-server.keystore")
145-
return libkeystore.Factory(keystoreCfg, defaultPathConfig, common.IsStrictPerms())
146-
}
147-
148144
func initPaths(cfg *config.C) error {
149145
// To Fix the chicken-egg problem with the Keystore and the loading of the configuration
150146
// files we are doing a partial unpack of the configuration file and only take into consideration

internal/beatcmd/config_fips.go

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Licensed to Elasticsearch B.V. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. Elasticsearch B.V. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
//go:build requirefips
19+
20+
package beatcmd
21+
22+
import (
23+
"github.com/elastic/elastic-agent-libs/config"
24+
libkeystore "github.com/elastic/elastic-agent-libs/keystore"
25+
)
26+
27+
// loadKeystore returns the appropriate keystore based on the configuration.
28+
func loadKeystore(cfg *config.C) (libkeystore.Keystore, error) {
29+
return nil, nil
30+
}

internal/beatcmd/config_nofips.go

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Licensed to Elasticsearch B.V. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. Elasticsearch B.V. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
//go:build !requirefips
19+
20+
package beatcmd
21+
22+
import (
23+
"github.com/elastic/beats/v7/libbeat/common"
24+
"github.com/elastic/elastic-agent-libs/config"
25+
libkeystore "github.com/elastic/elastic-agent-libs/keystore"
26+
"github.com/elastic/elastic-agent-libs/paths"
27+
)
28+
29+
// loadKeystore returns the appropriate keystore based on the configuration.
30+
func loadKeystore(cfg *config.C) (libkeystore.Keystore, error) {
31+
keystoreCfg, _ := cfg.Child("keystore", -1)
32+
defaultPathConfig := paths.Resolve(paths.Data, "apm-server.keystore")
33+
return libkeystore.Factory(keystoreCfg, defaultPathConfig, common.IsStrictPerms())
34+
}
+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Licensed to Elasticsearch B.V. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. Elasticsearch B.V. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
//go:build !requirefips
19+
20+
package beatcmd
21+
22+
import (
23+
"testing"
24+
25+
"github.com/stretchr/testify/assert"
26+
"github.com/stretchr/testify/require"
27+
28+
"github.com/elastic/elastic-agent-libs/keystore"
29+
)
30+
31+
func TestLoadConfigKeystore(t *testing.T) {
32+
initCfgfile(t, `
33+
apm-server:
34+
auth.secret_token: ${APM_SECRET_TOKEN}
35+
`)
36+
37+
cfg, _, _, err := LoadConfig(WithDisableConfigResolution())
38+
require.NoError(t, err)
39+
assertConfigEqual(t, map[string]interface{}{
40+
"auth": map[string]interface{}{
41+
"secret_token": "${APM_SECRET_TOKEN}",
42+
},
43+
}, cfg.APMServer)
44+
45+
cfg, _, ks, err := LoadConfig()
46+
require.NoError(t, err)
47+
48+
err = cfg.APMServer.Unpack(new(map[string]interface{}))
49+
require.Error(t, err)
50+
assert.Contains(t, err.Error(), `missing field accessing 'apm-server.auth'`)
51+
52+
wks, err := keystore.AsWritableKeystore(ks)
53+
require.NoError(t, err)
54+
err = wks.Store("APM_SECRET_TOKEN", []byte("abc123"))
55+
require.NoError(t, err)
56+
err = wks.Save()
57+
require.NoError(t, err)
58+
59+
assertConfigEqual(t, map[string]interface{}{
60+
"auth": map[string]interface{}{
61+
"secret_token": "abc123",
62+
},
63+
}, cfg.APMServer)
64+
}

internal/beatcmd/config_test.go

+1-38
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828

2929
"github.com/elastic/beats/v7/libbeat/cfgfile"
3030
"github.com/elastic/elastic-agent-libs/config"
31-
"github.com/elastic/elastic-agent-libs/keystore"
3231
"github.com/elastic/elastic-agent-libs/paths"
3332
)
3433

@@ -37,11 +36,10 @@ func TestLoadConfig(t *testing.T) {
3736
apm-server:
3837
host: :8200
3938
`)
40-
cfg, rawConfig, keystore, err := LoadConfig()
39+
cfg, rawConfig, _, err := LoadConfig()
4140
require.NoError(t, err)
4241
assert.NotNil(t, cfg)
4342
assert.NotNil(t, rawConfig)
44-
assert.NotNil(t, keystore)
4543

4644
assertConfigEqual(t, map[string]interface{}{
4745
"apm-server": map[string]interface{}{
@@ -75,41 +73,6 @@ apm-server:
7573
}, cfg.APMServer)
7674
}
7775

78-
func TestLoadConfigKeystore(t *testing.T) {
79-
initCfgfile(t, `
80-
apm-server:
81-
auth.secret_token: ${APM_SECRET_TOKEN}
82-
`)
83-
84-
cfg, _, _, err := LoadConfig(WithDisableConfigResolution())
85-
require.NoError(t, err)
86-
assertConfigEqual(t, map[string]interface{}{
87-
"auth": map[string]interface{}{
88-
"secret_token": "${APM_SECRET_TOKEN}",
89-
},
90-
}, cfg.APMServer)
91-
92-
cfg, _, ks, err := LoadConfig()
93-
require.NoError(t, err)
94-
95-
err = cfg.APMServer.Unpack(new(map[string]interface{}))
96-
require.Error(t, err)
97-
assert.Contains(t, err.Error(), `missing field accessing 'apm-server.auth'`)
98-
99-
wks, err := keystore.AsWritableKeystore(ks)
100-
require.NoError(t, err)
101-
err = wks.Store("APM_SECRET_TOKEN", []byte("abc123"))
102-
require.NoError(t, err)
103-
err = wks.Save()
104-
require.NoError(t, err)
105-
106-
assertConfigEqual(t, map[string]interface{}{
107-
"auth": map[string]interface{}{
108-
"secret_token": "abc123",
109-
},
110-
}, cfg.APMServer)
111-
}
112-
11376
func assertConfigEqual(t testing.TB, expected map[string]interface{}, actual *config.C) {
11477
t.Helper()
11578
var m map[string]interface{}

internal/beatcmd/keystore_fips.go

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Licensed to Elasticsearch B.V. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. Elasticsearch B.V. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
//go:build requirefips
19+
20+
package beatcmd
21+
22+
import "github.com/spf13/cobra"
23+
24+
var keystoreCommand *cobra.Command = nil

internal/beatcmd/keystore.go internal/beatcmd/keystore_nofips.go

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18+
//go:build !requirefips
19+
1820
package beatcmd
1921

2022
import (

0 commit comments

Comments
 (0)