Skip to content

Instantly share code, notes, and snippets.

@ploegert
Created October 19, 2021 16:26
Show Gist options
  • Save ploegert/c23f25afde410b6d20d54dcf83aa06c4 to your computer and use it in GitHub Desktop.
Save ploegert/c23f25afde410b6d20d54dcf83aa06c4 to your computer and use it in GitHub Desktop.
#!/bin/bash
#=============================================================#
# Name: CertGenerator #
# Description: Create a self-signed SSL Certificates #
# Author: justin.j.ploegert@jci.com #
# USAGE: #
# chmod +x ./certGen.sh
#===================================================================
# To Generate certificate with specified password in a pfx
# and save to a work folder
# sudo ./certGen.sh -d "CertGen" -p "localhost" -s "PASSWORD"
#===================================================================
# To clean the work folder
# sudo ./certGen.sh -d "CertGen" -c
#===================================================================
################## DECLARE FUNCTIONS ######################
# Exit on error. Append "|| true" if you expect an error.
set -o errexit
# Exit on error inside any functions or subshells.
set -o errtrace
# Do not allow use of undefined vars. Use ${VAR:-} to use an undefined VAR
# set -o nounset
# Catch the error in case mysqldump fails (but gzip succeeds) in `mysqldump |gzip`
set -o pipefail
# Turn on traces, useful while debugging but commented out by default
# set -o xtrace
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
__i_am_main_script="0" # false
if [[ "${__usage+x}" ]]; then
if [[ "${BASH_SOURCE[1]}" = "${0}" ]]; then
__i_am_main_script="1" # true
fi
__b3bp_external_usage="true"
__b3bp_tmp_source_idx=1
fi
else
__i_am_main_script="1" # true
[[ "${__usage+x}" ]] && unset -v __usage
[[ "${__helptext+x}" ]] && unset -v __helptext
fi
# Set magic variables for current file, directory, os, etc.
__dir="$(cd "$(dirname "${BASH_SOURCE[${__b3bp_tmp_source_idx:-0}]}")" && pwd)"
__file="${__dir}/$(basename "${BASH_SOURCE[${__b3bp_tmp_source_idx:-0}]}")"
__base="$(basename "${__file}" .sh)"
# Define the environment variables (and their defaults) that this script depends on
LOG_LEVEL="${LOG_LEVEL:-6}" # 7 = debug -> 0 = emergency
NO_COLOR="${NO_COLOR:-}" # true = disable color. otherwise autodetected
#===========================================================================================
#Log to console
function __b3bp_log () {
local log_level="${1}"
shift
local action=""
local lineout="${1}"
if [ $# -ge 2 ] && [ -n "$2" ]; then
action="[${2}]"
fi
local color_green="\x1b[32m"
local color_success="\x1b[32m"
local color_debug="\x1b[35m"
local color_info="\x1b[36m"
local color_success="\x1b[36m"
local color_notice="\x1b[34m"
local color_warning="\x1b[33m"
local color_banner="\x1b[33m"
local color_error="\x1b[31m"
local color_critical="\x1b[1;31m"
local color_alert="\x1b[1;33;41m"
local color_emergency="\x1b[1;4;5;33;41m"
local colorvar="color_${log_level}"
local color="${!colorvar:-${color_error}}"
local color_reset="\x1b[0m"
if [[ "${NO_COLOR:-}" = "true" ]] || [[ "${TERM:-}" != "xterm"* ]] || [[ ! -t 2 ]]; then
if [[ "${NO_COLOR:-}" != "false" ]]; then # Don't use colors on pipes or non-recognized terminals
color=""; color_reset=""
fi
fi
if [[ "${log_level}" = "banner" ]]; then
echo -e "$(date -u +"%Y-%m-%d %H:%M:%S UTC") ${color}$(printf "[%-9s]%s %s " "" "${action}" "${lineout}")${color_reset}" 1>&2
elif [ "${log_level}" = "success" ]; then
printf "$(date -u +"%Y-%m-%d %H:%M:%S UTC") ${color}[%-9s][%s] ${color_green} ${lineout} ${color_reset}\n" ${log_level} ${action}
else
echo -e "$(date -u +"%Y-%m-%d %H:%M:%S UTC") ${color}$(printf "[%-9s]%s " "${log_level}" "${action}")${color_reset} ${lineout}" 1>&2
fi
}
function log_emergency () { __b3bp_log emergency "${@}"; exit 1; }
function log_alert () { [[ "${LOG_LEVEL:-0}" -ge 1 ]] && __b3bp_log alert "${@}"; true; }
function log_critical () { [[ "${LOG_LEVEL:-0}" -ge 2 ]] && __b3bp_log critical "${@}"; true; }
function log_error () { [[ "${LOG_LEVEL:-0}" -ge 3 ]] && __b3bp_log error "${@}"; true; }
function log_warning () { [[ "${LOG_LEVEL:-0}" -ge 4 ]] && __b3bp_log warning "${@}"; true; }
function log_notice () { [[ "${LOG_LEVEL:-0}" -ge 5 ]] && __b3bp_log notice "${@}"; true; }
function log_info () { [[ "${LOG_LEVEL:-0}" -ge 6 ]] && __b3bp_log info "${@}"; true; }
function log_debug () { [[ "${LOG_LEVEL:-0}" -ge 7 ]] && __b3bp_log debug "${@}"; true; }
function log_banner () { __b3bp_log banner "${@}"; true; }
function log_success () { __b3bp_log success "${@}"; true; }
#===========================================================================================
#Log to Syslog
log_syslog()
{
/usr/bin/logger $1
}
#===========================================================================================
# Check if script is being run as Root
checkRoot() {
FUNC="checkRoot"
log_banner "=========================================" $FUNC
log_banner "Checking if script is being run as root" $FUNC
if [ $(id -u) -ne 0 ]; then
log_error "Script must be run as root. Try 'sudo ./createSslCert.sh'\n" $FUNC
exit 1
else
log_success "Script is being executed as Root." $FUNC
fi
log_success "${FUNC} is complete." $FUNC;
}
#===========================================================================================
# Check which Distribution is being used
check_distro(){
FUNC="check_distro"
log_banner "=========================================" $FUNC
log_banner "Checking Linux Distribution" $FUNC
case "$OSTYPE" in
solaris*) distro="SOLARIS" ;;
darwin*) distro="OSX" ;;
linux*) distro="LINUX" ;;
bsd*) distro="BSD" ;;
msys*) distro="WINDOWS" ;;
*) distro="unknown: $OSTYPE" ;;
esac
log_info "Linux distribution ==>: ${distro}" $FUNC
declare -A osInfo;
osInfo[/etc/redhat-release]=yum
osInfo[/etc/arch-release]=pacman
osInfo[/etc/gentoo-release]=emerge
osInfo[/etc/SuSE-release]=zypp
osInfo[/etc/debian_version]=apt-get
for f in ${!osInfo[@]}
do
if [[ -f $f ]];then
pkgman=${osInfo[$f]}
fi
done
log_info "Package Manager ==>: ${pkgman}" $FUNC
log_success "${FUNC} is complete." $FUNC;
}
#===========================================================================================
# Supporting function to Check system package manager
check_sys(){
local FUNC="check_sys"
# banner "=========================================" $FUNC
# banner "Checking system Package Manager" $FUNC
local checkType=$1
local value=$2
local release=''
local systemPackage=''
if [[ -f /etc/redhat-release ]]; then
release="centos"
systemPackage="yum"
elif cat /etc/issue | grep -Eqi "debian"; then
release="debian"
systemPackage="apt"
elif cat /etc/issue | grep -Eqi "ubuntu"; then
release="ubuntu"
systemPackage="apt"
elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then
release="centos"
systemPackage="yum"
elif cat /proc/version | grep -Eqi "debian"; then
release="debian"
systemPackage="apt"
elif cat /proc/version | grep -Eqi "ubuntu"; then
release="ubuntu"
systemPackage="apt"
elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then
release="centos"
systemPackage="yum"
fi
if [[ ${checkType} == "sysRelease" ]]; then
if [ "$value" == "$release" ]; then
return 0
else
return 1
fi
elif [[ ${checkType} == "packageManager" ]]; then
if [ "$value" == "$systemPackage" ]; then
return 0
else
return 1
fi
fi
}
#===========================================================================================
# Install Dependencies for Creating a cert
installDependencies() {
local FUNC="installDeps"
log_banner "=========================================" $FUNC
log_banner "Installing Dependencies (OpenSSL)..." $FUNC
if check_sys packageManager yum; then
log_info "Executing yum install -y openssl" $FUNC
yum install -y openssl
log_success "done." $FUNC
log_info "Executing yum install -y jq" $FUNC
yum install -y jq
log_success "done." $FUNC
elif check_sys packageManager apt; then
log_info "Executing apt-get update -y" $FUNC
apt-get -y update
log_success "done." $FUNC
log_info "Executing apt-get install -y openssl" $FUNC
apt-get -y install openssl
log_success "done." $FUNC
log_info "Executing apt-get install -y jq" $FUNC
apt-get -y install jq
log_success "done." $FUNC
fi
log_success "${FUNC} is complete." $FUNC;
}
#===========================================================================================
#Check if package is installed
checkOpenSslVersion() {
local FUNC="check_sys"
log_banner "=========================================" $FUNC
log_banner "Checking which OpenSSL Version is installed..." $FUNC
# rpm -qa | grep -i openssl
# dpkg -l | grep -i openssl
# dpkg -s openssl | grep Version
# dpkg -s libssl1.0.0
log_info "Executing openssl version -a" $FUNC
openssl version -a
log_success "${FUNC} is complete." $FUNC;
}
#===========================================================================================
# Generate Self Signed Cert
# $1 = target Directory
# $2 = prefix
# $3 = password
genSelfSignedCert() {
FUNC="genSelfSignedCert"
log_banner "=========================================" $FUNC
log_banner "Generating new SSL Certs" $FUNC
if [ $# -gt 3 ] || [ $# -lt 3 ]; then
echo "Incorrect parameters passed" # If parameters no equal 2
fi
#Parameters
local targetDir="${1}"
local prefix="${2}"
local pass="${3}"
#Derived Parameters
local startDir=$(pwd)
local subject="/C=US/ST=WI/L=Milwaukee/O=Jci/CN=${prefix}"
local fullpath="${startDir}/${targetDir}"
local file_key="${prefix}.key"
local file_cert="${prefix}.cert"
local file_pfx="${prefix}.pfx"
local file_b64pfx="${prefix}.txt"
local file_pass="${prefix}-pass.txt"
if [ -z "$pass" ]; then
log_warning "Script did not specify a password...generating a password because we are nice..." $FUNC
##PASS = echo "openssl rand -base64 14"
pass=$(openssl rand -base64 14)
fi
log_info " ========PARAMETERS==============" $FUNC
log_info " TargetDir ==> ${targetDir}" $FUNC
log_info " prefix ==> ${prefix}" $FUNC
log_info " password ==> ${pass}" $FUNC
#log_info " startDir ==> ${startDir}" $FUNC
log_info " subject ==> ${subject}" $FUNC
log_info " file_key ==> ${file_key}" $FUNC
log_info " file_cert ==> ${file_cert}" $FUNC
log_info " file_pfx ==> ${file_pfx}" $FUNC
log_info " file_b64pfx ==> ${file_b64pfx}" $FUNC
log_info " ===============================" $FUNC
#Ensure work Folder Exists
if [ ! -d ${fullpath} ]; then
log_warning "Working Directory (${fullpath} does not exist - Creating Directory...." $FUNC
mkdir -p ${targetDir}
log_success "Dir creation complete." $FUNC
else
log_info "Skipping creation of working directory as folder already exists." $FUNC
fi
pushd "${targetDir}" > /dev/null;
#Generate Private Key & Certificate
log_info "Generating Private key and certificate" $FUNC
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -subj "${subject}" -keyout "${file_key}" -out "${file_cert}"
log_success "Cert & Key files generated." $FUNC
# Convert to a Pfx with password
log_info "Generating pfx from ${file_cert} and ${file_key} files: Target ==> ${file_pfx}" $FUNC
openssl pkcs12 -export -in "${file_cert}" -inkey "${file_key}" -out "${file_pfx}" -passout pass:${pass}
log_success "Success! Pfx cert generated with password." $FUNC
log_info "Reading information about pfx to verify integrity..." $FUNC
openssl pkcs12 -info -in ${file_pfx} -passin pass:${pass} -passout pass:$pass | openssl x509 -noout -text #> certinfo.txt
#Create Base64 of File
log_info "Executing base64(${pfx}) > ${dst}...." $FUNC
base64 -w 0 ${file_pfx} > ${file_b64pfx}
log_success "Success! Base64 created." $FUNC
log_info "Saving password to file ==> ${file_pass}...." $FUNC
echo ${pass} > ${file_pass}
log_success "Success! file saved." $FUNC
log_info "Printing Base64 Encoding of the PFX stored in ${dst}...." $FUNC
cat ${file_b64pfx}
log_info "popping Directory..." $FUNC
popd
log_success "Generate SelfSignedCerts is done." $FUNC
}
#===========================================================================================
# Clean up specified folder
# $1 = Target Directory
function implode() {
FUNC="implode"
log_banner "=========================================" $FUNC
log_banner "Imploding directory...." $FUNC
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
echo "Incorrect parameters passed" # If parameters no equal 2
fi
startDir=$(pwd)
targetDir="${1}"
fullpath="${startDir}/${targetDir}"
log_info "removing directory ${fullpath}..." $FUNC
if [ ! -d ${fullpath} ]; then
log_info "Folder doesn't exist - no action required." $FUNC
else
rm ${targetDir} -r
log_success "Removed folder..." $FUNC
fi
log_info "Implode is done." $FUNC
}
#===========================================================================================
# Helper func for input
helpFunction()
{
echo ""
echo "Usage: $0 -d \"CertGen\" -p \"Localhost\" -s \"SOMEMPASSWORD\""
echo -e "\t-d Directory that will be used to create file in"
echo -e "\t-p Prefix of the name of the file"
echo -e "\t-s Password used to encrypt PFX"
echo -e "\t-c Cleanup files - Requires -d to be specified"
exit 1 # Exit script after printing help
}
#===========================================================================
# Main Execution Code
log_banner "========================================="
log_banner "START OF SCRIPT"
log_banner "========================================="
while getopts "d:p:s:c" opt
do
case "$opt" in
d) TARGETDIR=${OPTARG};;
p) PREFIX=${OPTARG};;
s) PASS=${OPTARG};;
c) CLEAN="true";;
? ) helpFunction ;; # Print helpFunction in case parameter is non-existent
esac
done
# Debug print the parameters passed in
FUNC="flags"
log_info " Clean ==> ${CLEAN}" ${FUNC}
log_info " TargetDir ==> ${TARGETDIR}" ${FUNC}
log_info " prefix ==> ${PREFIX}" ${FUNC}
log_info " password ==> ${PASS}" ${FUNC}
FUNC="Cleanup"
if [[ "${CLEAN}" = "true" ]] && [[ -z "$TARGETDIR" ]]; then
log_error "Cannot run Clean without a directory to clean!" $FUNC
helpFunction
#exit $?
elif [[ "${CLEAN}" = "true" ]] && [[ ! -z "$TARGETDIR" ]]; then
log_info "Clean option was specified. Cleaning up after the CertGen..." $FUNC
implode ${TARGETDIR}
log_info "Cleanup is done." $FUNC
exit $?
fi
# Print helpFunction in case parameters are empty
FUNC="ParmCheck"
if [ -z "$TARGETDIR" ] || [ -z "$PREFIX" ]
then
log_error "Some or all of the parameters are empty"; $FUNC
helpFunction
fi
FUNC="parameters"
log_info "__i_am_main_script: ${__i_am_main_script} " ${FUNC}
log_info "__file: ${__file}" ${FUNC}
log_info "__dir: ${__dir}" ${FUNC}
log_info "__base: ${__base}" ${FUNC}
log_info "OSTYPE: ${OSTYPE}" ${FUNC}
checkRoot
check_distro
installDependencies
checkOpenSslVersion
genSelfSignedCert ${TARGETDIR} ${PREFIX} ${PASS}
log_banner "========================================="
log_banner "END OF SCRIPT"
log_banner "========================================="
#./certGen.sh -d "CertGen" -p "localhost" -s "XMG3-Rel.1"
#./certGen.sh -d "CertGen" -c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment