Skip to content

Instantly share code, notes, and snippets.

@sebnyberg
Created September 21, 2021 21:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sebnyberg/2b83d86d8bc4f2fa46c6ca3f2f6ab6f4 to your computer and use it in GitHub Desktop.
Save sebnyberg/2b83d86d8bc4f2fa46c6ca3f2f6ab6f4 to your computer and use it in GitHub Desktop.
Create Kubernetes certs using openssl
#!/local/bin/env bash
#
# Create certs
#
set -eux
# Create Root CA cert
ca="rootca"
cat > $ca.conf << EOM
[ req ]
encrypt_key = no
prompt = no
utf8 = yes
default_md = sha256
default_bits = 4096
req_extensions = req_ext
x509_extensions = req_ext
distinguished_name = req_dn
[ req_ext ]
subjectKeyIdentifier = hash
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, keyCertSign
[ req_dn ]
O = Your Organization
CN = Root CA
EOM
openssl genrsa -out out/$ca-key.pem 4096
openssl req -new -key out/$ca-key.pem -config $ca.conf -out out/$ca.csr
openssl x509 -req -days 3650 \
-signkey out/$ca-key.pem \
-extensions req_ext -extfile $ca.conf \
-in out/$ca.csr -out out/$ca.pem
# Verify key and cert
openssl rsa -noout -text -in out/$ca-key.pem
openssl x509 -noout -text -in out/$ca.pem
# Create Intermediary Cluster Cert
clusterca="mycluster"
cat > $ca.conf << EOM
[ req ]
encrypt_key = no
prompt = no
utf8 = yes
default_md = sha256
default_bits = 4096
req_extensions = req_ext
x509_extensions = req_ext
distinguished_name = req_dn
[ req_ext ]
subjectKeyIdentifier = hash
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, keyCertSign
subjectAltName = @san
[ san ]
DNS.1 = istiod.istio-system.svc
[ req_dn ]
O = Your Organization
CN = Some Cluster CA
L = clustername
EOM
openssl genrsa -out out/$clusterca-key.pem 4096
openssl req -new -config $clusterca.conf -key out/$clusterca-key.pem -out out/$clusterca.csr
openssl x509 -req -days 1825 \
-CA out/$ca.pem -CAkey out/$ca-key.pem -CAcreateserial \
-extensions req_ext -extfile $clusterca.conf \
-in out/$clusterca.csr -out out/$clusterca.pem
# Concatenate CA certs into a chain
cat out/$clusterca.pem out/$ca.pem > out/chain.pem
# Verify key and cert
openssl rsa -noout -text -in out/$clusterca-key.pem
openssl x509 -noout -text -in out/$clusterca.pem
openssl verify -CAfile out/$ca.pem out/$clusterca.pem
# Create Service cert
svc="myservice"
cat > $svc.conf << EOM
[ req ]
encrypt_key = no
prompt = no
utf8 = yes
default_md = sha256
default_bits = 4096
req_extensions = req_ext
x509_extensions = req_ext
distinguished_name = req_dn
[ req_ext ]
subjectKeyIdentifier = hash
basicConstraints = critical, CA:false
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName=@san
[ san ]
DNS.1 = yourwebsite.example.com
DNS.2 = localhost
[ req_dn ]
O = Your Organization
CN = yourwebsite.example.com
L = Your Service
EOM
openssl genrsa -out out/$svc-key.pem 4096
openssl req -new -config $svc.conf -key out/$svc-key.pem -out out/$svc.csr
openssl x509 -req -days 365 \
-CA out/chain.pem -CAkey out/$clusterca-key.pem -CAcreateserial \
-extensions req_ext -extfile $svc.conf \
-in out/$svc.csr -out out/$svc.pem
# Create client cert (identical to previous)
client="myclient"
cat > $client.conf << EOM
[ req ]
encrypt_key = no
prompt = no
utf8 = yes
default_md = sha256
default_bits = 4096
req_extensions = req_ext
x509_extensions = req_ext
distinguished_name = req_dn
[ req_ext ]
subjectKeyIdentifier = hash
basicConstraints = critical, CA:false
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName=@san
[ san ]
DNS.1 = localhost
[ req_dn ]
O = Your Organization
CN = Some Client
EOM
openssl genrsa -out out/$client-key.pem 4096
openssl req -new -config $client.conf -key out/$client-key.pem -out out/$client.csr
openssl x509 -req -days 365 \
-CA out/chain.pem -CAkey out/$clusterca-key.pem -CAcreateserial \
-extensions req_ext -extfile $client.conf \
-in out/$client.csr -out out/$client.pem
@sebnyberg
Copy link
Author

sebnyberg commented Nov 22, 2021

#!/usr/bin/env bash

set -eux

vault="myvault"
clusterca="mycluster"
rootca="myroot"
client="myclient"
domains="domain1,domain1"

# Download key and cert as DER ASN.1 PCKS12
# Note the worst flag in the history of CLIs: --encoding=base64, this makes the
# result NOT be base64
az keyvault secret download \
    --file $clusterca.pfx \
    --vault-name $vault \
    --name $clusterca \
    --encoding=base64

# Download root CA (PEM/base64)
az keyvault certificate download \
    --file $rootca.pem \
    --name $rootca \
    --vault-name $vault

# Extract cert pem from secret
openssl pkcs12 -in "${clusterca}.pfx" -nodes -out "${clusterca}-bundle.pem"

# export cert from PEM bundle
openssl crl2pkcs7 -nocrl -certfile "${clusterca}-bundle.pem" \
    | openssl pkcs7 -print_certs -out "${clusterca}.pem"

# export key from PEM bundle
openssl pkey -in "${clusterca}-bundle.pem" -out "${clusterca}-key.pem"

# combine into cert chain
cat "${clusterca}.pem" "${rootca}.pem" > chain.pem

##################
# [...] issue client cert or something
##################
certmanager gen signed-cert \
    --ca-url "https://${vault}.vault.azure.net/secrets/${clusterca}" \
    --common-name $client \
    --domains "$domains"
mv "${client}.key" "${client}-key.pem"
mv "${client}.crt" "${client}.pem"

# Put all non-leaf certs into chain (root is not necessary)
# For this example, this is only the clusterca
openssl pkcs12 -export \
    -in "${client}.pem" \
    -inkey "${client}-key.pem" \
    -out "${client}.pfx"

# # upload client pfx to key vault
az keyvault certificate import \
    --vault-name $vault \
    -n $client \
    -f "${client}.pfx"

az keyvault secret download \
    --file "${client}.pfx" \
    --encoding base64 \
    --id "https://${vault}.vault.azure.net/secrets/${client}"

openssl pkcs12 -in "${client}.pfx" -nodes -out "${client}-bundle.pem"
openssl crl2pkcs7 -nocrl -certfile "${client}-bundle.pem" \
    | openssl pkcs7 -print_certs -out "${client}.pem"
openssl pkey -in "${client}-bundle.pem" -out "${client}-key.pem"

@sebnyberg
Copy link
Author

Get fingerprint of cert

openssl x509 -in cert.crt -noout -fingerprint

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment