Compare commits

..

535 Commits
2.5.2 ... 2.6.6

Author SHA1 Message Date
neil
50d7b8452d Merge pull request #611 from Neilpang/backup
Backup
2017-02-12 10:27:58 +08:00
neilpang
d88f8e862b move backup to sub folder. 2017-02-12 10:20:50 +08:00
neilpang
fd72cced13 move the backup file to acme home
fix https://github.com/Neilpang/acme.sh/issues/488
2017-02-12 10:10:53 +08:00
neil
a6feb0a887 Merge pull request #608 from Neilpang/dev
Dev
2017-02-11 21:31:38 +08:00
neilpang
cd9c3a79e5 update doc 2017-02-11 21:29:36 +08:00
neil
f3685bdef9 Merge pull request #607 from Neilpang/syslog
support syslog
2017-02-11 21:28:09 +08:00
neilpang
e2edf20833 support syslog 2017-02-11 21:15:36 +08:00
neil
31e39f1f6d Merge pull request #606 from Neilpang/dev
update issue template
2017-02-11 20:14:00 +08:00
neilpang
d47c5eaf60 update issue template 2017-02-11 20:13:21 +08:00
neil
b8e515a738 Merge pull request #604 from Neilpang/dev
minor, rename command
2017-02-11 13:53:04 +08:00
neilpang
0984585d58 minor, rename command 2017-02-11 13:36:52 +08:00
neil
f3e0eb705b Merge pull request #603 from Neilpang/dev
add doc
2017-02-11 13:25:00 +08:00
neilpang
04e0f87c03 add doc 2017-02-11 13:24:00 +08:00
neil
8ccfcd272f Merge pull request #602 from Neilpang/dev
Dev
2017-02-10 22:05:24 +08:00
neil
ba69062a36 Merge pull request #599 from hebbet/hebbet-patch-1
remove extra space
2017-02-10 22:04:46 +08:00
neil
cea24b5f70 Merge pull request #601 from Neilpang/dev
Dev
2017-02-10 21:06:14 +08:00
neil
f3a71f62a1 Merge pull request #600 from Neilpang/hex
better hexdump
2017-02-10 21:05:50 +08:00
neilpang
4e4a6d8397 better hexdump
fix https://github.com/Neilpang/acme.sh/issues/595
2017-02-10 20:55:25 +08:00
hebbet
d8beaf727f remove extra space
remove extra space from help
2017-02-10 13:26:17 +01:00
neil
c961c865ee Merge pull request #598 from Neilpang/mingw
support mingw/git-bash
2017-02-10 18:26:39 +08:00
neil
34f25fa590 support mingw/git-bash 2017-02-10 18:20:15 +08:00
neil
7af1155c11 Merge pull request #596 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/593
2017-02-10 13:37:24 +08:00
neil
c9d7daab70 fix https://github.com/Neilpang/acme.sh/issues/593 2017-02-10 13:34:34 +08:00
neil
981077516b Merge pull request #591 from Neilpang/dev
Dev
2017-02-06 21:38:15 +08:00
neilpang
7c488b5913 doc for stateless mode 2017-02-06 21:37:21 +08:00
neilpang
0e44f587a5 add stateless mode 2017-02-06 20:42:54 +08:00
neil
e593d86b80 Merge pull request #590 from Neilpang/dev
minor, output thumbprint
2017-02-06 20:07:14 +08:00
neilpang
339a8ad610 minor, output thumbprint 2017-02-06 19:53:12 +08:00
neil
d1190febec Merge pull request #589 from Neilpang/dev
add _utc_date function
2017-02-06 19:32:33 +08:00
neilpang
5d2c5b01a8 add _utc_date function 2017-02-06 19:30:53 +08:00
neil
0f954c20ff Merge pull request #587 from Neilpang/dev
Dev
2017-02-06 14:47:14 +08:00
neil
d6edff3182 fix ci 2017-02-06 14:20:37 +08:00
neil
dba26c3240 fix check for Mac nc command, it doesn't contain "openbsd", but it works. 2017-02-06 13:27:58 +08:00
neil
0ca5b7996c minor clear account conf 2017-02-06 09:29:33 +08:00
neil
63e1d3610c Merge pull request #585 from Neilpang/master
exe mode
2017-02-05 23:15:55 +08:00
neilpang
b4325026b1 exe 2017-02-05 23:14:25 +08:00
neil
b072ef2e82 Merge pull request #584 from Neilpang/dev
add note info if netcat-openbsd is required.
2017-02-05 23:06:38 +08:00
neilpang
562a4c056e add note info if netcat-openbsd is required. 2017-02-05 23:06:06 +08:00
neil
bb8248556d Merge pull request #583 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/578
2017-02-05 22:09:50 +08:00
neilpang
b22b085b50 fix https://github.com/Neilpang/acme.sh/issues/578
support openssl 1.1.0
2017-02-05 22:08:52 +08:00
neil
a50252382a Merge pull request #580 from Neilpang/dev
Dev
2017-02-05 13:20:35 +08:00
neilpang
9bdb799b41 fix bug when the od command is missing 2017-02-05 13:16:51 +08:00
neil
259cefab72 Merge pull request #571 from dkerr64/FreeDNS
Add FreeDNS plugin support to acme.sh
2017-02-05 11:12:13 +08:00
David Kerr
09ed421948 Merge remote-tracking branch 'upstream/master' into FreeDNS 2017-02-04 10:51:52 -05:00
David Kerr
87f5ec5be5 Add Accept-Language:en-US to HTTP header as precaution against future multi-lingual FreeDNS pages. 2017-02-04 10:36:51 -05:00
David Kerr
f78b656f5f Add error message if fails to add TXT record for missing security code (probably a FreeDNS public domain) 2017-02-04 10:21:58 -05:00
David Kerr
e6b940e247 Minor edits to FreeDNS documentation 2017-02-03 22:59:22 -05:00
David Kerr
50a9680f17 Travis error... remove blank line at end of file. 2017-02-03 11:13:12 -05:00
neil
f2a6dc4dfd Merge pull request #574 from Neilpang/dev
Dev
2017-02-03 20:22:16 +08:00
neil
67e3dd36b3 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2017-02-03 11:13:56 +08:00
neil
6c4cc357b5 _readlink 2017-02-03 11:13:38 +08:00
neil
94965a418f Merge pull request #573 from Neilpang/dev
Dev
2017-02-02 20:57:22 +08:00
David Kerr
40e6ba1100 fix heading level to match others. 2017-02-01 17:12:52 -05:00
David Kerr
0aed065a75 Updates to README.md 2017-02-01 17:08:26 -05:00
neil
70b63a5ed4 Create README.md 2017-02-01 23:18:37 +08:00
neilpang
1476a9ecf1 fix format 2017-02-01 16:12:43 +08:00
David Kerr
600a235140 Add FreeDNS plugin 2017-01-31 23:16:04 -05:00
neil
ffa9f104db Merge pull request #570 from Neilpang/dev
Dev
2017-01-31 20:06:55 +08:00
neilpang
b807ec0956 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2017-01-31 20:04:06 +08:00
neilpang
5f8daeeb6d minor, a better hex_dump 2017-01-31 20:03:41 +08:00
neil
aec8307417 Merge pull request #540 from trancee/dev
Added support for Linode DNS API.
2017-01-31 19:35:39 +08:00
neil
e96a1b01b9 Merge pull request #569 from Neilpang/dev
Dev
2017-01-31 19:25:11 +08:00
neilpang
d78ba322bf fix update 2017-01-31 19:22:14 +08:00
neilpang
ab5c1b0a3a minor 2017-01-31 19:03:29 +08:00
neilpang
53fa16d39f minor 2017-01-31 18:59:00 +08:00
neilpang
05cf405cb5 minor 2017-01-31 18:46:24 +08:00
neilpang
5d833336d3 minor 2017-01-31 18:41:32 +08:00
neil
13be9d8d79 Merge pull request #568 from Neilpang/dev
fix for solaris
2017-01-31 16:26:39 +08:00
neilpang
bb6326f4d4 fix for solaris 2017-01-31 15:57:43 +08:00
Philipp Grosswiler
c070407ab2 Fixed Travis CI complaining about missing newline at end of file. 2017-01-31 13:38:16 +07:00
neil
6b27bdadcd Merge pull request #567 from Neilpang/dev
fix for solaris
2017-01-31 14:05:16 +08:00
neilpang
1c22c2f76a fix for solaris 2017-01-31 14:04:40 +08:00
neil
aa262d4124 Merge pull request #566 from Neilpang/dev
fix for solaris
2017-01-31 12:52:32 +08:00
neilpang
646c0bfcb9 fix for solaris 2017-01-31 12:51:59 +08:00
neil
da68775472 Merge pull request #565 from Neilpang/dev
fix for solaris
2017-01-31 12:44:01 +08:00
neilpang
bcf96608d1 fix for solaris 2017-01-31 12:38:37 +08:00
Philipp Grosswiler
dd17ac5045 Added instructions on how to get the Linode API key. 2017-01-31 10:56:34 +07:00
Philipp Grosswiler
59182dbc97 Removed Linode CLI dependency. 2017-01-31 10:43:30 +07:00
neil
11df7187b3 Merge pull request #564 from Neilpang/dev
add my twitter
2017-01-30 14:30:08 +08:00
neilpang
0899803294 add my twitter 2017-01-30 14:29:40 +08:00
neil
4742e0951c Merge pull request #563 from Neilpang/dev
Dev
2017-01-30 12:42:49 +08:00
neilpang
c3b1eb0837 fix format 2017-01-30 12:25:56 +08:00
neilpang
542d7977db add new _url_encode 2017-01-30 12:07:50 +08:00
neilpang
11927a768e minor, rename 2017-01-29 11:47:04 +08:00
neil
ecd5bcec0c Merge pull request #529 from ggenot/dev
Adding kong deploy script
2017-01-29 11:41:41 +08:00
neil
911a2084d4 Merge pull request #559 from Neilpang/dev
Dev
2017-01-22 18:51:22 +08:00
neilpang
839bf0e2c9 fix format 2017-01-22 18:48:21 +08:00
neil
25555b8c3e pass the paths to reload cmd 2017-01-22 18:11:32 +08:00
neil
cd7ac94f35 Merge pull request #555 from Neilpang/dev
fix format
2017-01-21 14:20:00 +08:00
neilpang
68aea3af9e fix format 2017-01-21 14:19:01 +08:00
neil
cdb3216cc9 Merge pull request #554 from Neilpang/dev
add --remove
2017-01-21 13:39:51 +08:00
neilpang
78f0201dfa add --remove 2017-01-21 13:32:12 +08:00
neil
2cd47b0240 Merge pull request #553 from Neilpang/dev
minor, fix alias
2017-01-21 12:41:34 +08:00
neilpang
be83a6a37a minor, fix alias 2017-01-21 12:40:43 +08:00
neil
8ca99e85b0 Merge pull request #552 from Neilpang/dev
Dev
2017-01-21 11:56:04 +08:00
neilpang
f5b546b3c8 rename to LE_CONFIG_HOME 2017-01-21 11:28:10 +08:00
neil
50c9d17830 Merge pull request #547 from Neilpang/random
Random
2017-01-17 22:09:43 +08:00
neilpang
d87af4788e Merge branch 'random' into dev
# Conflicts:
#	acme.sh
2017-01-17 22:03:55 +08:00
neilpang
0f21537f14 format 2017-01-17 22:01:36 +08:00
neilpang
0533bde9f2 Merge branch 'random' into dev
# Conflicts:
#	acme.sh
2017-01-17 21:57:12 +08:00
neilpang
32b3717c32 random minute 2017-01-17 21:49:02 +08:00
neil
d950f801af Merge pull request #546 from Neilpang/comma
Comma
2017-01-17 20:17:53 +08:00
neil
a8ab028b84 Merge pull request #545 from Neilpang/comma
fix comma in domain
2017-01-17 20:15:50 +08:00
neilpang
2aff36e74b fix comma in domain 2017-01-17 20:13:15 +08:00
neil
db7e4bf940 fix format 2017-01-17 13:06:44 +08:00
neil
ee20015d44 fix format 2017-01-17 13:04:02 +08:00
neilpang
80941f8413 minor 2017-01-16 22:36:13 +08:00
neilpang
cf909db159 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2017-01-16 22:31:42 +08:00
neilpang
27dbe77fad add "--config-home" 2017-01-16 22:31:24 +08:00
Philipp Grosswiler
38f2334360 Added support for Linode DNS API. 2017-01-16 15:42:17 +07:00
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
Geoffroi
5fe91d6577 Correction of test from comment of Neilpang + Correction of CRLF with sh not working correctly 2017-01-11 16:17:16 +01:00
Geoffroi
753d0e7df7 Syntax fix part 2 2017-01-11 15:05:26 +01:00
Geoffroi
e2cc350fbc Fix function name 2017-01-11 14:54:52 +01:00
Geoffroi
07feb87dee Travis fix 2017-01-11 14:52:52 +01:00
Geoffroi
1699e94f0f Adding kong deploy script (https://getkong.org) 2017-01-11 14:09:58 +01: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
neil
a2e62f8e1d Update README.md 2016-11-09 23:44:24 +08:00
neil
4da493f3f3 Merge pull request #376 from Neilpang/dev
Dev
2016-11-09 23:17:02 +08:00
neilpang
dec90f7e5e format dns_me api 2016-11-09 23:15:08 +08:00
nytral
2ea5b283a8 _hmac use and generic date 2016-11-09 23:11:20 +08:00
nytral
eb23549cd6 s/bash/sh/ 2016-11-09 23:11:19 +08:00
nytral
cd90062850 better bugfix 2016-11-09 23:11:19 +08:00
nytral
3ec72fcee9 bugfix 2016-11-09 23:11:19 +08:00
nytral
b9091e14b3 adding DNSMadeEasy API 2016-11-09 23:11:19 +08:00
neil
5daefc0194 Merge pull request #375 from Neilpang/dev
Add shfmt to format source code
2016-11-09 23:08:07 +08:00
neilpang
44edb2bd2f fix shellcheck warnings 2016-11-09 22:35:30 +08:00
neilpang
201aa24448 fix shellcheck warnings. 2016-11-09 22:28:12 +08:00
neilpang
e799ef2977 fix shellcheck warnings. 2016-11-09 22:09:30 +08:00
neilpang
0c538f7527 fix shellcheck warnings 2016-11-09 22:07:32 +08:00
neilpang
ca7202eb0a fix shellcheck warnings 2016-11-09 21:56:50 +08:00
neilpang
d5ec5f80ff fix shellcheck warnings 2016-11-09 21:44:46 +08:00
neilpang
0c944a03fe fix shellcheck warnings 2016-11-09 21:26:35 +08:00
neilpang
79a267ab08 fix for shellcheck 2016-11-09 21:18:47 +08:00
neilpang
f9a6988ece fix for shellcheck 2016-11-09 21:06:22 +08:00
neilpang
95e06de5de fix for shellcheck 2016-11-09 20:45:57 +08:00
neilpang
f530a5074b fix CI exit code 2016-11-09 20:05:52 +08:00
root
439580b91b apply shfmt to dns_dp api. 2016-11-09 20:01:27 +08:00
neilpang
4c2a384159 Add shfmt to format source code 2016-11-09 19:30:39 +08:00
neil
cfd0b040e4 Merge pull request #373 from Neilpang/dev
Dev
2016-11-08 21:28:46 +08:00
neilpang
b001840dee minor: add _hmac function 2016-11-08 21:27:39 +08:00
neilpang
20a6ab3d1a find hook file in current dir first 2016-11-07 20:59:10 +08:00
neil
21f16b50f3 Merge pull request #368 from justmwa/master
bash support for luadns api
2016-11-07 00:00:49 +08:00
nytral
f58e83ee87 READMEs edit 2016-11-06 16:52:43 +01:00
neil
a9b4a2a1ac Merge pull request #370 from Neilpang/dev
add APACHE_HTTPD_CONF
2016-11-06 23:27:42 +08:00
neilpang
5be1449db5 add APACHE_HTTPD_CONF
https://github.com/Neilpang/acme.sh/issues/363
2016-11-06 23:26:38 +08:00
neil
37d7f89c6d Merge pull request #369 from Neilpang/dev
set default account key to 2048.
2016-11-06 23:15:32 +08:00
neilpang
57e58ce76c set default account key to 2048.
Some old platforms doesn't support ecc signing.
2016-11-06 23:08:45 +08:00
nytral
1d9f76e2c8 working email contact added 2016-11-06 15:24:23 +01:00
nytral
56e0269e5e email contact added 2016-11-06 15:12:25 +01:00
nytral
662df85e54 s/bash/sh/ 2016-11-06 15:09:08 +01:00
nytral
2be4a5e486 use _base64 2016-11-06 14:39:22 +01:00
nytral
a43d697225 cleanup 2016-11-06 12:42:27 +01:00
nytral
f06c1e6c78 luadns bash script 2016-11-06 12:37:13 +01:00
neil
b5d1918401 Merge pull request #367 from Neilpang/dev
Dev
2016-11-04 23:49:47 +08:00
neilpang
d018be5d36 hide private key from the log 2016-11-04 23:45:08 +08:00
neilpang
67184d7b20 add more error check 2016-11-04 23:34:06 +08:00
neil
dfdd48b990 Merge pull request #366 from Neilpang/dev
Dev
2016-11-04 22:54:40 +08:00
neilpang
cae9cee295 add debug info 2016-11-04 22:53:33 +08:00
neilpang
067d586c1c typo 2016-11-04 22:47:45 +08:00
neilpang
d22b7938da fix old version openssl issue for ecc key 2016-11-04 22:45:50 +08:00
neilpang
29b7510957 add sign error check. 2016-11-04 22:22:01 +08:00
neilpang
9d548d81ac add more debug info 2016-11-04 22:03:41 +08:00
neil
3c33cdfa3d Update README.md 2016-11-03 19:19:51 +08:00
neil
288485b209 Merge pull request #362 from Neilpang/dev
minor, add more log
2016-11-02 23:27:04 +08:00
neilpang
1cbf416b10 minor, add more log 2016-11-02 23:22:36 +08:00
neil
3b46d3dd74 Merge pull request #361 from Neilpang/dev
add issue template
2016-11-02 23:04:10 +08:00
neilpang
c243829234 add issue template 2016-11-02 23:02:42 +08:00
neil
fd80faa389 Merge pull request #357 from Neilpang/dev
Dev
2016-11-01 20:57:27 +08:00
neilpang
e7d4352292 minor 2016-11-01 20:38:00 +08:00
neilpang
610e0f21d6 fix apache error checks 2016-11-01 20:29:58 +08:00
neilpang
7e512bad96 fix apache mode 2016-11-01 19:31:20 +08:00
neil
98c4ce0c45 Merge pull request #356 from Neilpang/dev
add more error check
2016-11-01 19:15:01 +08:00
neilpang
93fc48a2db add more error check 2016-11-01 19:14:33 +08:00
neil
d7eea12a6f Merge pull request #353 from Neilpang/dev
Dev
2016-10-31 21:31:13 +08:00
neilpang
2a1e06f8a9 add --quiet for idn 2016-10-31 21:22:04 +08:00
neilpang
02d54a783a fix for idn on solaris 2016-10-31 21:12:11 +08:00
neil
5961d44339 Update README.md 2016-10-30 17:26:00 +08:00
neil
fb3be8509d Add gentoo linux 2016-10-29 22:59:53 +08:00
neil
97be53741d Merge pull request #352 from Neilpang/dev
minor
2016-10-29 22:44:05 +08:00
neilpang
0d2c26735e minor 2016-10-29 21:33:34 +08:00
neil
2d0a8ddb58 Merge pull request #351 from Neilpang/dev
fix performance
2016-10-29 17:44:37 +08:00
neilpang
72518d4827 fix performance 2016-10-29 17:43:38 +08:00
neil
c6cd744186 Merge pull request #350 from Neilpang/dev
Dev
2016-10-29 12:15:29 +08:00
neilpang
ae2db62f1c fix issues for ECC account key. 2016-10-29 12:14:48 +08:00
neilpang
8c76b8bc36 do not cache thumbprint for issues for ecc account key 2016-10-29 11:15:45 +08:00
neilpang
18256c4923 fix issue cache jwk for ecc key only 2016-10-29 11:08:18 +08:00
neil
f345cc66cf Dev (#349)
* rename JWK_HEADER

* fix performance

* fix performance, use cached nonce

* do not register account if already registered

* fix thumbprint

* minor, reduce the sleep time.
2016-10-29 10:55:16 +08:00
neilpang
5dbf664a6b minor, reduce the sleep time. 2016-10-29 10:53:45 +08:00
neil
d7c6679d70 fix issue performance. Reduce the time cost from about 20 seconds down to 8 seconds (#348)
* rename JWK_HEADER

* fix performance

* fix performance, use cached nonce

* do not register account if already registered

* fix thumbprint
2016-10-28 23:58:01 +08:00
neilpang
cae203be71 fix thumbprint 2016-10-28 23:30:32 +08:00
neilpang
8a29fbc850 do not register account if already registered 2016-10-28 22:45:19 +08:00
neilpang
00bcbd367f fix performance, use cached nonce 2016-10-28 21:30:40 +08:00
neilpang
1befee5aca fix performance 2016-10-28 20:56:18 +08:00
neil
5982f4bcf0 rename JWK_HEADER 2016-10-28 18:07:04 +08:00
neil
2399476a21 Merge pull request #347 from Neilpang/dev
minor, add message
2016-10-27 22:48:39 +08:00
neilpang
9e45ac939b minor, add message 2016-10-27 22:47:19 +08:00
neil
34f231f9f3 Merge pull request #346 from Neilpang/dev
add retry to deactivate command
2016-10-27 22:16:14 +08:00
neilpang
f940b2a58e add retry to deactivate command 2016-10-27 22:10:58 +08:00
neil
0383c33558 Merge pull request #345 from Neilpang/dev
add retry for temp authz request error
2016-10-27 20:26:27 +08:00
neilpang
3afa4b210d add retry for temp authz request error 2016-10-27 20:07:20 +08:00
neilpang
998783eb9d Support ECC account key.
fix https://github.com/Neilpang/acme.sh/issues/76

https://tools.ietf.org/html/rfc3278#section-8.2
http://bitcoin.stackexchange.com/questions/2376/ecdsa-r-s-encoding-as-a-signature
http://davidederosa.com/basic-blockchain-programming/elliptic-curve-digital-signatures/
2016-10-27 00:06:03 +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
neilpang
5d6fd8099f add dns_xxx_rm function
https://github.com/Neilpang/acme.sh/issues/79
2016-10-25 23:08:02 +08:00
neilpang
800e3f4599 support dns_xxx_rm function
fix https://github.com/Neilpang/acme.sh/issues/79
2016-10-25 23:02:49 +08:00
neil
35c61f52fe Merge pull request #339 from Neilpang/deploy
add deploy command
2016-10-25 21:19:24 +08:00
neilpang
3db446633c add deploy api 2016-10-25 21:09:01 +08:00
neilpang
e3b4a0213c Merge branch 'master' into deploy 2016-10-25 20:55:18 +08:00
Armando Lüscher
9910ff5fa1 Allow saved password strings to have special characters. (#334) 2016-10-25 20:49:22 +08:00
neilpang
049be10406 fix idn to support European chars
https://github.com/Neilpang/acme.sh/issues/331#issuecomment-255583889
2016-10-23 20:36:32 +08:00
neilpang
9aa3be7f9f add _uninstallalias 2016-10-23 15:10:09 +08:00
neilpang
aba5c634ae minor, add output info for installing alias.
fix https://github.com/Neilpang/acme.sh/issues/332
2016-10-23 15:04:52 +08:00
neil
9774b01b0e 2.6.1 support IDN (#335)
* Support IDN

* fix deactivate idn name

* 2.6.1 support IDN
2016-10-23 14:56:52 +08:00
neil
ecf0a710e1 fix typo 2016-10-21 18:26:35 +08:00
neil
c9febbdd87 fix for centos ncat and debian default netcat (#330) 2016-10-19 22:14:42 +08:00
Peter Lyons
caa2e45a8c use RFC2606 example.com domain in docs (#327)
https://www.rfc-editor.org/rfc/rfc2606.txt
2016-10-13 10:14:36 +08:00
neilpang
d9130c9852 minor 2016-10-12 22:38:28 +08:00
neilpang
661f05837c minor 2016-10-12 21:48:18 +08:00
neilpang
a61fe418b2 support deploy api 2016-10-11 20:56:59 +08:00
neil
b15cfc2c5a minor 2016-10-11 18:30:38 +08:00
neil
c575c9af3d Merge branch 'master' of https://github.com/Neilpang/acme.sh 2016-10-11 18:06:35 +08:00
neil
81f27e9077 minor, get the error info, if it contains CRLF 2016-10-11 18:05:32 +08:00
neil
f78babfaa0 nc (#324) 2016-10-10 19:47:16 +08:00
neilpang
66990cf872 minor 2016-10-09 22:27:25 +08:00
root
095fe2ed1b minor 2016-10-09 22:19:35 +08:00
neil
483ebc8141 Update README.md 2016-10-09 22:17:45 +08:00
neilpang
b9311282eb minor fix pdns api 2016-10-09 22:15:15 +08:00
Maxim Zalysin
d6f0c2b52b Add support PowerDNS API (#322)
* Add support PowerDNS API

* Small fixes
2016-10-09 21:56:04 +08:00
neil
bb25febd70 Checkdomain (#317)
* check if domains are changed

* fix output info
2016-10-05 22:09:15 +08:00
neil
19ab2a29ce fix tail for solaris 2016-10-05 13:03:45 +08:00
neil
24b4fe9867 Merge branch 'master' of https://github.com/Neilpang/acme.sh 2016-10-05 12:16:14 +08:00
neil
aa7b82de04 minor 2016-10-05 12:15:06 +08:00
neil
3d826bed3a fix for ncat on centos, try without '-p' first (#315) 2016-10-04 23:35:56 +08:00
neil
d2ae7e78ef 60 days 2016-10-04 21:17:19 +08:00
neil
656bd330f8 change default renew days o 60.
fix https://github.com/Neilpang/acme.sh/issues/314
https://github.com/Neilpang/acme.sh/issues/281
2016-10-04 20:55:31 +08:00
neil
c2c8f32010 fix for wget 2016-10-03 22:29:48 +08:00
neil
9f43c270e6 fix wget 2016-10-03 22:08:40 +08:00
neil
50827188ff minor: save on success 2016-10-02 23:54:21 +08:00
neil
6ae0f7f5c6 support "--listen-v4" and "--listen-v6" (#311)
https://github.com/Neilpang/acme.sh/issues/310
2016-10-02 23:37:37 +08:00
neil
c583d6bb49 fix sleep display 2016-09-30 22:43:24 +08:00
neil
fdcb6b721c fix for busybox 2016-09-30 22:13:27 +08:00
neil
ef858ef062 use head -n 2016-09-30 21:37:39 +08:00
neil
fe04faf675 Add Chinese link 2016-09-30 21:27:23 +08:00
neil
ad752b317d support csr that contains empty CN field. fix https://github.com/Neilpang/acme.sh/issues/306 2016-09-29 22:19:03 +08:00
neil
59649e9b1e support --auto-upgrade 2016-09-28 22:11:00 +08:00
neil
6bf281f905 support '--auto-upgrade' 2016-09-28 22:05:43 +08:00
neil
4dfc8b262c support individual ca path 2016-09-28 13:27:32 +08:00
neil
f08ffe9feb v2.6.0 2016-09-28 13:26:02 +08:00
neil
65de3110a9 minor, fix error message 2016-09-28 13:13:08 +08:00
neil
f6dcd98995 save api first 2016-09-28 13:07:51 +08:00
neil
950172dc01 debug info 2016-09-27 23:52:52 +08:00
neil
5c48e139d4 support individual ca accounts 2016-09-27 23:43:18 +08:00
neil
150e9c8a48 Update README.md 2016-09-27 22:03:42 +08:00
neil
b19ba13aff fix for Mac osx 2016-09-27 21:27:43 +08:00
neil
30bfc2cea7 fix https://github.com/Neilpang/acme.sh/issues/304 2016-09-27 13:11:08 +08:00
neil
30c2d84c6d minor: remove useless hook. 2016-09-26 13:33:09 +08:00
neil
fbd2038fa7 minor 2016-09-26 13:08:19 +08:00
neil
e4b8d9b9d6 minor, No need to save ACCOUNT_URL 2016-09-25 22:54:58 +08:00
neil
6b50003697 minor 2016-09-25 22:26:41 +08:00
neil
a73c5b3355 support log level 2016-09-25 21:58:59 +08:00
neil
eb59817e81 Support updateaccount and registeraccount. fix https://github.com/Neilpang/acme.sh/issues/70 2016-09-25 10:56:06 +08:00
neil
d404e92d16 Fetch agreement tos dynamically, fix https://github.com/Neilpang/acme.sh/issues/253 2016-09-24 23:53:53 +08:00
neil
86c017ec9d fix deactivate return code 2016-09-24 14:17:04 +08:00
neil
0407c4e0f7 minor 2016-09-24 14:01:28 +08:00
neil
0ba95a3dd4 fix auto upgrade 2016-09-24 13:43:08 +08:00
neil
0463b5d6cd support "--local-address" to specify a listening ip address in standalone mode if the server have multiple ips. By default, the standalone server listens to 0.0.0.0 2016-09-23 23:14:03 +08:00
neil
3f4513b3a9 Support deactivate in bulk 2016-09-23 22:35:13 +08:00
neil
fb2029e717 add more info 2016-09-22 23:25:32 +08:00
neil
48f02fb61b minor 2016-09-22 23:23:27 +08:00
neil
0c00e870c6 Support Authorization deactivation
https://github.com/Neilpang/acme.sh/issues/291
2016-09-22 23:17:50 +08:00
neil
7da50703fb minor 2016-09-22 21:38:11 +08:00
neil
cfdaff5a46 fix cf 2016-09-22 20:36:33 +08:00
neil
18e46962c2 fix https://github.com/Neilpang/acme.sh/issues/297 2016-09-22 13:15:25 +08:00
neil
319e0ae3cf fix auto upgrade 2016-09-21 13:39:39 +08:00
neil
e69a7c38d9 fix auto upgrade 2016-09-21 13:27:05 +08:00
neil
ecd685755b fix auto upgrade 2016-09-21 13:18:46 +08:00
neil
276b51d927 minor 2016-09-21 13:09:22 +08:00
neil
251d1c5c9f minor 2016-09-20 22:23:49 +08:00
neil
028e17475f minor, renew time minus 1 day 2016-09-20 21:03:43 +08:00
neil
1ab630435d fix color when upgrade in cronjob 2016-09-20 20:34:33 +08:00
neil
89002ed298 support AUTO_UPGRADE. In the cron job, try to upgrade acme.sh if "AUTO_UPGRADE" is set. 2016-09-20 20:22:25 +08:00
neil
d0871bdae3 rename "--logfile" to "--log", and give a default log file 2016-09-20 19:08:02 +08:00
neil
5ea6e9c9c0 support "--logfile" 2016-09-19 23:07:43 +08:00
27 changed files with 5845 additions and 1990 deletions

25
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,25 @@
<!--
请确保已经更新到最新的代码, 然后贴上来 `--debug 2` 的调试输出. 没有调试输出,我帮不了你.
如何调试 https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh
If it is a bug report:
- make sure you are able to repro it on the latest released version.
You can install the latest version by: `acme.sh --upgrade`
- Search the existing issues.
- Refer to the [WIKI](https://wiki.acme.sh).
- Debug info [Debug](https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh).
-->
Steps to reproduce
------------------
Debug log
-----------------
```
acme.sh --issue ..... --debug 2
```

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.
-->

53
.travis.yml Normal file
View File

@@ -0,0 +1,53 @@
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 "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 TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" OPENSSL_BIN="$OPENSSL_BIN" ./letest.sh ; fi
matrix:
fast_finish: true

248
README.md
View File

@@ -1,19 +1,26 @@
# An ACME Shell script: acme.sh
# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)
- An ACME protocol client written purely in Shell (Unix shell) language.
- Fully ACME protocol implementation.
- Simple, powerful and very easy to use. You only need 3 minutes to learn.
- 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
#Tested OS
Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
# [中文说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E)
# 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
@@ -34,42 +41,43 @@ Wiki: https://github.com/Neilpang/acme.sh/wiki
|16|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/mageia.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Mageia
|17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/Neilpang/acme.sh/wiki/How-to-run-on-OpenWRT)
|18|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/solaris.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|SunOS/Solaris
|19|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/gentoo-stage3-amd64.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Gentoo Linux
|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
- [Stateless mode](https://github.com/Neilpang/acme.sh/wiki/Stateless-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
@@ -79,14 +87,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:
@@ -94,180 +102,204 @@ 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.
```bash
acme.sh --issue -d aa.com -w /home/wwwroot/aa.com
acme.sh --issue -d example.com -w /home/wwwroot/example.com
```
**Example 2:** Multiple domains in the same cert.
```bash
acme.sh --issue -d aa.com -d www.aa.com -d cp.aa.com -w /home/wwwroot/aa.com
acme.sh --issue -d example.com -d www.example.com -d cp.example.com -w /home/wwwroot/example.com
```
The parameter `/home/wwwroot/aa.com` is the web root folder. You **MUST** have `write access` to this folder.
The parameter `/home/wwwroot/example.com` is the web root folder. You **MUST** have `write access` to this folder.
Second argument **"aa.com"** is the main domain you want to issue cert for.
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/aa.com`.
You must point and bind all the domains to the same webroot dir: `/home/wwwroot/example.com`.
Generate/issued certs will be placed in `~/.acme.sh/aa.com/`
Generated/issued certs will be placed in `~/.acme.sh/example.com/`
The issued cert will be renewed every 80 days automatically.
The issued cert will be renewed automatically every **60** days.
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
# 3. Install issued cert to apache/nginx etc.
# 3. Install the issued cert to Apache/Nginx etc.
After you issue a cert, you probably want to install the cert with your nginx/apache or other servers you may be using.
After you issue a cert, you probably want to install/copy the cert to your 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.
**Apache** example:
```bash
acme.sh --installcert -d aa.com \
--certpath /path/to/certfile/in/apache/nginx \
--keypath /path/to/keyfile/in/apache/nginx \
--capath /path/to/ca/certfile/apache/nginx \
--fullchainpath path/to/fullchain/certfile/apache/nginx \
--reloadcmd "service apache2|nginx reload"
acme.sh --install-cert -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 force-reload"
```
**Nginx** example:
```bash
acme.sh --install-cert -d example.com \
--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 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 80 days by default` (which is configurable). Once the cert is renewed, the apache/nginx will be automatically reloaded by the command: `service apache2 reload` or `service nginx reload`.
# 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 aa.com -d www.aa.com -d cp.aa.com
acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com
```
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
# 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 aa.com -d www.aa.com -d cp.aa.com
acme.sh --issue --tls -d example.com -d www.example.com -d cp.example.com
```
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
# 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 aa.com -d www.aa.com -d user.aa.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 aa.com -d www.aa.com -d user.aa.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:
Domain:_acme-challenge.aa.com
Domain:_acme-challenge.example.com
Txt value:9ihDbjYfTExAYeDs4DBUeuTo18KBzwvTEjUnSwd32-c
Add the following txt record:
Domain:_acme-challenge.www.aa.com
Domain:_acme-challenge.www.example.com
Txt value:9ihDbjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Please add those txt records to the domains. Waiting for the dns to take effect.
```
Then just rerun with `renew` argument:
```bash
acme.sh --renew -d aa.com
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. 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. 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
1. Linode.com API
1. FreeDNS (https://freedns.afraid.org/)
##### 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/aa.com -d aa.com --keylength ec-256
acme.sh --issue -w /home/wwwroot/example.com -d example.com --keylength ec-256
```
SAN multi domain ECC certificate:
### SAN multi domain ECC certificate
```bash
acme.sh --issue -w /home/wwwroot/aa.com -d aa.com -d www.aa.com --keylength ec-256
acme.sh --issue -w /home/wwwroot/example.com -d example.com -d www.example.com --keylength ec-256
```
Please look at the last parameter above.
@@ -279,30 +311,49 @@ 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 80 days.
No, you don't need to renew the certs manually. All the certs will be renewed automatically every **60** days.
However, you can also force to renew any cert:
```
acme.sh --renew -d aa.com --force
acme.sh --renew -d example.com --force
```
or, for ECC cert:
```
acme.sh --renew -d aa.com --force --ecc
acme.sh --renew -d example.com --force --ecc
```
# 11. How to upgrade `acme.sh`
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
```
# 12. Issue a cert from existing CSR
You can also enable auto upgrade:
```
acme.sh --upgrade --auto-upgrade
```
Then **acme.sh** will be kept up to date automatically.
Disable auto upgrade:
```
acme.sh --upgrade --auto-upgrade 0
```
# 12. Issue a cert from an existing CSR
https://github.com/Neilpang/acme.sh/wiki/Issue-a-cert-from-existing-CSR
@@ -313,22 +364,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 & Other
# 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)

4270
acme.sh

File diff suppressed because it is too large Load Diff

30
deploy/README.md Normal file
View File

@@ -0,0 +1,30 @@
# Using deploy api
Here are the scripts to deploy the certs/key to the server/services.
## 1. Deploy the certs to your cpanel host.
(cpanel deploy hook is not finished yet, this is just an example.)
Before you can deploy your cert, you must [issue the cert first](https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert).
Then you can deploy now:
```sh
export DEPLOY_CPANEL_USER=myusername
export DEPLOY_CPANEL_PASSWORD=PASSWORD
acme.sh --deploy -d example.com --deploy --deploy-hook cpanel
```
## 2. Deploy ssl cert on kong proxy engine based on api.
Before you can deploy your cert, you must [issue the cert first](https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert).
(TODO)
## 3. Deploy the cert to remote server through SSH access.
(TODO)

29
deploy/cpanel.sh Normal file
View File

@@ -0,0 +1,29 @@
#!/usr/bin/env sh
#Here is the script to deploy the cert to your cpanel account by the cpanel APIs.
#returns 0 means success, otherwise error.
#export DEPLOY_CPANEL_USER=myusername
#export DEPLOY_CPANEL_PASSWORD=PASSWORD
######## Public functions #####################
#domain keyfile certfile cafile fullchain
cpanel_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
_err "Not implemented yet"
return 1
}

81
deploy/kong.sh Executable file
View File

@@ -0,0 +1,81 @@
#!/usr/bin/env sh
# This deploy hook will deploy ssl cert on kong proxy engine based on api request_host parameter.
# Note that ssl plugin should be available on Kong instance
# The hook will match cdomain to request_host, in case of multiple domain it will always take the first
# one (acme.sh behaviour).
# If ssl config already exist it will update only cert and key not touching other parameter
# If ssl config doesn't exist it will only upload cert and key and not set other parameter
# Not that we deploy full chain
# See https://getkong.org/plugins/dynamic-ssl/ for other options
# Written by Geoffroi Genot <ggenot@voxbone.com>
######## Public functions #####################
#domain keyfile certfile cafile fullchain
kong_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_info "Deploying certificate on Kong instance"
if [ -z "$KONG_URL" ]; then
_debug "KONG_URL Not set, using default http://localhost:8001"
KONG_URL="http://localhost:8001"
fi
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
#Get uuid linked to the domain
uuid=$(_get "$KONG_URL/apis?request_host=$_cdomain" | _normalizeJson | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')
if [ -z "$uuid" ]; then
_err "Unable to get Kong uuid for domain $_cdomain"
_err "Make sure that KONG_URL is correctly configured"
_err "Make sure that a Kong api request_host match the domain"
_err "Kong url: $KONG_URL"
return 1
fi
#Save kong url if it's succesful (First run case)
_saveaccountconf KONG_URL "$KONG_URL"
#Generate DEIM
delim="-----MultipartDelimeter$(date "+%s%N")"
nl="\015\012"
#Set Header
_H1="Content-Type: multipart/form-data; boundary=$delim"
#Generate data for request (Multipart/form-data with mixed content)
#set name to ssl
content="--$delim${nl}Content-Disposition: form-data; name=\"name\"${nl}${nl}ssl"
#add key
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"config.key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")"
#Add cert
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"config.cert\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")"
#Close multipart
content="$content${nl}--$delim--${nl}"
#Convert CRLF
content=$(printf %b "$content")
#DEBUG
_debug header "$_H1"
_debug content "$content"
#Check if ssl plugins is aready enabled (if not => POST else => PATCH)
ssl_uuid=$(_get "$KONG_URL/apis/$uuid/plugins" | _egrep_o '"id":"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"[a-zA-Z0-9\-\,\"_\:]*"name":"ssl"' | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')
_debug ssl_uuid "$ssl_uuid"
if [ -z "$ssl_uuid" ]; then
#Post certificate to Kong
response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins" "" "POST")
else
#patch
response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins/$ssl_uuid" "" "PATCH")
fi
if ! [ "$(echo "$response" | _egrep_o "ssl")" = "ssl" ]; then
_err "An error occured with cert upload. Check response:"
_err "$response"
return 1
fi
_debug response "$response"
_info "Certificate successfully deployed"
}

28
deploy/myapi.sh Executable file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env sh
#Here is a sample custom api script.
#This file name is "myapi.sh"
#So, here must be a method myapi_deploy()
#Which will be called by acme.sh to deploy the cert
#returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
myapi_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
_err "Not implemented yet"
return 1
}

View File

@@ -1,118 +1,327 @@
# 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 aa.com -d www.aa.com
acme.sh --issue --dns dns_cf -d example.com -d www.example.com
```
The `CF_Key` and `CF_Email` will be saved in `~/.acme.sh/account.conf`, when next time you use cloudflare api, it will reuse this key.
The `CF_Key` and `CF_Email` will be saved in `~/.acme.sh/account.conf` 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 aa.com -d www.aa.com
acme.sh --issue --dns dns_dp -d example.com -d www.example.com
```
The `DP_Id` and `DP_Key` will be saved in `~/.acme.sh/account.conf`, when next time you use dnspod.cn api, it will reuse this key.
The `DP_Id` and `DP_Key` will be saved in `~/.acme.sh/account.conf` 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 aa.com -d www.aa.com
acme.sh --issue --dns dns_cx -d example.com -d www.example.com
```
The `CX_Key` and `CX_Secret` will be saved in `~/.acme.sh/account.conf`, when next time you use Cloudxns.com api, it will reuse this key.
The `CX_Key` and `CX_Secret` will be saved in `~/.acme.sh/account.conf` 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 integeration.
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 aa.com -d www.aa.com
acme.sh --issue --dns dns_gd -d example.com -d www.example.com
```
The `GD_Key` and `GD_Secret` will be saved in `~/.acme.sh/account.conf`, when next time you use cloudflare api, it will reuse this key.
The `GD_Key` and `GD_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## Use OVH/kimsufi/soyoustart/runabove API
## 5. Use PowerDNS embedded API to automatically issue cert
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/
```
export PDNS_Url="http://ns.example.com:8081"
export PDNS_ServerId="localhost"
export PDNS_Token="0123456789ABCDEF"
export PDNS_Ttl=60
```
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_pdns -d example.com -d www.example.com
```
The `PDNS_Url`, `PDNS_ServerId`, `PDNS_Token` and `PDNS_Ttl` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 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.
## 7. Use nsupdate to automatically issue cert
Let's assume you want to name it 'myapi',
First, generate a key for updating the zone
```
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}
```
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:
Include this key in your named configuration
```
include "/etc/named/keys/update.key";
```
Next, configure your zone to allow dynamic updates.
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.;
};
}
```
Finally, make the DNS server and update Key available to `acme.sh`
```
acme.sh --issue --dns dns_myapi -d aa.com -d www.aa.com
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 -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.
## 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 -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.
## 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.
## 14. Use Linode domain API
First you need to login to your Linode account to get your API Key.
[https://manager.linode.com/profile/api](https://manager.linode.com/profile/api)
Then add an API key with label *ACME* and copy the new key.
```sh
export LINODE_API_KEY="..."
```
Due to the reload time of any changes in the DNS records, we have to use the `dnssleep` option to wait at least 15 minutes for the changes to take effect.
Ok, let's issue a cert now:
```sh
acme.sh --issue --dns dns_linode --dnssleep 900 -d example.com -d www.example.com
```
The `LINODE_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 15. Use FreeDNS
FreeDNS (https://freedns.afraid.org/) does not provide an API to update DNS records (other than IPv4 and IPv6
dynamic DNS addresses). The acme.sh plugin therefore retrieves and updates domain TXT records by logging
into the FreeDNS website to read the HTML and posting updates as HTTP. The plugin needs to know your
userid and password for the FreeDNS website.
```sh
export FREEDNS_User="..."
export FREEDNS_Password="..."
```
You need only provide this the first time you run the acme.sh client with FreeDNS validation and then again
whenever you change your password at the FreeDNS site. The acme.sh FreeDNS plugin does not store your userid
or password but rather saves an authentication token returned by FreeDNS in `~/.acme.sh/account.conf` and
reuses that when needed.
Now you can issue a certificate.
```sh
acme.sh --issue --dns dns_freedns -d example.com -d www.example.com
```
Note that you cannot use acme.sh automatic DNS validation for FreeDNS public domains or for a subdomain that
you create under a FreeDNS public domain. You must own the top level domain in order to automaitcally
validate with acme.sh at FreeDNS.
# 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
# Use lexicon DNS API
https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api

147
dnsapi/dns_ad.sh Executable 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 Executable 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" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _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 Executable 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>/#&/g' | tr '#' '\n' | _egrep_o "<HostedZone><Id>[^<]*<.Id><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="$(printf "%s" "$kSecret" | _hex_dump | tr -d " ")"
_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

@@ -1,57 +1,61 @@
#!/usr/bin/env sh
#
#CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
#CF_Email="xxxx@sss.com"
CF_Api="https://api.cloudflare.com/client/v4"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_cf_add(){
dns_cf_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ] ; then
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
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
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain"
if ! printf "$response" | grep \"success\":true > /dev/null ; then
if ! printf "%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
if [ "$count" = "0" ]; then
_info "Adding record"
if _cf_rest POST "zones/$_domain_id/dns_records" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
if printf $response | grep $fulldomain > /dev/null ; then
_info "Added, sleeping 10 seconds"
sleep 10
#todo: check if the record takes effect
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, OK"
return 0
else
_err "Add txt record error."
@@ -61,27 +65,62 @@ dns_cf_add(){
_err "Add txt record error."
else
_info "Updating record"
record_id=$(printf "%s\n" "$response" | _egrep_o \"id\":\"[^\"]*\" | cut -d : -f 2 | tr -d \"| head -1)
_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\"}"
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
return 0;
_info "Updated, OK"
return 0
fi
_err "Update error"
return 1
fi
}
#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,28 +130,29 @@ _get_root() {
domain=$1
i=2
p=1
while [ '1' ] ; do
h=$(printf $domain | cut -d . -f $i-100)
if [ -z "$h" ] ; then
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 ! _cf_rest GET "zones?name=$h" ; then
return 1
fi
if printf $response | grep \"name\":\"$h\" >/dev/null ; then
_domain_id=$(printf "%s\n" "$response" | _egrep_o \"id\":\"[^\"]*\" | head -1 | cut -d : -f 2 | tr -d \")
if [ "$_domain_id" ] ; then
_sub_domain=$(printf $domain | cut -d . -f 1-$p)
if ! _cf_rest GET "zones?name=$h"; then
return 1
fi
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 "%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,25 +161,23 @@ _cf_rest() {
m=$1
ep="$2"
data="$3"
_debug $ep
_H1="X-Auth-Email: $CF_Email"
_H2="X-Auth-Key: $CF_Key"
_H3="Content-Type: application/json"
if [ "$data" ] ; then
_debug "$ep"
export _H1="X-Auth-Email: $CF_Email"
export _H2="X-Auth-Key: $CF_Key"
export _H3="Content-Type: application/json"
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
if [ "$?" != "0" ] ; then
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

View File

@@ -6,10 +6,8 @@
#
#CX_Secret="sADDsdasdgdsf"
CX_Api="https://www.cloudxns.net/api2"
#REST_API
######## Public functions #####################
@@ -17,45 +15,60 @@ CX_Api="https://www.cloudxns.net/api2"
dns_cx_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$CX_Key" ] || [ -z "$CX_Secret" ] ; then
if [ -z "$CX_Key" ] || [ -z "$CX_Secret" ]; then
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
if [ "$?" != "0" ]; then
_err "Error get existing records."
return 1
fi
if [ "$count" = "0" ] ; then
add_record $_domain $_sub_domain $txtvalue
if [ "$count" = "0" ]; then
add_record "$_domain" "$_sub_domain" "$txtvalue"
else
update_record $_domain $_sub_domain $txtvalue
update_record "$_domain" "$_sub_domain" "$txtvalue"
fi
if [ "$?" = "0" ] ; then
if [ "$?" = "0" ]; then
return 0
fi
return 1
}
#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
#return if the sub record already exists.
#echos the existing records count.
@@ -64,24 +77,24 @@ existing_records() {
_debug "Getting txt records"
root=$1
sub=$2
if ! _rest GET "record/$_domain_id?:domain_id?host_id=0&offset=0&row_num=100" ; then
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 '"record_id":[^{]*host":"'"$_sub_domain"'"[^}]*\}')
_debug seg "$seg"
if [ -z "$seg" ] ; then
if [ -z "$seg" ]; then
return 0
fi
if printf "$response" | grep '"type":"TXT"' > /dev/null ; then
if printf "%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
return 0
fi
}
#add the txt record.
@@ -90,14 +103,14 @@ add_record() {
root=$1
sub=$2
txtvalue=$3
fulldomain=$sub.$root
fulldomain="$sub.$root"
_info "Adding record"
if ! _rest POST "record" "{\"domain_id\": $_domain_id, \"host\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"type\":\"TXT\",\"ttl\":600, \"line_id\":1}"; then
return 1
fi
return 0
}
@@ -107,21 +120,18 @@ update_record() {
root=$1
sub=$2
txtvalue=$3
fulldomain=$sub.$root
fulldomain="$sub.$root"
_info "Updating record"
if _rest PUT "record/$record_id" "{\"domain_id\": $_domain_id, \"host\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"type\":\"TXT\",\"ttl\":600, \"line_id\":1}" ; then
if _rest PUT "record/$record_id" "{\"domain_id\": $_domain_id, \"host\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"type\":\"TXT\",\"ttl\":600, \"line_id\":1}"; then
return 0
fi
return 1
}
#################### Private functions bellow ##################################
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
@@ -131,79 +141,76 @@ _get_root() {
domain=$1
i=2
p=1
if ! _rest GET "domain" ; then
if ! _rest GET "domain"; 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)
_debug h "$h"
if [ -z "$h" ] ; then
if [ -z "$h" ]; then
#not valid
return 1;
return 1
fi
if printf "$response" | grep "$h." >/dev/null ; then
seg=$(printf "%s" "$response" | _egrep_o "{[^{]*\"$h\.\"[^}]*\}" )
if _contains "$response" "$h."; then
seg=$(printf "%s\n" "$response" | _egrep_o '"id":[^{]*"'"$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
if [ "$_domain_id" ]; then
_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
ep="$2"
_debug $ep
_debug ep "$ep"
url="$REST_API/$ep"
_debug url "$url"
cdate=$(date -u "+%Y-%m-%d %H:%M:%S UTC")
cdate=$(date -u "+%Y-%m-%d %H:%M:%S UTC")
_debug cdate "$cdate"
data="$3"
_debug data "$data"
sec="$CX_Key$url$data$cdate$CX_Secret"
_debug sec "$sec"
hmac=$(printf "$sec"| openssl md5 |cut -d " " -f 2)
hmac=$(printf "%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"
if [ "$data" ] ; then
response="$(_post "$data" "$url" "" $m)"
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")"
else
response="$(_get "$url")"
fi
if [ "$?" != "0" ] ; then
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
if ! printf "$response" | grep '"message":"success"' > /dev/null ; then
if ! _contains "$response" '"message":"success"'; then
return 1
fi
return 0
}

View File

@@ -6,51 +6,83 @@
#
#DP_Key="sADDsdasdgdsf"
REST_API="https://dnsapi.cn"
DP_Api="https://dnsapi.cn"
#REST_API
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_dp_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$DP_Id" ] || [ -z "$DP_Key" ] ; then
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
if [ "$?" != "0" ]; then
_err "Error get existing records."
return 1
fi
if [ "$count" = "0" ] ; then
add_record $_domain $_sub_domain $txtvalue
if [ "$count" = "0" ]; then
add_record "$_domain" "$_sub_domain" "$txtvalue"
else
update_record $_domain $_sub_domain $txtvalue
update_record "$_domain" "$_sub_domain" "$txtvalue"
fi
}
#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"
}
#usage: root sub
#return if the sub record already exists.
#echos the existing records count.
@@ -59,26 +91,26 @@ existing_records() {
_debug "Getting txt records"
root=$1
sub=$2
if ! _rest POST "Record.List" "login_token=$DP_Id,$DP_Key&domain_id=$_domain_id&sub_domain=$_sub_domain"; then
return 1
return 1
fi
if printf "$response" | grep 'No records' ; then
count=0;
return 0
if _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)
return 0
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."
return 1
fi
count=0
}
@@ -88,20 +120,19 @@ add_record() {
root=$1
sub=$2
txtvalue=$3
fulldomain=$sub.$root
fulldomain="$sub.$root"
_info "Adding record"
if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=默认"; then
return 1
fi
if printf "$response" | grep "Action completed successful" ; then
if _contains "$response" "Action completed successful"; then
return 0
fi
return 1 #error
}
@@ -111,26 +142,23 @@ update_record() {
root=$1
sub=$2
txtvalue=$3
fulldomain=$sub.$root
fulldomain="$sub.$root"
_info "Updating record"
if ! _rest POST "Record.Modify" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=默认&record_id=$record_id"; then
return 1
fi
if printf "$response" | grep "Action completed successful" ; then
if _contains "$response" "Action completed successful"; then
return 0
fi
return 1 #error
}
#################### Private functions bellow ##################################
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
@@ -140,59 +168,56 @@ _get_root() {
domain=$1
i=2
p=1
while [ '1' ] ; do
h=$(printf $domain | cut -d . -f $i-100)
if [ -z "$h" ] ; then
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1;
return 1
fi
if ! _rest POST "Domain.Info" "login_token=$DP_Id,$DP_Key&format=json&domain=$h"; then
return 1
fi
if printf "$response" | grep "Action completed successful" >/dev/null ; then
_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
if [ "$_domain_id" ]; then
_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
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

375
dnsapi/dns_freedns.sh Executable file
View File

@@ -0,0 +1,375 @@
#!/usr/bin/env sh
#This file name is "dns_freedns.sh"
#So, here must be a method dns_freedns_add()
#Which will be called by acme.sh to add the txt record to your api system.
#returns 0 means success, otherwise error.
#
#Author: David Kerr
#Report Bugs here: https://github.com/dkerr64/acme.sh
#
######## Public functions #####################
# Export FreeDNS userid and password in folowing variables...
# FREEDNS_User=username
# FREEDNS_Password=password
# login cookie is saved in acme account config file so userid / pw
# need to be set only when changed.
#Usage: dns_freedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_freedns_add() {
fulldomain="$1"
txtvalue="$2"
_info "Add TXT record using FreeDNS"
_debug "fulldomain: $fulldomain"
_debug "txtvalue: $txtvalue"
if [ -z "$FREEDNS_User" ] || [ -z "$FREEDNS_Password" ]; then
FREEDNS_User=""
FREEDNS_Password=""
if [ -z "$FREEDNS_COOKIE" ]; then
_err "You did not specify the FreeDNS username and password yet."
_err "Please export as FREEDNS_User / FREEDNS_Password and try again."
return 1
fi
using_cached_cookies="true"
else
FREEDNS_COOKIE="$(_freedns_login "$FREEDNS_User" "$FREEDNS_Password")"
if [ -z "$FREEDNS_COOKIE" ]; then
return 1
fi
using_cached_cookies="false"
fi
_debug "FreeDNS login cookies: $FREEDNS_COOKIE (cached = $using_cached_cookies)"
_saveaccountconf FREEDNS_COOKIE "$FREEDNS_COOKIE"
# split our full domain name into two parts...
i="$(echo "$fulldomain" | tr '.' ' ' | wc -w)"
i="$(_math "$i" - 1)"
top_domain="$(echo "$fulldomain" | cut -d. -f "$i"-100)"
i="$(_math "$i" - 1)"
sub_domain="$(echo "$fulldomain" | cut -d. -f -"$i")"
# Sometimes FreeDNS does not reurn the subdomain page but rather
# returns a page regarding becoming a premium member. This usually
# happens after a period of inactivity. Immediately trying again
# returns the correct subdomain page. So, we will try twice to
# load the page and obtain our domain ID
attempts=2
while [ "$attempts" -gt "0" ]; do
attempts="$(_math "$attempts" - 1)"
htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")"
if [ "$?" != "0" ]; then
if [ "$using_cached_cookies" = "true" ]; then
_err "Has your FreeDNS username and password channged? If so..."
_err "Please export as FREEDNS_User / FREEDNS_Password and try again."
fi
return 1
fi
# Now convert the tables in the HTML to CSV. This litte gem from
# http://stackoverflow.com/questions/1403087/how-can-i-convert-an-html-table-to-csv
subdomain_csv="$(echo "$htmlpage" \
| grep -i -e '</\?TABLE\|</\?TD\|</\?TR\|</\?TH' \
| sed 's/^[\ \t]*//g' \
| tr -d '\n' \
| sed 's/<\/TR[^>]*>/\n/Ig' \
| sed 's/<\/\?\(TABLE\|TR\)[^>]*>//Ig' \
| sed 's/^<T[DH][^>]*>\|<\/\?T[DH][^>]*>$//Ig' \
| sed 's/<\/T[DH][^>]*><T[DH][^>]*>/,/Ig' \
| grep 'edit.php?' \
| grep "$top_domain")"
# The above beauty ends with striping out rows that do not have an
# href to edit.php and do not have the top domain we are looking for.
# So all we should be left with is CSV of table of subdomains we are
# interested in.
# Now we have to read through this table and extract the data we need
lines="$(echo "$subdomain_csv" | wc -l)"
nl='
'
i=0
found=0
while [ "$i" -lt "$lines" ]; do
i="$(_math "$i" + 1)"
line="$(echo "$subdomain_csv" | cut -d "$nl" -f "$i")"
tmp="$(echo "$line" | cut -d ',' -f 1)"
if [ $found = 0 ] && _startswith "$tmp" "<td>$top_domain"; then
# this line will contain DNSdomainid for the top_domain
DNSdomainid="$(echo "$line" | cut -d ',' -f 2 | sed 's/^.*domain_id=//;s/>.*//')"
found=1
else
# lines contain DNS records for all subdomains
DNSname="$(echo "$line" | cut -d ',' -f 2 | sed 's/^[^>]*>//;s/<\/a>.*//')"
DNStype="$(echo "$line" | cut -d ',' -f 3)"
if [ "$DNSname" = "$fulldomain" ] && [ "$DNStype" = "TXT" ]; then
DNSdataid="$(echo "$line" | cut -d ',' -f 2 | sed 's/^.*data_id=//;s/>.*//')"
# Now get current value for the TXT record. This method may
# not produce accurate results as the value field is truncated
# on this webpage. To get full value we would need to load
# another page. However we don't really need this so long as
# there is only one TXT record for the acme chalenge subdomain.
DNSvalue="$(echo "$line" | cut -d ',' -f 4 | sed 's/^[^&quot;]*&quot;//;s/&quot;.*//;s/<\/td>.*//')"
if [ $found != 0 ]; then
break
# we are breaking out of the loop at the first match of DNS name
# and DNS type (if we are past finding the domainid). This assumes
# that there is only ever one TXT record for the LetsEncrypt/acme
# challenge subdomain. This seems to be a reasonable assumption
# as the acme client deletes the TXT record on successful validation.
fi
else
DNSname=""
DNStype=""
fi
fi
done
_debug "DNSname: $DNSname DNStype: $DNStype DNSdomainid: $DNSdomainid DNSdataid: $DNSdataid"
_debug "DNSvalue: $DNSvalue"
if [ -z "$DNSdomainid" ]; then
# If domain ID is empty then something went wrong (top level
# domain not found at FreeDNS).
if [ "$attempts" = "0" ]; then
# exhausted maximum retry attempts
_debug "$htmlpage"
_debug "$subdomain_csv"
_err "Domain $top_domain not found at FreeDNS"
return 1
fi
else
# break out of the 'retry' loop... we have found our domain ID
break
fi
_info "Domain $top_domain not found at FreeDNS"
_info "Retry loading subdomain page ($attempts attempts remaining)"
done
if [ -z "$DNSdataid" ]; then
# If data ID is empty then specific subdomain does not exist yet, need
# to create it this should always be the case as the acme client
# deletes the entry after domain is validated.
_freedns_add_txt_record "$FREEDNS_COOKIE" "$DNSdomainid" "$sub_domain" "$txtvalue"
return $?
else
if [ "$txtvalue" = "$DNSvalue" ]; then
# if value in TXT record matches value requested then DNS record
# does not need to be updated. But...
# Testing value match fails. Website is truncating the value field.
# So for now we will always go down the else path. Though in theory
# should never come here anyway as the acme client deletes
# the TXT record on successful validation, so we should not even
# have found a TXT record !!
_info "No update necessary for $fulldomain at FreeDNS"
return 0
else
# Delete the old TXT record (with the wrong value)
_freedns_delete_txt_record "$FREEDNS_COOKIE" "$DNSdataid"
if [ "$?" = "0" ]; then
# And add in new TXT record with the value provided
_freedns_add_txt_record "$FREEDNS_COOKIE" "$DNSdomainid" "$sub_domain" "$txtvalue"
fi
return $?
fi
fi
return 0
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_freedns_rm() {
fulldomain="$1"
txtvalue="$2"
_info "Delete TXT record using FreeDNS"
_debug "fulldomain: $fulldomain"
_debug "txtvalue: $txtvalue"
# Need to read cookie from conf file again in case new value set
# during login to FreeDNS when TXT record was created.
# acme.sh does not have a _readaccountconf() fuction
FREEDNS_COOKIE="$(_read_conf "$ACCOUNT_CONF_PATH" "FREEDNS_COOKIE")"
_debug "FreeDNS login cookies: $FREEDNS_COOKIE"
# Sometimes FreeDNS does not reurn the subdomain page but rather
# returns a page regarding becoming a premium member. This usually
# happens after a period of inactivity. Immediately trying again
# returns the correct subdomain page. So, we will try twice to
# load the page and obtain our TXT record.
attempts=2
while [ "$attempts" -gt "0" ]; do
attempts="$(_math "$attempts" - 1)"
htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")"
if [ "$?" != "0" ]; then
return 1
fi
# Now convert the tables in the HTML to CSV. This litte gem from
# http://stackoverflow.com/questions/1403087/how-can-i-convert-an-html-table-to-csv
subdomain_csv="$(echo "$htmlpage" \
| grep -i -e '</\?TABLE\|</\?TD\|</\?TR\|</\?TH' \
| sed 's/^[\ \t]*//g' \
| tr -d '\n' \
| sed 's/<\/TR[^>]*>/\n/Ig' \
| sed 's/<\/\?\(TABLE\|TR\)[^>]*>//Ig' \
| sed 's/^<T[DH][^>]*>\|<\/\?T[DH][^>]*>$//Ig' \
| sed 's/<\/T[DH][^>]*><T[DH][^>]*>/,/Ig' \
| grep 'edit.php?' \
| grep "$fulldomain")"
# The above beauty ends with striping out rows that do not have an
# href to edit.php and do not have the domain name we are looking for.
# So all we should be left with is CSV of table of subdomains we are
# interested in.
# Now we have to read through this table and extract the data we need
lines="$(echo "$subdomain_csv" | wc -l)"
nl='
'
i=0
found=0
while [ "$i" -lt "$lines" ]; do
i="$(_math "$i" + 1)"
line="$(echo "$subdomain_csv" | cut -d "$nl" -f "$i")"
DNSname="$(echo "$line" | cut -d ',' -f 2 | sed 's/^[^>]*>//;s/<\/a>.*//')"
DNStype="$(echo "$line" | cut -d ',' -f 3)"
if [ "$DNSname" = "$fulldomain" ] && [ "$DNStype" = "TXT" ]; then
DNSdataid="$(echo "$line" | cut -d ',' -f 2 | sed 's/^.*data_id=//;s/>.*//')"
DNSvalue="$(echo "$line" | cut -d ',' -f 4 | sed 's/^[^&quot;]*&quot;//;s/&quot;.*//;s/<\/td>.*//')"
_debug "DNSvalue: $DNSvalue"
# if [ "$DNSvalue" = "$txtvalue" ]; then
# Testing value match fails. Website is truncating the value
# field. So for now we will assume that there is only one TXT
# field for the sub domain and just delete it. Currently this
# is a safe assumption.
_freedns_delete_txt_record "$FREEDNS_COOKIE" "$DNSdataid"
return $?
# fi
fi
done
done
# If we get this far we did not find a match (after two attempts)
# Not necessarily an error, but log anyway.
_debug2 "$subdomain_csv"
_info "Cannot delete TXT record for $fulldomain/$txtvalue. Does not exist at FreeDNS"
return 0
}
#################### Private functions below ##################################
# usage: _freedns_login username password
# print string "cookie=value" etc.
# returns 0 success
_freedns_login() {
export _H1="Accept-Language:en-US"
username="$1"
password="$2"
url="https://freedns.afraid.org/zc.php?step=2"
_debug "Login to FreeDNS as user $username"
htmlpage="$(_post "username=$(printf '%s' "$username" | _url_encode)&password=$(printf '%s' "$password" | _url_encode)&submit=Login&action=auth" "$url")"
if [ "$?" != "0" ]; then
_err "FreeDNS login failed for user $username bad RC from _post"
return 1
fi
cookies="$(grep -i '^Set-Cookie.*dns_cookie.*$' "$HTTP_HEADER" | _head_n 1 | tr -d "\r\n" | cut -d " " -f 2)"
# if cookies is not empty then logon successful
if [ -z "$cookies" ]; then
_debug "$htmlpage"
_err "FreeDNS login failed for user $username. Check $HTTP_HEADER file"
return 1
fi
printf "%s" "$cookies"
return 0
}
# usage _freedns_retrieve_subdomain_page login_cookies
# echo page retrieved (html)
# returns 0 success
_freedns_retrieve_subdomain_page() {
export _H1="Cookie:$1"
export _H2="Accept-Language:en-US"
url="https://freedns.afraid.org/subdomain/"
_debug "Retrieve subdmoain page from FreeDNS"
htmlpage="$(_get "$url")"
if [ "$?" != "0" ]; then
_err "FreeDNS retrieve subdomins failed bad RC from _get"
return 1
elif [ -z "$htmlpage" ]; then
_err "FreeDNS returned empty subdomain page"
return 1
fi
_debug2 "$htmlpage"
printf "%s" "$htmlpage"
return 0
}
# usage _freedns_add_txt_record login_cookies domain_id subdomain value
# returns 0 success
_freedns_add_txt_record() {
export _H1="Cookie:$1"
export _H2="Accept-Language:en-US"
domain_id="$2"
subdomain="$3"
value="$(printf '%s' "$4" | _url_encode)"
url="http://freedns.afraid.org/subdomain/save.php?step=2"
htmlpage="$(_post "type=TXT&domain_id=$domain_id&subdomain=$subdomain&address=%22$value%22&send=Save%21" "$url")"
if [ "$?" != "0" ]; then
_err "FreeDNS failed to add TXT record for $subdomain bad RC from _post"
return 1
elif ! grep "200 OK" "$HTTP_HEADER" >/dev/null; then
_debug "$htmlpage"
_err "FreeDNS failed to add TXT record for $subdomain. Check $HTTP_HEADER file"
return 1
elif _contains "$htmlpage" "security code was incorrect"; then
_debug "$htmlpage"
_err "FreeDNS failed to add TXT record for $subdomain as FreeDNS requested seurity code"
_err "Note that you cannot use automatic DNS validation for FreeDNS public domains"
return 1
fi
_debug2 "$htmlpage"
_info "Added acme challenge TXT record for $fulldomain at FreeDNS"
return 0
}
# usage _freedns_delete_txt_record login_cookies data_id
# returns 0 success
_freedns_delete_txt_record() {
export _H1="Cookie:$1"
export _H2="Accept-Language:en-US"
data_id="$2"
url="https://freedns.afraid.org/subdomain/delete2.php"
htmlheader="$(_get "$url?data_id%5B%5D=$data_id&submit=delete+selected" "onlyheader")"
if [ "$?" != "0" ]; then
_err "FreeDNS failed to delete TXT record for $data_id bad RC from _get"
return 1
elif ! _contains "$htmlheader" "200 OK"; then
_debug "$htmlheader"
_err "FreeDNS failed to delete TXT record $data_id"
return 1
fi
_info "Deleted acme challenge TXT record for $fulldomain at FreeDNS"
return 0
}

View File

@@ -6,39 +6,39 @@
#
#GD_Secret="asdfsdfsfsdfsdfdfsdf"
GD_Api="https://api.godaddy.com/v1"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_gd_add(){
dns_gd_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$GD_Key" ] || [ -z "$GD_Secret" ] ; then
if [ -z "$GD_Key" ] || [ -z "$GD_Secret" ]; then
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
fi
#save the api key and email to the account conf file.
_saveaccountconf GD_Key "$GD_Key"
_saveaccountconf GD_Secret "$GD_Secret"
_debug "First detect the root zone"
if ! _get_root $fulldomain ; then
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_info "Adding record"
if _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[{\"data\":\"$txtvalue\"}]"; then
if [ "$response" = "{}" ] ; then
if _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[{\"data\":\"$txtvalue\"}]"; then
if [ "$response" = "{}" ]; then
_info "Added, sleeping 10 seconds"
sleep 10
#todo: check if the record takes effect
@@ -50,43 +50,44 @@ dns_gd_add(){
fi
fi
_err "Add txt record error."
}
#fulldomain
dns_gd_rm() {
fulldomain=$1
}
#################### 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)
if [ -z "$h" ] ; then
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1;
fi
if ! _gd_rest GET "domains/$h" ; then
return 1
fi
if printf "$response" | grep '"code":"NOT_FOUND"' >/dev/null ; then
if ! _gd_rest GET "domains/$h"; then
return 1
fi
if _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,24 +96,22 @@ _gd_rest() {
m=$1
ep="$2"
data="$3"
_debug $ep
_H1="Authorization: sso-key $GD_Key:$GD_Secret"
_H2="Content-Type: application/json"
if [ "$data" ] ; then
_debug "$ep"
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
if [ "$?" != "0" ] ; then
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

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"
@@ -13,15 +13,16 @@ wiki="https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api"
dns_lexicon_add() {
fulldomain=$1
txtvalue=$2
domain=$(printf "$fulldomain" | cut -d . -f 2-999)
if ! _exists $lexicon_cmd ; then
domain=$(printf "%s" "$fulldomain" | cut -d . -f 2-999)
if ! _exists "$lexicon_cmd"; then
_err "Please install $lexicon_cmd first: $wiki"
return 1
fi
if [ -z "$PROVIDER" ] ; then
if [ -z "$PROVIDER" ]; then
PROVIDER=""
_err "Please define env PROVIDER first: $wiki"
return 1
fi
@@ -29,41 +30,49 @@ 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"
fi
Lx_token=$(echo LEXICON_${PROVIDER}_TOKEN | tr [a-z] [A-Z])
eval Lx_token_v="\$$Lx_token"
_debug "$Lx_token" "$Lx_token_v"
if [ "$Lx_token_v" ] ; then
_saveaccountconf $Lx_token "$Lx_token_v"
export "$Lx_token"
fi
Lx_password=$(echo LEXICON_${PROVIDER}_PASSWORD | tr [a-z] [A-Z])
eval Lx_password_v="\$$Lx_password"
_debug "$Lx_password" "$Lx_password_v"
if [ "$Lx_password_v" ] ; then
_saveaccountconf $Lx_password "$Lx_password_v"
export "$Lx_password"
fi
Lx_domaintoken=$(echo LEXICON_${PROVIDER}_DOMAINTOKEN | tr [a-z] [A-Z])
eval Lx_domaintoken_v="\$$Lx_domaintoken"
_debug "$Lx_domaintoken" "$Lx_domaintoken_v"
if [ "$Lx_domaintoken_v" ] ; then
export "$Lx_domaintoken"
_saveaccountconf $Lx_domaintoken "$Lx_domaintoken_v"
if [ "$Lx_name_v" ]; then
_saveaccountconf "$Lx_name" "$Lx_name_v"
eval export "$Lx_name"
fi
$lexicon_cmd "$PROVIDER" create ${domain} TXT --name="_acme-challenge.${domain}." --content="${txtvalue}"
# 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"
eval export "$Lx_token"
fi
# 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"
eval export "$Lx_password"
fi
# 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
eval export "$Lx_domaintoken"
_saveaccountconf "$Lx_domaintoken" "$Lx_domaintoken_v"
fi
$lexicon_cmd "$PROVIDER" create "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}"
}
#fulldomain
dns_lexicon_rm() {
fulldomain=$1
}

183
dnsapi/dns_linode.sh Executable file
View File

@@ -0,0 +1,183 @@
#!/usr/bin/env sh
#Author: Philipp Grosswiler <philipp.grosswiler@swiss-design.net>
LINODE_API_URL="https://api.linode.com/?api_key=$LINODE_API_KEY&api_action="
######## Public functions #####################
#Usage: dns_linode_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_linode_add() {
fulldomain="${1}"
txtvalue="${2}"
if ! _Linode_API; then
return 1
fi
_info "Using Linode"
_debug "Calling: dns_linode_add() '${fulldomain}' '${txtvalue}'"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "Domain does not exist."
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_parameters="&DomainID=$_domain_id&Type=TXT&Name=$_sub_domain&Target=$txtvalue"
if _rest GET "domain.resource.create" "$_parameters" && [ -n "$response" ]; then
_resource_id=$(printf "%s\n" "$response" | _egrep_o "\"ResourceID\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1)
_debug _resource_id "$_resource_id"
if [ -z "$_resource_id" ]; then
_err "Error adding the domain resource."
return 1
fi
_info "Domain resource successfully added."
return 0
fi
return 1
}
#Usage: dns_linode_rm _acme-challenge.www.domain.com
dns_linode_rm() {
fulldomain="${1}"
if ! _Linode_API; then
return 1
fi
_info "Using Linode"
_debug "Calling: dns_linode_rm() '${fulldomain}'"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "Domain does not exist."
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_parameters="&DomainID=$_domain_id"
if _rest GET "domain.resource.list" "$_parameters" && [ -n "$response" ]; then
response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')"
resource="$(echo "$response" | _egrep_o "{.*\"NAME\":\s*\"$_sub_domain\".*}")"
if [ "$resource" ]; then
_resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"RESOURCEID\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
if [ "$_resource_id" ]; then
_debug _resource_id "$_resource_id"
_parameters="&DomainID=$_domain_id&ResourceID=$_resource_id"
if _rest GET "domain.resource.delete" "$_parameters" && [ -n "$response" ]; then
_resource_id=$(printf "%s\n" "$response" | _egrep_o "\"ResourceID\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1)
_debug _resource_id "$_resource_id"
if [ -z "$_resource_id" ]; then
_err "Error deleting the domain resource."
return 1
fi
_info "Domain resource successfully deleted."
return 0
fi
fi
return 1
fi
return 0
fi
return 1
}
#################### Private functions below ##################################
_Linode_API() {
if [ -z "$LINODE_API_KEY" ]; then
LINODE_API_KEY=""
_err "You didn't specify the Linode API key yet."
_err "Please create your key and try again."
return 1
fi
_saveaccountconf LINODE_API_KEY "$LINODE_API_KEY"
}
#################### 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 _rest GET "domain.list"; 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 "{.*\"DOMAIN\":\s*\"$h\".*}")"
if [ "$hostedzone" ]; then
_domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"DOMAINID\":\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 method action data
_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" "$LINODE_API_URL$ep" "" "$mtd")"
else
response="$(_get "$LINODE_API_URL$ep$data")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

145
dnsapi/dns_lua.sh Executable file
View File

@@ -0,0 +1,145 @@
#!/usr/bin/env sh
# bug reports to dev@1e.ca
#
#LUA_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
#LUA_Email="user@luadns.net"
LUA_Api="https://api.luadns.com/v1"
LUA_auth=$(printf "%s" "$LUA_Email:$LUA_Key" | _base64)
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_lua_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$LUA_Key" ] || [ -z "$LUA_Email" ]; then
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
fi
#save the api key and email to the account conf file.
_saveaccountconf LUA_Key "$LUA_Key"
_saveaccountconf LUA_Email "$LUA_Email"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_LUA_rest GET "zones/${_domain_id}/records"
if ! _contains "$response" "\"id\":"; then
_err "Error"
return 1
fi
count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | wc -l | tr -d " ")
_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 _contains "$response" "$fulldomain"; then
_info "Added"
#todo: check if the record takes effect
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
else
_info "Updating record"
record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | _head_n 1 | 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" ] && _contains "$response" "updated_at"; then
_info "Updated!"
#todo: check if the record takes effect
return 0
fi
_err "Update error"
return 1
fi
}
#fulldomain
dns_lua_rm() {
fulldomain=$1
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
# _domain_id=sdjkglgdfewsdfg
_get_root() {
domain=$1
i=2
p=1
if ! _LUA_rest GET "zones"; then
return 1
fi
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
if _contains "$response" "\"name\":\"$h\""; then
_domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$h\"" | cut -d : -f 2 | cut -d , -f 1)
_debug _domain_id "$_domain_id"
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
return 1
}
_LUA_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
export _H1="Accept: application/json"
export _H2="Authorization: Basic $LUA_auth"
if [ "$data" ]; then
_debug data "$data"
response="$(_post "$data" "$LUA_Api/$ep" "" "$m")"
else
response="$(_get "$LUA_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

146
dnsapi/dns_me.sh Executable file
View File

@@ -0,0 +1,146 @@
#!/usr/bin/env sh
# bug reports to dev@1e.ca
# ME_Key=qmlkdjflmkqdjf
# ME_Secret=qmsdlkqmlksdvnnpae
ME_Api=https://api.dnsmadeeasy.com/V2.0/dns/managed
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_me_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$ME_Key" ] || [ -z "$ME_Secret" ]; then
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
fi
#save the api key and email to the account conf file.
_saveaccountconf ME_Key "$ME_Key"
_saveaccountconf ME_Secret "$ME_Secret"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_me_rest GET "${_domain_id}/records?recordName=$_sub_domain&type=TXT"
if ! _contains "$response" "\"totalRecords\":"; then
_err "Error"
return 1
fi
count=$(printf "%s\n" "$response" | _egrep_o "\"totalRecords\":[^,]*" | cut -d : -f 2)
_debug count "$count"
if [ "$count" = "0" ]; then
_info "Adding record"
if _me_rest POST "$_domain_id/records/" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\",\"gtdLocation\":\"DEFAULT\",\"ttl\":120}"; then
if printf -- "%s" "$response" | grep \"id\": >/dev/null; then
_info "Added"
#todo: check if the record takes effect
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
else
_info "Updating record"
record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*" | cut -d : -f 2 | head -n 1)
_debug "record_id" "$record_id"
_me_rest PUT "$_domain_id/records/$record_id/" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\",\"gtdLocation\":\"DEFAULT\",\"ttl\":120}"
if [ "$?" = "0" ]; then
_info "Updated"
#todo: check if the record takes effect
return 0
fi
_err "Update error"
return 1
fi
}
#fulldomain
dns_me_rm() {
fulldomain=$1
}
#################### Private functions 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 true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1
fi
if ! _me_rest GET "name?domainname=$h"; then
return 1
fi
if _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 "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
return 0
fi
return 1
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_me_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
cdate=$(date -u +"%a, %d %b %Y %T %Z")
hmac=$(printf "%s" "$cdate" | _hmac sha1 "$(printf "%s" "$ME_Secret" | _hex_dump | tr -d " ")" hex)
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")"
else
response="$(_get "$ME_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

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;
}
#################### 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
#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"
}
_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
}

221
dnsapi/dns_ovh.sh Normal file → Executable file
View File

@@ -1,6 +1,5 @@
#!/usr/bin/env sh
#Applcation Key
#OVH_AK="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
@@ -10,10 +9,8 @@
#Consumer Key
#OVH_CK="sdfsdfsdfsdfsdfdsf"
#OVH_END_POINT=ovh-eu
#'ovh-eu'
OVH_EU='https://eu.api.ovh.com/1.0'
@@ -35,121 +32,118 @@ SYS_CA='https://ca.api.soyoustart.com/1.0'
#'runabove-ca'
RAV_CA='https://api.runabove.com/1.0'
wiki="https://github.com/Neilpang/acme.sh/wiki/How-to-use-OVH-domain-api"
ovh_success="https://github.com/Neilpang/acme.sh/wiki/OVH-Success"
_ovh_get_api() {
_ogaep="$1"
case "${_ogaep}" in
ovh-eu|ovheu)
printf "%s" $OVH_EU
return
;;
ovh-ca|ovhca)
printf "%s" $OVH_CA
return
;;
kimsufi-eu|kimsufieu)
printf "%s" $KSF_EU
return
;;
kimsufi-ca|kimsufica)
printf "%s" $KSF_CA
return
;;
soyoustart-eu|soyoustarteu)
printf "%s" $SYS_EU
return
;;
soyoustart-ca|soyoustartca)
printf "%s" $SYS_CA
return
;;
runabove-ca|runaboveca)
printf "%s" $RAV_CA
return
;;
ovh-eu | ovheu)
printf "%s" $OVH_EU
return
;;
ovh-ca | ovhca)
printf "%s" $OVH_CA
return
;;
kimsufi-eu | kimsufieu)
printf "%s" $KSF_EU
return
;;
kimsufi-ca | kimsufica)
printf "%s" $KSF_CA
return
;;
soyoustart-eu | soyoustarteu)
printf "%s" $SYS_EU
return
;;
soyoustart-ca | soyoustartca)
printf "%s" $SYS_CA
return
;;
runabove-ca | runaboveca)
printf "%s" $RAV_CA
return
;;
*)
_err "Unknown parameter : $1"
return 1
;;
esac
_err "Unknown parameter : $1"
return 1
;;
esac
}
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_ovh_add(){
dns_ovh_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$OVH_AK" ] || [ -z "$OVH_AS" ] ; then
if [ -z "$OVH_AK" ] || [ -z "$OVH_AS" ]; then
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
fi
#save the api key and email to the account conf file.
_saveaccountconf OVH_AK "$OVH_AK"
_saveaccountconf OVH_AS "$OVH_AS"
if [ -z "$OVH_END_POINT" ] ; then
if [ -z "$OVH_END_POINT" ]; then
OVH_END_POINT="ovh-eu"
fi
_info "Using OVH endpoint: $OVH_END_POINT"
if [ "$OVH_END_POINT" != "ovh-eu" ] ; then
_saveaccountconf OVH_END_POINT "$OVH_END_POINT"
if [ "$OVH_END_POINT" != "ovh-eu" ]; then
_saveaccountconf OVH_END_POINT "$OVH_END_POINT"
fi
OVH_API="$(_ovh_get_api $OVH_END_POINT )"
OVH_API="$(_ovh_get_api $OVH_END_POINT)"
_debug OVH_API "$OVH_API"
if [ -z "$OVH_CK" ] ; then
if [ -z "$OVH_CK" ]; then
_info "OVH consumer key is empty, Let's get one:"
if ! _ovh_authentication ; then
if ! _ovh_authentication; then
_err "Can not get consumer key."
fi
#return and wait for retry.
return 1;
return 1
fi
_info "Checking authentication"
response="$(_ovh_rest GET "domain/")"
if _contains "$response" "INVALID_CREDENTIAL" ; then
if _contains "$response" "INVALID_CREDENTIAL"; then
_err "The consumer key is invalid: $OVH_CK"
_err "Please retry to create a new one."
_clearaccountconf OVH_CK
_clearaccountconf OVH_CK
return 1
fi
_info "Consumer key is ok."
_debug "First detect the root zone"
if ! _get_root $fulldomain ; then
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_ovh_rest GET "domain/zone/$_domain/record?fieldType=TXT&subDomain=$_sub_domain"
if _contains "$response" '\[\]' || _contains "$response" "This service does not exist" ; then
if _contains "$response" '\[\]' || _contains "$response" "This service does not exist"; then
_info "Adding record"
if _ovh_rest POST "domain/zone/$_domain/record" "{\"fieldType\":\"TXT\",\"subDomain\":\"$_sub_domain\",\"target\":\"$txtvalue\",\"ttl\":60}"; then
if _contains "$response" "$txtvalue" ; then
if _ovh_rest POST "domain/zone/$_domain/record" "{\"fieldType\":\"TXT\",\"subDomain\":\"$_sub_domain\",\"target\":\"$txtvalue\",\"ttl\":60}"; then
if _contains "$response" "$txtvalue"; then
_ovh_rest POST "domain/zone/$_domain/refresh"
_debug "Refresh:$response"
_info "Added, sleeping 10 seconds"
@@ -161,93 +155,96 @@ dns_ovh_add(){
else
_info "Updating record"
record_id=$(printf "%s" "$response" | tr -d "[]" | cut -d , -f 1)
if [ -z "$record_id" ] ; then
if [ -z "$record_id" ]; then
_err "Can not get record id."
return 1
fi
_debug "record_id" $record_id
_debug "record_id" "$record_id"
if _ovh_rest PUT "domain/zone/$_domain/record/$record_id" "{\"target\":\"$txtvalue\",\"subDomain\":\"$_sub_domain\",\"ttl\":60}" ; then
if _contains "$response" "null" ; then
if _ovh_rest PUT "domain/zone/$_domain/record/$record_id" "{\"target\":\"$txtvalue\",\"subDomain\":\"$_sub_domain\",\"ttl\":60}"; then
if _contains "$response" "null"; then
_ovh_rest POST "domain/zone/$_domain/refresh"
_debug "Refresh:$response"
_info "Updated, sleeping 10 seconds"
sleep 10
return 0;
return 0
fi
fi
_err "Update error"
return 1
fi
}
#fulldomain
dns_ovh_rm() {
fulldomain=$1
#################### Private functions bellow ##################################
}
#################### Private functions below ##################################
_ovh_authentication() {
_H1="X-Ovh-Application: $OVH_AK"
_H2="Content-type: application/json"
_H3=""
_H4=""
_ovhdata='{"accessRules": [{"method": "GET","path": "/*"},{"method": "POST","path": "/*"},{"method": "PUT","path": "/*"},{"method": "DELETE","path": "/*"}],"redirection":"'$ovh_success'"}'
response="$(_post "$_ovhdata" "$OVH_API/auth/credential")"
_debug3 response "$response"
validationUrl="$(echo "$response" | _egrep_o "validationUrl\":\"[^\"]*\"" | _egrep_o "http.*\"" | tr -d '"')"
if [ -z "$validationUrl" ] ; then
if [ -z "$validationUrl" ]; then
_err "Unable to get validationUrl"
return 1
fi
_debug validationUrl "$validationUrl"
consumerKey="$(echo "$response" | _egrep_o "consumerKey\":\"[^\"]*\"" | cut -d : -f 2 | tr -d '"')"
if [ -z "$consumerKey" ] ; then
if [ -z "$consumerKey" ]; then
_err "Unable to get consumerKey"
return 1
fi
_debug consumerKey "$consumerKey"
OVH_CK="$consumerKey"
_saveaccountconf OVH_CK "$OVH_CK"
_info "Please open this link to do authentication: $(__green "$validationUrl" )"
_info "Here is a guide for you: $(__green "$wiki" )"
_info "Please open this link to do authentication: $(__green "$validationUrl")"
_info "Here is a guide for you: $(__green "$wiki")"
_info "Please retry after the authentication is done."
}
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
# _domain_id=sdjkglgdfewsdfg
_get_root() {
domain=$1
i=2
p=1
while [ '1' ] ; do
h=$(printf $domain | cut -d . -f $i-100)
if [ -z "$h" ] ; then
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1;
fi
if ! _ovh_rest GET "domain/zone/$h" ; then
return 1
fi
if ! _contains "$response" "This service does not exist" >/dev/null ; then
_sub_domain=$(printf $domain | cut -d . -f 1-$p)
_domain=$h
if ! _ovh_rest GET "domain/zone/$h"; then
return 1
fi
if ! _contains "$response" "This service does not exist" >/dev/null; then
_sub_domain=$(printf "%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
}
@@ -265,9 +262,8 @@ _ovh_rest() {
m=$1
ep="$2"
data="$3"
_debug $ep
_debug "$ep"
_ovh_url="$OVH_API/$ep"
_debug2 _ovh_url "$_ovh_url"
_ovh_t="$(_ovh_timestamp)"
@@ -276,27 +272,24 @@ _ovh_rest() {
_debug _ovh_p "$_ovh_p"
_ovh_hex="$(printf "%s" "$_ovh_p" | _digest sha1 hex)"
_debug2 _ovh_hex "$_ovh_hex"
_H1="X-Ovh-Application: $OVH_AK"
_H2="X-Ovh-Signature: \$1\$$_ovh_hex"
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"
if [ "$data" ] || [ "$m" = "POST" ] || [ "$m" = "PUT" ] ; then
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
if [ "$?" != "0" ] ; then
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

184
dnsapi/dns_pdns.sh Executable file
View File

@@ -0,0 +1,184 @@
#!/usr/bin/env sh
#PowerDNS Emdedded API
#https://doc.powerdns.com/md/httpapi/api_spec/
#
#PDNS_Url="http://ns.example.com:8081"
#PDNS_ServerId="localhost"
#PDNS_Token="0123456789ABCDEF"
#PDNS_Ttl=60
DEFAULT_PDNS_TTL=60
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000"
#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"
fi
#save the api addr and key to the account conf file.
_saveaccountconf PDNS_Url "$PDNS_Url"
_saveaccountconf PDNS_ServerId "$PDNS_ServerId"
_saveaccountconf PDNS_Token "$PDNS_Token"
if [ "$PDNS_Ttl" != "$DEFAULT_PDNS_TTL" ]; then
_saveaccountconf PDNS_Ttl "$PDNS_Ttl"
fi
_debug "Detect root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain "$_domain"
if ! set_record "$_domain" "$fulldomain" "$txtvalue"; then
return 1
fi
return 0
}
#fulldomain
dns_pdns_rm() {
fulldomain=$1
_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() {
_info "Adding record"
root=$1
full=$2
txtvalue=$3
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 ! notify_slaves "$root"; then
return 1
fi
return 0
}
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
if _pdns_rest "GET" "/api/v1/servers/$PDNS_ServerId/zones"; then
_zones_response="$response"
fi
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
return 1
fi
if _contains "$_zones_response" "\"name\": \"$h.\""; then
_domain="$h"
return 0
fi
i=$(_math $i + 1)
done
_debug "$domain not found"
return 1
}
_pdns_rest() {
method=$1
ep=$2
data=$3
export _H1="X-API-Key: $PDNS_Token"
if [ ! "$method" = "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$PDNS_Url$ep" "" "$method")"
else
response="$(_get "$PDNS_Url$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}