Compare commits

...
165 Commits
16 changed files with 3159 additions and 1615 deletions
+25
View File
@@ -0,0 +1,25 @@
<!--
If it is a bug report:
- make sure you are able to repro it on the latest released version.
You can install the latest version by: `acme.sh --upgrade`
- Search the existing issues.
- Refer to the [WIKI](https://wiki.acme.sh).
- Debug info [Debug](https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh).
-->
Steps to reproduce
------------------
Debug log
-----------------
```
acme.sh --issue ..... --debug 2
```
+11
View File
@@ -0,0 +1,11 @@
language: bash
env:
global:
- SHFMT_URL=https://github.com/mvdan/sh/releases/download/v0.4.0/shfmt_v0.4.0_linux_amd64
script:
- curl -sSL $SHFMT_URL -o ~/shfmt
- chmod +x ~/shfmt
- ~/shfmt -l -w -i 2 .
- git diff --exit-code || (echo "Run shfmt to fix the formatting issues" && false)
+59 -33
View File
@@ -1,4 +1,4 @@
# An ACME Shell script: 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)
- An ACME protocol client written purely in Shell (Unix shell) language.
- Fully ACME protocol implementation.
- Simple, powerful and very easy to use. You only need 3 minutes to learn.
@@ -13,6 +13,8 @@ It's probably the `easiest&smallest&smartest` shell script to automatically issu
Wiki: https://github.com/Neilpang/acme.sh/wiki
# [中文说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E)
#Tested OS
| NO | Status| Platform|
|----|-------|---------|
@@ -34,6 +36,7 @@ Wiki: https://github.com/Neilpang/acme.sh/wiki
|16|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/mageia.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Mageia
|17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/Neilpang/acme.sh/wiki/How-to-run-on-OpenWRT)
|18|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/solaris.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|SunOS/Solaris
|19|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/gentoo-stage3-amd64.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Gentoo Linux
For all build statuses, check our [daily build project](https://github.com/Neilpang/acmetest):
@@ -110,47 +113,56 @@ root@v1:~# acme.sh -h
**Example 1:** Single domain.
```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.
```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 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 80 days automatically.
The issued cert will be renewed every **60** days automatically.
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
# 3. Install issued cert to apache/nginx etc.
# 3. Install the issued cert to apache/nginx etc.
After you issue a cert, you probably want to install the cert with 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 **MUST** use this command to copy the certs to the target files, **Do NOT** use the certs files in **.acme.sh/** folder, they are for internal use only, the folder structure may change in future.
**nginx** example
```bash
acme.sh --installcert -d aa.com \
--certpath /path/to/certfile/in/apache/nginx \
--keypath /path/to/keyfile/in/apache/nginx \
--capath /path/to/ca/certfile/apache/nginx \
--fullchainpath path/to/fullchain/certfile/apache/nginx \
--reloadcmd "service apache2|nginx reload"
acme.sh --installcert -d example.com \
--keypath /path/to/keyfile/in/nginx/key.pem \
--fullchainpath path/to/fullchain/nginx/cert.pem \
--reloadcmd "service nginx restart"
```
**apache** example
```bash
acme.sh --installcert -d example.com \
--certpath /path/to/certfile/in/apache/cert.pem \
--keypath /path/to/keyfile/in/apache/key.pem \
--fullchainpath path/to/fullchain/certfile/apache/fullchain.pem \
--reloadcmd "service apache2 restart"
```
Only the domain is required, all the other parameters are optional.
Install the issued cert/key to the production apache or nginx path.
Install/copy the issued cert/key to the production apache or nginx path.
The cert will be `renewed every 80 days by default` (which is configurable). Once the cert is renewed, the apache/nginx will be automatically reloaded by the command: `service apache2 reload` or `service nginx reload`.
The cert will be `renewed every **60** days by default` (which is configurable). Once the cert is renewed, the apache/nginx will be automatically reloaded by the command: `service apache2 reload` or `service nginx reload`.
# 4. Use Standalone server to issue cert
@@ -159,7 +171,7 @@ The cert will be `renewed every 80 days by default` (which is configurable). Onc
The tcp `80` port **MUST** be free to listen, otherwise you will be prompted to free the `80` port and try again.
```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
@@ -173,7 +185,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.
```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
@@ -189,7 +201,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.
```
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
@@ -199,18 +211,18 @@ More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
Support the `dns-01` challenge.
```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:
```
Add the following txt record:
Domain:_acme-challenge.aa.com
Domain:_acme-challenge.example.com
Txt value:9ihDbjYfTExAYeDs4DBUeuTo18KBzwvTEjUnSwd32-c
Add the following txt record:
Domain:_acme-challenge.www.aa.com
Domain:_acme-challenge.www.example.com
Txt value:9ihDbjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Please add those txt records to the domains. Waiting for the dns to take effect.
@@ -220,7 +232,7 @@ Please add those txt records to the domains. Waiting for the dns to take effect.
Then just rerun with `renew` argument:
```bash
acme.sh --renew -d aa.com
acme.sh --renew -d example.com
```
Ok, it's finished.
@@ -239,8 +251,11 @@ You don't have do anything manually!
4. Godaddy.com API
5. OVH, kimsufi, soyoustart and runabove API
6. AWS Route 53, see: https://github.com/Neilpang/acme.sh/issues/65
7. lexicon dns api: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api
7. PowerDNS API
8. 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.)
9. LuaDNS.com API
10. DNSMadeEasy.com API
##### More APIs are coming soon...
@@ -261,13 +276,13 @@ For example:
### Single domain ECC cerfiticate:
```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:
```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.
@@ -281,17 +296,17 @@ Valid values are:
# 10. How to renew the cert
No, you don't need to renew the certs manually. All the certs will be renewed automatically every 80 days.
No, you don't need to renew the certs manually. All the certs will be renewed automatically every **60** days.
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:
```
acme.sh --renew -d aa.com --force --ecc
acme.sh --renew -d example.com --force --ecc
```
# 11. How to upgrade `acme.sh`
@@ -302,7 +317,18 @@ You can update acme.sh to the latest code:
acme.sh --upgrade
```
# 12. Issue a cert from existing CSR
You can enable auto upgrade:
```
acme.sh --upgrade --auto-upgrade
```
Then **acme.sh** will keep up to date automatically.
Disable auto upgrade:
```
acme.sh --upgrade --auto-upgrade 0
```
# 12. Issue a cert from an existing CSR
https://github.com/Neilpang/acme.sh/wiki/Issue-a-cert-from-existing-CSR
@@ -318,7 +344,7 @@ TODO:
2. ACME protocol: https://github.com/ietf-wg-acme/acme
3. Certbot: https://github.com/certbot/certbot
# License & Other
# License & Others
License is GPLv3
+2262 -1273
View File
File diff suppressed because it is too large Load Diff
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env sh
#Here is a sample custom api script.
#This file name is "myapi.sh"
#So, here must be a method myapi_deploy()
#Which will be called by acme.sh to deploy the cert
#returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
myapi_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
_err "Not implemented yet"
return 1
}
+66 -8
View File
@@ -15,7 +15,7 @@ export CF_Email="xxxx@sss.com"
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.
@@ -37,7 +37,7 @@ export DP_Key="sADDsdasdgdsf"
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.
@@ -58,7 +58,7 @@ export CX_Secret="sADDsdasdgdsf"
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.
@@ -66,7 +66,7 @@ The `CX_Key` and `CX_Secret` will be saved in `~/.acme.sh/account.conf`, when n
## Use Godaddy.com domain api to automatically issue cert
We support Godaddy integeration.
We support Godaddy integration.
First you need to login to your Godaddy account to get your api key and api secret.
@@ -84,11 +84,34 @@ export GD_Secret="asdfsdafdsfdsfdsfdsfdsafd"
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.
## Use PowerDNS embedded api to automatically issue cert
We support PowerDNS embedded API integration.
First you need to enable api and set your api-token in PowerDNS configuration.
https://doc.powerdns.com/md/httpapi/README/
```
export PDNS_Url="http://ns.example.com:8081"
export PDNS_ServerId="localhost"
export PDNS_Token="0123456789ABCDEF"
export PDNS_Ttl=60
```
Ok, let's issue cert now:
```
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`.
## Use OVH/kimsufi/soyoustart/runabove API
https://github.com/Neilpang/acme.sh/wiki/How-to-use-OVH-domain-api
@@ -104,15 +127,50 @@ Let's assume you want to name it 'myapi',
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)
# Use lexicon dns api
https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api
## Use LuaDNS domain API
Get your API token at https://api.luadns.com/settings
```
export LUA_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export LUA_Email="xxxx@sss.com"
```
To issue a cert:
```
acme.sh --issue --dns dns_lua --dnssleep 3 -d example.com -d www.example.com
```
The `LUA_Key` and `LUA_Email` will be saved in `~/.acme.sh/account.conf`, and will be reused when needed.
## Use DNSMadeEasy domain API
Get your API credentials at https://cp.dnsmadeeasy.com/account/info
```
export ME_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export ME_Secret="qdfqsdfkjdskfj"
```
To issue a cert:
```
acme.sh --issue --dns dns_me --dnssleep 3 -d example.com -d www.example.com
```
The `ME_Key` and `ME_Secret` will be saved in `~/.acme.sh/account.conf`, and will be reused when needed.
+37 -39
View File
@@ -1,54 +1,52 @@
#!/usr/bin/env sh
#
#CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
#CF_Email="xxxx@sss.com"
CF_Api="https://api.cloudflare.com/client/v4"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_cf_add(){
dns_cf_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ] ; then
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
_err "You don't specify cloudflare api key and email yet."
_err "Please create you key and try again."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf CF_Key "$CF_Key"
_saveaccountconf CF_Email "$CF_Email"
_debug "First detect the root zone"
if ! _get_root $fulldomain ; then
if ! _get_root $fulldomain; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain"
if ! printf "$response" | grep \"success\":true > /dev/null ; then
if ! printf "$response" | grep \"success\":true >/dev/null; then
_err "Error"
return 1
fi
count=$(printf "%s\n" "$response" | _egrep_o \"count\":[^,]* | cut -d : -f 2)
_debug count "$count"
if [ "$count" = "0" ] ; then
if [ "$count" = "0" ]; then
_info "Adding record"
if _cf_rest POST "zones/$_domain_id/dns_records" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
if printf $response | grep $fulldomain > /dev/null ; then
if _cf_rest POST "zones/$_domain_id/dns_records" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
if printf -- "%s" "$response" | grep $fulldomain >/dev/null; then
_info "Added, sleeping 10 seconds"
sleep 10
#todo: check if the record takes effect
@@ -61,25 +59,27 @@ dns_cf_add(){
_err "Add txt record error."
else
_info "Updating record"
record_id=$(printf "%s\n" "$response" | _egrep_o \"id\":\"[^\"]*\" | cut -d : -f 2 | tr -d \"| head -1)
record_id=$(printf "%s\n" "$response" | _egrep_o \"id\":\"[^\"]*\" | cut -d : -f 2 | tr -d \" | head -n 1)
_debug "record_id" $record_id
_cf_rest PUT "zones/$_domain_id/dns_records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"zone_name\":\"$_domain\"}"
_cf_rest PUT "zones/$_domain_id/dns_records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"zone_name\":\"$_domain\"}"
if [ "$?" = "0" ]; then
_info "Updated, sleeping 10 seconds"
sleep 10
#todo: check if the record takes effect
return 0;
return 0
fi
_err "Update error"
return 1
fi
}
#fulldomain
dns_cf_rm() {
fulldomain=$1
}
#################### Private functions bellow ##################################
#_acme-challenge.www.domain.com
@@ -91,20 +91,20 @@ _get_root() {
domain=$1
i=2
p=1
while [ '1' ] ; do
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
if [ -z "$h" ] ; then
if [ -z "$h" ]; then
#not valid
return 1;
fi
if ! _cf_rest GET "zones?name=$h" ; then
return 1
fi
if printf $response | grep \"name\":\"$h\" >/dev/null ; then
_domain_id=$(printf "%s\n" "$response" | _egrep_o \"id\":\"[^\"]*\" | head -1 | cut -d : -f 2 | tr -d \")
if [ "$_domain_id" ] ; then
if ! _cf_rest GET "zones?name=$h"; then
return 1
fi
if printf $response | grep \"name\":\"$h\" >/dev/null; then
_domain_id=$(printf "%s\n" "$response" | _egrep_o \"id\":\"[^\"]*\" | head -n 1 | cut -d : -f 2 | tr -d \")
if [ "$_domain_id" ]; then
_sub_domain=$(printf $domain | cut -d . -f 1-$p)
_domain=$h
return 0
@@ -122,24 +122,22 @@ _cf_rest() {
ep="$2"
data="$3"
_debug $ep
_H1="X-Auth-Email: $CF_Email"
_H2="X-Auth-Key: $CF_Key"
_H3="Content-Type: application/json"
if [ "$data" ] ; then
if [ "$data" ]; then
_debug data "$data"
response="$(_post "$data" "$CF_Api/$ep" "" $m)"
else
response="$(_get "$CF_Api/$ep")"
fi
if [ "$?" != "0" ] ; then
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}
+51 -54
View File
@@ -6,10 +6,8 @@
#
#CX_Secret="sADDsdasdgdsf"
CX_Api="https://www.cloudxns.net/api2"
#REST_API
######## Public functions #####################
@@ -17,45 +15,50 @@ CX_Api="https://www.cloudxns.net/api2"
dns_cx_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$CX_Key" ] || [ -z "$CX_Secret" ] ; then
if [ -z "$CX_Key" ] || [ -z "$CX_Secret" ]; then
_err "You don't specify cloudxns.com api key or secret yet."
_err "Please create you key and try again."
return 1
fi
REST_API=$CX_Api
#save the api key and email to the account conf file.
_saveaccountconf CX_Key "$CX_Key"
_saveaccountconf CX_Secret "$CX_Secret"
_debug "First detect the root zone"
if ! _get_root $fulldomain ; then
if ! _get_root $fulldomain; then
_err "invalid domain"
return 1
fi
existing_records $_domain $_sub_domain
existing_records $_domain $_sub_domain
_debug count "$count"
if [ "$?" != "0" ] ; then
if [ "$?" != "0" ]; then
_err "Error get existing records."
return 1
fi
if [ "$count" = "0" ] ; then
if [ "$count" = "0" ]; then
add_record $_domain $_sub_domain $txtvalue
else
update_record $_domain $_sub_domain $txtvalue
fi
if [ "$?" = "0" ] ; then
if [ "$?" = "0" ]; then
return 0
fi
return 1
}
#fulldomain
dns_cx_rm() {
fulldomain=$1
}
#usage: root sub
#return if the sub record already exists.
#echos the existing records count.
@@ -64,24 +67,24 @@ existing_records() {
_debug "Getting txt records"
root=$1
sub=$2
if ! _rest GET "record/$_domain_id?:domain_id?host_id=0&offset=0&row_num=100" ; then
if ! _rest GET "record/$_domain_id?:domain_id?host_id=0&offset=0&row_num=100"; then
return 1
fi
count=0
seg=$(printf "%s\n" "$response" | _egrep_o "{[^{]*host\":\"$_sub_domain\"[^}]*}")
seg=$(printf "%s\n" "$response" | _egrep_o "{[^\{]*host\":\"$_sub_domain\"[^\}]*\}")
_debug seg "$seg"
if [ -z "$seg" ] ; then
if [ -z "$seg" ]; then
return 0
fi
if printf "$response" | grep '"type":"TXT"' > /dev/null ; then
if printf "$response" | grep '"type":"TXT"' >/dev/null; then
count=1
record_id=$(printf "%s\n" "$seg" | _egrep_o \"record_id\":\"[^\"]*\" | cut -d : -f 2 | tr -d \")
_debug record_id "$record_id"
return 0
return 0
fi
}
#add the txt record.
@@ -91,13 +94,13 @@ add_record() {
sub=$2
txtvalue=$3
fulldomain=$sub.$root
_info "Adding record"
if ! _rest POST "record" "{\"domain_id\": $_domain_id, \"host\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"type\":\"TXT\",\"ttl\":600, \"line_id\":1}"; then
return 1
fi
return 0
}
@@ -108,19 +111,16 @@ update_record() {
sub=$2
txtvalue=$3
fulldomain=$sub.$root
_info "Updating record"
if _rest PUT "record/$record_id" "{\"domain_id\": $_domain_id, \"host\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"type\":\"TXT\",\"ttl\":600, \"line_id\":1}" ; then
if _rest PUT "record/$record_id" "{\"domain_id\": $_domain_id, \"host\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"type\":\"TXT\",\"ttl\":600, \"line_id\":1}"; then
return 0
fi
return 1
}
#################### Private functions bellow ##################################
#_acme-challenge.www.domain.com
#returns
@@ -131,25 +131,25 @@ _get_root() {
domain=$1
i=2
p=1
if ! _rest GET "domain" ; then
if ! _rest GET "domain"; then
return 1
fi
while [ '1' ] ; do
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ] ; then
if [ -z "$h" ]; then
#not valid
return 1;
return 1
fi
if printf "$response" | grep "$h." >/dev/null ; then
seg=$(printf "%s" "$response" | _egrep_o "{[^{]*\"$h\.\"[^}]*\}" )
if printf "$response" | grep "$h." >/dev/null; then
seg=$(printf "%s" "$response" | _egrep_o "\{[^\{]*\"$h\.\"[^\}]*\}")
_debug seg "$seg"
_domain_id=$(printf "%s" "$seg" | _egrep_o \"id\":\"[^\"]*\" | cut -d : -f 2 | tr -d \")
_debug _domain_id "$_domain_id"
if [ "$_domain_id" ] ; then
if [ "$_domain_id" ]; then
_sub_domain=$(printf $domain | cut -d . -f 1-$p)
_debug _sub_domain $_sub_domain
_domain=$h
@@ -164,7 +164,6 @@ _get_root() {
return 1
}
#Usage: method URI data
_rest() {
m=$1
@@ -172,38 +171,36 @@ _rest() {
_debug $ep
url="$REST_API/$ep"
_debug url "$url"
cdate=$(date -u "+%Y-%m-%d %H:%M:%S UTC")
cdate=$(date -u "+%Y-%m-%d %H:%M:%S UTC")
_debug cdate "$cdate"
data="$3"
_debug data "$data"
sec="$CX_Key$url$data$cdate$CX_Secret"
_debug sec "$sec"
hmac=$(printf "$sec"| openssl md5 |cut -d " " -f 2)
hmac=$(printf "$sec" | openssl md5 | cut -d " " -f 2)
_debug hmac "$hmac"
_H1="API-KEY: $CX_Key"
_H2="API-REQUEST-DATE: $cdate"
_H3="API-HMAC: $hmac"
_H4="Content-Type: application/json"
if [ "$data" ] ; then
if [ "$data" ]; then
response="$(_post "$data" "$url" "" $m)"
else
response="$(_get "$url")"
fi
if [ "$?" != "0" ] ; then
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
if ! printf "$response" | grep '"message":"success"' > /dev/null ; then
if ! printf "$response" | grep '"message":"success"' >/dev/null; then
return 1
fi
return 0
}
+50 -55
View File
@@ -6,10 +6,8 @@
#
#DP_Key="sADDsdasdgdsf"
DP_Api="https://dnsapi.cn"
#REST_API
######## Public functions #####################
@@ -17,40 +15,45 @@ DP_Api="https://dnsapi.cn"
dns_dp_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$DP_Id" ] || [ -z "$DP_Key" ] ; then
if [ -z "$DP_Id" ] || [ -z "$DP_Key" ]; then
_err "You don't specify dnspod api key and key id yet."
_err "Please create you key and try again."
return 1
fi
REST_API=$DP_Api
#save the api key and email to the account conf file.
_saveaccountconf DP_Id "$DP_Id"
_saveaccountconf DP_Key "$DP_Key"
_debug "First detect the root zone"
if ! _get_root $fulldomain ; then
if ! _get_root $fulldomain; then
_err "invalid domain"
return 1
fi
existing_records $_domain $_sub_domain
existing_records $_domain $_sub_domain
_debug count "$count"
if [ "$?" != "0" ] ; then
if [ "$?" != "0" ]; then
_err "Error get existing records."
return 1
fi
if [ "$count" = "0" ] ; then
if [ "$count" = "0" ]; then
add_record $_domain $_sub_domain $txtvalue
else
update_record $_domain $_sub_domain $txtvalue
fi
}
#fulldomain
dns_dp_rm() {
fulldomain=$1
}
#usage: root sub
#return if the sub record already exists.
#echos the existing records count.
@@ -59,26 +62,25 @@ existing_records() {
_debug "Getting txt records"
root=$1
sub=$2
if ! _rest POST "Record.List" "login_token=$DP_Id,$DP_Key&domain_id=$_domain_id&sub_domain=$_sub_domain"; then
return 1
return 1
fi
if printf "$response" | grep 'No records' ; then
count=0;
return 0
if printf "$response" | grep 'No records'; then
count=0
return 0
fi
if printf "$response" | grep "Action completed successful" >/dev/null ; then
if printf "$response" | grep "Action completed successful" >/dev/null; then
count=$(printf "$response" | grep '<type>TXT</type>' | wc -l)
record_id=$(printf "$response" | grep '^<id>' | tail -1 | cut -d '>' -f 2 | cut -d '<' -f 1)
return 0
return 0
else
_err "get existing records error."
return 1
fi
count=0
}
@@ -89,19 +91,18 @@ add_record() {
sub=$2
txtvalue=$3
fulldomain=$sub.$root
_info "Adding record"
if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=默认"; then
return 1
fi
if printf "$response" | grep "Action completed successful" ; then
if printf "$response" | grep "Action completed successful"; then
return 0
fi
return 1 #error
}
@@ -112,24 +113,21 @@ update_record() {
sub=$2
txtvalue=$3
fulldomain=$sub.$root
_info "Updating record"
if ! _rest POST "Record.Modify" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=默认&record_id=$record_id"; then
return 1
fi
if printf "$response" | grep "Action completed successful" ; then
if printf "$response" | grep "Action completed successful"; then
return 0
fi
return 1 #error
}
#################### Private functions bellow ##################################
#_acme-challenge.www.domain.com
#returns
@@ -140,21 +138,21 @@ _get_root() {
domain=$1
i=2
p=1
while [ '1' ] ; do
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
if [ -z "$h" ] ; then
if [ -z "$h" ]; then
#not valid
return 1;
return 1
fi
if ! _rest POST "Domain.Info" "login_token=$DP_Id,$DP_Key&format=json&domain=$h"; then
return 1
fi
if printf "$response" | grep "Action completed successful" >/dev/null ; then
if printf "$response" | grep "Action completed successful" >/dev/null; then
_domain_id=$(printf "%s\n" "$response" | _egrep_o \"id\":\"[^\"]*\" | cut -d : -f 2 | tr -d \")
_debug _domain_id "$_domain_id"
if [ "$_domain_id" ] ; then
if [ "$_domain_id" ]; then
_sub_domain=$(printf $domain | cut -d . -f 1-$p)
_debug _sub_domain $_sub_domain
_domain=$h
@@ -169,7 +167,6 @@ _get_root() {
return 1
}
#Usage: method URI data
_rest() {
m=$1
@@ -177,22 +174,20 @@ _rest() {
data="$3"
_debug $ep
url="$REST_API/$ep"
_debug url "$url"
if [ "$data" ] ; then
if [ "$data" ]; then
_debug2 data "$data"
response="$(_post $data "$url")"
else
response="$(_get "$url")"
fi
if [ "$?" != "0" ] ; then
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}
+26 -28
View File
@@ -6,39 +6,37 @@
#
#GD_Secret="asdfsdfsfsdfsdfdfsdf"
GD_Api="https://api.godaddy.com/v1"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_gd_add(){
dns_gd_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$GD_Key" ] || [ -z "$GD_Secret" ] ; then
if [ -z "$GD_Key" ] || [ -z "$GD_Secret" ]; then
_err "You don't specify godaddy api key and secret yet."
_err "Please create you key and try again."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf GD_Key "$GD_Key"
_saveaccountconf GD_Secret "$GD_Secret"
_debug "First detect the root zone"
if ! _get_root $fulldomain ; then
if ! _get_root $fulldomain; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_info "Adding record"
if _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[{\"data\":\"$txtvalue\"}]"; then
if [ "$response" = "{}" ] ; then
if _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[{\"data\":\"$txtvalue\"}]"; then
if [ "$response" = "{}" ]; then
_info "Added, sleeping 10 seconds"
sleep 10
#todo: check if the record takes effect
@@ -50,12 +48,14 @@ dns_gd_add(){
fi
fi
_err "Add txt record error."
}
#fulldomain
dns_gd_rm() {
fulldomain=$1
}
#################### Private functions bellow ##################################
#_acme-challenge.www.domain.com
@@ -67,18 +67,18 @@ _get_root() {
domain=$1
i=2
p=1
while [ '1' ] ; do
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
if [ -z "$h" ] ; then
if [ -z "$h" ]; then
#not valid
return 1;
fi
if ! _gd_rest GET "domains/$h" ; then
return 1
fi
if printf "$response" | grep '"code":"NOT_FOUND"' >/dev/null ; then
if ! _gd_rest GET "domains/$h"; then
return 1
fi
if printf "$response" | grep '"code":"NOT_FOUND"' >/dev/null; then
_debug "$h not found"
else
_sub_domain=$(printf $domain | cut -d . -f 1-$p)
@@ -96,23 +96,21 @@ _gd_rest() {
ep="$2"
data="$3"
_debug $ep
_H1="Authorization: sso-key $GD_Key:$GD_Secret"
_H2="Content-Type: application/json"
if [ "$data" ] ; then
if [ "$data" ]; then
_debug data "$data"
response="$(_post "$data" "$GD_Api/$ep" "" $m)"
else
response="$(_get "$GD_Api/$ep")"
fi
if [ "$?" != "0" ] ; then
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}
+20 -17
View File
@@ -13,15 +13,15 @@ wiki="https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api"
dns_lexicon_add() {
fulldomain=$1
txtvalue=$2
domain=$(printf "$fulldomain" | cut -d . -f 2-999)
if ! _exists $lexicon_cmd ; then
if ! _exists $lexicon_cmd; then
_err "Please install $lexicon_cmd first: $wiki"
return 1
fi
if [ -z "$PROVIDER" ] ; then
if [ -z "$PROVIDER" ]; then
_err "Please define env PROVIDER first: $wiki"
return 1
fi
@@ -29,34 +29,34 @@ dns_lexicon_add() {
_savedomainconf PROVIDER "$PROVIDER"
export PROVIDER
Lx_name=$(echo LEXICON_${PROVIDER}_USERNAME | tr [a-z] [A-Z])
Lx_name=$(echo LEXICON_${PROVIDER}_USERNAME | tr [a-z] [A-Z])
eval Lx_name_v="\$$Lx_name"
_debug "$Lx_name" "$Lx_name_v"
if [ "$Lx_name_v" ] ; then
if [ "$Lx_name_v" ]; then
_saveaccountconf $Lx_name "$Lx_name_v"
export "$Lx_name"
fi
Lx_token=$(echo LEXICON_${PROVIDER}_TOKEN | tr [a-z] [A-Z])
Lx_token=$(echo LEXICON_${PROVIDER}_TOKEN | tr [a-z] [A-Z])
eval Lx_token_v="\$$Lx_token"
_debug "$Lx_token" "$Lx_token_v"
if [ "$Lx_token_v" ] ; then
if [ "$Lx_token_v" ]; then
_saveaccountconf $Lx_token "$Lx_token_v"
export "$Lx_token"
fi
Lx_password=$(echo LEXICON_${PROVIDER}_PASSWORD | tr [a-z] [A-Z])
Lx_password=$(echo LEXICON_${PROVIDER}_PASSWORD | tr [a-z] [A-Z])
eval Lx_password_v="\$$Lx_password"
_debug "$Lx_password" "$Lx_password_v"
if [ "$Lx_password_v" ] ; then
if [ "$Lx_password_v" ]; then
_saveaccountconf $Lx_password "$Lx_password_v"
export "$Lx_password"
fi
Lx_domaintoken=$(echo LEXICON_${PROVIDER}_DOMAINTOKEN | tr [a-z] [A-Z])
Lx_domaintoken=$(echo LEXICON_${PROVIDER}_DOMAINTOKEN | tr [a-z] [A-Z])
eval Lx_domaintoken_v="\$$Lx_domaintoken"
_debug "$Lx_domaintoken" "$Lx_domaintoken_v"
if [ "$Lx_domaintoken_v" ] ; then
if [ "$Lx_domaintoken_v" ]; then
export "$Lx_domaintoken"
_saveaccountconf $Lx_domaintoken "$Lx_domaintoken_v"
fi
@@ -65,5 +65,8 @@ dns_lexicon_add() {
}
#fulldomain
dns_lexicon_rm() {
fulldomain=$1
}
+141
View File
@@ -0,0 +1,141 @@
#!/usr/bin/env sh
# bug reports to dev@1e.ca
#
#LUA_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
#LUA_Email="user@luadns.net"
LUA_Api="https://api.luadns.com/v1"
LUA_auth=$(printf $LUA_Email:$LUA_Key | _base64)
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_lua_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$LUA_Key" ] || [ -z "$LUA_Email" ]; then
_err "You don't specify luadns api key and email yet."
_err "Please create you key and try again."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf LUA_Key "$LUA_Key"
_saveaccountconf LUA_Email "$LUA_Email"
_debug "First detect the root zone"
if ! _get_root $fulldomain; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_LUA_rest GET "zones/${_domain_id}/records"
if ! printf "$response" | grep \"id\": >/dev/null; then
_err "Error"
return 1
fi
count=$(printf "%s\n" "$response" | _egrep_o \"name\":\"$fulldomain\" | wc -l)
_debug count "$count"
if [ "$count" = "0" ]; then
_info "Adding record"
if _LUA_rest POST "zones/$_domain_id/records" "{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
if printf -- "%s" "$response" | grep $fulldomain >/dev/null; 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 \"id\":[^,]*,\"name\":\"$fulldomain.\",\"type\":\"TXT\" | cut -d: -f2 | cut -d, -f1)
_debug "record_id" $record_id
_LUA_rest PUT "zones/$_domain_id/records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"ttl\":120}"
if [ "$?" = "0" ]; then
_info "Updated!"
#todo: check if the record takes effect
return 0
fi
_err "Update error"
return 1
fi
}
#fulldomain
dns_lua_rm() {
fulldomain=$1
}
#################### Private functions bellow ##################################
#_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 ! _LUA_rest GET "zones"; then
return 1
fi
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1
fi
if printf $response | grep \"name\":\"$h\" >/dev/null; then
_domain_id=$(printf "%s\n" "$response" | _egrep_o \"id\":[^,]*,\"name\":\"$h\" | cut -d : -f 2 | cut -d , -f 1)
if [ "$_domain_id" ]; then
_sub_domain=$(printf $domain | cut -d . -f 1-$p)
_domain=$h
return 0
fi
return 1
fi
p=$i
i=$(expr $i + 1)
done
return 1
}
_LUA_rest() {
m=$1
ep="$2"
data="$3"
_debug $ep
_H1="Accept: application/json"
_H2="Authorization: Basic $LUA_auth"
if [ "$data" ]; then
_debug data "$data"
response="$(_post "$data" "$LUA_Api/$ep" "" $m)"
else
response="$(_get "$LUA_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}
+144
View File
@@ -0,0 +1,144 @@
#!/usr/bin/env sh
# bug reports to dev@1e.ca
# ME_Key=qmlkdjflmkqdjf
# ME_Secret=qmsdlkqmlksdvnnpae
ME_Api=https://api.dnsmadeeasy.com/V2.0/dns/managed
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_me_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$ME_Key" ] || [ -z "$ME_Secret" ]; then
_err "You didn't specify DNSMadeEasy api key and secret yet."
_err "Please create you key and try again."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf ME_Key "$ME_Key"
_saveaccountconf ME_Secret "$ME_Secret"
_debug "First detect the root zone"
if ! _get_root $fulldomain; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_me_rest GET "${_domain_id}/records?recordName=$_sub_domain&type=TXT"
if ! printf "$response" | grep \"totalRecords\": >/dev/null; then
_err "Error"
return 1
fi
count=$(printf "%s\n" "$response" | _egrep_o \"totalRecords\":[^,]* | cut -d : -f 2)
_debug count "$count"
if [ "$count" = "0" ]; then
_info "Adding record"
if _me_rest POST "$_domain_id/records/" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\",\"gtdLocation\":\"DEFAULT\",\"ttl\":120}"; then
if printf -- "%s" "$response" | grep \"id\": >/dev/null; 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 \"id\":[^,]* | cut -d : -f 2 | head -n 1)
_debug "record_id" $record_id
_me_rest PUT "$_domain_id/records/$record_id/" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\",\"gtdLocation\":\"DEFAULT\",\"ttl\":120}"
if [ "$?" = "0" ]; then
_info "Updated"
#todo: check if the record takes effect
return 0
fi
_err "Update error"
return 1
fi
}
#fulldomain
dns_me_rm() {
fulldomain=$1
}
#################### Private functions bellow ##################################
#_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
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1
fi
if ! _me_rest GET "name?domainname=$h"; then
return 1
fi
if printf $response | grep \"name\":\"$h\" >/dev/null; then
_domain_id=$(printf "%s\n" "$response" | _egrep_o \"id\":[^,]* | head -n 1 | cut -d : -f 2)
if [ "$_domain_id" ]; then
_sub_domain=$(printf $domain | cut -d . -f 1-$p)
_domain=$h
return 0
fi
return 1
fi
p=$i
i=$(expr $i + 1)
done
return 1
}
_me_rest() {
m=$1
ep="$2"
data="$3"
_debug $ep
cdate=$(date -u +"%a, %d %b %Y %T %Z")
hmac=$(printf "$cdate" | _hmac sha1 "$ME_Secret" 1)
_H1="x-dnsme-apiKey: $ME_Key"
_H2="x-dnsme-requestDate: $cdate"
_H3="x-dnsme-hmac: $hmac"
if [ "$data" ]; then
_debug data "$data"
response="$(_post "$data" "$ME_Api/$ep" "" $m)"
else
response="$(_get "$ME_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}
+9 -9
View File
@@ -6,8 +6,6 @@
#Which will be called by acme.sh to add the txt record to your api system.
#returns 0 means success, otherwise error.
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
@@ -15,16 +13,18 @@ dns_myapi_add() {
fulldomain=$1
txtvalue=$2
_err "Not implemented!"
return 1;
return 1
}
#fulldomain
dns_myapi_rm() {
fulldomain=$1
}
#################### Private functions bellow ##################################
_info() {
if [ -z "$2" ] ; then
if [ -z "$2" ]; then
echo "[$(date)] $1"
else
echo "[$(date)] $1='$2'"
@@ -37,7 +37,7 @@ _err() {
}
_debug() {
if [ -z "$DEBUG" ] ; then
if [ -z "$DEBUG" ]; then
return
fi
_err "$@"
@@ -45,8 +45,8 @@ _debug() {
}
_debug2() {
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ] ; then
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
_debug "$@"
fi
return
}
}
Regular → Executable
+91 -99
View File
@@ -1,6 +1,5 @@
#!/usr/bin/env sh
#Applcation Key
#OVH_AK="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
@@ -10,10 +9,8 @@
#Consumer Key
#OVH_CK="sdfsdfsdfsdfsdfdsf"
#OVH_END_POINT=ovh-eu
#'ovh-eu'
OVH_EU='https://eu.api.ovh.com/1.0'
@@ -35,121 +32,116 @@ SYS_CA='https://ca.api.soyoustart.com/1.0'
#'runabove-ca'
RAV_CA='https://api.runabove.com/1.0'
wiki="https://github.com/Neilpang/acme.sh/wiki/How-to-use-OVH-domain-api"
ovh_success="https://github.com/Neilpang/acme.sh/wiki/OVH-Success"
_ovh_get_api() {
_ogaep="$1"
case "${_ogaep}" in
ovh-eu|ovheu)
printf "%s" $OVH_EU
return
;;
ovh-ca|ovhca)
printf "%s" $OVH_CA
return
;;
kimsufi-eu|kimsufieu)
printf "%s" $KSF_EU
return
;;
kimsufi-ca|kimsufica)
printf "%s" $KSF_CA
return
;;
soyoustart-eu|soyoustarteu)
printf "%s" $SYS_EU
return
;;
soyoustart-ca|soyoustartca)
printf "%s" $SYS_CA
return
;;
runabove-ca|runaboveca)
printf "%s" $RAV_CA
return
;;
ovh-eu | ovheu)
printf "%s" $OVH_EU
return
;;
ovh-ca | ovhca)
printf "%s" $OVH_CA
return
;;
kimsufi-eu | kimsufieu)
printf "%s" $KSF_EU
return
;;
kimsufi-ca | kimsufica)
printf "%s" $KSF_CA
return
;;
soyoustart-eu | soyoustarteu)
printf "%s" $SYS_EU
return
;;
soyoustart-ca | soyoustartca)
printf "%s" $SYS_CA
return
;;
runabove-ca | runaboveca)
printf "%s" $RAV_CA
return
;;
*)
_err "Unknown parameter : $1"
return 1
;;
esac
_err "Unknown parameter : $1"
return 1
;;
esac
}
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_ovh_add(){
dns_ovh_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$OVH_AK" ] || [ -z "$OVH_AS" ] ; then
if [ -z "$OVH_AK" ] || [ -z "$OVH_AS" ]; then
_err "You don't specify OVH application key and application secret yet."
_err "Please create you key and try again."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf OVH_AK "$OVH_AK"
_saveaccountconf OVH_AS "$OVH_AS"
if [ -z "$OVH_END_POINT" ] ; then
if [ -z "$OVH_END_POINT" ]; then
OVH_END_POINT="ovh-eu"
fi
_info "Using OVH endpoint: $OVH_END_POINT"
if [ "$OVH_END_POINT" != "ovh-eu" ] ; then
_saveaccountconf OVH_END_POINT "$OVH_END_POINT"
if [ "$OVH_END_POINT" != "ovh-eu" ]; then
_saveaccountconf OVH_END_POINT "$OVH_END_POINT"
fi
OVH_API="$(_ovh_get_api $OVH_END_POINT )"
OVH_API="$(_ovh_get_api $OVH_END_POINT)"
_debug OVH_API "$OVH_API"
if [ -z "$OVH_CK" ] ; then
if [ -z "$OVH_CK" ]; then
_info "OVH consumer key is empty, Let's get one:"
if ! _ovh_authentication ; then
if ! _ovh_authentication; then
_err "Can not get consumer key."
fi
#return and wait for retry.
return 1;
return 1
fi
_info "Checking authentication"
response="$(_ovh_rest GET "domain/")"
if _contains "$response" "INVALID_CREDENTIAL" ; then
if _contains "$response" "INVALID_CREDENTIAL"; then
_err "The consumer key is invalid: $OVH_CK"
_err "Please retry to create a new one."
_clearaccountconf OVH_CK
_clearaccountconf OVH_CK
return 1
fi
_info "Consumer key is ok."
_debug "First detect the root zone"
if ! _get_root $fulldomain ; then
if ! _get_root $fulldomain; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_ovh_rest GET "domain/zone/$_domain/record?fieldType=TXT&subDomain=$_sub_domain"
if _contains "$response" '\[\]' || _contains "$response" "This service does not exist" ; then
if _contains "$response" '\[\]' || _contains "$response" "This service does not exist"; then
_info "Adding record"
if _ovh_rest POST "domain/zone/$_domain/record" "{\"fieldType\":\"TXT\",\"subDomain\":\"$_sub_domain\",\"target\":\"$txtvalue\",\"ttl\":60}"; then
if _contains "$response" "$txtvalue" ; then
if _ovh_rest POST "domain/zone/$_domain/record" "{\"fieldType\":\"TXT\",\"subDomain\":\"$_sub_domain\",\"target\":\"$txtvalue\",\"ttl\":60}"; then
if _contains "$response" "$txtvalue"; then
_ovh_rest POST "domain/zone/$_domain/refresh"
_debug "Refresh:$response"
_info "Added, sleeping 10 seconds"
@@ -161,66 +153,70 @@ dns_ovh_add(){
else
_info "Updating record"
record_id=$(printf "%s" "$response" | tr -d "[]" | cut -d , -f 1)
if [ -z "$record_id" ] ; then
if [ -z "$record_id" ]; then
_err "Can not get record id."
return 1
fi
_debug "record_id" $record_id
if _ovh_rest PUT "domain/zone/$_domain/record/$record_id" "{\"target\":\"$txtvalue\",\"subDomain\":\"$_sub_domain\",\"ttl\":60}" ; then
if _contains "$response" "null" ; then
if _ovh_rest PUT "domain/zone/$_domain/record/$record_id" "{\"target\":\"$txtvalue\",\"subDomain\":\"$_sub_domain\",\"ttl\":60}"; then
if _contains "$response" "null"; then
_ovh_rest POST "domain/zone/$_domain/refresh"
_debug "Refresh:$response"
_info "Updated, sleeping 10 seconds"
sleep 10
return 0;
return 0
fi
fi
_err "Update error"
return 1
fi
}
#fulldomain
dns_ovh_rm() {
fulldomain=$1
}
#################### Private functions bellow ##################################
_ovh_authentication() {
_H1="X-Ovh-Application: $OVH_AK"
_H2="Content-type: application/json"
_H3=""
_H4=""
_ovhdata='{"accessRules": [{"method": "GET","path": "/*"},{"method": "POST","path": "/*"},{"method": "PUT","path": "/*"},{"method": "DELETE","path": "/*"}],"redirection":"'$ovh_success'"}'
response="$(_post "$_ovhdata" "$OVH_API/auth/credential")"
_debug3 response "$response"
validationUrl="$(echo "$response" | _egrep_o "validationUrl\":\"[^\"]*\"" | _egrep_o "http.*\"" | tr -d '"')"
if [ -z "$validationUrl" ] ; then
if [ -z "$validationUrl" ]; then
_err "Unable to get validationUrl"
return 1
fi
_debug validationUrl "$validationUrl"
consumerKey="$(echo "$response" | _egrep_o "consumerKey\":\"[^\"]*\"" | cut -d : -f 2 | tr -d '"')"
if [ -z "$consumerKey" ] ; then
if [ -z "$consumerKey" ]; then
_err "Unable to get consumerKey"
return 1
fi
_debug consumerKey "$consumerKey"
OVH_CK="$consumerKey"
_saveaccountconf OVH_CK "$OVH_CK"
_info "Please open this link to do authentication: $(__green "$validationUrl" )"
_info "Here is a guide for you: $(__green "$wiki" )"
_info "Please open this link to do authentication: $(__green "$validationUrl")"
_info "Here is a guide for you: $(__green "$wiki")"
_info "Please retry after the authentication is done."
}
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
@@ -230,18 +226,18 @@ _get_root() {
domain=$1
i=2
p=1
while [ '1' ] ; do
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
if [ -z "$h" ] ; then
if [ -z "$h" ]; then
#not valid
return 1;
fi
if ! _ovh_rest GET "domain/zone/$h" ; then
return 1
fi
if ! _contains "$response" "This service does not exist" >/dev/null ; then
if ! _ovh_rest GET "domain/zone/$h"; then
return 1
fi
if ! _contains "$response" "This service does not exist" >/dev/null; then
_sub_domain=$(printf $domain | cut -d . -f 1-$p)
_domain=$h
return 0
@@ -266,8 +262,7 @@ _ovh_rest() {
ep="$2"
data="$3"
_debug $ep
_ovh_url="$OVH_API/$ep"
_debug2 _ovh_url "$_ovh_url"
_ovh_t="$(_ovh_timestamp)"
@@ -276,7 +271,6 @@ _ovh_rest() {
_debug _ovh_p "$_ovh_p"
_ovh_hex="$(printf "%s" "$_ovh_p" | _digest sha1 hex)"
_debug2 _ovh_hex "$_ovh_hex"
_H1="X-Ovh-Application: $OVH_AK"
_H2="X-Ovh-Signature: \$1\$$_ovh_hex"
@@ -284,19 +278,17 @@ _ovh_rest() {
_H3="X-Ovh-Timestamp: $_ovh_t"
_H4="X-Ovh-Consumer: $OVH_CK"
_H5="Content-Type: application/json;charset=utf-8"
if [ "$data" ] || [ "$m" = "POST" ] || [ "$m" = "PUT" ] ; then
if [ "$data" ] || [ "$m" = "POST" ] || [ "$m" = "PUT" ]; then
_debug data "$data"
response="$(_post "$data" "$_ovh_url" "" $m)"
else
response="$(_get "$_ovh_url")"
fi
if [ "$?" != "0" ] ; then
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}
+139
View File
@@ -0,0 +1,139 @@
#!/usr/bin/env sh
#PowerDNS Emdedded API
#https://doc.powerdns.com/md/httpapi/api_spec/
#
#PDNS_Url="http://ns.example.com:8081"
#PDNS_ServerId="localhost"
#PDNS_Token="0123456789ABCDEF"
#PDNS_Ttl=60
DEFAULT_PDNS_TTL=60
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000"
dns_pdns_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$PDNS_Url" ]; then
_err "You don't specify PowerDNS address."
_err "Please set PDNS_Url and try again."
return 1
fi
if [ -z "$PDNS_ServerId" ]; then
_err "You don't specify PowerDNS server id."
_err "Please set you PDNS_ServerId and try again."
return 1
fi
if [ -z "$PDNS_Token" ]; then
_err "You don't specify PowerDNS token."
_err "Please create you PDNS_Token and try again."
return 1
fi
if [ -z "$PDNS_Ttl" ]; then
PDNS_Ttl=$DEFAULT_PDNS_TTL
fi
#save the api addr and key to the account conf file.
_saveaccountconf PDNS_Url "$PDNS_Url"
_saveaccountconf PDNS_ServerId "$PDNS_ServerId"
_saveaccountconf PDNS_Token "$PDNS_Token"
if [ "$PDNS_Ttl" != "$DEFAULT_PDNS_TTL" ]; then
_saveaccountconf PDNS_Ttl "$PDNS_Ttl"
fi
_debug "First detect the root zone"
if ! _get_root $fulldomain; then
_err "invalid domain"
return 1
fi
_debug _domain "$_domain"
if ! set_record "$_domain" "$fulldomain" "$txtvalue"; then
return 1
fi
return 0
}
#fulldomain
dns_pdns_rm() {
fulldomain=$1
}
set_record() {
_info "Adding record"
root=$1
full=$2
txtvalue=$3
if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root." "{\"rrsets\": [{\"name\": \"$full.\", \"changetype\": \"REPLACE\", \"type\": \"TXT\", \"ttl\": $PDNS_Ttl, \"records\": [{\"name\": \"$full.\", \"type\": \"TXT\", \"content\": \"\\\"$txtvalue\\\"\", \"disabled\": false, \"ttl\": $PDNS_Ttl}]}]}"; then
_err "Set txt record error."
return 1
fi
if ! _pdns_rest "PUT" "/api/v1/servers/$PDNS_ServerId/zones/$root./notify"; then
_err "Notify servers error."
return 1
fi
return 0
}
#################### Private functions bellow ##################################
#_acme-challenge.www.domain.com
#returns
# _domain=domain.com
_get_root() {
domain=$1
i=1
p=1
if _pdns_rest "GET" "/api/v1/servers/$PDNS_ServerId/zones"; then
_zones_response=$response
fi
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
if [ -z "$h" ]; then
return 1
fi
if printf "$_zones_response" | grep "\"name\": \"$h.\"" >/dev/null; then
_domain=$h
return 0
fi
p=$i
i=$(expr $i + 1)
done
_debug "$domain not found"
return 1
}
_pdns_rest() {
method=$1
ep=$2
data=$3
_H1="X-API-Key: $PDNS_Token"
if [ ! "$method" = "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$PDNS_Url$ep" "" "$method")"
else
response="$(_get "$PDNS_Url$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}