You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
5.1 KiB

6 years ago
#!/bin/sh
# Filename: gencert.sh
6 years ago
# Description: This script generates x509 server certificate (with all IPs in
# SAN) signed by a self-signed CA.
6 years ago
# Version: 0.1 - 30 June 2018
# Author: Andrey Arapov <andrey.arapov@nixaid.com>
# License: GPLv3
ME=$(printf '%s\n' "${0##*/}")
6 years ago
print_help() {
printf "[${ME}] HELP: I accept following arguments:
6 years ago
--help - show this message
--cn - certificate's CN name\t\t(MANDATORY)
--key - server key name\t\t\t(default: private.key)
--cert - server cert name\t\t\t(default: public.crt)
--days - server cert expiration in days\t(default: 365)
--cakey - CA key name\t\t\t(default: ca.key)
--ca - CA cert name\t\t\t(default: ca.crt)
6 years ago
--cadays - CA cert expiration in days\t(default: 3650)\n"
6 years ago
}
# A POSIX variable
OPTIND=1 # Reset in case getopts has been used previously in the shell.
# read arguments
opts=$(getopt \
6 years ago
--longoptions "help,cn:,key:,cert:,days:,cakey:,ca:,cadays:," \
6 years ago
--name "$(basename "$0")" \
--options "" \
-- "$@"
)
eval set --$opts
6 years ago
while [ $# -gt 0 ]; do
6 years ago
case "$1" in
--help)
print_help;
exit 0
;;
--cn)
ARG_CN=$2
shift 2
;;
--key)
ARG_KEY=$2
shift 2
;;
--cert)
ARG_CERT=$2
shift 2
;;
--days)
ARG_DAYS=$2
shift 2
;;
--cakey)
ARG_CAKEY=$2
shift 2
;;
--ca)
ARG_CA=$2
shift 2
;;
--cadays)
ARG_CADAYS=$2
shift 2
;;
*)
break
;;
esac
done
if [ -z "${ARG_CN}" ]; then
echo "[${ME}] ERROR: Please specify CN, example \"--cn your.site.com\""
print_help;
exit 1
fi
# For debugging purposes
# echo ARG_CN=$ARG_CN
# echo ARG_KEY=$ARG_KEY
# echo ARG_CERT=$ARG_CERT
# echo ARG_DAYS=$ARG_DAYS
# echo ARG_CAKEY=$ARG_CAKEY
# echo ARG_CA=$ARG_CA
# echo ARG_CADAYS=$ARG_CADAYS
OPENSSL_CONFIG="openssl.cnf"
CA_KEY="${ARG_CAKEY:-ca.key}"
CA_CERT="${ARG_CA:-ca.crt}"
CA_DAYS="${ARG_CADAYS:-3650}"
SERVER_KEY="${ARG_KEY:-private.key}"
SERVER_CERT="${ARG_CERT:-public.crt}"
DAYS="${ARG_DAYS:-365}"
# set -x
set -e
6 years ago
gen_openssl_config() {
6 years ago
OPENSSL_CONFIG_CONTENT="[ req ]
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_ca ]
basicConstraints = critical, CA:TRUE
keyUsage = critical, digitalSignature, keyEncipherment, keyCertSign
[ v3_req_server ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[ alt_names ]"
# Gather IPs for SAN
i=1
IPS="$(getent ahostsv4 $(hostname) | awk '{print $1}' |sort | uniq)"
echo "[${ME}] Found these IPs: " ${IPS}
PAYLOAD="$(for IP in $IPS; do echo "IP.${i} = ${IP}" ; i=$((i + 1)); done)"
6 years ago
printf "${OPENSSL_CONFIG_CONTENT}\n${PAYLOAD}\n" > "${OPENSSL_CONFIG}"
6 years ago
}
6 years ago
gen_ca() {
6 years ago
echo "[${ME}] Generating new CA: ${CA_KEY} / ${CA_CERT} ..."
6 years ago
openssl ecparam -name prime256v1 -genkey -noout -out "${CA_KEY}"
6 years ago
chmod 0600 "${CA_KEY}"
openssl req -x509 -new -sha256 -nodes -key "${CA_KEY}" -days "${CA_DAYS}" -out "${CA_CERT}" \
6 years ago
-subj "/CN=my-CA" -extensions v3_ca -config "${OPENSSL_CONFIG}"
6 years ago
}
6 years ago
gen_server_x509() {
6 years ago
echo "[${ME}] Generating new server x509: ${SERVER_KEY} / ${SERVER_CERT} ..."
6 years ago
openssl ecparam -name prime256v1 -genkey -noout -out "${SERVER_KEY}"
6 years ago
chmod 0600 "${SERVER_KEY}"
openssl req -new -sha256 -key "${SERVER_KEY}" -subj "/CN=${ARG_CN}" \
| openssl x509 -req -sha256 -CA "${CA_CERT}" -CAkey "${CA_KEY}" -CAcreateserial \
-out ${SERVER_CERT} -days "${DAYS}" \
6 years ago
-extensions v3_req_server -extfile "${OPENSSL_CONFIG}"
6 years ago
}
6 years ago
install_openssl() {
set +e
6 years ago
type openssl >/dev/null 2>&1
6 years ago
if [ $? -eq 0 ]; then
6 years ago
return;
fi
6 years ago
if [ -f /etc/debian_version ]; then
echo "[${ME}] Installing openssl in Debian/Ubuntu"
6 years ago
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get -y install openssl
6 years ago
elif [ -f /etc/alpine-release ]; then
echo "[${ME}] Installing openssl in Alpine"
apk add --update openssl
elif [ -f /etc/centos-release ]; then
echo "[${ME}] Installing openssl in CentOS"
yum -y install openssl
fi
type openssl >/dev/null
if [ $? -ne 0 ]; then
echo "[${ME}] ERROR: Could not install openssl. Exitting."
exit 1
6 years ago
fi
6 years ago
set -e
6 years ago
}
6 years ago
start() {
6 years ago
echo "[${ME}] Started in ${PWD} directory."
6 years ago
install_openssl;
6 years ago
gen_openssl_config;
if [ ! -f "${CA_KEY}" ]; then
echo "[${ME}] Could not find ${CA_KEY} file so I will generate a new one."
gen_ca;
fi
6 years ago
openssl x509 -in "${CA_CERT}" -noout -checkend 2592000 >/dev/null
if [ $? -ne 0 ]; then
6 years ago
echo "[${ME}] WARNING! Your CA certificate will expire in less than 30 days."
fi
6 years ago
openssl x509 -in "${CA_CERT}" -noout -checkend 1 >/dev/null
if [ $? -ne 0 ]; then
6 years ago
echo "[${ME}] WARNING! Your CA certificate has expired, so we will generate a new one."
gen_ca;
fi
# Generate a new server certificate with the detected IPs.
gen_server_x509;
echo "[${ME}] The certificates have been generated in ${PWD} directory."
CERT_INFO="$(openssl x509 -in "${SERVER_CERT}" -noout -text)"
echo "${CERT_INFO}" | grep -E "CN=|IP Address|Not\ "
}
start;