mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-23 23:51:08 +02:00
219 lines
6.6 KiB
Plaintext
219 lines
6.6 KiB
Plaintext
---
|
|
layout: 'docs'
|
|
page_title: 'Standalone server with TLS'
|
|
sidebar_current: 'docs-platform-k8s-examples-standalone-tls'
|
|
description: >-
|
|
Learn how to set up a standalone Vault server with TLS certificate.
|
|
---
|
|
|
|
# Standalone server with TLS
|
|
|
|
@include 'helm/version.mdx'
|
|
|
|
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](https://kubernetes.io/docs/concepts/configuration/secret/)
|
|
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.
|
|
|
|
```bash
|
|
# 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.
|
|
export SERVICE=vault-server-tls
|
|
|
|
# NAMESPACE where the Vault service is running.
|
|
export NAMESPACE=vault-namespace
|
|
|
|
# SECRET_NAME to create in the kubernetes secrets store.
|
|
export SECRET_NAME=vault-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=vault-csr
|
|
```
|
|
|
|
1. Create a key for Kubernetes to sign.
|
|
|
|
```shell-session
|
|
$ openssl genrsa -out ${TMPDIR}/vault.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
|
|
```
|
|
|
|
2. Create a CSR.
|
|
|
|
```bash
|
|
openssl req -new \
|
|
-key ${TMPDIR}/vault.key \
|
|
-subj "/CN=system:node:${SERVICE}.${NAMESPACE}.svc;/O=system:nodes" \
|
|
-out ${TMPDIR}/server.csr \
|
|
-config ${TMPDIR}/csr.conf
|
|
```
|
|
|
|
3. Create the certificate
|
|
|
|
~> **Important Note:** If you are using EKS, certificate signing requirements have changed. As per the AWS [certificate signing](https://docs.aws.amazon.com/eks/latest/userguide/cert-signing.html) 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:
|
|
|
|
```bash
|
|
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.
|
|
|
|
```shell-session
|
|
$ kubectl create -f ${TMPDIR}/csr.yaml
|
|
certificatesigningrequest.certificates.k8s.io/vault-csr created
|
|
```
|
|
|
|
-> If this process is automated, you may need to wait to ensure the CSR has been received and stored:
|
|
`kubectl get csr ${CSR_NAME}`
|
|
|
|
3. Approve the CSR in Kubernetes.
|
|
|
|
```shell-session
|
|
$ kubectl certificate approve ${CSR_NAME}
|
|
certificatesigningrequest.certificates.k8s.io/vault-csr approved
|
|
```
|
|
|
|
4. Verify that the certificate was approved and issued.
|
|
```shell-session
|
|
$ kubectl get csr ${CSR_NAME}
|
|
NAME AGE SIGNERNAME REQUESTOR CONDITION
|
|
vault-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.
|
|
|
|
```shell-session
|
|
$ serverCert=$(kubectl get csr ${CSR_NAME} -o jsonpath='{.status.certificate}')
|
|
```
|
|
|
|
-> 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.
|
|
|
|
2. Write the certificate out to a file.
|
|
|
|
```shell-session
|
|
$ echo "${serverCert}" | openssl base64 -d -A -out ${TMPDIR}/vault.crt
|
|
```
|
|
|
|
3. Retrieve Kubernetes CA.
|
|
|
|
```bash
|
|
kubectl get secret \
|
|
-o jsonpath="{.items[?(@.type==\"kubernetes.io/service-account-token\")].data['ca\.crt']}" \
|
|
| base64 --decode > ${TMPDIR}/vault.ca
|
|
```
|
|
|
|
4. Create the namespace.
|
|
|
|
```shell-session
|
|
$ kubectl create namespace ${NAMESPACE}
|
|
namespace/vault-namespace created
|
|
```
|
|
|
|
5. Store the key, cert, and Kubernetes CA into Kubernetes secrets.
|
|
|
|
```shell-session
|
|
$ 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
|
|
|
|
# secret/vault-server-tls created
|
|
```
|
|
|
|
## 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:
|
|
|
|
```yaml
|
|
global:
|
|
enabled: true
|
|
tlsDisable: false
|
|
|
|
server:
|
|
extraEnvironmentVars:
|
|
VAULT_CACERT: /vault/userconfig/vault-server-tls/vault.ca
|
|
|
|
volumes:
|
|
- name: userconfig-vault-server-tls
|
|
secret:
|
|
defaultMode: 420
|
|
secretName: vault-server-tls # Matches the ${SECRET_NAME} from above
|
|
|
|
volumeMounts:
|
|
- mountPath: /vault/userconfig/vault-server-tls
|
|
name: userconfig-vault-server-tls
|
|
readOnly: true
|
|
|
|
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"
|
|
}
|
|
```
|