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

gateway: initial frontend TLS implementation #50437

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
48 changes: 44 additions & 4 deletions pilot/pkg/config/kube/gateway/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -2432,6 +2432,31 @@ func buildTLS(ctx configContext, tls *k8s.GatewayTLSConfig, gw config.Config, is
}
}
out.CredentialName = cred
if fv := tls.FrontendValidation; fv != nil {
if len(fv.CACertificateRefs) != 1 {
return out, &ConfigError{Reason: InvalidTLS, Message: "exactly 1 caCertificateRefs should be present for frontend TLS validation"}
}
cert := fv.CACertificateRefs[0]
// Istio's implementation is currently limited
// * Only Secret reference is allowed
// * Secret must match the TLS cert
// TODO(https://github.com/istio/istio/issues/49511) fix these.
if !emptyOrEqual((string)(cert.Group), gvk.Secret.Group) || string(cert.Kind) != gvk.Secret.Kind {
return out, &ConfigError{
Reason: InvalidTLS,
Message: fmt.Sprintf("invalid caCertificateRefs %v, only secret is allowed", objectReferenceString(cert)),
}
}
caNs := ptr.OrDefault((*string)(cert.Namespace), namespace)
// Artificial limitation.
if cert.Name != tls.CertificateRefs[0].Name || caNs != credNs {
return out, &ConfigError{
Reason: InvalidTLS,
Message: fmt.Sprintf("invalid caCertificateRefs %v, must match certificateRef", objectReferenceString(cert)),
}
}
out.Mode = istio.ServerTLSSettings_MUTUAL
}
case k8s.TLSModePassthrough:
out.Mode = istio.ServerTLSSettings_PASSTHROUGH
if isAutoPassthrough {
Expand All @@ -2443,7 +2468,10 @@ func buildTLS(ctx configContext, tls *k8s.GatewayTLSConfig, gw config.Config, is

func buildSecretReference(ctx configContext, ref k8s.SecretObjectReference, gw config.Config) (string, *ConfigError) {
if !nilOrEqual((*string)(ref.Group), gvk.Secret.Group) || !nilOrEqual((*string)(ref.Kind), gvk.Secret.Kind) {
return "", &ConfigError{Reason: InvalidTLS, Message: fmt.Sprintf("invalid certificate reference %v, only secret is allowed", objectReferenceString(ref))}
return "", &ConfigError{
Reason: InvalidTLS,
Message: fmt.Sprintf("invalid certificate reference %v, only secret is allowed", secretObjectReferenceString(ref)),
}
}

secret := model.ConfigKey{
Expand All @@ -2462,27 +2490,35 @@ func buildSecretReference(ctx configContext, ref k8s.SecretObjectReference, gw c
if certInfo, err := ctx.Credentials.GetCertInfo(secret.Name, secret.Namespace); err != nil {
return "", &ConfigError{
Reason: InvalidTLS,
Message: fmt.Sprintf("invalid certificate reference %v, %v", objectReferenceString(ref), err),
Message: fmt.Sprintf("invalid certificate reference %v, %v", secretObjectReferenceString(ref), err),
}
} else if _, err = tls.X509KeyPair(certInfo.Cert, certInfo.Key); err != nil {
return "", &ConfigError{
Reason: InvalidTLS,
Message: fmt.Sprintf("invalid certificate reference %v, the certificate is malformed: %v", objectReferenceString(ref), err),
Message: fmt.Sprintf("invalid certificate reference %v, the certificate is malformed: %v", secretObjectReferenceString(ref), err),
}
}
}

return creds.ToKubernetesGatewayResource(secret.Namespace, secret.Name), nil
}

func objectReferenceString(ref k8s.SecretObjectReference) string {
func secretObjectReferenceString(ref k8s.SecretObjectReference) string {
return fmt.Sprintf("%s/%s/%s.%s",
ptr.OrEmpty(ref.Group),
ptr.OrEmpty(ref.Kind),
ref.Name,
ptr.OrEmpty(ref.Namespace))
}

func objectReferenceString(ref k8s.ObjectReference) string {
return fmt.Sprintf("%s/%s/%s.%s",
ref.Group,
ref.Kind,
ref.Name,
ptr.OrEmpty(ref.Namespace))
}

func parentRefString(ref k8s.ParentReference) string {
return fmt.Sprintf("%s/%s/%s/%s/%d.%s",
ptr.OrEmpty(ref.Group),
Expand Down Expand Up @@ -2555,6 +2591,10 @@ func nilOrEqual(have *string, expected string) bool {
return have == nil || *have == expected
}

func emptyOrEqual(have string, expected string) bool {
return have == "" || have == expected
}

func humanReadableJoin(ss []string) string {
switch len(ss) {
case 0:
Expand Down