Compare commits

...

18 Commits
master ... dev

Author SHA1 Message Date
Jérémy Dubois fdf9357792 Fix mode of shellpki script in README file when installing it 2022-12-13 19:40:52 +01:00
Jérémy Dubois d04d68f6cb Release 22.12.2 2022-12-13 17:46:50 +01:00
Jérémy Dubois 514cd2e50f Defaults default_crl_days to 2 years instead of 1 2022-12-13 17:43:45 +01:00
Jérémy Dubois 30ef252ff5 Fix ${CRL} and ${CA_DIR} rights so that CRL file can be read by openvpn 2022-12-13 17:41:31 +01:00
Jérémy Dubois e0c29cfcf1 Release 22.12.1 2022-12-02 18:04:11 +01:00
Jérémy Dubois 2afa4ab449 update CHANGELOG 2022-12-02 16:32:22 +01:00
Jérémy Dubois a750b71e05 Fix path variables in cert-expirations.sh 2022-12-02 16:15:18 +01:00
Jérémy Dubois 24249d829c cert-expirations.sh: check CARP state only when checking ca and certs expirations 2022-12-02 15:08:31 +01:00
Jérémy Dubois 7382947fc3 Release 22.12 2022-12-01 16:50:41 +01:00
Jérémy Dubois bd5e02bb87 Use functions in cert-expirations.sh 2022-12-01 16:42:35 +01:00
Jérémy Dubois e33722d440 Improved cert-expirations.sh for better readability of its ouput 2022-12-01 15:35:11 +01:00
Jérémy Dubois 467ea5fe3d update CHANGELOG 2022-09-06 14:36:14 +02:00
Jérémy Dubois 3b3e0b01bf Merge branch 'openssl-pkey' into dev 2022-09-06 14:29:30 +02:00
Jérémy Dubois 34b53e63f2 The key file can be read and written only by the owner 2022-08-31 11:35:12 +02:00
Jérémy Dubois e886ca9549 Update README : how to create or revoke many certificates at once 2022-08-09 15:48:20 +02:00
Jérémy Dubois 5f792272c6 update CHANGELOG file 2022-07-13 11:20:01 +02:00
Brice Waegeneire f58712f2b3 create index.txt.attr file 2022-07-11 11:09:37 +02:00
Mathieu Trossevin 38aac7b137
Use genpkey and pkey instead of genrsa and rsa
genrsa and rsa are being deprecated by OpenSSL and both genpkey and pkey
provides the same functionalities as genrsa and rsa will being more
configurable.
2022-04-06 11:40:17 +02:00
5 changed files with 196 additions and 39 deletions

View File

@ -12,10 +12,44 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
* Fix mode of shellpki script in README file when installing it
### Removed
### Security
## [22.12.2] 2022-12-13
### Changed
* Defaults default_crl_days to 2 years instead of 1
### Fixed
* Fix ${CRL} and ${CA_DIR} rights so that CRL file can be read by openvpn
## [22.12.1] 2022-12-02
### Fixed
* cert-expirations.sh: check CARP state only when checking ca and certs expirations
* Fix path variables in cert-expirations.sh
## [22.12] 2022-12-01
### Added
* The key file can be read and written only by the owner
### Changed
* Use genpkey and pkey instead of genrsa and rsa
* Improved cert-expirations.sh for better readability of its ouput
### Fixed
* Create index.txt.attr file
## [22.04] 2022-04-14
### Added

View File

