Improves Fake Cert generation

This commit is contained in:
Ricardo Pchevuzinske Katz 2017-01-31 19:48:55 -02:00
parent 1df6687805
commit 5fc45ea1f5
3 changed files with 27 additions and 19 deletions

View file

@ -56,7 +56,7 @@ func (ic *GenericController) syncSecret(k interface{}) error {
} }
} else { } else {
defCert, defKey := ssl.GetFakeSSLCert() 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 { if err != nil {
return nil return nil
} }

View file

@ -18,6 +18,7 @@ package controller
import ( import (
"fmt" "fmt"
"os"
"reflect" "reflect"
"sort" "sort"
"strconv" "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 no default Certificate was supplied, tries to generate a new dumb one
if err != nil { if err != nil {
var cert *ingress.SSLCert var cert *ingress.SSLCert
defCert, defKey := ssl.GetFakeSSLCert() fakeCertificate := "default-fake-certificate"
cert, err = ssl.AddOrUpdateCertAndKey("system-snake-oil-certificate", defCert, defKey, []byte{}) 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 { if err != nil {
glog.Fatalf("Error generating self signed certificate: %v", err) defCert, defKey := ssl.GetFakeSSLCert()
} else { cert, err = ssl.AddOrUpdateCertAndKey(fakeCertificate, defCert, defKey, []byte{})
if err != nil {
glog.Fatalf("Error generating self signed certificate: %v", err)
}
defaultPemFileName = cert.PemFileName defaultPemFileName = cert.PemFileName
defaultPemSHA = cert.PemSHA defaultPemSHA = cert.PemSHA
} else {
defaultPemFileName = fakeCertificatePath
defaultPemSHA = ssl.PemSHA1(fakeCertificatePath)
} }
} else { } else {
defaultPemFileName = defaultCertificate.PemFileName defaultPemFileName = defaultCertificate.PemFileName

View file

@ -17,17 +17,17 @@ limitations under the License.
package ssl package ssl
import ( import (
"crypto/rand"
"crypto/rsa"
"crypto/sha1" "crypto/sha1"
"crypto/x509" "crypto/x509"
"crypto/x509/pkix" "crypto/x509/pkix"
"crypto/rand"
"crypto/rsa"
"encoding/hex" "encoding/hex"
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt" "fmt"
"math/big"
"io/ioutil" "io/ioutil"
"math/big"
"os" "os"
"time" "time"
@ -118,14 +118,14 @@ func AddOrUpdateCertAndKey(name string, cert, key, ca []byte) (*ingress.SSLCert,
return &ingress.SSLCert{ return &ingress.SSLCert{
CAFileName: caFileName, CAFileName: caFileName,
PemFileName: pemFileName, PemFileName: pemFileName,
PemSHA: pemSHA1(pemFileName), PemSHA: PemSHA1(pemFileName),
CN: cn, CN: cn,
}, nil }, nil
} }
return &ingress.SSLCert{ return &ingress.SSLCert{
PemFileName: pemFileName, PemFileName: pemFileName,
PemSHA: pemSHA1(pemFileName), PemSHA: PemSHA1(pemFileName),
CN: cn, CN: cn,
}, nil }, nil
} }
@ -151,9 +151,9 @@ func SearchDHParamFile(baseDir string) string {
return "" 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. // reload NGINX in case a secret with a SSL certificate changed.
func pemSHA1(filename string) string { func PemSHA1(filename string) string {
hasher := sha1.New() hasher := sha1.New()
s, err := ioutil.ReadFile(filename) s, err := ioutil.ReadFile(filename)
if err != nil { if err != nil {
@ -164,25 +164,22 @@ func pemSHA1(filename string) string {
return hex.EncodeToString(hasher.Sum(nil)) return hex.EncodeToString(hasher.Sum(nil))
} }
// GetFakeSSLCert creates a Self Signed Certificate // GetFakeSSLCert creates a Self Signed Certificate
// Based in the code https://golang.org/src/crypto/tls/generate_cert.go // Based in the code https://golang.org/src/crypto/tls/generate_cert.go
func GetFakeSSLCert() ([]byte, []byte) { func GetFakeSSLCert() ([]byte, []byte) {
var priv, privtype interface{} var priv interface{}
var err error var err error
priv, err = rsa.GenerateKey(rand.Reader, 2048) priv, err = rsa.GenerateKey(rand.Reader, 2048)
privtype = &priv.(*rsa.PrivateKey).PublicKey
if err != nil { if err != nil {
glog.Fatalf("failed to generate fake private key: %s", err) glog.Fatalf("failed to generate fake private key: %s", err)
} }
notBefore := time.Now() notBefore := time.Now()
// This certificate is valid for 365 days // 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) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
@ -195,6 +192,7 @@ func GetFakeSSLCert() ([]byte, []byte) {
SerialNumber: serialNumber, SerialNumber: serialNumber,
Subject: pkix.Name{ Subject: pkix.Name{
Organization: []string{"Acme Co"}, Organization: []string{"Acme Co"},
CommonName: "Kubernetes Ingress Controller Fake Certificate",
}, },
NotBefore: notBefore, NotBefore: notBefore,
NotAfter: notAfter, NotAfter: notAfter,
@ -202,9 +200,9 @@ func GetFakeSSLCert() ([]byte, []byte) {
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true, 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 { if err != nil {
glog.Fatalf("Failed to create fake certificate: %s", err) glog.Fatalf("Failed to create fake certificate: %s", err)
} }