-
Notifications
You must be signed in to change notification settings - Fork 78
/
keygen
executable file
·106 lines (87 loc) · 3.13 KB
/
keygen
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
#!/bin/bash
set -e
_CMD=$0
show_help() {
cat <<EOF
Usage: ${_CMD} [--help]
Generate self-signed certificate and JWT authentication keys for the Mender server.
Environment variables:
CERT_CN - Certificate common name
CERT_SAN - Comma separated list of certificate subject alternative names (SANs)
See openssl-req(1)
EOF
}
while [ $# -gt 0 ]; do
case ${1} in
--help)
show_help
exit 0
break;;
*)
echo 'Unrecognized commandline argument "'${1}'"'
show_help
exit 1
break;;
esac
shift 1
done
# Verify dependencies
CLI_COMMANDS="cut sed sort head"
for cmd in ${CLI_COMMANDS}; do
command -v ${cmd} &>/dev/null || { echo >&2 "ERROR: Please install the '${cmd}' utility to generate key configuration."; exit 1; }
done
# verify openssl is present and sufficiently recent (genpkey seems to require openssl 1.1.1+)
OPENSSL_VERSION_MINIMAL="1.1.1"
command -v openssl >/dev/null 2>&1 || { echo >&2 "ERROR: Please install the openssl utility version ${OPENSSL_VERSION_MINIMAL} or newer to generate keys."; exit 1; }
OPENSSL_VERSION=$(openssl version | cut -d' ' -f2 | sed 's~[a-z]~~g')
if [[ "${OPENSSL_VERSION_MINIMAL}" != "$(printf "${OPENSSL_VERSION_MINIMAL}\n${OPENSSL_VERSION}" | sort -V | head -n 1)" ]]; then
echo "ERROR: openssl version '${OPENSSL_VERSION}' is too old, need version ${OPENSSL_VERSION_MINIMAL} or newer"
exit 1
fi
if [ -z "${CERT_CN}" ]; then
echo "Common name (CERT_CN) not set."
echo -n "Enter a certificate common name [docker.mender.io]:"
IFS='' read -r CERT_CN
if [ -z "${CERT_CN}" ]; then
CERT_CN="docker.mender.io"
fi
fi
if [ -z "${CERT_SAN}" ]; then
CERT_SAN="DNS:${CERT_CN},DNS:*.${CERT_CN}"
echo "Subject alternative name (CERT_SAN) not set, using default:"
echo " CERT_SAN=\"${CERT_SAN}\""
fi
CERT_VALID_DAYS="3650"
FILE_NAME_PRIVATE_KEY="private.key"
FILE_NAME_CERT="cert.crt"
ROOTDIR=$(pwd)/keys-generated
CERTDIR=${ROOTDIR}/cert
KEYDIR=${ROOTDIR}/keys
# generate web cert and corresponding private key
mkdir -p "${CERTDIR}"
cd "${CERTDIR}"
openssl req -x509 -sha256 -nodes \
-days ${CERT_VALID_DAYS} \
-newkey ec:<(openssl ecparam -name prime256v1) \
-keyout ${FILE_NAME_PRIVATE_KEY} \
-out ${FILE_NAME_CERT} \
-subj "/CN=${CERT_CN}" \
-addext "extendedKeyUsage = serverAuth" \
-addext "subjectAltName = ${CERT_SAN}"
# generate keys for signing JSON Web Tokens
mkdir -p "${KEYDIR}"
cd "${KEYDIR}"
for DIR in deviceauth useradm
do
mkdir -p ${DIR}
(
cd ${DIR}
openssl genpkey -algorithm RSA -out ${FILE_NAME_PRIVATE_KEY} -pkeyopt rsa_keygen_bits:3072
# convert to RSA private key format, otherwise services complain:"
# level=fatal msg="failed to read rsa private key: jwt: can't open key - not an rsa private key" file=proc.go func=runtime.main line=183
openssl rsa -in ${FILE_NAME_PRIVATE_KEY} -out ${FILE_NAME_PRIVATE_KEY}
)
done
echo "All Mender Server keys and certificates have been generated in directory ${ROOTDIR}."
echo "Please include them in your docker compose and device builds."
echo "For more information, please refer to https://docs.mender.io/"