-
Notifications
You must be signed in to change notification settings - Fork 884
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HA vault init with TLS - cannot validate certificate #243
Comments
Here is my guideline how to create Vault TLS client and CA certificates VariablesSERVICE=vault
NAMESPACE=vault
SECRET_NAME=vault-tls
CSR_NAME=vault-csr
BASENAME=vault
TMPDIR=./cert Create a Certificate Signing Request (CSR)# Create private key
openssl genrsa -out ${TMPDIR}/${BASENAME}.key rsa:2048 -days 3651
# Create a file ${TMPDIR}/${NAMESPACE}-csr.conf with the following contents
cat <<EOF >${TMPDIR}/${BASENAME}-csr.conf
[ req ]
default_bits = 2048
prompt = no
encrypt_key = yes
default_md = sha256
distinguished_name = dn
req_extensions = v3_req
[ dn ]
C = NO
ST = Oslo
L = Oslo
O = Personal
emailAddress = [email protected]
CN = ${SERVICE}.${NAMESPACE}.svc
[ 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
# Create a CSR
openssl req -config ${TMPDIR}/${BASENAME}-csr.conf -new -key ${TMPDIR}/${BASENAME}.key -subj "/CN=${SERVICE}.${NAMESPACE}.svc" -out ${TMPDIR}/${BASENAME}.csr -days 3651 Create the certificate# Create a file ${TMPDIR}/${BASENAME}.yaml with the following contents
cat <<EOF >${TMPDIR}/${BASENAME}-csr.yaml
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
name: ${CSR_NAME}
spec:
groups:
- system:authenticated
request: $(cat ${TMPDIR}/${BASENAME}.csr | base64 | tr -d '\n')
usages:
- digital signature
- key encipherment
- server auth
EOF
# Delete CSR and secret if exist
kubectl delete secret ${SERVICE_NAME} --namespace ${NAMESPACE}
kubectl delete csr ${CSR_NAME} --namespace ${NAMESPACE}
# Send the CSR to Kubernetes.
kubectl create -f ${TMPDIR}/${BASENAME}-csr.yaml --namespace ${NAMESPACE}
#If this process is automated, you may need to wait to ensure the CSR has been received and stored
kubectl get csr ${CSR_NAME} --namespace ${NAMESPACE}
## NAME AGE REQUESTOR CONDITION
## vault-csr 2m44s masterclient Pending
# Approve the CSR in Kubernetes
kubectl certificate approve ${CSR_NAME} --namespace ${NAMESPACE}
## certificatesigningrequest.certificates.k8s.io/vault-csr approved Store key, cert, and Kubernetes CA into Kubernetes secrets store# Retrieve the 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.
serverCert=$(kubectl get csr ${CSR_NAME} -o jsonpath='{.status.certificate}')
# Write the certificate out to the CRT file
echo "${serverCert}" | openssl base64 -d -A -out ${TMPDIR}/${BASENAME}.crt
# Retrieve Kubernetes CA
kubectl config view --raw --minify --flatten -o jsonpath='{.clusters[].cluster.certificate-authority-data}' | base64 -d > ${TMPDIR}/${BASENAME}.ca
# Delete secret (if needed)
#kubectl delete secret ${SERVICE_NAME} -all --namespace ${NAMESPACE}
# Store the key, cert, and Kubernetes CA into Kubernetes secrets.
### This will create files /vault/userconfig/vault.ca , /vault/userconfig/vault.crt, /vault/userconfig/vault.key in the vault Pods
### values.yaml: Update server.ha.config:listener, injection.cert:certName,certKey
kubectl create secret generic ${SECRET_NAME} \
--namespace ${NAMESPACE} \
--from-file=${BASENAME}.key=${TMPDIR}/${BASENAME}.key \
--from-file=${BASENAME}.crt=${TMPDIR}/${BASENAME}.crt \
--from-file=${BASENAME}.ca=${TMPDIR}/${BASENAME}.ca
# Verify the certificate:
openssl x509 -in ${TMPDIR}/${BASENAME}.crt -noout -text Vault Helm Configuration (values.yaml)# 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-tls/vault.ca # Matches the ${SECRET_NAME}/${BASENAME}.ca from above
injector:
#certs:
# secretName: vault-tls
#caBundle: "**enter string base64 of vault.ca**"
# certName: vault.crt
# keyName: vault.key
server:
image:
repository: 'vault'
tag: '1.3.4'
extraVolumes:
- type: secret
name: vault-tls # Matches the ${SECRET_NAME} from above
standalone:
enabled: true
config: |
api_addr = "http://POD_IP:8200"
listener "tcp" {
address = "0.0.0.0:8200"
cluster_address = "0.0.0.0:8201"
tls_cert_file = "/vault/userconfig/vault-tls/vault.crt" # Matches the ${SECRET_NAME}/${BASENAME}.crt from above
tls_key_file = "/vault/userconfig/vault-tls/vault.key" # Matches the ${SECRET_NAME}/${BASENAME}.key from above
tls_client_ca_file = "/vault/userconfig/vault-tls/vault.ca" # Matches the ${SECRET_NAME}/${BASENAME}.ca from above
}
storage "file" {
path = "/vault/data"
} Verifications# Checking certifiates on vailt Pods (webhook)
kubectl exec -it vault-0 -- ls /vault/userconfig/vault-tls
## vault.ca vault.crt vault.key
# Checking certifiates on agent-injecot (webhook)
kubectl exec -it vault-agent-injector-<POD_NAME_SUFFIX>-- ls /etc/webhook/certs
## vault.ca vault.crt vault.key
|
I followed the instructions, and verified the certs all match from inside the pod. But still getting the same error. |
I have removed injection.cert in my custom values file.
|
I don't believe so, This is the only the vault-server pods during init phase. When the pod first starts up, it logs
Then the vault pods will eventually crash loop, which I believe is normal behavior until the |
Interestingly, I edited the statefulset template env var for the vault-server from:
to
But then I got the error: So I changed it to
After that I was able to init the vault servers. Even though my altnames haven't changed on the csr.conf
|
Moved post to #244 |
We got permission denied on the https request while patching (agent injection). The way to solve this The reason why vault.vault.svc worked in the StatefulSet env is probably because of CN (Common Name) definition in the CSR. The best option is not to hard code and change it back as before: "127.0.0.1:8200" or else vault Pods fail to install in other Kubernetes context/namespaces. The TLS Certificate Signature Request needs to be something like this when using OpenSSL Greetings from Norway CSR filecat <<EOF > ./certs/vault-csr.conf
[ req ]
default_bits = 2048
prompt = no
encrypt_key = yes
default_md = sha256
distinguished_name = dn
req_extensions = v3_req
[ dn ]
C = NO
ST = Oslo
L = Oslo
O = Our Business
OU = Our Department
emailAddress = [email protected]
CN = vault.vault.svc
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = vault
DNS.2 = vault.vault
DNS.3 = vault.vault.svc
DNS.4 = vault.vault.svc.cluster.local
DNS.5 = vault-agent-injector-svc
DNS.6 = vault-agent-injector-svc.vault
DNS.7 = vault-agent-injector-svc.vault.svc
DNS.8 = vault-agent-injector-svc.vault.svc.cluster.local
IP.1 = 127.0.0.1
EOF |
Here is my config info. api_addr = "http://POD_IP:8200"
# https://www.vaultproject.io/docs/configuration/listener/tcp/
listener "tcp" {
address = "0.0.0.0:8200"
cluster_address = "0.0.0.0:8201"
http_idle_timeout = "5m"
http_read_header_timeout = "10s"
http_read_timeout = "30s"
http_write_timeout = "0"
max_request_size = 33554432
max_request_duration = "90s"
# https://www.vaultproject.io/docs/platform/k8s/helm/examples/standalone-tls/
tls_disable = "false"
tls_cert_file = "/vault/userconfig/vault-tls/vault-server-public.crt"
tls_key_file = "/vault/userconfig/vault-tls/vault-server-private.key"
tls_client_ca_file = "/vault/userconfig/vault-tls/vault-client.ca"
tls_min_version = "tls12"
} |
Just faced this issue today. You need to generate csr with the following config:
where
Then you can do:
That's it :) |
Using wildcard certificate as @ikarlashov noted worked for me. One thing to mention, when joining the cluster from vault operator raft join -leader-ca-cert="@${VAULT_CACERT}" -leader-client-cert="@${VAULT_TLSCERT}" -leader-client-key="@${VAULT_TLSKEY}" https://vault-0.vault-internal:8200' where env variables above are set in Helm chart's values: server:
extraEnvironmentVars:
VAULT_CACERT: /vault/userconfig/vault-tls/vault.ca
VAULT_TLSCERT: /vault/userconfig/vault-tls/vault.crt
VAULT_TLSKEY: /vault/userconfig/vault-tls/vault.key
ha:
enabled: true
raft:
enabled: true
config: |
ui = true
listener "tcp" {
address = "[::]:8200"
cluster_address = "[::]:8201"
tls_cert_file = "/vault/userconfig/vault-tls/vault.crt"
tls_key_file = "/vault/userconfig/vault-tls/vault.key"
tls_client_ca_file = "/vault/userconfig/vault-tls/vault.ca"
} Also, certificates have to be configured in |
@j-sokol Thank you so much for the tip that certificates need to be provided this way, worked for me!! In case anyone like me stumbles across this feel free to use my whole config, which works with the fixes described in this thread: global:
enabled: true
tlsDisable: false
injector:
enabled: false
server:
extraEnvironmentVars:
VAULT_CACERT: /vault/userconfig/vault/vault.ca
VAULT_TLSCERT: /vault/userconfig/vault/vault.crt
VAULT_TLSKEY: /vault/userconfig/vault/vault.key
extraVolumes:
- type: secret
name: vault
ha:
enabled: true
replicas: 3
raft:
enabled: true
setNodeId: false
config: |
ui = true
api_addr = "http://POD_IP:8200"
listener "tcp" {
address = "0.0.0.0:8200"
cluster_address = "0.0.0.0:8201"
tls_cert_file = "/vault/userconfig/vault/vault.crt"
tls_key_file = "/vault/userconfig/vault/vault.key"
tls_client_ca_file = "/vault/userconfig/vault/vault.ca"
}
storage "raft" {
path = "/vault/data"
retry_join {
leader_api_addr = "https://vault-0.vault-internal:8200"
leader_ca_cert_file = "/vault/userconfig/vault/vault.ca"
leader_client_cert_file = "/vault/userconfig/vault/vault.crt"
leader_client_key_file = "/vault/userconfig/vault/vault.key"
}
retry_join {
leader_api_addr = "https://vault-1.vault-internal:8200"
leader_ca_cert_file = "/vault/userconfig/vault/vault.ca"
leader_client_cert_file = "/vault/userconfig/vault/vault.crt"
leader_client_key_file = "/vault/userconfig/vault/vault.key"
}
retry_join {
leader_api_addr = "https://vault-2.vault-internal:8200"
leader_ca_cert_file = "/vault/userconfig/vault/vault.ca"
leader_client_cert_file = "/vault/userconfig/vault/vault.crt"
leader_client_key_file = "/vault/userconfig/vault/vault.key"
}
autopilot {
cleanup_dead_servers = "true"
last_contact_threshold = "200ms"
last_contact_failure_threshold = "10m"
max_trailing_logs = 250000
min_quorum = 3
server_stabilization_time = "10s"
}
} |
For anyone running across this who happens to be following the documentation in a cluster running 1.22 or greater, with the changes to the certificate API, you will need to make some changes. First, for the csr.yaml file you will need a You'll know if you're dealing with this problem if your certificate immediately goes to the
|
I got this error if i combine your solution with this document.
My values.yaml: # Vault Helm Chart Value Overrides
global:
enabled: true
tlsDisable: false
injector:
enabled: true
# Use the Vault K8s Image https://github.com/hashicorp/vault-k8s/
image:
repository: "hashicorp/vault-k8s"
tag: "latest"
resources:
requests:
memory: 512Mi
cpu: 500m
limits:
memory: 512Mi
cpu: 500m
server:
# Use the Enterprise Image
image:
repository: "hashicorp/vault"
tag: "1.9.0"
# These Resource Limits are in line with node requirements in the
# Vault Reference Architecture for a Small Cluster
resources: {}
# For HA configuration and because we need to manually init the vault,
# we need to define custom readiness/liveness Probe settings
readinessProbe:
enabled: true
path: "/v1/sys/health?standbyok=true&sealedcode=204&uninitcode=204"
livenessProbe:
enabled: true
path: "/v1/sys/health?standbyok=true"
initialDelaySeconds: 60
affinity: |
# extraEnvironmentVars is a list of extra environment variables to set with the stateful set. These could be
# used to include variables required for auto-unseal.
extraEnvironmentVars:
VAULT_CACERT: /vault/userconfig/vault-server-tls/vault.ca
# extraVolumes is a list of extra volumes to mount. These will be exposed
# to Vault in the path `/vault/userconfig/<name>/`.
extraVolumes:
- type: secret
name: vault-server-tls
# This configures the Vault Statefulset to create a PVC for audit logs.
# See https://www.vaultproject.io/docs/audit/index.html to know more
auditStorage:
enabled: true
standalone:
enabled: false
# Run Vault in "HA" mode.
ha:
enabled: true
replicas: 5
raft:
enabled: true
setNodeId: true
config: |
ui = true
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 "raft" {
path = "/vault/data"
retry_join {
leader_api_addr = "https://vault-0.vault-internal:8200"
leader_ca_cert_file = "/vault/userconfig/vault-server-tls/vault.ca"
leader_client_cert_file = "/vault/userconfig/vault-server-tls/vault.crt"
leader_client_key_file = "/vault/userconfig/vault-server-tls/vault.key"
}
retry_join {
leader_api_addr = "https://vault-1.vault-internal:8200"
leader_ca_cert_file = "/vault/userconfig/vault-server-tls/vault.ca"
leader_client_cert_file = "/vault/userconfig/vault-server-tls/vault.crt"
leader_client_key_file = "/vault/userconfig/vault-server-tls/vault.key"
}
retry_join {
leader_api_addr = "https://vault-2.vault-internal:8200"
leader_ca_cert_file = "/vault/userconfig/vault-server-tls/vault.ca"
leader_client_cert_file = "/vault/userconfig/vault-server-tls/vault.crt"
leader_client_key_file = "/vault/userconfig/vault-server-tls/vault.key"
}
retry_join {
leader_api_addr = "https://vault-3.vault-internal:8200"
leader_ca_cert_file = "/vault/userconfig/vault-server-tls/vault.ca"
leader_client_cert_file = "/vault/userconfig/vault-server-tls/vault.crt"
leader_client_key_file = "/vault/userconfig/vault-server-tls/vault.key"
}
retry_join {
leader_api_addr = "https://vault-4.vault-internal:8200"
leader_ca_cert_file = "/vault/userconfig/vault-server-tls/vault.ca"
leader_client_cert_file = "/vault/userconfig/vault-server-tls/vault.crt"
leader_client_key_file = "/vault/userconfig/vault-server-tls/vault.key"
}
autopilot {
cleanup_dead_servers = "true"
last_contact_threshold = "200ms"
last_contact_failure_threshold = "10m"
max_trailing_logs = 250000
min_quorum = 5
server_stabilization_time = "10s"
}
}
service_registration "kubernetes" {}
# Vault UI
ui:
enabled: true
serviceType: "NodePort"
serviceNodePort: 30082
externalPort: 8200 Am i missing something ? |
I think we'd have to see your certificate manifests to see how you signed and created the certificate. I used the cluster CA for my test deployment and had no issues, but the error you're receiving seems straight forward. |
With k8s 1.19 the
the |
it is possible to set specific server name which will be used in TLS handshake retry_join {
leader_tls_servername = "vault"
} ref. https://www.vaultproject.io/docs/concepts/integrated-storage#autojoin-with-tls-servername |
Hello All, thanks for all the comment which helped me in setting up vault in k8s with self-signed certificate. |
The `CertificateSigningRequest` for `v1beta1` API is no longer available, and now requires the `signerName` parameter. Many thanks to @DavidRBanks for the helpful notes in hashicorp/vault-helm#243 (comment) I tested this on Kubernetes 1.21 and 1.24. I also adjusted the `tr` command to work better on macOS (and still works fine on Linux).
Update helm standalone TLS doc for k8s 1.22 The `CertificateSigningRequest` for `v1beta1` API is no longer available, and now requires the `signerName` parameter. Many thanks to @DavidRBanks for the helpful notes in hashicorp/vault-helm#243 (comment) I tested this on Kubernetes 1.21 and 1.24. I also adjusted the `tr` command to work better on macOS (and still works fine on Linux).
Update helm standalone TLS doc for k8s 1.22 The `CertificateSigningRequest` for `v1beta1` API is no longer available, and now requires the `signerName` parameter. Many thanks to @DavidRBanks for the helpful notes in hashicorp/vault-helm#243 (comment) I tested this on Kubernetes 1.21 and 1.24. I also adjusted the `tr` command to work better on macOS (and still works fine on Linux).
Update helm standalone TLS doc for k8s 1.22 The `CertificateSigningRequest` for `v1beta1` API is no longer available, and now requires the `signerName` parameter. Many thanks to @DavidRBanks for the helpful notes in hashicorp/vault-helm#243 (comment) I tested this on Kubernetes 1.21 and 1.24. I also adjusted the `tr` command to work better on macOS (and still works fine on Linux). Co-authored-by: Christopher Swenson <[email protected]>
As the documentation has been updated, I'm going to go ahead and close this issue now. Please feel free to open a new issue if you continue to have problems with TLS and vault init. Thanks! |
I have configured the Vault-HA with TLS on Openshift4.8.36 platform by referring below links. https://www.vaultproject.io/docs/platform/k8s/helm/examples/standalone-tls #243. But Getting error at below steps while unseal vault-1 pods [root@tef-line-bastion hashicorp-vault]# VAULT_UNSEAL_KEY=$(jq -r ".unseal_keys_b64[]" cluster-keys.json) Joined true URL: PUT https://127.0.0.1:8200/v1/sys/unseal
Snippet vault-1 >>> 2022-11-18T11:45:10.139Z [INFO] core: security barrier not initialized 2022-11-18T11:45:20.141Z [INFO] core: security barrier not initialized Let me know why vault-1 not initialized after joining to vault-0. Any suggestion on this. |
Hello,
I'm trying to setup HA vault cluster consisting of 3 vault pods in EKS.
I followed the TLS cert generation instructions from https://www.vaultproject.io/docs/platform/k8s/helm/examples/standalone-tls/
When I try to run
vault operator init
, vault is returning:Error initializing: Put https://127.0.0.1:8200/v1/sys/init: x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs
In my csr.conf, I have these defined:
I also checked the csr generated:
I suspect 127.0.0.1 is from the env variable defined in the statefulset template
My tcp listener is configured as:
Is there another set of instructions I am missing?
Thanks
The text was updated successfully, but these errors were encountered: