Created
February 16, 2022 16:33
-
-
Save amigus/b4e6e642f88e756be1996e44a1c35349 to your computer and use it in GitHub Desktop.
A bash script that requests and approves a certificate from a Kubernetes cluster.
This file contains 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/sh | |
program=$(basename $0) | |
DEFAULT_NAMESPACE="default" | |
DEFAULT_DIRECTORY=. | |
DEFAULT_BITS=2048 | |
usage() { | |
cat<<EOF | |
Usage: ${program} -n NAME [OPTIONS]... | |
-n, -name, --name NAME | |
Maps to the host portion of the FQDN that is the subject of the | |
certificate; also the basename of the certificate and key files. | |
-d, -directory, --directory=DIRECTORY | |
The location of the resulting certificate and private-key. The | |
default is '${DEFAULT_DIRECTORY}' | |
-N, -namespace, --namespace=NAMESPACE | |
Represents the Kubernetes cluster Namespace and maps to the | |
domain of the FQDN that is the subject of the certificate. | |
the default is '${DEFAULT_NAMESPACE}' | |
-b, -bits, --bits=BITS | |
the RSA key size in bits; default is ${DEFAULT_BITS} | |
EOF | |
} | |
options=$(getopt -l "bits:,directory:,name:,namespace:" -o "b:d:n:N:" -a -n "${program}" -- "$@") | |
test $? -ne 0 && usage && exit 1 | |
eval set -- ${options} | |
while true | |
do | |
case "${1}" in | |
--name|-n) | |
shift | |
name="${1}" | |
;; | |
--namespace|-N) | |
shift | |
namespace="${1}" | |
;; | |
--bits|-b) | |
shift | |
bits="${1}" | |
;; | |
--directory|-d) | |
shift | |
directory="${1}" | |
;; | |
--) | |
shift | |
break | |
;; | |
*) | |
usage | |
exit 1 | |
;; | |
esac | |
shift | |
done | |
if test -z "${name}" | |
then | |
usage | |
exit 1 | |
fi | |
test -z "${bits}" && bits=${DEFAULT_BITS} | |
test -z "${directory}" && directory=${DEFAULT_DIRECTORY} | |
test -z "${namespace}" && namespace=${DEFAULT_NAMESPACE} | |
fqdn="${name}.${namespace}.svc" | |
kubectl=$(which kubectl) | |
if test $? -ne 0 | |
then | |
echo "${program}: unable to locate kubectl executable; exiting" | |
exit 1 | |
fi | |
openssl=$(which openssl) | |
if test $? -ne 0 | |
then | |
echo "${program}: unable to locate openssl executable; exiting" | |
exit 1 | |
fi | |
cd "${directory}" | |
"${openssl}" genrsa -out "${name}.key" ${bits} 2> /dev/null | |
csr_conf=`mktemp -t dsv-csr.XXXXXX` | |
trap 'rm "${csr_conf}"; exit' SIGINT SIGTERM EXIT | |
cat >"${csr_conf}"<<EOF | |
[req] | |
default_bits = ${DEFAULT_BITS} | |
distinguished_name = dn | |
prompt = no | |
req_extensions = ext | |
[dn] | |
organizationName = system:nodes | |
commonName = system:node:${fqdn} | |
[ext] | |
basicConstraints = CA:FALSE | |
keyUsage = digitalSignature, keyEncipherment, nonRepudiation | |
extendedKeyUsage = serverAuth | |
subjectAltName = @sans | |
[sans] | |
DNS.1 = ${name} | |
DNS.2 = ${name}.${namespace} | |
DNS.3 = ${fqdn} | |
EOF | |
"${openssl}" req -new -key "${name}.key" -out "${name}.csr"\ | |
-config "${csr_conf}" > /dev/null | |
"${kubectl}" delete csr --ignore-not-found=true "${fqdn}" > /dev/null | |
"${kubectl}" create -f - <<EOF > /dev/null | |
apiVersion: certificates.k8s.io/v1 | |
kind: CertificateSigningRequest | |
metadata: | |
name: ${fqdn} | |
spec: | |
signerName: kubernetes.io/kubelet-serving | |
groups: | |
- system:authenticated | |
request: $(cat "${name}.csr" | base64 | tr -d '\n') | |
usages: | |
- digital signature | |
- key encipherment | |
- server auth | |
EOF | |
retries=0 | |
while :; do | |
"${kubectl}" get csr "${fqdn}" > /dev/null | |
test "$?" -eq 0 && break | |
if test $retries -gt 9 | |
then | |
echo "no csr after ${retries} seconds; exiting" | |
exit 1 | |
else | |
let retries=retries+1 | |
fi | |
sleep 1 | |
done | |
"${kubectl}" certificate approve "${fqdn}" > /dev/null | |
retries=0 | |
while :; do | |
cert=$("${kubectl}" get csr ${fqdn} -o jsonpath='{.status.certificate}') | |
test -n "${cert}" && break | |
if test $retries -gt 9 | |
then | |
echo "no certificate after ${retries} seconds; exiting" | |
exit 1 | |
else | |
let retries=retries+1 | |
fi | |
sleep 1 | |
done | |
echo ${cert} | "${openssl}" base64 -d -A -out "${name}.pem" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment