Your IP : 3.134.247.163
#!/bin/bash
# state:
# init ----- create CA certificate and server certificate
# uninit ----- delete CA certificates
# add ----- add/update server certificate
# remove ----- remove server cerificate
# hostname: hostname
#
export LANG=en_EN.UTF-8
export NOLOCALE=yes
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
[[ -z $DEBUG ]] && DEBUG=0
BASE_DIR=/opt/webdir
LOGS_DIR=$BASE_DIR/logs
TEMP_DIR=$BASE_DIR/temp
SSL=$BASE_DIR/openssl
PRIV=$SSL/private
CERT=$SSL/newcerts
ARH=$SSL/archives
TMP_DIR=$BASE_DIR/tmp
[[ ! -d $TMP_DIR ]] && mkdir -m 700 $TMP_DIR
LOG_FILE=$TMP_DIR/bx_ca_$$.log
CA_PASS=$PRIV/ca_private
#set -x
log(){
mess=$1
echo "$(date +%s) $mess" >> $LOG_FILE
}
debug(){
mess=$1
[[ $DEBUG -gt 0 ]] && log "$mess"
}
# print error message
print_error() {
msg=$1
log "$msg"
echo "{\"changed\":false,\"failed\":true,\"msg\":\"$msg\"}"
exit 1
}
# print change
print_change() {
msg=$1
arh=$2
if [[ -n $arh ]]; then
echo "{\"changed\":true,\"msg\":\"$msg\",\"archive\":\"$arh\"}"
else
echo "{\"changed\":true,\"msg\":\"$msg\"}"
fi
debug "$msg"
exit 0
}
# print ok
print_ok() {
msg=$1
arh=$2
if [[ -n $arh ]]; then
echo "{\"changed\":false,\"msg\":\"$msg\",\"archive\":\"$arh\"}"
else
echo "{\"changed\":false,\"msg\":\"$msg\"}"
fi
debug "$msg"
exit 0
}
# create random string
create_random_string() {
randLength=15
rndStr=</dev/urandom tr -dc 'A-Za-z0-9!@#$%^&*()-+=' 2>/dev/null | head -c $randLength
echo $rndStr
}
test_hostname() {
hostname=$1
[[ -z $hostname ]] &&
print_error "You must define hostname= option."
}
status_cert() {
hostname=${1}
test_hostname "$hostname"
status_cert=$(grep "CN=${hostname}$" $SSL/index.txt 2>/dev/null)
if [[ -n $status_cert ]]; then
index_state=$(echo "$status_cert" | tail -n 1 | awk '{print $1}')
if [[ $index_state == "R" ]]; then
return 1
else
return 0
fi
fi
return 2
}
status_cert_print(){
hostname=${1}
[[ -z $hostname ]] && hostname=$(hostname)
status_cert $hostname
status_cert_rtn=$?
if [[ $status_cert_rtn -eq 0 ]]; then
echo "{\"archive\":\"$ARH/${hostname}.tar.gz}\",\"status\":\"exists\"}"
elif [[ $status_cert_rtn -eq 1 ]]; then
echo "{\"status\":\"revoke\"}"
else
echo "{\"status\":\"not_found\"}"
fi
}
add_cert() {
hostname=${1}
test_hostname "$hostname"
# status
status_cert "${hostname}"
if [[ $? -eq 0 ]]; then
print_ok "Certificate already exists for server=$hostname"
fi
# server key
srv_pass=$PRIV/${hostname}-private
create_random_string > $srv_pass
# generate server request
openssl req -new -keyout $SSL/$hostname-key.pem -out \
$SSL/$hostname-req.pem -days 3600 -config $SSL/openssl.cnf \
-subj "/CN=$hostname/" -passout file:$srv_pass >> $LOG_FILE 2>&1
[[ $? -gt 0 ]] && \
print_error "Cannot generate request for server=$hostname; Please see log=$LOG_FILE"
# remove password
openssl rsa -in $SSL/$hostname-key.pem -out $SSL/$hostname-key.pem \
-passin file:$srv_pass >> $LOG_FILE 2>&1
[[ $? -gt 0 ]] && \
print_error "Cannot remove password for server=$hostname; Please see log=$LOG_FILE"
# sign
openssl ca \
-batch \
-passin file:$CA_PASS \
-cert $SSL/ca.pem -policy policy_anything \
-out $SSL/$hostname-cert.pem -config $SSL/openssl.cnf \
-infiles $SSL/$hostname-req.pem >> $LOG_FILE 2>&1
[[ $? -gt 0 ]] && \
print_error "Cannot sign certificate for server=$hostname; Please see log=$LOG_FILE"
# archive
arch_dir=$ARH/${hostname}
arch_path=$ARH/${hostname}.tar.gz
[[ ! -d $arch_dir ]] && \
mkdir -m 0700 $arch_dir
cp --preserve="mode,ownership" -f $SSL/ca.pem $arch_dir/
cp --preserve="mode,ownership" -f $SSL/$hostname-key.pem $arch_dir/server.key
cp --preserve="mode,ownership" -f $SSL/$hostname-cert.pem $arch_dir/server.crt
cp -f $SSL/ca.pem $arch_dir/server_full.crt
cat $SSL/$hostname-cert.pem >> $arch_dir/server_full.crt
pushd $arch_dir 1>/dev/null 2>&1
tar czf $arch_path . >>$LOG_FILE 2>&1
[[ $? -gt 0 ]] && \
print_error "Cannot create archive=$arch_path; Please see log=$LOG_FILE"
popd 1>/dev/null 2>&1
rm -rf $arch_dir
ARCH_PATH=$ARH/${hostname}.tar.gz
}
update_cert() {
hostname=${1}
test_hostname "$hostname"
status_cert $hostname
status_cert_rtn=$?
if [[ $status_cert_rtn -eq 0 ]]; then
revoke_cert $hostname
fi
add_cert $hostname
}
revoke_cert() {
hostname=${1}
test_hostname "$hostname"
status_cert "$hostname"
if [[ $? -eq 1 ]]; then
print_ok "Not found valid certificate for hostname=$hostname"
fi
openssl ca \
-batch \
-passin file:$CA_PASS \
-config $SSL/openssl.cnf \
-revoke $SSL/$hostname-cert.pem >> $LOG_FILE 2>&1
[[ $? -gt 0 ]] && \
print_error "Cannot revoke certificate for server=$hostname; Please see log=$LOG_FILE"
rm -f $SSL/$hostname-key.pem $SSL/$hostname-cert.pem $SSL/$hostname-req.pem $PRIV/${hostname}-private
}
init_ca() {
status_cert "$(hostname)"
status_rtn=$?
[[ ( $status_rtn -eq 1 ) || ( $status_rtn -eq 0 ) ]] && \
print_ok "Auth CA already exists"
# create directories
for dir in $SSL $PRIV $CERT $ARH; do
[[ ! -d $dir ]] && \
mkdir -m 700 -p $dir
done
# config
cp /etc/pki/tls/openssl.cnf $SSL
sed -i "s:./demoCA:$SSL:" $SSL/openssl.cnf >> $LOG_FILE 2>&1
sed -i "s:/etc/pki/CA:$SSL:" $SSL/openssl.cnf >> $LOG_FILE 2>&1
sed -i "s:cacert.pem:ca.pem:" $SSL/openssl.cnf >> $LOG_FILE 2>&1
# Create necessary files: $database, $serial and $new_certs_dir
# directory (optional)
touch $SSL/index.txt
echo "01" > $SSL/serial
create_random_string > $CA_PASS
# generate CA
openssl req -new -x509 -keyout $PRIV/cakey.pem -out $SSL/ca.pem \
-days 3600 -passout file:$CA_PASS -config $SSL/openssl.cnf \
-subj "/CN=CertificateAuthority/" >> $LOG_FILE 2>&1
[[ $? -gt 0 ]] && \
print_error "Cannot create CA; please see log=$LOG_FILE"
# add certificate for server
add_cert $(hostname)
}
uninit_ca() {
status_cert "$(hostname)"
[[ $? -eq 2 ]] && \
print_ok "Not found Certificate Auth"
rm -rf $SSL
}
# get ansible options
source ${1}
case $state in
init)
init_ca
print_change "Create Certificate Auth and certificate for hostname=$hostname" "$ARCH_PATH"
;;
add)
add_cert "$hostname"
print_change "Create certificate for hostname=$hostname" "$ARCH_PATH"
;;
update)
update_cert "$hostname"
print_change "Update certificate for hostname=$hostname" "$ARCH_PATH"
;;
remove|revoke)
revoke_cert "$hostname"
print_change "Revoke certificate for hostname=$hostname"
;;
uninit)
uninit_ca
print_change "Remove Certificate Auth in $SSL"
;;
status)
status_cert_print "$hostname"
;;
*)
print_error "Unknown state=$state"
;;
esac