diff --git a/bin/v-add-letsencrypt-domain b/bin/v-add-letsencrypt-domain new file mode 100755 index 00000000..368511f9 --- /dev/null +++ b/bin/v-add-letsencrypt-domain @@ -0,0 +1,97 @@ +#!/bin/bash +# info: adding letsencrypt ssl cetificate for domain +# options: USER DOMAIN [ALIASES] [RESTART] +# +# The function turns on SSL support for a domain. Parameter ssl_dir is a path +# to directory where 2 or 3 ssl files can be found. Certificate file +# domain.tld.crt and its key domain.tld.key are mandatory. Certificate +# authority domain.tld.ca file is optional. If home directory parameter +# (ssl_home) is not set, https domain uses public_shtml as separate +# documentroot directory. + + +#----------------------------------------------------------# +# Variable&Function # +#----------------------------------------------------------# + +# Argument definition +user=$1 +domain=$2 +aliases=$3 +restart=$4 + +# Includes +source $VESTA/func/main.sh +source $VESTA/func/domain.sh +source $VESTA/conf/vesta.conf + + +#----------------------------------------------------------# +# Verifications # +#----------------------------------------------------------# + +check_args '2' "$#" 'USER DOMAIN [RESTART]' +is_format_valid 'user' 'domain' +is_system_enabled "$WEB_SYSTEM" 'WEB_SYSTEM' +is_system_enabled "$WEB_SSL" 'SSL_SUPPORT' +is_object_valid 'user' 'USER' "$user" +is_object_unsuspended 'user' 'USER' "$user" +is_object_valid 'web' 'DOMAIN' "$domain" +is_object_unsuspended 'web' 'DOMAIN' "$domain" + + +#----------------------------------------------------------# +# Action # +#----------------------------------------------------------# + +# Registering LetsEncrypt user account +$BIN/v-add-letsencrypt-user $user +check_result $? "LE account registration" >/dev/null +source $USER_DATA/ssl/le.conf +email=$EMAIL + +# Validating domain and aliases +i=1 +for alias in $(echo $domain,$aliases |tr ',' '\n' |sort -u); do + $BIN/v-check-letsencrypt-domain $user $alias + check_result $? "LE domain validation" >/dev/null + if [ "$i" -gt 6 ]; then + check_result $E_LIMIT "LE can't sign more than 6 domains" + fi + i=$((i++)) +done + +# Generating CSR +ssl_dir=$($BIN/v-generate-ssl-cert "$domain" "$email" "US" "California" \ + "San Francisco" "Vesta" "IT" "$aliases" |tail -n1 |awk '{print $2}') + +# Signing CSR +crt=$($BIN/v-sign-letsencrypt-csr $user $domain $ssl_dir) +check_result $? "$crt" +echo "$crt" > $ssl_dir/$domain.crt + +# Dowloading CA certificate +le_certs='https://letsencrypt.org/certs' +x1='lets-encrypt-x1-cross-signed.pem.txt' +x3='lets-encrypt-x3-cross-signed.pem.txt' +issuer=$(openssl x509 -text -in $ssl_dir/$domain.crt |grep "Issuer:") +if [ -z "$(echo $issuer|grep X3)" ]; then + curl -s $le_certs/$x1 > $ssl_dir/$domain.ca +else + curl -s $le_certs/$x3 > $ssl_dir/$domain.ca +fi + +# Adding SSL +$BIN/v-delete-web-domain-ssl $user $domain >/dev/null 2>&1 +$BIN/v-add-web-domain-ssl $user $domain $ssl_dir +check_result $? "SSL install" >/dev/null + + +#----------------------------------------------------------# +# Vesta # +#----------------------------------------------------------# + +# Logging +log_event "$OK" "$ARGUMENTS" + +exit diff --git a/bin/v-add-letsencrypt-user b/bin/v-add-letsencrypt-user new file mode 100755 index 00000000..431c2543 --- /dev/null +++ b/bin/v-add-letsencrypt-user @@ -0,0 +1,111 @@ +#!/bin/bash +# info: register letsencrypt user account +# options: USER [EMAIL] +# +# The function creates and register LetsEncript account key + + +#----------------------------------------------------------# +# Variable&Function # +#----------------------------------------------------------# + +# Argument definition +user=$1 +email=$2 +key_size=2048 + +# Includes +source $VESTA/func/main.sh +source $VESTA/conf/vesta.conf + +# encode base64 +encode_base64() { + cat |base64 |tr '+/' '-_' |tr -d '\r\n=' +} + + +#----------------------------------------------------------# +# Verifications # +#----------------------------------------------------------# + +check_args '1' "$#" 'USER [EMAIL]' +is_format_valid 'user' +is_object_valid 'user' 'USER' "$user" +if [ -e "$USER_DATA/ssl/le.conf" ]; then + exit +fi + + +#----------------------------------------------------------# +# Action # +#----------------------------------------------------------# + +api='https://acme-v01.api.letsencrypt.org' +agreement='https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf' +if [ -z "$email" ]; then + email=$(get_user_value '$CONTACT') +fi + +# Generating key +key="$USER_DATA/ssl/user.key" +if [ ! -e "$key" ]; then + openssl genrsa -out $key $key_size >/dev/null 2>&1 + chmod 600 $key +fi + +# Defining key exponent +exponent=$(openssl pkey -inform perm -in "$key" -noout -text_pub |\ + grep Exponent: |cut -f 2 -d '(' |cut -f 1 -d ')' |sed -e 's/x//' |\ + xxd -r -p |encode_base64) + +# Defining key modulus +modulus=$(openssl rsa -in "$key" -modulus -noout |\ + sed -e 's/^Modulus=//' |xxd -r -p |encode_base64) + +# Defining key thumb +thumb='{"e":"'$exponent'","kty":"RSA","n":"'"$modulus"'"}' +thumb="$(echo -n "$thumb" |openssl dgst -sha256 -binary |encode_base64)" + +# Defining JWK header +header='{"e":"'$exponent'","kty":"RSA","n":"'"$modulus"'"}' +header='{"alg":"RS256","jwk":'"$header"'}' + +# Requesting nonce +nonce=$(curl -s -I "$api/directory" |grep Nonce |cut -f 2 -d \ |tr -d '\r\n') +protected=$(echo -n '{"nonce":"'"$nonce"'"}' |encode_base64) + +# Defining registration query +query='{"resource":"new-reg","contact":["mailto:'"$email"'"],' +query=$query'"agreement":"'$agreement'"}' +payload=$(echo -n "$query" |encode_base64) +signature=$(printf "%s" "$protected.$payload" |\ + openssl dgst -sha256 -binary -sign "$key" |encode_base64) +data='{"header":'"$header"',"protected":"'"$protected"'",' +data=$data'"payload":"'"$payload"'","signature":"'"$signature"'"}' + +# Sending request to LetsEncrypt API +answer=$(curl -s -i -d "$data" "$api/acme/new-reg") +status=$(echo "$answer" |grep HTTP/1.1 |tail -n1 |cut -f2 -d ' ') + +# Checking http answer status +if [[ "$status" -ne "201" ]] && [[ "$status" -ne "409" ]]; then + check_result $E_CONNECT "LetsEncrypt account registration $status" +fi + + +#----------------------------------------------------------# +# Vesta # +#----------------------------------------------------------# + +# Adding le.conf +echo "EMAIL='$email'" > $USER_DATA/ssl/le.conf +echo "EXPONENT='$exponent'" >> $USER_DATA/ssl/le.conf +echo "MODULUS='$modulus'" >> $USER_DATA/ssl/le.conf +echo "THUMB='$thumb'" >> $USER_DATA/ssl/le.conf +chmod 660 $USER_DATA/ssl/le.conf + + +# Logging +log_event "$OK" "$ARGUMENTS" + +exit diff --git a/bin/v-check-letsencrypt-domain b/bin/v-check-letsencrypt-domain new file mode 100755 index 00000000..c38aea4a --- /dev/null +++ b/bin/v-check-letsencrypt-domain @@ -0,0 +1,145 @@ +#!/bin/bash +# info: check letsencrypt domain +# options: USER DOMAIN +# +# The function check and validates domain with LetsEncript + + +#----------------------------------------------------------# +# Variable&Function # +#----------------------------------------------------------# + +# Argument definition +user=$1 +domain=$(idn -t --quiet -u "$2" ) +domain=$(echo $domain | tr '[:upper:]' '[:lower:]') + +# Includes +source $VESTA/func/main.sh +source $VESTA/conf/vesta.conf + +# encode base64 +encode_base64() { + cat |base64 |tr '+/' '-_' |tr -d '\r\n=' +} + + +#----------------------------------------------------------# +# Verifications # +#----------------------------------------------------------# + +check_args '2' "$#" 'USER DOMAIN' +is_format_valid 'user' 'domain' +is_system_enabled "$WEB_SYSTEM" 'WEB_SYSTEM' +is_object_valid 'user' 'USER' "$user" +is_object_unsuspended 'user' 'USER' "$user" +if [ ! -e "$USER_DATA/ssl/le.conf" ]; then + check_result $E_NOTEXIST "LetsEncrypt key doesn't exist" +fi +check_domain=$(grep -w "$domain'" $USER_DATA/web.conf) +if [ -z "$check_domain" ]; then + check_result $E_NOTEXIST "domain $domain doesn't exist" +fi + + +#----------------------------------------------------------# +# Action # +#----------------------------------------------------------# + +source $USER_DATA/ssl/le.conf +api='https://acme-v01.api.letsencrypt.org' +r_domain=$(echo "$check_domain" |cut -f 2 -d \') +key="$USER_DATA/ssl/user.key" +exponent="$EXPONENT" +modulus="$MODULUS" +thumb="$THUMB" + +# Defining JWK header +header='{"e":"'$exponent'","kty":"RSA","n":"'"$modulus"'"}' +header='{"alg":"RS256","jwk":'"$header"'}' + +# Requesting nonce +nonce=$(curl -s -I "$api/directory" |grep Nonce |cut -f2 -d \ |tr -d '\r\n') +protected=$(echo -n '{"nonce":"'"$nonce"'"}' |encode_base64) + +# Defining ACME query (request challenge) +query='{"resource":"new-authz","identifier"' +query=$query':{"type":"dns","value":"'"$domain"'"}}' +payload=$(echo -n "$query" |encode_base64) +signature=$(printf "%s" "$protected.$payload" |\ + openssl dgst -sha256 -binary -sign "$key" |encode_base64) +data='{"header":'"$header"',"protected":"'"$protected"'",' +data=$data'"payload":"'"$payload"'","signature":"'"$signature"'"}' + +# Sending request to LetsEncrypt API +answer=$(curl -s -i -d "$data" "$api/acme/new-authz") + +# Checking http answer status +status=$(echo "$answer" |grep HTTP/1.1 |tail -n1 |cut -f2 -d ' ') +if [[ "$status" -ne "201" ]]; then + check_result $E_CONNECT "LetsEncrypt challenge request $status" +fi + +# Parsing domain nonce,token and uri +nonce=$(echo "$answer" |grep Nonce |cut -f2 -d \ |tr -d '\r\n') +protected=$(echo -n '{"nonce":"'"$nonce"'"}' |encode_base64) +token=$(echo "$answer" |tr ',' '\n' |grep -A 3 http-01 |grep token) +token=$(echo "$token" |cut -f 4 -d \") +uri=$(echo "$answer" |tr ',' '\n' |grep -A 3 http-01 |grep uri) +uri=$(echo "$uri" |cut -f 4 -d \") + +# Adding location wrapper for request challenge +if [ "$WEB_SYSTEM" = 'nginx' ] || [ "$PROXY_SYSTEM" = 'nginx' ]; then + conf="$HOMEDIR/$user/conf/web/nginx.$r_domain.conf_letsencrypt" + if [ ! -e "$conf" ]; then + echo 'location ~ "^/\.well-known/acme-challenge/(.*)$" {' > $conf + echo ' default_type text/plain;' >> $conf + echo ' return 200 "$1.'$thumb'";' >> $conf + echo '}' >> $conf + if [ ! -z "$PROXY_SYSTEM" ]; then + $BIN/v-restart-proxy + check_result $? "Proxy restart failed" >/dev/null + else + $BIN/v-restart-web + check_result $? "Web restart failed" >/dev/null + fi + fi +else + acme="$HOMEDIR/$user/web/$r_domain/public_html/.well-known/acme-challenge" + echo "$token" > $acme/$token.$thumb + chown -R $user:$user $HOMEDIR/$user/web/$r_domain/public_html/.well-known +fi + +# Defining ACME query (request validation) +query='{"resource":"challenge","type":"http-01","keyAuthorization"' +query=$query':"'$token.$thumb'","token":"'$token'"}' +payload=$(echo -n "$query" |encode_base64) +signature=$(printf "%s" "$protected.$payload" |\ + openssl dgst -sha256 -binary -sign "$key" |encode_base64) +data='{"header":'"$header"',"protected":"'"$protected"'",' +data=$data'"payload":"'"$payload"'","signature":"'"$signature"'"}' + +# Sending request to LetsEncrypt API +answer=$(curl -s -i -d "$data" "$uri") + +# Checking domain validation status +status=$(echo $answer |tr ',' '\n' |grep status |cut -f 4 -d \") +location=$(echo "$answer" |grep Location: |awk '{print $2}' |tr -d '\r\n') +while [ "$status" = 'pending' ] ; do + answer=$(curl -s -i "$location") + status=$(echo "$answer" |tr ',' '\n' |grep status |cut -f 4 -d \") +done +if [ "$status" = 'invalid' ]; then + detail="$(echo $answer |tr ',' '\n' |grep detail |cut -f 4 -d \")" + check_result $E_CONNECT "$detail" +fi + + +#----------------------------------------------------------# +# Vesta # +#----------------------------------------------------------# + +# Logging +log_event "$OK" "$ARGUMENTS" + +exit diff --git a/bin/v-generate-ssl-cert b/bin/v-generate-ssl-cert index e96edaa5..4ae89582 100755 --- a/bin/v-generate-ssl-cert +++ b/bin/v-generate-ssl-cert @@ -1,6 +1,6 @@ #!/bin/bash # info: generate self signed certificate and CSR request -# options: DOMAIN EMAIL COUNTRY STATE CITY ORG UNIT [FORMAT] +# options: DOMAIN EMAIL COUNTRY STATE CITY ORG UNIT [ALIASES] [FORMAT] # # The function generates self signed SSL certificate and CSR request @@ -11,8 +11,8 @@ # Argument definition domain=$1 -domain=$(echo $domain | sed -e 's/\.*$//g' -e 's/^\.*//g') -domain=$(echo $domain | tr '[:upper:]' '[:lower:]') +domain=$(echo $domain |sed -e 's/\.*$//g' -e 's/^\.*//g') +domain=$(echo $domain |tr '[:upper:]' '[:lower:]') domain_alias=$domain email=$2 country=$3 @@ -20,7 +20,8 @@ state=$4 city=$5 org=$6 org_unit=$7 -format=${8-shell} +aliases=$8 +format=${9-shell} KEY_SIZE=2048 DAYS=365 @@ -35,7 +36,8 @@ json_list_ssl() { echo -e "\t\"$domain\": {" echo " \"CRT\": \"$crt\"," echo " \"KEY\": \"$key\"," - echo " \"CSR\": \"$csr\"" + echo " \"CSR\": \"$csr\"," + echo " \"DIR\": \"$workdir\"" echo -e "\t}\n}" } @@ -50,15 +52,18 @@ shell_list_ssl() { if [ ! -z "$csr" ]; then echo -e "\n$csr" fi + echo -e "\nDirectory: $workdir" } + #----------------------------------------------------------# # Verifications # #----------------------------------------------------------# -check_args '7' "$#" 'DOMAIN EMAIL COUNTRY STATE CITY ORG UNIT [FORMAT]' -validate_format 'domain_alias' 'format' +args_usage='DOMAIN EMAIL COUNTRY STATE CITY ORG UNIT [ALIASES] [FORMAT]' +check_args '7' "$#" "$args_usage" +is_format_valid 'domain_alias' 'format' #----------------------------------------------------------# @@ -70,31 +75,41 @@ workdir=$(mktemp -d) cd $workdir # Generate private key -export PASSPHRASE=gen_password -openssl genrsa -des3 \ - -out $domain.key \ - -passout env:PASSPHRASE $KEY_SIZE 2>/dev/null +openssl genrsa $KEY_SIZE > $domain.key 2>/dev/null # Generate the CSR subj="/C=$country/ST=$state/localityName=$city/O=$org" subj="$subj/organizationalUnitName=$org_unit/commonName=$domain" subj="$subj/emailAddress=$email" +if [ -z "$aliases" ]; then + openssl req -sha256\ + -new \ + -batch \ + -subj "$subj" \ + -key $domain.key \ + -out $domain.csr >/dev/null 2>&1 +else + for alias in $(echo $domain,$aliases |tr ',' '\n' |sort -u); do + dns_aliases="${dns_aliases}DNS:$alias," + done + dns_aliases=$(echo $dns_aliases |sed "s/,$//") -openssl req -sha256\ - -new \ - -batch \ - -subj "$subj" \ - -key $domain.key \ - -out $domain.csr \ - -passin env:PASSPHRASE >/dev/null 2>&1 + if [ -e "/etc/ssl/openssl.cnf" ]; then + ssl_conf='/etc/ssl/openssl.cnf' + else + ssl_conf="/etc/pki/tls/openssl.cnf" + fi -# Remove passphrase -cp $domain.key $domain.key.tmp -openssl rsa \ - -in $domain.key.tmp \ - -out $domain.key \ - -passin env:PASSPHRASE >/dev/null 2>&1 -rm $domain.key.tmp + openssl req -sha256\ + -new \ + -batch \ + -subj "$subj" \ + -key $domain.key \ + -reqexts SAN \ + -config <(cat $ssl_conf \ + <(printf "[SAN]\nsubjectAltName=$dns_aliases")) \ + -out $domain.csr >/dev/null 2>&1 +fi # Generate the cert 1 year openssl x509 -req -sha256 \ @@ -124,7 +139,7 @@ case $format in esac # Delete tmp dir -rm -rf $workdir +#rm -rf $workdir #----------------------------------------------------------# @@ -132,6 +147,6 @@ rm -rf $workdir #----------------------------------------------------------# # Logging -log_event "$OK" "$EVENT" +log_event "$OK" "$ARGUMENTS" exit diff --git a/bin/v-list-letsencrypt-user b/bin/v-list-letsencrypt-user new file mode 100755 index 00000000..cded9600 --- /dev/null +++ b/bin/v-list-letsencrypt-user @@ -0,0 +1,82 @@ +#!/bin/bash +# info: list letsencrypt key +# options: USER [FORMAT] +# +# The function for obtaining the letsencrypt key thumbprint + + +#----------------------------------------------------------# +# Variable&Function # +#----------------------------------------------------------# + +# Argument definition +user=$1 +format=${2-shell} + +# Includes +source $VESTA/func/main.sh + +# JSON list function +json_list() { + echo '{' + echo ' "'$user'": { + "EMAIL": "'$EMAIL'", + "EXPONENT": "'$EXPONENT'", + "MODULUS": "'$MODULUS'", + "THUMB: "'$THUMB'" + }' + echo '}' +} + +# SHELL list function +shell_list() { + echo "USER: $user" + echo "EMAIL: $EMAIL" + echo "THUMB: $THUMB" + echo "EXPONENT: $EXPONENT" + echo "MODULUS: $MODULUS" +} + +# PLAIN list function +plain_list() { + echo -e "$user\t$EMAIL\t$EXPONENT\t$MODULUS\t$THUMB" +} + +# CSV list function +csv_list() { + echo "USER,EMAIL,EXPONENT,MODULUS,THUMB" + echo "$user,$EMAIL,$EXPONENT,$MODULUS,$THUMB" +} + + +#----------------------------------------------------------# +# Verifications # +#----------------------------------------------------------# + +check_args '1' "$#" 'USER [FORMAT]' +is_object_valid 'user' 'USER' "$user" +if [ ! -e "$USER_DATA/ssl/le.conf" ]; then + check_result $E_NOTEXIST "LetsEncrypt user account doesn't exist" +fi + + +#----------------------------------------------------------# +# Action # +#----------------------------------------------------------# + +source $USER_DATA/ssl/le.conf + +# Listing data +case $format in + json) json_list ;; + plain) plain_list ;; + csv) csv_list ;; + shell) shell_list ;; +esac + + +#----------------------------------------------------------# +# Vesta # +#----------------------------------------------------------# + +exit diff --git a/bin/v-sign-letsencrypt-csr b/bin/v-sign-letsencrypt-csr new file mode 100755 index 00000000..c0d4eceb --- /dev/null +++ b/bin/v-sign-letsencrypt-csr @@ -0,0 +1,112 @@ +#!/bin/bash +# info: sing letsencrypt csr +# options: USER DOMAIN CSR_DIR [FORMAT] +# +# The function signs certificate request using LetsEncript API + + +#----------------------------------------------------------# +# Variable&Function # +#----------------------------------------------------------# + +# Argument definition +user=$1 +domain=$(idn -t --quiet -u "$2" ) +domain=$(echo $domain | tr '[:upper:]' '[:lower:]') +csr="$3/$domain.csr" +format=$4 + +# Includes +source $VESTA/func/main.sh +source $VESTA/conf/vesta.conf + +# encode base64 +encode_base64() { + cat |base64 |tr '+/' '-_' |tr -d '\r\n=' +} + + +#----------------------------------------------------------# +# Verifications # +#----------------------------------------------------------# + +check_args '3' "$#" 'USER DOMAIN CSR' +is_format_valid 'user' 'domain' +is_system_enabled "$WEB_SYSTEM" 'WEB_SYSTEM' +is_object_valid 'user' 'USER' "$user" +is_object_unsuspended 'user' 'USER' "$user" +if [ ! -e "$USER_DATA/ssl/le.conf" ]; then + check_result $E_NOTEXIST "LetsEncrypt key doesn't exist" +fi +check_domain=$(grep -w "$domain'" $USER_DATA/web.conf) +if [ -z "$check_domain" ]; then + check_result $E_NOTEXIST "domain $domain doesn't exist" +fi +if [ ! -e "$csr" ]; then + check_result $E_NOTEXIST "$csr doesn't exist" +fi + + +#----------------------------------------------------------# +# Action # +#----------------------------------------------------------# + +source $USER_DATA/ssl/le.conf +api='https://acme-v01.api.letsencrypt.org' +r_domain=$(echo "$check_domain" |cut -f 2 -d \') +key="$USER_DATA/ssl/user.key" +exponent="$EXPONENT" +modulus="$MODULUS" +thumb="$THUMB" + +# Defining JWK header +header='{"e":"'$exponent'","kty":"RSA","n":"'"$modulus"'"}' +header='{"alg":"RS256","jwk":'"$header"'}' + +# Requesting nonce +nonce=$(curl -s -I "$api/directory" |grep Nonce |cut -f2 -d \ |tr -d '\r\n') +protected=$(echo -n '{"nonce":"'"$nonce"'"}' |encode_base64) + +# Defining ACME query (request challenge) +csr=$(openssl req -in $csr -outform DER |encode_base64) +query='{"resource":"new-cert","csr":"'$csr'"}' +payload=$(echo -n "$query" |encode_base64) +signature=$(printf "%s" "$protected.$payload" |\ + openssl dgst -sha256 -binary -sign "$key" |encode_base64) +data='{"header":'"$header"',"protected":"'"$protected"'",' +data=$data'"payload":"'"$payload"'","signature":"'"$signature"'"}' + +# Sending request to LetsEncrypt API +answer=$(mktemp) +curl -s -d "$data" "$api/acme/new-cert" -o $answer +if [ ! -z "$(grep Error $answer)" ]; then + detail="$(cat $answer |tr ',' '\n' |grep detail |cut -f 4 -d \")" + detail=$(echo "$detail" |awk -F "::" '{print $2}') + rm $answer + check_result $E_LIMIT "$detail" +fi + +# Printing certificate +crt=$(cat "$answer" |openssl base64 -e) +rm $answer +if [ "$format" != 'json' ]; then + echo "-----BEGIN CERTIFICATE-----" + echo "$crt" + echo "-----END CERTIFICATE-----" +else + echo -e "{\n\t\"$domain\": {\n\t\t\"CRT\":\"" + echo -n '-----BEGIN CERTIFICATE-----\n' + echo -n "$crt" |sed ':a;N;$!ba;s/\n/\\n/g' + echo -n '-----END CERTIFICATE-----' + echo -e "\"\n\t\t}\n\t}" +fi + + +#----------------------------------------------------------# +# Vesta # +#----------------------------------------------------------# + +# Logging +log_event "$OK" "$ARGUMENTS" + +exit diff --git a/bin/v-update-letsencrypt-ssl b/bin/v-update-letsencrypt-ssl new file mode 100755 index 00000000..39052097 --- /dev/null +++ b/bin/v-update-letsencrypt-ssl @@ -0,0 +1,66 @@ +#!/bin/bash +# info: update letsencrypt ssl certificates +# options: NONE +# +# The function for renew letsencrypt expired ssl certificate for all users + + +#----------------------------------------------------------# +# Variable&Function # +#----------------------------------------------------------# + +# Importing system enviroment as we run this script +# mostly by cron wich not read it by itself +source /etc/profile + +# Includes +source $VESTA/func/main.sh +source $VESTA/conf/vesta.conf + + +#----------------------------------------------------------# +# Action # +#----------------------------------------------------------# + +# Defining user list +users=$(ls $VESTA/data/users/*/ssl/le.conf |cut -f 7 -d /) + +# Checking users +for user in $users; do + # Checking user certificates + for crt in $(ls $VESTA/data/users/$user/ssl/*.crt 2>/dev/null); do + # Checking certificate issuer + crt_data=$(openssl x509 -text -in $crt) + issuer=$(echo "$crt_data" |grep Issuer: |grep Encrypt) + if [ ! -z "$issuer" ]; then + expire=$(echo "$crt_data" |grep "Not After") + expire=$(echo "$expire" |cut -f 2,3,4 -d :) + expire=$(date -d "$expire" +%s) + now=$(date +%s) + expire=$((expire - now)) + expire=$((expire / 86400)) + domain=$(basename $crt |sed -e "s/.crt$//") + if [[ "$expire" -lt 31 ]]; then + aliases=$(echo "$crt_data" |grep DNS:) + aliases=$(echo "$aliases" |sed -e "s/DNS://g" -e "s/,//") + aliases=$(echo "$aliases" |tr ' ' '\n' |sed "/^$/d") + aliases=$(echo "$aliases" |grep -v "^$domain$") + if [ ! -z "$aliases" ]; then + aliases=$(echo "$aliases" |sed -e ':a;N;$!ba;s/\n/,/g') + $BIN/v-add-letsencrypt-domain $user $domain $aliases + else + $BIN/v-add-letsencrypt-domain $user $domain + fi + fi + fi + done +done + +#----------------------------------------------------------# +# Vesta # +#----------------------------------------------------------# + +# No Logging +#log_event "$OK" "$EVENT" + +exit