Commit 4c3b3608 authored by neil's avatar neil
Browse files

minor

parent 48a8e6e6
#!/usr/bin/env bash #!/usr/bin/env bash
VER=1.1.8 VER=1.1.8
PROJECT="https://github.com/Neilpang/le" PROJECT="https://github.com/Neilpang/le"
DEFAULT_CA="https://acme-v01.api.letsencrypt.org" DEFAULT_CA="https://acme-v01.api.letsencrypt.org"
DEFAULT_AGREEMENT="https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf" DEFAULT_AGREEMENT="https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf"
STAGE_CA="https://acme-staging.api.letsencrypt.org" STAGE_CA="https://acme-staging.api.letsencrypt.org"
VTYPE_HTTP="http-01" VTYPE_HTTP="http-01"
VTYPE_DNS="dns-01" VTYPE_DNS="dns-01"
if [ -z "$AGREEMENT" ] ; then if [ -z "$AGREEMENT" ] ; then
AGREEMENT="$DEFAULT_AGREEMENT" AGREEMENT="$DEFAULT_AGREEMENT"
fi fi
_debug() { _debug() {
if [ -z "$DEBUG" ] ; then if [ -z "$DEBUG" ] ; then
return return
fi fi
if [ -z "$2" ] ; then if [ -z "$2" ] ; then
echo $1 echo $1
else else
echo "$1"="$2" echo "$1"="$2"
fi fi
} }
_info() { _info() {
if [ -z "$2" ] ; then if [ -z "$2" ] ; then
echo "$1" echo "$1"
else else
echo "$1"="$2" echo "$1"="$2"
fi fi
} }
_err() { _err() {
if [ -z "$2" ] ; then if [ -z "$2" ] ; then
echo "$1" >&2 echo "$1" >&2
else else
echo "$1"="$2" >&2 echo "$1"="$2" >&2
fi fi
return 1 return 1
} }
_h2b() { _h2b() {
hex=$(cat) hex=$(cat)
i=1 i=1
j=2 j=2
while [ '1' ] ; do while [ '1' ] ; do
h=$(printf $hex | cut -c $i-$j) h=$(printf $hex | cut -c $i-$j)
if [ -z "$h" ] ; then if [ -z "$h" ] ; then
break; break;
fi fi
printf "\x$h" printf "\x$h"
let "i+=2" let "i+=2"
let "j+=2" let "j+=2"
done done
} }
_base64() { _base64() {
openssl base64 -e | tr -d '\n' openssl base64 -e | tr -d '\n'
} }
#domain [2048] #domain [2048]
createAccountKey() { createAccountKey() {
_info "Creating account key" _info "Creating account key"
if [ -z "$1" ] ; then if [ -z "$1" ] ; then
echo Usage: createAccountKey account-domain [2048] echo Usage: createAccountKey account-domain [2048]
return return
fi fi
account=$1 account=$1
length=$2 length=$2
if [[ "$length" == "ec-"* ]] ; then if [[ "$length" == "ec-"* ]] ; then
length=2048 length=2048
fi fi
if [ -z "$2" ] ; then if [ -z "$2" ] ; then
_info "Use default length 2048" _info "Use default length 2048"
length=2048 length=2048
fi fi
_initpath _initpath
if [ -f "$ACCOUNT_KEY_PATH" ] ; then if [ -f "$ACCOUNT_KEY_PATH" ] ; then
_info "Account key exists, skip" _info "Account key exists, skip"
return return
else else
#generate account key #generate account key
openssl genrsa $length > "$ACCOUNT_KEY_PATH" openssl genrsa $length > "$ACCOUNT_KEY_PATH"
fi fi
} }
#domain length #domain length
createDomainKey() { createDomainKey() {
_info "Creating domain key" _info "Creating domain key"
if [ -z "$1" ] ; then if [ -z "$1" ] ; then
echo Usage: createDomainKey domain [2048] echo Usage: createDomainKey domain [2048]
return return
fi fi
domain=$1 domain=$1
length=$2 length=$2
isec="" isec=""
if [[ "$length" == "ec-"* ]] ; then if [[ "$length" == "ec-"* ]] ; then
isec="1" isec="1"
length=$(printf $length | cut -d '-' -f 2-100) length=$(printf $length | cut -d '-' -f 2-100)
eccname="$length" eccname="$length"
fi fi
if [ -z "$length" ] ; then if [ -z "$length" ] ; then
if [ "$isec" ] ; then if [ "$isec" ] ; then
length=256 length=256
else else
length=2048 length=2048
fi fi
fi fi
_info "Use length $length" _info "Use length $length"
if [ "$isec" ] ; then if [ "$isec" ] ; then
if [ "$length" == "256" ] ; then if [ "$length" == "256" ] ; then
eccname="prime256v1" eccname="prime256v1"
fi fi
if [ "$length" == "384" ] ; then if [ "$length" == "384" ] ; then
eccname="secp384r1" eccname="secp384r1"
fi fi
if [ "$length" == "521" ] ; then if [ "$length" == "521" ] ; then
eccname="secp521r1" eccname="secp521r1"
fi fi
_info "Using ec name: $eccname" _info "Using ec name: $eccname"
fi fi
_initpath $domain _initpath $domain
if [ ! -f "$CERT_KEY_PATH" ] || ( [ "$FORCE" ] && ! [ "$IS_RENEW" ] ); then if [ ! -f "$CERT_KEY_PATH" ] || ( [ "$FORCE" ] && ! [ "$IS_RENEW" ] ); then
#generate account key #generate account key
if [ "$isec" ] ; then if [ "$isec" ] ; then
openssl ecparam -name $eccname -genkey 2>/dev/null > "$CERT_KEY_PATH" openssl ecparam -name $eccname -genkey 2>/dev/null > "$CERT_KEY_PATH"
else else
openssl genrsa $length 2>/dev/null > "$CERT_KEY_PATH" openssl genrsa $length 2>/dev/null > "$CERT_KEY_PATH"
fi fi
else else
if [ "$IS_RENEW" ] ; then if [ "$IS_RENEW" ] ; then
_info "Domain key exists, skip" _info "Domain key exists, skip"
return 0 return 0
else else
_err "Domain key exists, do you want to overwrite the key?" _err "Domain key exists, do you want to overwrite the key?"
_err "Set FORCE=1, and try again." _err "Set FORCE=1, and try again."
return 1 return 1
fi fi
fi fi
} }
# domain domainlist # domain domainlist
createCSR() { createCSR() {
_info "Creating csr" _info "Creating csr"
if [ -z "$1" ] ; then if [ -z "$1" ] ; then
echo Usage: $0 domain [domainlist] echo Usage: $0 domain [domainlist]
return return
fi fi
domain=$1 domain=$1
_initpath $domain _initpath $domain
domainlist=$2 domainlist=$2
if [ -f "$CSR_PATH" ] && [ "$IS_RENEW" ] && ! [ "$FORCE" ]; then if [ -f "$CSR_PATH" ] && [ "$IS_RENEW" ] && ! [ "$FORCE" ]; then
_info "CSR exists, skip" _info "CSR exists, skip"
return return
fi fi
if [ -z "$domainlist" ] ; then if [ -z "$domainlist" ] ; then
#single domain #single domain
_info "Single domain" $domain _info "Single domain" $domain
openssl req -new -sha256 -key "$CERT_KEY_PATH" -subj "/CN=$domain" > "$CSR_PATH" openssl req -new -sha256 -key "$CERT_KEY_PATH" -subj "/CN=$domain" > "$CSR_PATH"
else else
alt="DNS:$(echo $domainlist | sed "s/,/,DNS:/g")" alt="DNS:$(echo $domainlist | sed "s/,/,DNS:/g")"
#multi #multi
_info "Multi domain" "$alt" _info "Multi domain" "$alt"
printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\n[SAN]\nsubjectAltName=$alt" > "$DOMAIN_SSL_CONF" printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\n[SAN]\nsubjectAltName=$alt" > "$DOMAIN_SSL_CONF"
openssl req -new -sha256 -key "$CERT_KEY_PATH" -subj "/CN=$domain" -reqexts SAN -config "$DOMAIN_SSL_CONF" -out "$CSR_PATH" openssl req -new -sha256 -key "$CERT_KEY_PATH" -subj "/CN=$domain" -reqexts SAN -config "$DOMAIN_SSL_CONF" -out "$CSR_PATH"
fi fi
} }
_b64() { _b64() {
__n=$(cat) __n=$(cat)
echo $__n | tr '/+' '_-' | tr -d '= ' echo $__n | tr '/+' '_-' | tr -d '= '
} }
_time2str() { _time2str() {
#BSD #BSD
if date -u -d@$1 2>/dev/null ; then if date -u -d@$1 2>/dev/null ; then
return return
fi fi
#Linux #Linux
if date -u -r $1 2>/dev/null ; then if date -u -r $1 2>/dev/null ; then
return return
fi fi
} }
_send_signed_request() { _send_signed_request() {
url=$1 url=$1
payload=$2 payload=$2
needbase64=$3 needbase64=$3
_debug url $url _debug url $url
_debug payload "$payload" _debug payload "$payload"
CURL_HEADER="$LE_WORKING_DIR/curl.header" CURL_HEADER="$LE_WORKING_DIR/curl.header"
dp="$LE_WORKING_DIR/curl.dump" dp="$LE_WORKING_DIR/curl.dump"
CURL="curl --silent --dump-header $CURL_HEADER " CURL="curl --silent --dump-header $CURL_HEADER "
if [ "$DEBUG" ] ; then if [ "$DEBUG" ] ; then
CURL="$CURL --trace-ascii $dp " CURL="$CURL --trace-ascii $dp "
fi fi
payload64=$(echo -n $payload | _base64 | _b64) payload64=$(echo -n $payload | _base64 | _b64)
_debug payload64 $payload64 _debug payload64 $payload64
nonceurl="$API/directory" nonceurl="$API/directory"
nonce="$($CURL -I $nonceurl | grep -o "^Replay-Nonce:.*$" | tr -d "\r\n" | cut -d ' ' -f 2)" nonce="$($CURL -I $nonceurl | grep -o "^Replay-Nonce:.*$" | tr -d "\r\n" | cut -d ' ' -f 2)"
_debug nonce "$nonce" _debug nonce "$nonce"
protected="$(printf "$HEADERPLACE" | sed "s/NONCE/$nonce/" )" protected="$(printf "$HEADERPLACE" | sed "s/NONCE/$nonce/" )"
_debug protected "$protected" _debug protected "$protected"
protected64="$(printf "$protected" | _base64 | _b64)" protected64="$(printf "$protected" | _base64 | _b64)"
_debug protected64 "$protected64" _debug protected64 "$protected64"
sig=$(echo -n "$protected64.$payload64" | openssl dgst -sha256 -sign $ACCOUNT_KEY_PATH | _base64 | _b64) sig=$(echo -n "$protected64.$payload64" | openssl dgst -sha256 -sign $ACCOUNT_KEY_PATH | _base64 | _b64)
_debug sig "$sig" _debug sig "$sig"
body="{\"header\": $HEADER, \"protected\": \"$protected64\", \"payload\": \"$payload64\", \"signature\": \"$sig\"}" body="{\"header\": $HEADER, \"protected\": \"$protected64\", \"payload\": \"$payload64\", \"signature\": \"$sig\"}"
_debug body "$body" _debug body "$body"
if [ "$needbase64" ] ; then if [ "$needbase64" ] ; then
response="$($CURL -X POST --data "$body" $url | _base64)" response="$($CURL -X POST --data "$body" $url | _base64)"
else else
response="$($CURL -X POST --data "$body" $url)" response="$($CURL -X POST --data "$body" $url)"
fi fi
responseHeaders="$(cat $CURL_HEADER)" responseHeaders="$(cat $CURL_HEADER)"
_debug responseHeaders "$responseHeaders" _debug responseHeaders "$responseHeaders"
_debug response "$response" _debug response "$response"
code="$(grep ^HTTP $CURL_HEADER | tail -1 | cut -d " " -f 2 | tr -d "\r\n" )" code="$(grep ^HTTP $CURL_HEADER | tail -1 | cut -d " " -f 2 | tr -d "\r\n" )"
_debug code $code _debug code $code
} }
_get() { _get() {
url="$1" url="$1"
_debug url $url _debug url $url
response="$(curl --silent $url)" response="$(curl --silent $url)"
ret=$? ret=$?
_debug response "$response" _debug response "$response"
code="$(echo $response | grep -o '"status":[0-9]\+' | cut -d : -f 2)" code="$(echo $response | grep -o '"status":[0-9]\+' | cut -d : -f 2)"
_debug code $code _debug code $code
return $ret return $ret
} }
#setopt "file" "opt" "=" "value" [";"] #setopt "file" "opt" "=" "value" [";"]
_setopt() { _setopt() {
__conf="$1" __conf="$1"
__opt="$2" __opt="$2"
__sep="$3" __sep="$3"
__val="$4" __val="$4"
__end="$5" __end="$5"
if [ -z "$__opt" ] ; then if [ -z "$__opt" ] ; then
echo usage: _setopt '"file" "opt" "=" "value" [";"]' echo usage: _setopt '"file" "opt" "=" "value" [";"]'
return return
fi fi
if [ ! -f "$__conf" ] ; then if [ ! -f "$__conf" ] ; then
touch "$__conf" touch "$__conf"
fi fi
if grep -H -n "^$__opt$__sep" "$__conf" > /dev/null ; then if grep -H -n "^$__opt$__sep" "$__conf" > /dev/null ; then
_debug OK _debug OK
if [[ "$__val" == *"&"* ]] ; then if [[ "$__val" == *"&"* ]] ; then
__val="$(echo $__val | sed 's/&/\\&/g')" __val="$(echo $__val | sed 's/&/\\&/g')"
fi fi
text="$(cat $__conf)" text="$(cat $__conf)"
printf "$text" | sed "s|^$__opt$__sep.*$|$__opt$__sep$__val$__end|" > "$__conf" printf "$text" | sed "s|^$__opt$__sep.*$|$__opt$__sep$__val$__end|" > "$__conf"
elif grep -H -n "^#$__opt$__sep" "$__conf" > /dev/null ; then elif grep -H -n "^#$__opt$__sep" "$__conf" > /dev/null ; then
if [[ "$__val" == *"&"* ]] ; then if [[ "$__val" == *"&"* ]] ; then
__val="$(echo $__val | sed 's/&/\\&/g')" __val="$(echo $__val | sed 's/&/\\&/g')"
fi fi
text="$(cat $__conf)" text="$(cat $__conf)"
printf "$text" | sed "s|^#$__opt$__sep.*$|$__opt$__sep$__val$__end|" > "$__conf" printf "$text" | sed "s|^#$__opt$__sep.*$|$__opt$__sep$__val$__end|" > "$__conf"
else else
_debug APP _debug APP
echo "" >> "$__conf" echo "" >> "$__conf"
echo "$__opt$__sep$__val$__end" >> "$__conf" echo "$__opt$__sep$__val$__end" >> "$__conf"
fi fi
_debug "$(grep -H -n "^$__opt$__sep" $__conf)" _debug "$(grep -H -n "^$__opt$__sep" $__conf)"
} }
#_savedomainconf key value #_savedomainconf key value
#save to domain.conf #save to domain.conf
_savedomainconf() { _savedomainconf() {
key="$1" key="$1"
value="$2" value="$2"
if [ "$DOMAIN_CONF" ] ; then if [ "$DOMAIN_CONF" ] ; then
_setopt $DOMAIN_CONF "$key" "=" "$value" _setopt $DOMAIN_CONF "$key" "=" "$value"
else else
_err "DOMAIN_CONF is empty, can not save $key=$value" _err "DOMAIN_CONF is empty, can not save $key=$value"
fi fi
} }
#_saveaccountconf key value #_saveaccountconf key value
_saveaccountconf() { _saveaccountconf() {
key="$1" key="$1"
value="$2" value="$2"
if [ "$ACCOUNT_CONF_PATH" ] ; then if [ "$ACCOUNT_CONF_PATH" ] ; then
_setopt $ACCOUNT_CONF_PATH "$key" "=" "$value" _setopt $ACCOUNT_CONF_PATH "$key" "=" "$value"
else else
_err "ACCOUNT_CONF_PATH is empty, can not save $key=$value" _err "ACCOUNT_CONF_PATH is empty, can not save $key=$value"
fi fi
} }
_startserver() { _startserver() {
content="$1" content="$1"
_NC="nc -q 1" _NC="nc -q 1"
if nc -h 2>&1 | grep "nmap.org/ncat" >/dev/null ; then if nc -h 2>&1 | grep "nmap.org/ncat" >/dev/null ; then
_NC="nc" _NC="nc"
fi fi
# while true ; do # while true ; do
if [ "$DEBUG" ] ; then if [ "$DEBUG" ] ; then
echo -e -n "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC -l -p $Le_HTTPPort -vv echo -e -n "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC -l -p $Le_HTTPPort -vv
else else
echo -e -n "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC -l -p $Le_HTTPPort > /dev/null echo -e -n "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC -l -p $Le_HTTPPort > /dev/null
fi fi
# done # done
} }
_stopserver() { _stopserver() {
pid="$1" pid="$1"
} }
_initpath() { _initpath() {
if [ -z "$LE_WORKING_DIR" ]; then if [ -z "$LE_WORKING_DIR" ]; then
LE_WORKING_DIR=$HOME/.le LE_WORKING_DIR=$HOME/.le
fi fi
if [ -z "$ACCOUNT_CONF_PATH" ] ; then if [ -z "$ACCOUNT_CONF_PATH" ] ; then
ACCOUNT_CONF_PATH="$LE_WORKING_DIR/account.conf" ACCOUNT_CONF_PATH="$LE_WORKING_DIR/account.conf"
fi fi
if [ -f "$ACCOUNT_CONF_PATH" ] ; then if [ -f "$ACCOUNT_CONF_PATH" ] ; then
source "$ACCOUNT_CONF_PATH" source "$ACCOUNT_CONF_PATH"
fi fi
if [ -z "$API" ] ; then if [ -z "$API" ] ; then
if [ -z "$STAGE" ] ; then if [ -z "$STAGE" ] ; then
API="$DEFAULT_CA" API="$DEFAULT_CA"
else else
API="$STAGE_CA" API="$STAGE_CA"
_info "Using stage api:$API" _info "Using stage api:$API"
fi fi
fi fi
if [ -z "$ACME_DIR" ] ; then if [ -z "$ACME_DIR" ] ; then
ACME_DIR="/home/.acme" ACME_DIR="/home/.acme"
fi fi
if [ -z "$APACHE_CONF_BACKUP_DIR" ] ; then if [ -z "$APACHE_CONF_BACKUP_DIR" ] ; then
APACHE_CONF_BACKUP_DIR="$LE_WORKING_DIR/" APACHE_CONF_BACKUP_DIR="$LE_WORKING_DIR/"
fi fi
domain="$1" domain="$1"
if ! mkdir -p "$LE_WORKING_DIR" ; then if ! mkdir -p "$LE_WORKING_DIR" ; then
_err "Can not craete working dir: $LE_WORKING_DIR" _err "Can not craete working dir: $LE_WORKING_DIR"
return 1 return 1
fi fi
if [ -z "$ACCOUNT_KEY_PATH" ] ; then if [ -z "$ACCOUNT_KEY_PATH" ] ; then
ACCOUNT_KEY_PATH="$LE_WORKING_DIR/account.key" ACCOUNT_KEY_PATH="$LE_WORKING_DIR/account.key"
fi fi
if [ -z "$domain" ] ; then if [ -z "$domain" ] ; then
return 0 return 0
fi fi
domainhome="$LE_WORKING_DIR/$domain" domainhome="$LE_WORKING_DIR/$domain"
mkdir -p "$domainhome" mkdir -p "$domainhome"
if [ -z "$DOMAIN_PATH" ] ; then if [ -z "$DOMAIN_PATH" ] ; then
DOMAIN_PATH="$domainhome" DOMAIN_PATH="$domainhome"
fi fi
if [ -z "$DOMAIN_CONF" ] ; then if [ -z "$DOMAIN_CONF" ] ; then
DOMAIN_CONF="$domainhome/$Le_Domain.conf" DOMAIN_CONF="$domainhome/$Le_Domain.conf"
fi fi
if [ -z "$DOMAIN_SSL_CONF" ] ; then if [ -z "$DOMAIN_SSL_CONF" ] ; then
DOMAIN_SSL_CONF="$domainhome/$Le_Domain.ssl.conf" DOMAIN_SSL_CONF="$domainhome/$Le_Domain.ssl.conf"
fi fi
if [ -z "$CSR_PATH" ] ; then if [ -z "$CSR_PATH" ] ; then
CSR_PATH="$domainhome/$domain.csr" CSR_PATH="$domainhome/$domain.csr"
fi fi
if [ -z "$CERT_KEY_PATH" ] ; then if [ -z "$CERT_KEY_PATH" ] ; then
CERT_KEY_PATH="$domainhome/$domain.key" CERT_KEY_PATH="$domainhome/$domain.key"
fi fi
if [ -z "$CERT_PATH" ] ; then if [ -z "$CERT_PATH" ] ; then
CERT_PATH="$domainhome/$domain.cer" CERT_PATH="$domainhome/$domain.cer"
fi fi
if [ -z "$CA_CERT_PATH" ] ; then if [ -z "$CA_CERT_PATH" ] ; then
CA_CERT_PATH="$domainhome/ca.cer" CA_CERT_PATH="$domainhome/ca.cer"
fi fi
} }
_apachePath() { _apachePath() {
httpdroot="$(apachectl -V | grep HTTPD_ROOT= | cut -d = -f 2 | tr -d '"' )" httpdroot="$(apachectl -V | grep HTTPD_ROOT= | cut -d = -f 2 | tr -d '"' )"
httpdconfname="$(apachectl -V | grep SERVER_CONFIG_FILE= | cut -d = -f 2 | tr -d '"' )" httpdconfname="$(apachectl -V | grep SERVER_CONFIG_FILE= | cut -d = -f 2 | tr -d '"' )"
httpdconf="$httpdroot/$httpdconfname" httpdconf="$httpdroot/$httpdconfname"
if [ ! -f $httpdconf ] ; then if [ ! -f $httpdconf ] ; then
_err "Apache Config file not found" $httpdconf _err "Apache Config file not found" $httpdconf
return 1 return 1
fi fi
return 0 return 0
} }
_restoreApache() { _restoreApache() {
if [ -z "$usingApache" ] ; then if [ -z "$usingApache" ] ; then
return 0 return 0
fi fi
_initpath _initpath
if ! _apachePath ; then if ! _apachePath ; then
return 1 return 1
fi fi
if [ ! -f "$APACHE_CONF_BACKUP_DIR/$httpdconfname" ] ; then if [ ! -f "$APACHE_CONF_BACKUP_DIR/$httpdconfname" ] ; then
_debug "No config file to restore." _debug "No config file to restore."
return 0 return 0
fi fi
cp -p "$APACHE_CONF_BACKUP_DIR/$httpdconfname" "$httpdconf" cp -p "$APACHE_CONF_BACKUP_DIR/$httpdconfname" "$httpdconf"
if ! apachectl -t ; then if ! apachectl -t ; then
_err "Sorry, restore apache config error, please contact me." _err "Sorry, restore apache config error, please contact me."
return 1; return 1;
fi fi
rm -f "$APACHE_CONF_BACKUP_DIR/$httpdconfname" rm -f "$APACHE_CONF_BACKUP_DIR/$httpdconfname"
return 0 return 0
} }
_setApache() { _setApache() {
_initpath _initpath
if ! _apachePath ; then if ! _apachePath ; then
return 1 return 1
fi fi
#backup the conf #backup the conf
_debug "Backup apache config file" $httpdconf _debug "Backup apache config file" $httpdconf
cp -p $httpdconf $APACHE_CONF_BACKUP_DIR/ cp -p $httpdconf $APACHE_CONF_BACKUP_DIR/
_info "JFYI, Config file $httpdconf is backuped to $APACHE_CONF_BACKUP_DIR/$httpdconfname" _info "JFYI, Config file $httpdconf is backuped to $APACHE_CONF_BACKUP_DIR/$httpdconfname"
_info "In case there is an error that can not be restored automatically, you may try restore it yourself." _info "In case there is an error that can not be restored automatically, you may try restore it yourself."
_info "The backup file will be deleted on sucess, just forget it." _info "The backup file will be deleted on sucess, just forget it."
#add alias #add alias
echo " echo "
Alias /.well-known/acme-challenge $ACME_DIR Alias /.well-known/acme-challenge $ACME_DIR
<Directory $ACME_DIR > <Directory $ACME_DIR >
Require all granted Require all granted
</Directory> </Directory>
" >> $httpdconf " >> $httpdconf
if ! apachectl -t ; then if ! apachectl -t ; then
_err "Sorry, apache config error, please contact me." _err "Sorry, apache config error, please contact me."
_restoreApache _restoreApache
return 1; return 1;
fi fi
if [ ! -d "$ACME_DIR" ] ; then if [ ! -d "$ACME_DIR" ] ; then
mkdir -p "$ACME_DIR" mkdir -p "$ACME_DIR"
chmod 755 "$ACME_DIR" chmod 755 "$ACME_DIR"
fi fi
if ! apachectl graceful ; then if ! apachectl graceful ; then
_err "Sorry, apachectl graceful error, please contact me." _err "Sorry, apachectl graceful error, please contact me."
_restoreApache _restoreApache
return 1; return 1;
fi fi
usingApache="1" usingApache="1"
return 0 return 0
} }
_clearup () { _clearup () {
_stopserver $serverproc _stopserver $serverproc
serverproc="" serverproc=""
_restoreApache _restoreApache
} }
# webroot removelevel tokenfile # webroot removelevel tokenfile
_clearupwebbroot() { _clearupwebbroot() {
__webroot="$1" __webroot="$1"
if [ -z "$__webroot" ] ; then if [ -z "$__webroot" ] ; then
_debug "no webroot specified, skip" _debug "no webroot specified, skip"
return 0 return 0
fi fi
if [ "$2" == '1' ] ; then if [ "$2" == '1' ] ; then
_debug "remove $__webroot/.well-known" _debug "remove $__webroot/.well-known"
rm -rf "$__webroot/.well-known" rm -rf "$__webroot/.well-known"
elif [ "$2" == '2' ] ; then elif [ "$2" == '2' ] ; then
_debug "remove $__webroot/.well-known/acme-challenge" _debug "remove $__webroot/.well-known/acme-challenge"
rm -rf "$__webroot/.well-known/acme-challenge" rm -rf "$__webroot/.well-known/acme-challenge"
elif [ "$2" == '3' ] ; then elif [ "$2" == '3' ] ; then
_debug "remove $__webroot/.well-known/acme-challenge/$3" _debug "remove $__webroot/.well-known/acme-challenge/$3"
rm -rf "$__webroot/.well-known/acme-challenge/$3" rm -rf "$__webroot/.well-known/acme-challenge/$3"
else else
_info "Skip for removelevel:$2" _info "Skip for removelevel:$2"
fi fi
return 0 return 0
} }
issue() { issue() {
if [ -z "$2" ] ; then if [ -z "$2" ] ; then
_err "Usage: le issue webroot|no|apache|dns a.com [www.a.com,b.com,c.com]|no [key-length]|no" _err "Usage: le issue webroot|no|apache|dns a.com [www.a.com,b.com,c.com]|no [key-length]|no"
return 1 return 1
fi fi
Le_Webroot="$1" Le_Webroot="$1"
Le_Domain="$2" Le_Domain="$2"
Le_Alt="$3" Le_Alt="$3"
Le_Keylength="$4" Le_Keylength="$4"
Le_RealCertPath="$5" Le_RealCertPath="$5"
Le_RealKeyPath="$6" Le_RealKeyPath="$6"
Le_RealCACertPath="$7" Le_RealCACertPath="$7"
Le_ReloadCmd="$8" Le_ReloadCmd="$8"
_initpath $Le_Domain _initpath $Le_Domain
if [ -f "$DOMAIN_CONF" ] ; then if [ -f "$DOMAIN_CONF" ] ; then
Le_NextRenewTime=$(grep "^Le_NextRenewTime=" "$DOMAIN_CONF" | cut -d '=' -f 2) Le_NextRenewTime=$(grep "^Le_NextRenewTime=" "$DOMAIN_CONF" | cut -d '=' -f 2)
if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(date -u "+%s" )" -lt "$Le_NextRenewTime" ] ; then if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(date -u "+%s" )" -lt "$Le_NextRenewTime" ] ; then
_info "Skip, Next renewal time is: $(grep "^Le_NextRenewTimeStr" "$DOMAIN_CONF" | cut -d '=' -f 2)" _info "Skip, Next renewal time is: $(grep "^Le_NextRenewTimeStr" "$DOMAIN_CONF" | cut -d '=' -f 2)"
return 2 return 2
fi fi
fi fi
if [ "$Le_Alt" == "no" ] ; then if [ "$Le_Alt" == "no" ] ; then
Le_Alt="" Le_Alt=""
fi fi
if [ "$Le_Keylength" == "no" ] ; then if [ "$Le_Keylength" == "no" ] ; then
Le_Keylength="" Le_Keylength=""
fi fi
if [ "$Le_RealCertPath" == "no" ] ; then if [ "$Le_RealCertPath" == "no" ] ; then
Le_RealCertPath="" Le_RealCertPath=""
fi fi
if [ "$Le_RealKeyPath" == "no" ] ; then if [ "$Le_RealKeyPath" == "no" ] ; then
Le_RealKeyPath="" Le_RealKeyPath=""
fi fi
if [ "$Le_RealCACertPath" == "no" ] ; then if [ "$Le_RealCACertPath" == "no" ] ; then
Le_RealCACertPath="" Le_RealCACertPath=""
fi fi
if [ "$Le_ReloadCmd" == "no" ] ; then if [ "$Le_ReloadCmd" == "no" ] ; then
Le_ReloadCmd="" Le_ReloadCmd=""
fi fi
_setopt "$DOMAIN_CONF" "Le_Domain" "=" "$Le_Domain" _setopt "$DOMAIN_CONF" "Le_Domain" "=" "$Le_Domain"
_setopt "$DOMAIN_CONF" "Le_Alt" "=" "$Le_Alt" _setopt "$DOMAIN_CONF" "Le_Alt" "=" "$Le_Alt"
_setopt "$DOMAIN_CONF" "Le_Webroot" "=" "$Le_Webroot" _setopt "$DOMAIN_CONF" "Le_Webroot" "=" "$Le_Webroot"
_setopt "$DOMAIN_CONF" "Le_Keylength" "=" "$Le_Keylength" _setopt "$DOMAIN_CONF" "Le_Keylength" "=" "$Le_Keylength"
_setopt "$DOMAIN_CONF" "Le_RealCertPath" "=" "\"$Le_RealCertPath\"" _setopt "$DOMAIN_CONF" "Le_RealCertPath" "=" "\"$Le_RealCertPath\""
_setopt "$DOMAIN_CONF" "Le_RealCACertPath" "=" "\"$Le_RealCACertPath\"" _setopt "$DOMAIN_CONF" "Le_RealCACertPath" "=" "\"$Le_RealCACertPath\""
_setopt "$DOMAIN_CONF" "Le_RealKeyPath" "=" "\"$Le_RealKeyPath\"" _setopt "$DOMAIN_CONF" "Le_RealKeyPath" "=" "\"$Le_RealKeyPath\""
_setopt "$DOMAIN_CONF" "Le_ReloadCmd" "=" "\"$Le_ReloadCmd\"" _setopt "$DOMAIN_CONF" "Le_ReloadCmd" "=" "\"$Le_ReloadCmd\""
if [ "$Le_Webroot" == "no" ] ; then if [ "$Le_Webroot" == "no" ] ; then
_info "Standalone mode." _info "Standalone mode."
if ! command -v "nc" > /dev/null ; then if ! command -v "nc" > /dev/null ; then
_err "Please install netcat(nc) tools first." _err "Please install netcat(nc) tools first."
return 1 return 1
fi fi
if [ -z "$Le_HTTPPort" ] ; then if [ -z "$Le_HTTPPort" ] ; then
Le_HTTPPort=80 Le_HTTPPort=80
fi fi
_setopt "$DOMAIN_CONF" "Le_HTTPPort" "=" "$Le_HTTPPort" _setopt "$DOMAIN_CONF" "Le_HTTPPort" "=" "$Le_HTTPPort"
netprc="$(ss -ntpl | grep :$Le_HTTPPort" ")" netprc="$(ss -ntpl | grep :$Le_HTTPPort" ")"
if [ "$netprc" ] ; then if [ "$netprc" ] ; then
_err "$netprc" _err "$netprc"
_err "tcp port $Le_HTTPPort is already used by $(echo "$netprc" | cut -d : -f 4)" _err "tcp port $Le_HTTPPort is already used by $(echo "$netprc" | cut -d : -f 4)"
_err "Please stop it first" _err "Please stop it first"
return 1 return 1
fi fi
fi fi
if [ "$Le_Webroot" == "apache" ] ; then if [ "$Le_Webroot" == "apache" ] ; then
if ! _setApache ; then if ! _setApache ; then
_err "set up apache error. Report error to me." _err "set up apache error. Report error to me."
return 1 return 1
fi fi
wellknown_path="$ACME_DIR" wellknown_path="$ACME_DIR"
else else
usingApache="" usingApache=""
fi fi
createAccountKey $Le_Domain $Le_Keylength createAccountKey $Le_Domain $Le_Keylength
if ! createDomainKey $Le_Domain $Le_Keylength ; then if ! createDomainKey $Le_Domain $Le_Keylength ; then
_err "Create domain key error." _err "Create domain key error."
return 1 return 1
fi fi
if ! createCSR $Le_Domain $Le_Alt ; then if ! createCSR $Le_Domain $Le_Alt ; then
_err "Create CSR error." _err "Create CSR error."
return 1 return 1
fi fi
pub_exp=$(openssl rsa -in $ACCOUNT_KEY_PATH -noout -text | grep "^publicExponent:"| cut -d '(' -f 2 | cut -d 'x' -f 2 | cut -d ')' -f 1) pub_exp=$(openssl rsa -in $ACCOUNT_KEY_PATH -noout -text | grep "^publicExponent:"| cut -d '(' -f 2 | cut -d 'x' -f 2 | cut -d ')' -f 1)
if [ "${#pub_exp}" == "5" ] ; then if [ "${#pub_exp}" == "5" ] ; then
pub_exp=0$pub_exp pub_exp=0$pub_exp
fi fi
_debug pub_exp "$pub_exp" _debug pub_exp "$pub_exp"
e=$(echo $pub_exp | _h2b | _base64) e=$(echo $pub_exp | _h2b | _base64)
_debug e "$e" _debug e "$e"
modulus=$(openssl rsa -in $ACCOUNT_KEY_PATH -modulus -noout | cut -d '=' -f 2 ) modulus=$(openssl rsa -in $ACCOUNT_KEY_PATH -modulus -noout | cut -d '=' -f 2 )
n=$(echo $modulus| _h2b | _base64 | _b64 ) n=$(echo $modulus| _h2b | _base64 | _b64 )
jwk='{"e": "'$e'", "kty": "RSA", "n": "'$n'"}' jwk='{"e": "'$e'", "kty": "RSA", "n": "'$n'"}'
HEADER='{"alg": "RS256", "jwk": '$jwk'}' HEADER='{"alg": "RS256", "jwk": '$jwk'}'
HEADERPLACE='{"nonce": "NONCE", "alg": "RS256", "jwk": '$jwk'}' HEADERPLACE='{"nonce": "NONCE", "alg": "RS256", "jwk": '$jwk'}'
_debug HEADER "$HEADER" _debug HEADER "$HEADER"
accountkey_json=$(echo -n "$jwk" | tr -d ' ' ) accountkey_json=$(echo -n "$jwk" | tr -d ' ' )
thumbprint=$(echo -n "$accountkey_json" | openssl dgst -sha256 -binary | _base64 | _b64) thumbprint=$(echo -n "$accountkey_json" | openssl dgst -sha256 -binary | _base64 | _b64)
_info "Registering account" _info "Registering account"
regjson='{"resource": "new-reg", "agreement": "'$AGREEMENT'"}' regjson='{"resource": "new-reg", "agreement": "'$AGREEMENT'"}'
if [ "$ACCOUNT_EMAIL" ] ; then if [ "$ACCOUNT_EMAIL" ] ; then
regjson='{"resource": "new-reg", "contact": ["mailto: '$ACCOUNT_EMAIL'"], "agreement": "'$AGREEMENT'"}' regjson='{"resource": "new-reg", "contact": ["mailto: '$ACCOUNT_EMAIL'"], "agreement": "'$AGREEMENT'"}'
fi fi
_send_signed_request "$API/acme/new-reg" "$regjson" _send_signed_request "$API/acme/new-reg" "$regjson"
if [ "$code" == "" ] || [ "$code" == '201' ] ; then if [ "$code" == "" ] || [ "$code" == '201' ] ; then
_info "Registered" _info "Registered"
echo $response > $LE_WORKING_DIR/account.json echo $response > $LE_WORKING_DIR/account.json
elif [ "$code" == '409' ] ; then elif [ "$code" == '409' ] ; then
_info "Already registered" _info "Already registered"
else else
_err "Register account Error." _err "Register account Error."
_clearup _clearup
return 1 return 1
fi fi
vtype="$VTYPE_HTTP" vtype="$VTYPE_HTTP"
if [[ "$Le_Webroot" == "dns"* ]] ; then if [[ "$Le_Webroot" == "dns"* ]] ; then
vtype="$VTYPE_DNS" vtype="$VTYPE_DNS"
fi fi
vlist="$Le_Vlist" vlist="$Le_Vlist"
# verify each domain # verify each domain
_info "Verify each domain" _info "Verify each domain"
sep='#' sep='#'
if [ -z "$vlist" ] ; then if [ -z "$vlist" ] ; then
alldomains=$(echo "$Le_Domain,$Le_Alt" | tr ',' ' ' ) alldomains=$(echo "$Le_Domain,$Le_Alt" | tr ',' ' ' )
for d in $alldomains for d in $alldomains
do do
_info "Getting token for domain" $d _info "Getting token for domain" $d
_send_signed_request "$API/acme/new-authz" "{\"resource\": \"new-authz\", \"identifier\": {\"type\": \"dns\", \"value\": \"$d\"}}" _send_signed_request "$API/acme/new-authz" "{\"resource\": \"new-authz\", \"identifier\": {\"type\": \"dns\", \"value\": \"$d\"}}"
if [ ! -z "$code" ] && [ ! "$code" == '201' ] ; then if [ ! -z "$code" ] && [ ! "$code" == '201' ] ; then
_err "new-authz error: $response" _err "new-authz error: $response"
_clearup _clearup
return 1 return 1
fi fi
entry="$(printf $response | egrep -o '{[^{]*"type":"'$vtype'"[^}]*')" entry="$(printf $response | egrep -o '{[^{]*"type":"'$vtype'"[^}]*')"
_debug entry "$entry" _debug entry "$entry"
token="$(printf "$entry" | egrep -o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')" token="$(printf "$entry" | egrep -o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')"
_debug token $token _debug token $token
uri="$(printf "$entry" | egrep -o '"uri":"[^"]*'| cut -d : -f 2,3 | tr -d '"' )" uri="$(printf "$entry" | egrep -o '"uri":"[^"]*'| cut -d : -f 2,3 | tr -d '"' )"
_debug uri $uri _debug uri $uri
keyauthorization="$token.$thumbprint" keyauthorization="$token.$thumbprint"
_debug keyauthorization "$keyauthorization" _debug keyauthorization "$keyauthorization"
dvlist="$d$sep$keyauthorization$sep$uri" dvlist="$d$sep$keyauthorization$sep$uri"
_debug dvlist "$dvlist" _debug dvlist "$dvlist"
vlist="$vlist$dvlist," vlist="$vlist$dvlist,"
done done
#add entry #add entry
dnsadded="" dnsadded=""
ventries=$(echo "$vlist" | tr ',' ' ' ) ventries=$(echo "$vlist" | tr ',' ' ' )
for ventry in $ventries for ventry in $ventries
do do
d=$(echo $ventry | cut -d $sep -f 1) d=$(echo $ventry | cut -d $sep -f 1)
keyauthorization=$(echo $ventry | cut -d $sep -f 2) keyauthorization=$(echo $ventry | cut -d $sep -f 2)
if [ "$vtype" == "$VTYPE_DNS" ] ; then if [ "$vtype" == "$VTYPE_DNS" ] ; then
dnsadded='0' dnsadded='0'
txtdomain="_acme-challenge.$d" txtdomain="_acme-challenge.$d"
_debug txtdomain "$txtdomain" _debug txtdomain "$txtdomain"
txt="$(echo -e -n $keyauthorization | openssl dgst -sha256 -binary | _base64 | _b64)" txt="$(echo -e -n $keyauthorization | openssl dgst -sha256 -binary | _base64 | _b64)"
_debug txt "$txt" _debug txt "$txt"
#dns #dns
#1. check use api #1. check use api
d_api="" d_api=""
if [ -f "$LE_WORKING_DIR/$d/$Le_Webroot" ] ; then if [ -f "$LE_WORKING_DIR/$d/$Le_Webroot" ] ; then
d_api="$LE_WORKING_DIR/$d/$Le_Webroot" d_api="$LE_WORKING_DIR/$d/$Le_Webroot"
elif [ -f "$LE_WORKING_DIR/$d/$Le_Webroot.sh" ] ; then elif [ -f "$LE_WORKING_DIR/$d/$Le_Webroot.sh" ] ; then
d_api="$LE_WORKING_DIR/$d/$Le_Webroot.sh" d_api="$LE_WORKING_DIR/$d/$Le_Webroot.sh"
elif [ -f "$LE_WORKING_DIR/$Le_Webroot" ] ; then elif [ -f "$LE_WORKING_DIR/$Le_Webroot" ] ; then
d_api="$LE_WORKING_DIR/$Le_Webroot" d_api="$LE_WORKING_DIR/$Le_Webroot"
elif [ -f "$LE_WORKING_DIR/$Le_Webroot.sh" ] ; then elif [ -f "$LE_WORKING_DIR/$Le_Webroot.sh" ] ; then
d_api="$LE_WORKING_DIR/$Le_Webroot.sh" d_api="$LE_WORKING_DIR/$Le_Webroot.sh"
elif [ -f "$LE_WORKING_DIR/dnsapi/$Le_Webroot" ] ; then elif [ -f "$LE_WORKING_DIR/dnsapi/$Le_Webroot" ] ; then
d_api="$LE_WORKING_DIR/dnsapi/$Le_Webroot" d_api="$LE_WORKING_DIR/dnsapi/$Le_Webroot"
elif [ -f "$LE_WORKING_DIR/dnsapi/$Le_Webroot.sh" ] ; then elif [ -f "$LE_WORKING_DIR/dnsapi/$Le_Webroot.sh" ] ; then
d_api="$LE_WORKING_DIR/dnsapi/$Le_Webroot.sh" d_api="$LE_WORKING_DIR/dnsapi/$Le_Webroot.sh"
fi fi
_debug d_api "$d_api" _debug d_api "$d_api"
if [ "$d_api" ]; then if [ "$d_api" ]; then
_info "Found domain api file: $d_api" _info "Found domain api file: $d_api"
else else
_err "Add the following TXT record:" _err "Add the following TXT record:"
_err "Domain: $txtdomain" _err "Domain: $txtdomain"
_err "TXT value: $txt" _err "TXT value: $txt"
_err "Please be aware that you prepend _acme-challenge. before your domain" _err "Please be aware that you prepend _acme-challenge. before your domain"
_err "so the resulting subdomain will be: $txtdomain" _err "so the resulting subdomain will be: $txtdomain"
continue continue
fi fi
if ! source $d_api ; then if ! source $d_api ; then
_err "Load file $d_api error. Please check your api file and try again." _err "Load file $d_api error. Please check your api file and try again."
return 1 return 1
fi fi
addcommand="$Le_Webroot-add" addcommand="$Le_Webroot-add"
if ! command -v $addcommand ; then if ! command -v $addcommand ; then
_err "It seems that your api file is not correct, it must have a function named: $Le_Webroot" _err "It seems that your api file is not correct, it must have a function named: $Le_Webroot"
return 1 return 1
fi fi
if ! $addcommand $txtdomain $txt ; then if ! $addcommand $txtdomain $txt ; then
_err "Error add txt for domain:$txtdomain" _err "Error add txt for domain:$txtdomain"
return 1 return 1
fi fi
dnsadded='1' dnsadded='1'
fi fi
done done
if [ "$dnsadded" == '0' ] ; then if [ "$dnsadded" == '0' ] ; then
_setopt "$DOMAIN_CONF" "Le_Vlist" "=" "\"$vlist\"" _setopt "$DOMAIN_CONF" "Le_Vlist" "=" "\"$vlist\""
_debug "Dns record not added yet, so, save to $DOMAIN_CONF and exit." _debug "Dns record not added yet, so, save to $DOMAIN_CONF and exit."
_err "Please add the TXT records to the domains, and retry again." _err "Please add the TXT records to the domains, and retry again."
return 1 return 1
fi fi
fi fi
if [ "$dnsadded" == '1' ] ; then if [ "$dnsadded" == '1' ] ; then
_info "Sleep 60 seconds for the txt records to take effect" _info "Sleep 60 seconds for the txt records to take effect"
sleep 60 sleep 60
fi fi
_debug "ok, let's start to verify" _debug "ok, let's start to verify"
ventries=$(echo "$vlist" | tr ',' ' ' ) ventries=$(echo "$vlist" | tr ',' ' ' )
for ventry in $ventries for ventry in $ventries
do do
d=$(echo $ventry | cut -d $sep -f 1) d=$(echo $ventry | cut -d $sep -f 1)
keyauthorization=$(echo $ventry | cut -d $sep -f 2) keyauthorization=$(echo $ventry | cut -d $sep -f 2)
uri=$(echo $ventry | cut -d $sep -f 3) uri=$(echo $ventry | cut -d $sep -f 3)
_info "Verifying:$d" _info "Verifying:$d"
_debug "d" "$d" _debug "d" "$d"
_debug "keyauthorization" "$keyauthorization" _debug "keyauthorization" "$keyauthorization"
_debug "uri" "$uri" _debug "uri" "$uri"
removelevel="" removelevel=""
token="" token=""
if [ "$vtype" == "$VTYPE_HTTP" ] ; then if [ "$vtype" == "$VTYPE_HTTP" ] ; then
if [ "$Le_Webroot" == "no" ] ; then if [ "$Le_Webroot" == "no" ] ; then
_info "Standalone mode server" _info "Standalone mode server"
_startserver "$keyauthorization" & _startserver "$keyauthorization" &
serverproc="$!" serverproc="$!"
sleep 2 sleep 2
_debug serverproc $serverproc _debug serverproc $serverproc
else else
if [ -z "$wellknown_path" ] ; then if [ -z "$wellknown_path" ] ; then
wellknown_path="$Le_Webroot/.well-known/acme-challenge" wellknown_path="$Le_Webroot/.well-known/acme-challenge"
fi fi
_debug wellknown_path "$wellknown_path" _debug wellknown_path "$wellknown_path"
if [ ! -d "$Le_Webroot/.well-known" ] ; then if [ ! -d "$Le_Webroot/.well-known" ] ; then
removelevel='1' removelevel='1'
elif [ ! -d "$Le_Webroot/.well-known/acme-challenge" ] ; then elif [ ! -d "$Le_Webroot/.well-known/acme-challenge" ] ; then
removelevel='2' removelevel='2'
else else
removelevel='3' removelevel='3'
fi fi
token="$(echo -e -n "$keyauthorization" | cut -d '.' -f 1)" token="$(echo -e -n "$keyauthorization" | cut -d '.' -f 1)"
_debug "writing token:$token to $wellknown_path/$token" _debug "writing token:$token to $wellknown_path/$token"
mkdir -p "$wellknown_path" mkdir -p "$wellknown_path"
echo -n "$keyauthorization" > "$wellknown_path/$token" echo -n "$keyauthorization" > "$wellknown_path/$token"
webroot_owner=$(stat -c '%U:%G' $Le_Webroot) webroot_owner=$(stat -c '%U:%G' $Le_Webroot)
_debug "Changing owner/group of .well-known to $webroot_owner" _debug "Changing owner/group of .well-known to $webroot_owner"
chown -R $webroot_owner "$Le_Webroot/.well-known" chown -R $webroot_owner "$Le_Webroot/.well-known"
fi fi
fi fi
_send_signed_request $uri "{\"resource\": \"challenge\", \"keyAuthorization\": \"$keyauthorization\"}" _send_signed_request $uri "{\"resource\": \"challenge\", \"keyAuthorization\": \"$keyauthorization\"}"
if [ ! -z "$code" ] && [ ! "$code" == '202' ] ; then if [ ! -z "$code" ] && [ ! "$code" == '202' ] ; then
_err "$d:Challenge error: $resource" _err "$d:Challenge error: $resource"
_clearupwebbroot "$Le_Webroot" "$removelevel" "$token" _clearupwebbroot "$Le_Webroot" "$removelevel" "$token"
_clearup _clearup
return 1 return 1
fi fi
while [ "1" ] ; do while [ "1" ] ; do
_debug "sleep 5 secs to verify" _debug "sleep 5 secs to verify"
sleep 5 sleep 5
_debug "checking" _debug "checking"
if ! _get $uri ; then if ! _get $uri ; then
_err "$d:Verify error:$resource" _err "$d:Verify error:$resource"
_clearupwebbroot "$Le_Webroot" "$removelevel" "$token" _clearupwebbroot "$Le_Webroot" "$removelevel" "$token"
_clearup _clearup
return 1 return 1
fi fi
status=$(echo $response | egrep -o '"status":"[^"]+"' | cut -d : -f 2 | tr -d '"') status=$(echo $response | egrep -o '"status":"[^"]+"' | cut -d : -f 2 | tr -d '"')
if [ "$status" == "valid" ] ; then if [ "$status" == "valid" ] ; then
_info "Success" _info "Success"
_stopserver $serverproc _stopserver $serverproc
serverproc="" serverproc=""
_clearupwebbroot "$Le_Webroot" "$removelevel" "$token" _clearupwebbroot "$Le_Webroot" "$removelevel" "$token"
break; break;
fi fi
if [ "$status" == "invalid" ] ; then if [ "$status" == "invalid" ] ; then
error=$(echo $response | egrep -o '"error":{[^}]*}' | grep -o '"detail":"[^"]*"' | cut -d '"' -f 4) error=$(echo $response | egrep -o '"error":{[^}]*}' | grep -o '"detail":"[^"]*"' | cut -d '"' -f 4)
_err "$d:Verify error:$error" _err "$d:Verify error:$error"
_clearupwebbroot "$Le_Webroot" "$removelevel" "$token" _clearupwebbroot "$Le_Webroot" "$removelevel" "$token"
_clearup _clearup
return 1; return 1;
fi fi
if [ "$status" == "pending" ] ; then if [ "$status" == "pending" ] ; then
_info "Pending" _info "Pending"
else else
_err "$d:Verify error:$response" _err "$d:Verify error:$response"
_clearupwebbroot "$Le_Webroot" "$removelevel" "$token" _clearupwebbroot "$Le_Webroot" "$removelevel" "$token"
_clearup _clearup
return 1 return 1
fi fi
done done
done done
_clearup _clearup
_info "Verify finished, start to sign." _info "Verify finished, start to sign."
der="$(openssl req -in $CSR_PATH -outform DER | _base64 | _b64)" der="$(openssl req -in $CSR_PATH -outform DER | _base64 | _b64)"
_send_signed_request "$API/acme/new-cert" "{\"resource\": \"new-cert\", \"csr\": \"$der\"}" "needbase64" _send_signed_request "$API/acme/new-cert" "{\"resource\": \"new-cert\", \"csr\": \"$der\"}" "needbase64"
Le_LinkCert="$(grep -i -o '^Location.*$' $CURL_HEADER | tr -d "\r\n" | cut -d " " -f 2)" Le_LinkCert="$(grep -i -o '^Location.*$' $CURL_HEADER | tr -d "\r\n" | cut -d " " -f 2)"
_setopt "$DOMAIN_CONF" "Le_LinkCert" "=" "$Le_LinkCert" _setopt "$DOMAIN_CONF" "Le_LinkCert" "=" "$Le_LinkCert"
if [ "$Le_LinkCert" ] ; then if [ "$Le_LinkCert" ] ; then
echo -----BEGIN CERTIFICATE----- > "$CERT_PATH" echo -----BEGIN CERTIFICATE----- > "$CERT_PATH"
curl --silent "$Le_LinkCert" | openssl base64 -e >> "$CERT_PATH" curl --silent "$Le_LinkCert" | openssl base64 -e >> "$CERT_PATH"
echo -----END CERTIFICATE----- >> "$CERT_PATH" echo -----END CERTIFICATE----- >> "$CERT_PATH"
_info "Cert success." _info "Cert success."
cat "$CERT_PATH" cat "$CERT_PATH"
_info "Your cert is in $CERT_PATH" _info "Your cert is in $CERT_PATH"
fi fi
if [ -z "$Le_LinkCert" ] ; then if [ -z "$Le_LinkCert" ] ; then
response="$(echo $response | openssl base64 -d -A)" response="$(echo $response | openssl base64 -d -A)"
_err "Sign failed: $(echo "$response" | grep -o '"detail":"[^"]*"')" _err "Sign failed: $(echo "$response" | grep -o '"detail":"[^"]*"')"
return 1 return 1
fi fi
_setopt "$DOMAIN_CONF" 'Le_Vlist' '=' "\"\"" _setopt "$DOMAIN_CONF" 'Le_Vlist' '=' "\"\""
Le_LinkIssuer=$(grep -i '^Link' $CURL_HEADER | cut -d " " -f 2| cut -d ';' -f 1 | tr -d '<>' ) Le_LinkIssuer=$(grep -i '^Link' $CURL_HEADER | cut -d " " -f 2| cut -d ';' -f 1 | tr -d '<>' )
_setopt "$DOMAIN_CONF" "Le_LinkIssuer" "=" "$Le_LinkIssuer" _setopt "$DOMAIN_CONF" "Le_LinkIssuer" "=" "$Le_LinkIssuer"
if [ "$Le_LinkIssuer" ] ; then if [ "$Le_LinkIssuer" ] ; then
echo -----BEGIN CERTIFICATE----- > "$CA_CERT_PATH" echo -----BEGIN CERTIFICATE----- > "$CA_CERT_PATH"
curl --silent "$Le_LinkIssuer" | openssl base64 -e >> "$CA_CERT_PATH" curl --silent "$Le_LinkIssuer" | openssl base64 -e >> "$CA_CERT_PATH"
echo -----END CERTIFICATE----- >> "$CA_CERT_PATH" echo -----END CERTIFICATE----- >> "$CA_CERT_PATH"
_info "The intermediate CA cert is in $CA_CERT_PATH" _info "The intermediate CA cert is in $CA_CERT_PATH"
fi fi
Le_CertCreateTime=$(date -u "+%s") Le_CertCreateTime=$(date -u "+%s")
_setopt "$DOMAIN_CONF" "Le_CertCreateTime" "=" "$Le_CertCreateTime" _setopt "$DOMAIN_CONF" "Le_CertCreateTime" "=" "$Le_CertCreateTime"
Le_CertCreateTimeStr=$(date -u ) Le_CertCreateTimeStr=$(date -u )
_setopt "$DOMAIN_CONF" "Le_CertCreateTimeStr" "=" "\"$Le_CertCreateTimeStr\"" _setopt "$DOMAIN_CONF" "Le_CertCreateTimeStr" "=" "\"$Le_CertCreateTimeStr\""
if [ ! "$Le_RenewalDays" ] ; then if [ ! "$Le_RenewalDays" ] ; then
Le_RenewalDays=80 Le_RenewalDays=80
fi fi
_setopt "$DOMAIN_CONF" "Le_RenewalDays" "=" "$Le_RenewalDays" _setopt "$DOMAIN_CONF" "Le_RenewalDays" "=" "$Le_RenewalDays"
let "Le_NextRenewTime=Le_CertCreateTime+Le_RenewalDays*24*60*60" let "Le_NextRenewTime=Le_CertCreateTime+Le_RenewalDays*24*60*60"
_setopt "$DOMAIN_CONF" "Le_NextRenewTime" "=" "$Le_NextRenewTime" _setopt "$DOMAIN_CONF" "Le_NextRenewTime" "=" "$Le_NextRenewTime"
Le_NextRenewTimeStr=$( _time2str $Le_NextRenewTime ) Le_NextRenewTimeStr=$( _time2str $Le_NextRenewTime )
_setopt "$DOMAIN_CONF" "Le_NextRenewTimeStr" "=" "\"$Le_NextRenewTimeStr\"" _setopt "$DOMAIN_CONF" "Le_NextRenewTimeStr" "=" "\"$Le_NextRenewTimeStr\""
installcert $Le_Domain "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" installcert $Le_Domain "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd"
} }
renew() { renew() {
Le_Domain="$1" Le_Domain="$1"
if [ -z "$Le_Domain" ] ; then if [ -z "$Le_Domain" ] ; then
_err "Usage: $0 domain.com" _err "Usage: $0 domain.com"
return 1 return 1
fi fi
_initpath $Le_Domain _initpath $Le_Domain
if [ ! -f "$DOMAIN_CONF" ] ; then if [ ! -f "$DOMAIN_CONF" ] ; then
_info "$Le_Domain is not a issued domain, skip." _info "$Le_Domain is not a issued domain, skip."
return 0; return 0;
fi fi
source "$DOMAIN_CONF" source "$DOMAIN_CONF"
if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(date -u "+%s" )" -lt "$Le_NextRenewTime" ] ; then if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(date -u "+%s" )" -lt "$Le_NextRenewTime" ] ; then
_info "Skip, Next renewal time is: $Le_NextRenewTimeStr" _info "Skip, Next renewal time is: $Le_NextRenewTimeStr"
return 2 return 2
fi fi
IS_RENEW="1" IS_RENEW="1"
issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd"
local res=$? local res=$?
IS_RENEW="" IS_RENEW=""
return $res return $res
} }
renewAll() { renewAll() {
_initpath _initpath
_info "renewAll" _info "renewAll"
for d in $(ls -F $LE_WORKING_DIR | grep [^.].*[.].*/$ ) ; do for d in $(ls -F $LE_WORKING_DIR | grep [^.].*[.].*/$ ) ; do
d=$(echo $d | cut -d '/' -f 1) d=$(echo $d | cut -d '/' -f 1)
_info "renew $d" _info "renew $d"
Le_LinkCert="" Le_LinkCert=""
Le_Domain="" Le_Domain=""
Le_Alt="" Le_Alt=""
Le_Webroot="" Le_Webroot=""
Le_Keylength="" Le_Keylength=""
Le_LinkIssuer="" Le_LinkIssuer=""
Le_CertCreateTime="" Le_CertCreateTime=""
Le_CertCreateTimeStr="" Le_CertCreateTimeStr=""
Le_RenewalDays="" Le_RenewalDays=""
Le_NextRenewTime="" Le_NextRenewTime=""
Le_NextRenewTimeStr="" Le_NextRenewTimeStr=""
Le_RealCertPath="" Le_RealCertPath=""
Le_RealKeyPath="" Le_RealKeyPath=""
Le_RealCACertPath="" Le_RealCACertPath=""
Le_ReloadCmd="" Le_ReloadCmd=""
DOMAIN_PATH="" DOMAIN_PATH=""
DOMAIN_CONF="" DOMAIN_CONF=""
DOMAIN_SSL_CONF="" DOMAIN_SSL_CONF=""
CSR_PATH="" CSR_PATH=""
CERT_KEY_PATH="" CERT_KEY_PATH=""
CERT_PATH="" CERT_PATH=""
CA_CERT_PATH="" CA_CERT_PATH=""
ACCOUNT_KEY_PATH="" ACCOUNT_KEY_PATH=""
wellknown_path="" wellknown_path=""
renew "$d" renew "$d"
done done
} }
installcert() { installcert() {
Le_Domain="$1" Le_Domain="$1"
if [ -z "$Le_Domain" ] ; then if [ -z "$Le_Domain" ] ; then
_err "Usage: $0 domain.com [cert-file-path]|no [key-file-path]|no [ca-cert-file-path]|no [reloadCmd]|no" _err "Usage: $0 domain.com [cert-file-path]|no [key-file-path]|no [ca-cert-file-path]|no [reloadCmd]|no"
return 1 return 1
fi fi
Le_RealCertPath="$2" Le_RealCertPath="$2"
Le_RealKeyPath="$3" Le_RealKeyPath="$3"
Le_RealCACertPath="$4" Le_RealCACertPath="$4"
Le_ReloadCmd="$5" Le_ReloadCmd="$5"
_initpath $Le_Domain _initpath $Le_Domain
_setopt "$DOMAIN_CONF" "Le_RealCertPath" "=" "\"$Le_RealCertPath\"" _setopt "$DOMAIN_CONF" "Le_RealCertPath" "=" "\"$Le_RealCertPath\""
_setopt "$DOMAIN_CONF" "Le_RealCACertPath" "=" "\"$Le_RealCACertPath\"" _setopt "$DOMAIN_CONF" "Le_RealCACertPath" "=" "\"$Le_RealCACertPath\""
_setopt "$DOMAIN_CONF" "Le_RealKeyPath" "=" "\"$Le_RealKeyPath\"" _setopt "$DOMAIN_CONF" "Le_RealKeyPath" "=" "\"$Le_RealKeyPath\""
_setopt "$DOMAIN_CONF" "Le_ReloadCmd" "=" "\"$Le_ReloadCmd\"" _setopt "$DOMAIN_CONF" "Le_ReloadCmd" "=" "\"$Le_ReloadCmd\""
if [ "$Le_RealCertPath" ] ; then if [ "$Le_RealCertPath" ] ; then
if [ -f "$Le_RealCertPath" ] ; then if [ -f "$Le_RealCertPath" ] ; then
cp -p "$Le_RealCertPath" "$Le_RealCertPath".bak cp -p "$Le_RealCertPath" "$Le_RealCertPath".bak
fi fi
cat "$CERT_PATH" > "$Le_RealCertPath" cat "$CERT_PATH" > "$Le_RealCertPath"
fi fi
if [ "$Le_RealCACertPath" ] ; then if [ "$Le_RealCACertPath" ] ; then
if [ -f "$Le_RealCACertPath" ] ; then if [ -f "$Le_RealCACertPath" ] ; then
cp -p "$Le_RealCACertPath" "$Le_RealCACertPath".bak cp -p "$Le_RealCACertPath" "$Le_RealCACertPath".bak
fi fi
if [ "$Le_RealCACertPath" == "$Le_RealCertPath" ] ; then if [ "$Le_RealCACertPath" == "$Le_RealCertPath" ] ; then
echo "" >> "$Le_RealCACertPath" echo "" >> "$Le_RealCACertPath"
cat "$CA_CERT_PATH" >> "$Le_RealCACertPath" cat "$CA_CERT_PATH" >> "$Le_RealCACertPath"
else else
cat "$CA_CERT_PATH" > "$Le_RealCACertPath" cat "$CA_CERT_PATH" > "$Le_RealCACertPath"
fi fi
fi fi
if [ "$Le_RealKeyPath" ] ; then if [ "$Le_RealKeyPath" ] ; then
if [ -f "$Le_RealKeyPath" ] ; then if [ -f "$Le_RealKeyPath" ] ; then
cp -p "$Le_RealKeyPath" "$Le_RealKeyPath".bak cp -p "$Le_RealKeyPath" "$Le_RealKeyPath".bak
fi fi
cat "$CERT_KEY_PATH" > "$Le_RealKeyPath" cat "$CERT_KEY_PATH" > "$Le_RealKeyPath"
fi fi
if [ "$Le_ReloadCmd" ] ; then if [ "$Le_ReloadCmd" ] ; then
_info "Run Le_ReloadCmd: $Le_ReloadCmd" _info "Run Le_ReloadCmd: $Le_ReloadCmd"
(cd "$DOMAIN_PATH" && eval "$Le_ReloadCmd") (cd "$DOMAIN_PATH" && eval "$Le_ReloadCmd")
fi fi
} }
installcronjob() { installcronjob() {
_initpath _initpath
_info "Installing cron job" _info "Installing cron job"
if ! crontab -l | grep 'le.sh cron' ; then if ! crontab -l | grep 'le.sh cron' ; then
if [ -f "$LE_WORKING_DIR/le.sh" ] ; then if [ -f "$LE_WORKING_DIR/le.sh" ] ; then
lesh="\"$LE_WORKING_DIR\"/le.sh" lesh="\"$LE_WORKING_DIR\"/le.sh"
else else
_err "Can not install cronjob, le.sh not found." _err "Can not install cronjob, le.sh not found."
return 1 return 1
fi fi
crontab -l | { cat; echo "0 0 * * * LE_WORKING_DIR=\"$LE_WORKING_DIR\" $lesh cron > /dev/null"; } | crontab - crontab -l | { cat; echo "0 0 * * * LE_WORKING_DIR=\"$LE_WORKING_DIR\" $lesh cron > /dev/null"; } | crontab -
fi fi
if [ "$?" != "0" ] ; then if [ "$?" != "0" ] ; then
_err "Install cron job failed. You need to manually renew your certs." _err "Install cron job failed. You need to manually renew your certs."
_err "Or you can add cronjob by yourself:" _err "Or you can add cronjob by yourself:"
_err "LE_WORKING_DIR=\"$LE_WORKING_DIR\" $lesh cron > /dev/null" _err "LE_WORKING_DIR=\"$LE_WORKING_DIR\" $lesh cron > /dev/null"
return 1 return 1
fi fi
} }
uninstallcronjob() { uninstallcronjob() {
_info "Removing cron job" _info "Removing cron job"
cr="$(crontab -l | grep 'le.sh cron')" cr="$(crontab -l | grep 'le.sh cron')"
if [ "$cr" ] ; then if [ "$cr" ] ; then
crontab -l | sed "/le.sh cron/d" | crontab - crontab -l | sed "/le.sh cron/d" | crontab -
LE_WORKING_DIR="$(echo "$cr" | cut -d ' ' -f 6 | cut -d '=' -f 2 | tr -d '"')" LE_WORKING_DIR="$(echo "$cr" | cut -d ' ' -f 6 | cut -d '=' -f 2 | tr -d '"')"
_info LE_WORKING_DIR "$LE_WORKING_DIR" _info LE_WORKING_DIR "$LE_WORKING_DIR"
fi fi
_initpath _initpath
} }
# Detect profile file if not specified as environment variable # Detect profile file if not specified as environment variable
_detect_profile() { _detect_profile() {
if [ -n "$PROFILE" -a -f "$PROFILE" ]; then if [ -n "$PROFILE" -a -f "$PROFILE" ]; then
echo "$PROFILE" echo "$PROFILE"
return return
fi fi
local DETECTED_PROFILE local DETECTED_PROFILE
DETECTED_PROFILE='' DETECTED_PROFILE=''
local SHELLTYPE local SHELLTYPE
SHELLTYPE="$(basename "/$SHELL")" SHELLTYPE="$(basename "/$SHELL")"
if [ "$SHELLTYPE" = "bash" ]; then if [ "$SHELLTYPE" = "bash" ]; then
if [ -f "$HOME/.bashrc" ]; then if [ -f "$HOME/.bashrc" ]; then
DETECTED_PROFILE="$HOME/.bashrc" DETECTED_PROFILE="$HOME/.bashrc"
elif [ -f "$HOME/.bash_profile" ]; then elif [ -f "$HOME/.bash_profile" ]; then
DETECTED_PROFILE="$HOME/.bash_profile" DETECTED_PROFILE="$HOME/.bash_profile"
fi fi
elif [ "$SHELLTYPE" = "zsh" ]; then elif [ "$SHELLTYPE" = "zsh" ]; then
DETECTED_PROFILE="$HOME/.zshrc" DETECTED_PROFILE="$HOME/.zshrc"
fi fi
if [ -z "$DETECTED_PROFILE" ]; then if [ -z "$DETECTED_PROFILE" ]; then
if [ -f "$HOME/.profile" ]; then if [ -f "$HOME/.profile" ]; then
DETECTED_PROFILE="$HOME/.profile" DETECTED_PROFILE="$HOME/.profile"
elif [ -f "$HOME/.bashrc" ]; then elif [ -f "$HOME/.bashrc" ]; then
DETECTED_PROFILE="$HOME/.bashrc" DETECTED_PROFILE="$HOME/.bashrc"
elif [ -f "$HOME/.bash_profile" ]; then elif [ -f "$HOME/.bash_profile" ]; then
DETECTED_PROFILE="$HOME/.bash_profile" DETECTED_PROFILE="$HOME/.bash_profile"
elif [ -f "$HOME/.zshrc" ]; then elif [ -f "$HOME/.zshrc" ]; then
DETECTED_PROFILE="$HOME/.zshrc" DETECTED_PROFILE="$HOME/.zshrc"
fi fi
fi fi
if [ ! -z "$DETECTED_PROFILE" ]; then if [ ! -z "$DETECTED_PROFILE" ]; then
echo "$DETECTED_PROFILE" echo "$DETECTED_PROFILE"
fi fi
} }
_initconf() { _initconf() {
_initpath _initpath
if [ ! -f "$ACCOUNT_CONF_PATH" ] ; then if [ ! -f "$ACCOUNT_CONF_PATH" ] ; then
echo "#Account configurations: echo "#Account configurations:
#Here are the supported macros, uncomment them to make them take effect. #Here are the supported macros, uncomment them to make them take effect.
#ACCOUNT_EMAIL=aaa@aaa.com # the account email used to register account. #ACCOUNT_EMAIL=aaa@aaa.com # the account email used to register account.
#STAGE=1 # Use the staging api #STAGE=1 # Use the staging api
#FORCE=1 # Force to issue cert #FORCE=1 # Force to issue cert
#DEBUG=1 # Debug mode #DEBUG=1 # Debug mode
#dns api #dns api
####################### #######################
#Cloudflare: #Cloudflare:
#api key #api key
#CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" #CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
#account email #account email
#CF_Email="xxxx@sss.com" #CF_Email="xxxx@sss.com"
####################### #######################
#Dnspod.cn: #Dnspod.cn:
#api key id #api key id
#DP_Id="1234" #DP_Id="1234"
#api key #api key
#DP_Key="sADDsdasdgdsf" #DP_Key="sADDsdasdgdsf"
####################### #######################
#Cloudxns.com: #Cloudxns.com:
#CX_Key="1234" #CX_Key="1234"
# #
#CX_Secret="sADDsdasdgdsf" #CX_Secret="sADDsdasdgdsf"
" > $ACCOUNT_CONF_PATH " > $ACCOUNT_CONF_PATH
fi fi
} }
install() { install() {
if ! _initpath ; then if ! _initpath ; then
_err "Install failed." _err "Install failed."
return 1 return 1
fi fi
#check if there is sudo installed, AND if the current user is a sudoer. #check if there is sudo installed, AND if the current user is a sudoer.
if command -v sudo > /dev/null ; then if command -v sudo > /dev/null ; then
if [ "$(sudo -n uptime 2>&1|grep "load"|wc -l)" != "0" ] ; then if [ "$(sudo -n uptime 2>&1|grep "load"|wc -l)" != "0" ] ; then
SUDO=sudo SUDO=sudo
fi fi
fi fi
if command -v yum > /dev/null ; then if command -v yum > /dev/null ; then
YUM="1" YUM="1"
INSTALL="$SUDO yum install -y " INSTALL="$SUDO yum install -y "
elif command -v apt-get > /dev/null ; then elif command -v apt-get > /dev/null ; then
INSTALL="$SUDO apt-get install -y " INSTALL="$SUDO apt-get install -y "
fi fi
if ! command -v "curl" > /dev/null ; then if ! command -v "curl" > /dev/null ; then
_err "Please install curl first." _err "Please install curl first."
_err "$INSTALL curl" _err "$INSTALL curl"
return 1 return 1
fi fi
if ! command -v "crontab" > /dev/null ; then if ! command -v "crontab" > /dev/null ; then
_err "Please install crontab first." _err "Please install crontab first."
if [ "$YUM" ] ; then if [ "$YUM" ] ; then
_err "$INSTALL crontabs" _err "$INSTALL crontabs"
else else
_err "$INSTALL crontab" _err "$INSTALL crontab"
fi fi
return 1 return 1
fi fi
if ! command -v "openssl" > /dev/null ; then if ! command -v "openssl" > /dev/null ; then
_err "Please install openssl first." _err "Please install openssl first."
_err "$INSTALL openssl" _err "$INSTALL openssl"
return 1 return 1
fi fi
_info "Installing to $LE_WORKING_DIR" _info "Installing to $LE_WORKING_DIR"
cp le.sh "$LE_WORKING_DIR/" && chmod +x "$LE_WORKING_DIR/le.sh" cp le.sh "$LE_WORKING_DIR/" && chmod +x "$LE_WORKING_DIR/le.sh"
if [ "$?" != "0" ] ; then if [ "$?" != "0" ] ; then
_err "Install failed, can not copy le.sh" _err "Install failed, can not copy le.sh"
return 1 return 1
fi fi
_info "Installed to $LE_WORKING_DIR/le.sh" _info "Installed to $LE_WORKING_DIR/le.sh"
_profile="$(_detect_profile)" _profile="$(_detect_profile)"
if [ "$_profile" ] ; then if [ "$_profile" ] ; then
_debug "Found profile: $_profile" _debug "Found profile: $_profile"
echo "LE_WORKING_DIR=$LE_WORKING_DIR echo "LE_WORKING_DIR=$LE_WORKING_DIR
alias le=\"$LE_WORKING_DIR/le.sh\" alias le=\"$LE_WORKING_DIR/le.sh\"
alias le.sh=\"$LE_WORKING_DIR/le.sh\" alias le.sh=\"$LE_WORKING_DIR/le.sh\"
" > "$LE_WORKING_DIR/le.env" " > "$LE_WORKING_DIR/le.env"
_setopt "$_profile" "source \"$LE_WORKING_DIR/le.env\"" _setopt "$_profile" "source \"$LE_WORKING_DIR/le.env\""
_info "OK, Close and reopen your terminal to start using le" _info "OK, Close and reopen your terminal to start using le"
else else
_info "No profile is found, you will need to go into $LE_WORKING_DIR to use le.sh" _info "No profile is found, you will need to go into $LE_WORKING_DIR to use le.sh"
fi fi
mkdir -p $LE_WORKING_DIR/dnsapi mkdir -p $LE_WORKING_DIR/dnsapi
cp dnsapi/* $LE_WORKING_DIR/dnsapi/ cp dnsapi/* $LE_WORKING_DIR/dnsapi/
#to keep compatible mv the .acc file to .key file #to keep compatible mv the .acc file to .key file
if [ -f "$LE_WORKING_DIR/account.acc" ] ; then if [ -f "$LE_WORKING_DIR/account.acc" ] ; then
mv "$LE_WORKING_DIR/account.acc" "$LE_WORKING_DIR/account.key" mv "$LE_WORKING_DIR/account.acc" "$LE_WORKING_DIR/account.key"
fi fi
installcronjob installcronjob
if [ ! -f "$ACCOUNT_CONF_PATH" ] ; then if [ ! -f "$ACCOUNT_CONF_PATH" ] ; then
_initconf _initconf
fi fi
_info OK _info OK
} }
uninstall() { uninstall() {
uninstallcronjob uninstallcronjob
_initpath _initpath
_profile="$(_detect_profile)" _profile="$(_detect_profile)"
if [ "$_profile" ] ; then if [ "$_profile" ] ; then
sed -i /le.env/d "$_profile" sed -i /le.env/d "$_profile"
fi fi
rm -f $LE_WORKING_DIR/le.sh rm -f $LE_WORKING_DIR/le.sh
_info "The keys and certs are in $LE_WORKING_DIR, you can remove them by yourself." _info "The keys and certs are in $LE_WORKING_DIR, you can remove them by yourself."
} }
cron() { cron() {
renewAll renewAll
} }
version() { version() {
_info "$PROJECT" _info "$PROJECT"
_info "v$VER" _info "v$VER"
} }
showhelp() { showhelp() {
version version
echo "Usage: le.sh [command] ...[args].... echo "Usage: le.sh [command] ...[args]....
Avalible commands: Avalible commands:
install: install:
Install le.sh to your system. Install le.sh to your system.
issue: issue:
Issue a cert. Issue a cert.
installcert: installcert:
Install the issued cert to apache/nginx or any other server. Install the issued cert to apache/nginx or any other server.
renew: renew:
Renew a cert. Renew a cert.
renewAll: renewAll:
Renew all the certs. Renew all the certs.
uninstall: uninstall:
Uninstall le.sh, and uninstall the cron job. Uninstall le.sh, and uninstall the cron job.
version: version:
Show version info. Show version info.
installcronjob: installcronjob:
Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job. Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job.
uninstallcronjob: uninstallcronjob:
Uninstall the cron job. The 'uninstall' command can do this automatically. Uninstall the cron job. The 'uninstall' command can do this automatically.
createAccountKey: createAccountKey:
Create an account private key, professional use. Create an account private key, professional use.
createDomainKey: createDomainKey:
Create an domain private key, professional use. Create an domain private key, professional use.
createCSR: createCSR:
Create CSR , professional use. Create CSR , professional use.
" "
} }
if [ -z "$1" ] ; then if [ -z "$1" ] ; then
showhelp showhelp
else else
"$@" "$@"
fi fi
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment