From 1df66878050d7910653368afe36445893ca3cd0e Mon Sep 17 00:00:00 2001 From: Ricardo Pchevuzinske Katz Date: Tue, 31 Jan 2017 17:00:01 -0200 Subject: [PATCH 1/3] Improve the Fake Certificate Creation --- core/pkg/net/ssl/ssl.go | 56 +++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/core/pkg/net/ssl/ssl.go b/core/pkg/net/ssl/ssl.go index 1ac6d2fa2..3559e1070 100644 --- a/core/pkg/net/ssl/ssl.go +++ b/core/pkg/net/ssl/ssl.go @@ -19,12 +19,17 @@ package ssl import ( "crypto/sha1" "crypto/x509" + "crypto/x509/pkix" + "crypto/rand" + "crypto/rsa" "encoding/hex" "encoding/pem" "errors" "fmt" + "math/big" "io/ioutil" "os" + "time" "github.com/golang/glog" @@ -159,23 +164,54 @@ func pemSHA1(filename string) string { return hex.EncodeToString(hasher.Sum(nil)) } -const ( - snakeOilPem = "/etc/ssl/certs/ssl-cert-snakeoil.pem" - snakeOilKey = "/etc/ssl/private/ssl-cert-snakeoil.key" -) -// GetFakeSSLCert returns the snake oil ssl certificate created by the command -// make-ssl-cert generate-default-snakeoil --force-overwrite +// GetFakeSSLCert creates a Self Signed Certificate +// Based in the code https://golang.org/src/crypto/tls/generate_cert.go func GetFakeSSLCert() ([]byte, []byte) { - cert, err := ioutil.ReadFile(snakeOilPem) + + var priv, privtype interface{} + var err error + + priv, err = rsa.GenerateKey(rand.Reader, 2048) + + privtype = &priv.(*rsa.PrivateKey).PublicKey + if err != nil { - return nil, nil + glog.Fatalf("failed to generate fake private key: %s", err) } - key, err := ioutil.ReadFile(snakeOilKey) + notBefore := time.Now() + // This certificate is valid for 365 days + notAfter := notBefore.Add(365*24*time.Hour) + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { - return nil, nil + glog.Fatalf("failed to generate fake serial number: %s", err) } + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{"Acme Co"}, + }, + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + DNSNames: []string{"ingress.local"}, + } + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, privtype, priv) + if err != nil { + glog.Fatalf("Failed to create fake certificate: %s", err) + } + + cert := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) + + key := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv.(*rsa.PrivateKey))}) + return cert, key } From 5fc45ea1f5ee8c6a88a80b023da506148cf72489 Mon Sep 17 00:00:00 2001 From: Ricardo Pchevuzinske Katz Date: Tue, 31 Jan 2017 19:48:55 -0200 Subject: [PATCH 2/3] Improves Fake Cert generation --- core/pkg/ingress/controller/backend_ssl.go | 2 +- core/pkg/ingress/controller/controller.go | 18 +++++++++++---- core/pkg/net/ssl/ssl.go | 26 ++++++++++------------ 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/core/pkg/ingress/controller/backend_ssl.go b/core/pkg/ingress/controller/backend_ssl.go index 92c32fc8c..13624fd8a 100644 --- a/core/pkg/ingress/controller/backend_ssl.go +++ b/core/pkg/ingress/controller/backend_ssl.go @@ -56,7 +56,7 @@ func (ic *GenericController) syncSecret(k interface{}) error { } } else { defCert, defKey := ssl.GetFakeSSLCert() - cert, err = ssl.AddOrUpdateCertAndKey("system-snake-oil-certificate", defCert, defKey, []byte{}) + cert, err = ssl.AddOrUpdateCertAndKey("default-fake-certificate", defCert, defKey, []byte{}) if err != nil { return nil } diff --git a/core/pkg/ingress/controller/controller.go b/core/pkg/ingress/controller/controller.go index 146a00aa3..28942e112 100644 --- a/core/pkg/ingress/controller/controller.go +++ b/core/pkg/ingress/controller/controller.go @@ -18,6 +18,7 @@ package controller import ( "fmt" + "os" "reflect" "sort" "strconv" @@ -834,13 +835,22 @@ func (ic *GenericController) createServers(data []interface{}, upstreams map[str // If no default Certificate was supplied, tries to generate a new dumb one if err != nil { var cert *ingress.SSLCert - defCert, defKey := ssl.GetFakeSSLCert() - cert, err = ssl.AddOrUpdateCertAndKey("system-snake-oil-certificate", defCert, defKey, []byte{}) + fakeCertificate := "default-fake-certificate" + fakeCertificatePath := fmt.Sprintf("%v/%v.pem", ingress.DefaultSSLDirectory, fakeCertificate) + + // Only generates a new certificate if it doesn't exists physically + _, err := os.Stat(fakeCertificatePath) if err != nil { - glog.Fatalf("Error generating self signed certificate: %v", err) - } else { + defCert, defKey := ssl.GetFakeSSLCert() + cert, err = ssl.AddOrUpdateCertAndKey(fakeCertificate, defCert, defKey, []byte{}) + if err != nil { + glog.Fatalf("Error generating self signed certificate: %v", err) + } defaultPemFileName = cert.PemFileName defaultPemSHA = cert.PemSHA + } else { + defaultPemFileName = fakeCertificatePath + defaultPemSHA = ssl.PemSHA1(fakeCertificatePath) } } else { defaultPemFileName = defaultCertificate.PemFileName diff --git a/core/pkg/net/ssl/ssl.go b/core/pkg/net/ssl/ssl.go index 3559e1070..46006c01e 100644 --- a/core/pkg/net/ssl/ssl.go +++ b/core/pkg/net/ssl/ssl.go @@ -17,17 +17,17 @@ limitations under the License. package ssl import ( + "crypto/rand" + "crypto/rsa" "crypto/sha1" "crypto/x509" "crypto/x509/pkix" - "crypto/rand" - "crypto/rsa" "encoding/hex" "encoding/pem" "errors" "fmt" - "math/big" "io/ioutil" + "math/big" "os" "time" @@ -118,14 +118,14 @@ func AddOrUpdateCertAndKey(name string, cert, key, ca []byte) (*ingress.SSLCert, return &ingress.SSLCert{ CAFileName: caFileName, PemFileName: pemFileName, - PemSHA: pemSHA1(pemFileName), + PemSHA: PemSHA1(pemFileName), CN: cn, }, nil } return &ingress.SSLCert{ PemFileName: pemFileName, - PemSHA: pemSHA1(pemFileName), + PemSHA: PemSHA1(pemFileName), CN: cn, }, nil } @@ -151,9 +151,9 @@ func SearchDHParamFile(baseDir string) string { return "" } -// pemSHA1 returns the SHA1 of a pem file. This is used to +// PemSHA1 returns the SHA1 of a pem file. This is used to // reload NGINX in case a secret with a SSL certificate changed. -func pemSHA1(filename string) string { +func PemSHA1(filename string) string { hasher := sha1.New() s, err := ioutil.ReadFile(filename) if err != nil { @@ -164,25 +164,22 @@ func pemSHA1(filename string) string { return hex.EncodeToString(hasher.Sum(nil)) } - // GetFakeSSLCert creates a Self Signed Certificate // Based in the code https://golang.org/src/crypto/tls/generate_cert.go func GetFakeSSLCert() ([]byte, []byte) { - var priv, privtype interface{} + var priv interface{} var err error priv, err = rsa.GenerateKey(rand.Reader, 2048) - privtype = &priv.(*rsa.PrivateKey).PublicKey - if err != nil { glog.Fatalf("failed to generate fake private key: %s", err) } notBefore := time.Now() // This certificate is valid for 365 days - notAfter := notBefore.Add(365*24*time.Hour) + notAfter := notBefore.Add(365 * 24 * time.Hour) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) @@ -195,6 +192,7 @@ func GetFakeSSLCert() ([]byte, []byte) { SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Acme Co"}, + CommonName: "Kubernetes Ingress Controller Fake Certificate", }, NotBefore: notBefore, NotAfter: notAfter, @@ -202,9 +200,9 @@ func GetFakeSSLCert() ([]byte, []byte) { KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, - DNSNames: []string{"ingress.local"}, + DNSNames: []string{"ingress.local"}, } - derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, privtype, priv) + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.(*rsa.PrivateKey).PublicKey, priv) if err != nil { glog.Fatalf("Failed to create fake certificate: %s", err) } From aa07e67a51ccd641b663fa4e0a77324d3ae008d1 Mon Sep 17 00:00:00 2001 From: Ricardo Pchevuzinske Katz Date: Tue, 28 Feb 2017 19:34:58 -0300 Subject: [PATCH 3/3] Removes the default certificate from non TLS configured vhosts --- core/pkg/ingress/controller/controller.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/pkg/ingress/controller/controller.go b/core/pkg/ingress/controller/controller.go index 189a2f4c9..ee04734cd 100644 --- a/core/pkg/ingress/controller/controller.go +++ b/core/pkg/ingress/controller/controller.go @@ -953,9 +953,6 @@ func (ic *GenericController) createServers(data []interface{}, servers[host].SSLCertificate = cert.PemFileName servers[host].SSLPemChecksum = cert.PemSHA } - } else { - servers[host].SSLCertificate = defaultPemFileName - servers[host].SSLPemChecksum = defaultPemSHA } } }