Browse Source

Merge pull request #1298 from Neilpang/dev

sync
pull/1348/head
neil 7 years ago
committed by GitHub
parent
commit
432037d20d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 22
      README.md
  2. 31
      acme.sh
  3. 2
      deploy/strongswan.sh
  4. 76
      dnsapi/dns_he.sh
  5. 4
      dnsapi/dns_lua.sh
  6. 6
      dnsapi/dns_nsone.sh
  7. 10
      dnsapi/dns_yandex.sh

22
README.md

@ -25,7 +25,7 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
# [中文说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E) # [中文说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E)
# Who are using **acme.sh**
# Who:
- [FreeBSD.org](https://blog.crashed.org/letsencrypt-in-freebsd-org/) - [FreeBSD.org](https://blog.crashed.org/letsencrypt-in-freebsd-org/)
- [ruby-china.org](https://ruby-china.org/topics/31983) - [ruby-china.org](https://ruby-china.org/topics/31983)
- [Proxmox](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x_and_newer)) - [Proxmox](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x_and_newer))
@ -74,7 +74,7 @@ https://github.com/Neilpang/acmetest
- Webroot mode - Webroot mode
- Standalone mode - Standalone mode
- Apache mode - Apache mode
- Nginx mode ( Beta )
- Nginx mode
- DNS mode - DNS mode
- [Stateless mode](https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode) - [Stateless mode](https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode)
@ -204,6 +204,8 @@ Install/copy the cert/key to the production Apache or Nginx path.
The cert will be renewed every **60** days by default (which is configurable). Once the cert is renewed, the Apache/Nginx service will be reloaded automatically by the command: `service apache2 force-reload` or `service nginx force-reload`. The cert will be renewed every **60** days by default (which is configurable). Once the cert is renewed, the Apache/Nginx service will be reloaded automatically by the command: `service apache2 force-reload` or `service nginx force-reload`.
**Please take care: The reloadcmd is very important. The cert can be automatically renewed, but, without a correct 'reloadcmd' the cert may not be flushed to your server(like nginx or apache), then your website will not be able to show renewwed cert in 60 days.**
# 4. Use Standalone server to issue cert # 4. Use Standalone server to issue cert
**(requires you to be root/sudoer or have permission to listen on port 80 (TCP))** **(requires you to be root/sudoer or have permission to listen on port 80 (TCP))**
@ -238,7 +240,7 @@ More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
If you are running a web server, Apache or Nginx, it is recommended to use the `Webroot mode`. If you are running a web server, Apache or Nginx, it is recommended to use the `Webroot mode`.
Particularly, if you are running an Apache server, you should use Apache mode instead. This mode doesn't write any files to your web root folder.
Particularly, if you are running an Apache server, you can use Apache mode instead. This mode doesn't write any files to your web root folder.
Just set string "apache" as the second argument and it will force use of apache plugin automatically. Just set string "apache" as the second argument and it will force use of apache plugin automatically.
@ -246,6 +248,10 @@ Just set string "apache" as the second argument and it will force use of apache
acme.sh --issue --apache -d example.com -d www.example.com -d cp.example.com acme.sh --issue --apache -d example.com -d www.example.com -d cp.example.com
``` ```
**This apache mode is only to issue the cert, it will not change your apache config files.
You will need to configure your website config files to use the cert by yourself.
We don't want to mess your apache server, don't worry.**
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
# 7. Use Nginx mode # 7. Use Nginx mode
@ -266,6 +272,10 @@ So, the config is not changed.
acme.sh --issue --nginx -d example.com -d www.example.com -d cp.example.com acme.sh --issue --nginx -d example.com -d www.example.com -d cp.example.com
``` ```
**This nginx mode is only to issue the cert, it will not change your nginx config files.
You will need to configure your website config files to use the cert by yourself.
We don't want to mess your nginx server, don't worry.**
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
# 8. Automatic DNS API integration # 8. Automatic DNS API integration
@ -332,7 +342,7 @@ For more details: [How to use DNS API](dnsapi)
# 9. Use DNS manual mode: # 9. Use DNS manual mode:
If your dns provider doesn't support any api access, you will have to add the txt record by your hand.
If your dns provider doesn't support any api access, you can add the txt record by your hand.
```bash ```bash
acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com
@ -370,7 +380,7 @@ Ok, it's done.
And we support them too! And we support them too!
Just set the `length` parameter with a prefix `ec-`.
Just set the `keylength` parameter with a prefix `ec-`.
For example: For example:
@ -386,7 +396,7 @@ acme.sh --issue -w /home/wwwroot/example.com -d example.com --keylength ec-256
acme.sh --issue -w /home/wwwroot/example.com -d example.com -d www.example.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 `keylength` parameter above.
Valid values are: Valid values are:

