255 Commits
2.6.4 ... 2.6.5

Author SHA1 Message Date
neil
6489a48e1f Merge pull request #536 from Neilpang/dev
Dev
2017-01-14 17:09:41 +08:00
neil
ca24d1762e Merge pull request #535 from bittorf/master
travis: use only POSIX constructs here, avoid bashisms
2017-01-14 17:08:38 +08:00
Bastian Bittorf
2f4b84c074 travis: use only POSIX constructs here, avoid bashisms
e.g. [[ ]] -> [ ] and 'which' -> command -V

Although this is not strictly needed, it keeps the project uniformly POSIX.

Signed-off-by: Bastian Bittorf <bb@npl.de>
2017-01-13 19:52:30 +01:00
neil
6ae810a1fa Merge pull request #534 from Neilpang/dev
Dev
2017-01-13 22:15:01 +08:00
neil
3e3f695536 Merge pull request #526 from bittorf/master
shellcheck: fix several occurences of SC2034
2017-01-13 22:13:28 +08:00
Bastian Bittorf
3ca93f4a4c shellcheck: fix several occurences of SC2034
message:
SC2034: $VARNAME appears unused. Verify it or export it.

most of these are related to the style:
we generate global vars, which are used in other functions.

the var "lexical_url" was really unused (left it as comment)

the travis-check now does not need anymore special flags.

Signed-off-by: Bastian Bittorf <bb@npl.de>
2017-01-13 14:54:09 +01:00
neil
f2d9930773 Merge pull request #533 from Neilpang/dev
minor
2017-01-13 20:50:52 +08:00
neilpang
2fbf399156 minor 2017-01-13 20:49:58 +08:00
neil
8a1e335bf5 Merge pull request #528 from Neilpang/dev
Dev
2017-01-10 10:41:37 +08:00
neil
5413bf8753 minor, clear account key cache if new-authz error. 2017-01-10 10:36:47 +08:00
neil
c4c5ecd03d Merge pull request #525 from bittorf/master
dnsapi/dns_dp.sh: shellcheck: fix 1 occurence of SC2126
2017-01-09 22:16:23 +08:00
Bastian Bittorf
3b67cf4378 dnsapi/dns_dp.sh: shellcheck: fix 1 occurence of SC2126
shellcheck message was:
"Consider using grep -c instead of grep | wc"
2017-01-09 15:08:41 +01:00
neil
f3c937f9ed Merge pull request #524 from Neilpang/dev
minor, fix shellcheck warning
2017-01-09 22:02:49 +08:00
neilpang
671a699472 minor, fix shellcheck warning 2017-01-09 22:01:48 +08:00
neil
cc4fa1c6bd Merge pull request #523 from Neilpang/dev
Dev
2017-01-09 20:51:27 +08:00
neilpang
d11d476126 "Don't use [] around ranges in tr, it replaces literal square brackets." 2017-01-09 20:26:07 +08:00
neil
1ce06c7cdd Merge pull request #521 from bittorf/master
dnsapi/dns_lexicon.sh: shellcheck: fix 4 occurences of SC2021
2017-01-09 20:21:58 +08:00
Bastian Bittorf
800f02ba38 dnsapi/dns_lexicon.sh: shellcheck: fix 4 occurences of SC2021:
"Don't use [] around ranges in tr, it replaces literal square brackets."

this introduces another warning:
"Use '[:lower:]' to support accents and foreign alphabets."

This is more a style thingy because we really want to only catch A-Z.
work around this by using a shellcheck-directive and a comment
that the [:lower:] will not work with e.g. busybox-ash.

if we later really want to use [:lower:], we should use 'sed' for that.
2017-01-09 12:21:32 +01:00
neil
79964b0e85 Merge pull request #519 from Neilpang/dev
Dev
2017-01-08 10:21:38 +08:00
neil
0924d11bbf Merge pull request #518 from wizonesolutions/fix-bad-domain-id-parse
Trim potential closing curly brace.
2017-01-08 10:21:02 +08:00
Kevin Kaland
3cf85634eb Trim potential closing curly brace.
Fixes GH-517.
2017-01-08 00:10:22 +01:00
neil
ec01175d37 Merge pull request #515 from Neilpang/dev
Dev
2017-01-07 16:55:09 +08:00
neil
5bb518ff0f Merge pull request #512 from ksperling/dnsaws
Add support for AWS_SESSION_TOKEN and fix bug when multiple hosted zones exist
2017-01-07 16:53:08 +08:00
Karsten Sperling
5415381cf4 Add support for AWS_SESSION_TOKEN and fix bug when multiple hosted zones exist 2017-01-06 15:36:35 +13:00
neil
129ae06354 Merge pull request #509 from Neilpang/dev
LF
2017-01-05 22:33:01 +08:00
neilpang
058e5d5f4b LF 2017-01-05 22:32:26 +08:00
neil
2ec493f033 Merge pull request #504 from Neilpang/dev
Dev
2017-01-03 21:13:15 +08:00
neil
a33e8a8509 Merge pull request #503 from wpk-/wpk-alwaysdata
Alwaysdata DNS API support.
2017-01-03 20:44:16 +08:00
Paul Koppen
7b4be7be40 Remove spaces from blank lines. 2017-01-03 12:35:10 +00:00
Paul Koppen
b90917a529 Improve legibility. 2017-01-03 12:33:10 +00:00
Paul Koppen
180f05f6f0 Add instructions for the Alwaysdata API. 2017-01-03 12:16:22 +00:00
Paul Koppen
b2686e5b6d Add Alwaysdata.com to list of supported API's. 2017-01-03 12:13:27 +00:00
Paul Koppen
831b95f13a Merge suggested improvements.
* Use `_head_n`.
* Add link to GitHub repo for bug reporting.
2017-01-03 12:09:57 +00:00
Paul Koppen
331b599a81 Use _post for DELETE and switch to JSON API (Alwaysdata default). 2017-01-03 11:41:11 +00:00
neil
3ef817ebc2 Merge pull request #502 from Neilpang/dev
Dev
2017-01-03 19:35:31 +08:00
neilpang
d0f7c309ab run pre-hook first 2017-01-03 19:31:11 +08:00
Paul Koppen
e5079b9dad Add Alwaysdata DNS API. 2017-01-02 23:39:00 +00:00
neil
9e773c9143 Merge pull request #499 from sercxanto/copycert
Add note about permissions of installed files
2016-12-29 18:58:38 +08:00
Georg Lutz
fe600441c9 Add note about permissions of installed files 2016-12-29 11:16:20 +01:00
neil
291b56db93 Merge pull request #496 from Neilpang/dev
fix format
2016-12-27 22:09:15 +08:00
neilpang
ec9975c3d9 fix format 2016-12-27 21:29:44 +08:00
neil
9e57161941 Merge pull request #495 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/465
2016-12-27 21:20:10 +08:00
neilpang
20444bf253 fix https://github.com/Neilpang/acme.sh/issues/465 2016-12-27 20:53:57 +08:00
neil
e428c4402e Merge pull request #494 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/490
2016-12-27 20:41:42 +08:00
neilpang
15af89d51c fix https://github.com/Neilpang/acme.sh/issues/490 2016-12-27 20:40:52 +08:00
neil
ed95865696 Merge pull request #493 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/491
2016-12-27 20:20:01 +08:00
neilpang
8c71bd57e7 fix https://github.com/Neilpang/acme.sh/issues/491 2016-12-27 20:19:22 +08:00
neil
d204be4b2c Merge pull request #487 from Neilpang/dev
service nginx force-reload
2016-12-22 20:07:33 +08:00
neilpang
4743171b4f service nginx force-reload 2016-12-22 20:06:55 +08:00
neil
1fb800f7a7 Merge pull request #486 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/481
2016-12-21 21:09:37 +08:00
neilpang
3a3b0dd5c1 fix https://github.com/Neilpang/acme.sh/issues/481 2016-12-21 20:38:14 +08:00
neil
2959281d42 Merge pull request #485 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/480
2016-12-21 20:22:43 +08:00
neilpang
e2c939fb97 fix https://github.com/Neilpang/acme.sh/issues/480 2016-12-21 20:19:57 +08:00
neil
51d0e4325e Merge pull request #484 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/478
2016-12-21 19:57:17 +08:00
neilpang
08b6cf0231 fix https://github.com/Neilpang/acme.sh/issues/478 2016-12-21 19:56:28 +08:00
neil
059147b74a Merge pull request #475 from Neilpang/dev
Dev
2016-12-18 21:43:45 +08:00
neil
c96ceeb1bd Merge pull request #474 from noplanman/typo_ocsp_staple
Fix typo.
2016-12-18 21:43:01 +08:00
Armando Lüscher
0a3b6c4813 Keep backwards compatible. 2016-12-18 05:29:27 +01:00
neil
8636a15695 Merge pull request #473 from Neilpang/dev
Dev
2016-12-18 11:39:53 +08:00
Armando Lüscher
96db9362c5 Fix typo. 2016-12-18 03:17:35 +01:00
neil
f81f93e9c3 Merge pull request #466 from ka7/spellingfixes_dev
Spellingfixes dev
2016-12-17 20:52:48 +08:00
neilpang
a3a04b5f76 revert last fix 2016-12-17 20:51:00 +08:00
klemens
329174b6d9 spelling fixes 2016-12-14 21:32:24 +01:00
neilpang
b171aff418 fix for wrt https://github.com/Neilpang/acme.sh/issues/465
I know it's a stupid fix, but it works.
I will check it later.
2016-12-13 20:42:36 +08:00
neilpang
1f6ffa3e88 fix warnings 2016-12-13 20:32:50 +08:00
neilpang
24d2a8b9d5 add debug info 2016-12-13 20:27:49 +08:00
neilpang
4d8b99a307 add more debug info 2016-12-13 20:04:43 +08:00
neil
f9085fedd7 fix renew for different CA
fix renew for different CA
2016-12-10 21:38:35 +08:00
neilpang
c4236e58d1 fix renew for different CA 2016-12-10 21:32:47 +08:00
neil
eb91f9575a fix deactivate function
fix deactivate function
2016-12-09 22:23:03 +08:00
neilpang
947d14ffeb fix deactivate function 2016-12-09 22:20:38 +08:00
neil
b3f915b5b2 fix deactivate for solaris
fix deactivate for solaris
2016-12-07 15:05:27 +08:00
neilpang
03d3f3afc3 fix for solaris 2016-12-07 14:50:45 +08:00
neilpang
2728170c01 add debug info 2016-12-07 14:30:17 +08:00
neil
c107f3632a fix for solaris
fix for solaris
2016-12-07 13:53:52 +08:00
neilpang
7d1c5fca0b fix for solaris 2016-12-07 13:52:31 +08:00
neil
e71887e1a8 fix for solaris
fix for solaris
2016-12-07 13:22:14 +08:00
neilpang
39d1eeda23 fix for solaris 2016-12-07 12:41:22 +08:00
neil
b482f3ce94 fix for solaris
fix for solaris
2016-12-07 11:59:27 +08:00
neilpang
122cc48c29 minor 2016-12-07 11:51:15 +08:00
neilpang
c7c57cfa0e fix for solaris 2016-12-07 11:49:24 +08:00
neil
1f9ca20dfd Merge pull request #452 from Neilpang/dev
minor, clear default confs
2016-12-06 20:54:13 +08:00
neilpang
5efbaa4849 minor, clear default confs 2016-12-06 20:50:33 +08:00
neil
c6f55bc4ab Mac OSX
Dev
2016-12-06 19:05:39 +08:00
neilpang
b28a3db3d6 Mac OSX 2016-12-06 19:03:59 +08:00
neilpang
b9ece28f68 add osx CI 2016-12-06 19:02:46 +08:00
neil
79b4907cb9 Merge pull request #449 from Neilpang/dev
support aws remove
2016-12-06 16:56:28 +08:00
neilpang
dfbc244b00 support aws remove 2016-12-06 16:52:02 +08:00
neil
b23d5e26e2 Merge pull request #448 from Neilpang/dev
Dev
2016-12-06 16:06:19 +08:00
neilpang
f1f3074306 fix format 2016-12-06 15:54:19 +08:00
neilpang
f162ad193f support dnspod remove 2016-12-06 15:46:22 +08:00
neil
5254f300f9 Merge pull request #447 from Neilpang/dev
Dev
2016-12-06 15:32:26 +08:00
neilpang
c0d0100ca8 fix format 2016-12-06 15:18:02 +08:00
neilpang
21f201e371 support cloudflare rm function 2016-12-06 14:58:36 +08:00
neil
bbc378ed8f Merge pull request #445 from Neilpang/dev
update template
2016-12-06 14:03:02 +08:00
neilpang
e2d494321c update template 2016-12-06 14:02:31 +08:00
neil
c2df8043db Merge pull request #444 from Neilpang/dev
Dev
2016-12-06 13:58:06 +08:00
neilpang
df62150b5a Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2016-12-06 13:55:28 +08:00
neilpang
eea52a5fa6 update api template 2016-12-06 13:55:06 +08:00
neil
2d9015b840 Merge pull request #441 from Neilpang/dev
Dev
2016-12-05 09:04:23 +08:00
neil
187ef29914 Merge pull request #440 from vjt/patch-1
Fix AWS Route53 API consumer
2016-12-05 09:03:37 +08:00
Marcello Barnaba
c12be766e9 Fix Route53 API consumer
Ignoring the Chthlulu argument 😃, Route53 returns its XML all on one line, making not possible to grep the hosted zone record with egrep/sed.

This change splits the XML in multiple lines, so that parsing can succeed.
2016-12-04 20:15:48 +01:00
neil
2168458f11 Merge pull request #439 from Neilpang/dev
support CloudXNS rm method
2016-12-04 22:22:54 +08:00
neil
8cf0725593 Merge pull request #433 from kookxiang/dev
Automatically delete acme txt record for CloudXNS
2016-12-04 22:19:25 +08:00
kookxiang
8379f015d7 Finish dns_cx_rm() method 2016-12-04 22:17:34 +08:00
neil
f08c01800f Merge pull request #438 from Neilpang/dev
fix cx for solaris
2016-12-04 22:00:01 +08:00
neilpang
a62706678e fix for solaris 2016-12-04 21:33:36 +08:00
neilpang
e4468562d2 fix cx 2016-12-04 21:24:38 +08:00
neil
7316bf7bc5 Merge pull request #437 from Neilpang/dev
Dev
2016-12-04 20:42:19 +08:00
neilpang
3747b7d930 fix cx 2016-12-04 20:40:27 +08:00
neilpang
5be3f22d06 fix issue 2016-12-04 14:45:26 +08:00
neil
c572ce946b Dev (#434)
* do not use script home

* fix format

* fix issue when there is no one records in the domain.
2016-12-04 13:46:07 +08:00
neilpang
d69f0289ca fix issue when there is no one records in the domain. 2016-12-04 12:22:36 +08:00
neil
048e5210f7 do not use script home
* do not use script home

* fix format
2016-12-02 21:12:20 +08:00
neilpang
219e9115c0 fix format 2016-12-02 20:30:52 +08:00
neilpang
b43416af97 do not use script home 2016-12-02 20:24:12 +08:00
neil
6d84da588b Merge pull request #427 from Neilpang/dev
Add NO_TIMESTAMP to mute the timestamp from the output
2016-11-29 00:20:41 +08:00
neilpang
569d6c557c fix https://github.com/Neilpang/acme.sh/issues/426 2016-11-29 00:11:02 +08:00
neil
58bb94d7c7 Update README.md 2016-11-25 22:20:54 +08:00
neil
4f8f775e69 Merge pull request #421 from sjau/master
Added ISPConfig DNS API
2016-11-25 12:01:41 +08:00
sjau
5eed02f7e9 Changing shebang back to sh 2016-11-25 04:50:05 +01:00
sjau
983f1f28ca Fixed wrong zone getting JSON and added lots of debug info 2016-11-24 18:02:42 +01:00
sjau
192ede5e64 Added ISPConfig DNS API 2016-11-24 16:00:32 +01:00
neil
803a7aa878 Merge pull request #420 from Neilpang/dev
Add DNS API support for aliyun
2016-11-24 22:47:44 +08:00
neilpang
93f3098aec minor 2016-11-24 22:36:21 +08:00
neilpang
dbd94d047b fix for aliyun api 2016-11-24 22:27:14 +08:00
baiyangliu
be39ab32d1 Add DNS API support for aliyun (#410)
* Add DNS API support for aliyun

* Update README.md

* format

* format

* format

* format...

* format...

* format

* format

* fix bug

* fix bug

* code format

* code format

* fix bug

* just ok...

* fix bug

* fix bug

* fix bug

* change "echo" to "printf"

* fix bug

* code format

* fix bug."head -c" in function _ali_nonce not supported by solaris

* fix bug."head -c" in function _ali_nonce not supported by solaris

* format

* fix bug._ali_nonce not work on solaris

* fix bug. _ali_nonce not work on solaris

* fix bug. _ali_nonce not work on solaris

* add aliyun.com to README.md
2016-11-24 21:49:45 +08:00
neil
8b1fb3cb0c Dev (#419)
* fix CI

* fix ci

* fix ci
2016-11-24 14:13:23 +08:00
neil
9e04222ee6 fix ci 2016-11-24 13:58:14 +08:00
neil
72349507c4 fix ci 2016-11-24 13:45:00 +08:00
neil
79db8daddd fix CI 2016-11-24 13:39:46 +08:00
neil
b967f83f20 Merge pull request #418 from Neilpang/dev
fix ci, remove NGROK_TOKEN_OSX
2016-11-23 22:51:55 +08:00
neilpang
74a7592b4b fix ci, remove NGROK_TOKEN_OSX 2016-11-23 22:07:24 +08:00
neil
486f23538f Merge pull request #416 from Neilpang/dev
add OSX test to CI
2016-11-23 22:04:22 +08:00
neilpang
df86ff2191 fix ci 2016-11-23 21:17:51 +08:00
neilpang
41266f05e9 fix CI 2016-11-23 21:01:47 +08:00
neilpang
d2aa331838 fix ci 2016-11-23 20:46:11 +08:00
neilpang
670cb9d223 fix ci 2016-11-23 20:35:47 +08:00
neilpang
a205762bf0 fix ci 2016-11-23 20:21:43 +08:00
neilpang
2ffab66d97 fix ci 2016-11-23 20:01:40 +08:00
neilpang
10a6aec998 fix ci 2016-11-23 19:48:14 +08:00
neil
7cbe31baad fix ci 2016-11-23 18:51:49 +08:00
neil
8a09dc1b9b fix ci 2016-11-23 18:50:34 +08:00
neil
fa6e174651 fix ci 2016-11-23 13:59:15 +08:00
neil
8dee328eae fix ci 2016-11-23 13:53:44 +08:00
neil
340155e6a6 fix ci 2016-11-23 13:51:01 +08:00
neil
7fe19a030a fix osx ci 2016-11-23 13:39:27 +08:00
neil
11e0ccdc91 fix ci 2016-11-23 13:35:30 +08:00
neil
e55b2f4f8d fix ci 2016-11-23 13:18:29 +08:00
neilpang
d78c1f695e fix ci 2016-11-22 23:10:41 +08:00
neilpang
cfbb3e86b3 fix ci 2016-11-22 22:52:08 +08:00
neilpang
fa6234e417 add NGROK_TOKEN_OSX 2016-11-22 22:37:48 +08:00
neilpang
9eeae9ad7e fix ch 2016-11-22 22:28:29 +08:00
neilpang
28688488ff fix ci 2016-11-22 22:21:51 +08:00
neilpang
41d804719f fix ci 2016-11-22 22:10:29 +08:00
neilpang
bc18168662 fix ci 2016-11-22 22:06:19 +08:00
neilpang
1fadae82c7 fix ci 2016-11-22 22:03:59 +08:00
neilpang
791c62ca64 fix ci 2016-11-22 22:02:10 +08:00
neilpang
4441a6ff59 support osx CI 2016-11-22 21:59:40 +08:00
neil
63a7002477 Merge pull request #415 from Neilpang/dev
support OPENSSL_BIN and "--openssl-bin"
2016-11-22 21:50:30 +08:00
neilpang
a746139c53 support OPENSSL_BIN and "--openssl-bin" 2016-11-22 21:43:42 +08:00
neil
697a060132 Merge pull request #413 from Neilpang/dev
refactor HTTPS_INSECURE
2016-11-21 21:04:47 +08:00
neilpang
7834c25253 refactor HTTPS_INSECURE 2016-11-21 20:56:50 +08:00
neil
2e7cbfcff5 Support AWS Route53 domain API
Support AWS Route53 domain API
2016-11-20 23:31:11 +08:00
neilpang
5b771039fc Support AWS Route53 api 2016-11-20 23:21:07 +08:00
neilpang
2f1bc5864f fix format 2016-11-20 23:09:57 +08:00
neilpang
16d79ebaac fix format 2016-11-20 23:04:28 +08:00
neilpang
e009ec8b93 Support AWS Route53 api 2016-11-20 22:57:07 +08:00
neil
738ece513f Merge pull request #404 from Neilpang/dev
fix ngrok
2016-11-19 09:45:41 +08:00
neilpang
5a7b7b51c5 fix ngrok 2016-11-18 21:40:03 +08:00
neil
5bba9bddfd Merge pull request #403 from Neilpang/dev
fix egrep performance
2016-11-18 20:27:29 +08:00
neilpang
a3c0c7546d fix egrep performance 2016-11-18 20:14:08 +08:00
neil
05d7ae4efa Merge pull request #402 from Neilpang/dev
Dev
2016-11-18 20:04:48 +08:00
neilpang
44483dba21 fix format 2016-11-18 19:44:43 +08:00
neilpang
3498a5856a fix bug https://github.com/Neilpang/acme.sh/issues/401 2016-11-18 19:40:41 +08:00
neilpang
cd79b0343a Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2016-11-18 19:27:53 +08:00
neil
abba00d595 Merge pull request #400 from magna-z/powerdns_dns_api
Add functional in method dns_pdns_rm()
2016-11-18 12:28:35 +08:00
neilpang
88a8d7d901 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2016-11-17 20:14:55 +08:00
magna-z
d5c00071d3 Add functional in method dns_pdns_rm() 2016-11-17 14:52:00 +03:00
neil
c7a6cf5463 Merge pull request #397 from Neilpang/dev
add PULL_REQUEST_TEMPLATE template
2016-11-17 13:46:54 +08:00
neil
2ce2a15fc6 add PULL_REQUEST_TEMPLATE template 2016-11-17 13:40:10 +08:00
neil
ce4be4e91e fix _exists 2016-11-17 13:20:20 +08:00
neil
82dc2244c0 fix _exists for busybox 2016-11-17 13:17:29 +08:00
neilpang
ab45b7783f fix format 2016-11-17 00:25:40 +08:00
neilpang
4a56b2406b fix check email 2016-11-17 00:22:45 +08:00
neil
e0cd2cdb9c Merge pull request #396 from Neilpang/dev
fix _exists
2016-11-16 23:55:44 +08:00
neilpang
7575094cf3 fix _exists 2016-11-16 23:53:32 +08:00
neil
40a3ae04b6 Merge pull request #393 from Neilpang/dev
Dev
2016-11-16 23:22:11 +08:00
neilpang
ac26f84170 fix shfmt 2016-11-16 22:53:59 +08:00
neilpang
fa574fe833 fix shfmt 2016-11-16 22:44:39 +08:00
neilpang
9a6e18ce80 fix shfmt 2016-11-16 22:37:03 +08:00
neilpang
8f9034fc8b fix shfmt 2016-11-16 22:28:33 +08:00
neilpang
3e5b102445 fix error message for nc 2016-11-16 22:20:47 +08:00
neil
d8b1a8d439 Merge pull request #392 from Neilpang/dev
minor, message typo
2016-11-16 20:33:08 +08:00
neilpang
54ae008dd7 minor, message typo 2016-11-16 19:45:00 +08:00
neil
9c1747581f Update README.md 2016-11-16 13:10:56 +08:00
neil
ae4f7b6d7a Merge pull request #389 from Neilpang/dev
run acmetest project in CI
2016-11-15 22:10:32 +08:00
neilpang
c947322a69 sudo for travis 2016-11-15 21:49:35 +08:00
neil
14db45215f Merge pull request #388 from noplanman/documentation_cleanup
Documentation cleanup
2016-11-15 21:48:15 +08:00
Armando Lüscher
d20831e41a Update DNS API readme 2016-11-15 14:43:15 +01:00
Armando Lüscher
1bb902984b Clean up readme. 2016-11-15 14:13:58 +01:00
neilpang
09f1c58872 test ngrok 2016-11-15 19:45:04 +08:00
neilpang
7f944c2c8b test ngrok 2016-11-15 19:38:28 +08:00
neilpang
1c02b85802 test ngrok 2016-11-15 19:29:02 +08:00
neilpang
a2801649b4 test ngrok 2016-11-15 19:24:08 +08:00
neilpang
15777732d3 test ngrok 2016-11-15 19:20:41 +08:00
neilpang
b875037150 check NGROK_BIN 2016-11-15 17:38:35 +08:00
neil
a6d583cb5e Merge pull request #387 from Neilpang/master
sync
2016-11-15 17:32:55 +08:00
neil
9882f3429a Update README.md 2016-11-15 17:28:15 +08:00
neil
29d47c4de2 Merge pull request #341 from philfry/master
nsupdate
2016-11-15 17:23:41 +08:00
Philippe Kueck
ce38ecb966 merge with upstream 2016-11-14 15:59:42 +01:00
Philippe Kueck
13ffa17048 add documentation for dns_nsupdate 2016-11-14 15:56:07 +01:00
neilpang
a387682dfb Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2016-11-14 22:11:24 +08:00
neilpang
f6ed197cd3 run acmetest in CI 2016-11-14 22:11:05 +08:00
Philippe Kueck
243593cdaa fix warnings and remove unused ${tmp} variable 2016-11-14 14:06:30 +01:00
neil
1e2d559859 Merge pull request #383 from Neilpang/dev
fix 'sed -i' permissions on PVE
2016-11-14 17:52:29 +08:00
neil
20ea859183 fix 'sed -i' permissions on PVE 2016-11-14 17:47:22 +08:00
neil
86b24ea059 Merge pull request #381 from Neilpang/dev
Dev
2016-11-13 21:50:07 +08:00
neilpang
07af42476d change default user agent 2016-11-13 21:47:58 +08:00
neilpang
87edf71e93 fast_finish: true 2016-11-12 18:39:26 +08:00
neil
e3ea2ed420 Merge pull request #379 from Neilpang/dev
Dev
2016-11-12 18:30:02 +08:00
neilpang
8f9a1881a4 v2.6.5, support shellcheck and shfmt 2016-11-12 18:28:17 +08:00
neilpang
a8c6111197 fix shellcheck warnings 2016-11-12 11:45:30 +08:00
neilpang
3de8570022 fix shellcheck warnings. 2016-11-12 11:40:30 +08:00
neilpang
a0311b0134 fix for shellcheck warnings 2016-11-12 11:35:19 +08:00
neilpang
158a628c0e fix CI 2016-11-12 11:16:40 +08:00
neilpang
422e5026d6 fix shellcheck warnings 2016-11-12 11:13:40 +08:00
neilpang
797cbb9b20 fix shellcheck warnings 2016-11-12 11:05:05 +08:00
neilpang
be68fbd4f5 fix for alpine 2016-11-12 10:58:20 +08:00
neilpang
e440223b40 fix shellcheck warnings 2016-11-12 00:50:44 +08:00
neilpang
5766250288 fix CI 2016-11-12 00:31:24 +08:00
neilpang
870274ad9d fix CI 2016-11-12 00:25:15 +08:00
neilpang
9d6abcd9be fix CI 2016-11-12 00:23:07 +08:00
neilpang
432771dfe3 add shellcheck to CI 2016-11-12 00:19:59 +08:00
neilpang
69925ce823 fix shellcheck warnings. 2016-11-12 00:09:45 +08:00
neilpang
e9f9f515bd fix shellcheck warnings. 2016-11-12 00:06:34 +08:00
neilpang
efd96153d8 minor fix log message. 2016-11-11 23:52:02 +08:00
neilpang
c7b8f223ee fix for solaris tr 2016-11-11 23:48:27 +08:00
neilpang
a0636d5a87 fix shellcheck warnings. 2016-11-11 23:34:21 +08:00
neilpang
c7b16249b8 fix shellcheck warnings 2016-11-11 23:30:14 +08:00
neilpang
031e885e4d fix shellcheck warnings 2016-11-11 22:36:16 +08:00
neilpang
796e2cc156 fix shellcheck warnings 2016-11-11 22:32:11 +08:00
neilpang
7af784adce fix shellcheck warnings 2016-11-11 22:30:55 +08:00
neilpang
a988a91e2e fix shfmt warnings 2016-11-11 22:14:21 +08:00
neilpang
a8b564fa64 typo 2016-11-11 22:10:14 +08:00
neilpang
b97e140389 fix shfmt warnings 2016-11-11 22:07:49 +08:00
neilpang
e51bef6d12 fix shellcheck warnings. 2016-11-11 22:00:15 +08:00
neilpang
4bd31f4967 fix shellcheck warnings 2016-11-11 21:47:24 +08:00
neilpang
7ff7a7c527 fix shellcheck warnning 2016-11-11 21:31:16 +08:00
neilpang
c4a375b3a5 fix shellcheck warnings. 2016-11-11 21:22:48 +08:00
neilpang
e3698edd19 fix shellcheck warnings 2016-11-11 21:15:48 +08:00
neilpang
e591d5cfe4 fix shellcheck warnings 2016-11-11 21:13:33 +08:00
Philippe Kueck
54d61bdc4a - get rid of bash-only syntax like ${foo:-bar}
- use sh instead of bash
- remove redundant functions _info, _err, _debug and _debug2
- get rid of mktemp, pipe commands directly to nsupdate
2016-10-26 16:14:47 +02:00
Philippe Kueck
2d279c4c5c add nsupdate to sample config 2016-10-26 11:57:45 +02:00
Philippe Kueck
0fb206fe15 add nsupdate script for dns-01 2016-10-26 11:52:26 +02:00
20 changed files with 1736 additions and 623 deletions

9
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,9 @@
<!--
Do NOT send pull request to `master` branch.
Please send to `dev` branch instead.
Any PR to `master` branch will NOT be merged.
-->

View File

@@ -1,11 +1,54 @@
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)
language: shell
sudo: required
os:
- linux
- osx
env:
global:
- SHFMT_URL=https://github.com/mvdan/sh/releases/download/v0.4.0/shfmt_v0.4.0_linux_amd64
addons:
apt:
sources:
- debian-sid # Grab shellcheck from the Debian repo (o_O)
packages:
- shellcheck
install:
- if [ "$TRAVIS_OS_NAME" = 'osx' ]; then
brew update && brew install openssl;
brew info openssl;
ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/;
ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/;
ln -s /usr/local/Cellar/openssl/1.0.2j/bin/openssl /usr/local/openssl;
_old_path="$PATH";
echo "PATH=$PATH";
export PATH="";
export OPENSSL_BIN="/usr/local/openssl";
openssl version 2>&1 || true;
$OPENSSL_BIN version 2>&1 || true;
export PATH="$_old_path";
fi
script:
- echo "TEST_LOCAL=$TEST_LOCAL"
- echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)"
- command -V openssl && openssl version
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then curl -sSL $SHFMT_URL -o ~/shfmt ; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then chmod +x ~/shfmt ; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then ~/shfmt -l -w -i 2 . ; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then git diff --exit-code && echo "shfmt OK" ; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -V ; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck **/*.sh && echo "shellcheck OK" ; fi
- cd ..
- git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest
- if [ "$TRAVIS_OS_NAME" = "linux" -a "$NGROK_TOKEN" ]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" -a "$NGROK_TOKEN" ]; then sudo NGROK_TOKEN="$NGROK_TOKEN" OPENSSL_BIN="$OPENSSL_BIN" ./letest.sh ; fi
matrix:
fast_finish: true

216
README.md
View File

@@ -1,21 +1,23 @@
# 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.
- Bash, dash and sh compatible.
- Full ACME protocol implementation.
- Simple, powerful and very easy to use. You only need 3 minutes to learn it.
- Bash, dash and sh compatible.
- Simplest shell script for Let's Encrypt free certificate client.
- Purely written in Shell with no dependencies on python or Let's Encrypt official client.
- Just one script, to issue, renew and install your certificates automatically.
- Purely written in Shell with no dependencies on python or the official Let's Encrypt client.
- Just one script to issue, renew and install your certificates automatically.
- DOES NOT require `root/sudoer` access.
It's probably the `easiest&smallest&smartest` shell script to automatically issue & renew the free certificates from Let's Encrypt.
Wiki: https://github.com/Neilpang/acme.sh/wiki
# [中文说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E)
#Tested OS
# Tested OS
| NO | Status| Platform|
|----|-------|---------|
|1|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/ubuntu-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Ubuntu
@@ -37,42 +39,41 @@ Wiki: https://github.com/Neilpang/acme.sh/wiki
|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
|20|[![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)|Mac OSX
For all build statuses, check our [daily build project](https://github.com/Neilpang/acmetest):
For all build statuses, check our [daily build project](https://github.com/Neilpang/acmetest):
https://github.com/Neilpang/acmetest
# Supported Mode
1. Webroot mode
2. Standalone mode
3. Apache mode
4. Dns mode
# Supported modes
- Webroot mode
- Standalone mode
- Apache mode
- DNS mode
# 1. How to install
### 1. Install online:
### 1. Install online
Check this project: https://github.com/Neilpang/get.acme.sh
```bash
curl https://get.acme.sh | sh
```
Or:
```bash
wget -O - https://get.acme.sh | sh
```
### 2. Or, Install from git:
### 2. Or, Install from git
Clone this project:
Clone this project and launch installation:
```bash
git clone https://github.com/Neilpang/acme.sh.git
@@ -82,14 +83,14 @@ cd ./acme.sh
You `don't have to be root` then, although `it is recommended`.
Advanced Installation: https://github.com/Neilpang/acme.sh/wiki/How-to-install
Advanced Installation: https://github.com/Neilpang/acme.sh/wiki/How-to-install
The installer will perform 3 actions:
1. Create and copy `acme.sh` to your home dir (`$HOME`): `~/.acme.sh/`.
All certs will be placed in this folder.
2. Create alias for: `acme.sh=~/.acme.sh/acme.sh`.
3. Create everyday cron job to check and renew the cert if needed.
1. Create and copy `acme.sh` to your home dir (`$HOME`): `~/.acme.sh/`.
All certs will be placed in this folder too.
2. Create alias for: `acme.sh=~/.acme.sh/acme.sh`.
3. Create daily cron job to check and renew the certs if needed.
Cron entry example:
@@ -97,18 +98,17 @@ Cron entry example:
0 0 * * * "/home/user/.acme.sh"/acme.sh --cron --home "/home/user/.acme.sh" > /dev/null
```
After the installation, you must close current terminal and reopen again to make the alias take effect.
After the installation, you must close the current terminal and reopen it to make the alias take effect.
Ok, you are ready to issue certs now.
Ok, you are ready to issue cert now.
Show help message:
```
root@v1:~# acme.sh -h
```
# 2. Just issue a cert:
# 2. Just issue a cert
**Example 1:** Single domain.
@@ -119,56 +119,59 @@ acme.sh --issue -d example.com -w /home/wwwroot/example.com
**Example 2:** Multiple domains in the same cert.
```bash
acme.sh --issue -d example.com -d www.example.com -d cp.example.com -w /home/wwwroot/example.com
acme.sh --issue -d example.com -d www.example.com -d cp.example.com -w /home/wwwroot/example.com
```
The parameter `/home/wwwroot/example.com` is the web root folder. You **MUST** have `write access` to this folder.
Second argument **"example.com"** is the main domain you want to issue cert for.
You must have at least a domain there.
Second argument **"example.com"** is the main domain you want to issue the cert for.
You must have at least one domain there.
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/example.com/`
Generated/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 automatically every **60** days.
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
# 3. Install the 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/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.
After you issue a cert, you probably want to install/copy the cert to your Apache/Nginx 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 the future.
**nginx** example
**Apache** example:
```bash
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"
--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 force-reload"
```
**apache** example
**Nginx** 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"
--keypath /path/to/keyfile/in/nginx/key.pem \
--fullchainpath /path/to/fullchain/nginx/cert.pem \
--reloadcmd "service nginx force-reload"
```
Only the domain is required, all the other parameters are optional.
Install/copy the issued cert/key to the production apache or nginx path.
The ownership and permission info of existing files are preserved. You may want to precreate the files to have defined ownership and permission.
Install/copy the issued 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 restarted automatically by the command: `service apache2 restart` or `service nginx restart`.
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
**(requires you be root/sudoer, or you have permission to listen tcp 80 port)**
**(requires you to be root/sudoer or have permission to listen on port 80 (TCP))**
The tcp `80` port **MUST** be free to listen, otherwise you will be prompted to free the `80` port and try again.
Port `80` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again.
```bash
acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com
@@ -176,13 +179,14 @@ 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
# 5. Use Standalone tls server to issue cert
**(requires you be root/sudoer, or you have permission to listen tcp 443 port)**
# 5. Use Standalone TLS server to issue cert
**(requires you to be root/sudoer or have permission to listen on port 443 (TCP))**
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.
Port `443` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again.
```bash
acme.sh --issue --tls -d example.com -d www.example.com -d cp.example.com
@@ -190,31 +194,33 @@ 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
# 6. Use Apache mode
**(requires you be root/sudoer, since it is required to interact with apache server)**
**(requires you to be root/sudoer, since it is required to interact with Apache server)**
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 should use Apache mode instead. This mode doesn't write any files to your web root folder.
Just set string "apache" as the second argument, 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.
```
acme.sh --issue --apache -d example.com -d www.example.com -d user.example.com
acme.sh --issue --apache -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
# 7. Use DNS mode:
Support the `dns-01` challenge.
```bash
acme.sh --issue --dns -d example.com -d www.example.com -d user.example.com
acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com
```
You should get the output like below:
You should get an output like below:
```
Add the following txt record:
@@ -226,7 +232,6 @@ Domain:_acme-challenge.www.example.com
Txt value:9ihDbjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Please add those txt records to the domains. Waiting for the dns to take effect.
```
Then just rerun with `renew` argument:
@@ -237,52 +242,58 @@ acme.sh --renew -d example.com
Ok, it's finished.
# 8. Automatic DNS API integration
If your DNS provider supports API access, we can use API to automatically issue the certs.
If your DNS provider supports API access, we can use that API to automatically issue the certs.
You don't have do anything manually!
You don't have to do anything manually!
### Currently acme.sh supports:
1. Cloudflare.com API
2. Dnspod.cn API
3. Cloudxns.com API
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. 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
1. CloudFlare.com API
1. DNSPod.cn API
1. CloudXNS.com API
1. GoDaddy.com API
1. OVH, kimsufi, soyoustart and runabove API
1. AWS Route 53
1. PowerDNS.com API
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.)
1. LuaDNS.com API
1. DNSMadeEasy.com API
1. nsupdate API
1. aliyun.com(阿里云) API
1. ISPConfig 3.1 API
1. Alwaysdata.com API
##### More APIs are coming soon...
**More APIs coming soon...**
If your DNS provider is not on the supported list above, you can write your own script API easily. If you do please consider submitting a [Pull Request](https://github.com/Neilpang/acme.sh/pulls) and contribute 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.
For more details: [How to use dns api](dnsapi)
For more details: [How to use DNS API](dnsapi)
# 9. Issue ECC certificate:
`Let's Encrypt` now can issue **ECDSA** certificates.
# 9. Issue ECC certificates
And we also support it.
`Let's Encrypt` can now issue **ECDSA** certificates.
And we support them too!
Just set the `length` parameter with a prefix `ec-`.
For example:
### Single domain ECC cerfiticate:
### Single domain ECC cerfiticate
```bash
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 --keylength ec-256
```
SAN multi domain ECC certificate:
### SAN multi domain ECC certificate
```bash
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.
@@ -294,40 +305,48 @@ Valid values are:
3. **ec-521 (secp521r1, "ECDSA P-521", which is not supported by Let's Encrypt yet.)**
# 10. How to renew the cert
# 10. How to renew the issued certs
No, you don't need to renew the certs manually. All the certs will be renewed automatically every **60** 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 example.com --force
acme.sh --renew -d example.com --force
```
or, for ECC cert:
```
acme.sh --renew -d example.com --force --ecc
acme.sh --renew -d example.com --force --ecc
```
# 11. How to upgrade `acme.sh`
acme.sh is in developing, it's strongly recommended to use the latest code.
acme.sh is in constant development, so it's strongly recommended to use the latest code.
You can update acme.sh to the latest code:
```
acme.sh --upgrade
```
You can enable auto upgrade:
You can also enable auto upgrade:
```
acme.sh --upgrade --auto-upgrade
acme.sh --upgrade --auto-upgrade
```
Then **acme.sh** will keep up to date automatically.
Then **acme.sh** will be kept up to date automatically.
Disable auto upgrade:
```
acme.sh --upgrade --auto-upgrade 0
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
@@ -339,22 +358,25 @@ Speak ACME language using shell, directly to "Let's Encrypt".
TODO:
# Acknowledgment
# Acknowledgments
1. Acme-tiny: https://github.com/diafygi/acme-tiny
2. ACME protocol: https://github.com/ietf-wg-acme/acme
3. Certbot: https://github.com/certbot/certbot
# License & Others
License is GPLv3
Please Star and Fork me.
[Issues](https://github.com/Neilpang/acme.sh/issues) and [pull requests](https://github.com/Neilpang/acme.sh/pulls) are welcomed.
[Issues](https://github.com/Neilpang/acme.sh/issues) and [pull requests](https://github.com/Neilpang/acme.sh/pulls) are welcome.
# Donate
1. PayPal: donate@acme.sh
1. PayPal: donate@acme.sh
[Donate List](https://github.com/Neilpang/acme.sh/wiki/Donate-list)

450
acme.sh

File diff suppressed because it is too large Load Diff

View File

@@ -1,99 +1,80 @@
# How to use dns api
# How to use DNS API
## Use CloudFlare domain api to automatically issue cert
## 1. Use CloudFlare domain API to automatically issue cert
For now, we support clourflare integeration.
First you need to login to your clourflare account to get your api key.
First you need to login to your CloudFlare account to get your API key.
```
export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export CF_Email="xxxx@sss.com"
```
Ok, let's issue cert now:
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_cf -d example.com -d www.example.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` and will be reused when needed.
## 2. Use DNSPod.cn domain API to automatically issue cert
## Use Dnspod.cn domain api to automatically issue cert
For now, we support dnspod.cn integeration.
First you need to login to your dnspod.cn account to get your api key and key id.
First you need to login to your DNSPod account to get your API Key and ID.
```
export DP_Id="1234"
export DP_Key="sADDsdasdgdsf"
```
Ok, let's issue cert now:
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_dp -d example.com -d www.example.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` and will be reused when needed.
## Use Cloudxns.com domain api to automatically issue cert
## 3. Use CloudXNS.com domain API to automatically issue cert
For now, we support Cloudxns.com integeration.
First you need to login to your Cloudxns.com account to get your api key and key secret.
First you need to login to your CloudXNS account to get your API Key and Secret.
```
export CX_Key="1234"
export CX_Secret="sADDsdasdgdsf"
```
Ok, let's issue cert now:
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_cx -d example.com -d www.example.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` and will be reused when needed.
## Use Godaddy.com domain api to automatically issue cert
## 4. Use GoDaddy.com domain API to automatically issue cert
We support Godaddy integration.
First you need to login to your Godaddy account to get your api key and api secret.
First you need to login to your GoDaddy account to get your API Key and Secret.
https://developer.godaddy.com/keys/
Please Create a Production key, instead of a Test key.
Please create a Production key, instead of a Test key.
```
export GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export GD_Secret="asdfsdafdsfdsfdsfdsfdsafd"
```
Ok, let's issue cert now:
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_gd -d example.com -d www.example.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` and will be reused when needed.
## Use PowerDNS embedded api to automatically issue cert
We support PowerDNS embedded API integration.
## 5. Use PowerDNS embedded API to automatically issue cert
First you need to enable api and set your api-token in PowerDNS configuration.
First you need to login to your PowerDNS account to enable the API and set your API-Token in the configuration.
https://doc.powerdns.com/md/httpapi/README/
@@ -102,75 +83,197 @@ 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:
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_pdns -d example.com -d www.example.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` and will be reused when needed.
## Use OVH/kimsufi/soyoustart/runabove API
## 6. Use OVH/kimsufi/soyoustart/runabove API to automatically issue cert
https://github.com/Neilpang/acme.sh/wiki/How-to-use-OVH-domain-api
# Use custom api
If your api is not supported yet, you can write your own dns api.
Let's assume you want to name it 'myapi',
1. Create a bash script named `~/.acme.sh/dns_myapi.sh`,
2. In the script, you must have a function named `dns_myapi_add()`. Which will be called by acme.sh to add dns records.
3. Then you can use your api to issue cert like:
## 7. Use nsupdate to automatically issue cert
First, generate a key for updating the zone
```
acme.sh --issue --dns dns_myapi -d example.com -d www.example.com
b=$(dnssec-keygen -a hmac-sha512 -b 512 -n USER -K /tmp foo)
cat > /etc/named/keys/update.key <<EOF
key "update" {
algorithm hmac-sha512;
secret "$(awk '/^Key/{print $2}' /tmp/$b.private)";
};
EOF
rm -f /tmp/$b.{private,key}
```
For more details, please check our sample script: [dns_myapi.sh](dns_myapi.sh)
Include this key in your named configuration
```
include "/etc/named/keys/update.key";
```
# Use lexicon dns api
Next, configure your zone to allow dynamic updates.
https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api
Depending on your named version, use either
```
zone "example.com" {
type master;
allow-update { key "update"; };
};
```
or
```
zone "example.com" {
type master;
update-policy {
grant update subdomain example.com.;
};
}
```
## Use LuaDNS domain API
Finally, make the DNS server and update Key available to `acme.sh`
```
export NSUPDATE_SERVER="dns.example.com"
export NSUPDATE_KEY="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=="
```
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_nsupdate -d example.com -d www.example.com
```
The `NSUPDATE_SERVER` and `NSUPDATE_KEY` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 8. 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
acme.sh --issue --dns dns_lua -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.
The `LUA_Key` and `LUA_Email` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## Use DNSMadeEasy domain API
## 9. 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
acme.sh --issue --dns dns_me -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.
The `ME_Key` and `ME_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 10. Use Amazon Route53 domain API
https://github.com/Neilpang/acme.sh/wiki/How-to-use-Amazon-Route53-API
```
export AWS_ACCESS_KEY_ID=XXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXX
```
To issue a cert:
```
acme.sh --issue --dns dns_aws -d example.com -d www.example.com
```
The `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 11. Use Aliyun domain API to automatically issue cert
First you need to login to your Aliyun account to get your API key.
[https://ak-console.aliyun.com/#/accesskey](https://ak-console.aliyun.com/#/accesskey)
```
export Ali_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export Ali_Secret="jlsdflanljkljlfdsaklkjflsa"
```
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_ali -d example.com -d www.example.com
```
The `Ali_Key` and `Ali_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 12. Use ISPConfig 3.1 API
This only works for ISPConfig 3.1 (and newer).
Create a Remote User in the ISPConfig Control Panel. The Remote User must have access to at least `DNS zone functions` and `DNS txt functions`.
```
export ISPC_User="xxx"
export ISPC_Password="xxx"
export ISPC_Api="https://ispc.domain.tld:8080/remote/json.php"
export ISPC_Api_Insecure=1
```
If you have installed ISPConfig on a different port, then alter the 8080 accordingly.
Leaver ISPC_Api_Insecure set to 1 if you have not a valid ssl cert for your installation. Change it to 0 if you have a valid ssl cert.
To issue a cert:
```
acme.sh --issue --dns dns_ispconfig -d example.com -d www.example.com
```
The `ISPC_User`, `ISPC_Password`, `ISPC_Api`and `ISPC_Api_Insecure` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 13. Use Alwaysdata domain API
First you need to login to your Alwaysdata account to get your API Key.
```sh
export AD_API_KEY="myalwaysdataapikey"
```
Ok, let's issue a cert now:
```sh
acme.sh --issue --dns dns_ad -d example.com -d www.example.com
```
The `AD_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused
when needed.
# Use custom API
If your API is not supported yet, you can write your own DNS API.
Let's assume you want to name it 'myapi':
1. Create a bash script named `~/.acme.sh/dns_myapi.sh`,
2. In the script you must have a function named `dns_myapi_add()` which will be called by acme.sh to add the DNS records.
3. Then you can use your API to issue cert like this:
```
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

147
dnsapi/dns_ad.sh Normal file
View File

@@ -0,0 +1,147 @@
#!/usr/bin/env sh
#
#AD_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje"
#This is the Alwaysdata api wrapper for acme.sh
#
#Author: Paul Koppen
#Report Bugs here: https://github.com/wpk-/acme.sh
AD_API_URL="https://$AD_API_KEY:@api.alwaysdata.com/v1"
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_ad_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$AD_API_KEY" ]; then
AD_API_KEY=""
_err "You didn't specify the AD api key yet."
_err "Please create you key and try again."
return 1
fi
_saveaccountconf AD_API_KEY "$AD_API_KEY"
_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"
_ad_tmpl_json="{\"domain\":$_domain_id,\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\"}"
if _ad_rest POST "record/" "$_ad_tmpl_json" && [ -z "$response" ]; then
_info "txt record updated success."
return 0
fi
return 1
}
#fulldomain txtvalue
dns_ad_rm() {
fulldomain=$1
txtvalue=$2
_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"
_ad_rest GET "record/?domain=$_domain_id&name=$_sub_domain"
if [ -n "$response" ]; then
record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1)
_debug record_id "$record_id"
if [ -z "$record_id" ]; then
_err "Can not get record id to remove."
return 1
fi
if _ad_rest DELETE "record/$record_id/" && [ -z "$response" ]; then
_info "txt record deleted success."
return 0
fi
_debug response "$response"
return 1
fi
return 1
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
# _domain_id=12345
_get_root() {
domain=$1
i=2
p=1
if _ad_rest GET "domain/"; then
response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
hostedzone="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$h\".*}")"
if [ "$hostedzone" ]; then
_domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
return 1
fi
p=$i
i=$(_math "$i" + 1)
done
fi
return 1
}
#method uri qstr data
_ad_rest() {
mtd="$1"
ep="$2"
data="$3"
_debug mtd "$mtd"
_debug ep "$ep"
export _H1="Accept: application/json"
export _H2="Content-Type: application/json"
if [ "$mtd" != "GET" ]; then
# both POST and DELETE.
_debug data "$data"
response="$(_post "$data" "$AD_API_URL/$ep" "" "$mtd")"
else
response="$(_get "$AD_API_URL/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

187
dnsapi/dns_ali.sh Normal file
View File

@@ -0,0 +1,187 @@
#!/usr/bin/env sh
Ali_API="https://alidns.aliyuncs.com/"
#Ali_Key="LTqIA87hOKdjevsf5"
#Ali_Secret="0p5EYueFNq501xnCPzKNbx6K51qPH2"
#Usage: dns_ali_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_ali_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then
Ali_Key=""
Ali_Secret=""
_err "You don't specify aliyun api key and secret yet."
return 1
fi
#save the api key and secret to the account conf file.
_saveaccountconf Ali_Key "$Ali_Key"
_saveaccountconf Ali_Secret "$Ali_Secret"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
return 1
fi
_debug "Add record"
_add_record_query "$_domain" "$_sub_domain" "$txtvalue" && _ali_rest "Add record"
}
dns_ali_rm() {
fulldomain=$1
_clean
}
#################### Private functions below ##################################
_get_root() {
domain=$1
i=2
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1
fi
_describe_records_query "$h"
if ! _ali_rest "Get root" "ignore"; then
return 1
fi
if _contains "$response" "PageNumber"; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_debug _sub_domain "$_sub_domain"
_domain="$h"
_debug _domain "$_domain"
return 0
fi
p="$i"
i=$(_math "$i" + 1)
done
return 1
}
_ali_rest() {
signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(_hex "$Ali_Secret&")" | _base64)
signature=$(_ali_urlencode "$signature")
url="$Ali_API?$query&Signature=$signature"
if ! response="$(_get "$url")"; then
_err "Error <$1>"
return 1
fi
if [ -z "$2" ]; then
message="$(printf "%s" "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")"
if [ -n "$message" ]; then
_err "$message"
return 1
fi
fi
_debug2 response "$response"
return 0
}
_ali_urlencode() {
_str="$1"
_str_len=${#_str}
_u_i=1
while [ "$_u_i" -le "$_str_len" ]; do
_str_c="$(printf "%s" "$_str" | cut -c "$_u_i")"
case $_str_c in [a-zA-Z0-9.~_-])
printf "%s" "$_str_c"
;;
*)
printf "%%%02X" "'$_str_c"
;;
esac
_u_i="$(_math "$_u_i" + 1)"
done
}
_ali_nonce() {
#_head_n 1 </dev/urandom | _digest "sha256" hex | cut -c 1-31
#Not so good...
date +"%s%N"
}
_check_exist_query() {
query=''
query=$query'AccessKeyId='$Ali_Key
query=$query'&Action=DescribeDomainRecords'
query=$query'&DomainName='$1
query=$query'&Format=json'
query=$query'&RRKeyWord=_acme-challenge'
query=$query'&SignatureMethod=HMAC-SHA1'
query=$query"&SignatureNonce=$(_ali_nonce)"
query=$query'&SignatureVersion=1.0'
query=$query'&Timestamp='$(_timestamp)
query=$query'&TypeKeyWord=TXT'
query=$query'&Version=2015-01-09'
}
_add_record_query() {
query=''
query=$query'AccessKeyId='$Ali_Key
query=$query'&Action=AddDomainRecord'
query=$query'&DomainName='$1
query=$query'&Format=json'
query=$query'&RR='$2
query=$query'&SignatureMethod=HMAC-SHA1'
query=$query"&SignatureNonce=$(_ali_nonce)"
query=$query'&SignatureVersion=1.0'
query=$query'&Timestamp='$(_timestamp)
query=$query'&Type=TXT'
query=$query'&Value='$3
query=$query'&Version=2015-01-09'
}
_delete_record_query() {
query=''
query=$query'AccessKeyId='$Ali_Key
query=$query'&Action=DeleteDomainRecord'
query=$query'&Format=json'
query=$query'&RecordId='$1
query=$query'&SignatureMethod=HMAC-SHA1'
query=$query"&SignatureNonce=$(_ali_nonce)"
query=$query'&SignatureVersion=1.0'
query=$query'&Timestamp='$(_timestamp)
query=$query'&Version=2015-01-09'
}
_describe_records_query() {
query=''
query=$query'AccessKeyId='$Ali_Key
query=$query'&Action=DescribeDomainRecords'
query=$query'&DomainName='$1
query=$query'&Format=json'
query=$query'&SignatureMethod=HMAC-SHA1'
query=$query"&SignatureNonce=$(_ali_nonce)"
query=$query'&SignatureVersion=1.0'
query=$query'&Timestamp='$(_timestamp)
query=$query'&Version=2015-01-09'
}
_clean() {
_check_exist_query "$_domain"
if ! _ali_rest "Check exist records" "ignore"; then
return 1
fi
records="$(echo "$response" -n | _egrep_o "\"RecordId\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")"
printf "%s" "$records" \
| while read -r record_id; do
_delete_record_query "$record_id"
_ali_rest "Delete record $record_id" "ignore"
done
}
_timestamp() {
date -u +"%Y-%m-%dT%H%%3A%M%%3A%SZ"
}

227
dnsapi/dns_aws.sh Normal file
View File

@@ -0,0 +1,227 @@
#!/usr/bin/env sh
#
#AWS_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
#AWS_SECRET_ACCESS_KEY="xxxxxxx"
#This is the Amazon Route53 api wrapper for acme.sh
AWS_HOST="route53.amazonaws.com"
AWS_URL="https://$AWS_HOST"
AWS_WIKI="https://github.com/Neilpang/acme.sh/wiki/How-to-use-Amazon-Route53-API"
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_aws_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then
AWS_ACCESS_KEY_ID=""
AWS_SECRET_ACCESS_KEY=""
_err "You don't specify aws route53 api key id and and api key secret yet."
_err "Please create you key and try again. see $(__green $AWS_WIKI)"
return 1
fi
if [ -z "$AWS_SESSION_TOKEN" ]; then
_saveaccountconf AWS_ACCESS_KEY_ID "$AWS_ACCESS_KEY_ID"
_saveaccountconf AWS_SECRET_ACCESS_KEY "$AWS_SECRET_ACCESS_KEY"
fi
_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"
_aws_tmpl_xml="<ChangeResourceRecordSetsRequest xmlns=\"https://route53.amazonaws.com/doc/2013-04-01/\"><ChangeBatch><Changes><Change><Action>UPSERT</Action><ResourceRecordSet><Name>$fulldomain</Name><Type>TXT</Type><TTL>300</TTL><ResourceRecords><ResourceRecord><Value>\"$txtvalue\"</Value></ResourceRecord></ResourceRecords></ResourceRecordSet></Change></Changes></ChangeBatch></ChangeResourceRecordSetsRequest>"
if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then
_info "txt record updated success."
return 0
fi
return 1
}
#fulldomain txtvalue
dns_aws_rm() {
fulldomain=$1
txtvalue=$2
_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"
_aws_tmpl_xml="<ChangeResourceRecordSetsRequest xmlns=\"https://route53.amazonaws.com/doc/2013-04-01/\"><ChangeBatch><Changes><Change><Action>DELETE</Action><ResourceRecordSet><ResourceRecords><ResourceRecord><Value>\"$txtvalue\"</Value></ResourceRecord></ResourceRecords><Name>$fulldomain.</Name><Type>TXT</Type><TTL>300</TTL></ResourceRecordSet></Change></Changes></ChangeBatch></ChangeResourceRecordSetsRequest>"
if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then
_info "txt record deleted success."
return 0
fi
return 1
}
#################### Private functions below ##################################
_get_root() {
domain=$1
i=2
p=1
if aws_rest GET "2013-04-01/hostedzone"; then
_debug "response" "$response"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1
fi
if _contains "$response" "<Name>$h.</Name>"; then
hostedzone="$(echo "$response" | sed 's/<HostedZone>/\n&/g' | _egrep_o "<HostedZone>.*?<Name>$h.<.Name>.*?<.HostedZone>")"
_debug hostedzone "$hostedzone"
if [ -z "$hostedzone" ]; then
_err "Error, can not get hostedzone."
return 1
fi
_domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "<Id>.*<.Id>" | head -n 1 | _egrep_o ">.*<" | tr -d "<>")
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
return 1
fi
p=$i
i=$(_math "$i" + 1)
done
fi
return 1
}
#method uri qstr data
aws_rest() {
mtd="$1"
ep="$2"
qsr="$3"
data="$4"
_debug mtd "$mtd"
_debug ep "$ep"
_debug qsr "$qsr"
_debug data "$data"
CanonicalURI="/$ep"
_debug2 CanonicalURI "$CanonicalURI"
CanonicalQueryString="$qsr"
_debug2 CanonicalQueryString "$CanonicalQueryString"
RequestDate="$(date -u +"%Y%m%dT%H%M%SZ")"
_debug2 RequestDate "$RequestDate"
#RequestDate="20161120T141056Z" ##############
export _H1="x-amz-date: $RequestDate"
aws_host="$AWS_HOST"
CanonicalHeaders="host:$aws_host\nx-amz-date:$RequestDate\n"
SignedHeaders="host;x-amz-date"
if [ -n "$AWS_SESSION_TOKEN" ]; then
export _H2="x-amz-security-token: $AWS_SESSION_TOKEN"
CanonicalHeaders="${CanonicalHeaders}x-amz-security-token:$AWS_SESSION_TOKEN\n"
SignedHeaders="${SignedHeaders};x-amz-security-token"
fi
_debug2 CanonicalHeaders "$CanonicalHeaders"
_debug2 SignedHeaders "$SignedHeaders"
RequestPayload="$data"
_debug2 RequestPayload "$RequestPayload"
Hash="sha256"
CanonicalRequest="$mtd\n$CanonicalURI\n$CanonicalQueryString\n$CanonicalHeaders\n$SignedHeaders\n$(printf "%s" "$RequestPayload" | _digest "$Hash" hex)"
_debug2 CanonicalRequest "$CanonicalRequest"
HashedCanonicalRequest="$(printf "$CanonicalRequest%s" | _digest "$Hash" hex)"
_debug2 HashedCanonicalRequest "$HashedCanonicalRequest"
Algorithm="AWS4-HMAC-SHA256"
_debug2 Algorithm "$Algorithm"
RequestDateOnly="$(echo "$RequestDate" | cut -c 1-8)"
_debug2 RequestDateOnly "$RequestDateOnly"
Region="us-east-1"
Service="route53"
CredentialScope="$RequestDateOnly/$Region/$Service/aws4_request"
_debug2 CredentialScope "$CredentialScope"
StringToSign="$Algorithm\n$RequestDate\n$CredentialScope\n$HashedCanonicalRequest"
_debug2 StringToSign "$StringToSign"
kSecret="AWS4$AWS_SECRET_ACCESS_KEY"
#kSecret="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY" ############################
_debug2 kSecret "$kSecret"
kSecretH="$(_hex "$kSecret")"
_debug2 kSecretH "$kSecretH"
kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)"
_debug2 kDateH "$kDateH"
kRegionH="$(printf "$Region%s" | _hmac "$Hash" "$kDateH" hex)"
_debug2 kRegionH "$kRegionH"
kServiceH="$(printf "$Service%s" | _hmac "$Hash" "$kRegionH" hex)"
_debug2 kServiceH "$kServiceH"
kSigningH="$(printf "aws4_request%s" | _hmac "$Hash" "$kServiceH" hex)"
_debug2 kSigningH "$kSigningH"
signature="$(printf "$StringToSign%s" | _hmac "$Hash" "$kSigningH" hex)"
_debug2 signature "$signature"
Authorization="$Algorithm Credential=$AWS_ACCESS_KEY_ID/$CredentialScope, SignedHeaders=$SignedHeaders, Signature=$signature"
_debug2 Authorization "$Authorization"
_H3="Authorization: $Authorization"
_debug _H3 "$_H3"
url="$AWS_URL/$ep"
if [ "$mtd" = "GET" ]; then
response="$(_get "$url")"
else
response="$(_post "$data" "$url")"
fi
_ret="$?"
if [ "$_ret" = "0" ]; then
if _contains "$response" "<ErrorResponse"; then
_err "Response error:$response"
return 1
fi
fi
return "$_ret"
}

View File

@@ -15,17 +15,25 @@ dns_cf_add() {
txtvalue=$2
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
CF_Key=""
CF_Email=""
_err "You don't specify cloudflare api key and email yet."
_err "Please create you key and try again."
return 1
fi
if ! _contains "$CF_Email" "@"; then
_err "It seems that the CF_Email=$CF_Email is not a valid email address."
_err "Please check and retry."
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
@@ -36,20 +44,18 @@ dns_cf_add() {
_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 "%s" "$response" | grep \"success\":true >/dev/null; then
_err "Error"
return 1
fi
count=$(printf "%s\n" "$response" | _egrep_o \"count\":[^,]* | cut -d : -f 2)
count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2)
_debug count "$count"
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 -- "%s" "$response" | grep $fulldomain >/dev/null; then
_info "Added, sleeping 10 seconds"
sleep 10
#todo: check if the record takes effect
if printf -- "%s" "$response" | grep "$fulldomain" >/dev/null; then
_info "Added, OK"
return 0
else
_err "Add txt record error."
@@ -59,14 +65,12 @@ 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 -n 1)
_debug "record_id" $record_id
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\"}"
if [ "$?" = "0" ]; then
_info "Updated, sleeping 10 seconds"
sleep 10
#todo: check if the record takes effect
_info "Updated, OK"
return 0
fi
_err "Update error"
@@ -75,13 +79,48 @@ dns_cf_add() {
}
#fulldomain
#fulldomain txtvalue
dns_cf_rm() {
fulldomain=$1
txtvalue=$2
_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"
_cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain&content=$txtvalue"
if ! printf "%s" "$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
_info "Don't need to remove."
else
record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1)
_debug "record_id" "$record_id"
if [ -z "$record_id" ]; then
_err "Can not get record id to remove."
return 1
fi
if ! _cf_rest DELETE "zones/$_domain_id/dns_records/$record_id"; then
_err "Delete record error."
return 1
fi
_contains "$response" '"success":true'
fi
}
#################### Private functions bellow ##################################
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
@@ -91,8 +130,9 @@ _get_root() {
domain=$1
i=2
p=1
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
@@ -102,17 +142,17 @@ _get_root() {
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 _contains "$response" "\"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)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
return 1
fi
p=$i
i=$(expr $i + 1)
i=$(_math "$i" + 1)
done
return 1
}
@@ -121,15 +161,15 @@ _cf_rest() {
m=$1
ep="$2"
data="$3"
_debug $ep
_debug "$ep"
_H1="X-Auth-Email: $CF_Email"
_H2="X-Auth-Key: $CF_Key"
_H3="Content-Type: application/json"
export _H1="X-Auth-Email: $CF_Email"
export _H2="X-Auth-Key: $CF_Key"
export _H3="Content-Type: application/json"
if [ "$data" ]; then
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$CF_Api/$ep" "" $m)"
response="$(_post "$data" "$CF_Api/$ep" "" "$m")"
else
response="$(_get "$CF_Api/$ep")"
fi

View File

@@ -17,24 +17,26 @@ dns_cx_add() {
txtvalue=$2
if [ -z "$CX_Key" ] || [ -z "$CX_Secret" ]; then
CX_Key=""
CX_Secret=""
_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
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
_err "Error get existing records."
@@ -42,9 +44,9 @@ dns_cx_add() {
fi
if [ "$count" = "0" ]; then
add_record $_domain $_sub_domain $txtvalue
add_record "$_domain" "$_sub_domain" "$txtvalue"
else
update_record $_domain $_sub_domain $txtvalue
update_record "$_domain" "$_sub_domain" "$txtvalue"
fi
if [ "$?" = "0" ]; then
@@ -56,7 +58,15 @@ dns_cx_add() {
#fulldomain
dns_cx_rm() {
fulldomain=$1
REST_API="$CX_Api"
if _get_root "$fulldomain"; then
record_id=""
existing_records "$_domain" "$_sub_domain"
if ! [ "$record_id" = "" ]; then
_rest DELETE "record/$record_id/$_domain_id" "{}"
_info "Deleted record ${fulldomain}"
fi
fi
}
#usage: root sub
@@ -67,20 +77,20 @@ existing_records() {
_debug "Getting txt records"
root=$1
sub=$2
count=0
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
return 0
fi
if printf "$response" | grep '"type":"TXT"' >/dev/null; then
if printf "%s" "$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 \")
record_id=$(printf "%s\n" "$seg" | _egrep_o '"record_id":"[^"]*"' | cut -d : -f 2 | tr -d \" | _head_n 1)
_debug record_id "$record_id"
return 0
fi
@@ -93,7 +103,7 @@ add_record() {
root=$1
sub=$2
txtvalue=$3
fulldomain=$sub.$root
fulldomain="$sub.$root"
_info "Adding record"
@@ -110,7 +120,7 @@ update_record() {
root=$1
sub=$2
txtvalue=$3
fulldomain=$sub.$root
fulldomain="$sub.$root"
_info "Updating record"
@@ -121,7 +131,7 @@ update_record() {
return 1
}
#################### Private functions bellow ##################################
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
@@ -136,30 +146,30 @@ _get_root() {
return 1
fi
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
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 printf "$response" | grep "$h." >/dev/null; then
seg=$(printf "%s" "$response" | _egrep_o "\{[^\{]*\"$h\.\"[^\}]*\}")
if _contains "$response" "$h."; then
seg=$(printf "%s\n" "$response" | _egrep_o '[^{]*"'"$h"'."[^}]*}')
_debug seg "$seg"
_domain_id=$(printf "%s" "$seg" | _egrep_o \"id\":\"[^\"]*\" | cut -d : -f 2 | tr -d \")
_domain_id=$(printf "%s\n" "$seg" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")
_debug _domain_id "$_domain_id"
if [ "$_domain_id" ]; then
_sub_domain=$(printf $domain | cut -d . -f 1-$p)
_debug _sub_domain $_sub_domain
_domain=$h
_debug _domain $_domain
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_debug _sub_domain "$_sub_domain"
_domain="$h"
_debug _domain "$_domain"
return 0
fi
return 1
fi
p=$i
i=$(expr $i + 1)
p="$i"
i=$(_math "$i" + 1)
done
return 1
}
@@ -168,7 +178,7 @@ _get_root() {
_rest() {
m=$1
ep="$2"
_debug $ep
_debug ep "$ep"
url="$REST_API/$ep"
_debug url "$url"
@@ -180,16 +190,16 @@ _rest() {
sec="$CX_Key$url$data$cdate$CX_Secret"
_debug sec "$sec"
hmac=$(printf "$sec" | openssl md5 | cut -d " " -f 2)
hmac=$(printf "%s" "$sec" | _digest md5 hex)
_debug hmac "$hmac"
_H1="API-KEY: $CX_Key"
_H2="API-REQUEST-DATE: $cdate"
_H3="API-HMAC: $hmac"
_H4="Content-Type: application/json"
export _H1="API-KEY: $CX_Key"
export _H2="API-REQUEST-DATE: $cdate"
export _H3="API-HMAC: $hmac"
export _H4="Content-Type: application/json"
if [ "$data" ]; then
response="$(_post "$data" "$url" "" $m)"
response="$(_post "$data" "$url" "" "$m")"
else
response="$(_get "$url")"
fi
@@ -199,7 +209,7 @@ _rest() {
return 1
fi
_debug2 response "$response"
if ! printf "$response" | grep '"message":"success"' >/dev/null; then
if ! _contains "$response" '"message":"success"'; then
return 1
fi
return 0

View File

@@ -6,9 +6,8 @@
#
#DP_Key="sADDsdasdgdsf"
DP_Api="https://dnsapi.cn"
REST_API="https://dnsapi.cn"
#REST_API
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
@@ -17,24 +16,24 @@ dns_dp_add() {
txtvalue=$2
if [ -z "$DP_Id" ] || [ -z "$DP_Key" ]; then
DP_Id=""
DP_Key=""
_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
_err "Error get existing records."
@@ -42,15 +41,45 @@ dns_dp_add() {
fi
if [ "$count" = "0" ]; then
add_record $_domain $_sub_domain $txtvalue
add_record "$_domain" "$_sub_domain" "$txtvalue"
else
update_record $_domain $_sub_domain $txtvalue
update_record "$_domain" "$_sub_domain" "$txtvalue"
fi
}
#fulldomain
#fulldomain txtvalue
dns_dp_rm() {
fulldomain=$1
txtvalue=$2
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
if ! _rest POST "Record.List" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain"; then
_err "Record.Lis error."
return 1
fi
if _contains "$response" 'No records'; then
_info "Don't need to remove."
return 0
fi
record_id=$(echo "$response" | _egrep_o '{[^{]*"value":"'"$txtvalue"'"' | cut -d , -f 1 | cut -d : -f 2 | tr -d \")
_debug record_id "$record_id"
if [ -z "$record_id" ]; then
_err "Can not get record id."
return 1
fi
if ! _rest POST "Record.Remove" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&record_id=$record_id"; then
_err "Record.Remove error."
return 1
fi
_contains "$response" "Action completed successful"
}
@@ -67,14 +96,15 @@ existing_records() {
return 1
fi
if printf "$response" | grep 'No records'; then
if _contains "$response" 'No records'; then
count=0
return 0
fi
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)
if _contains "$response" "Action completed successful"; then
count=$(printf "%s" "$response" | grep -c '<type>TXT</type>' | tr -d ' ')
record_id=$(printf "%s" "$response" | grep '^<id>' | tail -1 | cut -d '>' -f 2 | cut -d '<' -f 1)
_debug record_id "$record_id"
return 0
else
_err "get existing records error."
@@ -90,7 +120,7 @@ add_record() {
root=$1
sub=$2
txtvalue=$3
fulldomain=$sub.$root
fulldomain="$sub.$root"
_info "Adding record"
@@ -98,7 +128,7 @@ add_record() {
return 1
fi
if printf "$response" | grep "Action completed successful"; then
if _contains "$response" "Action completed successful"; then
return 0
fi
@@ -112,7 +142,7 @@ update_record() {
root=$1
sub=$2
txtvalue=$3
fulldomain=$sub.$root
fulldomain="$sub.$root"
_info "Updating record"
@@ -120,7 +150,7 @@ update_record() {
return 1
fi
if printf "$response" | grep "Action completed successful"; then
if _contains "$response" "Action completed successful"; then
return 0
fi
@@ -128,7 +158,7 @@ update_record() {
return 1 #error
}
#################### Private functions bellow ##################################
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
@@ -138,8 +168,8 @@ _get_root() {
domain=$1
i=2
p=1
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1
@@ -149,39 +179,39 @@ _get_root() {
return 1
fi
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 \")
if _contains "$response" "Action completed successful"; 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
_sub_domain=$(printf $domain | cut -d . -f 1-$p)
_debug _sub_domain $_sub_domain
_domain=$h
_debug _domain $_domain
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_debug _sub_domain "$_sub_domain"
_domain="$h"
_debug _domain "$_domain"
return 0
fi
return 1
fi
p=$i
i=$(expr $i + 1)
p="$i"
i=$(_math "$i" + 1)
done
return 1
}
#Usage: method URI data
_rest() {
m=$1
m="$1"
ep="$2"
data="$3"
_debug $ep
_debug "$ep"
url="$REST_API/$ep"
_debug url "$url"
if [ "$data" ]; then
_debug2 data "$data"
response="$(_post $data "$url")"
if [ "$m" = "GET" ]; then
response="$(_get "$url" | tr -d '\r')"
else
response="$(_get "$url")"
_debug2 data "$data"
response="$(_post "$data" "$url" | tr -d '\r')"
fi
if [ "$?" != "0" ]; then

View File

@@ -16,6 +16,8 @@ dns_gd_add() {
txtvalue=$2
if [ -z "$GD_Key" ] || [ -z "$GD_Secret" ]; then
GD_Key=""
GD_Secret=""
_err "You don't specify godaddy api key and secret yet."
_err "Please create you key and try again."
return 1
@@ -26,11 +28,11 @@ dns_gd_add() {
_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"
@@ -57,18 +59,17 @@ dns_gd_rm() {
}
#################### Private functions bellow ##################################
#################### 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
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1
@@ -78,15 +79,15 @@ _get_root() {
return 1
fi
if printf "$response" | grep '"code":"NOT_FOUND"' >/dev/null; then
if _contains "$response" '"code":"NOT_FOUND"'; then
_debug "$h not found"
else
_sub_domain=$(printf $domain | cut -d . -f 1-$p)
_domain=$h
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
return 0
fi
p=$i
i=$(expr $i + 1)
p="$i"
i=$(_math "$i" + 1)
done
return 1
}
@@ -95,14 +96,14 @@ _gd_rest() {
m=$1
ep="$2"
data="$3"
_debug $ep
_debug "$ep"
_H1="Authorization: sso-key $GD_Key:$GD_Secret"
_H2="Content-Type: application/json"
export _H1="Authorization: sso-key $GD_Key:$GD_Secret"
export _H2="Content-Type: application/json"
if [ "$data" ]; then
_debug data "$data"
response="$(_post "$data" "$GD_Api/$ep" "" $m)"
response="$(_post "$data" "$GD_Api/$ep" "" "$m")"
else
response="$(_get "$GD_Api/$ep")"
fi

177
dnsapi/dns_ispconfig.sh Executable file
View File

@@ -0,0 +1,177 @@
#!/usr/bin/env sh
# ISPConfig 3.1 API
# User must provide login data and URL to the ISPConfig installation incl. port. The remote user in ISPConfig must have access to:
# - DNS zone Functions
# - DNS txt Functions
# Report bugs to https://github.com/sjau/acme.sh
# Values to export:
# export ISPC_User="remoteUser"
# export ISPC_Password="remotePassword"
# export ISPC_Api="https://ispc.domain.tld:8080/remote/json.php"
# export ISPC_Api_Insecure=1 # Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1)
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_ispconfig_add() {
fulldomain="${1}"
txtvalue="${2}"
_debug "Calling: dns_ispconfig_add() '${fulldomain}' '${txtvalue}'"
_ISPC_credentials && _ISPC_login && _ISPC_getZoneInfo && _ISPC_addTxt
}
#Usage: dns_myapi_rm _acme-challenge.www.domain.com
dns_ispconfig_rm() {
fulldomain="${1}"
_debug "Calling: dns_ispconfig_rm() '${fulldomain}'"
_ISPC_credentials && _ISPC_login && _ISPC_rmTxt
}
#################### Private functions below ##################################
_ISPC_credentials() {
if [ -z "${ISPC_User}" ] || [ -z "$ISPC_Password" ] || [ -z "${ISPC_Api}" ] || [ -z "${ISPC_Api_Insecure}" ]; then
ISPC_User=""
ISPC_Password=""
ISPC_Api=""
ISPC_Api_Insecure=""
_err "You haven't specified the ISPConfig Login data, URL and whether you want check the ISPC SSL cert. Please try again."
return 1
else
_saveaccountconf ISPC_User "${ISPC_User}"
_saveaccountconf ISPC_Password "${ISPC_Password}"
_saveaccountconf ISPC_Api "${ISPC_Api}"
_saveaccountconf ISPC_Api_Insecure "${ISPC_Api_Insecure}"
# Set whether curl should use secure or insecure mode
export HTTPS_INSECURE="${ISPC_Api_Insecure}"
fi
}
_ISPC_login() {
_info "Getting Session ID"
curData="{\"username\":\"${ISPC_User}\",\"password\":\"${ISPC_Password}\",\"client_login\":false}"
curResult="$(_post "${curData}" "${ISPC_Api}?login")"
_debug "Calling _ISPC_login: '${curData}' '${ISPC_Api}?login'"
_debug "Result of _ISPC_login: '$curResult'"
if _contains "${curResult}" '"code":"ok"'; then
sessionID=$(echo "${curResult}" | _egrep_o "response.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
_info "Retrieved Session ID."
_debug "Session ID: '${sessionID}'"
else
_err "Couldn't retrieve the Session ID."
return 1
fi
}
_ISPC_getZoneInfo() {
_info "Getting Zoneinfo"
zoneEnd=false
curZone="${fulldomain}"
while [ "${zoneEnd}" = false ]; do
# we can strip the first part of the fulldomain, since it's just the _acme-challenge string
curZone="${curZone#*.}"
# suffix . needed for zone -> domain.tld.
curData="{\"session_id\":\"${sessionID}\",\"primary_id\":{\"origin\":\"${curZone}.\"}}"
curResult="$(_post "${curData}" "${ISPC_Api}?dns_zone_get")"
_debug "Calling _ISPC_getZoneInfo: '${curData}' '${ISPC_Api}?login'"
_debug "Result of _ISPC_getZoneInfo: '$curResult'"
if _contains "${curResult}" '"id":"'; then
zoneFound=true
zoneEnd=true
_info "Retrieved zone data."
_debug "Zone data: '${curResult}'"
fi
if [ "${curZone#*.}" != "$curZone" ]; then
_debug2 "$curZone still contains a '.' - so we can check next higher level"
else
zoneEnd=true
_err "Couldn't retrieve zone data."
return 1
fi
done
if [ "${zoneFound}" ]; then
server_id=$(echo "${curResult}" | _egrep_o "server_id.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
_debug "Server ID: '${server_id}'"
case "${server_id}" in
'' | *[!0-9]*)
_err "Server ID is not numeric."
return 1
;;
*) _info "Retrieved Server ID" ;;
esac
zone=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
_debug "Zone: '${zone}'"
case "${zone}" in
'' | *[!0-9]*)
_err "Zone ID is not numeric."
return 1
;;
*) _info "Retrieved Zone ID" ;;
esac
client_id=$(echo "${curResult}" | _egrep_o "sys_userid.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
_debug "Client ID: '${client_id}'"
case "${client_id}" in
'' | *[!0-9]*)
_err "Client ID is not numeric."
return 1
;;
*) _info "Retrieved Client ID." ;;
esac
zoneFound=""
zoneEnd=""
fi
}
_ISPC_addTxt() {
curSerial="$(date +%s)"
curStamp="$(date +'%F %T')"
params="\"server_id\":\"${server_id}\",\"zone\":\"${zone}\",\"name\":\"${fulldomain}.\",\"type\":\"txt\",\"data\":\"${txtvalue}\",\"aux\":\"0\",\"ttl\":\"3600\",\"active\":\"y\",\"stamp\":\"${curStamp}\",\"serial\":\"${curSerial}\""
curData="{\"session_id\":\"${sessionID}\",\"client_id\":\"${client_id}\",\"params\":{${params}}}"
curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_add")"
_debug "Calling _ISPC_addTxt: '${curData}' '${ISPC_Api}?dns_txt_add'"
_debug "Result of _ISPC_addTxt: '$curResult'"
record_id=$(echo "${curResult}" | _egrep_o "\"response.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
_debug "Record ID: '${record_id}'"
case "${record_id}" in
'' | *[!0-9]*)
_err "Couldn't add ACME Challenge TXT record to zone."
return 1
;;
*) _info "Added ACME Challenge TXT record to zone." ;;
esac
}
_ISPC_rmTxt() {
# Need to get the record ID.
curData="{\"session_id\":\"${sessionID}\",\"primary_id\":{\"name\":\"${fulldomain}.\",\"type\":\"TXT\"}}"
curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_get")"
_debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_get'"
_debug "Result of _ISPC_rmTxt: '$curResult'"
if _contains "${curResult}" '"code":"ok"'; then
record_id=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
_debug "Record ID: '${record_id}'"
case "${record_id}" in
'' | *[!0-9]*)
_err "Record ID is not numeric."
return 1
;;
*)
unset IFS
_info "Retrieved Record ID."
curData="{\"session_id\":\"${sessionID}\",\"primary_id\":\"${record_id}\"}"
curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_delete")"
_debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_delete'"
_debug "Result of _ISPC_rmTxt: '$curResult'"
if _contains "${curResult}" '"code":"ok"'; then
_info "Removed ACME Challenge TXT record from zone."
else
_err "Couldn't remove ACME Challenge TXT record from zone."
return 1
fi
;;
esac
fi
}

View File

@@ -2,7 +2,7 @@
# dns api wrapper of lexicon for acme.sh
lexicon_url="https://github.com/AnalogJ/lexicon"
# https://github.com/AnalogJ/lexicon
lexicon_cmd="lexicon"
wiki="https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api"
@@ -14,14 +14,15 @@ dns_lexicon_add() {
fulldomain=$1
txtvalue=$2
domain=$(printf "$fulldomain" | cut -d . -f 2-999)
domain=$(printf "%s" "$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
PROVIDER=""
_err "Please define env PROVIDER first: $wiki"
return 1
fi
@@ -29,39 +30,44 @@ dns_lexicon_add() {
_savedomainconf PROVIDER "$PROVIDER"
export PROVIDER
Lx_name=$(echo LEXICON_${PROVIDER}_USERNAME | tr [a-z] [A-Z])
eval Lx_name_v="\$$Lx_name"
# e.g. busybox-ash does not know [:upper:]
# shellcheck disable=SC2018,SC2019
Lx_name=$(echo LEXICON_"${PROVIDER}"_USERNAME | tr 'a-z' 'A-Z')
Lx_name_v=$(eval echo \$"$Lx_name")
_debug "$Lx_name" "$Lx_name_v"
if [ "$Lx_name_v" ]; then
_saveaccountconf $Lx_name "$Lx_name_v"
export "$Lx_name"
_saveaccountconf "$Lx_name" "$Lx_name_v"
eval export "$Lx_name"
fi
Lx_token=$(echo LEXICON_${PROVIDER}_TOKEN | tr [a-z] [A-Z])
eval Lx_token_v="\$$Lx_token"
# shellcheck disable=SC2018,SC2019
Lx_token=$(echo LEXICON_"${PROVIDER}"_TOKEN | tr 'a-z' 'A-Z')
Lx_token_v=$(eval echo \$"$Lx_token")
_debug "$Lx_token" "$Lx_token_v"
if [ "$Lx_token_v" ]; then
_saveaccountconf $Lx_token "$Lx_token_v"
export "$Lx_token"
_saveaccountconf "$Lx_token" "$Lx_token_v"
eval export "$Lx_token"
fi
Lx_password=$(echo LEXICON_${PROVIDER}_PASSWORD | tr [a-z] [A-Z])
eval Lx_password_v="\$$Lx_password"
# shellcheck disable=SC2018,SC2019
Lx_password=$(echo LEXICON_"${PROVIDER}"_PASSWORD | tr 'a-z' 'A-Z')
Lx_password_v=$(eval echo \$"$Lx_password")
_debug "$Lx_password" "$Lx_password_v"
if [ "$Lx_password_v" ]; then
_saveaccountconf $Lx_password "$Lx_password_v"
export "$Lx_password"
_saveaccountconf "$Lx_password" "$Lx_password_v"
eval export "$Lx_password"
fi
Lx_domaintoken=$(echo LEXICON_${PROVIDER}_DOMAINTOKEN | tr [a-z] [A-Z])
eval Lx_domaintoken_v="\$$Lx_domaintoken"
# shellcheck disable=SC2018,SC2019
Lx_domaintoken=$(echo LEXICON_"${PROVIDER}"_DOMAINTOKEN | tr 'a-z' 'A-Z')
Lx_domaintoken_v=$(eval echo \$"$Lx_domaintoken")
_debug "$Lx_domaintoken" "$Lx_domaintoken_v"
if [ "$Lx_domaintoken_v" ]; then
export "$Lx_domaintoken"
_saveaccountconf $Lx_domaintoken "$Lx_domaintoken_v"
eval export "$Lx_domaintoken"
_saveaccountconf "$Lx_domaintoken" "$Lx_domaintoken_v"
fi
$lexicon_cmd "$PROVIDER" create ${domain} TXT --name="_acme-challenge.${domain}." --content="${txtvalue}"
$lexicon_cmd "$PROVIDER" create "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}"
}

View File

@@ -8,7 +8,7 @@
#LUA_Email="user@luadns.net"
LUA_Api="https://api.luadns.com/v1"
LUA_auth=$(printf $LUA_Email:$LUA_Key | _base64)
LUA_auth=$(printf "%s" "$LUA_Email:$LUA_Key" | _base64)
######## Public functions #####################
@@ -18,6 +18,8 @@ dns_lua_add() {
txtvalue=$2
if [ -z "$LUA_Key" ] || [ -z "$LUA_Email" ]; then
LUA_Key=""
LUA_Email=""
_err "You don't specify luadns api key and email yet."
_err "Please create you key and try again."
return 1
@@ -28,7 +30,7 @@ dns_lua_add() {
_saveaccountconf LUA_Email "$LUA_Email"
_debug "First detect the root zone"
if ! _get_root $fulldomain; then
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
@@ -39,17 +41,17 @@ dns_lua_add() {
_debug "Getting txt records"
_LUA_rest GET "zones/${_domain_id}/records"
if ! printf "$response" | grep \"id\": >/dev/null; then
if ! _contains "$response" "\"id\":"; then
_err "Error"
return 1
fi
count=$(printf "%s\n" "$response" | _egrep_o \"name\":\"$fulldomain\" | wc -l)
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
if printf -- "%s" "$response" | grep "$fulldomain" >/dev/null; then
_info "Added"
#todo: check if the record takes effect
return 0
@@ -61,8 +63,8 @@ dns_lua_add() {
_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
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
@@ -82,7 +84,7 @@ dns_lua_rm() {
}
#################### Private functions bellow ##################################
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
@@ -95,24 +97,24 @@ _get_root() {
if ! _LUA_rest GET "zones"; then
return 1
fi
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
while true; do
h=$(printf "%s" "$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 _contains "$response" "\"name\":\"$h\""; 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
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
return 0
fi
return 1
fi
p=$i
i=$(expr $i + 1)
i=$(_math "$i" + 1)
done
return 1
}
@@ -121,13 +123,13 @@ _LUA_rest() {
m=$1
ep="$2"
data="$3"
_debug $ep
_debug "$ep"
_H1="Accept: application/json"
_H2="Authorization: Basic $LUA_auth"
export _H1="Accept: application/json"
export _H2="Authorization: Basic $LUA_auth"
if [ "$data" ]; then
_debug data "$data"
response="$(_post "$data" "$LUA_Api/$ep" "" $m)"
response="$(_post "$data" "$LUA_Api/$ep" "" "$m")"
else
response="$(_get "$LUA_Api/$ep")"
fi

View File

@@ -15,6 +15,8 @@ dns_me_add() {
txtvalue=$2
if [ -z "$ME_Key" ] || [ -z "$ME_Secret" ]; then
ME_Key=""
ME_Secret=""
_err "You didn't specify DNSMadeEasy api key and secret yet."
_err "Please create you key and try again."
return 1
@@ -25,7 +27,7 @@ dns_me_add() {
_saveaccountconf ME_Secret "$ME_Secret"
_debug "First detect the root zone"
if ! _get_root $fulldomain; then
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
@@ -36,12 +38,12 @@ dns_me_add() {
_debug "Getting txt records"
_me_rest GET "${_domain_id}/records?recordName=$_sub_domain&type=TXT"
if ! printf "$response" | grep \"totalRecords\": >/dev/null; then
if ! _contains "$response" "\"totalRecords\":"; then
_err "Error"
return 1
fi
count=$(printf "%s\n" "$response" | _egrep_o \"totalRecords\":[^,]* | cut -d : -f 2)
count=$(printf "%s\n" "$response" | _egrep_o "\"totalRecords\":[^,]*" | cut -d : -f 2)
_debug count "$count"
if [ "$count" = "0" ]; then
_info "Adding record"
@@ -58,8 +60,8 @@ dns_me_add() {
_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
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
@@ -79,7 +81,7 @@ dns_me_rm() {
}
#################### Private functions bellow ##################################
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
@@ -89,8 +91,8 @@ _get_root() {
domain=$1
i=2
p=1
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1
@@ -100,17 +102,17 @@ _get_root() {
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 _contains "$response" "\"name\":\"$h\""; 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
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
return 0
fi
return 1
fi
p=$i
i=$(expr $i + 1)
i=$(_math "$i" + 1)
done
return 1
}
@@ -119,18 +121,18 @@ _me_rest() {
m=$1
ep="$2"
data="$3"
_debug $ep
_debug "$ep"
cdate=$(date -u +"%a, %d %b %Y %T %Z")
hmac=$(printf "$cdate" | _hmac sha1 "$ME_Secret" 1)
hmac=$(printf "%s" "$cdate" | _hmac sha1 "$(_hex "$ME_Secret")" hex)
_H1="x-dnsme-apiKey: $ME_Key"
_H2="x-dnsme-requestDate: $cdate"
_H3="x-dnsme-hmac: $hmac"
export _H1="x-dnsme-apiKey: $ME_Key"
export _H2="x-dnsme-requestDate: $cdate"
export _H3="x-dnsme-hmac: $hmac"
if [ "$data" ]; then
_debug data "$data"
response="$(_post "$data" "$ME_Api/$ep" "" $m)"
response="$(_post "$data" "$ME_Api/$ep" "" "$m")"
else
response="$(_get "$ME_Api/$ep")"
fi

View File

@@ -5,48 +5,31 @@
#So, here must be a method dns_myapi_add()
#Which will be called by acme.sh to add the txt record to your api system.
#returns 0 means success, otherwise error.
#
#Author: Neilpang
#Report Bugs here: https://github.com/Neilpang/acme.sh
#
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_myapi_add() {
fulldomain=$1
txtvalue=$2
_info "Using myapi"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_err "Not implemented!"
return 1
}
#fulldomain
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_myapi_rm() {
fulldomain=$1
txtvalue=$2
_info "Using myapi"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
}
#################### Private functions bellow ##################################
_info() {
if [ -z "$2" ]; then
echo "[$(date)] $1"
else
echo "[$(date)] $1='$2'"
fi
}
_err() {
_info "$@" >&2
return 1
}
_debug() {
if [ -z "$DEBUG" ]; then
return
fi
_err "$@"
return 0
}
_debug2() {
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
_debug "$@"
fi
return
}
#################### Private functions below ##################################

58
dnsapi/dns_nsupdate.sh Executable file
View File

@@ -0,0 +1,58 @@
#!/usr/bin/env sh
######## Public functions #####################
#Usage: dns_nsupdate_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_nsupdate_add() {
fulldomain=$1
txtvalue=$2
_checkKeyFile || return 1
[ -n "${NSUPDATE_SERVER}" ] || NSUPDATE_SERVER="localhost"
# save the dns server and key to the account conf file.
_saveaccountconf NSUPDATE_SERVER "${NSUPDATE_SERVER}"
_saveaccountconf NSUPDATE_KEY "${NSUPDATE_KEY}"
_info "adding ${fulldomain}. 60 in txt \"${txtvalue}\""
nsupdate -k "${NSUPDATE_KEY}" <<EOF
server ${NSUPDATE_SERVER}
update add ${fulldomain}. 60 in txt "${txtvalue}"
send
EOF
if [ $? -ne 0 ]; then
_err "error updating domain"
return 1
fi
return 0
}
#Usage: dns_nsupdate_rm _acme-challenge.www.domain.com
dns_nsupdate_rm() {
fulldomain=$1
_checkKeyFile || return 1
[ -n "${NSUPDATE_SERVER}" ] || NSUPDATE_SERVER="localhost"
_info "removing ${fulldomain}. txt"
nsupdate -k "${NSUPDATE_KEY}" <<EOF
server ${NSUPDATE_SERVER}
update delete ${fulldomain}. txt
send
EOF
if [ $? -ne 0 ]; then
_err "error updating domain"
return 1
fi
return 0
}
#################### Private functions below ##################################
_checkKeyFile() {
if [ -z "${NSUPDATE_KEY}" ]; then
_err "you must specify a path to the nsupdate key file"
return 1
fi
if [ ! -r "${NSUPDATE_KEY}" ]; then
_err "key ${NSUPDATE_KEY} is unreadable"
return 1
fi
}

View File

@@ -86,6 +86,8 @@ dns_ovh_add() {
txtvalue=$2
if [ -z "$OVH_AK" ] || [ -z "$OVH_AS" ]; then
OVH_AK=""
OVH_AS=""
_err "You don't specify OVH application key and application secret yet."
_err "Please create you key and try again."
return 1
@@ -127,11 +129,11 @@ dns_ovh_add() {
_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"
@@ -157,7 +159,7 @@ dns_ovh_add() {
_err "Can not get record id."
return 1
fi
_debug "record_id" $record_id
_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
@@ -180,7 +182,7 @@ dns_ovh_rm() {
}
#################### Private functions bellow ##################################
#################### Private functions below ##################################
_ovh_authentication() {
@@ -221,13 +223,12 @@ _ovh_authentication() {
#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)
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1
@@ -238,12 +239,12 @@ _get_root() {
fi
if ! _contains "$response" "This service does not exist" >/dev/null; then
_sub_domain=$(printf $domain | cut -d . -f 1-$p)
_domain=$h
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
return 0
fi
p=$i
i=$(expr $i + 1)
i=$(_math "$i" + 1)
done
return 1
}
@@ -261,7 +262,7 @@ _ovh_rest() {
m=$1
ep="$2"
data="$3"
_debug $ep
_debug "$ep"
_ovh_url="$OVH_API/$ep"
_debug2 _ovh_url "$_ovh_url"
@@ -272,15 +273,15 @@ _ovh_rest() {
_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"
export _H1="X-Ovh-Application: $OVH_AK"
export _H2="X-Ovh-Signature: \$1\$$_ovh_hex"
_debug2 _H2 "$_H2"
_H3="X-Ovh-Timestamp: $_ovh_t"
_H4="X-Ovh-Consumer: $OVH_CK"
_H5="Content-Type: application/json;charset=utf-8"
export _H3="X-Ovh-Timestamp: $_ovh_t"
export _H4="X-Ovh-Consumer: $OVH_CK"
export _H5="Content-Type: application/json;charset=utf-8"
if [ "$data" ] || [ "$m" = "POST" ] || [ "$m" = "PUT" ]; then
_debug data "$data"
response="$(_post "$data" "$_ovh_url" "" $m)"
response="$(_post "$data" "$_ovh_url" "" "$m")"
else
response="$(_get "$_ovh_url")"
fi

View File

@@ -12,30 +12,35 @@ DEFAULT_PDNS_TTL=60
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000"
#fulldomain
#txtvalue
dns_pdns_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$PDNS_Url" ]; then
PDNS_Url=""
_err "You don't specify PowerDNS address."
_err "Please set PDNS_Url and try again."
return 1
fi
if [ -z "$PDNS_ServerId" ]; then
PDNS_ServerId=""
_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
PDNS_Token=""
_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
PDNS_Ttl="$DEFAULT_PDNS_TTL"
fi
#save the api addr and key to the account conf file.
@@ -47,8 +52,8 @@ dns_pdns_add() {
_saveaccountconf PDNS_Ttl "$PDNS_Ttl"
fi
_debug "First detect the root zone"
if ! _get_root $fulldomain; then
_debug "Detect root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
@@ -65,6 +70,18 @@ dns_pdns_add() {
dns_pdns_rm() {
fulldomain=$1
_debug "Detect root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain "$_domain"
if ! rm_record "$_domain" "$fulldomain"; then
return 1
fi
return 0
}
set_record() {
@@ -73,45 +90,73 @@ set_record() {
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
if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root." "{\"rrsets\": [{\"changetype\": \"REPLACE\", \"name\": \"$full.\", \"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."
if ! notify_slaves "$root"; then
return 1
fi
return 0
}
#################### Private functions bellow ##################################
rm_record() {
_info "Remove record"
root=$1
full=$2
if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root." "{\"rrsets\": [{\"changetype\": \"DELETE\", \"name\": \"$full.\", \"type\": \"TXT\"}]}"; then
_err "Delete txt record error."
return 1
fi
if ! notify_slaves "$root"; then
return 1
fi
return 0
}
notify_slaves() {
root=$1
if ! _pdns_rest "PUT" "/api/v1/servers/$PDNS_ServerId/zones/$root./notify"; then
_err "Notify slaves error."
return 1
fi
return 0
}
#################### Private functions below ##################################
#_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
_zones_response="$response"
fi
while [ '1' ]; do
h=$(printf $domain | cut -d . -f $i-100)
while true; do
h=$(printf "%s" "$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
if _contains "$_zones_response" "\"name\": \"$h.\""; then
_domain="$h"
return 0
fi
p=$i
i=$(expr $i + 1)
i=$(_math $i + 1)
done
_debug "$domain not found"
return 1
}
@@ -120,7 +165,7 @@ _pdns_rest() {
ep=$2
data=$3
_H1="X-API-Key: $PDNS_Token"
export _H1="X-API-Key: $PDNS_Token"
if [ ! "$method" = "GET" ]; then
_debug data "$data"