@ -16,7 +16,7 @@ be copied to [ansible-roles/openvpn](https://gitea.evolix.org/evolix/ansible-rol
useradd shellpki --system -M --home-dir /etc/shellpki --shell /usr/sbin/nologin
mkdir /etc/shellpki
install -m 0640 openssl.cnf /etc/shellpki/
install -m 0755 shellpki /usr/local/sbin/shellpki
install -m 0750 shellpki /usr/local/sbin/shellpki
chown -R shellpki: /etc/shellpki
~~~
@ -31,7 +31,7 @@ chown -R shellpki: /etc/shellpki
useradd -r 1..1000 -d /etc/shellpki -s /sbin/nologin _shellpki
mkdir /etc/shellpki
install -m 0640 openssl.cnf /etc/shellpki/
install -m 0755 shellpki /usr/local/sbin/shellpki
install -m 0750 shellpki /usr/local/sbin/shellpki
chown -R _shellpki:_shellpki /etc/shellpki
~~~
@ -137,6 +137,24 @@ Show help :
shellpki help
~~~
## Loop
We can loop over a file to revoke or create many certificates at once.
To revoke :
~~~
$ read CA_PASS
$ for cert_name in $(cat /path/to/file_certs_to_revoke); do CA_PASSWORD=$CA_PASS shellpki revoke $cert_name --non-interactive ; done
~~~
To create (without `--replace-existing`) or renew (with `--replace-existing`), with a password on the client key :
~~~
$ read CA_PASS
$ for cert_name in $(cat /path/to/file_certs_to_create); do apg -n 1 -m 16 -M lcN > /path/to/folder/to/store/${cert_name}.passwd; CA_PASSWORD=$CA_PASS shellpki create --replace-existing --non-interactive --password-file /path/to/folder/to/store/${cert_name}.passwd ${cert_name}; done
~~~
## License
ShellPKI is an [Evolix](https://evolix.com) project and is licensed

View File

@ -1,28 +1,126 @@
#!/bin/sh
VERSION="22.04"
VERSION="22.12.1"
carp=$(/sbin/ifconfig carp0 2>/dev/null | grep 'status' | cut -d' ' -f2)
show_version() {
cat <<END
cert-expirations.sh version ${VERSION}
if [ "$carp" = "backup" ]; then
exit 0
fi
Copyright 2020-2022 Evolix <info@evolix.fr>,
Jérémy Lecour <jlecour@evolix.fr>,
Jérémy Dubois <jdubois@evolix.fr>
and others.
echo "Warning : all times are in UTC !\n"
cert-expirations.sh comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
See the MIT Licence for details.
END
}
echo "CA certificate:"
openssl x509 -enddate -noout -in /etc/shellpki/cacert.pem \
| cut -d '=' -f 2 \
| sed -e "s/^\(.*\)\ \(20..\).*/- \2 \1/"
show_usage() {
cat <<END
Usage: ${0} [--version]
END
}
echo ""
check_carp_state() {
if [ "${SYSTEM}" = "openbsd" ]; then
carp=$(/sbin/ifconfig carp0 2>/dev/null | grep 'status' | cut -d' ' -f2)
echo "Client certificates:"
cat /etc/shellpki/index.txt \
| grep ^V \
| awk -F "/" '{print $1,$5}' \
| awk '{print $2,$5}' \
| sed 's/CN=//' \
| sed -E 's/([[:digit:]]{2})([[:digit:]]{2})([[:digit:]]{2})([[:digit:]]{2})([[:digit:]]{2})([[:digit:]]{2})Z (.*)/- 20\1 \2 \3 \4:\5:\6 \7/' \
| awk '{if ($3 == "01") $3="Jan"; else if ($3 == "02") $3="Feb"; else if ($3 == "03") $3="Mar"; else if ($3 == "04") $3="Apr"; else if ($3 == "05") $3="May"; else if ($3 == "06") $3="Jun"; else if ($3 == "07") $3="Jul"; else if ($3 == "08") $3="Aug"; else if ($3 == "09") $3="Sep"; else if ($3 == "10") $3="Oct"; else if ($3 == "11") $3="Nov"; else if ($3 == "12") $3="Dec"; print $0;}' \
| sort -n -k 2 -k 3M -k 4
if [ "$carp" = "backup" ]; then
exit 0
fi
fi
}
check_ca_expiration() {
echo "CA certificate:"
openssl x509 -enddate -noout -in ${cacert_path} \
| cut -d '=' -f 2 \
| sed -e "s/^\(.*\)\ \(20..\).*/- \2 \1/"
}
check_certs_expiration() {
# Syntax "cmd | { while read line; do var="foo"; done echo $var }" needed, otherwise $var is empty at the end of while loop
grep ^V ${index_path} \
| awk -F "/" '{print $1,$5}' \
| awk '{print $2,$5}' \
| sed 's/CN=//' \
| sed -E 's/([[:digit:]]{2})([[:digit:]]{2})([[:digit:]]{2})([[:digit:]]{2})([[:digit:]]{2})([[:digit:]]{2})Z (.*)/- 20\1 \2 \3 \4:\5:\6 \7/' \
| awk '{if ($3 == "01") $3="Jan"; else if ($3 == "02") $3="Feb"; else if ($3 == "03") $3="Mar"; else if ($3 == "04") $3="Apr"; else if ($3 == "05") $3="May"; else if ($3 == "06") $3="Jun"; else if ($3 == "07") $3="Jul"; else if ($3 == "08") $3="Aug"; else if ($3 == "09") $3="Sep"; else if ($3 == "10") $3="Oct"; else if ($3 == "11") $3="Nov"; else if ($3 == "12") $3="Dec"; print $0;}' \
| sort -n -k 2 -k 3M -k 4 | {
while read -r line; do
# Predicting expirations - OpenBSD case (date is not the same than in Linux)
if [ "${SYSTEM}" = "openbsd" ]; then
# Already expired if expiration date is before now
if [ "$(TZ=:Zulu date -jf "%Y %b %d %H:%M:%S" "$(echo "$line" | awk '{print $2,$3,$4,$5}')" +%s)" -le "$(date +%s)" ]; then
expired_certs="${expired_certs}$line\n"
# Expiring soon if expiration date is after now and before now + $somedays days
elif [ "$(TZ=:Zulu date -jf "%Y %b %d %H:%M:%S" "$(echo "$line" | awk '{print $2,$3,$4,$5}')" +%s)" -gt "$(date +%s)" ] && [ "$(TZ=:Zulu date -jf "%Y %b %d %H:%M:%S" "$(echo "$line" | awk '{print $2,$3,$4,$5}')" +%s)" -lt "$(($(date +%s) + somedays))" ]; then
expiring_soon_certs="${expiring_soon_certs}$line\n"
# Still valid for a time if expiration date is after now + $somedays days
elif [ "$(TZ=:Zulu date -jf "%Y %b %d %H:%M:%S" "$(echo "$line" | awk '{print $2,$3,$4,$5}')" +%s)" -ge "$(($(date +%s) + somedays))" ]; then
still_valid_certs="${still_valid_certs}$line\n"
fi
# Non OpenBSD cases
else
# Already expired if expiration date is before now
if [ "$(TZ=:Zulu date -d "$(echo "$line" | awk '{print $3,$4,$2,$5}')" +%s)" -le "$(date +%s)" ]; then
expired_certs="${expired_certs}$line\n"
# Expiring soon if expiration date is after now and before now + $somedays days
elif [ "$(TZ=:Zulu date -d "$(echo "$line" | awk '{print $3,$4,$2,$5}')" +%s)" -gt "$(date +%s)" ] && [ "$(TZ=:Zulu date -d "$(echo "$line" | awk '{print $3,$4,$2,$5}')" +%s)" -lt "$(($(date +%s) + somedays))" ]; then
expiring_soon_certs="${expiring_soon_certs}$line\n"
# Still valid for a time if expiration date is after now + $somedays days
elif [ "$(TZ=:Zulu date -d "$(echo "$line" | awk '{print $3,$4,$2,$5}')" +%s)" -ge "$(($(date +%s) + somedays))" ]; then
still_valid_certs="${still_valid_certs}$line\n"
fi
fi
done
echo "Expired client certificates:"
echo "${expired_certs}"
echo "Valid client certificates expiring soon (in less than $((somedays / 60 / 60 / 24)) days):"
echo "${expiring_soon_certs}"
echo "Valid client certificates expiring later (in more than $((somedays / 60 / 60 / 24)) days):"
echo "${still_valid_certs}"
}
}
main() {
SYSTEM=$(uname | tr '[:upper:]' '[:lower:]')
cacert_path="/etc/shellpki/cacert.pem"
index_path="/etc/shellpki/index.txt"
somedays="3456000" # 40 days currently
expired_certs=""
expiring_soon_certs=""
still_valid_certs=""
case "$1" in
version|--version)
show_version
exit 0
;;
help|--help)
show_usage
exit 0
;;
"")
check_carp_state
echo "Warning : all times are in UTC !"
echo ""
check_ca_expiration
echo ""
check_certs_expiration
;;
*)
show_usage >&2
exit 1
;;
esac
}
main "$@"

View File

@ -1,4 +1,4 @@
# VERSION="22.04"
# VERSION="22.12.2"
[ ca ]
default_ca = CA_default
@ -14,7 +14,7 @@ crl = $dir/crl.pem
private_key = $dir/cakey.key
RANDFILE = $dir/.rand
default_days = 365
default_crl_days= 365
default_crl_days= 730
default_md = sha256
preserve = no
policy = policy_match

View File

@ -5,7 +5,7 @@
set -u
VERSION="22.04"
VERSION="22.12.2"
show_version() {
cat <<END
@ -137,14 +137,14 @@ warning() {
}
verify_ca_password() {
"${OPENSSL_BIN}" rsa \
"${OPENSSL_BIN}" pkey \
-in "${CA_KEY}" \
-passin pass:"${CA_PASSWORD}" \
>/dev/null 2>&1
}
get_real_path() {
# --canonicalize is supported on Linux
# -f is supported on Linux and OpenBSD
# -f is supported on Linux and OpenBSD
readlink -f -- "${1}"
}
@ -224,9 +224,10 @@ replace_existing_or_abort() {
init() {
umask 0177
[ -d "${CA_DIR}" ] || mkdir -m 0750 "${CA_DIR}"
[ -d "${CA_DIR}" ] || mkdir -m 0751 "${CA_DIR}"
[ -d "${CRT_DIR}" ] || mkdir -m 0750 "${CRT_DIR}"
[ -f "${INDEX_FILE}" ] || touch "${INDEX_FILE}"
[ -f "${INDEX_FILE}.attr" ] || touch "${INDEX_FILE}.attr"
[ -f "${CRL}" ] || touch "${CRL}"
[ -f "${SERIAL}" ] || echo "01" > "${SERIAL}"
@ -278,17 +279,18 @@ init() {
passout_arg=""
if [ -n "${CA_PASSWORD:-}" ]; then
passout_arg="-passout pass:${CA_PASSWORD}"
passout_arg="-pass pass:${CA_PASSWORD}"
elif [ "${non_interactive}" -eq 1 ]; then
error "In non-interactive mode, you must pass CA_PASSWORD as environment variable."
fi
if [ ! -f "${CA_KEY}" ]; then
"${OPENSSL_BIN}" genrsa \
"${OPENSSL_BIN}" genpkey \
-algorithm RSA \
-out "${CA_KEY}" \
${passout_arg} \
-aes256 \
"${CA_KEY_LENGTH}" \
-pkeyopt "rsa_keygen_bits:${CA_KEY_LENGTH}" \
>/dev/null 2>&1
# shellcheck disable=SC2181
if [ "$?" -ne 0 ]; then
@ -355,9 +357,10 @@ ocsp() {
port=$(echo "${ocsp_uri}" | cut -d':' -f2)
if [ ! -f "${OCSP_KEY}" ]; then
"${OPENSSL_BIN}" genrsa \
"${OPENSSL_BIN}" genpkey \
-algorithm RSA \
-out "${OCSP_KEY}" \
"${KEY_LENGTH}" \
-pkeyopt "rsa_keygen_bits:${KEY_LENGTH}" \
>/dev/null 2>&1
# shellcheck disable=SC2181
if [ "$?" -ne 0 ]; then
@ -680,17 +683,19 @@ create() {
# generate private key
pass_args=""
if [ -n "${password_file:-}" ]; then
pass_args="-aes256 -passout file:${password_file}"
pass_args="-aes256 -pass file:${password_file}"
elif [ -n "${PASSWORD:-}" ]; then
pass_args="-aes256 -passout pass:${PASSWORD}"
pass_args="-aes256 -pass pass:${PASSWORD}"
fi
"${OPENSSL_BIN}" genrsa \
"${OPENSSL_BIN}" genpkey \
-algorithm RSA \
-out "${key_file}" \
${pass_args} \
"${KEY_LENGTH}" \
-pkeyopt "rsa_keygen_bits:${KEY_LENGTH}" \
>/dev/null 2>&1
# shellcheck disable=SC2181
if [ "$?" -eq 0 ]; then
chmod 600 "${key_file}"
echo "The KEY file is available at \`${key_file}'"
else
error "Error generating the private key"
@ -1098,9 +1103,11 @@ main() {
# fix right
chown -R "${PKI_USER}":"${PKI_USER}" "${CA_DIR}"
chmod 750 "${CA_DIR}" "${CRT_DIR}" "${KEY_DIR}" "${CSR_DIR}" "${PKCS12_DIR}" "${OVPN_DIR}" "${TMP_DIR}"
chmod 600 "${INDEX_FILE}"* "${SERIAL}"* "${CA_KEY}" "${CRL}"
chmod 750 "${CRT_DIR}" "${KEY_DIR}" "${CSR_DIR}" "${PKCS12_DIR}" "${OVPN_DIR}" "${TMP_DIR}"
chmod 600 "${INDEX_FILE}"* "${SERIAL}"* "${CA_KEY}"
chmod 640 "${CA_CERT}"
chmod 604 "${CRL}"
chmod 751 "${CA_DIR}"
}
main "$@"