Last active
February 2, 2018 22:04
-
-
Save joejulian/acf80f116a66ecedaa8c573fe7e0e2fa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -e | |
# Setup a Root CA in vault | |
# Generate and sign an Intermediate cert | |
# | |
# Requires: | |
# * A running vault server already initialzed and unsealed | |
# * Environment variable VAULT_TOKEN is set | |
# * vault cli (https://www.vaultproject.io) | |
# * httpie (https://github.com/jkbrzt/httpie) | |
# * jq (https://stedolan.github.io/jq/) | |
# | |
# Note: we use httpie + jq because vault write commands aren't able to return | |
# formatted json for parsing | |
[[ "${VAULT_TOKEN}" == "" ]] && { echo "VAULT_TOKEN is not set"; exit 1; } | |
ROOT_PATH=${ROOT_PATH:-root_ca} | |
INTR_PATH=${INTR_PATH:-intermediate_clusterops} | |
COMPANY="${COMPANY:-CNCT}" | |
DOMAIN="${DOMAIN:-clusterops}" | |
UNDER_DOM=${DOMAIN//\./_} | |
USER="${USER:-testuser}" | |
# check dependencies | |
command -v vault 2> /dev/null || { echo "Please install vault (https://www.vaultproject.io)"; exit 1; } | |
command -v http 2> /dev/null || { echo "Please install httpie (https://github.com/jkbrzt/httpie)"; exit 1; } | |
command -v jq 2> /dev/null || { echo "Please install jq (https://stedolan.github.io/jq/)"; exit 1; } | |
############################################################################# | |
# Step 0: Prepare a cluster (minikube) | |
############################################################################# | |
export VAULT_ADDR='http://127.0.0.1:8200' | |
export VAULT_ROOT_TOKEN=$(uuidgen) | |
minikube start | |
# Start vault if START_VAULT is set | |
if [ -n $START_VAULT ]; then | |
vault server -dev -dev-root-token-id="${VAULT_ROOT_TOKEN}" > /tmp/vault.log 2>&1 & | |
vault auth $VAULT_ROOT_TOKEN | |
fi | |
############################################################################# | |
# Step 1: Admin initializes Vault to issue intermediate certificates based on the cluster CA | |
############################################################################# | |
# minikube in default mode generates a CA for the cluster and client certificate in "$HOME/.minikube" directory. | |
cat ~/.minikube/ca.{crt,key} > clientCA.bundle | |
# Register the client CA generaged by minikube. | |
vault mount -path="${ROOT_PATH}" pki | |
# Set the max TTL for the root CA to 10 years | |
echo "Tuning root CA" | |
vault mount-tune -max-lease-ttl="87600h" "${ROOT_PATH}" | |
# Write the CA | |
vault write ${ROOT_PATH}/config/ca [email protected] | |
############################################################################# | |
# Step 2: Create an intermediate CA | |
############################################################################# | |
# Intermediate CAs should be created for each organization (kubernetes group) | |
# for this example, that's ${DOMAIN}. | |
# Mount the intermediate CA for the zone | |
echo "Creating intermediate CA" | |
vault mount -path=${INTR_PATH} pki | |
# Set the max TTL for ${DOMAIN} certs to 1 year | |
echo "Tuning intermediate CA" | |
vault mount-tune -max-lease-ttl=8760h ${INTR_PATH} | |
# Generate CSR for ${DOMAIN} to be signed by the root CA, the key is stored | |
# internally to vault | |
echo "Generating intermediate CSR" | |
http POST ${VAULT_ADDR}/v1/${INTR_PATH}/intermediate/generate/internal X-Vault-Token:$VAULT_TOKEN common_name=${DOMAIN} | jq -r .data.csr > ${UNDER_DOM}.csr | |
# Generate and sign the ${DOMAIN} certificate as an intermediate CA | |
echo "Get intermediate cert" | |
http POST ${VAULT_ADDR}/v1/${ROOT_PATH}/root/sign-intermediate X-Vault-Token:$VAULT_TOKEN ttl="8760h" csr=@${UNDER_DOM}.csr | jq -r .data.certificate > ${UNDER_DOM}.crt | |
# Add signed ${DOMAIN} certificate to intermediate CA backend | |
echo "Add intermediate cert" | |
vault write ${INTR_PATH}/intermediate/set-signed certificate=@${UNDER_DOM}.crt | |
# Create role for issuing ${DOMAIN} certificates | |
# Max lease time is 14 days | |
echo "Create a role for subdomain certs" | |
vault write ${INTR_PATH}/roles/${UNDER_DOM} allow_any_name=true organization=${DOMAIN} generate_lease=true server_flag=false lease_max="336h" | |
############################################################################# | |
# Step 3: Issue client certificates for user | |
############################################################################# | |
# issue certificate for CN:${USER} O:${DOMAIN} | |
http POST ${VAULT_ADDR}/v1/${INTR_PATH}/issue/${UNDER_DOM} X-Vault-Token:$VAULT_TOKEN common_name="${USER}" ttl="168h" | jq -r .data.private_key,.data.certificate,.data.issuing_ca > ${USER}_${UNDER_DOM}.pem | |
############################################################################# | |
# Step 4: Users can add their certificates to kubeconfig | |
############################################################################# | |
# Separate bundle into cert and key | |
cat ${USER}_${UNDER_DOM}.pem | sed -n '/certificate/,/END CERTI/p' | sed 's/certificate[ \t]*//g' > ${USER}_${UNDER_DOM}.crt | |
cat ${USER}_${UNDER_DOM}.pem | sed -n '/private_key /,/END RSA/p' | sed 's/private_key[ \t]*//g' > ${USER}_${UNDER_DOM}.key | |
# Add user in kubeconfig | |
kubectl config set-credentials ${USER} --client-certificate=${USER}_${UNDER_DOM}.crt --client-key=${USER}_${UNDER_DOM}.key | |
#################################################################retrieve the CRL in PEM format with############ | |
# Step 4: Check if the kubeconfig works | |
############################################################################# | |
kubectl config set-context admin-context --cluster=minikube --user=${USER} | |
kubectl config use-context admin-context | |
kubectl get nodes | |
# NAME STATUS ROLES AGE VERSION | |
# minikube Ready <none> <invalid> v1.9.0 | |
# retrieve the CRL in PEM format | |
http GET ${VAULT_ADDR}/v1/root_ca/crl/pem |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment