Skip to content

Commit

Permalink
Merge pull request openshift#145 from yifan-gu/generate_tls
Browse files Browse the repository at this point in the history
tls: Generate TLS assets through dependency graph
  • Loading branch information
openshift-merge-robot authored Aug 29, 2018
2 parents aaa47f6 + cf8cd4c commit ae7fe33
Show file tree
Hide file tree
Showing 18 changed files with 1,007 additions and 93 deletions.
4 changes: 2 additions & 2 deletions installer/pkg/config-generator/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ go_library(
deps = [
"//installer/pkg/config:go_default_library",
"//installer/pkg/copy:go_default_library",
"//installer/pkg/tls:go_default_library",
"//pkg/asset/tls:go_default_library",
"//vendor/github.com/apparentlymart/go-cidr/cidr:go_default_library",
"//vendor/github.com/coreos/ignition/config/v2_2:go_default_library",
"//vendor/github.com/coreos/ignition/config/v2_2/types:go_default_library",
Expand All @@ -35,6 +35,6 @@ go_test(
embed = [":go_default_library"],
deps = [
"//installer/pkg/config:go_default_library",
"//installer/pkg/tls:go_default_library",
"//pkg/asset/tls:go_default_library",
],
)
6 changes: 3 additions & 3 deletions installer/pkg/config-generator/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"testing"

"github.com/openshift/installer/installer/pkg/config"
"github.com/openshift/installer/installer/pkg/tls"
"github.com/openshift/installer/pkg/asset/tls"
)

func initConfig(t *testing.T, file string) ConfigGenerator {
Expand Down Expand Up @@ -131,7 +131,7 @@ func TestGenerateCert(t *testing.T) {
CommonName: "test-self-signed-ca",
OrganizationalUnit: []string{"openshift"},
},
Validity: validityTenYears,
Validity: tls.ValidityTenYears,
}
caCert, err := tls.SelfSignedCACert(caCfg, caKey)
if err != nil {
Expand All @@ -151,7 +151,7 @@ func TestGenerateCert(t *testing.T) {
KeyUsages: x509.KeyUsageKeyEncipherment,
DNSNames: []string{"test-api.kubernetes.default"},
ExtKeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
Validity: validityTenYears,
Validity: tls.ValidityTenYears,
IsCA: false,
},
clusterDir: "./",
Expand Down
130 changes: 47 additions & 83 deletions installer/pkg/config-generator/tls.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package configgenerator

import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
Expand All @@ -10,10 +9,9 @@ import (
"io/ioutil"
"net"
"path/filepath"
"time"

"github.com/openshift/installer/installer/pkg/copy"
"github.com/openshift/installer/installer/pkg/tls"
"github.com/openshift/installer/pkg/asset/tls"
)

const (
Expand Down Expand Up @@ -48,9 +46,6 @@ const (
tncKeyPath = "generated/tls/tnc.key"
serviceAccountPubkeyPath = "generated/tls/service-account.pub"
serviceAccountPrivateKeyPath = "generated/tls/service-account.key"

validityTenYears = time.Hour * 24 * 365 * 10
validityThirtyMinutes = time.Minute * 30
)

// GenerateTLSConfig fetches and validates the TLS cert files
Expand All @@ -77,7 +72,7 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
cfg := &tls.CertCfg{
Subject: pkix.Name{CommonName: "kube-ca", OrganizationalUnit: []string{"bootkube"}},
KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
Validity: validityTenYears,
Validity: tls.ValidityTenYears,
IsCA: true,
}
kubeCAKey, kubeCACert, err := generateCert(clusterDir, caKey, caCert, kubeCAKeyPath, kubeCACertPath, cfg, false)
Expand All @@ -90,7 +85,7 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
Subject: pkix.Name{CommonName: "etcd", OrganizationalUnit: []string{"etcd"}},
KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
IsCA: true,
Validity: validityTenYears,
Validity: tls.ValidityTenYears,
}
etcdCAKey, etcdCACert, err := generateCert(clusterDir, caKey, caCert, etcdCAKeyPath, etcdCACertPath, cfg, false)
if err != nil {
Expand All @@ -109,7 +104,7 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
Subject: pkix.Name{CommonName: "etcd", OrganizationalUnit: []string{"etcd"}},
KeyUsages: x509.KeyUsageKeyEncipherment,
ExtKeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
Validity: validityTenYears,
Validity: tls.ValidityTenYears,
}
if _, _, err := generateCert(clusterDir, etcdCAKey, etcdCACert, etcdClientKeyPath, etcdClientCertPath, cfg, false); err != nil {
return fmt.Errorf("failed to generate etcd client certificate: %v", err)
Expand All @@ -119,7 +114,7 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
cfg = &tls.CertCfg{
Subject: pkix.Name{CommonName: "aggregator", OrganizationalUnit: []string{"bootkube"}},
KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
Validity: validityTenYears,
Validity: tls.ValidityTenYears,
IsCA: true,
}
aggregatorCAKey, aggregatorCACert, err := generateCert(clusterDir, caKey, caCert, aggregatorCAKeyPath, aggregatorCACertPath, cfg, false)
Expand All @@ -131,7 +126,7 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
cfg = &tls.CertCfg{
Subject: pkix.Name{CommonName: "service-serving", OrganizationalUnit: []string{"bootkube"}},
KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
Validity: validityTenYears,
Validity: tls.ValidityTenYears,
IsCA: true,
}
if _, _, err := generateCert(clusterDir, caKey, caCert, serviceServingCAKeyPath, serviceServingCACertPath, cfg, false); err != nil {
Expand All @@ -152,7 +147,7 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
fmt.Sprintf("*.%s", baseAddress),
},
Subject: pkix.Name{CommonName: baseAddress, Organization: []string{"ingress"}},
Validity: validityTenYears,
Validity: tls.ValidityTenYears,
IsCA: false,
}

Expand All @@ -165,7 +160,7 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
Subject: pkix.Name{CommonName: "system:admin", Organization: []string{"system:masters"}},
Validity: validityTenYears,
Validity: tls.ValidityTenYears,
IsCA: false,
}

Expand All @@ -188,7 +183,7 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
"kubernetes.default.svc",
"kubernetes.default.svc.cluster.local",
},
Validity: validityTenYears,
Validity: tls.ValidityTenYears,
IPAddresses: []net.IP{net.ParseIP(apiServerAddress)},
IsCA: false,
}
Expand All @@ -209,7 +204,7 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
"openshift-apiserver.kube-system.svc",
"openshift-apiserver.kube-system.svc.cluster.local",
"localhost", "127.0.0.1"},
Validity: validityTenYears,
Validity: tls.ValidityTenYears,
IPAddresses: []net.IP{net.ParseIP(apiServerAddress)},
IsCA: false,
}
Expand All @@ -223,7 +218,7 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
Subject: pkix.Name{CommonName: "kube-apiserver-proxy", Organization: []string{"kube-master"}},
Validity: validityTenYears,
Validity: tls.ValidityTenYears,
IsCA: false,
}

