Skip to main content

Standalone server with TLS

warning

Important Note: This chart is not compatible with Helm 2. Please use Helm 3.6+ with this chart.

This example can be used to set up a single server OpenBao 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 four variables that will be used in this example.

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

# NAMESPACE where the OpenBao service is running.
export NAMESPACE=openbao-namespace

# SECRET_NAME to create in the kubernetes secrets store.
export SECRET_NAME=openbao-server-tls

# TMPDIR is a temporary working directory.
export TMPDIR=/tmp

# CSR_NAME will be the name of our certificate signing request as seen by kubernetes.
export CSR_NAME=openbao-csr
  1. Create a key for Kubernetes to sign.

    $ openssl genrsa -out ${TMPDIR}/openbao.key 2048
    Generating RSA private key, 2048 bit long modulus

...................................................................................................+++ ...............+++ e is 65537 (0x10001)


2. Create a Certificate Signing Request (CSR).

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

```bash
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
  1. Create a CSR.

    openssl req -new \
    -key ${TMPDIR}/openbao.key \
    -subj "/CN=system:node:${SERVICE}.${NAMESPACE}.svc;/O=system:nodes" \
    -out ${TMPDIR}/server.csr \
    -config ${TMPDIR}/csr.conf
  2. Create the certificate

warning

Important Note: If you are using EKS, certificate signing requirements have changed. As per the AWS certificate signing documentation, EKS version 1.22 and later now requires the signerName to be beta.eks.amazonaws.com/app-serving, otherwise, the CSR will be approved but the certificate will not be issued.

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

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

    $ kubectl create -f ${TMPDIR}/csr.yaml
    certificatesigningrequest.certificates.k8s.io/openbao-csr created
info

If this process is automated, you may need to wait to ensure the CSR has been received and stored: kubectl get csr ${CSR_NAME}

  1. Approve the CSR in Kubernetes.

    $ kubectl certificate approve ${CSR_NAME}
    certificatesigningrequest.certificates.k8s.io/openbao-csr approved
  2. Verify that the certificate was approved and issued.

    $ kubectl get csr ${CSR_NAME}
    NAME AGE SIGNERNAME REQUESTOR CONDITION
    openbao-csr 1m13s kubernetes.io/kubelet-serving kubernetes-admin Approved,Issued

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}')
info

If this process is automated, you may need to wait to ensure the certificate has been created. If it hasn't, this will return an empty string.

  1. Write the certificate out to a file.

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

    kubectl get secret \
    -o jsonpath="{.items[?(@.type==\"kubernetes.io/service-account-token\")].data['ca\.crt']}" \
    | base64 --decode > ${TMPDIR}/openbao.ca
  3. Create the namespace.

    $ kubectl create namespace ${NAMESPACE}
    namespace/openbao-namespace created
  4. Store the key, cert, and Kubernetes CA into Kubernetes secrets.

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

    # secret/openbao-server-tls created

3. helm configuration

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

global:
enabled: true
tlsDisable: false

server:
extraEnvironmentVars:
OPENBAO_CACERT: /openbao/userconfig/openbao-server-tls/openbao.ca

volumes:
- name: userconfig-openbao-server-tls
secret:
defaultMode: 420
secretName: openbao-server-tls # Matches the ${SECRET_NAME} from above

volumeMounts:
- mountPath: /openbao/userconfig/openbao-server-tls
name: userconfig-openbao-server-tls
readOnly: true

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

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