Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(security)!: Switch Consul's default_policy to deny #3402

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"acl": {
"enabled": true,
"default_policy": "allow",
"default_policy": "deny",
"enable_token_persistence": true
}
}
13 changes: 12 additions & 1 deletion internal/security/bootstrapper/command/setupacl/acltokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,19 @@ func (c *cmd) readTokenIDBy(bootstrapACLToken BootStrapACLTokenInfo, accessorID
// insertNewAgentToken creates a new Consul token
// it returns the token's ID and error if any error occurs
func (c *cmd) insertNewAgentToken(bootstrapACLToken BootStrapACLTokenInfo) (string, error) {
// get a policy for this agent token to associate with
edgexAgentPolicy, err := c.getOrCreateRegistryPolicy(bootstrapACLToken.SecretID,
"edgex-agent-policy",
edgeXPolicyRules)
if err != nil {
return share.EmptyToken, fmt.Errorf("failed to create edgex agent policy: %v", err)
}

unlimitedDuration := "0s"
createToken := NewCreateRegistryToken("edgex-core-consul agent token", bootstrapACLToken.Policies, true, &unlimitedDuration)
createToken := NewCreateRegistryToken("edgex-core-consul agent token",
[]Policy{
*edgexAgentPolicy,
}, true, &unlimitedDuration)
newTokenInfo, err := c.createNewToken(bootstrapACLToken.SecretID, createToken)
if err != nil {
return share.EmptyToken, fmt.Errorf("failed to insert new edgex agent token: %v", err)
Expand Down
21 changes: 13 additions & 8 deletions internal/security/bootstrapper/command/setupacl/acltokens_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,15 @@ func TestCreateAgentToken(t *testing.T) {
listTokensRetriesOkResponse bool
createTokenOkResponse bool
readTokenOkResponse bool
policyAlreadyExists bool
expectedErr bool
}{
{"Good:agent token ok response", testBootstrapToken, true, true, true, true, false},
{"Bad:list tokens bad response", testBootstrapToken, false, false, true, true, true},
{"Bad:create token bad response", testBootstrapToken, true, true, false, true, true},
{"Bad:read token bad response", testBootstrapToken, true, true, true, false, true},
{"Bad:empty bootstrap token", BootStrapACLTokenInfo{}, false, false, false, true, true},
{"Good:agent token ok response 1st time", testBootstrapToken, true, true, true, true, false, false},
{"Good:agent token ok response 2nd time or later", testBootstrapToken, true, true, true, true, true, false},
{"Bad:list tokens bad response", testBootstrapToken, false, false, true, true, false, true},
{"Bad:create token bad response", testBootstrapToken, true, true, false, true, false, true},
{"Bad:read token bad response", testBootstrapToken, true, true, true, false, false, true},
{"Bad:empty bootstrap token", BootStrapACLTokenInfo{}, false, false, false, true, false, true},
}

for _, tt := range tests {
Expand All @@ -113,9 +115,12 @@ func TestCreateAgentToken(t *testing.T) {
t.Parallel()
// prepare test
responseOpts := serverOptions{
listTokensOk: test.listTokensOkResponse,
createTokenOk: test.createTokenOkResponse,
readTokenOk: test.readTokenOkResponse,
listTokensOk: test.listTokensOkResponse,
createTokenOk: test.createTokenOkResponse,
readTokenOk: test.readTokenOkResponse,
policyAlreadyExists: test.policyAlreadyExists,
readPolicyByNameOk: true,
createNewPolicyOk: true,
}
testSrv := newRegistryTestServer(responseOpts)
conf := testSrv.getRegistryServerConf(t)
Expand Down
19 changes: 9 additions & 10 deletions snap/local/runtime-helpers/bin/start-consul.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ echo "$(date) deploying the default EdgeX configuration for Consul"
# https://github.com/edgexfoundry/edgex-docs/blob/master/docs_src/design/adr/security/0017-consul-security.md#phase-1
cat > "$SNAP_DATA/consul/config/consul_default.json" <<EOF
{
"node_name": "edgex-core-consul",
"enable_local_script_checks": true,
"disable_update_check": true,
"ports": {
Expand All @@ -24,7 +25,7 @@ if [ "${ENABLE_REGISTRY_ACL}" == "true" ]; then
{
"acl": {
"enabled": true,
"default_policy": "allow",
"default_policy": "deny",
"enable_token_persistence": true
}
}
Expand All @@ -43,12 +44,10 @@ fi
# and not when bootstrapping
# see https://github.com/hashicorp/consul/issues/4380

# to actually test if consul is ready, we simply check to see if consul
# itself shows up in it's service catalog
# also note we don't have a timeout here because we use start-timeout for this
# daemon so systemd will kill us if we take too long waiting for this
CONSUL_URL=http://localhost:8500/v1/catalog/service/consul
until [ -n "$(curl -s $CONSUL_URL | jq -r '. | length')" ] &&
[ "$(curl -s $CONSUL_URL | jq -r '. | length')" -gt "0" ] ; do
sleep 1
done
# Note: we no longer loop trying to connect to consul here as it is already
# taken care by security-consul-bootstrapper, in which it actually waits for
# the consul leader being elected
# see details in https://github.com/edgexfoundry/edgex-go/blob/master/internal/security/bootstrapper/command/setupacl/command.go#L117-L131
# this is to avoid the chicken-and-egg problem when it is running in "deny" policy mode
# as the consul token being required for the service checking API to be able to talk to consul
# in tandem with non-blocking startup of security-consul-bootstrapper