dev #20260420
This commit is contained in:
parent
609c0f7856
commit
8eaacc490f
163
bin/create-ca.sh
Executable file
163
bin/create-ca.sh
Executable file
@ -0,0 +1,163 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#############################################################
|
||||||
|
# Script name: create-CA.sh
|
||||||
|
# Author: Gilles Mouchet (gilles.mouchet@gmail.com
|
||||||
|
# Version: 1.0.0
|
||||||
|
# Description: Script to create a own CA
|
||||||
|
# License: GNU GPL v3
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# Changelog
|
||||||
|
# [1.0.0] - 2026-04-19
|
||||||
|
# Added:
|
||||||
|
# - CA creation
|
||||||
|
# Project initialization:
|
||||||
|
# - initialization by gilles.mouchet@gmail.com
|
||||||
|
#
|
||||||
|
############################################################
|
||||||
|
|
||||||
|
version=1.0.0
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# FUNCTIONS
|
||||||
|
############################################################
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# display usage
|
||||||
|
usage() {
|
||||||
|
cat << EOF
|
||||||
|
Usage: ./$(basename "$0") -n <commonName>
|
||||||
|
Template script
|
||||||
|
Options:
|
||||||
|
-n, --common-name <cn> - CA common name [mandatory]
|
||||||
|
-h, --help - show this help
|
||||||
|
-v, --version - show script version
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
Show this help
|
||||||
|
./$(basename "$0") -n "GMOLab CA"
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
############################################################
|
||||||
|
# MAIN
|
||||||
|
############################################################
|
||||||
|
|
||||||
|
main(){
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||||
|
|
||||||
|
# read library
|
||||||
|
source "$ROOT_DIR/lib/stdlib.sh"
|
||||||
|
|
||||||
|
# check if param exist
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# init config
|
||||||
|
init_default
|
||||||
|
init_env
|
||||||
|
|
||||||
|
# set color
|
||||||
|
set_color
|
||||||
|
|
||||||
|
# check if script is runnibf with sudo
|
||||||
|
check_sudo
|
||||||
|
|
||||||
|
# read cli parameters
|
||||||
|
while [[ "$#" -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-n|--commonname)
|
||||||
|
# check if param $2 exist
|
||||||
|
if [ -z "$2" ]; then
|
||||||
|
echo -e "\n${RED}Error: Argument missing for option -n or --name${NC}\n"
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
COMMON_NAME="$2"
|
||||||
|
fi
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
version|-v|--version)
|
||||||
|
cat << EOF
|
||||||
|
$(basename "$0") $version Copyright (C) 2003 - $(date +%Y) Gilles Mouchet
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
*|help|-h|--help)
|
||||||
|
usage
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# clean variable commonName
|
||||||
|
CA_NAME=$(clean_string "${COMMON_NAME}")
|
||||||
|
# summary
|
||||||
|
|
||||||
|
printf "
|
||||||
|
${CYAN}Summary
|
||||||
|
----------------------------------------------------------------------------${NC}
|
||||||
|
CA private file name (key): ${GREEN}%s.key${NC}
|
||||||
|
CA public file name (crt): ${GREEN}%s.crt${NC}
|
||||||
|
|
||||||
|
${CYAN}Informations${NC}
|
||||||
|
Country name: ${ORANGE}%s${NC}
|
||||||
|
State or province name: ${ORANGE}%s${NC}
|
||||||
|
Locality name: ${ORANGE}%s${NC}
|
||||||
|
Organization name: ${ORANGE}%s${NC}
|
||||||
|
Organizational unit name: ${ORANGE}%s${NC}
|
||||||
|
Common name: ${ORANGE}%s${NC}
|
||||||
|
Email address: ${ORANGE}%s${NC}
|
||||||
|
|
||||||
|
${RED}IMPORTANT${NC}
|
||||||
|
You will be asked for a password. Choose a ${RED}STRONG PASSWORD${NC}
|
||||||
|
and KEEP IT SECURE.
|
||||||
|
|
||||||
|
You will be asked for it when creating certificates.
|
||||||
|
|
||||||
|
" "${KEY_CA_PATH}/${CA_NAME}" "${CRT_CA_PATH}/${CA_NAME}" \
|
||||||
|
"$COUNTRY_NAME" "$STATE_OR_PROVINCE_NAME" "$LOCALITY_NAME" \
|
||||||
|
"$ORGANIZATION_NAME" "$ORGANIZATIONAL_UNIT_NAME" "$COMMON_NAME" "$EMAIL_ADDRESS"
|
||||||
|
|
||||||
|
yes_no "Is it ok"
|
||||||
|
|
||||||
|
# check if CA files exist
|
||||||
|
if [ -f "$KEY_CA_PATH/$CA_NAME.key" ]; then
|
||||||
|
#echo -e "${RED}\n$KEY_CA_PATH/$CA_NAME.key already exists!\n"
|
||||||
|
msg_warn "\n$KEY_CA_PATH/$CA_NAME.key already exists!\n"
|
||||||
|
yes_no "Are you sure you want to delete it"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# config ca-conf file
|
||||||
|
sed -e "s|%COUNTRY_NAME%|$COUNTRY_NAME|" \
|
||||||
|
-e "s|%STATE_OF_PROVINCE_NAME%|$STATE_OR_PROVINCE_NAME|" \
|
||||||
|
-e "s|%LOCALITY_NAME%|$LOCALITY_NAME|" \
|
||||||
|
-e "s|%ORGANIZITION_NAME%|$ORGANIZATION_NAME|" \
|
||||||
|
-e "s|%ORGANiZATION_UNIT_NAME%|$ORGANIZATIONAL_UNIT_NAME|" \
|
||||||
|
-e "s|%COMMON_NAME%|$COMMON_NAM|" \
|
||||||
|
-e "s|%EMAIL_ADDRESS%|$EMAIL_ADDRESS|" < $ROOT_DIR/config/ca-config.tmpl > $ROOT_DIR/config/ca-config
|
||||||
|
|
||||||
|
# create ca
|
||||||
|
openssl req -new -x509 -extensions v3_ca -days 1825 -newkey rsa:4096 \
|
||||||
|
-keyout ${KEY_CA_PATH}/${CA_NAME}.key \
|
||||||
|
-out ${CRT_CA_PATH}/${CA_NAME}.crt \
|
||||||
|
-config $ROOT_DIR/config/ca-config \
|
||||||
|
-batch > /dev/null 2>&1
|
||||||
|
|
||||||
|
if [ "$?" == "0" ]; then
|
||||||
|
echo -e "${RED}!! Keep your password safe !! ${NC}"
|
||||||
|
echo -e "${GREEN}CA created successfully ${NC}"
|
||||||
|
echo -e "Install ${ORANGE}${CRT_CA_PATH}/${CA_NAME}.crt${NC} in you browser."
|
||||||
|
else
|
||||||
|
echo -e "${RED}An error occured (rc: $?)${NC}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
main "$@"
|
||||||
348
bin/generate-cert.sh
Executable file
348
bin/generate-cert.sh
Executable file
@ -0,0 +1,348 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#############################################################
|
||||||
|
# Script name: create-cert.sh
|
||||||
|
# Author: Gilles Mouchet (gilles.mouchet@gmail.com
|
||||||
|
# Version: 1.0.0
|
||||||
|
# Description: Create a cert and save it on db
|
||||||
|
# License: GNU GPL v3
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# Changelog
|
||||||
|
# [1.0.0] - 2026-04-12
|
||||||
|
# Added:
|
||||||
|
# - adding cert into DB
|
||||||
|
# - generating private key
|
||||||
|
# - generating Certificate Signing Request (csr) file
|
||||||
|
# - signing the certificate with the CA
|
||||||
|
# Project initialization
|
||||||
|
# - initialization by gilles.mouchet@gmail.com
|
||||||
|
#
|
||||||
|
############################################################
|
||||||
|
#
|
||||||
|
version=1.0.0
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# 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> - ca name (./info-cert.sh -c get list of CA name)
|
||||||
|
-n, --commonName <cn> - common name (server.domain.ext)
|
||||||
|
-d, --dns <dns1,dns2,dnsx> - subject alternative name (multiple SAN separated by commas)
|
||||||
|
-i, --ip <ip1,ipx> - ip address to add to the certificate (multiple IPs separated by commas)
|
||||||
|
-t, --days <days> - validity period of the certificate in days (defaults $days days)
|
||||||
|
-y, --assumeyes - automatically answer yes for all questions.
|
||||||
|
-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
|
||||||
|
############################################################
|
||||||
|
|
||||||
|
main(){
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||||
|
|
||||||
|
# read library
|
||||||
|
source "$ROOT_DIR/lib/stdlib.sh"
|
||||||
|
|
||||||
|
# init config
|
||||||
|
init_default
|
||||||
|
init_env
|
||||||
|
|
||||||
|
# set color
|
||||||
|
set_color
|
||||||
|
|
||||||
|
# check if script is runnibf with sudo
|
||||||
|
check_sudo
|
||||||
|
|
||||||
|
# check if param exist
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set color
|
||||||
|
set_color
|
||||||
|
|
||||||
|
# parse cli parameters
|
||||||
|
while [[ "$#" -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-c|--ca-name)
|
||||||
|
if [[ -z "$2" || "$2" == -* ]]; then
|
||||||
|
msg_error "\nError: Argument missing for option -c or --ca-name.\n"
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
CA_CRT=$2.crt
|
||||||
|
CA_KEY=$2.key
|
||||||
|
fi
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-n|--common-name)
|
||||||
|
if [[ -z "$2" || "$2" == -* ]]; then
|
||||||
|
msg_error "\nError: Argument missing for option -n or --common-name.\n"
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
if [[ ! $2 =~ ^([a-z0-9]+(-[a-z0-9]+)*\.){2,}[a-z]{2,}$ ]]; then
|
||||||
|
msg_error "\n$2 is not a commonName valid.\n"
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
COMMON_NAME=$2
|
||||||
|
# record for db if no option -d or --dns exist.
|
||||||
|
# some browser needed the commName in Subject Alternative Name
|
||||||
|
DNS_LINE=$2 # record for db if no option -d or --dns exist. Some browser needed the commName in Subject Alternative Name
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-d|--dns)
|
||||||
|
if [[ -z "$2" || "$2" == -* ]]; then
|
||||||
|
msg_error "\nError: Argument missing for option -d or --dns.\n"
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
# add commonName and parameters -d --dns value in dnsLine variable.
|
||||||
|
# some browser needed the commName in Subject Alternative Name
|
||||||
|
DNS_LINE="$COMMON_NAME,$2"
|
||||||
|
|
||||||
|
# put dnsLine value in dns array
|
||||||
|
IFS=',' read -r -a DNS <<< "$DNS_LINE"
|
||||||
|
|
||||||
|
# check dns format
|
||||||
|
for SAN_DNS in "${DNS[@]}"; do
|
||||||
|
if [[ ! $SAN_DNS =~ ^([a-z0-9]+(-[a-z0-9]+)*\.){2,}[a-z]{2,}$ ]]; then
|
||||||
|
msg_error "\n$SAN_DNS is not a commonName valid.\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-i|--ip)
|
||||||
|
if [[ -z "$2" || "$2" == -* ]]; then
|
||||||
|
msg_error "\nError: Argument missing for option -i or --ip.\n"
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
# add parameters -i --ip values in IP_LINE variable.
|
||||||
|
IP_LINE=$2
|
||||||
|
# put ipLine value in ipAddrs array
|
||||||
|
IFS=',' read -r -a IP_ADDRS <<< "$2"
|
||||||
|
|
||||||
|
# check ip format
|
||||||
|
for SAN_IP in "${IP_ADDRS[@]}"; do
|
||||||
|
if [[ ! $SAN_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
|
||||||
|
msg_error "\n$SAN_IP is not an address IP valid.\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-t|--days)
|
||||||
|
if [[ -z "$2" || "$2" == -* ]]; then
|
||||||
|
msg_err "\nError: Argument missing for option -t or --days.\n"
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
DAYS=$2
|
||||||
|
fi
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-y|--assumeyes)
|
||||||
|
ASSUME_YES="1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-v|--version)
|
||||||
|
cat << EOF
|
||||||
|
$(basename "$0") $version Copyright (C) 2003 - $(date +%Y) Gilles Mouchet
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# if array dns is empty we add commonName
|
||||||
|
if [ "${#DNS[@]}" -eq 0 ]; then
|
||||||
|
DNS+="$COMMON_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if mandatory variables exists
|
||||||
|
if [[ -z "$CA_CRT" || -z "$CA_KEY" || -z "$COMMON_NAME" ]]; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if ca key and ca crt file exist
|
||||||
|
if [[ ! -f "$CRT_CA_PATH/$CA_CRT" || ! -f "$KEY_CA_PATH/$CA_KEY" ]]; then
|
||||||
|
msg_error "One or both of the following files are missing:"
|
||||||
|
msg_warn " - $CRT_CA_PATH/$CA_CRT"
|
||||||
|
msg_warn " - $KEY_CA_PATH/$CA_KEY"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# summary
|
||||||
|
printf "
|
||||||
|
${CYAN}Summary
|
||||||
|
---------------------------------------------------------------------${NC}
|
||||||
|
Certifcate authority: ${GREEN}%s${NC}
|
||||||
|
Common name: ${GREEN}%s${NC}
|
||||||
|
" "$CRT_CA_PATH/$CA_CRT" "$COMMON_NAME"
|
||||||
|
|
||||||
|
echo -e "SAN List:"
|
||||||
|
for SAN_DNS in "${DNS[@]}"; do
|
||||||
|
msg_ok " - $SAN_DNS"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "IP List:"
|
||||||
|
for SAN_IP in "${IP_ADDRS[@]}"; do
|
||||||
|
msg_ok " - $SAN_IP"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "Validity:"
|
||||||
|
echo -e " Not before: ${GREEN}$(date +"%b %d %H:%M:%S %Y GMT")${NC}"
|
||||||
|
echo -e " Not After : ${GREEN}$(date -u -d "+$DAYS days" +"%b %d %H:%M:%S %Y GMT")${NC}"
|
||||||
|
|
||||||
|
if [ "$ASSUME_YES" == "0" ]; then
|
||||||
|
yes_no "Is it ok"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# create destination path
|
||||||
|
if [ ! -d "$CERTS_TMP_PATH" ]; then
|
||||||
|
echo "create $CERTS_TMP_PATH"
|
||||||
|
mkdir -p $CERTS_TMP_PATH
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\nPrepare the openSSL configuration file"
|
||||||
|
cat > "$CERTS_TMP_PATH/${COMMON_NAME}_openssl.cnf" << EOF
|
||||||
|
[ req ]
|
||||||
|
default_bits = 2048
|
||||||
|
distinguished_name = req_distinguished_name
|
||||||
|
req_extensions = req_ext
|
||||||
|
prompt = no
|
||||||
|
|
||||||
|
[ req_distinguished_name ]
|
||||||
|
CN = $COMMON_NAME
|
||||||
|
|
||||||
|
[ req_ext ]
|
||||||
|
subjectAltName = @alt_names
|
||||||
|
|
||||||
|
[ alt_names ]
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo -e " Add SAN"
|
||||||
|
# add dns
|
||||||
|
i=1
|
||||||
|
#echo "DNS.$i = ${COMMON_NAME}" >> "$CERTS_TMP_PATH/${COMMON_NAME}_openssl.cnf"
|
||||||
|
#((i++))
|
||||||
|
for SAN_DNS in "${DNS[@]}"; do
|
||||||
|
echo "DNS.$i = $AN_DNS" >> "$CERTS_TMP_PATH/${COMMON_NAME}_openssl.cnf"
|
||||||
|
((i++))
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e " Add IP"
|
||||||
|
# add ip
|
||||||
|
i=1
|
||||||
|
for SAN_IP in "${IP_ADDRS[@]}"; do
|
||||||
|
echo "IP.$i = $SAN_IP" >> "$CERTS_TMP_PATH/${COMMON_NAME}_openssl.cnf"
|
||||||
|
((i++))
|
||||||
|
done
|
||||||
|
|
||||||
|
# create certificate
|
||||||
|
echo -e "Generating the private key..."
|
||||||
|
openssl genrsa -out "${CERTS_TMP_PATH}/${COMMON_NAME}.key" 4096
|
||||||
|
|
||||||
|
echo -e "Generating csr file..."
|
||||||
|
openssl req -new -key "${CERTS_TMP_PATH}/${COMMON_NAME}.key" -out "${CERTS_TMP_PATH}/${COMMON_NAME}.csr" -config "$CERTS_TMP_PATH/${COMMON_NAME}_openssl.cnf"
|
||||||
|
|
||||||
|
echo -e "Signing the certificate with the CA..."
|
||||||
|
openssl x509 -req -in "${CERTS_TMP_PATH}/${COMMON_NAME}.csr" \
|
||||||
|
-CA "$CRT_CA_PATH/$CA_CRT" -CAkey "$KEY_CA_PATH/$CA_KEY" -CAcreateserial \
|
||||||
|
-out "${CERTS_TMP_PATH}/${COMMON_NAME}.crt" -days "$DAYS" \
|
||||||
|
-extensions req_ext -extfile "$CERTS_TMP_PATH/${COMMON_NAME}_openssl.cnf" \
|
||||||
|
> /dev/null 2>&1 #-passin pass:pa55w0rd > /dev/null 2>&1
|
||||||
|
echo -n "Result of certificate signing: "
|
||||||
|
check_rc $?
|
||||||
|
#echo -e "\nVerify certifcate"
|
||||||
|
#echo -e "\nValidity"
|
||||||
|
#openssl x509 -in $CERTS_TMP_PATH/${COMMON_NAME}.crt -noout -dates
|
||||||
|
#echo -e "\nSubject Alternative Name"
|
||||||
|
#openssl x509 -in $CERTS_TMP_PATH/${COMMON_NAME}.crt -noout -ext subjectAltName
|
||||||
|
echo -e -n "\nVerify the validity of ${GREEN}$CERTS_TMP_PATH/${COMMON_NAME}.crt${NC} using the trust chain: "
|
||||||
|
openssl verify -CAfile $CRT_CA_PATH/$CA_CRT $CERTS_TMP_PATH/$COMMON_NAME.crt > /dev/null 2>&1
|
||||||
|
check_rc $?
|
||||||
|
# get validity date
|
||||||
|
notBefore=$(openssl x509 -noout -in $CERTS_TMP_PATH/${COMMON_NAME}.crt -startdate | cut -d'=' -f2)
|
||||||
|
notAfter=$(openssl x509 -noout -in $CERTS_TMP_PATH/${COMMON_NAME}.crt -enddate | cut -d'=' -f2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
exit
|
||||||
|
# check if commonName already exist on db
|
||||||
|
echo -e -n "\nCheck if ${GREEN}${COMMON_NAME}${NC} exist in DB: "
|
||||||
|
recordExist=$(sqlite3 $dbCertFile "SELECT EXISTS(SELECT 1 FROM certs WHERE common_name='${COMMON_NAME}');")
|
||||||
|
rc="$?"
|
||||||
|
[ "$rc" != "0" ] && { echo -e "${RED}Error reading the database (RC:$rc - $recordExist)${NC}"; exit; } || echo -e "${GREEN}Ok${NC}"
|
||||||
|
|
||||||
|
if [ "$recordExist" == "1" ]; then
|
||||||
|
echo -e -n "Update ${ORANGE}${COMMON_NAME}${NC} in DB: "
|
||||||
|
sqlite3 $dbCertFile <<EOF
|
||||||
|
UPDATE certs SET san_dns = '$dnsLine',
|
||||||
|
san_ip = '$ipLine',
|
||||||
|
cert_key = readfile('${CERTS_TMP_PATH}/${COMMON_NAME}.key'),
|
||||||
|
cert_csr = readfile('${CERTS_TMP_PATH}/${COMMON_NAME}.csr'),
|
||||||
|
cert_crt = readfile('${CERTS_TMP_PATH}/${COMMON_NAME}.crt'),
|
||||||
|
not_valid_before = '$notBefore',
|
||||||
|
not_valid_after = '$notAfter'
|
||||||
|
WHERE common_name = '${COMMON_NAME}';
|
||||||
|
EOF
|
||||||
|
rc="$?"
|
||||||
|
[ "$rc" != "0" ] && { echo -e "${RED}Error updating record in the database (RC:$rc - $recordExist)${NC}"; exit; } || echo -e "${GREEN}Ok${NC}"
|
||||||
|
else
|
||||||
|
echo -e -n "Add ${ORANGE}${COMMON_NAME}${NC} in DB: "
|
||||||
|
sqlite3 $dbCertFile <<EOF
|
||||||
|
INSERT INTO certs (common_name,san_dns,san_ip,cert_key,cert_csr,cert_crt,not_valid_before,not_valid_after)
|
||||||
|
VALUES ('${COMMON_NAME}', '$dnsLine','$ipLine',
|
||||||
|
readfile('${CERTS_TMP_PATH}/${COMMON_NAME}.key'),
|
||||||
|
readfile('${CERTS_TMP_PATH}/${COMMON_NAME}.csr'),
|
||||||
|
readfile('${CERTS_TMP_PATH}/${COMMON_NAME}.crt'),
|
||||||
|
'$notBefore',
|
||||||
|
'$notAfter')
|
||||||
|
EOF
|
||||||
|
rc="$?"
|
||||||
|
[ "$rc" != "0" ] && { echo -e "${RED}Error writing record in the database (RC:$rc - $recordExist)${NC}"; exit; } || echo -e "${GREEN}Ok${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
main "$@"
|
||||||
148
bin/install.sh
148
bin/install.sh
@ -24,13 +24,6 @@
|
|||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
VERSION=1.0.0
|
VERSION=1.0.0
|
||||||
# path resolution
|
|
||||||
# scripts and lib
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
||||||
|
|
||||||
# database
|
|
||||||
DB_PATH=/var/lib/own-pki/certificates.db
|
|
||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
# FUNCTIONS
|
# FUNCTIONS
|
||||||
@ -38,9 +31,31 @@ DB_PATH=/var/lib/own-pki/certificates.db
|
|||||||
#-----------------------------------------------------------
|
#-----------------------------------------------------------
|
||||||
# init db
|
# init db
|
||||||
init_db(){
|
init_db(){
|
||||||
|
|
||||||
mkdir -p "$(dirname "$DB_PATH")"
|
mkdir -p "$(dirname "$DB_PATH")"
|
||||||
|
sqlite3 $DB_PATH <<EOF
|
||||||
|
CREATE TABLE IF NOT EXISTS certs (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
common_name TEXT UNIQUE,
|
||||||
|
san_dns TEXT,
|
||||||
|
san_ip TEXT,
|
||||||
|
cert_key TEXT,
|
||||||
|
cert_csr TEXT,
|
||||||
|
cert_crt TEXT,
|
||||||
|
not_valid_before TEXT,
|
||||||
|
not_valid_after TEXT,
|
||||||
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TRIGGER IF NOT EXISTS update_certs_updated_at
|
||||||
|
AFTER UPDATE ON certs
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
UPDATE certs
|
||||||
|
SET updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = OLD.id;
|
||||||
|
END;
|
||||||
|
EOF
|
||||||
}
|
}
|
||||||
############################################################
|
############################################################
|
||||||
# Main
|
# Main
|
||||||
@ -49,8 +64,121 @@ init_db(){
|
|||||||
# path resolution
|
# path resolution
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
|
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||||
|
ETC_PATH="/etc/own-pki"
|
||||||
|
ENABLE_COLOR=true
|
||||||
|
BIN_PATH="/opt/own-pki"
|
||||||
|
DB_PATH="/var/lib/own-pki/certificates.db"
|
||||||
|
ASSUME_YES=0
|
||||||
|
|
||||||
echo $SCRIPT_DIR
|
# read stdlib.sh
|
||||||
echo $ROOT_DIR
|
source "$ROOT_DIR/lib/set-color.sh"
|
||||||
|
source "$ROOT_DIR/lib/message.sh"
|
||||||
|
source "$ROOT_DIR/lib/check-rc.sh"
|
||||||
|
source "$ROOT_DIR/lib/yes-no.sh"
|
||||||
|
|
||||||
|
set_color
|
||||||
|
|
||||||
|
main(){
|
||||||
|
# check if user has sudo rigth
|
||||||
|
if sudo ! -n true 2>/dev/null; then
|
||||||
|
msg_error "Access denied: user $USER does not have sudo privileges or a password is required.."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if the effective user ID is 0 (root)
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
msg_error "\nThis script must be run as root or with sudo.\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# install sqlite
|
||||||
|
echo -n -e "Install ${ORANGE}sqlite${NC}. Please wait...: "
|
||||||
|
dnf install sqlite -y > /dev/null 2>&1
|
||||||
|
check_rc $?
|
||||||
|
|
||||||
|
# create paths
|
||||||
|
echo -n -e "Create path $BIN_PATH: "
|
||||||
|
if [ ! -d "$BIN_PATH" ]; then
|
||||||
|
mkdir -p "$BIN_PATH" 2>/dev/null
|
||||||
|
check_rc $?
|
||||||
|
else
|
||||||
|
msg_warn "$BIN_PATH already exists!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n -e "Create path $BIN_PATH/lib: "
|
||||||
|
if [ ! -d "$BIN_PATH/lib" ]; then
|
||||||
|
mkdir -p "$BIN_PATH/lib" 2>/dev/null
|
||||||
|
check_rc $?
|
||||||
|
else
|
||||||
|
msg_warn "$BIN_PATH/lib already exists!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e -n "Create $BIN_PATH/bin: "
|
||||||
|
if [ ! -d "$BIN_PATH/bin" ]; then
|
||||||
|
mkdir -p $BIN_PATH/bin 2>/dev/null
|
||||||
|
check_rc $?
|
||||||
|
else
|
||||||
|
msg_warn "$BIN_PATH/bin already exists!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e -n "Create $ETC_PATH: "
|
||||||
|
if [ ! -d "$ETC_PATH" ]; then
|
||||||
|
mkdir -p $ETC_PATH 2>/dev/null
|
||||||
|
check_rc $?
|
||||||
|
else
|
||||||
|
msg_warn "$ETC_PATH already exists!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# copy config file
|
||||||
|
echo -e -n "Copy ${ORANGE}$ROOT_DIR/config/own-pki.conf${NC} to ${ETC_PATH}/: "
|
||||||
|
cp "$ROOT_DIR/config/own-pki.conf" "${ETC_PATH}/."
|
||||||
|
check_rc $?
|
||||||
|
|
||||||
|
# create DB
|
||||||
|
echo -n -e "Create DB $DB_PATH: "
|
||||||
|
if [ -f "$DB_PATH" ]; then
|
||||||
|
msg_warn "$DB_PATH already exists!"
|
||||||
|
yes_no "Are you sure you want to recreate a database"
|
||||||
|
rm -rf "$DB_PATH"
|
||||||
|
init_db
|
||||||
|
check_rc $?
|
||||||
|
else
|
||||||
|
init_db
|
||||||
|
check_rc $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# copy script file to opt
|
||||||
|
msg_info "Copy librairie scripts files"
|
||||||
|
files=( $ROOT_DIR/lib/* )
|
||||||
|
for f in "${files[@]}"; do
|
||||||
|
echo -e -n " copy ${ORANGE}$f${NC} to ${BIN_PATH}/lib: "
|
||||||
|
cp "$f" "$BIN_PATH/lib/"
|
||||||
|
check_rc $?
|
||||||
|
done
|
||||||
|
|
||||||
|
msg_info "Copy main scripts files"
|
||||||
|
files=( $ROOT_DIR/bin/* )
|
||||||
|
for f in "${files[@]}"; do
|
||||||
|
# exclude install.sh
|
||||||
|
if [ "$f" != "$ROOT_DIR/bin/install.sh" ]; then
|
||||||
|
echo -e -n " copy ${ORANGE}$f${NC} to ${BIN_PATH}/bin: "
|
||||||
|
cp "$f" "$BIN_PATH/bin/"
|
||||||
|
check_rc $?
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
msg_info "Create link"
|
||||||
|
files=( $ROOT_DIR/bin/* )
|
||||||
|
for f in "${files[@]}"; do
|
||||||
|
# exclude install.sh
|
||||||
|
if [ "$f" != "$ROOT_DIR/bin/install.sh" ]; then
|
||||||
|
SCRIPT_FILE=$(basename "$f")
|
||||||
|
echo -e -n " create link ${ORANGE}$BIN_PATH/bin/$SCRIPT_FILE${NC} to /usr/local/bin/: "
|
||||||
|
ln -f -s $BIN_PATH/bin/$SCRIPT_FILE /usr/local/bin/ #>"$out_tmp" 2>"$err_tmp"
|
||||||
|
check_rc $?
|
||||||
|
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
main "$@"
|
||||||
|
|
||||||
|
|||||||
102
config/ca-config
Normal file
102
config/ca-config
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
HOME = .
|
||||||
|
RANDFILE = $ENV::HOME/.rnd
|
||||||
|
oid_section = new_oids
|
||||||
|
|
||||||
|
[ new_oids ]
|
||||||
|
|
||||||
|
[ ca ]
|
||||||
|
default_ca = CA_default # The default ca section
|
||||||
|
[ CA_default ]
|
||||||
|
dir = . # Where everything is kept
|
||||||
|
certs = $dir/certs # Where the issued certs are kept
|
||||||
|
crl_dir = $dir/crl # Where the issued crl are kept
|
||||||
|
database = $dir/dbca/index.txt # database index file.
|
||||||
|
new_certs_dir = $dir/newcerts # default place for new certs.
|
||||||
|
certificate = $dir/cacert.pem # The CA certificate
|
||||||
|
serial = $dir/serial/serial # The current serial number
|
||||||
|
crl = $dir/crl.pem # The current CRL
|
||||||
|
private_key = $dir/private/cakey.pem# The private key
|
||||||
|
RANDFILE = $dir/private/.rand # private random number file
|
||||||
|
x509_extensions = usr_cert # The extentions to add to the cert
|
||||||
|
default_days = 365 # how long to certify for
|
||||||
|
default_crl_days= 30 # how long before next CRL
|
||||||
|
default_md = md5 # which md to use.
|
||||||
|
preserve = no # keep passed DN ordering
|
||||||
|
policy = policy_match
|
||||||
|
|
||||||
|
[ policy_match ]
|
||||||
|
countryName = match
|
||||||
|
stateOrProvinceName = match
|
||||||
|
organizationName = match
|
||||||
|
organizationalUnitName = optional
|
||||||
|
commonName = supplied
|
||||||
|
emailAddress = optional
|
||||||
|
|
||||||
|
[ policy_anything ]
|
||||||
|
countryName = optional
|
||||||
|
stateOrProvinceName = optional
|
||||||
|
localityName = optional
|
||||||
|
organizationName = optional
|
||||||
|
organizationalUnitName = optional
|
||||||
|
commonName = supplied
|
||||||
|
emailAddress = optional
|
||||||
|
|
||||||
|
[ req ]
|
||||||
|
default_bits = 1024
|
||||||
|
default_keyfile = privkey.pem
|
||||||
|
distinguished_name = req_distinguished_name
|
||||||
|
attributes = req_attributes
|
||||||
|
x509_extensions = v3_ca # The extentions to add to the self signed cert
|
||||||
|
string_mask = nombstr
|
||||||
|
|
||||||
|
[ req_distinguished_name ]
|
||||||
|
countryName = Country Name (2 letter code)
|
||||||
|
countryName_default = CH
|
||||||
|
countryName_min = 2
|
||||||
|
countryName_max = 2
|
||||||
|
|
||||||
|
stateOrProvinceName = State or Province Name (full name)
|
||||||
|
stateOrProvinceName_default = Vaud
|
||||||
|
|
||||||
|
localityName = Locality Name (eg, city)
|
||||||
|
localityName_default = Nyon
|
||||||
|
|
||||||
|
0.organizationName = Organization Name (eg, company)
|
||||||
|
0.organizationName_default = GMO Lab (gmolab)
|
||||||
|
|
||||||
|
organizationalUnitName = Organizational Unit Name (eg, section)
|
||||||
|
|
||||||
|
organizationalUnitName_default = ITCS (Information Technology and Communications Service)
|
||||||
|
|
||||||
|
commonName = Common Name (eg, YOUR name)
|
||||||
|
commonName_default =
|
||||||
|
commonName_max = 64
|
||||||
|
|
||||||
|
emailAddress = Email Address
|
||||||
|
emailAddress_default = example@example.com
|
||||||
|
emailAddress_max = 40
|
||||||
|
|
||||||
|
[ req_attributes ]
|
||||||
|
challengePassword = A challenge password
|
||||||
|
challengePassword_min = 4
|
||||||
|
challengePassword_max = 20
|
||||||
|
|
||||||
|
unstructuredName = An optional company name
|
||||||
|
|
||||||
|
[ usr_cert ]
|
||||||
|
basicConstraints=CA:FALSE
|
||||||
|
nsComment = "OpenSSL Generated Certificate"
|
||||||
|
subjectKeyIdentifier=hash
|
||||||
|
authorityKeyIdentifier=keyid,issuer:always
|
||||||
|
|
||||||
|
[ v3_req ]
|
||||||
|
basicConstraints = CA:FALSE
|
||||||
|
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||||
|
|
||||||
|
[ v3_ca ]
|
||||||
|
subjectKeyIdentifier=hash
|
||||||
|
authorityKeyIdentifier=keyid:always,issuer:always
|
||||||
|
basicConstraints = CA:true
|
||||||
|
|
||||||
|
[ crl_ext ]
|
||||||
|
authorityKeyIdentifier=keyid:always,issuer:always
|
||||||
102
config/ca-config.tmpl
Normal file
102
config/ca-config.tmpl
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
HOME = .
|
||||||
|
RANDFILE = $ENV::HOME/.rnd
|
||||||
|
oid_section = new_oids
|
||||||
|
|
||||||
|
[ new_oids ]
|
||||||
|
|
||||||
|
[ ca ]
|
||||||
|
default_ca = CA_default # The default ca section
|
||||||
|
[ CA_default ]
|
||||||
|
dir = . # Where everything is kept
|
||||||
|
certs = $dir/certs # Where the issued certs are kept
|
||||||
|
crl_dir = $dir/crl # Where the issued crl are kept
|
||||||
|
database = $dir/dbca/index.txt # database index file.
|
||||||
|
new_certs_dir = $dir/newcerts # default place for new certs.
|
||||||
|
certificate = $dir/cacert.pem # The CA certificate
|
||||||
|
serial = $dir/serial/serial # The current serial number
|
||||||
|
crl = $dir/crl.pem # The current CRL
|
||||||
|
private_key = $dir/private/cakey.pem# The private key
|
||||||
|
RANDFILE = $dir/private/.rand # private random number file
|
||||||
|
x509_extensions = usr_cert # The extentions to add to the cert
|
||||||
|
default_days = 365 # how long to certify for
|
||||||
|
default_crl_days= 30 # how long before next CRL
|
||||||
|
default_md = md5 # which md to use.
|
||||||
|
preserve = no # keep passed DN ordering
|
||||||
|
policy = policy_match
|
||||||
|
|
||||||
|
[ policy_match ]
|
||||||
|
countryName = match
|
||||||
|
stateOrProvinceName = match
|
||||||
|
organizationName = match
|
||||||
|
organizationalUnitName = optional
|
||||||
|
commonName = supplied
|
||||||
|
emailAddress = optional
|
||||||
|
|
||||||
|
[ policy_anything ]
|
||||||
|
countryName = optional
|
||||||
|
stateOrProvinceName = optional
|
||||||
|
localityName = optional
|
||||||
|
organizationName = optional
|
||||||
|
organizationalUnitName = optional
|
||||||
|
commonName = supplied
|
||||||
|
emailAddress = optional
|
||||||
|
|
||||||
|
[ req ]
|
||||||
|
default_bits = 1024
|
||||||
|
default_keyfile = privkey.pem
|
||||||
|
distinguished_name = req_distinguished_name
|
||||||
|
attributes = req_attributes
|
||||||
|
x509_extensions = v3_ca # The extentions to add to the self signed cert
|
||||||
|
string_mask = nombstr
|
||||||
|
|
||||||
|
[ req_distinguished_name ]
|
||||||
|
countryName = Country Name (2 letter code)
|
||||||
|
countryName_default = %COUNTRY_NAME%
|
||||||
|
countryName_min = 2
|
||||||
|
countryName_max = 2
|
||||||
|
|
||||||
|
stateOrProvinceName = State or Province Name (full name)
|
||||||
|
stateOrProvinceName_default = %STATE_OF_PROVINCE_NAME%
|
||||||
|
|
||||||
|
localityName = Locality Name (eg, city)
|
||||||
|
localityName_default = %LOCALITY_NAME%
|
||||||
|
|
||||||
|
0.organizationName = Organization Name (eg, company)
|
||||||
|
0.organizationName_default = %ORGANIZITION_NAME%
|
||||||
|
|
||||||
|
organizationalUnitName = Organizational Unit Name (eg, section)
|
||||||
|
|
||||||
|
organizationalUnitName_default = %ORGANiZATION_UNIT_NAME%
|
||||||
|
|
||||||
|
commonName = Common Name (eg, YOUR name)
|
||||||
|
commonName_default = %COMMON_NAME%
|
||||||
|
commonName_max = 64
|
||||||
|
|
||||||
|
emailAddress = Email Address
|
||||||
|
emailAddress_default = %EMAIL_ADDRESS%
|
||||||
|
emailAddress_max = 40
|
||||||
|
|
||||||
|
[ req_attributes ]
|
||||||
|
challengePassword = A challenge password
|
||||||
|
challengePassword_min = 4
|
||||||
|
challengePassword_max = 20
|
||||||
|
|
||||||
|
unstructuredName = An optional company name
|
||||||
|
|
||||||
|
[ usr_cert ]
|
||||||
|
basicConstraints=CA:FALSE
|
||||||
|
nsComment = "OpenSSL Generated Certificate"
|
||||||
|
subjectKeyIdentifier=hash
|
||||||
|
authorityKeyIdentifier=keyid,issuer:always
|
||||||
|
|
||||||
|
[ v3_req ]
|
||||||
|
basicConstraints = CA:FALSE
|
||||||
|
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||||
|
|
||||||
|
[ v3_ca ]
|
||||||
|
subjectKeyIdentifier=hash
|
||||||
|
authorityKeyIdentifier=keyid:always,issuer:always
|
||||||
|
basicConstraints = CA:true
|
||||||
|
|
||||||
|
[ crl_ext ]
|
||||||
|
authorityKeyIdentifier=keyid:always,issuer:always
|
||||||
49
config/default.conf
Normal file
49
config/default.conf
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# Enables colorization (true) or disables it (false)
|
||||||
|
ENABLE_COLOR=true
|
||||||
|
|
||||||
|
# Path to the certificate authority's private key file
|
||||||
|
KEY_CA_PATH=/etc/pki/tls/private
|
||||||
|
|
||||||
|
# Path to the certificate authority's public key file
|
||||||
|
CRT_CA_PATH=/etc/pki/tls/certs
|
||||||
|
|
||||||
|
# Default number of days for the certificate's validity
|
||||||
|
# This can be overridden with the `-t or --days` option
|
||||||
|
# when running the script.
|
||||||
|
DAYS=365
|
||||||
|
|
||||||
|
# Variables to use for create ca-config file
|
||||||
|
# Country Name (2 letter code)
|
||||||
|
COUNTRY_NAME=CH
|
||||||
|
|
||||||
|
# State or province name (full name)
|
||||||
|
STATE_OR_PROVINCE_NAME=Vaud
|
||||||
|
|
||||||
|
# Locality name (eg, city)
|
||||||
|
LOCALITY_NAME=Nyon
|
||||||
|
|
||||||
|
# Organization name (eg, company)
|
||||||
|
ORGANIZATION_NAME="GMO Lab (gmolab)"
|
||||||
|
|
||||||
|
# Organizational Unit Name (eg, section)
|
||||||
|
ORGANIZATIONAL_UNIT_NAME="ITCS (Information Technology and Communications Service)"
|
||||||
|
|
||||||
|
# NOT USE. SET WITH PARAM -n from create-ca.sh script
|
||||||
|
# Common Name (eg, YOUR name)
|
||||||
|
COMMON_NAME="GMOLab CA"
|
||||||
|
|
||||||
|
# Email address
|
||||||
|
EMAIL_ADDRESS=example@example.com
|
||||||
|
|
||||||
|
# Debug
|
||||||
|
# false = debug inactive
|
||||||
|
# true = debug active
|
||||||
|
DEBUG=false
|
||||||
|
|
||||||
|
# Automatically answers yes to the questions
|
||||||
|
# 0 = Ask confirmation
|
||||||
|
# 1 = does not ask confirmation
|
||||||
|
ASSUME_YES=0
|
||||||
|
|
||||||
|
# Temp path for certificates files
|
||||||
|
CERTS_TMP_PATH=/tmp/ca
|
||||||
39
config/own-pki.conf
Normal file
39
config/own-pki.conf
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# Enables colorization (true) or disables it (false)
|
||||||
|
#ENABLE_COLOR=true
|
||||||
|
|
||||||
|
# Path to the certificate authority's private key file
|
||||||
|
#KEY_CA_PATH=/etc/pki/tls/private
|
||||||
|
|
||||||
|
# Path to the certificate authority's public key file
|
||||||
|
#CRT_CA_PATH=/etc/pki/tls/certs
|
||||||
|
|
||||||
|
# Default number of days for the certificate's validity
|
||||||
|
# This can be overridden with the `-t or --days` option
|
||||||
|
# when running the script.
|
||||||
|
#DAYS=365
|
||||||
|
|
||||||
|
# Variables to use for create ca-config file
|
||||||
|
# Country Name (2 letter code)
|
||||||
|
#COUNTRY_NAME=CH
|
||||||
|
|
||||||
|
# State or province name (full name)
|
||||||
|
#STATE_OR_PROVINCE_NAME=Vaud
|
||||||
|
|
||||||
|
# Locality name (eg, city)
|
||||||
|
#LOCALITY_NAME=Nyon
|
||||||
|
|
||||||
|
# Organization name (eg, company)
|
||||||
|
#ORGANIZATION_NAME="GMO Lab (gmolab)"
|
||||||
|
|
||||||
|
# Organizational Unit Name (eg, section)
|
||||||
|
#ORGANIZATIONAL_UNIT_NAME="ITCS (Information Technology and Communications Service)"
|
||||||
|
|
||||||
|
# NOT USE. SET WITH PARAM -n from create-ca.sh script
|
||||||
|
# Common Name (eg, YOUR name)
|
||||||
|
#COMMON_NAME="GMOLab CA"
|
||||||
|
|
||||||
|
# Email address
|
||||||
|
#EMAIL_ADDRESS=example@example.com
|
||||||
|
|
||||||
|
# Temp path for certificates files
|
||||||
|
#CERTS_TMP_PATH=/tmp/ca
|
||||||
11
lib/check-rc.sh
Normal file
11
lib/check-rc.sh
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# check if run from script
|
||||||
|
[[ "${BASH_SOURCE[0]}" == "${0}" ]] && exit 1
|
||||||
|
|
||||||
|
check_rc(){
|
||||||
|
if [ "$1" != "0" ]; then
|
||||||
|
msg_error "Error (RC:$rc)"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
msg_ok "OK"
|
||||||
|
fi
|
||||||
|
}
|
||||||
51
lib/core.sh
Normal file
51
lib/core.sh
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# check if run from script
|
||||||
|
[[ "${BASH_SOURCE[0]}" == "${0}" ]] && exit 1
|
||||||
|
|
||||||
|
init_default(){
|
||||||
|
# read default conf file
|
||||||
|
DEFAULT_CONF="${ROOT_DIR}/config/default.conf"
|
||||||
|
[[ -f "$DEFAULT_CONF" ]] && source "$DEFAULT_CONF"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
init_env() {
|
||||||
|
# read config file
|
||||||
|
CONFIG_FILE="/etc/own-pki/own-pki.conf"
|
||||||
|
[[ -f "$CONFIG_FILE" ]] && source "$CONFIG_FILE" || msg_error "File ${ORANGE}$CONFIG_FILE${RED} missing. Run 'sudo bin/install.sh'${NC}"
|
||||||
|
|
||||||
|
# debug mode
|
||||||
|
if [[ "${DEBUG:-false}" == "true" ]]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
out_tmp=$(mktemp)
|
||||||
|
err_tmp=$(mktemp)
|
||||||
|
}
|
||||||
|
|
||||||
|
clean_string() {
|
||||||
|
echo "$1" | \
|
||||||
|
# translate special chars to closest ASCII (e.g., 'é' -> 'e')
|
||||||
|
iconv -f utf-8 -t ascii//TRANSLIT | \
|
||||||
|
# convert to lowercase
|
||||||
|
tr '[:upper:]' '[:lower:]' | \
|
||||||
|
# replace any non-alphanumeric character with an underscore
|
||||||
|
sed -E 's/[^a-z0-9]+/_/g' | \
|
||||||
|
# replace multiple underscores into one
|
||||||
|
sed -E 's/(_)+/_/g' | \
|
||||||
|
# remove underscores at the beginning or end
|
||||||
|
sed -E 's/^_|_$//g'
|
||||||
|
}
|
||||||
|
|
||||||
|
check_sudo(){
|
||||||
|
# check if user has sudo rigth
|
||||||
|
if sudo ! -n true 2>/dev/null; then
|
||||||
|
msg_error "\nAccess denied: user $USER does not have sudo privileges or a password is required.\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if the effective user ID is 0 (root)
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
msg_error "\nThis script must be run as root or with sudo.\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
13
lib/error.sh
Normal file
13
lib/error.sh
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
trap 'on_error $LINENO' ERR
|
||||||
|
|
||||||
|
on_error() {
|
||||||
|
local exit_code=$?
|
||||||
|
local line="$1"
|
||||||
|
local cmd="${BASH_COMMAND}"
|
||||||
|
|
||||||
|
log_error "Error (code: $exit_code)"
|
||||||
|
log_error "Line: $line"
|
||||||
|
log_error "Command: $cmd"
|
||||||
|
|
||||||
|
exit "$exit_code"
|
||||||
|
}
|
||||||
23
lib/log.sh
Normal file
23
lib/log.sh
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# check if run from script
|
||||||
|
[[ "${BASH_SOURCE[0]}" == "${0}" ]] && exit 1
|
||||||
|
|
||||||
|
LOG_FILE=""
|
||||||
|
|
||||||
|
init_logs() {
|
||||||
|
LOG_DIR="${ROOT_DIR}/logs"
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
LOG_FILE="${LOG_DIR}/app.log"
|
||||||
|
}
|
||||||
|
|
||||||
|
_log() {
|
||||||
|
local level="$1"
|
||||||
|
local message="$2"
|
||||||
|
local timestamp
|
||||||
|
timestamp="$(date '+%Y-%m-%d %H:%M:%S')"
|
||||||
|
|
||||||
|
echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info() { _log "INFO" "$1"; }
|
||||||
|
log_warn() { _log "WARN" "$1"; }
|
||||||
|
log_error() { _log "ERROR" "$1"; }
|
||||||
28
lib/message.sh
Normal file
28
lib/message.sh
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# check if run from script
|
||||||
|
[[ "${BASH_SOURCE[0]}" == "${0}" ]] && exit 1
|
||||||
|
|
||||||
|
_message(){
|
||||||
|
case $1 in
|
||||||
|
INFO)
|
||||||
|
echo -e "${NC}$2${NC}"
|
||||||
|
;;
|
||||||
|
OK)
|
||||||
|
echo -e "${GREEN}$2${NC}"
|
||||||
|
;;
|
||||||
|
ASK)
|
||||||
|
echo -e -n "${CYAN}$2${NC}"
|
||||||
|
;;
|
||||||
|
WARN)
|
||||||
|
echo -e "${ORANGE}$2${NC}"
|
||||||
|
;;
|
||||||
|
ERROR)
|
||||||
|
echo -e "${RED}$2${NC}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_info() { _message "INFO" "$1"; }
|
||||||
|
msg_ok() { _message "OK" "$1"; }
|
||||||
|
msg_ask() { _message "ASK" "$1"; }
|
||||||
|
msg_warn() { _message "WARN" "$1"; }
|
||||||
|
msg_error() { _message "ERROR" "$1"; }
|
||||||
25
lib/set-color.sh
Normal file
25
lib/set-color.sh
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# check if run from script
|
||||||
|
[[ "${BASH_SOURCE[0]}" == "${0}" ]] && exit 1
|
||||||
|
|
||||||
|
#-----------------------------------------------------------
|
||||||
|
# set colors
|
||||||
|
# RED Error
|
||||||
|
# ORANGE Attention or color for parameters when
|
||||||
|
# confirmation
|
||||||
|
# CYAN Ask to useer
|
||||||
|
# GREEN OK
|
||||||
|
set_color(){
|
||||||
|
if [[ "$ENABLE_COLOR" == "true" ]]; then
|
||||||
|
RED='\e[0;31m'
|
||||||
|
ORANGE='\e[0;33m'
|
||||||
|
CYAN='\e[0;36m'
|
||||||
|
GREEN='\e[0;32m'
|
||||||
|
NC='\e[0m'
|
||||||
|
else
|
||||||
|
RED=''
|
||||||
|
ORANGE=''
|
||||||
|
CYAN=''
|
||||||
|
GREEN=''
|
||||||
|
NC=''
|
||||||
|
fi
|
||||||
|
}
|
||||||
11
lib/stdlib.sh
Normal file
11
lib/stdlib.sh
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# scripts and lib
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||||
|
|
||||||
|
#source "$ROOT_DIR/lib/log.sh"
|
||||||
|
#source "$ROOT_DIR/lib/error.sh"
|
||||||
|
source "$ROOT_DIR/lib/core.sh"
|
||||||
|
source "$ROOT_DIR/lib/set-color.sh"
|
||||||
|
source "$ROOT_DIR/lib/message.sh"
|
||||||
|
source "$ROOT_DIR/lib/check-rc.sh"
|
||||||
|
source "$ROOT_DIR/lib/yes-no.sh"
|
||||||
14
lib/yes-no.sh
Normal file
14
lib/yes-no.sh
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# check if run from script
|
||||||
|
[[ "${BASH_SOURCE[0]}" == "${0}" ]] && exit 1
|
||||||
|
|
||||||
|
yes_no(){
|
||||||
|
if [ "$ASSUME_YES" == "0" ]; then
|
||||||
|
echo -n -e "${CYAN}$1 [y/N]? ${NC}"
|
||||||
|
unset answer
|
||||||
|
read answer
|
||||||
|
if [ "${answer}" != "y" ]; then
|
||||||
|
echo -e "${ORANGE}Canceled!${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
15
logs/app.log
Normal file
15
logs/app.log
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[2026-04-18 13:51:26] [ERROR] ❌ Erreur (code: 127)
|
||||||
|
[2026-04-18 13:51:26] [ERROR] 📍 Ligne: 77
|
||||||
|
[2026-04-18 13:51:26] [ERROR] 💥 Commande: risky_function
|
||||||
|
[2026-04-18 13:54:55] [ERROR] ❌ Error (code: 127)
|
||||||
|
[2026-04-18 13:54:55] [ERROR] 📍 Line: 77
|
||||||
|
[2026-04-18 13:54:55] [ERROR] 💥 Command: risky_function
|
||||||
|
[2026-04-18 13:55:28] [ERROR] ❌ Error (code: 1)
|
||||||
|
[2026-04-18 13:55:28] [ERROR] 📍 Line: 77
|
||||||
|
[2026-04-18 13:55:28] [ERROR] 💥 Command: false
|
||||||
|
[2026-04-18 14:16:23] [ERROR] Error (code: 127)
|
||||||
|
[2026-04-18 14:16:23] [ERROR] Line: 77
|
||||||
|
[2026-04-18 14:16:23] [ERROR] Command: message_info "info"
|
||||||
|
[2026-04-18 14:25:42] [ERROR] Error (code: 127)
|
||||||
|
[2026-04-18 14:25:42] [ERROR] Line: 87
|
||||||
|
[2026-04-18 14:25:42] [ERROR] Command: 3echo -e "\n"
|
||||||
Loading…
x
Reference in New Issue
Block a user