mirror of
https://github.com/plantroon/acme.sh.git
synced 2024-12-22 21:21:42 +00:00
Merge remote-tracking branch 'upstream/master' into ssh-deploy
This commit is contained in:
commit
6093a4f9f8
10
Dockerfile
10
Dockerfile
@ -4,17 +4,17 @@ RUN apk update -f \
|
|||||||
&& apk --no-cache add -f \
|
&& apk --no-cache add -f \
|
||||||
openssl \
|
openssl \
|
||||||
curl \
|
curl \
|
||||||
netcat-openbsd
|
netcat-openbsd \
|
||||||
|
&& rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
ENV LE_CONFIG_HOME /acme.sh
|
ENV LE_CONFIG_HOME /acme.sh
|
||||||
|
|
||||||
ENV AUTO_UPGRADE 1
|
ENV AUTO_UPGRADE 1
|
||||||
|
|
||||||
#Install
|
#Install
|
||||||
RUN mkdir -p /install_acme.sh/
|
|
||||||
ADD ./ /install_acme.sh/
|
ADD ./ /install_acme.sh/
|
||||||
RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh)
|
RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/
|
||||||
RUN rm -rf /install_acme.sh/
|
|
||||||
|
|
||||||
RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh
|
RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh
|
||||||
|
|
||||||
@ -55,5 +55,7 @@ else \n \
|
|||||||
/root/.acme.sh/acme.sh --config-home /acme.sh \"\$@\"\n \
|
/root/.acme.sh/acme.sh --config-home /acme.sh \"\$@\"\n \
|
||||||
fi" >/entry.sh && chmod +x /entry.sh
|
fi" >/entry.sh && chmod +x /entry.sh
|
||||||
|
|
||||||
|
VOLUME /acme.sh
|
||||||
|
|
||||||
ENTRYPOINT ["/entry.sh"]
|
ENTRYPOINT ["/entry.sh"]
|
||||||
CMD ["--help"]
|
CMD ["--help"]
|
||||||
|
22
README.md
22
README.md
@ -1,4 +1,6 @@
|
|||||||
# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)
|
# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)
|
||||||
|
|
||||||
|
[![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
- An ACME protocol client written purely in Shell (Unix shell) language.
|
- An ACME protocol client written purely in Shell (Unix shell) language.
|
||||||
- Full ACME protocol implementation.
|
- Full ACME protocol implementation.
|
||||||
- Simple, powerful and very easy to use. You only need 3 minutes to learn it.
|
- Simple, powerful and very easy to use. You only need 3 minutes to learn it.
|
||||||
@ -8,6 +10,7 @@
|
|||||||
- Just one script to issue, renew and install your certificates automatically.
|
- Just one script to issue, renew and install your certificates automatically.
|
||||||
- DOES NOT require `root/sudoer` access.
|
- DOES NOT require `root/sudoer` access.
|
||||||
- Docker friendly
|
- Docker friendly
|
||||||
|
- IPv6 support
|
||||||
|
|
||||||
It's probably the `easiest & smartest` shell script to automatically issue & renew the free certificates from Let's Encrypt.
|
It's probably the `easiest & smartest` shell script to automatically issue & renew the free certificates from Let's Encrypt.
|
||||||
|
|
||||||
@ -304,17 +307,14 @@ You don't have to do anything manually!
|
|||||||
|
|
||||||
1. CloudFlare.com API
|
1. CloudFlare.com API
|
||||||
1. DNSPod.cn API
|
1. DNSPod.cn API
|
||||||
1. DNSimple API
|
|
||||||
1. CloudXNS.com API
|
1. CloudXNS.com API
|
||||||
1. GoDaddy.com API
|
1. GoDaddy.com API
|
||||||
1. OVH, kimsufi, soyoustart and runabove API
|
|
||||||
1. AWS Route 53
|
|
||||||
1. PowerDNS.com API
|
1. PowerDNS.com API
|
||||||
1. lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api
|
1. OVH, kimsufi, soyoustart and runabove API
|
||||||
(DigitalOcean, DNSimple, DNSMadeEasy, DNSPark, EasyDNS, Namesilo, NS1, PointHQ, Rage4 and Vultr etc.)
|
1. nsupdate API
|
||||||
1. LuaDNS.com API
|
1. LuaDNS.com API
|
||||||
1. DNSMadeEasy.com API
|
1. DNSMadeEasy.com API
|
||||||
1. nsupdate API
|
1. AWS Route 53
|
||||||
1. aliyun.com(阿里云) API
|
1. aliyun.com(阿里云) API
|
||||||
1. ISPConfig 3.1 API
|
1. ISPConfig 3.1 API
|
||||||
1. Alwaysdata.com API
|
1. Alwaysdata.com API
|
||||||
@ -329,8 +329,18 @@ You don't have to do anything manually!
|
|||||||
1. Infoblox NIOS API (https://www.infoblox.com/)
|
1. Infoblox NIOS API (https://www.infoblox.com/)
|
||||||
1. VSCALE (https://vscale.io/)
|
1. VSCALE (https://vscale.io/)
|
||||||
1. Dynu API (https://www.dynu.com)
|
1. Dynu API (https://www.dynu.com)
|
||||||
|
1. DNSimple API
|
||||||
|
1. NS1.com API
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
And:
|
||||||
|
|
||||||
|
1. lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api
|
||||||
|
(DigitalOcean, DNSimple, DNSMadeEasy, DNSPark, EasyDNS, Namesilo, NS1, PointHQ, Rage4 and Vultr etc.)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**More APIs coming soon...**
|
**More APIs coming soon...**
|
||||||
|
|
||||||
If your DNS provider is not on the supported list above, you can write your own DNS API script easily. If you do, please consider submitting a [Pull Request](https://github.com/Neilpang/acme.sh/pulls) and contribute it to the project.
|
If your DNS provider is not on the supported list above, you can write your own DNS API script easily. If you do, please consider submitting a [Pull Request](https://github.com/Neilpang/acme.sh/pulls) and contribute it to the project.
|
||||||
|
40
acme.sh
40
acme.sh
@ -444,19 +444,27 @@ if [ "$(printf '\x41')" != 'A' ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
_h2b() {
|
_h2b() {
|
||||||
|
if _exists xxd; then
|
||||||
|
xxd -r -p
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
hex=$(cat)
|
hex=$(cat)
|
||||||
i=1
|
i=1
|
||||||
j=2
|
j=2
|
||||||
|
_debug2 _URGLY_PRINTF "$_URGLY_PRINTF"
|
||||||
_debug3 _URGLY_PRINTF "$_URGLY_PRINTF"
|
if [ -z "$_URGLY_PRINTF" ]; then
|
||||||
while true; do
|
while true; do
|
||||||
if [ -z "$_URGLY_PRINTF" ]; then
|
|
||||||
h="$(printf "%s" "$hex" | cut -c $i-$j)"
|
h="$(printf "%s" "$hex" | cut -c $i-$j)"
|
||||||
if [ -z "$h" ]; then
|
if [ -z "$h" ]; then
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
printf "\x$h%s"
|
printf "\x$h%s"
|
||||||
else
|
i="$(_math "$i" + 2)"
|
||||||
|
j="$(_math "$j" + 2)"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
while true; do
|
||||||
ic="$(printf "%s" "$hex" | cut -c $i)"
|
ic="$(printf "%s" "$hex" | cut -c $i)"
|
||||||
jc="$(printf "%s" "$hex" | cut -c $j)"
|
jc="$(printf "%s" "$hex" | cut -c $j)"
|
||||||
if [ -z "$ic$jc" ]; then
|
if [ -z "$ic$jc" ]; then
|
||||||
@ -465,12 +473,11 @@ _h2b() {
|
|||||||
ic="$(_h_char_2_dec "$ic")"
|
ic="$(_h_char_2_dec "$ic")"
|
||||||
jc="$(_h_char_2_dec "$jc")"
|
jc="$(_h_char_2_dec "$jc")"
|
||||||
printf '\'"$(printf "%o" "$(_math "$ic" \* 16 + $jc)")""%s"
|
printf '\'"$(printf "%o" "$(_math "$ic" \* 16 + $jc)")""%s"
|
||||||
fi
|
i="$(_math "$i" + 2)"
|
||||||
|
j="$(_math "$j" + 2)"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
i="$(_math "$i" + 2)"
|
|
||||||
j="$(_math "$j" + 2)"
|
|
||||||
|
|
||||||
done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_is_solaris() {
|
_is_solaris() {
|
||||||
@ -1244,17 +1251,20 @@ createDomainKey() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
domain=$1
|
domain=$1
|
||||||
length=$2
|
_cdl=$2
|
||||||
|
|
||||||
if [ -z "$length" ]; then
|
if [ -z "$_cdl" ]; then
|
||||||
_debug "Use DEFAULT_DOMAIN_KEY_LENGTH=$DEFAULT_DOMAIN_KEY_LENGTH"
|
_debug "Use DEFAULT_DOMAIN_KEY_LENGTH=$DEFAULT_DOMAIN_KEY_LENGTH"
|
||||||
length="$DEFAULT_DOMAIN_KEY_LENGTH"
|
_cdl="$DEFAULT_DOMAIN_KEY_LENGTH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_initpath "$domain" "$length"
|
_initpath "$domain" "$_cdl"
|
||||||
|
|
||||||
if [ ! -f "$CERT_KEY_PATH" ] || ([ "$FORCE" ] && ! [ "$IS_RENEW" ]); then
|
if [ ! -f "$CERT_KEY_PATH" ] || ([ "$FORCE" ] && ! [ "$IS_RENEW" ]); then
|
||||||
_createkey "$length" "$CERT_KEY_PATH"
|
if _createkey "$_cdl" "$CERT_KEY_PATH"; then
|
||||||
|
_savedomainconf Le_Keylength "$_cdl"
|
||||||
|
_info "The domain key is here: $(__green $CERT_KEY_PATH)"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
if [ "$IS_RENEW" ]; then
|
if [ "$IS_RENEW" ]; then
|
||||||
_info "Domain key exists, skip"
|
_info "Domain key exists, skip"
|
||||||
|
@ -494,6 +494,17 @@ be reused when needed.
|
|||||||
If you have any issues with this integration please report them to
|
If you have any issues with this integration please report them to
|
||||||
https://github.com/pho3nixf1re/acme.sh/issues.
|
https://github.com/pho3nixf1re/acme.sh/issues.
|
||||||
|
|
||||||
|
## 26. Use NS1.com API
|
||||||
|
|
||||||
|
```
|
||||||
|
export NS1_Key="fdmlfsdklmfdkmqsdfk"
|
||||||
|
```
|
||||||
|
|
||||||
|
Ok, let's issue a cert now:
|
||||||
|
```
|
||||||
|
acme.sh --issue --dns dns_nsone -d example.com -d www.example.com
|
||||||
|
```
|
||||||
|
|
||||||
# Use custom API
|
# Use custom API
|
||||||
|
|
||||||
If your API is not supported yet, you can write your own DNS API.
|
If your API is not supported yet, you can write your own DNS API.
|
||||||
|
@ -106,7 +106,7 @@ _get_root() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if _contains "$response" "<Name>$h.</Name>"; then
|
if _contains "$response" "<Name>$h.</Name>"; then
|
||||||
hostedzone="$(echo "$response" | sed 's/<HostedZone>/#&/g' | tr '#' '\n' | _egrep_o "<HostedZone><Id>[^<]*<.Id><Name>$h.<.Name>.*<.HostedZone>")"
|
hostedzone="$(echo "$response" | sed 's/<HostedZone>/#&/g' | tr '#' '\n' | _egrep_o "<HostedZone><Id>[^<]*<.Id><Name>$h.<.Name>.*<PrivateZone>false<.PrivateZone>.*<.HostedZone>")"
|
||||||
_debug hostedzone "$hostedzone"
|
_debug hostedzone "$hostedzone"
|
||||||
if [ -z "$hostedzone" ]; then
|
if [ -z "$hostedzone" ]; then
|
||||||
_err "Error, can not get hostedzone."
|
_err "Error, can not get hostedzone."
|
||||||
|
@ -37,7 +37,7 @@ dns_gandi_livedns_add() {
|
|||||||
_debug sub_domain "$_sub_domain"
|
_debug sub_domain "$_sub_domain"
|
||||||
|
|
||||||
_gandi_livedns_rest PUT "domains/$_domain/records/$_sub_domain/TXT" "{\"rrset_ttl\": 300, \"rrset_values\":[\"$txtvalue\"]}" \
|
_gandi_livedns_rest PUT "domains/$_domain/records/$_sub_domain/TXT" "{\"rrset_ttl\": 300, \"rrset_values\":[\"$txtvalue\"]}" \
|
||||||
&& _contains "$response" '{"message": "Zone Record Created"}' \
|
&& _contains "$response" '{"message": "DNS Record Created"}' \
|
||||||
&& _info "Add $(__green "success")"
|
&& _info "Add $(__green "success")"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
158
dnsapi/dns_nsone.sh
Normal file
158
dnsapi/dns_nsone.sh
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# bug reports to dev@1e.ca
|
||||||
|
|
||||||
|
#
|
||||||
|
#NS1_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
|
||||||
|
#
|
||||||
|
|
||||||
|
NS1_Api="https://api.nsone.net/v1"
|
||||||
|
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
dns_nsone_add() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
if [ -z "$NS1_Key" ]; then
|
||||||
|
NS1_Key=""
|
||||||
|
_err "You didn't specify nsone dns api key yet."
|
||||||
|
_err "Please create you key and try again."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#save the api key and email to the account conf file.
|
||||||
|
_saveaccountconf NS1_Key "$NS1_Key"
|
||||||
|
|
||||||
|
_debug "First detect the root zone"
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
_err "invalid domain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug _sub_domain "$_sub_domain"
|
||||||
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
|
_debug "Getting txt records"
|
||||||
|
_nsone_rest GET "zones/${_domain}"
|
||||||
|
|
||||||
|
if ! _contains "$response" "\"records\":"; then
|
||||||
|
_err "Error"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
count=$(printf "%s\n" "$response" | _egrep_o "\"domain\":\"$fulldomain\",[^{]*\"type\":\"TXT\"" | wc -l | tr -d " ")
|
||||||
|
_debug count "$count"
|
||||||
|
if [ "$count" = "0" ]; then
|
||||||
|
_info "Adding record"
|
||||||
|
|
||||||
|
if _nsone_rest PUT "zones/$_domain/$fulldomain/TXT" "{\"answers\":[{\"answer\":[\"$txtvalue\"]}],\"type\":\"TXT\",\"domain\":\"$fulldomain\",\"zone\":\"$_domain\"}"; then
|
||||||
|
if _contains "$response" "$fulldomain"; then
|
||||||
|
_info "Added"
|
||||||
|
#todo: check if the record takes effect
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Add txt record error."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_err "Add txt record error."
|
||||||
|
else
|
||||||
|
_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"
|
||||||
|
|
||||||
|
_nsone_rest POST "zones/$_domain/$fulldomain/TXT" "{\"answers\": [{\"answer\": [\"$txtvalue\"]}],\"type\": \"TXT\",\"domain\":\"$fulldomain\",\"zone\": \"$_domain\"}"
|
||||||
|
if [ "$?" = "0" ] && _contains "$response" "$fulldomain"; then
|
||||||
|
_info "Updated!"
|
||||||
|
#todo: check if the record takes effect
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
_err "Update error"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#fulldomain
|
||||||
|
dns_nsone_rm() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
_debug "First detect the root zone"
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
_err "invalid domain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug _sub_domain "$_sub_domain"
|
||||||
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
|
_debug "Getting txt records"
|
||||||
|
_nsone_rest GET "zones/${_domain}/$fulldomain/TXT"
|
||||||
|
|
||||||
|
count=$(printf "%s\n" "$response" | _egrep_o "\"domain\":\"$fulldomain\",.*\"type\":\"TXT\"" | wc -l | tr -d " ")
|
||||||
|
_debug count "$count"
|
||||||
|
if [ "$count" = "0" ]; then
|
||||||
|
_info "Don't need to remove."
|
||||||
|
else
|
||||||
|
if ! _nsone_rest DELETE "zones/${_domain}/$fulldomain/TXT"; then
|
||||||
|
_err "Delete record error."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_contains "$response" ""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#################### Private functions below ##################################
|
||||||
|
#_acme-challenge.www.domain.com
|
||||||
|
#returns
|
||||||
|
# _sub_domain=_acme-challenge.www
|
||||||
|
# _domain=domain.com
|
||||||
|
# _domain_id=sdjkglgdfewsdfg
|
||||||
|
_get_root() {
|
||||||
|
domain=$1
|
||||||
|
i=2
|
||||||
|
p=1
|
||||||
|
if ! _nsone_rest GET "zones"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
while true; do
|
||||||
|
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||||
|
_debug h "$h"
|
||||||
|
if [ -z "$h" ]; then
|
||||||
|
#not valid
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if _contains "$response" "\"zone\":\"$h\""; then
|
||||||
|
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||||
|
_domain="$h"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
p=$i
|
||||||
|
i=$(_math "$i" + 1)
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_nsone_rest() {
|
||||||
|
m=$1
|
||||||
|
ep="$2"
|
||||||
|
data="$3"
|
||||||
|
_debug "$ep"
|
||||||
|
|
||||||
|
export _H1="Accept: application/json"
|
||||||
|
export _H2="X-NSONE-Key: $NS1_Key"
|
||||||
|
if [ "$m" != "GET" ]; then
|
||||||
|
_debug data "$data"
|
||||||
|
response="$(_post "$data" "$NS1_Api/$ep" "" "$m")"
|
||||||
|
else
|
||||||
|
response="$(_get "$NS1_Api/$ep")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$?" != "0" ]; then
|
||||||
|
_err "error $ep"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug2 response "$response"
|
||||||
|
return 0
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user