Skip to content

Instantly share code, notes, and snippets.

@M0r13n
Created February 11, 2023 14:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save M0r13n/409abd1df5a136b2da390babee8ec422 to your computer and use it in GitHub Desktop.
Save M0r13n/409abd1df5a136b2da390babee8ec422 to your computer and use it in GitHub Desktop.
Bash script to create a certificate signing request (CSR).
#!/usr/bin/env bash
set -e
# ------------------------------------------------------------------------------
# This script will generate a new private key and a Certificate Signing Request
# (CSR) using OpenSSL.
# This script is non-interactive. Instead it uses the variables set at the
# beginning of this script.
# ------------------------------------------------------------------------------
# REPLACE TO MATCH A GIVEN SYSTEM/SERVICE
COMMONNAME="leonmortenrichter.de" # Domain name, e.g. "example.com"
ORGANIZATION="Foo Bar" # Company name
UNIT="Foo Unit" # Organizational unit name
LOCALITY="Kiel" # City
STATE="Schleswig Holstein" # State
COUNTRY="DE" # 2 letter code,("GB", "US", "DE")
ALT_NAMES=("192.0.2.1") # Optional number of alternatives names (e.g. IP)
# ------------------------------------------------------------------------------
# DO NOT CHANGE (unless you know what to do)
# ------------------------------------------------------------------------------
YEAR=$(date +"%Y")
DATE=$(date +"%Y-%m-%d")
TARGET_DIR="${COMMONNAME}/${DATE}"
PRIVATE_KEY_FILE="${TARGET_DIR}/${COMMONNAME}_${YEAR}.key"
CERT_SIGN_REQUEST_FILE="${TARGET_DIR}/${COMMONNAME}_${YEAR}.csr"
ALTERNATE_NAMES=""
# Iterate over all alternate names and build the [alt_names] section
i=3 # Start with 3, because 1 and 2 are already used by the common name
for altName in "${ALT_NAMES[@]}"; do
ALTERNATE_NAMES+="DNS.${i} = ${altName}"$'\n'
((i++))
done
cat <<EOF > .temp-openssl-config
[req]
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no
[req_distinguished_name]
countryName = ${COUNTRY}
stateOrProvinceName = ${STATE}
localityName = ${LOCALITY}
organizationalUnitName = ${UNIT}
organizationName = ${ORGANIZATION}
commonName = ${COMMONNAME}
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = ${COMMONNAME}
${ALTERNATE_NAMES}
EOF
trap 'rm -f .temp-openssl-config' EXIT
if [ -d "${TARGET_DIR}" ]; then
echo "Target directory already exists: ${TARGET_DIR}"
echo "Remove or rename it before you try again."
exit 1
fi
mkdir -p "${TARGET_DIR}"
openssl genrsa -out "${PRIVATE_KEY_FILE}" 4096
openssl req -new -key "${PRIVATE_KEY_FILE}" -out "${CERT_SIGN_REQUEST_FILE}" -config .temp-openssl-config
# Check
M_RSA=$(openssl rsa -noout -modulus -in "${PRIVATE_KEY_FILE}")
M_REQ=$(openssl req -noout -modulus -in "${CERT_SIGN_REQUEST_FILE}")
if [ "${M_RSA}" != "${M_REQ}" ]; then
echo "Something went wrong. Private key and CSR files don't match."
exit 1
fi
echo "Done. The following files were generated:"
echo ""
echo " 1. Private key:"
echo " ${PRIVATE_KEY_FILE}"
echo " > Keep this file safe. It will be required on the web server."
echo ""
echo " 2. Certificate Signing Request (CSR):"
echo " ${CERT_SIGN_REQUEST_FILE}"
echo " > Submit this file to the SSL certificate provider."
echo ""
echo "To see the decoded contents of the CSR file, run the following command:"
echo " openssl req -verify -noout -text -in ${CERT_SIGN_REQUEST_FILE}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment