Standalone Server with TLS

This example can be used to set up a single server Vault cluster using TLS.

  1. Create key & certificate using Kubernetes CA
  2. Store key & cert into Kubernetes secrets store
  3. Configure helm chart to use Kubernetes secret from step 2

1. Create key & certificate using Kubernetes CA

There are three variables that will be used in this example.

# SERVICE is the name of the Vault service in Kubernetes.
# It does not have to match the actual running service, though it may help for consistency.
SERVICE=vault-server-tls

# NAMESPACE where the Vault service is running.
NAMESPACE=vault-namespace

# SECRET_NAME to create in the Kubernetes secrets store.
SECRET_NAME=vault-server-tls

# TMPDIR is a temporary working directory.
TMPDIR=/tmp
  1. Create a key for Kubernetes to sign.

    openssl genrsa -out ${TMPDIR}/vault.key 2048
    
  2. Create a Certificate Signing Request (CSR).

    1. Create a file ${TMPDIR}/csr.conf with the following contents:

      $ cat <<EOF >${TMPDIR}/csr.conf
      [req]
      req_extensions = v3_req
      distinguished_name = req_distinguished_name
      [req_distinguished_name]
      [ v3_req ]
      basicConstraints = CA:FALSE
      keyUsage = nonRepudiation, digitalSignature, keyEncipherment
      extendedKeyUsage = serverAuth
      subjectAltName = @alt_names
      [alt_names]
      DNS.1 = ${SERVICE}
      DNS.2 = ${SERVICE}.${NAMESPACE}
      DNS.3 = ${SERVICE}.${NAMESPACE}.svc
      DNS.4 = ${SERVICE}.${NAMESPACE}.svc.cluster.local
      IP.1 = 127.0.0.1
      EOF
      
    2. Create a CSR.

      openssl req -new -key ${TMPDIR}/vault.key -subj "/CN=${SERVICE}.${NAMESPACE}.svc" -out ${TMPDIR}/server.csr -config ${TMPDIR}/csr.conf
      
  3. Create the certificate

    1. Create a file ${TMPDIR}/csr.yaml with the following contents:

      $ export CSR_NAME=vault-csr
      $ cat <<EOF >${TMPDIR}/csr.yaml
      apiVersion: certificates.k8s.io/v1beta1
      kind: CertificateSigningRequest
      metadata:
        name: ${CSR_NAME}
      spec:
        groups:
        - system:authenticated
        request: $(cat ${TMPDIR}/server.csr | base64 | tr -d '\n')
        usages:
        - digital signature
        - key encipherment
        - server auth
      EOF
      
    2. Send the CSR to Kubernetes.

      kubectl create -f ${TMPDIR}/csr.yaml
      
    3. Approve the CSR in Kubernetes.

      kubectl certificate approve ${CSR_NAME}
      

2. Store key, cert, and Kubernetes CA into Kubernetes secrets store

  1. Retrieve the certificate.

    serverCert=$(kubectl get csr ${CSR_NAME} -o jsonpath='{.status.certificate}')
    
  2. Write the certificate out to a file.

    echo "${serverCert}" | openssl base64 -d -A -out ${TMPDIR}/vault.crt
    
  3. Retrieve Kubernetes CA.

    kubectl config view --raw --minify --flatten -o jsonpath='{.clusters[].cluster.certificate-authority-data}' | base64 -D > ${TMPDIR}/vault.ca
    
  4. Store the key, cert, and Kubernetes CA into Kubernetes secrets.

    kubectl create secret generic ${SECRET_NAME} \
            --namespace ${NAMESPACE} \
            --from-file=vault.key=${TMPDIR}/vault.key \
            --from-file=vault.crt=${TMPDIR}/vault.crt \
            --from-file=vault.ca=${TMPDIR}/vault.ca
    

3. Helm Configuration

The below custom-values.yaml can be used to set up a single server Vault cluster using TLS. This assumes that a Kubernetes secret exists with the server certificate, key and certificate authority:

global:
  enabled: true
  tlsDisable: false
  extraEnvironmentVars:
    VAULT_CACERT: /vault/userconfig/vault-server-tls/vault.ca

server:
  image:
    repository: 'vault'
    tag: '1.3.1'

  extraVolumes:
  - type: secret
    name: vault-server-tls # Matches the ${SECRET_NAME} from above

  standalone:
    enabled: true
    config: |
      listener "tcp" {
        address = "[::]:8200"
        cluster_address = "[::]:8201"
        tls_cert_file = "/vault/userconfig/vault-server-tls/vault.crt"
        tls_key_file  = "/vault/userconfig/vault-server-tls/vault.key"
        tls_client_ca_file = "/vault/userconfig/vault-server-tls/vault.ca"
      }

      storage "file" {
        path = "/vault/data"
      }