Skip to content

Commit

Permalink
dns token (#17936)
Browse files Browse the repository at this point in the history
* dns token

fix whitespace for docs and comments

fix test cases

fix test cases

remove tabs in help text

Add changelog

Peering dns test

Peering dns test

Partial implementation of Peered DNS test

Swap to new topology lib

expose dns port for integration tests on client

remove partial test implementation

remove extra port exposure

remove changelog from the ent pr

Add dns token to set-agent-token switch

Add enterprise golden file

Use builtin/dns template in tests

Update ent dns policy

Update ent dns template test

remove local gen certs

fix templated policy specs

* add changelog

* go mod tidy
  • Loading branch information
johnlanda authored Sep 20, 2023
1 parent 0236c48 commit 9eaa8eb
Show file tree
Hide file tree
Showing 22 changed files with 305 additions and 108 deletions.
3 changes: 3 additions & 0 deletions .changelog/17936.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:feature
acl: Add new `acl.tokens.dns` config field which specifies the token used implicitly during dns checks.
```
3 changes: 3 additions & 0 deletions agent/agent_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -1531,6 +1531,9 @@ func (s *HTTPHandlers) AgentToken(resp http.ResponseWriter, req *http.Request) (
case "config_file_service_registration":
s.agent.tokens.UpdateConfigFileRegistrationToken(args.Token, token_store.TokenSourceAPI)

case "dns_token", "dns":
s.agent.tokens.UpdateDNSToken(args.Token, token_store.TokenSourceAPI)

default:
return HTTPError{StatusCode: http.StatusNotFound, Reason: fmt.Sprintf("Token %q is unknown", target)}
}
Expand Down
1 change: 1 addition & 0 deletions agent/config/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,7 @@ func (b *builder) build() (rt RuntimeConfig, err error) {
ACLAgentRecoveryToken: stringVal(c.ACL.Tokens.AgentRecovery),
ACLReplicationToken: stringVal(c.ACL.Tokens.Replication),
ACLConfigFileRegistrationToken: stringVal(c.ACL.Tokens.ConfigFileRegistration),
ACLDNSToken: stringVal(c.ACL.Tokens.DNS),
},

// Autopilot
Expand Down
1 change: 1 addition & 0 deletions agent/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,7 @@ type Tokens struct {
Default *string `mapstructure:"default"`
Agent *string `mapstructure:"agent"`
ConfigFileRegistration *string `mapstructure:"config_file_service_registration"`
DNS *string `mapstructure:"dns"`

// Enterprise Only
ManagedServiceProvider []ServiceProviderToken `mapstructure:"managed_service_provider"`
Expand Down
1 change: 1 addition & 0 deletions agent/config/testdata/TestRuntimeConfig_Sanitize.golden
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"ACLAgentRecoveryToken": "hidden",
"ACLAgentToken": "hidden",
"ACLConfigFileRegistrationToken": "hidden",
"ACLDNSToken": "hidden",
"ACLDefaultToken": "hidden",
"ACLReplicationToken": "hidden",
"DataDir": "",
Expand Down
22 changes: 15 additions & 7 deletions agent/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) {
args := structs.DCSpecificRequest{
Datacenter: datacenter,
QueryOptions: structs.QueryOptions{
Token: d.agent.tokens.UserToken(),
Token: d.coalesceDNSToken(),
AllowStale: cfg.AllowStale,
},
}
Expand Down Expand Up @@ -452,7 +452,7 @@ func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) {
sargs := structs.ServiceSpecificRequest{
Datacenter: datacenter,
QueryOptions: structs.QueryOptions{
Token: d.agent.tokens.UserToken(),
Token: d.coalesceDNSToken(),
AllowStale: cfg.AllowStale,
},
ServiceAddress: serviceAddress,
Expand Down Expand Up @@ -513,7 +513,7 @@ func (d *DNSServer) handleQuery(resp dns.ResponseWriter, req *dns.Msg) {

cfg := d.config.Load().(*dnsConfig)

// Setup the message response
// Set up the message response
m := new(dns.Msg)
m.SetReply(req)
m.Compress = !cfg.DisableCompression
Expand Down Expand Up @@ -875,7 +875,7 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi
ServiceName: queryParts[len(queryParts)-1],
EnterpriseMeta: locality.EnterpriseMeta,
QueryOptions: structs.QueryOptions{
Token: d.agent.tokens.UserToken(),
Token: d.coalesceDNSToken(),
},
}
if args.PeerName == "" {
Expand Down Expand Up @@ -1093,7 +1093,7 @@ func (d *DNSServer) nodeLookup(cfg *dnsConfig, lookup nodeLookup, req, resp *dns
PeerName: lookup.PeerName,
Node: lookup.Node,
QueryOptions: structs.QueryOptions{
Token: d.agent.tokens.UserToken(),
Token: d.coalesceDNSToken(),
AllowStale: cfg.AllowStale,
},
EnterpriseMeta: lookup.EnterpriseMeta,
Expand Down Expand Up @@ -1425,7 +1425,7 @@ func (d *DNSServer) lookupServiceNodes(cfg *dnsConfig, lookup serviceLookup) (st
ServiceTags: serviceTags,
TagFilter: lookup.Tag != "",
QueryOptions: structs.QueryOptions{
Token: d.agent.tokens.UserToken(),
Token: d.coalesceDNSToken(),
AllowStale: cfg.AllowStale,
MaxAge: cfg.CacheMaxAge,
UseCache: cfg.UseCache,
Expand Down Expand Up @@ -1503,7 +1503,7 @@ func (d *DNSServer) preparedQueryLookup(cfg *dnsConfig, datacenter, query string
Datacenter: datacenter,
QueryIDOrName: query,
QueryOptions: structs.QueryOptions{
Token: d.agent.tokens.UserToken(),
Token: d.coalesceDNSToken(),
AllowStale: cfg.AllowStale,
MaxAge: cfg.CacheMaxAge,
},
Expand Down Expand Up @@ -2172,3 +2172,11 @@ func (d *DNSServer) resolveCNAME(cfg *dnsConfig, name string, maxRecursionLevel
d.logger.Error("all resolvers failed for name", "name", name)
return nil
}

func (d *DNSServer) coalesceDNSToken() string {
if d.agent.tokens.DNSToken() != "" {
return d.agent.tokens.DNSToken()
} else {
return d.agent.tokens.UserToken()
}
}
5 changes: 3 additions & 2 deletions agent/dns_ce_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import (
"context"
"testing"

"github.com/miekg/dns"
"github.com/stretchr/testify/require"

"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/testrpc"
"github.com/miekg/dns"
"github.com/stretchr/testify/require"
)

func TestDNS_CE_PeeredServices(t *testing.T) {
Expand Down
45 changes: 42 additions & 3 deletions agent/dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6310,6 +6310,22 @@ func TestDNS_ServiceLookup_SRV_RFC_TCP_Default(t *testing.T) {

}

func initDNSToken(t *testing.T, rpc RPC) {
t.Helper()

reqToken := structs.ACLTokenSetRequest{
Datacenter: "dc1",
ACLToken: structs.ACLToken{
SecretID: "279d4735-f8ca-4d48-b5cc-c00a9713bbf8",
Policies: nil,
TemplatedPolicies: []*structs.ACLTemplatedPolicy{{TemplateName: "builtin/dns"}},
},
WriteRequest: structs.WriteRequest{Token: "root"},
}
err := rpc.RPC(context.Background(), "ACL.TokenSet", &reqToken, &structs.ACLToken{})
require.NoError(t, err)
}

func TestDNS_ServiceLookup_FilterACL(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
Expand All @@ -6322,10 +6338,11 @@ func TestDNS_ServiceLookup_FilterACL(t *testing.T) {
}{
{"root", 1},
{"anonymous", 0},
{"dns", 1},
}
for _, tt := range tests {
t.Run("ACLToken == "+tt.token, func(t *testing.T) {
a := NewTestAgent(t, `
hcl := `
primary_datacenter = "dc1"
acl {
Expand All @@ -6335,13 +6352,34 @@ func TestDNS_ServiceLookup_FilterACL(t *testing.T) {
tokens {
initial_management = "root"
default = "`+tt.token+`"
`
if tt.token == "dns" {
// Create a UUID for dns token since it doesn't have an alias
dnsToken := "279d4735-f8ca-4d48-b5cc-c00a9713bbf8"

hcl = hcl + `
default = "anonymous"
dns = "` + dnsToken + `"
`
} else {
hcl = hcl + `
default = "` + tt.token + `"
`
}

hcl = hcl + `
}
}
`)
`

a := NewTestAgent(t, hcl)
defer a.Shutdown()
testrpc.WaitForLeader(t, a.RPC, "dc1")

if tt.token == "dns" {
initDNSToken(t, a)
}

// Register a service
args := &structs.RegisterRequest{
Datacenter: "dc1",
Expand Down Expand Up @@ -6373,6 +6411,7 @@ func TestDNS_ServiceLookup_FilterACL(t *testing.T) {
})
}
}

func TestDNS_ServiceLookup_MetaTXT(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
Expand Down
5 changes: 4 additions & 1 deletion agent/testagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ type TestACLConfigParams struct {
DefaultToken string
AgentRecoveryToken string
ReplicationToken string
DNSToken string
EnableTokenReplication bool
}

Expand All @@ -547,7 +548,8 @@ func (p *TestACLConfigParams) HasConfiguredTokens() bool {
p.AgentToken != "" ||
p.DefaultToken != "" ||
p.AgentRecoveryToken != "" ||
p.ReplicationToken != ""
p.ReplicationToken != "" ||
p.DNSToken != ""
}

func TestACLConfigNew() string {
Expand All @@ -557,6 +559,7 @@ func TestACLConfigNew() string {
InitialManagementToken: "root",
AgentToken: "root",
AgentRecoveryToken: "towel",
DNSToken: "dns",
})
}

Expand Down
16 changes: 16 additions & 0 deletions agent/token/persistence.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type Config struct {
ACLAgentRecoveryToken string
ACLReplicationToken string
ACLConfigFileRegistrationToken string
ACLDNSToken string

EnterpriseConfig
}
Expand Down Expand Up @@ -77,6 +78,7 @@ type persistedTokens struct {
Default string `json:"default,omitempty"`
Agent string `json:"agent,omitempty"`
ConfigFileRegistration string `json:"config_file_service_registration,omitempty"`
DNS string `json:"dns,omitempty"`
}

type fileStore struct {
Expand Down Expand Up @@ -144,6 +146,16 @@ func loadTokens(s *Store, cfg Config, tokens persistedTokens, logger Logger) {
s.UpdateConfigFileRegistrationToken(cfg.ACLConfigFileRegistrationToken, TokenSourceConfig)
}

if tokens.DNS != "" {
s.UpdateDNSToken(tokens.DNS, TokenSourceAPI)

if cfg.ACLDNSToken != "" {
logger.Warn("\"dns\" token present in both the configuration and persisted token store, using the persisted token")
}
} else {
s.UpdateDNSToken(cfg.ACLDNSToken, TokenSourceConfig)
}

loadEnterpriseTokens(s, cfg)
}

Expand Down Expand Up @@ -206,6 +218,10 @@ func (p *fileStore) saveToFile(s *Store) error {
tokens.ConfigFileRegistration = tok
}

if tok, source := s.DNSTokenAndSource(); tok != "" && source == TokenSourceAPI {
tokens.DNS = tok
}

data, err := json.Marshal(tokens)
if err != nil {
p.logger.Warn("failed to persist tokens", "error", err)
Expand Down
Loading

0 comments on commit 9eaa8eb

Please sign in to comment.