add gencert 0.1
This commit is contained in:
parent
88130f8a0f
commit
86e662e286
237
gencert.sh
Executable file
237
gencert.sh
Executable file
@ -0,0 +1,237 @@
|
||||
#!/bin/sh
|
||||
# Filename: gencert.sh
|
||||
# Description: generates self-signed x509 with CA and IPs in SAN
|
||||
# Version: 0.1 - 30 June 2018
|
||||
# Author: Andrey Arapov <andrey.arapov@nixaid.com>
|
||||
# License: GPLv3
|
||||
#
|
||||
# Purpose
|
||||
# - This script will always produce a self-signed x509 certificate in the
|
||||
# current path with the IP addresses embedded to x509's SAN.
|
||||
# It will also produce a CA certificate and can be used by other services
|
||||
# which may need to authenticate against this self-signed certificate.
|
||||
# The authentication works in a way that a public CA certificate will be
|
||||
# used by the client in order to validate the server's certificate.
|
||||
#
|
||||
# Application
|
||||
# Backend requiring x509 running behind reverse proxy
|
||||
# - This script has been created in order to ease the Minio's SSE-C
|
||||
# (Server Side Encryption - Customer provided keys) enablement when
|
||||
# Minio server is running as a backend behind a reverse proxy like Traefik.
|
||||
# Minio server enables SSE-C only when it detects the x509 certificates.
|
||||
# Traefik running with docker service provider talks to the backend using
|
||||
# the IP. The IP usually is not static, hence this script comes handy.
|
||||
#
|
||||
# Example usage
|
||||
# Minio server with Traefik example
|
||||
# 1. Replace "minio server" command with the following one:
|
||||
# - "cd /root/.minio/certs && ./gencert.sh --cn minio.example.com && minio server"
|
||||
# 2. Copy the CA certificate "ca.crt" file to "/usr/local/share/ca-certificates/" and
|
||||
# run "update-ca-certificates" command which will update
|
||||
# "/etc/ssl/certs/ca-certificates.crt" file.
|
||||
# 3. Restart Traefik.
|
||||
#
|
||||
# NOTE: Steps 2. and 3. will need to be repeated each time you get a new CA
|
||||
# certificate. Then they can be automated this way:
|
||||
# - Start Traefik with this command:
|
||||
# sh -c "update-ca-certificates && traefik"
|
||||
# while "/usr/local/share/ca-certificates" path is a host mounted
|
||||
# path with the CA certificate produced by this script.
|
||||
# NOTE: I am using Alpine Traefik image, the correct ca certificates path is
|
||||
# "/usr/local/share/ca-certificates/", otherwise one of these
|
||||
# https://golang.org/src/crypto/x509/root_linux.go
|
||||
#
|
||||
# Script logic
|
||||
# - generate CA cert if does not find any.
|
||||
# - always generate server cert on startup to ensure all IP addresses are in
|
||||
# x509 SAN.
|
||||
# - warn if the CA cert about to expire (<30 days till expiration).
|
||||
# - regenerate the CA cert if it finds it has expired.
|
||||
#
|
||||
# Notes
|
||||
# - The CA cert will be valid for 3650 days (10 years).
|
||||
# - The server cert will be valid for 365 days (1 year).
|
||||
# - The x509 certs are ECDSA with prime256v1 curve and SHA256 signatures.
|
||||
|
||||
ME=$(printf '%s\n' "${0##*/}")
|
||||
|
||||
function print_help() {
|
||||
echo -e "[${ME}] HELP: I accept following arguments:
|
||||
--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)
|
||||
--cadays - CA cert expiration in days\t(default: 3650)"
|
||||
}
|
||||
|
||||
# A POSIX variable
|
||||
OPTIND=1 # Reset in case getopts has been used previously in the shell.
|
||||
|
||||
ARGUMENT_LIST=(
|
||||
"cn"
|
||||
"key"
|
||||
"cert"
|
||||
"days"
|
||||
"cakey"
|
||||
"ca"
|
||||
"cadays"
|
||||
)
|
||||
|
||||
# read arguments
|
||||
opts=$(getopt \
|
||||
--longoptions "help,$(printf "%s:," "${ARGUMENT_LIST[@]}")" \
|
||||
--name "$(basename "$0")" \
|
||||
--options "" \
|
||||
-- "$@"
|
||||
)
|
||||
|
||||
eval set --$opts
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
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
|
||||
|
||||
function gen_openssl_config() {
|
||||
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)"
|
||||
|
||||
echo -e "${OPENSSL_CONFIG_CONTENT}\n${PAYLOAD}" > "${OPENSSL_CONFIG}"
|
||||
}
|
||||
|
||||
function gen_ca() {
|
||||
echo "[${ME}] Generating new CA: ${CA_KEY} / ${CA_CERT} ..."
|
||||
openssl ecparam -name prime256v1 -genkey -noout -out "${CA_KEY}" 2>/dev/null
|
||||
chmod 0600 "${CA_KEY}"
|
||||
openssl req -x509 -new -sha256 -nodes -key "${CA_KEY}" -days "${CA_DAYS}" -out "${CA_CERT}" \
|
||||
-subj "/CN=my-CA" -extensions v3_ca -config "${OPENSSL_CONFIG}" 2>/dev/null
|
||||
}
|
||||
|
||||
function gen_server_x509() {
|
||||
echo "[${ME}] Generating new server x509: ${SERVER_KEY} / ${SERVER_CERT} ..."
|
||||
openssl ecparam -name prime256v1 -genkey -noout -out "${SERVER_KEY}" 2>/dev/null
|
||||
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}" \
|
||||
-extensions v3_req_server -extfile "${OPENSSL_CONFIG}" 2>/dev/null
|
||||
}
|
||||
|
||||
function start() {
|
||||
echo "[${ME}] Started in ${PWD} directory."
|
||||
|
||||
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
|
||||
|
||||
if ! openssl x509 -in "${CA_CERT}" -noout -checkend 2592000; then
|
||||
echo "[${ME}] WARNING! Your CA certificate will expire in less than 30 days."
|
||||
fi
|
||||
|
||||
if ! openssl x509 -in "${CA_CERT}" -noout -checkend 1; then
|
||||
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;
|
Loading…
Reference in New Issue
Block a user