228 lines
6.2 KiB
Bash
Executable File
228 lines
6.2 KiB
Bash
Executable File
#!/bin/bash
|
||
#############################################################
|
||
# Script name: template.sh
|
||
# Author: Gilles Mouchet (gilles.mouchet@gmail.com
|
||
# Version: v1beta 2026-04-05
|
||
# Description: Script template linux
|
||
# License: CC BY-NC 4.0 (https://creativecommons.org/licenses/by-nc/4.0/)
|
||
#
|
||
# This script is provided "as is", WITHOUT ANY WARRANTY OF ANY KIND.
|
||
# Commercial use is strictly prohibited without prior authorization.
|
||
#
|
||
# Changelog
|
||
# [1.0.0] - 2026-04-05
|
||
# Project initialization
|
||
# - initialization by gilles.mouchet@gmail.com
|
||
#
|
||
############################################################
|
||
#
|
||
version=v1beta
|
||
days=365
|
||
|
||
############################################################
|
||
# FUNCTIONS
|
||
############################################################
|
||
#-----------------------------------------------------------
|
||
# Display usage
|
||
usage() {
|
||
cat << EOF
|
||
Usage: $0 -c <ca_cert> -k <ca_key> -n <common_name> [-d <dns1,dns2>] [-i <ip1,ip2>] [-t <days>]"
|
||
|
||
Template script
|
||
Options:
|
||
-c, --ca-name - ca name
|
||
-n, --commonName - common name (server.domain.ext)
|
||
-d, --dns - subject alternative name (multiple SAN separated by commas)
|
||
-i, --ip - ip address to add to the certificate (multiple IPs separated by commas)
|
||
-t, --days - validity period of the certificate in days (defaults $days days)
|
||
-h, --help - show this help
|
||
-v, --version - show script version
|
||
|
||
Examples:
|
||
Generate a certificate for myweb.gmolab.net
|
||
./$(basename "$0") -c gmolab_ca -n myweb.gmolab.net
|
||
|
||
Generate a certifciate for myweb.gmolab.net with dns alias and ip
|
||
./$(basename "$0") -c gmolab_ca -n myweb.gmolab.net -i 92.168.1.10,10.0.0.5,10.10.34.25 --dns www.gmolab.net,qual-myweb.gmolab.net -t 49
|
||
|
||
Show this help
|
||
./$(basename "$0") -h
|
||
EOF
|
||
}
|
||
|
||
############################################################
|
||
# MAIN
|
||
############################################################
|
||
# var for config file
|
||
progName=`echo $0 | sed -e 's|.*/||g' | cut -f1 -d.`
|
||
confDir=/etc/own-pki
|
||
cfgFile=${confDir}/own-pki.conf
|
||
|
||
# check if conf file or passphrase file exist
|
||
if [ ! -f $cfgFile ]; then
|
||
echo "$progName not installed correctly. Please run install.sh script"
|
||
exit 1
|
||
fi
|
||
|
||
# read config file
|
||
. $cfgFile
|
||
# check if param exist
|
||
if [ -z "$1" ]; then
|
||
usage
|
||
exit 1
|
||
fi
|
||
|
||
# parse cli parameters
|
||
while [[ "$#" -gt 0 ]]; do
|
||
case "$1" in
|
||
-c|--ca-name)
|
||
ca_crt=$2.crt
|
||
ca_key=$2.key
|
||
shift 2
|
||
;;
|
||
-n|--common-name)
|
||
if [[ ! $2 =~ ^([a-z0-9]+(-[a-z0-9]+)*\.){2,}[a-z]{2,}$ ]]; then
|
||
echo -e "\n$2 is not a commonName valid\n"
|
||
usage
|
||
exit 1
|
||
else
|
||
commonName=$2
|
||
fi
|
||
shift 2
|
||
;;
|
||
-d|--dns)
|
||
IFS=',' read -r -a dns <<< "$2"
|
||
shift 2
|
||
;;
|
||
-i|--ip)
|
||
IFS=',' read -r -a ipAddrs <<< "$2"
|
||
shift 2
|
||
;;
|
||
-t|--days)
|
||
days=$2
|
||
shift 2
|
||
;;
|
||
version|-v|--version)
|
||
cat << EOF
|
||
$(basename "$0") $version (c) 1990 - $(date +%Y) by Gilles Mouchet
|
||
|
||
This script is provided "as is", WITHOUT ANY WARRANTY OF ANY KIND.
|
||
Non-Commercial Use License – See LICENSE for details
|
||
|
||
EOF
|
||
exit
|
||
;;
|
||
*|help|-h|--help)
|
||
usage
|
||
exit
|
||
;;
|
||
esac
|
||
done
|
||
# check
|
||
if [[ -z "$ca_crt" || -z "$ca_key" || -z "$commonName" ]]; then
|
||
usage
|
||
exit 1
|
||
fi
|
||
|
||
# check if ca key and ca crt exist
|
||
if [[ ! -f "$certPath/$ca_crt" || ! -f "$certPath/$ca_key" ]]; then
|
||
cat << EOF
|
||
|
||
One or both of the following files are missing:
|
||
- $certPath/$ca_crt
|
||
- $certPath/$ca_key
|
||
|
||
EOF
|
||
exit 1
|
||
fi
|
||
cat << EOF
|
||
Summary
|
||
---------------------------------------------------------------------
|
||
Certifcate authority: $ca_crt
|
||
Common name: $commonName
|
||
EOF
|
||
echo "SAN List:"
|
||
echo " - ${commonName}"
|
||
|
||
for san in "${dns[@]}"; do
|
||
echo " - $san"
|
||
done
|
||
|
||
echo "IP List:"
|
||
for ip in "${ipAddrs[@]}"; do
|
||
if [[ $ip =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]; then
|
||
echo " - $ip"
|
||
else
|
||
echo " - $ip is not valid !"
|
||
fi
|
||
done
|
||
|
||
echo "Validity:"
|
||
echo " Not before: $(date +"%b %d %H:%M:%S %Y GMT")"
|
||
echo " Not After : $(date -u -d "+$days days" +"%b %d %H:%M:%S %Y GMT")"
|
||
|
||
read -p "Are you OK (y/N)? " answer
|
||
if [[ "$answer" != "y" && "$answer" != "Y" ]]; then
|
||
exit 1
|
||
fi
|
||
|
||
echo -e "\nPrepare the openSSL configuration file"
|
||
cat > "$certPath/${commonName}_openssl.cnf" << EOF
|
||
[ req ]
|
||
default_bits = 2048
|
||
distinguished_name = req_distinguished_name
|
||
req_extensions = req_ext
|
||
prompt = no
|
||
|
||
[ req_distinguished_name ]
|
||
CN = $commonName
|
||
|
||
[ req_ext ]
|
||
subjectAltName = @alt_names
|
||
|
||
[ alt_names ]
|
||
EOF
|
||
|
||
echo -e " Add SAN"
|
||
# add dns
|
||
i=1
|
||
echo "DNS.$i = ${commonName}" >> "$certPath/${commonName}_openssl.cnf"
|
||
((i++))
|
||
for san in "${dns[@]}"; do
|
||
echo "DNS.$i = $san" >> "$certPath/${commonName}_openssl.cnf"
|
||
((i++))
|
||
done
|
||
|
||
echo -e " Add IP"
|
||
# add ip
|
||
i=1
|
||
for ip in "${ipAddrs[@]}"; do
|
||
if [[ $ip =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]; then
|
||
echo "IP.$i = $ip" >> "$certPath/${commonName}_openssl.cnf"
|
||
((i++))
|
||
else
|
||
echo -e "\nAddress ip $ip is not valid\n"
|
||
((i++))
|
||
fi
|
||
done
|
||
|
||
echo -e "\nGenerating the private key..."
|
||
openssl genrsa -out "${certPath}/${commonName}.key" 4096
|
||
|
||
echo -e "\nGenerating csr file..."
|
||
openssl req -new -key "${certPath}/${commonName}.key" -out "${certPath}/${commonName}.csr" -config "$certPath/${commonName}_openssl.cnf"
|
||
|
||
echo -e "\nSigning the certificate with the CA...\n"
|
||
openssl x509 -req -in "${certPath}/${commonName}.csr" \
|
||
-CA "$certPath/$ca_crt" -CAkey "$certPath/$ca_key" -CAcreateserial \
|
||
-out "${certPath}/${commonName}.crt" -days "$days" \
|
||
-extensions req_ext -extfile "$certPath/${commonName}_openssl.cnf"
|
||
|
||
echo -e "\nVerify certifcate"
|
||
|
||
echo -e "\nValidity"
|
||
openssl x509 -in $certPath/$commonName.crt -noout -dates
|
||
echo -e "\nSubject Alternative Name"
|
||
openssl x509 -in $certPath/$commonName.crt -noout -ext subjectAltName
|
||
echo -e "\nVerify the validity of a certificate using the trust chain"
|
||
openssl verify -CAfile $certPath/$ca_crt $certPath/$commonName.crt |