Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions installer/cmd/tectonic/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ var (
clusterInitConfigFlag = clusterInitCommand.Flag("config", "Cluster specification file").Required().ExistingFile()

clusterInstallCommand = kingpin.Command("install", "Create a new Tectonic cluster")
clusterInstallTLSCommand = clusterInstallCommand.Command("tls", "Generate TLS Certificates.")
clusterInstallTLSNewCommand = clusterInstallCommand.Command("newtls", "Generate TLS Certificates, using a new engine (experimental)")
clusterInstallTLSNewCommand = clusterInstallCommand.Command("tls", "Generate TLS Certificates.")
clusterInstallAssetsCommand = clusterInstallCommand.Command("assets", "Generate Tectonic assets.")
clusterInstallBootstrapCommand = clusterInstallCommand.Command("bootstrap", "Create a single bootstrap node Tectonic cluster.")
clusterInstallFullCommand = clusterInstallCommand.Command("full", "Create a new Tectonic cluster").Default()
Expand All @@ -39,8 +38,6 @@ func main() {
w = workflow.InitWorkflow(*clusterInitConfigFlag)
case clusterInstallFullCommand.FullCommand():
w = workflow.InstallFullWorkflow(*clusterInstallDirFlag)
case clusterInstallTLSCommand.FullCommand():
w = workflow.InstallTLSWorkflow(*clusterInstallDirFlag)
case clusterInstallTLSNewCommand.FullCommand():
w = workflow.InstallTLSNewWorkflow(*clusterInstallDirFlag)
case clusterInstallAssetsCommand.FullCommand():
Expand Down
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 @@ -131,7 +131,7 @@ func TestGenerateCert(t *testing.T) {
CommonName: "test-self-signed-ca",
OrganizationalUnit: []string{"openshift"},
},
Validity: validityThreeYears,
Validity: validityTenYears,
}
caCert, err := tls.SelfSignedCACert(caCfg, caKey)
if err != nil {
Expand All @@ -151,15 +151,15 @@ func TestGenerateCert(t *testing.T) {
KeyUsages: x509.KeyUsageKeyEncipherment,
DNSNames: []string{"test-api.kubernetes.default"},
ExtKeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
Validity: validityThreeYears,
Validity: validityTenYears,
IsCA: false,
},
clusterDir: "./",
err: false,
},
}
for i, c := range cases {
_, _, err := generateCert(c.clusterDir, caKey, caCert, keyPath, certPath, c.cfg)
_, _, err := generateCert(c.clusterDir, caKey, caCert, keyPath, certPath, c.cfg, false)
if err != nil {
no := "no"
if c.err {
Expand Down
136 changes: 79 additions & 57 deletions installer/pkg/config-generator/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,36 @@ import (
)

const (
adminCertPath = "generated/newTLS/admin.crt"
adminKeyPath = "generated/newTLS/admin.key"
aggregatorCACertPath = "generated/newTLS/aggregator-ca.crt"
aggregatorCAKeyPath = "generated/newTLS/aggregator-ca.key"
apiServerCertPath = "generated/newTLS/apiserver.crt"
apiServerKeyPath = "generated/newTLS/apiserver.key"
apiServerProxyCertPath = "generated/newTLS/apiserver-proxy.crt"
apiServerProxyKeyPath = "generated/newTLS/apiserver-proxy.key"
etcdCACertPath = "generated/newTLS/etcd-ca.crt"
etcdCAKeyPath = "generated/newTLS/etcd-ca.key"
etcdClientCertPath = "generated/newTLS/etcd-client.crt"
etcdClientKeyPath = "generated/newTLS/etcd-client.key"
ingressCACertPath = "generated/newTLS/ingress-ca.crt"
ingressCertPath = "generated/newTLS/ingress.crt"
ingressKeyPath = "generated/newTLS/ingress.key"
kubeCACertPath = "generated/newTLS/kube-ca.crt"
kubeCAKeyPath = "generated/newTLS/kube-ca.key"
kubeletCertPath = "generated/newTLS/kubelet.crt"
kubeletKeyPath = "generated/newTLS/kubelet.key"
osAPIServerCertPath = "generated/newTLS/openshift-apiserver.crt"
osAPIServerKeyPath = "generated/newTLS/openshift-apiserver.key"
rootCACertPath = "generated/newTLS/root-ca.crt"
rootCAKeyPath = "generated/newTLS/root-ca.key"
serviceServingCACertPath = "generated/newTLS/service-serving-ca.crt"
serviceServingCAKeyPath = "generated/newTLS/service-serving-ca.key"
tncCertPath = "generated/newTLS/tnc.crt"
tncKeyPath = "generated/newTLS/tnc.key"

validityThreeYears = time.Hour * 24 * 365 * 3
adminCertPath = "generated/tls/admin.crt"
adminKeyPath = "generated/tls/admin.key"
aggregatorCACertPath = "generated/tls/aggregator-ca.crt"
aggregatorCAKeyPath = "generated/tls/aggregator-ca.key"
apiServerCertPath = "generated/tls/apiserver.crt"
apiServerKeyPath = "generated/tls/apiserver.key"
apiServerProxyCertPath = "generated/tls/apiserver-proxy.crt"
apiServerProxyKeyPath = "generated/tls/apiserver-proxy.key"
etcdCACertPath = "generated/tls/etcd-ca.crt"
etcdCAKeyPath = "generated/tls/etcd-ca.key"
etcdClientCertPath = "generated/tls/etcd-client.crt"
etcdClientKeyPath = "generated/tls/etcd-client.key"
ingressCACertPath = "generated/tls/ingress-ca.crt"
ingressCertPath = "generated/tls/ingress.crt"
ingressKeyPath = "generated/tls/ingress.key"
kubeCACertPath = "generated/tls/kube-ca.crt"
kubeCAKeyPath = "generated/tls/kube-ca.key"
kubeletCertPath = "generated/tls/kubelet.crt"
kubeletKeyPath = "generated/tls/kubelet.key"
osAPIServerCertPath = "generated/tls/openshift-apiserver.crt"
osAPIServerKeyPath = "generated/tls/openshift-apiserver.key"
rootCACertPath = "generated/tls/root-ca.crt"
rootCAKeyPath = "generated/tls/root-ca.key"
serviceServingCACertPath = "generated/tls/service-serving-ca.crt"
serviceServingCAKeyPath = "generated/tls/service-serving-ca.key"
tncCertPath = "generated/tls/tnc.crt"
tncKeyPath = "generated/tls/tnc.key"

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

// GenerateTLSConfig fetches and validates the TLS cert files
Expand All @@ -72,10 +73,10 @@ 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: validityThreeYears,
Validity: validityTenYears,
IsCA: true,
}
kubeCAKey, kubeCACert, err := generateCert(clusterDir, caKey, caCert, kubeCAKeyPath, kubeCACertPath, cfg)
kubeCAKey, kubeCACert, err := generateCert(clusterDir, caKey, caCert, kubeCAKeyPath, kubeCACertPath, cfg, false)
if err != nil {
return fmt.Errorf("failed to generate kubernetes CA: %v", err)
}
Expand All @@ -85,46 +86,56 @@ 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,
}
etcdCAKey, etcdCACert, err := generateCert(clusterDir, caKey, caCert, etcdCAKeyPath, etcdCACertPath, cfg)
etcdCAKey, etcdCACert, err := generateCert(clusterDir, caKey, caCert, etcdCAKeyPath, etcdCACertPath, cfg, false)
if err != nil {
return fmt.Errorf("failed to generate etcd CA: %v", err)
}

if err := copy.Copy(filepath.Join(clusterDir, etcdCAKeyPath), filepath.Join(clusterDir, "generated/tls/etcd-client-ca.key")); err != nil {
return fmt.Errorf("failed to import kube CA cert into ingress-ca.crt: %v", err)
}
if err := copy.Copy(filepath.Join(clusterDir, etcdCACertPath), filepath.Join(clusterDir, "generated/tls/etcd-client-ca.crt")); err != nil {
return fmt.Errorf("failed to import kube CA cert into ingress-ca.crt: %v", err)
}

// generate etcd client certificate
cfg = &tls.CertCfg{
Subject: pkix.Name{CommonName: "etcd", OrganizationalUnit: []string{"etcd"}},
KeyUsages: x509.KeyUsageKeyEncipherment,
ExtKeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
Validity: validityTenYears,
}
if _, _, err := generateCert(clusterDir, etcdCAKey, etcdCACert, etcdClientKeyPath, etcdClientCertPath, cfg); err != nil {
if _, _, err := generateCert(clusterDir, etcdCAKey, etcdCACert, etcdClientKeyPath, etcdClientCertPath, cfg, false); err != nil {
return fmt.Errorf("failed to generate etcd client certificate: %v", err)
}

// generate aggregator CA
cfg = &tls.CertCfg{
Subject: pkix.Name{CommonName: "aggregator", OrganizationalUnit: []string{"bootkube"}},
KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
Validity: validityThreeYears,
Validity: validityTenYears,
IsCA: true,
}
if _, _, err := generateCert(clusterDir, caKey, caCert, aggregatorCAKeyPath, aggregatorCACertPath, cfg); err != nil {
aggregatorCAKey, aggregatorCACert, err := generateCert(clusterDir, caKey, caCert, aggregatorCAKeyPath, aggregatorCACertPath, cfg, false)
if err != nil {
return fmt.Errorf("failed to generate aggregator CA: %v", err)
}

// generate service-serving CA
cfg = &tls.CertCfg{
Subject: pkix.Name{CommonName: "service-serving", OrganizationalUnit: []string{"bootkube"}},
KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
Validity: validityThreeYears,
Validity: validityTenYears,
IsCA: true,
}
if _, _, err := generateCert(clusterDir, caKey, caCert, serviceServingCAKeyPath, serviceServingCACertPath, cfg); err != nil {
if _, _, err := generateCert(clusterDir, caKey, caCert, serviceServingCAKeyPath, serviceServingCACertPath, cfg, false); err != nil {
return fmt.Errorf("failed to generate service-serving CA: %v", err)
}

// Ingress certs
if copy.Copy(kubeCACertPath, ingressCACertPath); err != nil {
if err := copy.Copy(filepath.Join(clusterDir, kubeCACertPath), filepath.Join(clusterDir, ingressCACertPath)); err != nil {
return fmt.Errorf("failed to import kube CA cert into ingress-ca.crt: %v", err)
}

Expand All @@ -137,11 +148,11 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
fmt.Sprintf("%s.%s", "*", baseAddress),
},
Subject: pkix.Name{CommonName: baseAddress, Organization: []string{"ingress"}},
Validity: validityThreeYears,
Validity: validityTenYears,
IsCA: false,
}

if _, _, err := generateCert(clusterDir, kubeCAKey, kubeCACert, ingressKeyPath, ingressCertPath, cfg); err != nil {
if _, _, err := generateCert(clusterDir, kubeCAKey, kubeCACert, ingressKeyPath, ingressCertPath, cfg, true); err != nil {
return fmt.Errorf("failed to generate ingress CA: %v", err)
}

Expand All @@ -150,11 +161,11 @@ 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: validityThreeYears,
Validity: validityTenYears,
IsCA: false,
}

if _, _, err = generateCert(clusterDir, kubeCAKey, kubeCACert, adminKeyPath, adminCertPath, cfg); err != nil {
if _, _, err = generateCert(clusterDir, kubeCAKey, kubeCACert, adminKeyPath, adminCertPath, cfg, false); err != nil {
return fmt.Errorf("failed to generate kube admin certificate: %v", err)
}

Expand All @@ -173,12 +184,12 @@ func (c *ConfigGenerator) GenerateTLSConfig(clusterDir string) error {
"kubernetes.default.svc",
"kubernetes.default.svc.cluster.local",
},
Validity: validityThreeYears,
Validity: validityTenYears,
IPAddresses: []net.IP{net.ParseIP(apiServerAddress)},
IsCA: false,
}

if _, _, err := generateCert(clusterDir, kubeCAKey, kubeCACert, apiServerKeyPath, apiServerCertPath, cfg); err != nil {
if _, _, err := generateCert(clusterDir, kubeCAKey, kubeCACert, apiServerKeyPath, apiServerCertPath, cfg, true); err != nil {
return fmt.Errorf("failed to generate kube api server certificate: %v", err)
}

Expand All @@ -194,12 +205,12 @@ 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: validityThreeYears,
Validity: validityTenYears,
IPAddresses: []net.IP{net.ParseIP(apiServerAddress)},
IsCA: false,
}

if _, _, err := generateCert(clusterDir, kubeCAKey, kubeCACert, osAPIServerKeyPath, osAPIServerCertPath, cfg); err != nil {
if _, _, err := generateCert(clusterDir, aggregatorCAKey, aggregatorCACert, osAPIServerKeyPath, osAPIServerCertPath, cfg, true); err != nil {
return fmt.Errorf("failed to generate openshift api server certificate: %v", err)
}

Expand All @@ -208,11 +219,11 @@ 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: validityThreeYears,
Validity: validityTenYears,
IsCA: false,
}

if _, _, err := generateCert(clusterDir, kubeCAKey, kubeCACert, apiServerProxyKeyPath, apiServerProxyCertPath, cfg); err != nil {
if _, _, err := generateCert(clusterDir, aggregatorCAKey, aggregatorCACert, apiServerProxyKeyPath, apiServerProxyCertPath, cfg, false); err != nil {
return fmt.Errorf("failed to generate kube api proxy certificate: %v", err)
}

Expand All @@ -221,11 +232,11 @@ 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: validityThreeYears,
Validity: validityThirtyMinutes,
IsCA: false,
}

if _, _, err := generateCert(clusterDir, kubeCAKey, kubeCACert, kubeletKeyPath, kubeletCertPath, cfg); err != nil {
if _, _, err := generateCert(clusterDir, kubeCAKey, kubeCACert, kubeletKeyPath, kubeletCertPath, cfg, false); err != nil {
return fmt.Errorf("failed to generate kubelet certificate: %v", err)
}

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

if _, _, err := generateCert(clusterDir, caKey, caCert, tncKeyPath, tncCertPath, cfg); err != nil {
if _, _, err := generateCert(clusterDir, caKey, caCert, tncKeyPath, tncCertPath, cfg, false); err != nil {
return fmt.Errorf("failed to generate tnc certificate: %v", err)
}
return nil
Expand Down Expand Up @@ -308,12 +319,16 @@ func getCertFiles(clusterDir string, certPath string, keyPath string) (*x509.Cer
}

// generateCert creates a key, csr & a signed cert
// If appendCA is true, then also append the CA cert into the result cert.
// This is useful for apiserver and openshift-apiser cert which will be
// authenticated by the kubeconfig using root-ca.
func generateCert(clusterDir string,
caKey *rsa.PrivateKey,
caCert *x509.Certificate,
keyPath string,
certPath string,
cfg *tls.CertCfg) (*rsa.PrivateKey, *x509.Certificate, error) {
cfg *tls.CertCfg,
appendCA bool) (*rsa.PrivateKey, *x509.Certificate, error) {

// create a private key
key, err := generatePrivateKey(clusterDir, keyPath)
Expand All @@ -333,7 +348,7 @@ func generateCert(clusterDir string,
}

// create a cert
cert, err := generateSignedCert(cfg, csr, key, caKey, caCert, clusterDir, certPath)
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)
}
Expand All @@ -349,7 +364,7 @@ func generateRootCA(path string, key *rsa.PrivateKey) (*x509.Certificate, error)
OrganizationalUnit: []string{"openshift"},
},
KeyUsages: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
Validity: validityThreeYears,
Validity: validityTenYears,
IsCA: true,
}
cert, err := tls.SelfSignedCACert(cfg, key)
Expand All @@ -368,13 +383,20 @@ func generateSignedCert(cfg *tls.CertCfg,
caKey *rsa.PrivateKey,
caCert *x509.Certificate,
clusterDir string,
path string) (*x509.Certificate, error) {
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)
}
fileTargetPath := filepath.Join(clusterDir, path)
if err := ioutil.WriteFile(fileTargetPath, []byte(tls.CertToPem(cert)), 0666); err != nil {

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
}
return cert, nil
Expand Down
5 changes: 0 additions & 5 deletions installer/pkg/workflow/destroy.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,10 @@ func DestroyWorkflow(clusterDir string) Workflow {
destroyTNCDNSStep,
destroyTopologyStep,
destroyAssetsStep,
destroyTLSAssetsStep,
},
}
}

func destroyTLSAssetsStep(m *metadata) error {
return runDestroyStep(m, tlsStep)
}

func destroyAssetsStep(m *metadata) error {
return runDestroyStep(m, assetsStep)
}
Expand Down
2 changes: 1 addition & 1 deletion installer/pkg/workflow/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const (
kubeSystemPath = "generated/manifests"
kubeSystemFileName = "cluster-config.yaml"
tectonicSystemPath = "generated/tectonic"
newTLSPath = "generated/newTLS"
tlsPath = "generated/tls"
tectonicSystemFileName = "cluster-config.yaml"
terraformVariablesFileName = "terraform.tfvars"
)
Expand Down
Loading