31
acme.sh

@ -1281,6 +1281,7 @@ _create_account_key() {
else else
#generate account key #generate account key
_createkey "$length" "$ACCOUNT_KEY_PATH" _createkey "$length" "$ACCOUNT_KEY_PATH"
chmod 600 "$ACCOUNT_KEY_PATH"
fi fi
} }
@ -1838,7 +1839,7 @@ _send_signed_request() {
_body="$response" _body="$response"
if [ "$needbase64" ]; then if [ "$needbase64" ]; then
_body="$(echo "$_body" | _dbase64)" _body="$(echo "$_body" | _dbase64)"
_debug2 _body "$_body"
_debug3 _body "$_body"
fi fi
if _contains "$_body" "JWS has invalid anti-replay nonce"; then if _contains "$_body" "JWS has invalid anti-replay nonce"; then
@ -2006,9 +2007,19 @@ _startserver() {
_NC="$_NC -6" _NC="$_NC -6"
fi fi
_debug "_NC" "$_NC"
#todo listen address
$_NC TCP-LISTEN:$Le_HTTPPort,crlf,reuseaddr,fork SYSTEM:"sleep 0.5; echo HTTP/1.1 200 OK; echo ; echo $content; echo;" &
if [ "$DEBUG" ] && [ "$DEBUG" -gt "1" ]; then
_NC="$_NC -d -d -v"
fi
SOCAT_OPTIONS=TCP-LISTEN:$Le_HTTPPort,crlf,reuseaddr,fork
#Adding bind to local-address
if [ "$ncaddr" ]; then
SOCAT_OPTIONS="$SOCAT_OPTIONS,bind=${ncaddr}"
fi
_debug "_NC" "$_NC $SOCAT_OPTIONS"
$_NC $SOCAT_OPTIONS SYSTEM:"sleep 1; echo HTTP/1.0 200 OK; echo ; echo $content; echo;" &
serverproc="$!" serverproc="$!"
} }
@ -5062,7 +5073,7 @@ _installalias() {
} }
# nocron confighome
# nocron confighome noprofile
install() { install() {
if [ -z "$LE_WORKING_DIR" ]; then if [ -z "$LE_WORKING_DIR" ]; then
@ -5071,6 +5082,7 @@ install() {
_nocron="$1" _nocron="$1"
_c_home="$2" _c_home="$2"
_noprofile="$3"
if ! _initpath; then if ! _initpath; then
_err "Install failed." _err "Install failed."
return 1 return 1
@ -5136,7 +5148,7 @@ install() {
_info "Installed to $LE_WORKING_DIR/$PROJECT_ENTRY" _info "Installed to $LE_WORKING_DIR/$PROJECT_ENTRY"
if [ "$IN_CRON" != "1" ]; then
if [ "$IN_CRON" != "1" ] && [ -z "$_noprofile" ]; then
_installalias "$_c_home" _installalias "$_c_home"
fi fi
@ -5362,10 +5374,11 @@ Parameters:
" "
} }
# nocron
# nocron noprofile
_installOnline() { _installOnline() {
_info "Installing from online archive." _info "Installing from online archive."
_nocron="$1" _nocron="$1"
_noprofile="$2"
if [ ! "$BRANCH" ]; then if [ ! "$BRANCH" ]; then
BRANCH="master" BRANCH="master"
fi fi
@ -5386,7 +5399,7 @@ _installOnline() {
cd "$PROJECT_NAME-$BRANCH" cd "$PROJECT_NAME-$BRANCH"
chmod +x $PROJECT_ENTRY chmod +x $PROJECT_ENTRY
if ./$PROJECT_ENTRY install "$_nocron"; then
if ./$PROJECT_ENTRY install "$_nocron" "" "$_noprofile"; then
_info "Install success!" _info "Install success!"
fi fi
@ -5402,7 +5415,7 @@ upgrade() {
_initpath _initpath
export LE_WORKING_DIR export LE_WORKING_DIR
cd "$LE_WORKING_DIR" cd "$LE_WORKING_DIR"
_installOnline "nocron"
_installOnline "nocron" "noprofile"
); then ); then
_info "Upgrade success!" _info "Upgrade success!"
exit 0 exit 0

2
deploy/strongswan.sh

@ -22,6 +22,8 @@ strongswan_deploy() {
_ipsec=/usr/sbin/ipsec _ipsec=/usr/sbin/ipsec
elif [ -x /usr/sbin/strongswan ]; then elif [ -x /usr/sbin/strongswan ]; then
_ipsec=/usr/sbin/strongswan _ipsec=/usr/sbin/strongswan
elif [ -x /usr/local/sbin/ipsec ]; then
_ipsec=/usr/local/sbin/ipsec
else else
_err "no strongswan or ipsec command is detected" _err "no strongswan or ipsec command is detected"
return 1 return 1

76
dnsapi/dns_he.sh

@ -75,17 +75,19 @@ dns_he_rm() {
body="$body&hosted_dns_zoneid=$_zone_id" body="$body&hosted_dns_zoneid=$_zone_id"
body="$body&menu=edit_zone" body="$body&menu=edit_zone"
body="$body&hosted_dns_editzone=" body="$body&hosted_dns_editzone="
domain_regex="$(echo "$_full_domain" | sed 's/\./\\./g')" # escape dots
_record_id=$(_post "$body" "https://dns.he.net/" \
| tr -d '\n' \
| _egrep_o "data=\"&quot;${_txt_value}&quot;([^>]+>){6}[^<]+<[^;]+;deleteRecord\('[0-9]+','${domain_regex}','TXT'\)" \
| _egrep_o "[0-9]+','${domain_regex}','TXT'\)$" \
| _egrep_o "^[0-9]+"
)
# The series of egreps above could have been done a bit shorter but
# I wanted to double-check whether it's the correct record (in case
# HE changes their website somehow).
response="$(_post "$body" "https://dns.he.net/")"
_debug2 "response" "$response"
if ! _contains "$response" "$_txt_value"; then
_debug "The txt record is not found, just skip"
return 0
fi
_record_id="$(echo "$response" | tr -d "#" | sed "s/<tr/#<tr/g" | tr -d "\n" | tr "#" "\n" | grep "$_full_domain" | grep '"dns_tr"' | grep "$_txt_value" | cut -d '"' -f 4)"
_debug2 _record_id "$_record_id"
if [ -z "$_record_id" ]; then
_err "Can not find record id"
return 1
fi
# Remove the record # Remove the record
body="email=${HE_Username}&pass=${HE_Password}" body="email=${HE_Username}&pass=${HE_Password}"
body="$body&menu=edit_zone" body="$body&menu=edit_zone"
@ -108,41 +110,26 @@ dns_he_rm() {
########################## PRIVATE FUNCTIONS ########################### ########################## PRIVATE FUNCTIONS ###########################
#-- _find_zone() -------------------------------------------------------
# Returns the most specific zone found in administration interface.
#
# Example:
#
# _find_zone first.second.third.co.uk
#
# ... will return the first zone that exists in admin out of these:
# - "first.second.third.co.uk"
# - "second.third.co.uk"
# - "third.co.uk"
# - "co.uk" <-- unlikely
# - "uk" <-'
#
# (another approach would be something like this:
# https://github.com/hlandau/acme/blob/master/_doc/dns.hook
# - that's better if there are multiple pages. It's so much simpler.
# )
_find_zone() { _find_zone() {
_domain="$1" _domain="$1"
body="email=${HE_Username}&pass=${HE_Password}" body="email=${HE_Username}&pass=${HE_Password}"
_matches=$(_post "$body" "https://dns.he.net/" \
| _egrep_o "delete_dom.*name=\"[^\"]+\" value=\"[0-9]+"
)
response="$(_post "$body" "https://dns.he.net/")"
_debug2 response "$response"
_table="$(echo "$response" | tr -d "#" | sed "s/<table/#<table/g" | tr -d "\n" | tr "#" "\n" | grep 'id="domains_table"')"
_debug2 _table "$_table"
_matches="$(echo "$_table" | sed "s/<tr/#<tr/g" | tr "#" "\n" | grep 'alt="edit"' | tr -d " " | sed "s/<td/#<td/g" | tr "#" "\n" | sed -n 3p)"
_debug2 _matches "$_matches"
# Zone names and zone IDs are in same order # Zone names and zone IDs are in same order
_zone_ids=$(echo "$_matches" | cut -d '"' -f 5)
_zone_names=$(echo "$_matches" | cut -d '"' -f 3)
_zone_ids=$(echo "$_matches" | _egrep_o "hosted_dns_zoneid=[0-9]*&" | cut -d = -f 2 | tr -d '&')
_zone_names=$(echo "$_matches" | _egrep_o "name=.*onclick" | cut -d '"' -f 2)
_debug2 "These are the zones on this HE account:" _debug2 "These are the zones on this HE account:"
_debug2 "$_zone_names" _debug2 "$_zone_names"
_debug2 "And these are their respective IDs:" _debug2 "And these are their respective IDs:"
_debug2 "$_zone_ids" _debug2 "$_zone_ids"
if [ -z "$_zone_names" ] || [ -z "$_zone_ids" ]; then
_err "Can not get zone names."
return 1
fi
# Walk through all possible zone names # Walk through all possible zone names
_strip_counter=1 _strip_counter=1
while true; do while true; do
@ -156,17 +143,10 @@ _find_zone() {
_debug "Looking for zone \"${_attempted_zone}\"" _debug "Looking for zone \"${_attempted_zone}\""
# Take care of "." and only match whole lines. Note that grep -F
# cannot be used because there's no way to make it match whole
# lines.
regex="^$(echo "$_attempted_zone" | sed 's/\./\\./g')$"
line_num=$(echo "$_zone_names" \
| grep -n "$regex" \
| cut -d : -f 1
)
if [ -n "$line_num" ]; then
_zone_id=$(echo "$_zone_ids" | sed "${line_num}q;d")
line_num="$(echo "$_zone_names" | grep -n "$_attempted_zone" | cut -d : -f 1)"
if [ "$line_num" ]; then
_zone_id=$(echo "$_zone_ids" | sed -n "${line_num}p")
_debug "Found relevant zone \"$_attempted_zone\" with id \"$_zone_id\" - will be used for domain \"$_domain\"." _debug "Found relevant zone \"$_attempted_zone\" with id \"$_zone_id\" - will be used for domain \"$_domain\"."
return 0 return 0
fi fi

4
dnsapi/dns_lua.sh

@ -8,7 +8,6 @@
#LUA_Email="user@luadns.net" #LUA_Email="user@luadns.net"
LUA_Api="https://api.luadns.com/v1" LUA_Api="https://api.luadns.com/v1"
LUA_auth=$(printf "%s" "$LUA_Email:$LUA_Key" | _base64)
######## Public functions ##################### ######## Public functions #####################
@ -19,6 +18,8 @@ dns_lua_add() {
LUA_Key="${LUA_Key:-$(_readaccountconf_mutable LUA_Key)}" LUA_Key="${LUA_Key:-$(_readaccountconf_mutable LUA_Key)}"
LUA_Email="${LUA_Email:-$(_readaccountconf_mutable LUA_Email)}" LUA_Email="${LUA_Email:-$(_readaccountconf_mutable LUA_Email)}"
LUA_auth=$(printf "%s" "$LUA_Email:$LUA_Key" | _base64)
if [ -z "$LUA_Key" ] || [ -z "$LUA_Email" ]; then if [ -z "$LUA_Key" ] || [ -z "$LUA_Email" ]; then
LUA_Key="" LUA_Key=""
LUA_Email="" LUA_Email=""
@ -60,6 +61,7 @@ dns_lua_rm() {
LUA_Key="${LUA_Key:-$(_readaccountconf_mutable LUA_Key)}" LUA_Key="${LUA_Key:-$(_readaccountconf_mutable LUA_Key)}"
LUA_Email="${LUA_Email:-$(_readaccountconf_mutable LUA_Email)}" LUA_Email="${LUA_Email:-$(_readaccountconf_mutable LUA_Email)}"
LUA_auth=$(printf "%s" "$LUA_Email:$LUA_Key" | _base64)
_debug "First detect the root zone" _debug "First detect the root zone"
if ! _get_root "$fulldomain"; then if ! _get_root "$fulldomain"; then
_err "invalid domain" _err "invalid domain"

6
dnsapi/dns_nsone.sh

@ -59,10 +59,10 @@ dns_nsone_add() {
_err "Add txt record error." _err "Add txt record error."
else else
_info "Updating record" _info "Updating record"
record_id=$(printf "%s\n" "$response" | _egrep_o "\"domain\":\"$fulldomain.\",[^{]*\"type\":\"TXT\",\"id\":\"[^,]*\"" | _head_n 1 | cut -d: -f7 | cut -d, -f1)
_debug "record_id" "$record_id"
prev_txt=$(printf "%s\n" "$response" | _egrep_o "\"domain\":\"$fulldomain\",\"short_answers\":\[\"[^,]*\]" | _head_n 1 | cut -d: -f3 | cut -d, -f1)
_debug "prev_txt" "$prev_txt"
_nsone_rest POST "zones/$_domain/$fulldomain/TXT" "{\"answers\": [{\"answer\": [\"$txtvalue\"]}],\"type\": \"TXT\",\"domain\":\"$fulldomain\",\"zone\": \"$_domain\"}"
_nsone_rest POST "zones/$_domain/$fulldomain/TXT" "{\"answers\": [{\"answer\": [\"$txtvalue\"]},{\"answer\": $prev_txt}],\"type\": \"TXT\",\"domain\":\"$fulldomain\",\"zone\": \"$_domain\"}"
if [ "$?" = "0" ] && _contains "$response" "$fulldomain"; then if [ "$?" = "0" ] && _contains "$response" "$fulldomain"; then
_info "Updated!" _info "Updated!"
#todo: check if the record takes effect #todo: check if the record takes effect

10
dnsapi/dns_yandex.sh

@ -16,7 +16,7 @@ dns_yandex_add() {
_PDD_credentials || return 1 _PDD_credentials || return 1
export _H1="PddToken: $PDD_Token" export _H1="PddToken: $PDD_Token"
curDomain=$(_PDD_get_domain "$fulldomain")
_PDD_get_domain "$fulldomain"
_debug "Found suitable domain in pdd: $curDomain" _debug "Found suitable domain in pdd: $curDomain"
curData="domain=${curDomain}&type=TXT&subdomain=${curSubdomain}&ttl=360&content=${txtvalue}" curData="domain=${curDomain}&type=TXT&subdomain=${curSubdomain}&ttl=360&content=${txtvalue}"
curUri="https://pddimp.yandex.ru/api2/admin/dns/add" curUri="https://pddimp.yandex.ru/api2/admin/dns/add"
@ -33,7 +33,7 @@ dns_yandex_rm() {
record_id=$(pdd_get_record_id "${fulldomain}") record_id=$(pdd_get_record_id "${fulldomain}")
_debug "Result: $record_id" _debug "Result: $record_id"
curDomain=$(_PDD_get_domain "$fulldomain")
_PDD_get_domain "$fulldomain"
_debug "Found suitable domain in pdd: $curDomain" _debug "Found suitable domain in pdd: $curDomain"
curUri="https://pddimp.yandex.ru/api2/admin/dns/del" curUri="https://pddimp.yandex.ru/api2/admin/dns/del"
@ -72,8 +72,8 @@ _PDD_get_domain() {
if [ "$d" = "$__t" ]; then if [ "$d" = "$__t" ]; then
p=$(_math $k - 1) p=$(_math $k - 1)
curSubdomain="$(echo "$fulldomain" | cut -d . -f "1-$p")" curSubdomain="$(echo "$fulldomain" | cut -d . -f "1-$p")"
echo "$__t"
return
curDomain="$__t"
return 0
fi fi
done done
k=$(_math $k + 1) k=$(_math $k + 1)
@ -96,7 +96,7 @@ _PDD_credentials() {
pdd_get_record_id() { pdd_get_record_id() {
fulldomain="${1}" fulldomain="${1}"
curDomain=$(_PDD_get_domain "$fulldomain")
_PDD_get_domain "$fulldomain"
_debug "Found suitable domain in pdd: $curDomain" _debug "Found suitable domain in pdd: $curDomain"
curUri="https://pddimp.yandex.ru/api2/admin/dns/list?domain=${curDomain}" curUri="https://pddimp.yandex.ru/api2/admin/dns/list?domain=${curDomain}"

Loading…
Cancel
Save