Validate hosts input in ingress gateway config entry
We can only allow host names that are valid domain names because we put these hosts into a DNSSAN. In addition, we validate that the wildcard specifier '*' is only present as the leftmost label to allow for a wildcard DNSSAN and associated wildcard Host routing in the ingress gateway proxy.
This commit is contained in:
parent
bd6bb3bf2d
commit
91586b9228
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/lib"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// IngressGatewayConfigEntry manages the configuration for an ingress service
|
||||
|
@ -163,12 +164,14 @@ func (e *IngressGatewayConfigEntry) Validate() error {
|
|||
return fmt.Errorf("Wildcard namespace is not supported for ingress services (listener on port %d)", listener.Port)
|
||||
}
|
||||
|
||||
// TODO(ingress): Validate Hosts are valid?
|
||||
for _, h := range s.Hosts {
|
||||
if declaredHosts[h] {
|
||||
return fmt.Errorf("Hosts must be unique within a specific listener (listener on port %d)", listener.Port)
|
||||
}
|
||||
declaredHosts[h] = true
|
||||
if err := validateHost(h); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -176,6 +179,19 @@ func (e *IngressGatewayConfigEntry) Validate() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func validateHost(host string) error {
|
||||
wildcardPrefix := "*."
|
||||
if _, ok := dns.IsDomainName(host); !ok {
|
||||
return fmt.Errorf("Host %q must be a valid DNS hostname", host)
|
||||
}
|
||||
|
||||
if strings.ContainsRune(strings.TrimPrefix(host, wildcardPrefix), '*') {
|
||||
return fmt.Errorf("Host %q is not valid, a wildcard specifier is only allowed as the leftmost label", host)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *IngressGatewayConfigEntry) CanRead(authz acl.Authorizer) bool {
|
||||
var authzContext acl.AuthorizerContext
|
||||
e.FillAuthzContext(&authzContext)
|
||||
|
|
|
@ -316,6 +316,85 @@ func TestIngressConfigEntry_Validate(t *testing.T) {
|
|||
},
|
||||
expectErr: "Hosts must be unique within a specific listener",
|
||||
},
|
||||
{
|
||||
name: "hosts must be a valid DNS name",
|
||||
entry: IngressGatewayConfigEntry{
|
||||
Kind: "ingress-gateway",
|
||||
Name: "ingress-web",
|
||||
Listeners: []IngressListener{
|
||||
{
|
||||
Port: 1111,
|
||||
Protocol: "http",
|
||||
Services: []IngressService{
|
||||
{
|
||||
Name: "db",
|
||||
Hosts: []string{"example..com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectErr: `Host "example..com" must be a valid DNS hostname`,
|
||||
},
|
||||
{
|
||||
name: "wildcard specifier is only allowed in the leftmost label",
|
||||
entry: IngressGatewayConfigEntry{
|
||||
Kind: "ingress-gateway",
|
||||
Name: "ingress-web",
|
||||
Listeners: []IngressListener{
|
||||
{
|
||||
Port: 1111,
|
||||
Protocol: "http",
|
||||
Services: []IngressService{
|
||||
{
|
||||
Name: "db",
|
||||
Hosts: []string{"*.example.com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "wildcard specifier is not allowed in non-leftmost labels",
|
||||
entry: IngressGatewayConfigEntry{
|
||||
Kind: "ingress-gateway",
|
||||
Name: "ingress-web",
|
||||
Listeners: []IngressListener{
|
||||
{
|
||||
Port: 1111,
|
||||
Protocol: "http",
|
||||
Services: []IngressService{
|
||||
{
|
||||
Name: "db",
|
||||
Hosts: []string{"example.*.com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectErr: `Host "example.*.com" is not valid, a wildcard specifier is only allowed as the leftmost label`,
|
||||
},
|
||||
{
|
||||
name: "wildcard specifier is not allowed in leftmost labels as a partial",
|
||||
entry: IngressGatewayConfigEntry{
|
||||
Kind: "ingress-gateway",
|
||||
Name: "ingress-web",
|
||||
Listeners: []IngressListener{
|
||||
{
|
||||
Port: 1111,
|
||||
Protocol: "http",
|
||||
Services: []IngressService{
|
||||
{
|
||||
Name: "db",
|
||||
Hosts: []string{"*-test.example.com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectErr: `Host "*-test.example.com" is not valid, a wildcard specifier is only allowed as the leftmost label`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range cases {
|
||||
|
|
Loading…
Reference in New Issue