-
Notifications
You must be signed in to change notification settings - Fork 0
vm broker ‐ k8s ‐ tenants ‐ kes vault (with TLS)
Allan Roger Reid edited this page Feb 7, 2024
·
5 revisions
loginctl enable-linger ubuntu
sudo touch /dev/kmsg
curl -sfL https://get.k3s.io | K3S_KUBECONFIG_MODE="644" sh -s - --snapshotter=fuse-overlayfs
systemctl is-active k3s
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
helm repo add hashicorp https://helm.releases.hashicorp.com
helm search repo vault
https://developer.hashicorp.com/vault/docs/platform/k8s/helm/examples/standalone-tls
# 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-internal
# NAMESPACE where the Vault service is running.
export NAMESPACE=hashicorp-vault
# 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
kubectl create namespace ${NAMESPACE}
openssl genrsa -out ${TMPDIR}/vault.key 2048
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
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
kubectl get serviceaccount
kubectl delete secret/service-account-vault
cat <<EOF >${TMPDIR}/service-account-token.yaml
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
name: service-account-vault
annotations:
kubernetes.io/service-account.name: default
EOF
kubectl create -f ${TMPDIR}/service-account-token.yaml
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
Send the CSR to Kubernetes. Approve the CSR in Kubernetes. Verify that the certificate was approved and issued.
kubectl create -f ${TMPDIR}/csr.yaml
kubectl certificate approve ${CSR_NAME}
kubectl get csr ${CSR_NAME}
serverCert=$(kubectl get csr ${CSR_NAME} -o jsonpath='{.status.certificate}')
echo "${serverCert}" | openssl base64 -d -A -out ${TMPDIR}/vault.crt
kubectl get secret \
-o jsonpath="{.items[?(@.type==\"kubernetes.io/service-account-token\")].data['ca\.crt']}" \
| base64 --decode > ${TMPDIR}/vault.ca
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
vi custom-values.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"
}
helm install vault hashicorp/vault --namespace ${NAMESPACE} -f custom-values.yaml
kubectl --namespace ${NAMESPACE} get pods
kubectl --namespace ${NAMESPACE} describe pods/vault-0
kubectl --namespace ${NAMESPACE} logs pods/vault-0
kubectl -n ${NAMESPACE} exec -i -t pod/vault-0 -- /bin/sh
export VAULT_ADDR='https://127.0.0.1:8200'
vault operator init
###
Unseal Key 1: nv/TiCt70oNHPHf8UXfN5zv64DO+KXef78FEfwru3KKm
Unseal Key 2: 9n5GWhmBcJxYqpykJNVtl5ovfvWdAD7J7JoeDnkYvFeT
Unseal Key 3: PxlzBbj7/kkh78rDTo/OGjlDuoMEWs0+dJrPTXWLy9t2
Unseal Key 4: meiLsApxYusWH+xBkdL7DontI0D1+5l0l9S4bNiVBV0M
Unseal Key 5: 5jVnyBZucQeCuQl6OkS3/NRrCEhCjnEqq0hvvBytuD9p
Initial Root Token: hvs.B39eL5npf5QaHVbYxA6alPz1
###
export VAULT_TOKEN=hvs.B39eL5npf5QaHVbYxA6alPz1
vault status
vault operator unseal nv/TiCt70oNHPHf8UXfN5zv64DO+KXef78FEfwru3KKm
vault operator unseal 9n5GWhmBcJxYqpykJNVtl5ovfvWdAD7J7JoeDnkYvFeT
vault operator unseal PxlzBbj7/kkh78rDTo/OGjlDuoMEWs0+dJrPTXWLy9t2
vault status
export VAULT_FORMAT="json"
vault auth disable approle
vault auth enable approle
vault secrets disable kv
vault secrets enable -version=1 kv
cat << EOF > /tmp/kes-policy.hcl
path "kv/*" {
capabilities = [ "create", "read", "update", "patch", "delete", "list" ]
}
EOF
vault policy write kes-policy /tmp/kes-policy.hcl
vault write auth/approle/role/kes-role token_num_uses=0 secret_id_num_uses=0 period=5m policies=kes-policy
export VAULT_ROLE_ID=$(vault read auth/approle/role/kes-role/role-id | grep -o '"role_id": "[^"]*' | grep -o '[^"]*$')
echo "${VAULT_ROLE_ID}" > /tmp/VAULT_ROLE_ID.var
export VAULT_SECRET_ID=$(vault write -f auth/approle/role/kes-role/secret-id | grep -o '"secret_id": "[^"]*' | grep -o '[^"]*$')
echo "${VAULT_SECRET_ID}" > /tmp/VAULT_SECRET_ID.var
exit
export VAULT_ROLE_ID=$(kubectl --namespace=hashicorp-vault exec -it vault-0 --container vault -- /bin/sh -c "cat /tmp/VAULT_ROLE_ID.var | tr -d '\n'")
export VAULT_SECRET_ID=$(kubectl --namespace=hashicorp-vault exec -it vault-0 --container vault -- /bin/sh -c "cat /tmp/VAULT_SECRET_ID.var | tr -d '\n'")
echo $VAULT_ROLE_ID
echo $VAULT_SECRET_ID
rm -rf ~/github/operator && mkdir -p ~/github/operator && cd ~/github && git clone https://github.com/minio/operator.git && cd ~
cat << EOF > ~/github/operator/examples/kustomization/tenant-kes-encryption/kes-configuration-secret-demo.yaml
apiVersion: v1
kind: Secret
metadata:
name: kes-configuration
namespace: tenant-kms-encrypted
type: Opaque
stringData:
server-config.yaml: |-
version: v1
address: :7373
admin:
identity: \${MINIO_KES_IDENTITY}
tls:
key: /tmp/kes/server.key
cert: /tmp/kes/server.crt
proxy:
identities: []
header:
cert: X-Tls-Client-Cert
policy:
my-policy:
allow:
- /v1/api
- /v1/key/create/*
- /v1/key/generate/*
- /v1/key/decrypt/*
- /v1/key/bulk/decrypt/*
- /v1/key/list/*
- /v1/status
identities:
cache:
expiry:
any: 5m0s
unused: 20s
log:
error: on
audit: off
keystore:
vault:
version: "v1"
endpoint: "https://vault-0.vault-internal.hashicorp-vault.svc.cluster.local:8200"
namespace: ""
prefix: "my-minio"
approle:
id: "${VAULT_ROLE_ID}"
secret: "${VAULT_SECRET_ID}"
retry: 15s
status:
ping: 10s
tls:
ca: "/tmp/kes/vault-crt.crt"
EOF
cat ${TMPDIR}/vault.ca | base64 -w0
cat ${TMPDIR}/vault.crt | base64 -w0
cat <<EOF > vault-ca-crt.yml
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: vault-ca-crt
namespace: tenant-kms-encrypted
data:
vault-ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkakNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdGMyVnkKZG1WeUxXTmhRREUzTURJME56STBNalF3SGhjTk1qTXhNakV6TVRNd01ESTBXaGNOTXpNeE1qRXdNVE13TURJMApXakFqTVNFd0h3WURWUVFEREJock0zTXRjMlZ5ZG1WeUxXTmhRREUzTURJME56STBNalF3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFSMFpabW9Hc0RxbXJtUGxCekl4TUJpaExuL2srUG0rd1g5NHV2czVOUW8KbEt6emFjc2I5WlRQT05ESHpzRU9vd01zY05BYXFKSUZQNFBHWDM1Tk55cDRvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVUNZMFRTSkQ5WlVpc3hUVGRNT1F4CkR6MDA5K013Q2dZSUtvWkl6ajBFQXdJRFJ3QXdSQUlnRExnTWlyUjB0WVRZMzg1cG1PbCt3RFduSE5PTWhFOFUKaUk3dTFNc0VFd2NDSUhHL3l0U3FJTWRQc2ttMnhLcnkwVlowcHpUOGJiUDJ2WHo2eldjTEtwV1MKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
vault-crt.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURPVENDQXQ2Z0F3SUJBZ0lSQU1xdm9PMWRGOGwxbi85Mi9BUnhpRkl3Q2dZSUtvWkl6ajBFQXdJd0l6RWgKTUI4R0ExVUVBd3dZYXpOekxYTmxjblpsY2kxallVQXhOekF5TkRjeU5ESTBNQjRYRFRJek1USXhPREV6TVRVMQpNbG9YRFRJME1USXhOekV6TVRVMU1sb3dVVEVWTUJNR0ExVUVDaE1NYzNsemRHVnRPbTV2WkdWek1UZ3dOZ1lEClZRUUREQzl6ZVhOMFpXMDZibTlrWlRwMllYVnNkQzFwYm5SbGNtNWhiQzVvWVhOb2FXTnZjbkF0ZG1GMWJIUXUKYzNaak96Q0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUtmWEN5SU9JV2F5RUVvKwp4V2hoa1BPbm82YlNHN2xMNld0Y3lsdnczZTJNa3ovcWNhNEtrTmV6UUYvR1B4c1JqeEEwY0tlb1FKNThXT3F6Cnp0eFZiNWFjK1AxV3JmMFdLU1BHZmN0SUZySzJPaldvTmFVS1ZJQmliclNiaytXOTBuQW9IU08xUzVjcGJRRWUKZUs3dEsrd2tiS0s3YU5JUTF3N1hhZGVsVStZaXUzTmZLUFpkQ2F1THZyRjk5bkU5R3NvWG9zUFNtVlk4QlhrOApaTjRhWDZTQ1F3OFRrT3hveHRwU3JUQjVnZUdmWjd3T2NIRVczMG5BSERCQnMrV3F3OW5TalhTTjRhL2dTNHZ4ClBjYW96TGEzYjlFdDZlZEVmR3FmenVtUmdkaTVXT3kyY1dHb2R4SXlUWDh5TG8rTmgzME1BWUF2K1EyeEwwNDgKYVFpOWJiRUNBd0VBQWFPQitUQ0I5akFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQgpCUVVIQXdFd0RBWURWUjBUQVFIL0JBSXdBREFmQmdOVkhTTUVHREFXZ0JRSmpSTklrUDFsU0t6Rk5OMHc1REVQClBUVDM0ekNCbndZRFZSMFJCSUdYTUlHVWdoQXFMblpoZFd4MExXbHVkR1Z5Ym1Gc2dpQXFMblpoZFd4MExXbHUKZEdWeWJtRnNMbWhoYzJocFkyOXljQzEyWVhWc2RJSWtLaTUyWVhWc2RDMXBiblJsY201aGJDNW9ZWE5vYVdOdgpjbkF0ZG1GMWJIUXVjM1pqZ2pJcUxuWmhkV3gwTFdsdWRHVnlibUZzTG1oaGMyaHBZMjl5Y0MxMllYVnNkQzV6CmRtTXVZMngxYzNSbGNpNXNiMk5oYkljRWZ3QUFBVEFLQmdncWhrak9QUVFEQWdOSkFEQkdBaUVBa3JjeTRmOVkKQWpnZEJwUlljYlI5Z05PUHJvR0FkSjZIMzNiNHlpd3JibndDSVFDQkNmZFRTZ3BHN01hTkpkUFRRNStJUFFxbQo5S1ZWblpsSXRXTEkxb0d1TXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
EOF
vi ~/github/operator/examples/kustomization/tenant-kes-encryption/tenant.yaml
#
clientCertSecret:
name: vault-ca-crt
type: Opaque
#
cat << EOF > ~/github/operator/examples/kustomization/tenant-kes-encryption/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: tenant-kms-encrypted
resources:
- ../base
- kes-configuration-secret-demo.yaml
patchesStrategicMerge:
- tenant.yaml
EOF
sudo snap install kustomize
kubectl delete namespace/tenant-kms-encrypted
kustomize build ~/github/operator/examples/kustomization/tenant-kes-encryption | kubectl apply -f -
kubectl --namespace tenant-kms-encrypted apply -f ./vault-ca-crt.yml
#### Tweak tenant size and storeclass/pvcs
kubectl patch tenant -n tenant-kms-encrypted myminio --type='merge' -p '{"spec":{"pools":[{"name": "pool-0", "servers": '4', "volumesPerServer": 1, "volumeClaimTemplate": {"apiVersion": "v1", "metadata": {"name": "data"}, "spec": {"accessModes": ["ReadWriteOnce"], "resources": {"requests": {"storage": "1Gi"}}, "storageClassName": "local-path"}}}]}}'
kubectl -n tenant-kms-encrypted delete pods -l app=minio
kubectl -n tenant-kms-encrypted delete statefulset/myminio-pool-0
kubectl -n tenant-kms-encrypted delete statefulset/myminio-kes
kubectl -n tenant-kms-encrypted get tenant
kubectl -n tenant-kms-encrypted get pods
kubectl -n tenant-kms-encrypted logs pod/myminio-kes-1
cat ${TMPDIR}/vault.ca
cat ${TMPDIR}/vault.crt
#
-----BEGIN CERTIFICATE-----
MIIBdjCCAR2gAwIBAgIBADAKBggqhkjOPQQDAjAjMSEwHwYDVQQDDBhrM3Mtc2Vy
dmVyLWNhQDE3MDI0NzI0MjQwHhcNMjMxMjEzMTMwMDI0WhcNMzMxMjEwMTMwMDI0
WjAjMSEwHwYDVQQDDBhrM3Mtc2VydmVyLWNhQDE3MDI0NzI0MjQwWTATBgcqhkjO
PQIBBggqhkjOPQMBBwNCAAR0ZZmoGsDqmrmPlBzIxMBihLn/k+Pm+wX94uvs5NQo
lKzzacsb9ZTPONDHzsEOowMscNAaqJIFP4PGX35NNyp4o0IwQDAOBgNVHQ8BAf8E
BAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUCY0TSJD9ZUisxTTdMOQx
Dz009+MwCgYIKoZIzj0EAwIDRwAwRAIgDLgMirR0tYTY385pmOl+wDWnHNOMhE8U
iI7u1MsEEwcCIHG/ytSqIMdPskm2xKry0VZ0pzT8bbP2vXz6zWcLKpWS
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDOTCCAt6gAwIBAgIRAMqvoO1dF8l1n/92/ARxiFIwCgYIKoZIzj0EAwIwIzEh
MB8GA1UEAwwYazNzLXNlcnZlci1jYUAxNzAyNDcyNDI0MB4XDTIzMTIxODEzMTU1
MloXDTI0MTIxNzEzMTU1MlowUTEVMBMGA1UEChMMc3lzdGVtOm5vZGVzMTgwNgYD
VQQDDC9zeXN0ZW06bm9kZTp2YXVsdC1pbnRlcm5hbC5oYXNoaWNvcnAtdmF1bHQu
c3ZjOzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKfXCyIOIWayEEo+
xWhhkPOno6bSG7lL6Wtcylvw3e2Mkz/qca4KkNezQF/GPxsRjxA0cKeoQJ58WOqz
ztxVb5ac+P1Wrf0WKSPGfctIFrK2OjWoNaUKVIBibrSbk+W90nAoHSO1S5cpbQEe
eK7tK+wkbKK7aNIQ1w7XadelU+Yiu3NfKPZdCauLvrF99nE9GsoXosPSmVY8BXk8
ZN4aX6SCQw8TkOxoxtpSrTB5geGfZ7wOcHEW30nAHDBBs+Wqw9nSjXSN4a/gS4vx
PcaozLa3b9Et6edEfGqfzumRgdi5WOy2cWGodxIyTX8yLo+Nh30MAYAv+Q2xL048
aQi9bbECAwEAAaOB+TCB9jAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYB
BQUHAwEwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBQJjRNIkP1lSKzFNN0w5DEP
PTT34zCBnwYDVR0RBIGXMIGUghAqLnZhdWx0LWludGVybmFsgiAqLnZhdWx0LWlu
dGVybmFsLmhhc2hpY29ycC12YXVsdIIkKi52YXVsdC1pbnRlcm5hbC5oYXNoaWNv
cnAtdmF1bHQuc3ZjgjIqLnZhdWx0LWludGVybmFsLmhhc2hpY29ycC12YXVsdC5z
dmMuY2x1c3Rlci5sb2NhbIcEfwAAATAKBggqhkjOPQQDAgNJADBGAiEAkrcy4f9Y
AjgdBpRYcbR9gNOProGAdJ6H33b4yiwrbnwCIQCBCfdTSgpG7MaNJdPTQ5+IPQqm
9KVVnZlItWLI1oGuMw==
-----END CERTIFICATE-----
#
kubectl --namespace default exec -it ubuntu -- /bin/bash
apt-get install vim -y
apt-get install build-essential -y
vi ${TMPDIR}/vault.ca
vi ${TMPDIR}/vault.crt
curl --request POST --data '{"role_id":"4a7532a2-97c4-33da-1212-ed3f2011c3ae","secret_id":"6f3f65c5-b5a5-3a28-e991-48d41bb7ae79"}' https://vault-0.vault-internal.hashicorp-vault.svc.cluster.local:8200/v1/auth/approle/login
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
VERSUS
curl --request POST --data '{"role_id":"4a7532a2-97c4-33da-1212-ed3f2011c3ae","secret_id":"6f3f65c5-b5a5-3a28-e991-48d41bb7ae79"}' https://vault-0.vault-internal.hashicorp-vault.svc.cluster.local:8200/v1/auth/approle/login --cacert /tmp/vault.ca
OR
curl --request POST --data '{"role_id":"4a7532a2-97c4-33da-1212-ed3f2011c3ae","secret_id":"6f3f65c5-b5a5-3a28-e991-48d41bb7ae79"}' https://vault-0.vault-internal.hashicorp-vault.svc.cluster.local:8200/v1/auth/approle/login --cacert /tmp/vault.crt
exit
export NODEPORT_HTTP=31092
export NODEPORT_HTTPS=30045
kubectl patch service -n tenant-kms-encrypted myminio-console -p '{"spec":{"ports":[{"name": "http-console","port": 9090,"protocol": "TCP","nodePort":'${NODEPORT_HTTP}'},{"name": "https-console","port": 9443,"protocol": "TCP","nodePort":'${NODEPORT_HTTPS}'}],"type": "NodePort"}}'
mkdir -p ~/mc && cd ~/mc && rm -rf mc* && wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc && cd ~
kubectl port-forward svc/myminio-hl 9000:9000 -n tenant-kms-encrypted &
mc/mc alias set kes-demo https://127.0.0.1:9000 minio minio123 --insecure
mc/mc admin kms key status kes-demo --insecure
SA_TOKEN=$(kubectl -n minio-operator get secret console-sa-secret -o jsonpath="{.data.token}" | base64 --decode) && echo $SA_TOKEN
echo "Access the minio tenant console from https://$(hostname).lab.min.dev:${NODEPORT_HTTPS} using username and password"