forked from kserve/kserve
-
Notifications
You must be signed in to change notification settings - Fork 0
/
self-signed-ca.sh
executable file
·158 lines (144 loc) · 6.12 KB
/
self-signed-ca.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/bin/bash
set -e
usage() {
cat <<EOF
Generate certificate suitable for use with an KFServing webhook service.
This script uses openssl to generate self-signed CA certificate that is
suitable for use with KFServing webhook services. See
https://kubernetes.io/docs/concepts/cluster-administration/certificates/#distributing-self-signed-ca-certificate
for detailed explantion and additional instructions.
The server key/cert CA cert are stored in a k8s secret.
usage: ${0} [OPTIONS]
The following flags are optional.
--service Service name of webhook. Default: kfserving-webhook-server-service
--namespace Namespace where webhook service and secret reside. Default: kfserving-system
--secret Secret name for CA certificate and server certificate/key pair. Default: kfserving-webhook-server-cert
--webhookName Name for the mutating and validating webhook config. Default: inferenceservice.serving.kubeflow.org
--webhookDeployment Statefulset name of the webhook controller. Default: kfserving-controller-manager
EOF
exit 1
}
while [[ $# -gt 0 ]]; do
case ${1} in
--service)
service="$2"
shift
;;
--secret)
secret="$2"
shift
;;
--namespace)
namespace="$2"
shift
;;
--webhookName)
webhookName="$2"
shift
;;
--webhookDeployment)
webhookDeployment="$2"
shift
;;
*)
usage
;;
esac
shift
done
[ -z ${secret} ] && secret=kfserving-webhook-server-cert
[ -z ${namespace} ] && namespace=kfserving-system
[ -z ${webhookDeployment} ] && webhookDeployment=kfserving-controller-manager
[ -z ${webhookName} ] && webhookName=inferenceservice.serving.kubeflow.org
[ -z ${service} ] && service=kfserving-webhook-server-service
webhookDeploymentName=${webhookDeployment}-0
webhookConfigName=${webhookName}
echo service: ${service}
echo namespace: ${namespace}
echo secret: ${secret}
echo webhookDeploymentName: ${webhookDeploymentName}
echo webhookConfigName: ${webhookConfigName}
if [ ! -x "$(command -v openssl)" ]; then
echo "openssl not found"
exit 1
fi
tmpdir=$(mktemp -d)
echo "creating certs in tmpdir ${tmpdir} "
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
DNS.5 = ${service}.${namespace}.svc.cluster.local
EOF
# Create CA and Server key/certificate
openssl genrsa -out ${tmpdir}/ca.key 2048
openssl req -x509 -newkey rsa:2048 -key ${tmpdir}/ca.key -out ${tmpdir}/ca.crt -days 365 -nodes -subj "/CN=${service}.${namespace}.svc"
openssl genrsa -out ${tmpdir}/server.key 2048
openssl req -new -key ${tmpdir}/server.key -subj "/CN=${service}.${namespace}.svc" -out ${tmpdir}/server.csr -config ${tmpdir}/csr.conf
# Self sign
openssl x509 -extensions v3_req -req -days 365 -in ${tmpdir}/server.csr -CA ${tmpdir}/ca.crt -CAkey ${tmpdir}/ca.key -CAcreateserial -out ${tmpdir}/server.crt -extfile ${tmpdir}/csr.conf
# create the secret with server cert/key
kubectl create secret generic ${secret} \
--from-file=tls.key=${tmpdir}/server.key \
--from-file=tls.crt=${tmpdir}/server.crt \
--dry-run -o yaml |
kubectl -n ${namespace} apply -f -
# Webhook pod needs to be restarted so that the service reload the secret
# http://github.com/kueflow/kubeflow/issues/3227
webhookPod=$(kubectl get pods -n ${namespace} |grep ${webhookDeploymentName} |awk '{print $1;}')
# ignore error if webhook pod does not exist
kubectl delete pod ${webhookPod} -n ${namespace} 2>/dev/null || true
echo "webhook ${webhookPod} is restarted to utilize the new secret"
echo "CA Certificate:"
cat ${tmpdir}/ca.crt
# -a means base64 encode
caBundle=$(cat ${tmpdir}/ca.crt | openssl enc -a -A)
echo "Encoded CA:"
echo -e "${caBundle} \n"
# check if jq is installed
if [ ! -x "$(command -v jq)" ]; then
echo "jq not found"
exit 1
fi
# Patch CA Certificate to mutatingWebhook
mutatingWebhookCount=$(kubectl get mutatingwebhookconfiguration ${webhookConfigName} -ojson | jq -r '.webhooks' | jq length)
# build patchstring based on webhook counts
mutatingPatchString='['
for i in $(seq 0 $(($mutatingWebhookCount-1)))
do
mutatingPatchString=$mutatingPatchString'{"op": "replace", "path": "/webhooks/'$i'/clientConfig/caBundle", "value":"{{CA_BUNDLE}}"}, '
done
# strip ', '
mutatingPatchString=${mutatingPatchString%, }']'
mutatingPatchString=$(echo ${mutatingPatchString} | sed "s|{{CA_BUNDLE}}|${caBundle}|g")
echo "patching ca bundle for mutating webhook configuration..."
kubectl patch mutatingwebhookconfiguration ${webhookConfigName} \
--type='json' -p="${mutatingPatchString}"
# Patch CA Certificate to validatingWebhook
validatingWebhookCount=$(kubectl get validatingwebhookconfiguration ${webhookConfigName} -ojson | jq -r '.webhooks' | jq length)
validatingPatchString='['
for i in $(seq 0 $(($validatingWebhookCount-1)))
do
validatingPatchString=$validatingPatchString'{"op": "replace", "path": "/webhooks/'$i'/clientConfig/caBundle", "value":"{{CA_BUNDLE}}"}, '
done
validatingPatchString=${validatingPatchString%, }']'
validatingPatchString=$(echo ${validatingPatchString} | sed "s|{{CA_BUNDLE}}|${caBundle}|g")
echo "patching ca bundle for validating webhook configuration..."
kubectl patch validatingwebhookconfiguration ${webhookConfigName} \
--type='json' -p="${validatingPatchString}"
echo "patching ca bundler for conversion webhook configuration.."
conversionPatchString='[{"op": "replace", "path": "/spec/conversion/webhook/clientConfig/caBundle", "value":"{{CA_BUNDLE}}"}]'
conversionPatchString=$(echo ${conversionPatchString} | sed "s|{{CA_BUNDLE}}|${caBundle}|g")
kubectl patch CustomResourceDefinition inferenceservices.serving.kubeflow.org \
--type='json' -p="${conversionPatchString}"