diff --git a/contrib/charts/vault/templates/vault-config.yaml b/contrib/charts/vault/templates/vault-config.yaml
new file mode 100644
index 000000000..bda91bdc3
--- /dev/null
+++ b/contrib/charts/vault/templates/vault-config.yaml
@@ -0,0 +1,9 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: vault-config
+ labels:
+ app: vault
+data:
+ config.json: |
+ {{ .Values.vault.config | toJson }}
diff --git a/contrib/charts/vault/templates/vault-deployment.yaml b/contrib/charts/vault/templates/vault-deployment.yaml
index a5ca34210..31533ba5b 100644
--- a/contrib/charts/vault/templates/vault-deployment.yaml
+++ b/contrib/charts/vault/templates/vault-deployment.yaml
@@ -17,6 +17,8 @@ spec:
containers:
- name: vault
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ command: ["vault", "server", "-dev", "-dev-listen-address=[::]:8202", "-config", "/vault/config/config.json"]
+ # command: ["/bin/sh", "-c", "sleep 9999"]
ports:
- containerPort: 8200
name: vaultport
@@ -32,3 +34,16 @@ spec:
httpGet:
path: /v1/sys/health
port: 8200
+ scheme: HTTPS
+ volumeMounts:
+ - name: vault-config
+ mountPath: /vault/config
+ - name: vault-tls
+ mountPath: /vault/tls
+ volumes:
+ - name: vault-config
+ configMap:
+ name: vault-config
+ - name: vault-tls
+ secret:
+ secretName: vault-tls
diff --git a/contrib/charts/vault/templates/vault-secret.yaml b/contrib/charts/vault/templates/vault-secret.yaml
new file mode 100644
index 000000000..cb532b3a2
--- /dev/null
+++ b/contrib/charts/vault/templates/vault-secret.yaml
@@ -0,0 +1,8 @@
+apiVersion: v1
+kind: Secret
+metadata:
+ name: vault-tls
+type: Opaque
+data:
+ server.crt: {{ .Values.vault.publicKey | b64enc }}
+ server.key: {{ .Values.vault.privateKey | b64enc }}
diff --git a/contrib/charts/vault/values.yaml b/contrib/charts/vault/values.yaml
index a5e966c06..4e7dcad17 100644
--- a/contrib/charts/vault/values.yaml
+++ b/contrib/charts/vault/values.yaml
@@ -1,4 +1,18 @@
image:
repository: vault
tag: "0.9.3"
- pullPolicy: IfNotPresent
+
+vault:
+ publicKey:
+ privateKey:
+
+ config:
+ listener:
+ tcp:
+ address: '[::]:8200'
+ cluster_address: '[::]:8201'
+ tls_disable: false
+ tls_prefer_server_cipher_suites: true
+ tls_cipher_suites: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA
+ tls_cert_file: /vault/tls/server.crt
+ tls_key_file: /vault/tls/server.key
diff --git a/docs/generated/reference/openapi/openapi_generated.go b/docs/generated/reference/openapi/openapi_generated.go
index 8e3cedd7e..b91c65b65 100644
--- a/docs/generated/reference/openapi/openapi_generated.go
+++ b/docs/generated/reference/openapi/openapi_generated.go
@@ -1641,6 +1641,13 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
Format: "",
},
},
+ "caBundle": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Base64 encoded CA bundle to validate Vault server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection.",
+ Type: []string{"string"},
+ Format: "byte",
+ },
+ },
},
Required: []string{"auth", "server", "path"},
},
diff --git a/docs/generated/reference/output/reference/api-docs/index.html b/docs/generated/reference/output/reference/api-docs/index.html
index a3d275d9d..9e14791b1 100644
--- a/docs/generated/reference/output/reference/api-docs/index.html
+++ b/docs/generated/reference/output/reference/api-docs/index.html
@@ -1930,6 +1930,10 @@ Appears In:
Vault authentication |
+caBundle string |
+Base64 encoded CA bundle to validate Vault server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection. |
+
+
path string |
Vault URL path to the certificate role |
diff --git a/docs/tutorials/vault/creating-vault-issuers.rst b/docs/tutorials/vault/creating-vault-issuers.rst
index 01e0b3db6..a88d874c3 100644
--- a/docs/tutorials/vault/creating-vault-issuers.rst
+++ b/docs/tutorials/vault/creating-vault-issuers.rst
@@ -54,6 +54,7 @@ We can now create a cluster issuer referencing this secret:
vault:
path: pki_int/sign/example-dot-com
server: https://vault
+ caBundle:
auth:
appRole:
path: approle
@@ -72,6 +73,11 @@ key value that store the *secretId*. The optional attribute *path* specifies
where the AppRole authentication is mounted in Vault. The attribute *path* default
value is *approle*.
+An optional base64 encoded *caBundle* in PEM format can be provided to validate
+the TLS connection to the Vault Server. When *caBundle* is set it replaces the CA
+bundle inside the container running cert-manager. This parameter as no effect if the
+connection used is in plain HTTP.
+
Once we have created the above Issuer we can use it to obtain a certificate.
.. code-block:: yaml
@@ -153,12 +159,18 @@ We can now create an issuer referencing this secret:
key: token
path: pki_int/sign/example-dot-com
server: https://vault
+ caBundle:
Where *path* is the Vault role path of the PKI backend and *server* is
the Vault server base URL. The secret created previously is referenced in the issuer
with its *name* and *key* corresponding to the name of the Kubernetes secret and the
property name containing the token value respectively.
+An optional base64 encoded *caBundle* in PEM format can be provided to validate
+the TLS connection to the Vault Server. When *caBundle* is set it replaces the CA
+bundle inside the container running cert-manager. This parameter as no effect if the
+connection used is in plain HTTP.
+
Once we have created the above Issuer we can use it to obtain a certificate.
.. code-block:: yaml
diff --git a/pkg/apis/certmanager/v1alpha1/types_issuer.go b/pkg/apis/certmanager/v1alpha1/types_issuer.go
index 7c3b650cc..bccf1ba2d 100644
--- a/pkg/apis/certmanager/v1alpha1/types_issuer.go
+++ b/pkg/apis/certmanager/v1alpha1/types_issuer.go
@@ -91,6 +91,11 @@ type VaultIssuer struct {
Server string `json:"server"`
// Vault URL path to the certificate role
Path string `json:"path"`
+ // Base64 encoded CA bundle to validate Vault server certificate. Only used
+ // if the Server URL is using HTTPS protocol. This parameter is ignored for
+ // plain HTTP protocol connection. If not set the system root certificates
+ // are used to validate the TLS connection.
+ CABundle []byte `json:"caBundle,omitempty"`
}
// Vault authentication can be configured:
diff --git a/pkg/apis/certmanager/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/certmanager/v1alpha1/zz_generated.deepcopy.go
index 04d9ff490..7af02e0c9 100644
--- a/pkg/apis/certmanager/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/certmanager/v1alpha1/zz_generated.deepcopy.go
@@ -796,7 +796,7 @@ func (in *IssuerConfig) DeepCopyInto(out *IssuerConfig) {
*out = nil
} else {
*out = new(VaultIssuer)
- **out = **in
+ (*in).DeepCopyInto(*out)
}
}
if in.SelfSigned != nil {
@@ -1169,6 +1169,11 @@ func (in *VaultAuth) DeepCopy() *VaultAuth {
func (in *VaultIssuer) DeepCopyInto(out *VaultIssuer) {
*out = *in
out.Auth = in.Auth
+ if in.CABundle != nil {
+ in, out := &in.CABundle, &out.CABundle
+ *out = make([]byte, len(*in))
+ copy(*out, *in)
+ }
return
}
diff --git a/pkg/apis/certmanager/validation/issuer.go b/pkg/apis/certmanager/validation/issuer.go
index 001ff362a..36accad53 100644
--- a/pkg/apis/certmanager/validation/issuer.go
+++ b/pkg/apis/certmanager/validation/issuer.go
@@ -17,6 +17,7 @@ limitations under the License.
package validation
import (
+ "crypto/x509"
"fmt"
"strings"
@@ -122,6 +123,17 @@ func ValidateVaultIssuerConfig(iss *v1alpha1.VaultIssuer, fldPath *field.Path) f
if len(iss.Path) == 0 {
el = append(el, field.Required(fldPath.Child("path"), ""))
}
+
+ // check if caBundle is valid
+ certs := iss.CABundle
+ if len(certs) > 0 {
+ caCertPool := x509.NewCertPool()
+ ok := caCertPool.AppendCertsFromPEM(certs)
+ if !ok {
+ el = append(el, field.Invalid(fldPath.Child("caBundle"), "", "Specified CA bundle is invalid"))
+ }
+ }
+
return el
// TODO: add validation for Vault authentication types
}
diff --git a/pkg/apis/certmanager/validation/issuer_test.go b/pkg/apis/certmanager/validation/issuer_test.go
index 13c4a38f1..c4d00249b 100644
--- a/pkg/apis/certmanager/validation/issuer_test.go
+++ b/pkg/apis/certmanager/validation/issuer_test.go
@@ -72,6 +72,16 @@ func TestValidateVaultIssuerConfig(t *testing.T) {
field.Required(fldPath.Child("path"), ""),
},
},
+ "vault issuer with invalid fields": {
+ spec: &v1alpha1.VaultIssuer{
+ Server: "something",
+ Path: "a/b/c",
+ CABundle: []byte("invalid"),
+ },
+ errs: []*field.Error{
+ field.Invalid(fldPath.Child("caBundle"), "", "Specified CA bundle is invalid"),
+ },
+ },
}
for n, s := range scenarios {
t.Run(n, func(t *testing.T) {
@@ -619,7 +629,7 @@ func TestValidateACMEIssuerDNS01Config(t *testing.T) {
}
func TestValidateSecretKeySelector(t *testing.T) {
- validName := v1alpha1.LocalObjectReference{"name"}
+ validName := v1alpha1.LocalObjectReference{Name: "name"}
validKey := "key"
// invalidName := v1alpha1.LocalObjectReference{"-name-"}
// invalidKey := "-key-"
diff --git a/pkg/issuer/vault/issue.go b/pkg/issuer/vault/issue.go
index 230c3c52c..9b5ccf41a 100644
--- a/pkg/issuer/vault/issue.go
+++ b/pkg/issuer/vault/issue.go
@@ -19,8 +19,10 @@ package vault
import (
"bytes"
"context"
+ "crypto/x509"
"encoding/pem"
"fmt"
+ "net/http"
"path"
"strings"
"time"
@@ -109,14 +111,36 @@ func (v *Vault) obtainCertificate(ctx context.Context, crt *v1alpha1.Certificate
return keyBytes, crtBytes, caBytes, nil
}
+func (v *Vault) configureCertPool(cfg *vault.Config) error {
+ certs := v.issuer.GetSpec().Vault.CABundle
+ if len(certs) == 0 {
+ return nil
+ }
+
+ caCertPool := x509.NewCertPool()
+ ok := caCertPool.AppendCertsFromPEM(certs)
+ if ok == false {
+ return fmt.Errorf("error loading Vault CA bundle")
+ }
+
+ cfg.HttpClient.Transport.(*http.Transport).TLSClientConfig.RootCAs = caCertPool
+
+ return nil
+}
+
func (v *Vault) initVaultClient() (*vault.Client, error) {
- client, err := vault.NewClient(nil)
+ vaultCfg := vault.DefaultConfig()
+ vaultCfg.Address = v.issuer.GetSpec().Vault.Server
+ err := v.configureCertPool(vaultCfg)
+ if err != nil {
+ return nil, err
+ }
+
+ client, err := vault.NewClient(vaultCfg)
if err != nil {
return nil, fmt.Errorf("error initializing Vault client: %s", err.Error())
}
- client.SetAddress(v.issuer.GetSpec().Vault.Server)
-
tokenRef := v.issuer.GetSpec().Vault.Auth.TokenSecretRef
if tokenRef.Name != "" {
token, err := v.vaultTokenRef(tokenRef.Name, tokenRef.Key)
diff --git a/test/e2e/BUILD.bazel b/test/e2e/BUILD.bazel
index 72a4f8b13..7c34f01d0 100644
--- a/test/e2e/BUILD.bazel
+++ b/test/e2e/BUILD.bazel
@@ -23,6 +23,7 @@ go_library(
"//test/e2e/clusterissuer:go_default_library",
"//test/e2e/framework:go_default_library",
"//test/e2e/issuer:go_default_library",
+ "//test/util/vault:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/onsi/ginkgo:go_default_library",
"//vendor/github.com/onsi/ginkgo/config:go_default_library",
diff --git a/test/e2e/certificate/certificate_vault.go b/test/e2e/certificate/certificate_vault.go
index 079ee54a4..524a986ec 100644
--- a/test/e2e/certificate/certificate_vault.go
+++ b/test/e2e/certificate/certificate_vault.go
@@ -69,14 +69,14 @@ var _ = framework.CertManagerDescribe("Vault Certificate (AppRole)", func() {
vaultInit.Clean()
})
- vaultURL := "http://vault.vault:8200"
+ vaultURL := "https://vault.vault:8200"
It("should generate a new valid certificate", func() {
By("Creating an Issuer")
certClient := f.CertManagerClientSet.CertmanagerV1alpha1().Certificates(f.Namespace.Name)
secretClient := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name)
- _, err := f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Create(util.NewCertManagerVaultIssuerAppRole(issuerName, vaultURL, vaultPath, roleId, vaultSecretAppRoleName, authPath))
+ _, err := f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Create(util.NewCertManagerVaultIssuerAppRole(issuerName, vaultURL, vaultPath, roleId, vaultSecretAppRoleName, authPath, vault.VaultCA))
Expect(err).NotTo(HaveOccurred())
By("Waiting for Issuer to become Ready")
@@ -137,14 +137,14 @@ var _ = framework.CertManagerDescribe("Vault Certificate (AppRole with a custom
vaultInit.Clean()
})
- vaultURL := "http://vault.vault:8200"
+ vaultURL := "https://vault.vault:8200"
It("should generate a new valid certificate", func() {
By("Creating an Issuer")
certClient := f.CertManagerClientSet.CertmanagerV1alpha1().Certificates(f.Namespace.Name)
secretClient := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name)
- _, err := f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Create(util.NewCertManagerVaultIssuerAppRole(issuerName, vaultURL, vaultPath, roleId, vaultSecretAppRoleName, authPath))
+ _, err := f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Create(util.NewCertManagerVaultIssuerAppRole(issuerName, vaultURL, vaultPath, roleId, vaultSecretAppRoleName, authPath, vault.VaultCA))
Expect(err).NotTo(HaveOccurred())
By("Waiting for Issuer to become Ready")
diff --git a/test/e2e/e2e.go b/test/e2e/e2e.go
index 4d4206c43..7f3377817 100644
--- a/test/e2e/e2e.go
+++ b/test/e2e/e2e.go
@@ -35,6 +35,7 @@ import (
_ "github.com/jetstack/cert-manager/test/e2e/clusterissuer"
"github.com/jetstack/cert-manager/test/e2e/framework"
_ "github.com/jetstack/cert-manager/test/e2e/issuer"
+ "github.com/jetstack/cert-manager/test/util/vault"
)
const certManagerDeploymentNamespace = "cert-manager"
@@ -69,7 +70,8 @@ func RunE2ETests(t *testing.T) {
}
InstallHelmChart(t, "pebble", "./contrib/charts/pebble", "pebble", "./test/fixtures/pebble-values.yaml", extraArgs...)
- InstallHelmChart(t, "vault", "./contrib/charts/vault", "vault", "./test/fixtures/vault-values.yaml")
+ vaultExtraArgs := []string{"--set", "vault.privateKey=" + string(vault.VaultCertPrivateKey), "--set", "vault.publicKey=" + string(vault.VaultCert)}
+ InstallHelmChart(t, "vault", "./contrib/charts/vault", "vault", "./test/fixtures/vault-values.yaml", vaultExtraArgs...)
glog.Infof("Starting e2e run %q on Ginkgo node %d", framework.RunId, config.GinkgoConfig.ParallelNode)
diff --git a/test/e2e/issuer/issuer_vault.go b/test/e2e/issuer/issuer_vault.go
index 4f6d6665e..1aa5558a2 100644
--- a/test/e2e/issuer/issuer_vault.go
+++ b/test/e2e/issuer/issuer_vault.go
@@ -67,13 +67,13 @@ var _ = framework.CertManagerDescribe("Vault Issuer", func() {
const vaultDefaultDuration = time.Hour * 24 * 90
- vaultURL := "http://vault.vault:8200"
+ vaultURL := "https://vault.vault:8200"
It("should be ready with a valid AppRole", func() {
_, err := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Create(vault.NewVaultAppRoleSecret(vaultSecretAppRoleName, secretId))
Expect(err).NotTo(HaveOccurred())
By("Creating an Issuer")
- _, err = f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Create(util.NewCertManagerVaultIssuerAppRole(issuerName, vaultURL, vaultPath, roleId, vaultSecretAppRoleName, authPath))
+ _, err = f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Create(util.NewCertManagerVaultIssuerAppRole(issuerName, vaultURL, vaultPath, roleId, vaultSecretAppRoleName, authPath, vault.VaultCA))
Expect(err).NotTo(HaveOccurred())
By("Waiting for Issuer to become Ready")
@@ -88,7 +88,7 @@ var _ = framework.CertManagerDescribe("Vault Issuer", func() {
It("should fail to init with missing Vault AppRole", func() {
By("Creating an Issuer")
- _, err := f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Create(util.NewCertManagerVaultIssuerAppRole(issuerName, vaultURL, vaultPath, roleId, vaultSecretAppRoleName, authPath))
+ _, err := f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Create(util.NewCertManagerVaultIssuerAppRole(issuerName, vaultURL, vaultPath, roleId, vaultSecretAppRoleName, authPath, vault.VaultCA))
Expect(err).NotTo(HaveOccurred())
By("Waiting for Issuer to become Ready")
@@ -103,7 +103,7 @@ var _ = framework.CertManagerDescribe("Vault Issuer", func() {
It("should fail to init with missing Vault Token", func() {
By("Creating an Issuer")
- _, err := f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Create(util.NewCertManagerVaultIssuerToken(issuerName, vaultURL, vaultPath, vaultSecretTokenName))
+ _, err := f.CertManagerClientSet.CertmanagerV1alpha1().Issuers(f.Namespace.Name).Create(util.NewCertManagerVaultIssuerToken(issuerName, vaultURL, vaultPath, vaultSecretTokenName, authPath, vault.VaultCA))
Expect(err).NotTo(HaveOccurred())
By("Waiting for Issuer to become Ready")
diff --git a/test/util/util.go b/test/util/util.go
index e05e3a98e..475ac6b7a 100644
--- a/test/util/util.go
+++ b/test/util/util.go
@@ -473,7 +473,7 @@ func NewCertManagerSelfSignedIssuer(name string) *v1alpha1.Issuer {
}
}
-func NewCertManagerVaultIssuerToken(name, vaultURL, vaultPath, vaultSecretToken string) *v1alpha1.Issuer {
+func NewCertManagerVaultIssuerToken(name, vaultURL, vaultPath, vaultSecretToken, authPath string, caBundle []byte) *v1alpha1.Issuer {
return &v1alpha1.Issuer{
ObjectMeta: metav1.ObjectMeta{
Name: name,
@@ -481,8 +481,9 @@ func NewCertManagerVaultIssuerToken(name, vaultURL, vaultPath, vaultSecretToken
Spec: v1alpha1.IssuerSpec{
IssuerConfig: v1alpha1.IssuerConfig{
Vault: &v1alpha1.VaultIssuer{
- Server: vaultURL,
- Path: vaultPath,
+ Server: vaultURL,
+ Path: vaultPath,
+ CABundle: caBundle,
Auth: v1alpha1.VaultAuth{
TokenSecretRef: v1alpha1.SecretKeySelector{
Key: "secretkey",
@@ -497,7 +498,7 @@ func NewCertManagerVaultIssuerToken(name, vaultURL, vaultPath, vaultSecretToken
}
}
-func NewCertManagerVaultIssuerAppRole(name, vaultURL, vaultPath, roleId, vaultSecretAppRole, authPath string) *v1alpha1.Issuer {
+func NewCertManagerVaultIssuerAppRole(name, vaultURL, vaultPath, roleId, vaultSecretAppRole string, authPath string, caBundle []byte) *v1alpha1.Issuer {
return &v1alpha1.Issuer{
ObjectMeta: metav1.ObjectMeta{
Name: name,
@@ -505,8 +506,9 @@ func NewCertManagerVaultIssuerAppRole(name, vaultURL, vaultPath, roleId, vaultSe
Spec: v1alpha1.IssuerSpec{
IssuerConfig: v1alpha1.IssuerConfig{
Vault: &v1alpha1.VaultIssuer{
- Server: vaultURL,
- Path: vaultPath,
+ Server: vaultURL,
+ Path: vaultPath,
+ CABundle: caBundle,
Auth: v1alpha1.VaultAuth{
AppRole: v1alpha1.VaultAppRole{
Path: authPath,
diff --git a/test/util/vault/util.go b/test/util/vault/util.go
index 4ad00fd2e..f14ef08ef 100644
--- a/test/util/vault/util.go
+++ b/test/util/vault/util.go
@@ -17,7 +17,16 @@ limitations under the License.
package vault
import (
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/tls"
+ "crypto/x509"
+ "crypto/x509/pkix"
+ "encoding/pem"
"fmt"
+ "math/big"
+ "net"
+ "net/http"
"os/exec"
"path"
"time"
@@ -30,6 +39,18 @@ import (
const vaultToken = "vault-root-token"
+var (
+ VaultCA []byte
+ VaultCAPrivateKey []byte
+ VaultCert []byte
+ VaultCertPrivateKey []byte
+)
+
+func init() {
+ generateCA()
+ generateCert()
+}
+
func NewVaultTokenSecret(name string) *v1.Secret {
return &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
@@ -72,7 +93,16 @@ func NewVaultInitializer(container, rootMount, intermediateMount, role, authPath
time.Sleep(3 * time.Second)
cfg := vault.DefaultConfig()
- cfg.Address = "http://127.0.0.1:8200"
+ cfg.Address = "https://127.0.0.1:8200"
+
+ caCertPool := x509.NewCertPool()
+ ok := caCertPool.AppendCertsFromPEM(VaultCA)
+ if ok == false {
+ glog.Fatal("error loading Vault CA bundle")
+ }
+
+ cfg.HttpClient.Transport.(*http.Transport).TLSClientConfig.RootCAs = caCertPool
+
client, err := vault.NewClient(cfg)
if err != nil {
return nil, fmt.Errorf("Unable to initialize vault client: %s", err.Error())
@@ -284,8 +314,8 @@ func (v *VaultInitializer) importSignIntermediate(intermediateCa, rootCa, interm
func (v *VaultInitializer) configureCert(mount string) error {
params := map[string]string{
- "issuing_certificates": fmt.Sprintf("http://vault.vault:8200/v1/%s/ca", mount),
- "crl_distribution_points": fmt.Sprintf("http://vault.vault:8200/v1/%s/crl", mount),
+ "issuing_certificates": fmt.Sprintf("https://vault.vault:8200/v1/%s/ca", mount),
+ "crl_distribution_points": fmt.Sprintf("https://vault.vault:8200/v1/%s/crl", mount),
}
url := path.Join("/v1", mount, "config", "urls")
@@ -353,3 +383,78 @@ func (v *VaultInitializer) callVault(method, url, field string, params map[strin
return fieldData, err
}
+
+func generateCA() {
+ ca := &x509.Certificate{
+ SerialNumber: big.NewInt(1653),
+ Subject: pkix.Name{
+ Organization: []string{"cert-manager test"},
+ },
+ NotBefore: time.Now(),
+ NotAfter: time.Now().AddDate(10, 0, 0),
+ IsCA: true,
+ ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
+ KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
+ BasicConstraintsValid: true,
+ }
+
+ privateKey, _ := rsa.GenerateKey(rand.Reader, 2048)
+ pubKey := &privateKey.PublicKey
+ caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, pubKey, privateKey)
+ if err != nil {
+ glog.Fatalf("create ca failed: %s", err.Error())
+ }
+
+ VaultCA = encodePublicKey(caBytes)
+ VaultCAPrivateKey = encodePrivateKey(privateKey)
+}
+
+func generateCert() {
+ catls, err := tls.X509KeyPair(VaultCA, VaultCAPrivateKey)
+ if err != nil {
+ glog.Fatalf("parsing ca key pair failed: %s", err.Error())
+ }
+ ca, err := x509.ParseCertificate(catls.Certificate[0])
+ if err != nil {
+ glog.Fatalf("parsing ca failed: %s", err.Error())
+ }
+
+ cert := &x509.Certificate{
+ SerialNumber: big.NewInt(1658),
+ Subject: pkix.Name{
+ CommonName: "vault.vault",
+ Organization: []string{"cert-manager vault server"},
+ },
+ NotBefore: time.Now(),
+ NotAfter: time.Now().AddDate(10, 0, 0),
+ SubjectKeyId: []byte{1, 2, 3, 4, 6},
+ ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
+ KeyUsage: x509.KeyUsageDigitalSignature,
+ IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1)},
+ DNSNames: []string{"vault.vault"},
+ }
+ privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
+ if err != nil {
+ glog.Fatalf("private key generation failed: %s", err.Error())
+ }
+
+ publicKey := &privateKey.PublicKey
+
+ certBytes, err := x509.CreateCertificate(rand.Reader, cert, ca, publicKey, catls.PrivateKey)
+ if err != nil {
+ glog.Fatal(err)
+ }
+
+ VaultCert = encodePublicKey(certBytes)
+ VaultCertPrivateKey = encodePrivateKey(privateKey)
+}
+
+func encodePublicKey(pub []byte) []byte {
+ return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: pub})
+}
+
+func encodePrivateKey(priv *rsa.PrivateKey) []byte {
+ block := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}
+
+ return pem.EncodeToMemory(block)
+}