Merge pull request #2698 from antoineco/bug/no-host-tls

Improve best-cert guessing with empty tls.hosts
This commit is contained in:
k8s-ci-robot 2018-06-24 17:00:04 -07:00 committed by GitHub
commit e8a34d252c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 19 deletions

View file

@ -1063,7 +1063,7 @@ func extractTLSSecretName(host string, ing *extensions.Ingress,
} }
} }
// no TLS host matching host name, try each TLS host for matching CN // no TLS host matching host name, try each TLS host for matching SAN or CN
for _, tls := range ing.Spec.TLS { for _, tls := range ing.Spec.TLS {
key := fmt.Sprintf("%v/%v", ing.Namespace, tls.SecretName) key := fmt.Sprintf("%v/%v", ing.Namespace, tls.SecretName)
cert, err := getLocalSSLCert(key) cert, err := getLocalSSLCert(key)
@ -1072,13 +1072,16 @@ func extractTLSSecretName(host string, ing *extensions.Ingress,
continue continue
} }
if cert == nil { if cert == nil { // for tests
continue continue
} }
if sets.NewString(cert.CN...).Has(host) { err = cert.Certificate.VerifyHostname(host)
return tls.SecretName if err != nil {
continue
} }
glog.V(3).Infof("Found SSL certificate matching host %q: %q", host, key)
return tls.SecretName
} }
return "" return ""

View file

@ -17,6 +17,9 @@ limitations under the License.
package controller package controller
import ( import (
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"testing" "testing"
extensions "k8s.io/api/extensions/v1beta1" extensions "k8s.io/api/extensions/v1beta1"
@ -25,13 +28,13 @@ import (
) )
func TestExtractTLSSecretName(t *testing.T) { func TestExtractTLSSecretName(t *testing.T) {
tests := []struct { testCases := map[string]struct {
host string host string
ingress *extensions.Ingress ingress *extensions.Ingress
fn func(string) (*ingress.SSLCert, error) fn func(string) (*ingress.SSLCert, error)
expName string expName string
}{ }{
{ "nil ingress": {
"foo.bar", "foo.bar",
nil, nil,
func(string) (*ingress.SSLCert, error) { func(string) (*ingress.SSLCert, error) {
@ -39,7 +42,7 @@ func TestExtractTLSSecretName(t *testing.T) {
}, },
"", "",
}, },
{ "empty ingress": {
"foo.bar", "foo.bar",
&extensions.Ingress{}, &extensions.Ingress{},
func(string) (*ingress.SSLCert, error) { func(string) (*ingress.SSLCert, error) {
@ -47,7 +50,7 @@ func TestExtractTLSSecretName(t *testing.T) {
}, },
"", "",
}, },
{ "ingress tls, nil secret": {
"foo.bar", "foo.bar",
&extensions.Ingress{ &extensions.Ingress{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -69,7 +72,7 @@ func TestExtractTLSSecretName(t *testing.T) {
}, },
"", "",
}, },
{ "ingress tls, no host, matching cert cn": {
"foo.bar", "foo.bar",
&extensions.Ingress{ &extensions.Ingress{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -88,12 +91,38 @@ func TestExtractTLSSecretName(t *testing.T) {
}, },
func(string) (*ingress.SSLCert, error) { func(string) (*ingress.SSLCert, error) {
return &ingress.SSLCert{ return &ingress.SSLCert{
CN: []string{"foo.bar", "example.com"}, Certificate: fakeX509Cert([]string{"foo.bar", "example.com"}),
}, nil }, nil
}, },
"demo", "demo",
}, },
{ "ingress tls, no host, wildcard cert with matching cn": {
"foo.bar",
&extensions.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
Spec: extensions.IngressSpec{
TLS: []extensions.IngressTLS{
{
SecretName: "demo",
},
},
Rules: []extensions.IngressRule{
{
Host: "test.foo.bar",
},
},
},
},
func(string) (*ingress.SSLCert, error) {
return &ingress.SSLCert{
Certificate: fakeX509Cert([]string{"*.foo.bar", "foo.bar"}),
}, nil
},
"demo",
},
"ingress tls, hosts, matching cert cn": {
"foo.bar", "foo.bar",
&extensions.Ingress{ &extensions.Ingress{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -114,18 +143,29 @@ func TestExtractTLSSecretName(t *testing.T) {
}, },
}, },
func(string) (*ingress.SSLCert, error) { func(string) (*ingress.SSLCert, error) {
return &ingress.SSLCert{ return nil, nil
CN: []string{"foo.bar", "example.com"},
}, nil
}, },
"demo", "demo",
}, },
} }
for _, testCase := range tests { for title, tc := range testCases {
name := extractTLSSecretName(testCase.host, testCase.ingress, testCase.fn) t.Run(title, func(t *testing.T) {
if name != testCase.expName { name := extractTLSSecretName(tc.host, tc.ingress, tc.fn)
t.Errorf("expected %v as the name of the secret but got %v", testCase.expName, name) if name != tc.expName {
} t.Errorf("Expected Secret name %q (got %q)", tc.expName, name)
}
})
}
}
var oidExtensionSubjectAltName = asn1.ObjectIdentifier{2, 5, 29, 17}
func fakeX509Cert(dnsNames []string) *x509.Certificate {
return &x509.Certificate{
DNSNames: dnsNames,
Extensions: []pkix.Extension{
{Id: oidExtensionSubjectAltName},
},
} }
} }