Expand All @@ -236,7 +231,7 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
Subject: pkix.Name{CommonName: "system:serviceaccount:kube-system:default", Organization: []string{"system:serviceaccounts:kube-system"}},
Validity: validityThirtyMinutes,
Validity: tls.ValidityThirtyMinutes,
IsCA: false,
}

Expand All @@ -250,7 +245,7 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
ExtKeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
DNSNames: []string{tncDomain},
Subject: pkix.Name{CommonName: tncDomain},
Validity: validityTenYears,
Validity: tls.ValidityTenYears,
IsCA: false,
}

Expand All @@ -262,7 +257,7 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
cfg = &tls.CertCfg{
Subject: pkix.Name{CommonName: "cluster-apiserver", OrganizationalUnit: []string{"bootkube"}},
KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
Validity: validityTenYears,
Validity: tls.ValidityTenYears,
IsCA: true,
}
if _, _, err := generateCert(clusterDir, aggregatorCAKey, aggregatorCACert, clusterAPIServerKeyPath, clusterAPIServerCertPath, cfg, true); err != nil {
Expand Down Expand Up @@ -302,15 +297,32 @@ func generatePrivateKey(clusterDir string, path string) (*rsa.PrivateKey, error)

// generateRootCert creates the rootCAKey and rootCACert
func generateRootCert(clusterDir string) (cert *x509.Certificate, key *rsa.PrivateKey, err error) {
// generate key and certificate
caKey, err := generatePrivateKey(clusterDir, rootCAKeyPath)
if err != nil {
return nil, nil, fmt.Errorf("failed to generate private key: %v", err)
targetKeyPath := filepath.Join(clusterDir, rootCAKeyPath)
targetCertPath := filepath.Join(clusterDir, rootCACertPath)

cfg := &tls.CertCfg{
Subject: pkix.Name{
CommonName: "root-ca",
OrganizationalUnit: []string{"openshift"},
},
KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
Validity: tls.ValidityTenYears,
IsCA: true,
}
caCert, err := generateRootCA(clusterDir, caKey)

caKey, caCert, err := tls.GenerateRootCertKey(cfg)
if err != nil {
return nil, nil, fmt.Errorf("failed to create a certificate: %v", err)
return nil, nil, err
}

if err := ioutil.WriteFile(targetKeyPath, []byte(tls.PrivateKeyToPem(caKey)), 0600); err != nil {
return nil, nil, err
}

if err := ioutil.WriteFile(targetCertPath, []byte(tls.CertToPem(caCert)), 0666); err != nil {
return nil, nil, err
}

return caCert, caKey, nil
}

Expand Down Expand Up @@ -361,74 +373,26 @@ func generateCert(clusterDir string,
cfg *tls.CertCfg,
appendCA bool) (*rsa.PrivateKey, *x509.Certificate, error) {

// create a private key
key, err := generatePrivateKey(clusterDir, keyPath)
if err != nil {
return nil, nil, fmt.Errorf("failed to generate private key: %v", err)
}

// create a CSR
csrTmpl := x509.CertificateRequest{Subject: cfg.Subject, DNSNames: cfg.DNSNames, IPAddresses: cfg.IPAddresses}
csrBytes, err := x509.CreateCertificateRequest(rand.Reader, &csrTmpl, key)
if err != nil {
return nil, nil, fmt.Errorf("error creating certificate request: %v", err)
}
csr, err := x509.ParseCertificateRequest(csrBytes)
if err != nil {
return nil, nil, fmt.Errorf("error parsing certificate request: %v", err)
}

// create a cert
cert, err := generateSignedCert(cfg, csr, key, caKey, caCert, clusterDir, certPath, appendCA)
if err != nil {
return nil, nil, fmt.Errorf("failed to create a certificate: %v", err)
}
return key, cert, nil
}
targetKeyPath := filepath.Join(clusterDir, keyPath)
targetCertPath := filepath.Join(clusterDir, certPath)

// generateRootCA creates and returns the root CA
func generateRootCA(path string, key *rsa.PrivateKey) (*x509.Certificate, error) {
fileTargetPath := filepath.Join(path, rootCACertPath)
cfg := &tls.CertCfg{
Subject: pkix.Name{
CommonName: "root-ca",
OrganizationalUnit: []string{"openshift"},
},
KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
Validity: validityTenYears,
IsCA: true,
}
cert, err := tls.SelfSignedCACert(cfg, key)
key, cert, err := tls.GenerateCert(caKey, caCert, cfg)
if err != nil {
return nil, fmt.Errorf("error generating self signed certificate: %v", err)
}
if err := ioutil.WriteFile(fileTargetPath, []byte(tls.CertToPem(cert)), 0666); err != nil {
return nil, err
return nil, nil, err
}
return cert, nil
}

func generateSignedCert(cfg *tls.CertCfg,
csr *x509.CertificateRequest,
key *rsa.PrivateKey,
caKey *rsa.PrivateKey,
caCert *x509.Certificate,
clusterDir string,
path string,
appendCA bool) (*x509.Certificate, error) {
cert, err := tls.SignedCertificate(cfg, csr, key, caCert, caKey)
if err != nil {
return nil, fmt.Errorf("error signing certificate: %v", err)
if err := ioutil.WriteFile(targetKeyPath, []byte(tls.PrivateKeyToPem(key)), 0600); err != nil {
return nil, nil, err
}
fileTargetPath := filepath.Join(clusterDir, path)

content := []byte(tls.CertToPem(cert))
if appendCA {
content = append(content, '\n')
content = append(content, []byte(tls.CertToPem(caCert))...)
}
if err := ioutil.WriteFile(fileTargetPath, content, 0666); err != nil {
return nil, err
if err := ioutil.WriteFile(targetCertPath, content, 0666); err != nil {
return nil, nil, err
}
return cert, nil

return key, cert, nil
}
2 changes: 1 addition & 1 deletion installer/pkg/validate/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ go_test(
srcs = ["validate_test.go"],
embed = [":go_default_library"],
deps = [
"//installer/pkg/tls:go_default_library",
"//pkg/asset/tls:go_default_library",
"//vendor/gopkg.in/square/go-jose.v2:go_default_library",
],
)
Expand Down
2 changes: 1 addition & 1 deletion installer/pkg/validate/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"testing"
"time"

"github.com/openshift/installer/installer/pkg/tls"
"github.com/openshift/installer/pkg/asset/tls"
jose "gopkg.in/square/go-jose.v2"
)

Expand Down
2 changes: 1 addition & 1 deletion pkg/asset/installconfig/stock.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type Stock interface {
Platform() asset.Asset
}

// StockImpl is the
// StockImpl implements the Stock interface for installconfig and user inputs.
type StockImpl struct {
installConfig asset.Asset
clusterID asset.Asset
Expand Down
8 changes: 8 additions & 0 deletions pkg/asset/stock/stock.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,31 @@ import (
"os"

"github.com/openshift/installer/pkg/asset/installconfig"
"github.com/openshift/installer/pkg/asset/tls"
)

// Stock is the stock of assets that can be generated.
type Stock struct {
installConfigStock
tlsStock
}

type installConfigStock struct {
installconfig.StockImpl
}

type tlsStock struct {
tls.StockImpl
}

var _ installconfig.Stock = (*Stock)(nil)

// EstablishStock establishes the stock of assets in the specified directory.
func EstablishStock(directory string) *Stock {
s := &Stock{}
inputReader := bufio.NewReader(os.Stdin)
s.installConfigStock.EstablishStock(directory, inputReader)
s.tlsStock.EstablishStock(directory, &s.installConfigStock)

return s
}
6 changes: 4 additions & 2 deletions installer/pkg/tls/BUILD.bazel → pkg/asset/tls/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_test(
name = "go_default_test",
size = "small",
srcs = ["tls_test.go"],
srcs = [
"tls_test.go",
],
embed = [":go_default_library"],
)

Expand All @@ -13,6 +15,6 @@ go_library(
"tls.go",
"utils.go",
],
importpath = "github.com/openshift/installer/installer/pkg/tls",
importpath = "github.com/openshift/installer/pkg/asset/tls",
visibility = ["//visibility:public"],
)
Loading

0 comments on commit ae7fe33

Please sign in to comment.