%PDF- %PDF-
Direktori : /etc/ansible/library/ |
Current File : //etc/ansible/library/bx_ca |
#!/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 replace ./demoCA $SSL -- $SSL/openssl.cnf >> $LOG_FILE 2>&1 replace /etc/pki/CA $SSL -- $SSL/openssl.cnf >> $LOG_FILE 2>&1 replace 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