Merge branch 'master' into deploy

This commit is contained in:
neilpang 2016-10-25 20:55:18 +08:00
commit e3b4a0213c
3 changed files with 121 additions and 43 deletions

View File

@ -112,23 +112,23 @@ root@v1:~# acme.sh -h
**Example 1:** Single domain. **Example 1:** Single domain.
```bash ```bash
acme.sh --issue -d aa.com -w /home/wwwroot/aa.com acme.sh --issue -d example.com -w /home/wwwroot/example.com
``` ```
**Example 2:** Multiple domains in the same cert. **Example 2:** Multiple domains in the same cert.
```bash ```bash
acme.sh --issue -d aa.com -d www.aa.com -d cp.aa.com -w /home/wwwroot/aa.com acme.sh --issue -d example.com -d www.example.com -d cp.example.com -w /home/wwwroot/example.com
``` ```
The parameter `/home/wwwroot/aa.com` is the web root folder. You **MUST** have `write access` to this folder. The parameter `/home/wwwroot/example.com` is the web root folder. You **MUST** have `write access` to this folder.
Second argument **"aa.com"** is the main domain you want to issue cert for. Second argument **"example.com"** is the main domain you want to issue cert for.
You must have at least a domain there. You must have at least a domain there.
You must point and bind all the domains to the same webroot dir: `/home/wwwroot/aa.com`. You must point and bind all the domains to the same webroot dir: `/home/wwwroot/example.com`.
Generate/issued certs will be placed in `~/.acme.sh/aa.com/` Generate/issued certs will be placed in `~/.acme.sh/example.com/`
The issued cert will be renewed every **60** days automatically. The issued cert will be renewed every **60** days automatically.
@ -140,7 +140,7 @@ More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
After you issue a cert, you probably want to install/copy the cert to your nginx/apache or other servers you may be using. After you issue a cert, you probably want to install/copy the cert to your nginx/apache or other servers you may be using.
```bash ```bash
acme.sh --installcert -d aa.com \ acme.sh --installcert -d example.com \
--certpath /path/to/certfile/in/apache/nginx \ --certpath /path/to/certfile/in/apache/nginx \
--keypath /path/to/keyfile/in/apache/nginx \ --keypath /path/to/keyfile/in/apache/nginx \
--capath /path/to/ca/certfile/apache/nginx \ --capath /path/to/ca/certfile/apache/nginx \
@ -161,7 +161,7 @@ The cert will be `renewed every **60** days by default` (which is configurable).
The tcp `80` port **MUST** be free to listen, otherwise you will be prompted to free the `80` port and try again. The tcp `80` port **MUST** be free to listen, otherwise you will be prompted to free the `80` port and try again.
```bash ```bash
acme.sh --issue --standalone -d aa.com -d www.aa.com -d cp.aa.com acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com
``` ```
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
@ -175,7 +175,7 @@ acme.sh supports `tls-sni-01` validation.
The tcp `443` port **MUST** be free to listen, otherwise you will be prompted to free the `443` port and try again. The tcp `443` port **MUST** be free to listen, otherwise you will be prompted to free the `443` port and try again.
```bash ```bash
acme.sh --issue --tls -d aa.com -d www.aa.com -d cp.aa.com acme.sh --issue --tls -d example.com -d www.example.com -d cp.example.com
``` ```
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
@ -191,7 +191,7 @@ Particularly, if you are running an apache server, you should use apache mode in
Just set string "apache" as the second argument, it will force use of apache plugin automatically. Just set string "apache" as the second argument, it will force use of apache plugin automatically.
``` ```
acme.sh --issue --apache -d aa.com -d www.aa.com -d user.aa.com acme.sh --issue --apache -d example.com -d www.example.com -d user.example.com
``` ```
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
@ -201,18 +201,18 @@ More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
Support the `dns-01` challenge. Support the `dns-01` challenge.
```bash ```bash
acme.sh --issue --dns -d aa.com -d www.aa.com -d user.aa.com acme.sh --issue --dns -d example.com -d www.example.com -d user.example.com
``` ```
You should get the output like below: You should get the output like below:
``` ```
Add the following txt record: Add the following txt record:
Domain:_acme-challenge.aa.com Domain:_acme-challenge.example.com
Txt value:9ihDbjYfTExAYeDs4DBUeuTo18KBzwvTEjUnSwd32-c Txt value:9ihDbjYfTExAYeDs4DBUeuTo18KBzwvTEjUnSwd32-c
Add the following txt record: Add the following txt record:
Domain:_acme-challenge.www.aa.com Domain:_acme-challenge.www.example.com
Txt value:9ihDbjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Txt value:9ihDbjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Please add those txt records to the domains. Waiting for the dns to take effect. Please add those txt records to the domains. Waiting for the dns to take effect.
@ -222,7 +222,7 @@ Please add those txt records to the domains. Waiting for the dns to take effect.
Then just rerun with `renew` argument: Then just rerun with `renew` argument:
```bash ```bash
acme.sh --renew -d aa.com acme.sh --renew -d example.com
``` ```
Ok, it's finished. Ok, it's finished.
@ -264,13 +264,13 @@ For example:
### Single domain ECC cerfiticate: ### Single domain ECC cerfiticate:
```bash ```bash
acme.sh --issue -w /home/wwwroot/aa.com -d aa.com --keylength ec-256 acme.sh --issue -w /home/wwwroot/example.com -d example.com --keylength ec-256
``` ```
SAN multi domain ECC certificate: SAN multi domain ECC certificate:
```bash ```bash
acme.sh --issue -w /home/wwwroot/aa.com -d aa.com -d www.aa.com --keylength ec-256 acme.sh --issue -w /home/wwwroot/example.com -d example.com -d www.example.com --keylength ec-256
``` ```
Please look at the last parameter above. Please look at the last parameter above.
@ -289,12 +289,12 @@ No, you don't need to renew the certs manually. All the certs will be renewed a
However, you can also force to renew any cert: However, you can also force to renew any cert:
``` ```
acme.sh --renew -d aa.com --force acme.sh --renew -d example.com --force
``` ```
or, for ECC cert: or, for ECC cert:
``` ```
acme.sh --renew -d aa.com --force --ecc acme.sh --renew -d example.com --force --ecc
``` ```
# 11. How to upgrade `acme.sh` # 11. How to upgrade `acme.sh`

112
acme.sh
View File

@ -1,6 +1,6 @@
#!/usr/bin/env sh #!/usr/bin/env sh
VER=2.6.0 VER=2.6.1
PROJECT_NAME="acme.sh" PROJECT_NAME="acme.sh"
@ -94,7 +94,7 @@ _printargs() {
_log() { _log() {
[ -z "$LOG_FILE" ] && return [ -z "$LOG_FILE" ] && return
_printargs "$@" >> "$LOG_FILE" _printargs "$@" >> $LOG_FILE
} }
_info() { _info() {
@ -483,6 +483,45 @@ _createkey() {
fi fi
} }
#domain
_is_idn() {
_is_idn_d="$1"
_debug2 _is_idn_d "$_is_idn_d"
_idn_temp=$(printf "%s" "$_is_idn_d" | tr -d "[0-9a-zA-Z.,-]")
_debug2 _idn_temp "$_idn_temp"
[ "$_idn_temp" ]
}
#aa.com
#aa.com,bb.com,cc.com
_idn() {
__idn_d="$1"
if ! _is_idn "$__idn_d" ; then
printf "%s" "$__idn_d"
return 0
fi
if _exists idn ; then
if _contains "$__idn_d" ',' ; then
_i_first="1"
for f in $(echo "$__idn_d" | tr ',' ' ') ; do
[ -z "$f" ] && continue
if [ -z "$_i_first" ] ; then
printf "%s" ","
else
_i_first=""
fi
idn "$f" | tr -d "\r\n"
done
else
idn "$__idn_d" | tr -d "\r\n"
fi
else
_err "Please install idn to process IDN names."
fi
}
#_createcsr cn san_list keyfile csrfile conf #_createcsr cn san_list keyfile csrfile conf
_createcsr() { _createcsr() {
_debug _createcsr _debug _createcsr
@ -503,6 +542,8 @@ _createcsr() {
#single domain #single domain
_info "Single domain" "$domain" _info "Single domain" "$domain"
else else
domainlist="$(_idn $domainlist)"
_debug2 domainlist "$domainlist"
if _contains "$domainlist" "," ; then if _contains "$domainlist" "," ; then
alt="DNS:$(echo $domainlist | sed "s/,/,DNS:/g")" alt="DNS:$(echo $domainlist | sed "s/,/,DNS:/g")"
else else
@ -516,7 +557,10 @@ _createcsr() {
_savedomainconf Le_OCSP_Stable "$Le_OCSP_Stable" _savedomainconf Le_OCSP_Stable "$Le_OCSP_Stable"
printf -- "\nbasicConstraints = CA:FALSE\n1.3.6.1.5.5.7.1.24=DER:30:03:02:01:05" >> "$csrconf" printf -- "\nbasicConstraints = CA:FALSE\n1.3.6.1.5.5.7.1.24=DER:30:03:02:01:05" >> "$csrconf"
fi fi
openssl req -new -sha256 -key "$csrkey" -subj "/CN=$domain" -config "$csrconf" -out "$csr"
_csr_cn="$(_idn "$domain")"
_debug2 _csr_cn "$_csr_cn"
openssl req -new -sha256 -key "$csrkey" -subj "/CN=$_csr_cn" -config "$csrconf" -out "$csr"
} }
#_signcsr key csr conf cert #_signcsr key csr conf cert
@ -1181,7 +1225,7 @@ _saveaccountconf() {
_sckey="$1" _sckey="$1"
_scvalue="$2" _scvalue="$2"
if [ "$ACCOUNT_CONF_PATH" ] ; then if [ "$ACCOUNT_CONF_PATH" ] ; then
_setopt "$ACCOUNT_CONF_PATH" "$_sckey" "=" "\"$_scvalue\"" _setopt "$ACCOUNT_CONF_PATH" "$_sckey" "=" "'$_scvalue'"
else else
_err "ACCOUNT_CONF_PATH is empty, can not save $_sckey=$_scvalue" _err "ACCOUNT_CONF_PATH is empty, can not save $_sckey=$_scvalue"
fi fi
@ -1232,14 +1276,29 @@ _startserver() {
_debug "_NC" "$_NC" _debug "_NC" "$_NC"
# while true ; do #for centos ncat
if _contains "$nchelp" "nmap.org" ; then
_debug "Using ncat: nmap.org"
if [ "$DEBUG" ] ; then if [ "$DEBUG" ] ; then
if ! printf "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC $Le_HTTPPort ; then if printf "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC $Le_HTTPPort ; then
printf "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC -p $Le_HTTPPort ; return
fi fi
else else
if ! printf "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC $Le_HTTPPort > /dev/null 2>&1; then if printf "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC $Le_HTTPPort > /dev/null 2>&1; then
printf "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC -p $Le_HTTPPort > /dev/null 2>&1 return
fi
fi
_err "ncat listen error."
fi
# while true ; do
if [ "$DEBUG" ] ; then
if ! printf "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC -p $Le_HTTPPort ; then
printf "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC $Le_HTTPPort ;
fi
else
if ! printf "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC -p $Le_HTTPPort > /dev/null 2>&1; then
printf "HTTP/1.1 200 OK\r\n\r\n$content" | $_NC $Le_HTTPPort > /dev/null 2>&1
fi fi
fi fi
if [ "$?" != "0" ] ; then if [ "$?" != "0" ] ; then
@ -2153,7 +2212,7 @@ issue() {
_info "Getting new-authz for domain" $d _info "Getting new-authz for domain" $d
if ! _send_signed_request "$API/acme/new-authz" "{\"resource\": \"new-authz\", \"identifier\": {\"type\": \"dns\", \"value\": \"$d\"}}" ; then if ! _send_signed_request "$API/acme/new-authz" "{\"resource\": \"new-authz\", \"identifier\": {\"type\": \"dns\", \"value\": \"$(_idn "$d")\"}}" ; then
_err "Can not get domain token." _err "Can not get domain token."
_clearup _clearup
_on_issue_err _on_issue_err
@ -3082,7 +3141,7 @@ _deactivate() {
do do
_info "Deactivate: $_d_domain" _info "Deactivate: $_d_domain"
_d_i="$(_math $_d_i + 1)" _d_i="$(_math $_d_i + 1)"
if ! _send_signed_request "$API/acme/new-authz" "{\"resource\": \"new-authz\", \"identifier\": {\"type\": \"dns\", \"value\": \"$_d_domain\"}}" ; then if ! _send_signed_request "$API/acme/new-authz" "{\"resource\": \"new-authz\", \"identifier\": {\"type\": \"dns\", \"value\": \"$(_idn "$_d_domain")\"}}" ; then
_err "Can not get domain token." _err "Can not get domain token."
return 1 return 1
fi fi
@ -3200,7 +3259,7 @@ _initconf() {
#Account configurations: #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@example.com # the account email used to register account.
#ACCOUNT_KEY_PATH=\"/path/to/account.key\" #ACCOUNT_KEY_PATH=\"/path/to/account.key\"
#CERT_HOME=\"/path/to/cert/home\" #CERT_HOME=\"/path/to/cert/home\"
@ -3324,6 +3383,7 @@ _installalias() {
_profile="$(_detect_profile)" _profile="$(_detect_profile)"
if [ "$_profile" ] ; then if [ "$_profile" ] ; then
_debug "Found profile: $_profile" _debug "Found profile: $_profile"
_info "Installing alias to '$_profile'"
_setopt "$_profile" ". \"$_envfile\"" _setopt "$_profile" ". \"$_envfile\""
_info "OK, Close and reopen your terminal to start using $PROJECT_NAME" _info "OK, Close and reopen your terminal to start using $PROJECT_NAME"
else else
@ -3335,6 +3395,7 @@ _installalias() {
_cshfile="$LE_WORKING_DIR/$PROJECT_ENTRY.csh" _cshfile="$LE_WORKING_DIR/$PROJECT_ENTRY.csh"
_csh_profile="$HOME/.cshrc" _csh_profile="$HOME/.cshrc"
if [ -f "$_csh_profile" ] ; then if [ -f "$_csh_profile" ] ; then
_info "Installing alias to '$_csh_profile'"
_setopt "$_cshfile" "setenv LE_WORKING_DIR" " " "\"$LE_WORKING_DIR\"" _setopt "$_cshfile" "setenv LE_WORKING_DIR" " " "\"$LE_WORKING_DIR\""
_setopt "$_cshfile" "alias $PROJECT_ENTRY" " " "\"$LE_WORKING_DIR/$PROJECT_ENTRY\"" _setopt "$_cshfile" "alias $PROJECT_ENTRY" " " "\"$LE_WORKING_DIR/$PROJECT_ENTRY\""
_setopt "$_csh_profile" "source \"$_cshfile\"" _setopt "$_csh_profile" "source \"$_cshfile\""
@ -3343,6 +3404,7 @@ _installalias() {
#for tcsh #for tcsh
_tcsh_profile="$HOME/.tcshrc" _tcsh_profile="$HOME/.tcshrc"
if [ -f "$_tcsh_profile" ] ; then if [ -f "$_tcsh_profile" ] ; then
_info "Installing alias to '$_tcsh_profile'"
_setopt "$_cshfile" "setenv LE_WORKING_DIR" " " "\"$LE_WORKING_DIR\"" _setopt "$_cshfile" "setenv LE_WORKING_DIR" " " "\"$LE_WORKING_DIR\""
_setopt "$_cshfile" "alias $PROJECT_ENTRY" " " "\"$LE_WORKING_DIR/$PROJECT_ENTRY\"" _setopt "$_cshfile" "alias $PROJECT_ENTRY" " " "\"$LE_WORKING_DIR/$PROJECT_ENTRY\""
_setopt "$_tcsh_profile" "source \"$_cshfile\"" _setopt "$_tcsh_profile" "source \"$_cshfile\""
@ -3463,27 +3525,37 @@ uninstall() {
fi fi
_initpath _initpath
_uninstallalias
rm -f $LE_WORKING_DIR/$PROJECT_ENTRY
_info "The keys and certs are in $LE_WORKING_DIR, you can remove them by yourself."
}
_uninstallalias() {
_initpath
_profile="$(_detect_profile)" _profile="$(_detect_profile)"
if [ "$_profile" ] ; then if [ "$_profile" ] ; then
_info "Uninstalling alias from: '$_profile'"
text="$(cat $_profile)" text="$(cat $_profile)"
echo "$text" | sed "s|^.*\"$LE_WORKING_DIR/$PROJECT_NAME.env\"$||" > "$_profile" echo "$text" | sed "s|^.*\"$LE_WORKING_DIR/$PROJECT_NAME.env\"$||" > "$_profile"
fi fi
_csh_profile="$HOME/.cshrc" _csh_profile="$HOME/.cshrc"
if [ -f "$_csh_profile" ] ; then if [ -f "$_csh_profile" ] ; then
_info "Uninstalling alias from: '$_csh_profile'"
text="$(cat $_csh_profile)" text="$(cat $_csh_profile)"
echo "$text" | sed "s|^.*\"$LE_WORKING_DIR/$PROJECT_NAME.csh\"$||" > "$_csh_profile" echo "$text" | sed "s|^.*\"$LE_WORKING_DIR/$PROJECT_NAME.csh\"$||" > "$_csh_profile"
fi fi
_tcsh_profile="$HOME/.tcshrc" _tcsh_profile="$HOME/.tcshrc"
if [ -f "$_tcsh_profile" ] ; then if [ -f "$_tcsh_profile" ] ; then
_info "Uninstalling alias from: '$_csh_profile'"
text="$(cat $_tcsh_profile)" text="$(cat $_tcsh_profile)"
echo "$text" | sed "s|^.*\"$LE_WORKING_DIR/$PROJECT_NAME.csh\"$||" > "$_tcsh_profile" echo "$text" | sed "s|^.*\"$LE_WORKING_DIR/$PROJECT_NAME.csh\"$||" > "$_tcsh_profile"
fi fi
rm -f $LE_WORKING_DIR/$PROJECT_ENTRY
_info "The keys and certs are in $LE_WORKING_DIR, you can remove them by yourself."
} }
cron() { cron() {
@ -3793,6 +3865,10 @@ _process() {
_err "'$_dvalue' is not a valid domain for parameter '$1'" _err "'$_dvalue' is not a valid domain for parameter '$1'"
return 1 return 1
fi fi
if _is_idn "$_dvalue" && ! _exists idn ; then
_err "It seems that $_dvalue is an IDN( Internationalized Domain Names), please install 'idn' command first."
return 1
fi
if [ -z "$_domain" ] ; then if [ -z "$_domain" ] ; then
_domain="$_dvalue" _domain="$_dvalue"
@ -4050,13 +4126,15 @@ _process() {
if [ "${_CMD}" != "install" ] ; then if [ "${_CMD}" != "install" ] ; then
__initHome __initHome
if [ "$_log" ] && [ -z "$_logfile" ] ; then if [ "$_log" ]; then
if [ -z "$_logfile" ] ; then
_logfile="$DEFAULT_LOG_FILE" _logfile="$DEFAULT_LOG_FILE"
fi fi
fi
if [ "$_logfile" ] ; then if [ "$_logfile" ] ; then
_saveaccountconf "LOG_FILE" "$_logfile" _saveaccountconf "LOG_FILE" "$_logfile"
fi
LOG_FILE="$_logfile" LOG_FILE="$_logfile"
fi
if [ "$_log_level" ] ; then if [ "$_log_level" ] ; then
_saveaccountconf "LOG_LEVEL" "$_log_level" _saveaccountconf "LOG_LEVEL" "$_log_level"

View File

@ -15,7 +15,7 @@ export CF_Email="xxxx@sss.com"
Ok, let's issue cert now: Ok, let's issue cert now:
``` ```
acme.sh --issue --dns dns_cf -d aa.com -d www.aa.com acme.sh --issue --dns dns_cf -d example.com -d www.example.com
``` ```
The `CF_Key` and `CF_Email` will be saved in `~/.acme.sh/account.conf`, when next time you use cloudflare api, it will reuse this key. The `CF_Key` and `CF_Email` will be saved in `~/.acme.sh/account.conf`, when next time you use cloudflare api, it will reuse this key.
@ -37,7 +37,7 @@ export DP_Key="sADDsdasdgdsf"
Ok, let's issue cert now: Ok, let's issue cert now:
``` ```
acme.sh --issue --dns dns_dp -d aa.com -d www.aa.com acme.sh --issue --dns dns_dp -d example.com -d www.example.com
``` ```
The `DP_Id` and `DP_Key` will be saved in `~/.acme.sh/account.conf`, when next time you use dnspod.cn api, it will reuse this key. The `DP_Id` and `DP_Key` will be saved in `~/.acme.sh/account.conf`, when next time you use dnspod.cn api, it will reuse this key.
@ -58,7 +58,7 @@ export CX_Secret="sADDsdasdgdsf"
Ok, let's issue cert now: Ok, let's issue cert now:
``` ```
acme.sh --issue --dns dns_cx -d aa.com -d www.aa.com acme.sh --issue --dns dns_cx -d example.com -d www.example.com
``` ```
The `CX_Key` and `CX_Secret` will be saved in `~/.acme.sh/account.conf`, when next time you use Cloudxns.com api, it will reuse this key. The `CX_Key` and `CX_Secret` will be saved in `~/.acme.sh/account.conf`, when next time you use Cloudxns.com api, it will reuse this key.
@ -84,7 +84,7 @@ export GD_Secret="asdfsdafdsfdsfdsfdsfdsafd"
Ok, let's issue cert now: Ok, let's issue cert now:
``` ```
acme.sh --issue --dns dns_gd -d aa.com -d www.aa.com acme.sh --issue --dns dns_gd -d example.com -d www.example.com
``` ```
The `GD_Key` and `GD_Secret` will be saved in `~/.acme.sh/account.conf`, when next time you use cloudflare api, it will reuse this key. The `GD_Key` and `GD_Secret` will be saved in `~/.acme.sh/account.conf`, when next time you use cloudflare api, it will reuse this key.
@ -107,7 +107,7 @@ export PDNS_Ttl=60
Ok, let's issue cert now: Ok, let's issue cert now:
``` ```
acme.sh --issue --dns dns_pdns -d aa.com -d www.aa.com acme.sh --issue --dns dns_pdns -d example.com -d www.example.com
``` ```
The `PDNS_Url`, `PDNS_ServerId`, `PDNS_Token` and `PDNS_Ttl` will be saved in `~/.acme.sh/account.conf`. The `PDNS_Url`, `PDNS_ServerId`, `PDNS_Token` and `PDNS_Ttl` will be saved in `~/.acme.sh/account.conf`.
@ -127,7 +127,7 @@ Let's assume you want to name it 'myapi',
3. Then you can use your api to issue cert like: 3. Then you can use your api to issue cert like:
``` ```
acme.sh --issue --dns dns_myapi -d aa.com -d www.aa.com acme.sh --issue --dns dns_myapi -d example.com -d www.example.com
``` ```
For more details, please check our sample script: [dns_myapi.sh](dns_myapi.sh) For more details, please check our sample script: [dns_myapi.sh](dns_myapi.sh)