#!/usr/bin/env bash script_dir="$(dirname $(realpath $0))" log_file="$(mktemp)" _date="$(date +%Y-%m-%d-%H%M)" key_names_reserverd="ta ca server" # - For checking if revokation was successfull # - _CHECK_DIR="$(mktemp -d)" _RT_CERT="${_CHECK_DIR}/revoke-test.pem" #--------------------------------------- #----------------------------- # Some functions #----------------------------- #--------------------------------------- clean_up() { # Perform program exit housekeeping rm $log_file rm -rf $_CHECK_DIR blank_line exit $1 } blank_line() { if $terminal ; then echo "" fi } is_number() { return $(test ! -z "${1##*[!0-9]*}" > /dev/null 2>&1); # - also possible # - #[[ ! -z "${1##*[!0-9]*}" ]] && return 0 || return 1 #return $([[ ! -z "${1##*[!0-9]*}" ]]) } is_int() { return $(test "$@" -eq "$@" > /dev/null 2>&1); } echononl(){ echo X\\c > /tmp/shprompt$$ if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then echo -e -n "$*\\c" 1>&2 else echo -e -n "$*" 1>&2 fi rm /tmp/shprompt$$ } error(){ echo "" echo -e "\t[ \033[31m\033[1mError\033[m ]: $*" echo "" } fatal(){ echo "" echo -e "\t[ \033[31m\033[1mFatal\033[m ]: $*" echo "" echo -e "\t\033[37m\033[1mscript will be interrupted\033[m\033[m" echo "" clean_up 1 } warn (){ echo "" echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*" echo "" } info (){ echo "" echo -e "\t[ \033[32m\033[1mInfo\033[m ]: $*" echo "" } echo_done() { echo -e "\033[80G[ \033[32mdone\033[m ]" } echo_ok() { echo -e "\033[80G[ \033[32mok\033[m ]" } echo_warning() { echo -e "\033[80G[ \033[33m\033[1mwarn\033[m ]" } echo_failed(){ echo -e "\033[80G[ \033[1;31mfailed\033[m ]" } echo_skipped() { echo -e "\033[80G[ \033[37mskipped\033[m ]" } trap clean_up SIGHUP SIGINT SIGTERM # ------------- # --- Check some prerequisites # ------------- # -Is systemd supported on this system? # - systemd_supported=false systemd=$(which systemd) systemctl=$(which systemctl) if [[ -n "$systemd" ]] && [[ -n "$systemctl" ]] ; then systemd_supported=true fi clear echo "" echo -e "\033[21G\033[32mRevoke OpenVPN key.. \033[m" echo "" echo "" declare -a conf_file_arr=() declare -a conf_name_arr=() for _conf_file in `ls ${script_dir}/conf/server-*.conf 2>/dev/null` ; do conf_file_arr+=("${_conf_file}") _basename=$(basename $_conf_file) _tmp_name=${_basename%%.*} _tmp_name=${_tmp_name#*-} conf_name_arr+=("$_tmp_name") done if [[ ${#conf_file_arr[@]} -lt 1 ]] ; then fatal "NO Configuration found!" fi echo "" declare -i i=0 if [[ ${#conf_file_arr[@]} -gt 1 ]] ; then echo "" echo "Which Configuration should be loaded?" echo "" for _conf_file in ${conf_file_arr[@]} ; do echo " [${i}] ${conf_name_arr[${i}]}" (( i++ )) done _OK=false echo echononl "Eingabe: " while ! $_OK ; do read _IN if is_number "$_IN" && [[ -n ${conf_file_arr[$_IN]} ]]; then conf_file=${conf_file_arr[$_IN]} _OK=true else echo "" echo -e "\tFalsche Eingabe !" echo "" echononl "Eingabe: " fi done else conf_file=${conf_file_arr[0]} fi echo "" echo -e "\033[32m--\033[m" echo "" #--------------------------------------- #----------------------------- # Read Configurations from $conf_file #----------------------------- #--------------------------------------- echononl " Load Configuration File $(basename ${conf_file}).." if [[ ! -f "$conf_file" ]]; then echo_failed fatal "Configuration file \033[37m\033[1m$(basename ${conf_file})\033[m not found!" else source "${conf_file}" > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed fatal "$(cat $log_file)" fi fi EASY_RSA_DIR="${OPENVPN_BASE_DIR}/easy-rsa" if [[ -d "${OPENVPN_BASE_DIR}/pki" ]] ; then EASYRSA_LAYOUT_NEW=true else EASYRSA_LAYOUT_NEW=false fi if [[ -z "$OPENVPN_KEY_DIR" ]] ; then if $EASYRSA_LAYOUT_NEW ; then OPENVPN_KEY_DIR="${OPENVPN_BASE_DIR}/pki" else OPENVPN_KEY_DIR="${OPENVPN_BASE_DIR}/keys" fi fi echo "" echo -e "\033[32m--\033[m" echo "" KEY_NAME_TO_REVOKE="" if [ -z "$KEY_NAME_TO_REVOKE" ]; then echo "Insert key name you wish to revoke." echo "" echo "" echononl "key name to revoke: " read KEY_NAME_TO_REVOKE while [ "X$KEY_NAME_TO_REVOKE" = "X" ] ; do echo -e "\n\t\033[33m\033[1mKey name is required!\033[m\n" echononl "key name: " read KEY_NAME_TO_REVOKE done fi # - Remove '${KEY_CN}-' from key name # - KEY_NAME_TO_REVOKE="${KEY_NAME_TO_REVOKE/${KEY_CN}-/}" _CLIENT_CN="${KEY_CN}-${KEY_NAME_TO_REVOKE}" if $EASYRSA_LAYOUT_NEW ; then _CLIENT_CERT="${OPENVPN_KEY_DIR}/issued/${_CLIENT_CN}.crt" _CLIENT_KEY="${OPENVPN_KEY_DIR}/private/${_CLIENT_CN}.key" else _CLIENT_CERT="${OPENVPN_KEY_DIR}/${KEY_NAME_TO_REVOKE}.crt" _CLIENT_KEY="${OPENVPN_KEY_DIR}/${KEY_NAME_TO_REVOKE}.key" fi _CRL="${OPENVPN_KEY_DIR}/crl.pem" _CA_CERT="${OPENVPN_KEY_DIR}/ca.crt" for _name in $key_names_reserverd ; do [[ "$_name" = "$KEY_NAME_TO_REVOKE" ]] && fatal "Name '$KEY_NAME_TO_REVOKE' cannot be used - its a reserved name!" done if [[ ! -f "${_CLIENT_CERT}" ]]; then fatal "Key '$KEY_NAME_TO_REVOKE' not found!" fi echo "" echo -e "\033[32m--\033[m" echo "" echo "Key to revoke...........: $(basename "$_CLIENT_KEY")" info "Going to revoke key \033[37m\033[1m$(basename "$_CLIENT_KEY")\033[m.." echo -n "To continue type uppercase 'YES': " read OK echo "" if [[ "$OK" != "YES" ]] ; then fatal "Abort by user request - Answer as not 'YES'" fi #--------------------------------------- #----------------------------- # Revoke Key #----------------------------- #--------------------------------------- echo "" # --- # - Backup existing OpenVPN directory # --- echononl "Backup existing OpenVPN directory '$OPENVPN_BASE_DIR'.." if [[ -d "$OPENVPN_BASE_DIR" ]]; then cp -a "$OPENVPN_BASE_DIR" "${OPENVPN_BASE_DIR}.$_date" > "$log_file" 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fatal "$(cat $log_file)" fi else echo_skipped fatal "OpenVPN directory '$OPENVPN_BASE_DIR' not found!" fi echononl "Backup cert to revoke for further check. (see below" cp -a "$_CLIENT_CERT" "$_CHECK_DIR" > "$log_file" 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fatal "$(cat $log_file)" fi if $EASYRSA_LAYOUT_NEW ; then # --- # - Revoke Key # --- echononl "Revoke key '$(basename "$_CLIENT_KEY")'.." $EASY_RSA_DIR/easyrsa revoke "$_CLIENT_CN" > "$log_file" 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" fi # --- # - Generate new crl.pem # --- echononl "Generate new CRL (Certificate Revokation List) 'crl.pem'.." $EASY_RSA_DIR/easyrsa gen-crl > "$log_file" 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" fi else # --- # - source file vars # --- echononl " Load configuration '${EASY_RSA_DIR}/vars'.." source ${EASY_RSA_DIR}/vars > "$log_file" 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" fi if [[ -z "$KEY_CONFIG" ]] ; then if [[ -h "${EASY_RSA_DIR}/openssl.cnf" ]] ; then KEY_CONFIG="$(realpath "${EASY_RSA_DIR}/openssl.cnf")" fi fi if [[ -z "$KEY_CONFIG" ]] ; then fatal "No OpenSSL configuration file found.." fi # --- # - Revoke Key # --- echo "" echo -e "\033[32m--\033[m" echo "Revoke Key ${KEY_NAME_TO_REVOKE}.key .." echo -e "\033[32m--\033[m" echo "" echononl "Revoke key ${KEY_NAME_TO_REVOKE}.key and update data base .." $OPENSSL ca -revoke "${_CLIENT_CERT}" -config "$KEY_CONFIG" > "$log_file" 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fatal "$(cat $log_file)" fi echononl "Generate a new CRL -- try to be compatible with intermediate PKIs" $OPENSSL ca -gencrl -out "$_CRL" -config "$KEY_CONFIG" > "$log_file" 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fatal "$(cat $log_file)" fi fi # --- # - Change group (nogroup) for file 'crl.pem' # --- echononl "Change group (to nogroup) for '${OPENVPN_KEY_DIR}/crl.pem'.." chgrp nogroup "${_CRL}" > "$log_file" 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" fi # --- # - Change permission (640) for file 'crl.pem' # --- echononl "Change permissions (640) for ${OPENVPN_KEY_DIR}/crl.pem" chmod 640 "${_CRL}" > "$log_file" 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" fi # --- # - Check if Revokation was sucessfully. # --- echo "" echo -e "\033[32m--\033[m" echo "Check if Revokation of Key $(basename "$_CLIENT_KEY") was sucessfully.." echo -e "\033[32m--\033[m" echo "" # - "Create CA file '$_RT_CERT' including (new) $_CRL to check against.. # - echononl "Create CA file '$_RT_CERT' to check against.." cat "$_CA_CERT" "$_CRL" >"$_RT_CERT" 2> "$log_file" if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" fatal "Verifying the revocation is not possible!" fi [[ -z "$OPENSSL" ]] && OPENSSL="$(which openssl)" echononl "Verify the revocation.." $OPENSSL verify -CAfile "$_RT_CERT" -crl_check "${_CHECK_DIR}/$(basename "$_CLIENT_CERT")" > "$log_file" 2>&1 if [[ $? -eq 2 ]]; then echo_ok info "Key \033[37m\033[1m$(basename "$_CLIENT_KEY")\033[m successfully revoked." else echo_failed error "$(cat $log_file)" fi # --- # - Start apache webservice # --- echo "" echononl "\tRestart OpenVPN Service.." if $systemd_supported ; then systemctl restart openvpn > $log_file 2>&1 else /etc/init.d/openvpn restart > $log_file 2>&1 fi if [ "$?" = "0" ]; then echo_ok else echo_failed error "$(cat $log_file)" warn "Restarting OpenVPN Service failed!." fi clean_up 0