Compare commits

...

1832 Commits

Author SHA1 Message Date
neil
bc2642f6d4 getdnsconf 2019-07-16 18:31:33 +08:00
Jeff Wang
3cdfa4051d Change 1.1.1.1 to 1.0.0.1 to probe compatibility (#2330)
As we can see, 1.1.1.1 is not routed or routed to an Intranet devices due to historical reason. Change 1.1.1.1 to 1.0.0.1 will have a better compatibility. I found this problem on my Tencent Cloud server.
2019-07-13 23:05:30 +08:00
Honza Hommer
28a9df669d Escape slashes (#2375) 2019-07-13 20:35:09 +08:00
neilpang
42497028c4 ttl 3000 2019-07-13 19:35:55 +08:00
neilpang
57b16e3ac2 fix format 2019-07-13 17:42:01 +08:00
neilpang
bd9af86de1 support jdcloud.com 2019-07-13 17:33:04 +08:00
neilpang
d694ee8651 update 2019-06-30 10:48:21 +08:00
neil
0e9fbf3c5a Merge pull request #2365 from Neilpang/master
sync
2019-06-30 10:38:36 +08:00
neil
ec40807c54 Merge pull request #2364 from Raphux/master
dns_azure : Multiple domains with same ending bug
2019-06-30 10:37:13 +08:00
Raphaël Berlamont
971a85a6f8 dns_azure : Multiple domains with same ending bug
We have a few domains that ends the same. For example :
  iperfony.com
  perfony.com

The problem was in the _get_root functions, when getting the domain_id :
only the first result "iperfony.com" was returned, because "perfony.com"
is contained in the "iperfony.com" string.

The correction consist of being strict in the regex, adding a slash (/)
so that it will only match on ".*/(perfony.com).*" and not
".*(perfony.com).*".
2019-06-29 18:14:34 +02:00
neil
8e36695bc4 Merge pull request #2182 from maxemann96/oath
Added oathtool to Dockerfile
2019-06-22 23:44:18 +08:00
maxemann96
2e2e056198 Merge branch 'dev' into oath 2019-06-21 23:52:10 +02:00
Maximilian Hippler
e0d4115ed7 Finally added oathtool 2019-06-21 23:43:32 +02:00
neil
6ff3f5d1ff Merge pull request #2346 from Neilpang/dev
sync
2019-06-19 21:51:51 +08:00
neilpang
a2738e8599 minor, add debug info 2019-06-19 21:50:41 +08:00
neilpang
468edfa6cc Merge branch 'dev' of github.com:Neilpang/acme.sh into dev 2019-06-19 21:50:08 +08:00
neilpang
c83f2f98bd fix https://github.com/Neilpang/acme.sh/issues/2300 2019-06-19 21:49:42 +08:00
neil
06f860c8ea Merge pull request #2292 from cngarrison/master
change to routeros native script rather than bash multiline commands
2019-06-19 21:27:32 +08:00
neil
24e574ee09 Merge pull request #2324 from deflorator1980/dns-api-regru
Dns api regru
2019-06-17 22:05:41 +08:00
neil
803b67af9f Merge pull request #2342 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/2341
2019-06-15 08:33:54 +08:00
neilpang
f803c6c0bf fix https://github.com/Neilpang/acme.sh/issues/2341 2019-06-15 08:33:16 +08:00
neil
254feecf21 Merge pull request #2339 from Neilpang/dev
fix  https://github.com/Neilpang/acme.sh/issues/2321
2019-06-14 23:56:50 +08:00
neilpang
c6b6855131 fix https://github.com/Neilpang/acme.sh/issues/2321
https://github.com/Neilpang/acme.sh/issues/2291
2019-06-14 23:55:59 +08:00
neil
9bc45563ee Merge pull request #2338 from Neilpang/dev
Dev
2019-06-14 23:07:43 +08:00
neilpang
882ac74a0c fix issue: clear Le_Vlist earlier 2019-06-14 22:41:28 +08:00
AndreyIsakov
d883a870e1 dnsapi for regru: remove debug info 2019-06-13 19:56:40 +03:00
AndreyIsakov
f2c6e3f65b dnsapi for regru: replace echo by _info() 2019-06-13 19:31:44 +03:00
neil
1ff3dcf138 Merge pull request #2332 from endreszabo/patch-1
Help text suggests bad practice.
2019-06-13 19:30:30 +08:00
Endre Szabo
9b564431b0 Help text suggests bad practice.
Please remove the phrase `No news is good news.` as it suggests to decide to go on with a bad operational habit.

Why I am stating this is because that `no news` also could mean that:
- your `cron` daemon stopped working,
- your MTA has issues (in case or mail notifications of course),
- anything in between the host running `acme.sh` and your client went wrong.

(... and probably you will not notice in time if `acme.sh` would otherwise send an error notification (if it runs anyway))

If you expect a daily mail (using `--notify-level 3`) you can always be sure that `acme.sh` has ran successfully before. You can also tick the `acme.sh` checkbox in the daily operational report of your enterprise. ;)
2019-06-13 12:39:38 +02:00
neil
65058db89f Merge pull request #2071 from awalgarg/dns_maradns
Add support for MaraDNS
2019-06-12 19:34:53 +08:00
AndreyIsakov
487d2a9221 dnsapi for regru: CI linter remove empty line 2019-06-11 20:13:48 +03:00
AndreyIsakov
6151debeab dnsapi for regru: CI linter ok 2019-06-11 19:59:02 +03:00
AndreyIsakov
e05ef230a7 test CI error 2019-06-11 19:37:39 +03:00
neil
685755fe64 Merge pull request #2320 from Neilpang/dev
sync
2019-06-10 22:41:19 +08:00
neilpang
465ece5d25 fix format 2019-06-10 22:40:14 +08:00
neilpang
10d1361a2c add guide link 2019-06-10 22:35:55 +08:00
neil
34617270a5 Merge pull request #2319 from Neilpang/dev
sync
2019-06-10 22:02:02 +08:00
neil
29aa370aa6 Merge pull request #2313 from Neilpang/docker
support deploy docker
2019-06-07 18:19:00 +08:00
neil
6650072fe6 Merge pull request #2276 from der-berni/dev
updated to work with one.com
2019-06-04 20:53:23 +08:00
neilpang
951bd3a517 minor, check for mkdir 2019-06-03 21:03:03 +08:00
neilpang
2e3ddd3a61 trim quotation marks 2019-06-03 20:55:22 +08:00
neil
dd628514c6 Merge pull request #2308 from honzahommer/feat/notify-postmark
Add notify postmark
2019-06-03 20:11:42 +08:00
neil
c74686a197 Merge pull request #2285 from dkerr64/FreeDNS
Fixes to dns_freedns.sh for multi-part top level domain names
2019-06-03 20:08:10 +08:00
Charlie Garrison
c42dbbfec8 reformatted RouterOS script for shfmt checks 2019-06-03 11:38:39 +10:00
Honza Hommer
ea3678f8c7 Merge branch 'dev' into feat/notify-postmark 2019-06-03 01:56:14 +02:00
Honza Hommer
51099bf148 Add postmark notify 2019-06-03 01:54:04 +02:00
David Kerr
924e0261f9 Update dns_freedns.sh 2019-06-02 13:09:57 -04:00
neilpang
dc5eda7ebb fix savedeployconf 2019-06-02 20:04:36 +08:00
neilpang
aec6636205 add _getdeployconf 2019-06-02 19:36:11 +08:00
neilpang
a18c3ff07d use sh -c 2019-06-02 15:21:08 +08:00
neilpang
64928b28bc trim quotation marks 2019-06-02 11:11:34 +08:00
neilpang
0bbaa51945 fix format 2019-06-02 10:05:24 +08:00
neilpang
561803c0a7 add deploy hook to docker containers 2019-06-01 22:30:25 +08:00
der-berni
1a5279bd6e cleanup according to styleguide 2019-05-31 08:55:21 +02:00
der-berni
534ddf01db try to remove errors in travis-ci
No newline at end of file
2019-05-31 08:34:33 +02:00
der-berni
937d5b5472 try to remove errors in travis-ci 2019-05-31 08:26:48 +02:00
Charlie Garrison
03a407d4df Added additional shellcheck ignores for client-side evaluation warning
Should pass CI tests now
2019-05-29 14:05:20 +10:00
neil
3508e1e6d5 Merge pull request #2298 from kroepke/gcloud-bsd-support
Make dns_gcloud.sh BSD compatible
2019-05-28 20:47:00 +08:00
Kay Roepke
145b1f4fb3 Improve compatibility with *BSD xargs
The --no-run-if-empty option is a GNU extension and the long version isn't supported by *BSD variants.
Instead use the short version (-r) which is present, but ignored as it is the default behavior, in at least FreeBSD: https://www.freebsd.org/cgi/man.cgi?xargs
2019-05-28 13:46:19 +02:00
neil
09bce5e6d6 sync (#2297)
* Create LICENSE.md

* remove _hostingde_parse_no_strip_whitespace function as this breaks API requests

* Fix sessionid parsing on BSD

* Make travis happy. (SC2020)

* fix for https://github.com/Neilpang/acme.sh/issues/2286

* Notify mail update (#2293)

* feat: disable e-mail validation if MAIL_NOVALIDATE is set

* fix: expose _MAIL_BIN variable

* fix: call _mail_body and _mail_cmnd directly to make sure that all used variables are exposed

* fix: update notify/mail.sh

Co-Authored-By: Matej Mihevc <zuexo@users.noreply.github.com>

* fix: remove useless echo, quote eval
2019-05-28 08:47:33 +08:00
Honza Hommer
51447961cb Notify mail update (#2293)
* feat: disable e-mail validation if MAIL_NOVALIDATE is set

* fix: expose _MAIL_BIN variable

* fix: call _mail_body and _mail_cmnd directly to make sure that all used variables are exposed

* fix: update notify/mail.sh

Co-Authored-By: Matej Mihevc <zuexo@users.noreply.github.com>

* fix: remove useless echo, quote eval
2019-05-27 22:45:44 +08:00
der-berni
89e73594eb fixed error in CI 2019-05-25 17:35:40 +02:00
Charlie Garrison
0cddc8a154 change to routeros native script rather than bash multiline commands 2019-05-26 01:32:13 +10:00
Awal Garg
8152309435 Add support for MaraDNS
MaraDNS is a lightweight self-hosting DNS server. This patch adds
support for adding records to zone files stored on the server in the
format expected by MaraDNS. Path to the file should be exported in
MARA_ZONE_FILE environment variable. To reload the configuration
automatically, the user must provide path to the pid file of duende (the
daemonization tool that ships with MaraDNS) in MARA_DUENDE_PID_PATH
(--pid argument to duende).
2019-05-25 16:55:09 +05:30
der-berni
a3089a719f Updated to work with curl
Now works with curl.
Check the root domain.
2019-05-24 09:44:13 +02:00
David Kerr
2cb0b00e3a replace _read_conf() with _readaccountconf() 2019-05-23 18:11:25 -04:00
neil
2aa219e150 Merge pull request #2288 from andreasschulze/master
fix for https://github.com/Neilpang/acme.sh/issues/2286
2019-05-23 22:43:36 +08:00
andreasschulze
93740c997c fix for https://github.com/Neilpang/acme.sh/issues/2286 2019-05-23 16:19:08 +02:00
neil
264ec5bab7 Merge pull request #2284 from devNan0/fix_netcup_parsing_on_bsd
dnsapi: netcup: Fix sessionid parsing on BSD
2019-05-23 21:30:22 +08:00
der-berni
e340593ad1 Revert parameter changes
Revert ONECOM_PASSWORD back to ONECOM_Password
and ONECOM_USER back to ONECOM_User
2019-05-23 09:39:54 +02:00
devNan0
05b6afcd17 Make travis happy. (SC2020) 2019-05-23 08:15:03 +02:00
David Kerr
10994d65be Even blank lines (with spaces) give Travis heartache. Sigh. 2019-05-22 23:01:23 -04:00
David Kerr
a18ce275ab Another Travis CI warning fixed. 2019-05-22 22:54:56 -04:00
David Kerr
66c39a953a Fix warnings from Travis build 2019-05-22 22:50:26 -04:00
David Kerr
09fb9dcd92 Fix bug preventing multipart TLD names to work. And simplify/cleanup the code. 2019-05-22 22:16:46 -04:00
David Kerr
eb5c2e9823 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2019-05-22 22:05:49 -04:00
devNan0
50d5c4b9ca Fix sessionid parsing on BSD 2019-05-22 17:01:11 +02:00
neil
54708c6131 Merge pull request #2283 from hosting-de/feature/fix-pr2207
remove _hostingde_parse_no_strip_whitespace function as this breaks A…
2019-05-22 22:35:14 +08:00
Oliver Dick
0e9ba9a004 remove _hostingde_parse_no_strip_whitespace function as this breaks API requests 2019-05-22 16:20:28 +02:00
neil
08f10d3cea Merge pull request #2282 from Neilpang/add-license-1
Add license
2019-05-22 22:01:11 +08:00
neil
c2dd7e0f6e Create LICENSE.md 2019-05-22 22:00:39 +08:00
neil
57fc5d28a9 Merge pull request #2272 from Neilpang/dev
sync
2019-05-22 12:58:12 +08:00
Maximilian Hippler
49bdcad4b6 Updated oathtoolkit from edge/testing to edge/community 2019-05-21 18:50:12 +02:00
neil
ef7d259bb7 Merge pull request #2277 from mjthompson/patch-1
Fix typo
2019-05-21 23:04:54 +08:00
mjthompson
688fe131c9 Fix typo 2019-05-21 18:21:54 +08:00
der-berni
68b42a00e0 updated to work with one.com
rev command not found on OpenWrt
CURL does not work, using wget
JSESSIONID replaced with OneSIDCrmAdmin
CSRF_G_TOKEN not needed
2019-05-20 17:40:43 +02:00
David Kerr
7368a790a3 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2019-05-19 17:11:58 -04:00
neil
527e1b8a16 Merge pull request #2273 from MilanPala/active24_fix_token
Fix saving token for DNS Active24
2019-05-19 18:28:17 +08:00
Milan Pála
f6d6658de7 Fix saving token for DNS Active24 2019-05-19 11:47:19 +02:00
neil
6a929d6a1a Merge pull request #2264 from honzahommer/notify-slack
Add slack notify
2019-05-19 08:29:23 +08:00
neil
ae380cb21e Merge pull request #2259 from honzahommer/notify-sendmail
Add mail notify
2019-05-19 08:28:43 +08:00
neilpang
cf4c603362 fix format 2019-05-19 08:05:40 +08:00
Honza Hommer
d83c9da830 add clearaccountconf MAIL_BIN 2019-05-18 18:21:19 +02:00
Honza Hommer
9a7c9e8d98 remove unset 2019-05-18 18:20:16 +02:00
neilpang
ace947e6b3 add dns_durabledns.sh 2019-05-18 21:00:39 +08:00
neil
5f9378569b Merge pull request #2268 from Neilpang/dev
sync
2019-05-17 22:53:20 +08:00
neilpang
a180b95cca add more debug info 2019-05-17 20:16:26 +08:00
Honza Hommer
73bbe25d26 add slack notify 2019-05-13 19:49:16 +02:00
Honza Hommer
fc5e3a0aec remove echo command 2019-05-13 18:59:58 +02:00
Honza Hommer
7625d66259 wip 2019-05-13 18:58:28 +02:00
Honza Hommer
30f2c2bd77 prevent _MAIL_BIN modification 2019-05-13 18:11:44 +02:00
Honza Hommer
e3052c8c57 expose MAIL_BIN variable 2019-05-13 17:44:04 +02:00
Honza Hommer
7b6ebc5c98 try to use ACCOUNT_MAIL if MAIL_FROM is not set 2019-05-13 17:42:07 +02:00
neilpang
0093dc3d32 fix https://github.com/Neilpang/acme.sh/issues/2256 2019-05-13 23:30:31 +08:00
neil
ccefd3be02 Merge pull request #2255 from mdbraber/update-acmeproxy
dns_acmeproxy: Username/password no longer required
2019-05-13 22:47:18 +08:00
Honza Hommer
d509ef7581 make MAIL_FROM not required 2019-05-13 16:06:24 +02:00
Maarten den Braber
5e165819a1 Update authentication logic / info 2019-05-13 08:45:57 +02:00
Honza Hommer
d180f01b45 typos 2019-05-12 22:28:37 +02:00
Honza Hommer
91c09dd0a0 ssmtp 2019-05-12 20:26:31 +02:00
Honza Hommer
f6ca92337b remove unsupported options from mail and mutt command 2019-05-12 20:24:02 +02:00
neil
ade9d662db Merge pull request #2210 from chasefox/dev
Fix gcloud most-specific zone match
2019-05-12 21:58:44 +08:00
neil
baca196da6 Merge pull request #1878 from Ne-Lexa/dev
Added dns api support for internet.bs
2019-05-12 20:35:51 +08:00
Honza Hommer
10801bfb25 use mutt if installed 2019-05-12 13:06:45 +02:00
Honza Hommer
a89a62071b cleanup, lint 2019-05-12 13:03:01 +02:00
wapplay
657051e4b6 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev
# Conflicts:
#	README.md
#	dnsapi/README.md
2019-05-12 13:36:01 +03:00
Honza Hommer
f6f6d89e06 move sendmail notify to mail notify 2019-05-12 10:41:32 +02:00
neil
1a6af5d896 Merge pull request #1582 from v0s/pddfixes
Multiple fixes to Yandex DNSAPI plugin
2019-05-12 15:40:17 +08:00
neilpang
a4b83895a3 fix https://github.com/Neilpang/acme.sh/issues/2258 2019-05-12 15:34:58 +08:00
Honza Hommer
4f03548608 typos 2019-05-12 00:35:47 +02:00
Honza Hommer
773e1d4e05 use hostname function instead of HOSTNAME env variable 2019-05-12 00:34:46 +02:00
Honza Hommer
d9ef8c1779 add sendmail notify 2019-05-12 00:25:36 +02:00
Maarten den Braber
f9e3a2132f Username/password no longer required 2019-05-09 21:14:26 +02:00
neil
9ab318cafc Merge pull request #2250 from mdbraber/add-acmeproxy-provider
Add acmeproxy provider
2019-05-08 22:17:34 +08:00
neilpang
1a126b700f fix https://github.com/Neilpang/acme.sh/issues/2252 2019-05-08 22:13:33 +08:00
neil
92dd5e1610 Merge pull request #2253 from Neilpang/dev
sync
2019-05-08 22:09:35 +08:00
neilpang
11ecbd27be fix punycode domain 2019-05-08 22:07:27 +08:00
Maarten den Braber
585ef998d0 Fixed CI errors 2019-05-07 16:47:23 +02:00
Maarten den Braber
c297aff99b Improved logging description 2019-05-06 18:31:58 +02:00
Maarten den Braber
68142c9835 Update description 2019-05-06 17:14:31 +02:00
Maarten den Braber
b8f4fa359c Add acmeproxy provider 2019-05-06 17:12:50 +02:00
neilpang
2b765fdedb add set-notify 2019-05-04 11:54:59 +08:00
neil
0accdb9e34 Merge pull request #2248 from Neilpang/dev
add notifications
2019-05-04 11:08:25 +08:00
neilpang
5d468f7ca5 add notifications 2019-05-04 11:06:25 +08:00
neilpang
83768f0531 reduce info message 2019-05-04 11:02:10 +08:00
neilpang
acae0ac2a6 fix RENEW_SKIP code 2019-05-04 10:59:00 +08:00
neilpang
0f86651089 fix idn 2019-05-04 10:43:39 +08:00
neilpang
a77f2fa424 remove test file 2019-05-04 10:32:01 +08:00
neilpang
6198e43fe6 fix idn 2019-05-04 10:21:15 +08:00
neilpang
621d4745b4 fix idn 2019-05-04 10:18:42 +08:00
neilpang
dac75a1dda rename 2019-05-03 20:50:42 +08:00
neilpang
f1c0f3d45f Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2019-05-03 20:49:02 +08:00
neil
08b6a2c36d Merge pull request #2098 from diseq/dev
one.com dns api
2019-05-03 20:48:27 +08:00
neil
130b67821c Merge branch 'dev' into dev 2019-05-03 20:46:16 +08:00
neil
b902769fa8 Merge pull request #2242 from plantroon/master
Add NLnetLabs NSD
2019-05-03 20:38:20 +08:00
neil
7503a58d1f Merge pull request #2243 from mod242/master
New API for Schlundtech.de
2019-05-03 20:35:34 +08:00
mod242
096ce1a207 Create DNS API for Schlundtech 2019-05-02 12:18:16 +02:00
Jakub Filo
d1ef039e39 Removed trailing line 2019-05-01 12:25:46 +02:00
Jakub Filo
040ca5320d Fixed style to match upstream 2019-05-01 12:17:54 +02:00
neil
625c85291d Merge pull request #2236 from mod242/master
Correct parsing error in sed
2019-05-01 15:14:14 +08:00
neil
b28835a604 Update haproxy deploy hook (#1591)
* implement basic haproxy deploy

HAProxy requires the certificate chain and key to be concatenated and placed somewhere (can be anywhere). This script expects a single environment variable with the path where the concatenated PEM file should be written

* add docs for HAProxy deployment

* Add conditional check to ensure path is provided

* remove whitespace

* remove more whitespace (trying to get TravisCI working)

* add reload

* update for POSIX compliance

* add documentation for reload command

* Update haproxy deploy hook

Add functionality to add OCSP stapling info (.ocsp file), issuer (.issuer file) and multi-cert bundles (suffix on pem file based on key type).

This also corrects the order of key, certificate and intermediate in the PEM file, which although HAProxy does not seem to care, was incorrect in the prior version.

* Document updated haproxy deploy hook

* Fix variable name

* whitespace fixes

* Support HAPROXY_DEPLOY_PEM_PATH

Adds compatibility to original haproxy deploy hook while still allowing custom PEM file name (via HAPROXY_DEPLOY_PEM_NAME)

* update for new haproxy deploy vars

* Fix return from reload

* Fix Le_Keylength case

* Update cert suffix for bundles .ocsp generation

* Whitepspace

* Change default for reload

* Readme update

* Actually set reload default

* Fix README.md confict
2019-05-01 15:13:42 +08:00
Тимур Яхин
6340704173 fixed line breaks for support api gcore_cdn (#2237) 2019-05-01 15:11:39 +08:00
Jakub Filo
522b7c51f7 Adding NLnetLabs NSD API 2019-05-01 01:53:51 +02:00
neilpang
388ff75260 --- Auto-Git Commit --- 2019-04-30 20:43:10 +08:00
andrewheberle
37ef0a0cb6 Fix README.md confict 2019-04-30 15:32:36 +08:00
mod242
d7be2c5b8a Remove from Master Branch 2019-04-29 16:17:24 +02:00
neil
b50e701cae Add notification (#2241)
* add cron notify

* fix format

* fix format
2019-04-29 22:13:54 +08:00
neilpang
b7a0443091 lets start 2.8.2 2019-04-29 22:11:25 +08:00
neil
a8f0fd1fff Merge pull request #2240 from Neilpang/dev
use mutable
2019-04-29 21:59:42 +08:00
neilpang
a89d50d34e use mutable 2019-04-29 21:52:22 +08:00
neil
6489cfbce6 Merge pull request #2239 from Neilpang/dev
sync
2019-04-29 21:46:10 +08:00
neilpang
d10f40f109 fix idn issue. 2019-04-29 21:44:25 +08:00
mod242
175b56b43c Update dns_schlundtech.sh 2019-04-29 12:18:05 +02:00
mod242
9b68a3ef4a Update dns_schlundtech.sh 2019-04-29 12:13:40 +02:00
mod242
345d6c5687 Update dns_schlundtech.sh 2019-04-29 10:44:23 +02:00
mod242
5b1b5cc8f2 Create dns_schlundtech.sh 2019-04-29 10:43:16 +02:00
mod242
1b062ab929 Correct sed parsing error 2019-04-28 15:58:08 +02:00
neilpang
a7420ca3d4 typo 2019-04-27 09:17:26 +08:00
neil
4dcd1f3e65 Merge pull request #2233 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/2195
2019-04-26 23:59:32 +08:00
neilpang
e46b392a8d Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2019-04-26 23:58:09 +08:00
neilpang
47ff768b70 fix https://github.com/Neilpang/acme.sh/issues/2195 2019-04-26 23:57:40 +08:00
neil
ba4bd3ed55 Merge pull request #2232 from Neilpang/dev
sync
2019-04-26 23:52:01 +08:00
neil
68428a5d5e Merge pull request #2205 from kirpichiki/dns_cf_invalid_domain
CloudFlare dns invalid domain
2019-04-26 23:50:50 +08:00
neil
28694e8afb Merge pull request #2207 from Kimmax/dns_hostingde_missing_templateValues
dns_hostingde.sh zoneConfig missing templateValues object
2019-04-26 23:49:41 +08:00
neil
c420a0ae2b Merge pull request #2222 from dim0x69/master
Implement Update Account Information for ACMEv2
2019-04-26 23:49:10 +08:00
neil
a85e50f465 Merge pull request #2229 from mod242/master
Create DDNSS API based on the work of helbgd
2019-04-26 23:47:19 +08:00
neilpang
4962cc3da8 fix idn issues 2019-04-26 23:44:25 +08:00
mod242
bb703281a2 Update dns_ddnss.sh 2019-04-25 16:18:52 +02:00
neilpang
52f5564122 fix image links 2019-04-25 20:58:13 +08:00
neil
1dc420ce51 Merge pull request #2139 from loonies/dns-loopia-api-endpoint
Make the Loopia API endpoint configurable
2019-04-25 20:52:38 +08:00
mod242
20af1ceb7d Cleanup comment 2019-04-24 19:38:07 +02:00
mod242
ec982ccacb Cleanup according to styleguide 2019-04-24 16:15:01 +02:00
mod242
a97e74b2d4 Update dns_ddnss.sh 2019-04-24 16:05:44 +02:00
mod242
fecc5b09f8 Removed -e and changed tail to funktion 2019-04-24 14:57:48 +02:00
mod242
d1030eb0b2 Create DDNSS API based on the work of helbgd 2019-04-24 14:03:54 +02:00
David Kerr
fb749dc526 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2019-04-21 10:12:51 -04:00
neilpang
e6df1828d9 fix https://github.com/Neilpang/acme.sh/issues/2192 2019-04-21 12:37:26 +08:00
neilpang
9ff53fea98 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2019-04-21 12:23:57 +08:00
neilpang
4f1888d2ea fix https://github.com/Neilpang/acme.sh/issues/2192 2019-04-21 12:23:06 +08:00
neil
53dcd0dee9 Merge pull request #2224 from honzahommer/feat-install-noprofile
Add `--noprofile` option to `install` command
2019-04-20 13:19:27 +08:00
neil
e291ada371 Merge pull request #2226 from Neilpang/dev
sync
2019-04-20 13:09:38 +08:00
neilpang
9c9fed749a fix https://github.com/Neilpang/acme.sh/issues/2225
make NSUPDATE_SERVER can be overwritten
2019-04-20 12:49:51 +08:00
Honza Hommer
61556a54e2 feat: add --noprofile option to install command 2019-04-19 17:27:32 +02:00
dim0x69
79e2f8a2e5 implement account update for acmev2 2019-04-17 14:51:07 +02:00
neil
d1f39e6217 Merge pull request #706 from palhaland/dev
Shell script for deploying changes to a routeros server.
2019-04-10 20:49:05 +08:00
chasefox
4aa488f48b Formatting - indentation
I think this is what CI wants....
2019-04-08 07:51:39 -04:00
chasefox
2d72b25c43 CI wanted double-quote 2019-04-08 07:44:41 -04:00
chasefox
f23b0aacd7 Remove here string
CI doesn't want here strings
2019-04-08 07:11:08 -04:00
Matthew R Chase
98d27c4a6a Fix most-specific zone match
Most specific zone selected by deepest sub-domain (how many '.' in the domain)
rather than seemingly irrelevant count of the number of characters within the zone.
2019-04-07 15:04:03 -04:00
neil
d01ab227b8 Merge pull request #2209 from Neilpang/dev
sync
2019-04-06 23:06:36 +08:00
neilpang
0cfeee4ded fix format 2019-04-06 16:48:17 +08:00
neilpang
c97e43dcd6 fix format 2019-04-06 16:45:58 +08:00
neilpang
eda321954d fix https://github.com/Neilpang/acme.sh/issues/2208 2019-04-06 16:05:08 +08:00
Kimmax
64e5392788 Zone delete also needs new "templateValues" field 2019-04-02 23:29:58 +00:00
Kimmax
987f95221c Added missing "templateValues" object to "zoneConfig" on "_hostingde_getZoneConfig" 2019-04-02 23:08:39 +00:00
Gorbachev
6e917d156c Trim double quotes for email and key
Currently dns_cf generates headers like this: 'X-Auth-Email: "sample@mail.com"'. Cloudflare API responses 400 BadRequest for quoted headers with message "Invalid format for X-Auth-Email header".
2019-04-02 18:05:52 +03:00
neilpang
36e697b344 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2019-03-31 21:46:45 +08:00
neilpang
c2d0d4d28c root domain as dns alias mode 2019-03-31 21:46:14 +08:00
Miodrag Tokić
aec9c3c9a4 Double quote unquoted variables
Double quote unquoted variables to prevent globbing and word splitting.
2019-03-28 16:34:13 +01:00
Miodrag Tokić
0daa225e26 Make the Loopia API endpoint configurable
Loopia provides hosting in several countries. Each hosting location has
it's own API endpoint, such as "https://api.loopia.<TLD>/RPCSERV", where
<TLD> is one of: com, no, rs, se.

The current LOOPIA_Api variable is hard-coded to ".se". This prevents
using the Loopia DNS API on other hosting locations.

This commit makes the LOOPIA_Api variable configurable and it falls back
to ".se" TLD if LOOPIA_Api is not set.

References:

 - https://www.loopia.com/api/authentication/
 - https://www.loopia.no/api/authentication/
 - https://www.loopia.rs/api/authentication/
 - https://www.loopia.se/api/authentication/
2019-03-27 13:58:23 +01:00
Miodrag Tokić
85be2b85fd Fix error message language 2019-03-27 13:58:23 +01:00
Miodrag Tokić
a7d6146169 Extract configuration saving code to function 2019-03-27 13:58:23 +01:00
Miodrag Tokić
978ec91107 Extract configuration loading code to function 2019-03-27 13:58:23 +01:00
neil
297859c5bc Merge pull request #2191 from temoffey/gcore_cdn_deploy
fix gcore_cdn_deploy
2019-03-23 21:46:40 +08:00
temoffey
bea52aa743 remove use grep -E 2019-03-23 16:29:33 +03:00
neil
54f1be69c7 Merge pull request #2190 from Neilpang/dev
sync
2019-03-23 16:51:40 +08:00
neil
a4cc9ef2cc Merge pull request #2178 from temoffey/gcore_cdn_deploy
Gcore cdn deploy
2019-03-23 11:06:16 +08:00
neil
4f47594b6d Merge pull request #2189 from scj643/master
Fixed Digital Ocean dns api
2019-03-23 10:57:39 +08:00
Charles Surett
189a7766d4 Made dns_dgon.sh use _lower_case
Fixed private function which breaks on embedded systems before.
2019-03-22 18:43:06 -04:00
temoffey
df9174577a remove check jq 2019-03-22 23:00:47 +03:00
temoffey
bd1bb7a71b fix syntax 2019-03-22 20:08:35 +03:00
temoffey
4b6e7e6c37 remove use while, [[ ]], array 2019-03-22 20:02:59 +03:00
temoffey
8896642e25 fix syntax 2019-03-22 20:01:39 +03:00
temoffey
0ecb5a3fec fix syntax 2019-03-22 04:31:58 +03:00
temoffey
d289b0b450 fix syntax 2019-03-22 04:21:41 +03:00
temoffey
b8489464b3 remove use awk, jq, curl 2019-03-22 03:41:26 +03:00
Pål Håland
ebaa3f39e4 Merge remote-tracking branch 'origin/dev' into dev 2019-03-21 15:54:02 +01:00
Pål Håland
e19753dcde Moved documentation from deploy/README.md to deploy/routeros.sh 2019-03-21 15:53:11 +01:00
neil
13255a3762 Merge pull request #2185 from Neilpang/dev
syc
2019-03-21 22:26:24 +08:00
neil
15ce2a3d67 Merge pull request #2161 from sotux/dev
dnsapi: add deSEC.io api support
2019-03-21 20:02:24 +08:00
James Qian
3bb97b81de dnsapi: add deSEC.io api support
Signed-off-by: James Qian <sotux82@gmail.com>
2019-03-21 10:58:13 +08:00
Maximilian Hippler
9247780073 Added oathtool to Dockerfile 2019-03-20 22:34:50 +01:00
neil
37161d3017 Merge pull request #2105 from TheLastProject/feature/dns-openprovider
Add OpenProvider support
2019-03-20 23:18:43 +08:00
Sylvia van Os
4532037e4f Merge branch 'dev' into feature/dns-openprovider 2019-03-20 16:12:57 +01:00
Sylvia van Os
0fe08e1b33 Merge branch 'dev' into feature/dns-openprovider 2019-03-20 16:12:08 +01:00
neilpang
236acbd6e8 move to wiki 2019-03-20 23:11:13 +08:00
temoffey
16b0704acc remove readme 2019-03-20 18:10:53 +03:00
neilpang
61bcd67a5d move to wiki 2019-03-20 23:03:49 +08:00
neilpang
0629c2a086 move to wiki 2019-03-20 23:01:24 +08:00
neilpang
fbdc5a0eb5 fix https://github.com/Neilpang/acme.sh/issues/2179 2019-03-20 22:52:40 +08:00
neil
68a8d81b6a Merge pull request #2177 from vbrandl/feature/deploy-mailcow
Add deploy hook for mailcow
2019-03-20 21:13:26 +08:00
neil
a368301dbf Merge pull request #2176 from bz-heilig/patch-1
Update README.md
2019-03-20 20:40:49 +08:00
temoffey
89989adcad fix syntax 2019-03-20 14:05:18 +03:00
temoffey
95cdb4b2bc fix syntax 2019-03-20 14:02:11 +03:00
temoffey
228c835466 gcore_cdn_deploy 2019-03-20 03:03:10 +03:00
Valentin Brandl
d604166194 Fix formatting 2019-03-19 19:15:31 +01:00
Valentin Brandl
d643a2ff13 Check if mailcow path is set and fix directory check 2019-03-19 19:09:25 +01:00
Valentin Brandl
b581a171f0 Add documentation for mailcow deploy hook 2019-03-19 18:43:07 +01:00
Valentin Brandl
307336cfc4 Add deploy hook for mailcow
This hook will copy the key and certificate chain to the specified
mailcow installation (as described in
https://mailcow.github.io/mailcow-dockerized-docs/firststeps-ssl/#use-own-certificates)
and restarts the containers, that are using the certificates.

The hook has 2 parameters:

* `DEPLOY_MAILCOW_PATH`: The path to the mailcow installation (required)
* `DEPLOY_MAILCOW_RELOAD`: The reload command, defaults to `docker-compose restart postfix-mailcow dovecot-mailcow nginx-mailcow`
2019-03-19 18:42:47 +01:00
neil
fc30171725 Merge pull request #2175 from loial/dns_gdnsdk_fix
dns_gdnsdk: Fixed stupid regex error, want literal "-", not a range
2019-03-19 22:20:15 +08:00
bz-heilig
34be7e99f0 Update README.md
Added links for do.de API token creation and documentation of API.
2019-03-19 15:04:37 +01:00
Herman Sletteng
7679df062c dns_gdnsdk: Fixed stupid regex error, want literal "-", not a range 2019-03-19 14:16:13 +01:00
Sylvia van Os
71cfd874ae Fix SC2116 2019-03-18 16:10:58 +01:00
Sylvia van Os
08be0c374a Merge branch 'feature/dns-openprovider' of https://github.com/TheLastProject/acme.sh into feature/dns-openprovider 2019-03-18 15:59:08 +01:00
Sylvia van Os
7decce9718 Resolve comments on pull request 2019-03-18 15:43:52 +01:00
Sylvia van Os
22bab90a90 Merge branch 'dev' into feature/dns-openprovider 2019-03-18 12:54:19 +01:00
neil
02882fb327 Merge pull request #2168 from Neilpang/dev
sync
2019-03-17 23:33:02 +08:00
neilpang
c74d597c84 add debug info 2019-03-16 18:34:44 +08:00
neilpang
653c77e852 update 2019-03-16 15:09:49 +08:00
neilpang
2b36f4f57f update 2019-03-16 15:07:34 +08:00
neilpang
82b0ebb787 minor, remove dns records only when it's added success 2019-03-16 14:53:02 +08:00
neilpang
3f35006c26 fix error message 2019-03-16 14:35:33 +08:00
neilpang
2ffd8637e1 fix standalone content 2019-03-16 14:28:24 +08:00
neil
44c1572b8f Merge pull request #2166 from Neilpang/dev
sync
2019-03-16 14:18:49 +08:00
neilpang
d0d749074e fix for solaris 2019-03-16 14:00:15 +08:00
neilpang
dbc44c08df fix for solaris 2019-03-16 13:38:17 +08:00
Steven M. Miano
46fbd7f1e1 support ultradns.com api (#2117)
support ultradns.com api (#2117)
2019-03-14 20:41:13 +08:00
tambetliiv
5048c6c22a Add zone.ee (zone.eu) DNS API (#2151)
* add zone.ee (zone.eu) dns api
2019-03-14 20:20:39 +08:00
neil
709d82e764 sync
sync
2019-03-13 21:32:10 +08:00
neil
9d64b35ed8 Merge pull request #2157 from hosting-de/fix/read-endpoint
hosting.de: reading endpoint
2019-03-13 21:29:59 +08:00
neil
0f00862e5e support windows scheduler (#2158)
* support Windows scheduler. fix https://github.com/Neilpang/acme.sh/issues/2145
2019-03-13 21:28:30 +08:00
Oliver Dick
532e79c7d0 Fix reading endpoint 2019-03-13 14:14:40 +01:00
neilpang
4ebad10557 fix format 2019-03-13 21:11:59 +08:00
neilpang
0b04a7f17f fix format 2019-03-13 20:49:26 +08:00
neilpang
77f96b386e support Windows scheduler. fix https://github.com/Neilpang/acme.sh/issues/2145 2019-03-13 20:42:02 +08:00
Sylvia van Os
ea86ddc693 Merge branch 'dev' into feature/dns-openprovider 2019-03-13 10:22:40 +01:00
neil
e3e43d0ba0 Merge pull request #2155 from Neilpang/dev
sync
2019-03-12 22:20:00 +08:00
neil
b10929fe23 Merge pull request #2154 from Neilpang/vv
use acme v2 as default
2019-03-12 22:17:35 +08:00
neil
f512cb8e35 Merge pull request #2081 from nederhost/master
Add support for NederHost DNS API
2019-03-12 22:06:47 +08:00
Sebastiaan Hoogeveen
4f240f538d Merge branch 'master' of https://github.com/nederhost/acme.sh 2019-03-12 14:39:26 +01:00
Sebastiaan Hoogeveen
db6db6a4e9 Removed overwriting of the HTTP header file before sending a request. 2019-03-12 14:36:42 +01:00
neilpang
f2add8de94 use acme v2 as default 2019-03-12 21:16:15 +08:00
Sebastiaan Hoogeveen
88c6621cfe Merge branch 'dev' into master 2019-03-12 11:59:13 +01:00
neil
c152b6f0ad Merge pull request #2152 from Neilpang/dev
sync
2019-03-11 21:32:28 +08:00
neilpang
53c0188248 fix https://github.com/Neilpang/acme.sh/issues/2150 2019-03-11 21:30:24 +08:00
neilpang
725addafda fix format 2019-03-09 09:13:49 +08:00
Sylvia van Os
19628c4732 Merge branch 'dev' into feature/dns-openprovider 2019-03-08 16:44:36 +01:00
Sylvia van Os
04eaf7f175 Add OpenProvider support 2019-03-08 16:42:52 +01:00
neilpang
f5850d0c08 fix format 2019-03-08 22:20:56 +08:00
neil
855eb8355a Merge pull request #2143 from 5ll/core-networks-support
Adding Support for Core-Networks API
2019-03-08 22:14:41 +08:00
neil
fdbb7fd30f Merge pull request #2144 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/2141
2019-03-08 22:09:12 +08:00
5ll
30d0ac0784 Updated README with Core-Networks support 2019-03-08 10:48:06 +01:00
5ll
3d5c75420a Changed Order 2019-03-08 10:46:35 +01:00
5ll
1d5967d143 Updated README with Core-Networks support 2019-03-08 10:45:36 +01:00
5ll
110a41d18d initial commit
DNS API for acme.sh for Core-Networks (https://beta.api.core-networks.de/doc/)
2019-03-08 10:33:09 +01:00
neil
a3d8b9935a fix https://github.com/Neilpang/acme.sh/issues/2141 2019-03-08 14:31:11 +08:00
neil
08357e3cb0 Merge pull request #2137 from Neilpang/dev
Dev
2019-03-05 21:50:47 +08:00
neil
162a445a50 Merge pull request #2136 from Neilpang/cmd
Cmd
2019-03-05 21:47:50 +08:00
neilpang
c7257bcf46 base64 hooks, fix https://github.com/Neilpang/acme.sh/issues/1969 2019-03-05 21:44:34 +08:00
neilpang
dfca8c09e0 fix format 2019-03-05 21:22:03 +08:00
neilpang
7690f73e81 base64 encode reloadcmd.
fix https://github.com/Neilpang/acme.sh/issues/2134
2019-03-05 21:05:10 +08:00
Pål Håland
86fbb5952e Use env sh 2019-03-02 16:39:41 +01:00
Sebastiaan Hoogeveen
78c92642e4 Merge branch 'dev' into master 2019-03-02 13:58:56 +01:00
neilpang
b3f6129718 fix https://github.com/Neilpang/acme.sh/issues/2122 2019-03-02 20:44:08 +08:00
neil
2a52603b7e Merge pull request #2128 from the729/fix-qiniu-base64
fix deploy/qiniu.sh base64
2019-03-01 22:44:23 +08:00
neil
e6f9f258ec Merge pull request #2129 from the729/fix-qiniu-doc
fix doc of qiniu deploy script
2019-03-01 22:40:45 +08:00
tianji
22e7b4c911 fix doc of qiniu deploy script
A leading dot should be included when updating wildcard domains.
2019-02-28 23:51:43 +08:00
tianji
af5f7a7779 fix deploy/qiniu.sh base64
According to the doc (https://developer.qiniu.com/kodo/manual/1231/appendix#1), we should use URL-safe base64 instead of plain base64 for token calculation.
2019-02-28 23:43:58 +08:00
neil
693d692a47 sync (#2127)
* Support for MyDevil.net (#2076)

support mydevil

* Fix verification for namecheap domains not *owned* by the calling user (#2106)

* Peb (#2126)

* support pebble
* support async finalize order

* add Pebble
2019-02-27 20:41:50 +08:00
neilpang
81f0189d23 add Pebble 2019-02-27 20:40:10 +08:00
neil
e7f7e96d58 Peb (#2126)
* support pebble
* support async finalize order
2019-02-27 20:36:13 +08:00
Pål Håland
1dab2ac7d3 Updated with latest changes from Neilpang/dev 2019-02-26 17:41:24 +01:00
Timothy Nelson
ec54074392 Fix verification for namecheap domains not *owned* by the calling user (#2106) 2019-02-25 19:19:36 +08:00
dsc
23b4c9c667 add docs for one.com 2019-02-21 08:43:09 +01:00
diseq
472ed721a3 fix format 2019-02-20 21:51:59 +01:00
diseq
ed3f2646f0 fix format 2019-02-20 11:54:48 +01:00
diseq
0499d2b5c4 remove line break 2019-02-20 11:51:06 +01:00
diseq
81ba629b56 allow set-cookie as well as Set-Cookie 2019-02-20 11:27:49 +01:00
diseq
0bb746ba39 Update dns_one.sh 2019-02-20 09:44:25 +01:00
Marcin Konicki
16a0f40ac2 Support for MyDevil.net (#2076)
support mydevil
2019-02-20 09:40:36 +08:00
neil
f84103918a Merge pull request #2101 from Neilpang/dev
Doh (#2100)
2019-02-19 22:01:39 +08:00
neil
b5ca9bbab2 Doh (#2100)
support doh to poll dns status
fix https://github.com/Neilpang/acme.sh/issues/2015
2019-02-19 21:39:06 +08:00
neil
ff38d2bba6 Merge pull request #2099 from Neilpang/dev
Dev
2019-02-18 21:20:35 +08:00
neil
8f2a8a0051 Merge pull request #1357 from martgras/patch-1
avoid side effects in _printargs
2019-02-18 21:16:14 +08:00
neilpang
97147b594b fix https://github.com/Neilpang/acme.sh/issues/2096 2019-02-18 20:57:13 +08:00
dsc
9ff6d6e7b5 initial commit 2019-02-17 23:20:17 +01:00
neilpang
a0ec5b18e7 fx format 2019-02-17 14:26:27 +08:00
neilpang
f2acdd27fd fix tr err for Mac 2019-02-17 14:19:14 +08:00
neil
4ade446b55 Merge pull request #2095 from Augustin-FL/dev
Add online.net DNS API
2019-02-15 22:30:26 +08:00
Augustin-FL
ec6569fbea fix travis 2019-02-15 08:56:09 +00:00
Augustin-FL
1ad6742dbc fix travis 2019-02-15 08:43:07 +00:00
Augustin-FL
63ea3e8d27 acme.sh does not follow Location: headers when using wget 2019-02-15 08:29:44 +00:00
Augustin-FL
9ace7db216 simplify online_rest 2019-02-15 08:08:32 +00:00
Augustin-FL
841513501a update get_root 2019-02-15 08:08:32 +00:00
Augustin-FL
5c94147603 use read/saveconf_mutable, not readconf from OVH 2019-02-15 08:08:10 +00:00
Augustin-FL
02f6d4cb66 use read/saveconf_mutable, not readconf from OVH 2019-02-15 07:56:13 +00:00
Augustin-FL
ec5fad433c Add online.net DNS API 2019-02-14 08:34:21 +01:00
neil
b4fa97fd54 Merge pull request #2090 from ianw/rackdns
Rackspace Cloud DNS
2019-02-13 09:24:35 +08:00
Tom Cocca
d30b441ede Rackspace Cloud DNS
Support Rackspace Cloud DNS

This commit is based on the original pull request by tcocca
  https://github.com/Neilpang/acme.sh/pull/1297

Addtional cleanup was provided by senseisimple in
  https://github.com/Neilpang/acme.sh/pull/1999

This pull request has squashed the changes for review, fixed a minor
(but breaking) problem with the field ordering in the response, and
added documenation per the API guide.

Co-Author: Chris <chris@chrisnovoa.com>
Co-Author: Ian Wienand <ian@wienand.org>
2019-02-13 12:00:05 +11:00
neil
dda29f7e2f Merge pull request #2082 from laszlof/nw_dns_api
Add support for Thermo, Nexcess, and Futurehosting DNS APIs
2019-02-11 23:00:14 +08:00
neil
952e281993 Merge pull request #2077 from hosting-de/fix/better-parsing-of-responses
hosting.de: better parsing of json responses
2019-02-11 22:47:08 +08:00
Oliver Dick
1fa026b9c7 using ' ' instead of '[:space:]' for tr 2019-02-11 11:47:48 +01:00
neil
e8c91e6e12 Merge pull request #2083 from siwyd/ns1-dns-ttl
Set NS1 DNS record TTL to 0
2019-02-10 23:03:07 +08:00
neil
41425f7f74 Merge pull request #2086 from christianbur/patch-3
Update Dockerfile (apline 3.9 and tzdata)
2019-02-10 23:02:19 +08:00
Christian Burmeister
2cf01c23a2 Update Dockerfile 2019-02-09 19:38:32 +01:00
Ne-Lexa
412f85b665 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev
# Conflicts:
#	README.md
#	dnsapi/README.md
2019-02-08 12:31:01 +03:00
Simon Wydooghe
ebc90f6ab8 Set NS1 DNS record TTL to 0
Default of a zone might be high, which is annoying when testing
with the ACME staging API. I think setting the TTL to 0 makes sense
as acme.sh is the only one checking this, so having an always up
to date response seems desirable.
2019-02-06 21:49:17 +01:00
Frank Laszlo
84d80e93bc Add support for Thermo, Nexcess, and Futurehosting DNS APIs 2019-02-06 10:42:11 -05:00
Sebastiaan Hoogeveen
b7e92dbced Documentation update. 2019-02-06 14:27:26 +01:00
Sebastiaan Hoogeveen
44dcb0d0a9 Make Travis happy; fixed formatting of return statements. 2019-02-06 11:46:47 +01:00
Sebastiaan Hoogeveen
b3e3e080a9 Cleaned up some of the comments from shellcheck. 2019-02-05 16:37:08 +01:00
Sebastiaan Hoogeveen
1167cdcaec Added DNS API support for NederHost (https://www.nederhost.nl/) 2019-02-05 16:32:41 +01:00
Oliver Dick
4eda39a31d making shellcheck happy 2019-02-04 15:40:45 +01:00
Oliver Dick
759b75ca48 better parsing of json responses
fixes an error if customer does not have access to dns-groups
2019-02-04 11:27:04 +01:00
neil
55e862a4a4 Merge pull request #2068 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/pull/1979
2019-01-30 20:14:10 +08:00
neilpang
227547f826 fix https://github.com/Neilpang/acme.sh/pull/1979 2019-01-30 20:13:23 +08:00
neil
7c41dd5e31 Merge pull request #2064 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/1364#issuecomment-4580…
2019-01-28 19:24:09 +08:00
neilpang
a964646803 fix https://github.com/Neilpang/acme.sh/issues/1364#issuecomment-458035330 2019-01-28 19:11:45 +08:00
neil
9dac02ba5d Merge pull request #2063 from Neilpang/dev
sync
2019-01-27 13:42:50 +08:00
neilpang
43877d2647 fix rm method to urlencode the existing txt records.
fix https://github.com/Neilpang/acme.sh/issues/2052
2019-01-26 20:27:53 +08:00
neilpang
cc6159b39b urlencode the existing txt record value
fix https://github.com/Neilpang/acme.sh/issues/2052
2019-01-26 19:15:13 +08:00
neilpang
43ff787b04 remove tls-sni 2019-01-26 18:32:11 +08:00
neilpang
3633598462 Lets start 2.8.1 2019-01-25 22:39:22 +08:00
neil
94922f2df6 Merge pull request #2053 from Manawyrm/dev
Added dns_doapi.sh
2019-01-25 22:38:11 +08:00
Tobias Mädel
75fe022f96 Changed order in readme, added do.de 2019-01-25 15:26:41 +01:00
Tobias Mädel
bc839569fb Merge branch 'dev' into dev 2019-01-25 14:38:35 +01:00
neil
f62a4a0c0c Merge pull request #2056 from Neilpang/dev
sync
2019-01-25 21:35:29 +08:00
neil
8dacd51abb Merge pull request #1997 from MilanPala/master
Add support for Active24.cz
2019-01-25 21:33:42 +08:00
neil
06302871bc Merge pull request #1543 from Rid/patch-2
Fix DNSimple when zone has > 100 records
2019-01-25 17:31:06 +08:00
Grant Millar
c1ec2afeca Changed records per page to 5000 2019-01-25 09:27:30 +00:00
Tobias Mädel
e2f1338f94 Added documentation 2019-01-24 17:05:01 +01:00
Tobias Mädel
5f9b57d300 Cleaned up dns_doapi.sh 2019-01-24 17:00:37 +01:00
Tobias Mädel
ddf77f10e9 Cleaned up dns_doapi.sh 2019-01-24 16:59:36 +01:00
Tobias Mädel
127532c226 Added dns_doapi.sh 2019-01-24 16:53:03 +01:00
Milan Pála
572adbaad2 Add support for Active24.cz 2019-01-23 14:27:13 +01:00
neil
f4c7822bc9 Merge pull request #2046 from hosting-de/fix/update-to-latest-dns-api
Update hosting.de Plugin to latest API Changes
2019-01-22 11:33:07 +08:00
neil
89561b8d45 Merge pull request #2027 from shonenada/deploy-qiniu
Qiniu deployment support
2019-01-22 11:24:02 +08:00
Oliver Dick
b0775f7a58 making shftm really happy 2019-01-21 16:32:45 +01:00
Oliver Dick
2dc50e6633 making shfmt happy 2019-01-21 15:45:32 +01:00
neil
ad2a3d603e Merge pull request #2047 from Neilpang/dev
sync
2019-01-21 22:32:30 +08:00
neilpang
545f23551f trigger validation before cleanup
fix https://github.com/Neilpang/acme.sh/issues/2037
2019-01-21 22:25:23 +08:00
neilpang
b15c1ffedc clean TXT records when error happens.
https://github.com/Neilpang/acme.sh/issues/2037
2019-01-21 22:09:13 +08:00
Oliver Dick
56d70e4ea7 Update to latest API Changes 2019-01-21 15:02:09 +01:00
neil
0b934232fd Merge pull request #2023 from jim-p/acme-fix-2022
Use cross-platform grep pattern for Namecheap API. Fixes #2022
2019-01-21 19:38:40 +08:00
shonenada
a4a53e1355 Move docs into README.md from README_zh.md 2019-01-21 17:33:09 +08:00
shonenada
c445e70cff fix indent 2019-01-21 14:33:15 +08:00
shonenada
e8eec2cb41 add chinese readme 2019-01-21 00:11:06 +08:00
shonenada
dd6fa4af00 Save QINIU_CDN_DOMAIN only when defined 2019-01-20 23:58:10 +08:00
shonenada
afdb9a63ff chore: replece Le_Deploy_Qiniu_* with QINIU_* 2019-01-19 23:58:55 +08:00
jim-p
10ba2cd312 Use a literal space instead of an escaped space. Fixes #2022 2019-01-14 16:26:22 -05:00
shonenada
4c1fa9c242 save CDN Domain with _savedomainconf 2019-01-14 22:55:05 +08:00
shonenada
3c6b707353 add QINIU_CDN_DOMAIN for wildcard certificate 2019-01-13 12:25:03 +08:00
shonenada
96efc8c7f0 lint codes 2019-01-12 23:11:19 +08:00
shonenada
0cd6afde6f Add guidance to deploying cert to qiniu.com 2019-01-12 21:15:16 +08:00
shonenada
82b11da4ca replace awk with sed and tr 2019-01-12 21:07:22 +08:00
shonenada
4ec39ab707 replace with functions defined in acme.sh 2019-01-12 20:16:28 +08:00
shonenada
d2a60f3ca4 lint code 2019-01-12 15:54:42 +08:00
shonenada
3bc6628227 Update Qiniu's domain settings after uploading certificate 2019-01-12 15:25:36 +08:00
neil
27579e0701 Merge pull request #2012 from bremensaki/pointhq-api
Native PointHQ API
2019-01-12 11:01:14 +08:00
neil
f91bcfeb4b Merge pull request #2021 from krufab/feature/2020-improve-verification-log-readability
Feature/2020 improve verification log readability
2019-01-12 11:00:15 +08:00
shonenada
e19809d5b5 Add deployment for qiniu cdn
Upload certificate and privkey to Qiniu's CDN service with https://developer.qiniu.com/fusion/api/4248/certificate
2019-01-11 18:47:01 +08:00
Fabio Kruger
dd068467de 2020 Added a space to improve log readability 2019-01-10 19:33:25 +01:00
Mike Barnes
3099c799b2 Added PointHQ to supported API list 2019-01-09 10:24:28 +11:00
Mike Barnes
cd3ef8fa5a Correct edits to README.md this time 2019-01-08 15:59:29 +11:00
Mike Barnes
72ce37704b Native PointHQ support 2019-01-08 15:59:29 +11:00
neil
4420d073bb Merge pull request #1889 from apollo13/fix_inwx
Fix inwx account without Mobile TAN
2019-01-07 22:57:09 +08:00
neil
9cc9f519fc Merge pull request #2010 from Neilpang/dev
Support Post as Get
2019-01-06 21:30:57 +08:00
neil
0483d841e3 Support Post as Get (#2009)
* Support POST as GET
https://community.letsencrypt.org/t/acme-v2-scheduled-deprecation-of-unauthenticated-resource-gets/74380

* fix PAG,
The newline '\n' in response is removed by _send_signed_request(), to keep it, we just use needbase64

* fix PAG, the cert is muti line

* fix format

* PAG is only for v2
2019-01-06 21:05:33 +08:00
neil
5546120312 Merge pull request #2006 from Neilpang/dev
sync
2019-01-04 22:54:03 +08:00
neilpang
ad613e2437 fix alpn oid.
https://github.com/Neilpang/acme.sh/issues/2005
2019-01-04 22:40:59 +08:00
neil
c544759d36 Merge pull request #2002 from Ivru/feature/exoscale
Exoscale DNS API
2019-01-03 21:42:42 +08:00
neil
20503d3c58 Merge pull request #2004 from hebbet/patch-4
add link to profile of Cloudflare
2019-01-03 21:27:13 +08:00
Ivru
3fb17c5de8 Merge branch 'dev' into feature/exoscale 2019-01-03 14:25:50 +01:00
Ivru
a5e4bf16d3 Merge pull request #2 from Neilpang/dev
Merging develop
2019-01-03 14:23:16 +01:00
hebbet
68d9aad3a2 add link to profile of Cloudflare
follow-up for #1893
2019-01-03 14:19:55 +01:00
neil
0aba1b4ad3 Merge pull request #1839 from sunflowerit/digitalocean-fix
Fixes on DigitalOcean implementation
2019-01-03 21:14:54 +08:00
neil
e12c7c8d27 Merge pull request #1890 from LLeny/master
Fixes Neilpang/acme.sh#1888
2019-01-03 21:09:45 +08:00
neil
83a040722e Merge pull request #1994 from drott/add_rm_multiple_gandi
[dnsapi] Support adding / removing multiple TXT values for Gandi
2019-01-03 21:03:55 +08:00
neil
b7b504d43a Merge pull request #1996 from Tigger2014/dev
dnsapi update dynu for api v2
2019-01-03 20:55:46 +08:00
neil
b18804f57f Merge pull request #2001 from hosting-de/fix-issue-2000
hosting.de API: waiting for API zoneStatus active
2019-01-03 20:54:55 +08:00
neil
550a5fb4c0 Merge pull request #2003 from martonsz/msz-dns-loopia-fix-wildcard
fix dns_loopia wildcard certificate
2019-01-03 20:53:09 +08:00
Marton Szucs
40f0238bb7 fix dns_loopia wildcard certificate
Checks if a subdomain already exists before creating one. The loopia API clears all records for a subdomain when adding it again.

Adding TXT-records instead of updating the existing record when using the add method. Wildcard certificates require multiple TXT-records for the same subdomain. 

Now you can create wildcard certificates using:
 `acme.sh  --issue -d example.com  -d '*.example.com'  --dns dns_loopia`
Double quoting variables
2019-01-03 11:32:43 +01:00
Oliver Dick
089823785e Using _sleep() instead of sleep 2019-01-03 10:32:59 +01:00
Ivru
ecf7dded07 Fix typo 2019-01-03 08:39:51 +01:00
Ivru
909aba27d1 Merge pull request #1 from Neilpang/master
Merging master
2019-01-03 08:35:54 +01:00
Oliver Dick
cd4f29135b waiting for API zoneStatus active 2019-01-02 16:44:11 +01:00
Ben Edmunds
68c5c366f4 dnsapi update dynu for api v2 2018-12-30 03:21:16 +00:00
Dominik Röttsches
29a5311ae0 [dnsapi] Support adding / removing multiple TXT values for Gandi
Gandi supports setting multiple entries by setting multiple array items
for the rrset_values field in their API. Modify the dns_gandi_livedns.sh
script so that it checks for existing entries, appends new ones if
needed, and removes existing ones individually. This enabled wildcard
certificate support on Gandi.

Fixes the dns_gandi_livedns part of #1261.

Tested for creating a multidomain, multiple wild-card certificate on
Gandi and using a test script executing only the dns_gandi_livedns_add
and dns_gandi_livedns_rm functions.
2018-12-29 10:54:21 +02:00
neil
62d774a548 Merge pull request #1993 from Neilpang/dev
add tls-alpn mode
2018-12-28 23:32:33 +08:00
neilpang
c9baca7910 add tls-alpn mode 2018-12-28 23:12:16 +08:00
neil
86366ae157 Merge pull request #1992 from Neilpang/dev
sync
2018-12-28 23:07:01 +08:00
neilpang
c4094c68ee Support BuyPass.com CA 2018-12-28 23:04:40 +08:00
neilpang
ec67a1b2c1 Do not limit the renew days to 60, it's just a default value.
buypass support 180 days.
2018-12-28 22:52:40 +08:00
neilpang
7ba9a5972d revert fix for https://github.com/Neilpang/acme.sh/issues/1941
1. fix https://github.com/Neilpang/acme.sh/issues/1977
2. The cache is too long to as a line to save in the conf
2018-12-28 22:45:40 +08:00
neilpang
b32071ad04 remove unused code 2018-12-28 22:12:54 +08:00
neil
b38c4e1a28 Merge pull request #1989 from mysteq/buypass-support
Added fixes so BuyPass Go ACME server can be used
2018-12-28 21:32:37 +08:00
neil
a13b2b4018 Merge pull request #1991 from Neilpang/dev
sync
2018-12-28 21:31:20 +08:00
Ketil
65a2f789dc Removing BUYPASS_CA variable 2018-12-28 13:26:20 +01:00
Ketil
8bd12ed040 Rewrite to remove BuyPass spesific fixes and adapt ACME v1 2018-12-28 09:22:31 +01:00
neil
6914662dd8 Merge pull request #1988 from mysteq/spellfix
Fixed spelling of 'tigger' to 'Trigger'
2018-12-28 09:14:39 +08:00
neil
bcb11d9b7e Merge pull request #1987 from mysteq/cloudflare-fix
Bugfix for allowing '+' character in CloudFlare email
2018-12-28 09:13:59 +08:00
Ketil
920cab6f12 Added fixes to also use BuyPass Go ACME server 2018-12-27 16:06:41 +01:00
Ketil
9756adb933 Fixed spelling of 'tigger' to 'Trigger'. 2018-12-27 15:45:19 +01:00
Ketil
2671af13cd Bugfix for allowing '+' character in CloudFlare email 2018-12-27 15:17:19 +01:00
Ne-Lexa
b7b94e38ac support change account conf from env 2018-12-24 14:59:14 +03:00
neil
37792e9b38 Merge pull request #1983 from Neilpang/dev
Dev
2018-12-24 19:33:05 +08:00
Ne-Lexa
f90bf756fb Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2018-12-24 13:42:42 +03:00
Ne-Lexa
0b363a5c98 removed the _clearaccountconf() call for erroneous requests 2018-12-24 13:33:25 +03:00
neil
ebb1a8af1b Merge pull request #1978 from Ivru/feature/exoscale
Feature/exoscale
2018-12-22 10:55:25 +08:00
neil
f4ba7fcaf4 Merge pull request #1979 from titanofold/linode-v4-api-fix
Linode v4 API Fix
2018-12-22 10:52:51 +08:00
neil
13964ac726 Merge pull request #1981 from Neilpang/alpn
Alpn
2018-12-21 20:59:12 +08:00
Aaron W. Swenson
c8c1140f15 Linode API v4 Redo
The Cloud and Classic Manager work with different APIs, and so require
a separate module, which we introduce here.

The README has also been modified to state that the two are separate
and incompatible, and provides instructions on using either.
2018-12-20 11:01:34 -05:00
Aaron W. Swenson
9a473640fb Revert "Update Linode API to v4"
This reverts commit 9a27b38976.

Turns out, the Cloud Manager is not backward compatible, nor is the
Classic Manager forward compatible.
2018-12-20 11:00:10 -05:00
Ivru
405173a0b4 Remove extraneous blank lines 2018-12-20 16:37:11 +01:00
Ivru
8e43b86f06 Export header _H3 2018-12-20 16:30:02 +01:00
Ivru
eea9aaf940 Fix typos 2018-12-20 16:24:08 +01:00
Ivru
67d3e8d049 Add Exoscape API support for DNSAPI 2018-12-20 16:07:05 +01:00
neilpang
f99ca918db fix format 2018-12-18 20:33:33 +08:00
neilpang
79a0a66f1f support --tlsport 2018-12-18 20:18:18 +08:00
neilpang
08681f4a8b support tls-alpn-01 https://github.com/Neilpang/acme.sh/issues/1675#issuecomment-447857756 2018-12-18 19:28:38 +08:00
neil
a58ef94a9c Merge pull request #1972 from Neilpang/dev
sync
2018-12-17 23:03:16 +08:00
neilpang
2b9ebd6662 fix showcsr https://github.com/Neilpang/acme.sh/issues/1968 2018-12-17 23:02:02 +08:00
neil
6fdd2f40ed Merge pull request #1963 from cshoredaniel/pr-allow-dyn-standard-dns
Allow dyn standard dns and debug nsupdate
2018-12-17 10:08:00 +08:00
neilpang
238990a285 add more debug info
https://github.com/Neilpang/acme.sh/issues/1932
2018-12-16 21:10:22 +08:00
Daniel F. Dickinson
1a77490969 dnsapi: Add option to set zone for nsupdate
Some DNS servers for which dns_nsupdate.sh is applicable (such
as dyn.com's 'Standard DNS' TSIG update mechanism), require that
the zone be set during the nsupdate transaction.  Therefore we
add a new environment variable NSUPDATE_ZONE which is used to
set the zone for the DNS TSIG transaction.

Signed-off-by: Daniel F. Dickinson <cshored@thecshore.com>
2018-12-13 01:55:43 -05:00
Daniel F. Dickinson
5431d05168 dnsapi nsupdate: Add nsupdate debug option
When debug is enabled, also use nsupdate's debug logging
so that the user can see potential issues with the nsupdate
transaction.

Signed-off-by: Daniel F. Dickinson <cshored@thecshore.com>
2018-12-13 01:55:00 -05:00
neil
eb97cdc33a Merge pull request #1961 from Neilpang/dev
Dev
2018-12-11 21:42:45 +08:00
neil
b54d6589c3 Merge pull request #1957 from pashinin/master
Write certs in Vault for Fabio load balancer
2018-12-11 21:27:45 +08:00
neil
463768fcf7 Merge pull request #1960 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/1959
2018-12-11 19:19:48 +08:00
neil
a43545c6ea fix https://github.com/Neilpang/acme.sh/issues/1959 2018-12-11 19:11:56 +08:00
Sergey Pashinin
9f067d7f56 Deploy to Hashicorp Vault docs 2018-12-10 18:17:18 +03:00
neil
8907e2d850 Merge pull request #1958 from Neilpang/dev
sync
2018-12-10 22:41:34 +08:00
Sergey Pashinin
c84466b131 Write certs in Vault for Fabio load balancer 2018-12-10 16:55:21 +03:00
neilpang
f62b956e74 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2018-12-06 22:06:15 +08:00
neilpang
9841063df9 fix nginx mode 2018-12-06 22:05:26 +08:00
neil
803c8177d3 Merge pull request #1949 from felixonmars/patch-1
Arch Linux package acme.sh is now in [community]
2018-12-05 13:15:24 +08:00
Felix Yan
7ff525468f Arch Linux package acme.sh is now in [community] 2018-12-05 03:01:50 +08:00
neil
7c1c36f043 Merge pull request #1944 from titanofold/dev
Update Linode API to v4
2018-12-04 21:44:46 +08:00
neil
565e3f75c7 Merge pull request #1947 from aalmenar/master
Neodigit.net DNS API
2018-12-04 21:40:37 +08:00
Adrian Almenar
842f030355 Revert change 2018-12-04 14:36:28 +01:00
Adrian Almenar
f4ad42bb84 Changes requested on commit review 2018-12-04 14:33:00 +01:00
Adrian Almenar
fb08b53f0b Add Neodigit.net DNS API 2018-12-03 18:42:33 +01:00
neilpang
598becf619 minor, fix format 2018-12-03 20:31:20 +08:00
Aaron W. Swenson
9a27b38976 Update Linode API to v4
Linode API has made breaking changes that are resolved by this
update. No user action is required.

Additionally, related README.md entry updated to include new cloud
manager interface.
2018-12-02 12:10:10 -05:00
neilpang
7917aa2a7c fix https://github.com/Neilpang/acme.sh/issues/1941
cache dns zones response
2018-12-02 19:37:35 +08:00
neil
d0c97a589b Merge pull request #1939 from Neilpang/dev
sync
2018-11-29 22:32:17 +08:00
neil
8ec1ea7b7a Merge pull request #1921 from nakermann1973/patch-1
Add missing bind-tools package
2018-11-29 09:54:48 +08:00
neil
71cb6d2bce Merge pull request #1759 from hosting-de/feature/hosting.de-plugin
added hosting.de DNS Plugin
2018-11-28 22:25:57 +08:00
Oliver Dick
ee258f1425 Merge branch 'dev' into feature/hosting.de-plugin 2018-11-28 14:34:09 +01:00
neil
50278674f0 Merge pull request #1934 from epgdatacapbon/master
Increase security using https for MyDNS.JP API
2018-11-26 09:11:12 +08:00
epgdatacapbon
be5085f205 Increase security using https for MyDNS.JP API 2018-11-25 18:14:52 +09:00
neil
ca9476f72a Merge pull request #1931 from epgdatacapbon/master
Add DNS API support for MyDNS.JP
2018-11-24 20:52:59 +08:00
epgdatacapbon
d55c64c838 Update README.md 2018-11-24 14:07:50 +09:00
neil
563de2cc90 Merge pull request #1926 from Rohlik/patch-1
Fix dot
2018-11-24 10:32:39 +08:00
epgdatacapbon
6afe3ccc3b Merge branch 'master' of https://github.com/epgdatacapbon/acme.sh 2018-11-24 02:03:23 +09:00
epgdatacapbon
14ad5955b5 Add DNS API support for MyDNS.JP 2018-11-24 02:02:53 +09:00
epgdatacapbon
a6f2110141 Add DNS API support for MyDNS.JP 2018-11-24 01:58:46 +09:00
neil
393d8b9ded Merge pull request #1929 from Neilpang/dev
sync
2018-11-23 23:11:52 +08:00
neilpang
137dc1eac0 fix https://github.com/Neilpang/acme.sh/issues/1912 2018-11-23 22:53:02 +08:00
Thomas Rohlik
5fee82ce39 Fix dot
Very important commit 🥇
2018-11-19 16:09:32 +01:00
nakermann1973
552710ac2a Add missing bind-tools package
The bind_tools package is required for dns_nsupdate to work
2018-11-13 10:15:38 +01:00
neil
0a9a11636a Merge pull request #1892 from hebbet/patch-2
add link to cloudflare profile for api key
2018-11-10 21:32:48 +08:00
neil
e550631275 Merge pull request #1886 from philr/skip_alias_when_already_verified
Skip aliases of already verified domains
2018-11-10 21:32:05 +08:00
neil
87d2f7f27a Merge pull request #1910 from joakimlemb/master
Increase Azure DNS Zone Limit from 100 to 500
2018-11-10 21:10:47 +08:00
neil
a40cd2b46f Merge pull request #1916 from pavelaks/patch-1
Fix for VSCALE example
2018-11-10 21:09:59 +08:00
pavelaks
4b581f3720 Update README.md
Fix VSCALE example (add export before VSCALE_API_KEY)
2018-11-10 12:10:06 +03:00
Joakim Lemb
12956679e7 Added top URI parameter 2018-11-05 14:52:26 +01:00
neilpang
7903fcb48c fix typo 2018-10-30 22:50:44 +08:00
neilpang
9672c6b885 fix https://github.com/Neilpang/acme.sh/issues/1905 2018-10-30 22:14:49 +08:00
neil
55369d30a6 Merge pull request #1867 from evoadmin/patch-1
Update dns_he.sh
2018-10-30 22:10:21 +08:00
Ne-Lexa
a207199879 fixed _get_root() function 2018-10-29 15:18:43 +03:00
hebbet
a894b7cc9b add link to cloudflare profil for api key 2018-10-24 16:33:02 +02:00
LLeny
46b3a9158c Fixes Neilpang/acme.sh#1888 2018-10-21 18:17:23 +08:00
Jan-Otto Kröpke
26421684dc Fix inwx account without Mobile TAN 2018-10-19 16:08:00 +02:00
Phil Ross
fd536d373e Skip aliases of already verified domains.
When issuing a two-domain certificate using a different alias for each
domain, if the first domain is already verified, verification for the
second domain would be attempted (unsuccessfully) using the alias of the
first domain.

Increment the alias index when skipping verified domains so that the
correct alias will be used for subsequent domains.
2018-10-18 17:57:15 +01:00
neil
4f59a821d3 Merge pull request #1883 from Neilpang/dev
Dev
2018-10-17 22:38:18 +08:00
neil
b29e21efa8 Merge pull request #1881 from ephen/patch-1
cloudxns.net
2018-10-17 22:33:54 +08:00
Ne-Lexa
a63dc75b43 Added documentation on using dns api internet.bs 2018-10-15 18:20:26 +03:00
Ephen
9f6f721a13 cloudxns.net
cloudxns.net is the main domain.
2018-10-15 17:11:25 +08:00
Ne-Lexa
fdb9d93b12 formatted 2018-10-12 19:27:41 +03:00
Ne-Lexa
475e6e28eb Added dns api support for internet.bs 2018-10-12 19:04:18 +03:00
evoadmin
4c1f70af4b Update dns_he.sh
If you have a password with special char it will fail at Remove record
2018-10-02 10:43:25 +03:00
andrewheberle
454c90820d Actually set reload default 2018-09-28 08:57:13 +08:00
andrewheberle
0a4e61c1dd Readme update 2018-09-28 08:46:39 +08:00
andrewheberle
31d9ba7e02 Change default for reload 2018-09-28 08:45:18 +08:00
neilpang
6a81b0f807 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2018-09-25 23:42:14 +08:00
neilpang
3322630732 minor, debug msg 2018-09-25 23:42:04 +08:00
Oliver Dick
d8885984ab Merge branch 'dev' into feature/hosting.de-plugin 2018-09-12 10:04:45 +02:00
Tom Blauwendraat
4a18c45e4f fixup! [FIX] Delete all occurrences of TXT key, dont fail if there is more than one, [FIX] Respect pagination on domain listing, before only the first page was loaded 2018-09-12 05:46:51 +02:00
Tom Blauwendraat
5b7cac1002 [FIX] Delete all occurrences of TXT key, dont fail if there is more than one, [FIX] Respect pagination on domain listing, before only the first page was loaded 2018-09-12 05:34:56 +02:00
neil
5aef9266cb Merge pull request #1833 from cbrandel/master
use perl instead of iconv, if iconv is not available
2018-09-10 13:13:33 +08:00
Christian Brandel
80b40c02b4 use perl instead of iconv, if iconv is not available 2018-09-10 01:24:20 +02:00
neil
56d6079c4a Merge pull request #1831 from LLeny/master
Namecheap API
2018-09-09 21:14:10 +08:00
LLeny
3975792bf1 shfmt 2018-09-08 08:06:35 +08:00
LLeny
697e694de6 Indentation 2018-09-08 07:28:56 +08:00
LLeny
828d8eaadb NC API warning 2018-09-08 07:06:35 +08:00
LLeny
30ee00ff50 RM TXT check 2018-09-08 07:06:16 +08:00
LLeny
7e130c2618 README fixes 2018-09-08 07:05:44 +08:00
LLeny
b859dd660c dns_rm support 2018-09-07 20:53:21 +08:00
LLeny
8868783476 Staging 2018-09-07 20:52:49 +08:00
LLeny
dc0dd6588c Support list 2018-09-07 20:52:34 +08:00
LLeny
f7e7e885a9 Usage 2018-09-07 20:52:10 +08:00
LLeny
d813be1f48 WIP 2018-09-05 21:29:42 +08:00
LLeny
0d03309c2f Namecheap initial 2018-09-02 21:25:44 +08:00
Oliver Dick
1dab353fdb Merge branch 'dev' into feature/hosting.de-plugin 2018-08-30 14:28:50 +02:00
neil
8eb4efaddb Merge pull request #1819 from loial/dns_gdnsdk_fix
Gratisdns.dk: Fix typo in url, also added note recommending --dnsslee…
2018-08-29 13:43:37 +08:00
Herman Sletteng
12c900ea7d Gratisdns.dk: Fix typo in url, also added note recommending --dnssleep 300 2018-08-29 00:46:54 +02:00
neil
c31db83b26 Merge pull request #1817 from Neilpang/dev
Dev
2018-08-27 23:05:59 +08:00
neil
98ce8f4c2f Merge pull request #1620 from loial/dns_gratisdns.dk
DNS plugin for Danish service gratisdns.dk
2018-08-27 23:05:15 +08:00
Herman Sletteng
1f25b4a8a9 Replacing "grep -o -P" with "_egrep_o" and sed 2018-08-24 13:27:16 +02:00
Herman Sletteng
1756bbff84 DNS plugin for Danish service gratisdns.dk
Currently only supports primary domains. My use case does not involve
secondary domains so I'm not sure how it behaves, and cannot test it.
Might be as simple as turning all "primary"-references into a variable
that's either "primary" or "secondary", and make an extra check for this
in _get_domain...

Cookie handling heavily inspired by freedns plugin, including caching
the cookie in the config file, so we can rm without re-authenticating
2018-08-24 02:12:33 +02:00
neil
21b2ffa42e Merge pull request #1796 from ybizeul/deploy-gitlab
Gitlab deploy option
2018-08-23 13:36:57 +08:00
neil
b6efdac1db Merge pull request #1605 from linux-insideDE/dev
Added netcup DNS API
2018-08-23 13:25:54 +08:00
linux-insideDE
fc9d321ebe Merge branch 'dev' into dev 2018-08-22 21:07:05 +02:00
Yann Bizeul
68a290c347 revert dns_inwx.sh to dev 2018-08-22 19:08:33 +02:00
neil
9133de50e9 Merge pull request #1756 from crazyhacks/conoha
Add support ConoHa DNS API
2018-08-22 22:48:33 +08:00
KUDO Takashi
73d04b976e avoid "SC2046: Quote this to prevent word splitting." Travis CI error. 2018-08-22 23:25:55 +09:00
KUDO Takashi
a35d271669 cleanup 2018-08-22 23:25:55 +09:00
KUDO Takashi
72a7f932c6 fix indent 2018-08-22 23:25:55 +09:00
KUDO Takashi
2e74df2583 Add support ConoHa DNS API 2018-08-22 23:25:55 +09:00
linux-insideDE
4fffb3c816 make shfmt happy 2018-08-21 21:55:44 +02:00
linux-insideDE
840b3a34cb changed some chars 2018-08-21 21:47:40 +02:00
linux-insideDE
dc267663a7 Merge branch 'dev' into dev 2018-08-21 21:15:53 +02:00
Yann Bizeul
8d6443b25d Fix Syntax 2018-08-21 16:41:45 +02:00
Yann Bizeul
e3c7fc8077 Fix Syntax 2018-08-21 16:35:39 +02:00
Yann Bizeul
bbf2a15f27 Fix Syntax 2018-08-21 16:30:33 +02:00
Yann Bizeul
5a326b82bd Fix Syntax 2018-08-21 16:24:57 +02:00
Yann Bizeul
f1b0dd7836 Fix Syntax 2018-08-21 16:22:08 +02:00
Yann Bizeul
c205777542 Better integration with acme.sh utils 2018-08-21 16:18:00 +02:00
neil
329a1e6f16 Merge pull request #1623 from lenartj/dev
Added support for Google Cloud DNS API (dns_gcloud)
2018-08-21 21:38:19 +08:00
Janos Lenart
9c39121e99 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2018-08-21 13:32:29 +00:00
Yann Bizeul
e5e57e684e Merge branch 'deploy-gitlab' of github.com:ybizeul/acme.sh into deploy-gitlab 2018-08-21 15:28:52 +02:00
neil
659a60aeec Merge pull request #1772 from gliljas/patch-2
Spelling in dns_aws.sh
2018-08-21 21:06:36 +08:00
neil
b0268adad9 Merge pull request #1782 from omegazeng/dev
add dns api support for dnspod.com
2018-08-21 21:05:43 +08:00
neil
71e4bbfc99 Merge pull request #1804 from ctron/feature/add_lexicon_opts_1
Add support for additional Lexicon options
2018-08-21 21:01:28 +08:00
neil
c6bd004d63 Merge pull request #1806 from Aarup/dev
Update dns api to support v2 wildcard cert #1261
2018-08-21 20:58:26 +08:00
Aarup
8b6986ba18 Fix file formatting 2018-08-21 12:32:30 +02:00
Jens Reimann
b23718f3ad Add support for additional Lexicon options 2018-08-21 11:51:26 +02:00
Aarup
8113548920 Update dns api to support v2 wildcard cert #1261 2018-08-21 11:44:36 +02:00
Yann Bizeul
b401dbbf65 Fix Syntax 2018-08-15 19:17:24 +02:00
Yann Bizeul
75dd0a770f Fix Syntax 2018-08-15 19:10:31 +02:00
Yann Bizeul
6d8292cdd8 Syntax fix 2018-08-15 19:00:08 +02:00
Yann Bizeul
0575eb671a Fix double quote around URL 2018-08-15 18:44:24 +02:00
Yann Bizeul
d06eea53ef Add deploy plugin for Gitlab pages 2018-08-15 18:36:34 +02:00
Yann Bizeul
9e96a93172 Updated README with Gitlab help 2018-08-15 18:36:24 +02:00
Janos Lenart
441f8f3ce8 Replied to PR comments 2018-08-15 12:05:57 +01:00
Janos Lenart
1d4dec5510 Moved dns_gcloud to 47. 2018-08-15 12:05:57 +01:00
Janos Lenart
167758003c Fixed shfmt (dns_gcloud) 2018-08-15 12:03:38 +01:00
Janos Lenart
0a3ac1f5c3 Added support for Google Cloud DNS API (dns_gcloud) 2018-08-15 12:03:38 +01:00
neil
9173140ddf Merge pull request #1788 from ghostwheel42/dev
createDomainKey: fix exitcode for creating new key
2018-08-15 13:27:04 +08:00
Alexander Graf
7aeb113c62 createDomainKey: fix exitcode for creating new key
when running acme.sh headless (without terminal) to create a new key
createDomainKey returns a non-zero exit-code.
explicitly returning zero avoids this.
2018-08-14 10:04:14 +02:00
Hitoshi
22cd408efb add dns api support for dnspod.com 2018-08-12 18:15:20 +08:00
Gunnar Liljas
4fbd21da57 Spelling 2018-08-07 13:35:08 +02:00
Oliver Dick
ed95509a4f hosting.de API keys can contain special chars, so using simple quotes 2018-08-02 15:47:02 +02:00
Oliver Dick
4162975f9f added hosting.de API to README's 2018-08-02 15:43:40 +02:00
neil
ac0cdcf70b Merge pull request #1760 from lf-zbw/dev
Fix key leakage in SSH deploy log.
2018-08-02 21:25:26 +08:00
little-fat
63134fafec Fix key leakage in SSH deploy log 2018-08-02 20:57:27 +08:00
Oliver Dick
5494e88e08 making shfmt happy 2018-08-01 17:00:22 +02:00
Oliver Dick
86276ad17b added hosting.de DNS Plugin
* can be used with API of hosting.de
 * can also be used with ICANN registrar http.net
 * needs just API key and endpoint
 * support wildcard certificates
2018-08-01 16:48:00 +02:00
neil
c883ec40d7 Merge pull request #1750 from jkroepke/fix_inwx_tfa
Fix inwx account without Mobile TAN
2018-07-29 19:16:11 +08:00
neil
d19bc328f3 Merge pull request #1745 from oldium/add-lexicon-rm
Added dns_lexicon_rm command
2018-07-29 19:13:29 +08:00
neil
f286f904dc Merge pull request #1753 from Neilpang/dev
Dev
2018-07-28 22:40:42 +08:00
neil
150029a5e2 Merge pull request #1752 from Neilpang/badnonce
add more retry for badnonce error
2018-07-28 22:14:16 +08:00
neilpang
709a3fb06f add more retry for badnonce error 2018-07-28 22:02:03 +08:00
Jan-Otto Kröpke
d3c9d0b331 Fix inwx account without Mobile TAN 2018-07-26 21:32:35 +02:00
neilpang
cc2d59468d use json content type for both v1 and v2 2018-07-26 21:57:22 +08:00
neil
91391fba5d Merge pull request #1749 from Neilpang/dev
Dev
2018-07-26 21:56:39 +08:00
Oldřich Jedlička
4369402855 Cleaned-up shellcheck warnings. 2018-07-25 10:40:57 +02:00
neil
0bc556618f Merge pull request #1746 from j-c-m/time2str-dev
BSD fix _time2str()
2018-07-25 12:10:39 +08:00
Jesse Miller
cb11580981 BSD fix _time2str()
date -u -d@"12345" does not produce an error on *BSD and outputs the
current date in UTC, which is not the expected output from _time2str()

Fix, reorder _time2str() to attempt BSD style date first, which
errors on Linux, so cascade style OS detection works correctly.
2018-07-24 22:41:01 -05:00
Old?ich Jedli?ka
0366e8758c Added reading of stored config. 2018-07-24 22:41:43 +02:00
Old?ich Jedli?ka
8d230dd798 Added dns_lexicon_rm command.
Remove created TXT record when finished. Works with lexicon version 2.3.0
and later.
2018-07-24 16:30:47 +02:00
neilpang
411b342a27 request a new nonce for invalid anti-replay nonce error 2018-07-18 22:00:09 +08:00
neilpang
b9b7032386 lets start v2.8.0 2018-07-18 00:33:07 +08:00
neil
c38ef9023b Merge pull request #1738 from Neilpang/dev
sync
2018-07-18 00:30:47 +08:00
neil
9cecd525e2 fix JWS has an invalid anti-replay nonce https://github.com/Neilpang/acme.sh/issues/1630 2018-07-18 00:26:21 +08:00
neil
4f5995abc0 Merge pull request #1717 from initit/master
added dnsapi for euserv.eu
2018-07-10 09:18:58 +08:00
Michael
2945b230e4 replaced tail/head with _tail_n/_head_n and printf with echo 2018-07-09 22:54:34 +02:00
Michael
261cc448f7 fixed shfmt related errors in dns_euserv.sh and modified README.md 2018-07-08 23:00:26 +02:00
Michael
616b0b6baa fixed shfmt related errors in dns_euserv.sh and modified README.md 2018-07-08 22:50:52 +02:00
Michael
d99968ee6d Modified dnsapi/README.md 2018-07-08 16:25:35 +02:00
Michael
4a65ff6ae2 Merge https://www.github.com/initit/acme.sh 2018-07-08 16:20:09 +02:00
Michael
94f91ae687 initial version with Euserv.eu DNS API Support
- added dnsapi/dns_euserv.sh
 - modified dnsapi/README.md
2018-07-08 16:17:57 +02:00
Michael
28e4bcf67f initial version with Euserv.eu DNS API Support 2018-07-08 16:04:18 +02:00
neil
884461f1a6 Merge pull request #1705 from war59312/patch-2
Update README.md - HTTPS For centminmod.com Link
2018-07-02 09:53:37 +08:00
Will
26c669e42d Update README.md - HTTPS For centminmod.com Link
Update README.md - HTTPS For centminmod.com Link
2018-07-01 18:53:47 -04:00
neil
f60dde4138 Merge pull request #1698 from Neilpang/dev
Dev
2018-06-29 20:12:57 +08:00
neilpang
9c545059ae fix warning 2018-06-28 22:21:22 +08:00
neilpang
05dea7b22a fix warning 2018-06-28 20:34:29 +08:00
neil
5b3f915d90 Merge pull request #1697 from santerikannisto/patch-6
Issue #1328 bug fix v3
2018-06-28 15:39:30 +08:00
Santeri Kannisto
d987d61ea9 Issue #1328 bug fix v3
Eliminated php dependency with a private function for urlencode using sed. Php had failed on godaddy due to multiple php instances and naturally cron using the one without the necessary -r option. Compared to previous PR the sed code is now POSIX and should work on all environments.
2018-06-28 09:38:14 +02:00
neil
dedb56d295 Merge pull request #1563 from kordianbruck/dev
Increase serial when adding txt records
2018-06-27 10:51:31 +08:00
neil
8697972d5d Merge pull request #1669 from Neilpang/dev
check UNABLE_TO_AUTHENTICATE
2018-06-12 21:23:33 +08:00
neilpang
f90a2ae195 check UNABLE_TO_AUTHENTICATE 2018-06-12 21:19:27 +08:00
neil
084de9d8e0 Merge pull request #1635 from Neilpang/dev
Dev
2018-05-29 23:37:48 +08:00
linux-insideDE
69b780ee32 Update dns_netcup.sh 2018-05-29 17:24:53 +02:00
linux-insideDE
c7b904501c make shfmt happy 2018-05-29 16:56:07 +02:00
neilpang
206be3c161 fix https://github.com/Neilpang/acme.sh/issues/1633 2018-05-29 22:38:52 +08:00
linux-insideDE
48e8022095 improved handling for third level domains 2018-05-29 16:23:28 +02:00
linux-insideDE
4715a1a5e0 satisfy shellcheck 2018-05-16 22:07:44 +02:00
linux-insideDE
ed2ba6bc3a removed jq dependencies 2018-05-15 16:22:40 +02:00
linux-insideDE
ca1d62bec0 removed jq dependencies 2018-05-15 16:21:57 +02:00
linux-insideDE
6a4aad1aa8 replaced increment/decrement with _math function 2018-05-15 14:38:29 +02:00
linux-insideDE
3f0462b68b Merge pull request #1 from linux-insideDE/netcup-api
added netcup api
2018-05-15 13:26:00 +02:00
linux-insideDE
f3a622d1a7 added netcup dns api 2018-05-15 13:22:55 +02:00
linux-insideDE
3cd5b9ca2e added netcup dns api 2018-05-15 13:21:25 +02:00
linux-insideDE
e9782c3219 Create dns_netcup.sh 2018-05-15 13:18:50 +02:00
andrewheberle
8d348954a7 Whitepspace 2018-05-14 13:22:46 +08:00
andrewheberle
7d19d784df Update cert suffix for bundles .ocsp generation 2018-05-14 13:16:56 +08:00
andrewheberle
733b4e0a34 Fix Le_Keylength case 2018-05-14 11:26:03 +08:00
andrewheberle
08d29a8342 Fix return from reload 2018-05-14 10:58:46 +08:00
andrewheberle
675e2d25d6 update for new haproxy deploy vars 2018-05-10 15:28:54 +08:00
andrewheberle
ba20af48d3 Support HAPROXY_DEPLOY_PEM_PATH
Adds compatibility to original haproxy deploy hook while still allowing custom PEM file name (via HAPROXY_DEPLOY_PEM_NAME)
2018-05-10 15:25:28 +08:00
andrewheberle
707e053949 whitespace fixes 2018-05-10 12:18:03 +08:00
andrewheberle
c47e67e52c Fix variable name 2018-05-10 12:06:25 +08:00
andrewheberle
3a95bfb699 Document updated haproxy deploy hook 2018-05-10 12:02:58 +08:00
andrewheberle
6567bb4c12 Update haproxy deploy hook
Add functionality to add OCSP stapling info (.ocsp file), issuer (.issuer file) and multi-cert bundles (suffix on pem file based on key type).

This also corrects the order of key, certificate and intermediate in the PEM file, which although HAProxy does not seem to care, was incorrect in the prior version.
2018-05-10 11:51:59 +08:00
neil
39ba697e19 Merge pull request #1584 from dwatrous/patch-1
Add HAProxy deploy implementation and documentation
2018-05-08 22:06:41 +08:00
Daniel Watrous
c9818ea2c4 add documentation for reload command 2018-05-04 13:03:27 -05:00
Daniel Watrous
afe5cb588d update for POSIX compliance 2018-05-04 10:25:54 -05:00
Daniel Watrous
e9e999542d add reload 2018-05-04 10:14:31 -05:00
neil
d9db90752e Merge pull request #1579 from par-pa/support-tele3
Support tele3
2018-05-04 22:29:10 +08:00
neil
f7c3f52817 Merge pull request #1585 from Neilpang/dev
Dev
2018-05-04 22:24:52 +08:00
neilpang
681e3785ef add dns alias mode 2018-05-04 22:23:56 +08:00
Daniel Watrous
5f593994c7 remove more whitespace (trying to get TravisCI working) 2018-05-03 12:25:11 -05:00
Daniel Watrous
ec73aeba16 remove whitespace 2018-05-03 12:17:26 -05:00
Daniel Watrous
7573e560b6 Add conditional check to ensure path is provided 2018-05-03 10:06:05 -05:00
Daniel Watrous
c8bc155cfe Merge pull request #1 from dwatrous/patch-2
add docs for HAProxy deployment
2018-05-03 01:38:33 -05:00
Daniel Watrous
1eae73105a add docs for HAProxy deployment 2018-05-03 01:33:06 -05:00
Daniel Watrous
360dc140ea implement basic haproxy deploy
HAProxy requires the certificate chain and key to be concatenated and placed somewhere (can be anywhere). This script expects a single environment variable with the path where the concatenated PEM file should be written
2018-05-03 01:28:56 -05:00
Vlad Roskov
f85348ba94 fix delete multiple records 2018-05-03 01:01:14 +03:00
Vlad Roskov
2f15ad4be0 fix authentication 2018-05-03 01:00:51 +03:00
Vlad Roskov
f254bb39a5 bail out on no access 2018-05-03 00:58:25 +03:00
Vlad Roskov
c58465d630 fix comparison on empty var 2018-05-03 00:57:50 +03:00
Kordian Bruck
03a1386902 Update serial also when deleting the token 2018-05-02 23:01:52 +02:00
Roman Bližík
70b56eb527 remove whitespace 2018-05-02 11:13:10 +02:00
Roman Bližík
4e05062def add tele3-dns plugin 2018-04-30 15:09:51 +02:00
neil
266333468b Merge pull request #1566 from steffenbusch/dev
Added --force-color to enforce the use of ANSI Color. Issue #1557
2018-04-27 23:26:53 +08:00
Steffen Busch
e32b3aac22 Added --force-color to enforce the use of ANSI Color. Issue #1557 2018-04-26 21:02:37 +02:00
Kordian Bruck
676402d918 Increase serial when adding txt records 2018-04-26 11:40:17 +02:00
neil
edb4d066a9 Merge pull request #1555 from Neilpang/dev
sync
2018-04-24 19:53:07 +08:00
neil
03f4518da9 Merge pull request #1553 from OlegRakovitch/patch-2
Add missing package to docker image
2018-04-23 23:39:56 +08:00
Oleg Rakovitch
8259e82787 Add missing package to docker image
Issue #1552
2018-04-23 18:34:15 +03:00
neil
838d3ddc17 Merge pull request #1550 from Neilpang/dev
sync
2018-04-22 16:04:38 +08:00
neilpang
66686de4e4 add --branch 2018-04-21 13:21:56 +08:00
neilpang
ce8dca7afe move renewhook after installcert
fix https://github.com/Neilpang/acme.sh/issues/1547
2018-04-21 13:15:17 +08:00
neil
9f5ef4c1cb Merge pull request #1546 from Neilpang/dev
fix shfmt
2018-04-21 10:53:32 +08:00
neilpang
f0a87da375 fix shfmt 2018-04-20 23:32:42 +08:00
neil
263e30d25d Merge pull request #1545 from Neilpang/dev
Dev
2018-04-20 23:26:48 +08:00
neilpang
15ffc30d88 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2018-04-20 23:23:11 +08:00
neilpang
8a5c4979ad fix shellcheck 2018-04-20 23:22:25 +08:00
Grant Millar
e36fbd6af5 Fix DNSimple when zone has > 100 records
The _get_records function currently returns the first 100 records. As our TXT is added most recently, if you have > 100 records it will not be returned.

I've changed the function to sort by ID DESC, so it will always return the latest 100 records.
2018-04-20 09:41:07 +01:00
neil
3216806fae Merge pull request #1540 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/1539
2018-04-20 14:05:44 +08:00
neil
f8526f027c fix https://github.com/Neilpang/acme.sh/issues/1539 2018-04-20 14:05:09 +08:00
neil
ed3066aae7 Merge pull request #1515 from Neilpang/dev
sync
2018-04-13 22:33:53 +08:00
neilpang
98a7e72f0a fix https://github.com/Neilpang/acme.sh/issues/1512#issuecomment-381121303 2018-04-13 21:28:13 +08:00
neil
a2259865b3 Merge pull request #1501 from jkroepke/inwx_mtan
Add Support for inwx.de mobile tan
2018-04-12 20:54:53 +08:00
Jan-Otto Kröpke
63f3283591 Add Support for inwx mobile tan 2018-04-10 20:02:57 +02:00
neil
d670ea4f59 Merge pull request #1497 from Neilpang/dev
sync
2018-04-07 11:52:53 +08:00
neil
d0d10bc6e7 Merge pull request #1490 from AlexeyStolyarov/master
#issue with nsupdate on Ubuntu 14.04.1 LTS
2018-04-07 11:52:05 +08:00
neil
4fea06c9fa Merge pull request #1393 from webner/acme-dns
add acme-dns plugin
2018-04-07 11:50:33 +08:00
neil
09fed60dec Merge pull request #1494 from Neilpang/dev
sync
2018-04-06 11:37:22 +08:00
AlexeyStolyarov
75b9c39b0e Update dns_nsupdate.sh 2018-04-05 14:50:55 +05:00
AlexeyStolyarov
5957a1068f Update dns_nsupdate.sh 2018-04-05 14:45:15 +05:00
AlexeyStolyarov
df5229c7c8 Merge pull request #1 from AlexeyStolyarov/AlexeyStolyarov-patch-1
#issue with nsupdate on  Ubuntu 14.04.1 LTS
2018-04-05 14:19:34 +05:00
AlexeyStolyarov
ed817c81de #issue with nsupdate on Ubuntu 14.04.1 LTS
on  Ubuntu 14.04.1 LTS if nsupdate runs without port number given it treated argument following server name as port number.
and throws error: 
```
port 'update' is not numeric
syntax error
```
2018-04-05 14:18:53 +05:00
Wolfgang Ebner
dd72f7638d add acme-dns plugin 2018-04-03 10:18:54 +02:00
neil
a77e4aa6fa Merge pull request #1482 from martgras/dev
Fixes dns_he Issue #1476
2018-04-03 09:14:16 +08:00
martgras
792f3775ce Fixes dns_he Issue #1476
username / password has to be urlencoded
2018-04-02 18:32:28 +02:00
neil
4c7700ec3b Merge pull request #1480 from Neilpang/master
sync
2018-04-02 13:31:21 +08:00
neil
eee296c4c2 Merge pull request #1475 from pandiloko/patch-1
False case in variable name for dreamhost api
2018-04-02 13:17:29 +08:00
pandiloko
499f745732 False case in variable name for dreamhost api 2018-04-01 14:41:35 +02:00
neil
446388e0ba Merge pull request #1378 from ivarmedi/master
Add dns_loopia
2018-04-01 09:51:22 +08:00
neil
e1628bcdd8 Merge pull request #1429 from softcat/dev
Fixed DNSAPI for PowerDNS to support wildcard certificates
2018-04-01 09:50:33 +08:00
neil
6d5874fc45 Merge pull request #1448 from martgras/patch-3
dns_azure  add support for validation record at domain apex
2018-04-01 09:49:28 +08:00
neil
3d563dea87 Merge pull request #1444 from adrum/patch-1
Fixed Dreamhost ENV var name in dnsapi/README.md
2018-04-01 09:48:48 +08:00
neilpang
09304c33c1 start 2.7.9 2018-03-29 21:51:33 +08:00
neil
521d8c4b1f Merge pull request #1464 from Neilpang/dev
sync
2018-03-29 21:39:09 +08:00
Ivar Larsson
b7d573a4b8 Merge branch 'dev' of github.com:Neilpang/acme.sh 2018-03-28 22:05:39 -04:00
neil
4a62385dcc Merge pull request #1460 from Habetdin/patch-1
Update Zilore API description
2018-03-29 09:33:50 +08:00
Habetdin
98e15f658e Update Zilore API description 2018-03-29 04:31:46 +03:00
neil
0a3fa35c5d Merge pull request #1451 from Habetdin/dev
Adding support of Zilore API
2018-03-29 09:09:45 +08:00
neil
02e095bec2 Merge pull request #1459 from rbelnap/vault_deploy_chain_Fix
add chain cert
2018-03-29 09:08:45 +08:00
Ivar Larsson
696d9c6bd3 remove merge chars 2018-03-28 17:15:31 -04:00
Ivar Larsson
50dee5d464 Merge branch 'master' of github.com:Neilpang/acme.sh 2018-03-28 16:25:38 -04:00
Bob Belnap
87a8dda955 add chain cert 2018-03-28 12:40:31 -04:00
Habetdin
d7c73f590c Merge branch 'patch-2' into dev 2018-03-28 18:29:54 +03:00
Habetdin
d1b197e339 Merge branch 'patch-1' into dev 2018-03-28 18:29:48 +03:00
Habetdin
8f5ee989ba Update README.md 2018-03-28 18:26:34 +03:00
Habetdin
ce9c227425 Update README.md 2018-03-28 18:25:52 +03:00
Habetdin
e32c2b84ee Revert "Update README #1"
This reverts commit 6b0333e919.
2018-03-28 18:22:38 +03:00
Habetdin
ce9f77afed Revert "Update README #2"
This reverts commit 882e1db1d6.
2018-03-28 18:22:36 +03:00
Habetdin
2bc38b2063 Revert "Update README.md"
This reverts commit b4f4c28871.
2018-03-28 18:22:33 +03:00
Habetdin
b4f4c28871 Update README.md 2018-03-28 18:17:22 +03:00
Habetdin
b14ef537e1 head => _head_n 2018-03-28 18:14:45 +03:00
neil
84ac386481 Merge pull request #1437 from james-gibson/remove-line-wraps-on-basic-auth
Disable line wrapping on base64 conversion to prevent auth failure
2018-03-28 22:00:44 +08:00
neil
f0365d32aa Merge pull request #1457 from Neilpang/dev
sync
2018-03-28 21:37:58 +08:00
neil
795764f22f Merge pull request #1420 from kinghost/master
Add dns_kinghost.sh
2018-03-28 21:26:44 +08:00
Felipe Braz
986f61ac92 deleted wrog file 2018-03-28 10:18:43 -03:00
neil
09576f2f4f Merge pull request #1445 from martgras/patch-2
dns_he - proposed fix for #1438
2018-03-28 21:08:32 +08:00
neil
bba474dc6b Merge pull request #1447 from itssimple/dev
Fixes DNSimple for Wildcard certificates
2018-03-28 20:17:51 +08:00
Habetdin
fde971fe81 Fix formatting 2018-03-27 06:31:25 +03:00
Habetdin
882e1db1d6 Update README #2 2018-03-27 06:23:15 +03:00
Habetdin
6b0333e919 Update README #1 2018-03-27 06:21:10 +03:00
Habetdin
914808b867 Adding Zilore API support 2018-03-27 06:16:39 +03:00
Pål Håland
8d38cf4d1f Use allchain instead of ca an cert, add documentation after review 2018-03-26 22:00:01 +02:00
Felipe Braz
2d1d512d0f removed redundant api call 2018-03-26 14:28:52 -03:00
Felipe Braz
37bc099d39 removed redundant api call 2018-03-26 14:27:21 -03:00
martgras
9e3c931b34 dns_azure add support for validation record at domain apex
Prevent the issue described in #1442
Fix [SC1117] Backslash is literal in "\[".
2018-03-26 17:45:16 +02:00
Felipe Braz
f8fb0e67b4 fix dnsapi/dns_kinghost.sh with shfmt utility 2018-03-26 12:17:10 -03:00
Felipe Braz
86ef6e6987 fixes on dnsapi/dns_kinghost.sh and dnsapi/README.md 2018-03-26 11:21:12 -03:00
Felipe Braz
e8fd373e6c removed blank space at ending of dnsapi/dns_kinghost.sh 2018-03-26 10:58:56 -03:00
Felipe Braz
7efa546665 removed local .gitignore file 2018-03-26 10:58:22 -03:00
Felipe Braz
4d2a0697ed fix identation dnsapi/dns_kinghost.sh 2018-03-26 10:49:34 -03:00
Felipe Braz
c6023782a4 Merge branch 'dev' of github.com:Neilpang/acme.sh 2018-03-26 10:39:58 -03:00
Chris
30283282d2 Fixing code style according to Travis 2018-03-26 09:40:33 +02:00
Chris
7588fc0989 Fixes DNSimple for Wildcard certificates 2018-03-26 09:32:41 +02:00
Pål Håland
d698c1093a remove spaces around assignment 2018-03-26 08:24:04 +02:00
Pål Håland
7b327d47c0 Fix documentation 2018-03-26 08:21:31 +02:00
Pål Håland
e629985cf4 Use _cdomain if ROUTER_OS_HOST is missing 2018-03-26 07:41:56 +02:00
Pål Håland
aa875f1147 Merge branch 'master' into dev 2018-03-25 22:50:58 +02:00
martgras
fe843bc466 dns_he - proposed fix for #1438
if you have more than one zone of a domain (e.g.  example.com and subdomain.example.com) _find_zone fails. 
This fix removes partials matches.
2018-03-25 14:32:51 +02:00
Austin Drummond
5b355c6ca7 Fixed Dreamhost ENV var name in dnsapi/README.md 2018-03-24 18:57:22 -04:00
Nils Sandmann
a3f7ff90e3 Used e_grep_o instead grep -Po, dns_pdns_rm() now deletes only entry with matching txt value 2018-03-24 18:46:04 +01:00
Nils Sandmann
1f3f8a5073 Merge remote-tracking branch 'upstream/master' into dev 2018-03-24 18:43:21 +01:00
James Gibson
9c88971bc1 Use internal base64 util instead of PATH bin/ 2018-03-23 14:46:54 -06:00
neilpang
aad309ee4f fix https://github.com/Neilpang/acme.sh/issues/1430 2018-03-24 00:06:39 +08:00
Felipe Braz
e80ca4ddbc Merge branch 'dev' of github.com:Neilpang/acme.sh 2018-03-23 12:06:07 -03:00
neil
28ccad28c2 Merge pull request #1436 from james-gibson/patch-1
Clarified the language around the Name.com steps
2018-03-23 20:35:58 +08:00
James Gibson
ba9e7fbf64 Clarified the language around the Name.com steps
Name.com has simplified the process to obtain API tokens, this clarifies the language around requesting a key.
2018-03-22 22:52:30 -06:00
neil
28c85cf8e7 Merge pull request #1432 from pyriand3r/master
Added additional information for do.de users
2018-03-23 09:25:19 +08:00
neil
526b5a8d25 Merge pull request #1435 from ATLief/patch-1
Patch 1
2018-03-23 09:10:46 +08:00
Alex
6b15cf3f72 Remove template text 2018-03-22 13:45:43 -04:00
pyriand3r
fbd8ab47ea only reseller can use do.de's reseller interface 2018-03-22 11:23:16 +01:00
Nils Sandmann
893917a25d Fix travis errors 2018-03-22 11:13:46 +01:00
Nils Sandmann
af5ff2bb93 Modified DNSAPI for PowerDNS to support wildcard certificates 2018-03-21 16:43:42 +01:00
Ivar Larsson
8995d3434f _contains instead of echo 2018-03-21 11:19:22 -04:00
Ivar Larsson
5f9b0675e2 loopia -> loopia.se 2018-03-21 11:18:26 -04:00
neilpang
46ac97a3ff update doc 2018-03-21 20:57:48 +08:00
neil
db3264ab8c Merge pull request #1427 from Neilpang/dev
sync
2018-03-21 20:40:59 +08:00
neilpang
a0923622ae fix https://github.com/Neilpang/acme.sh/issues/1029
https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode
2018-03-21 20:30:52 +08:00
Felipe Braz
aa9975ad0d dns_kinghost.sh :: changed printf to echo 2018-03-20 10:08:52 -03:00
Felipe Braz
6787c81abe renamed KINGHOST_username => KINGHOST_Username 2018-03-20 09:58:10 -03:00
Felipe Braz
72205176e1 Merge branch 'dev' of github.com:Neilpang/acme.sh 2018-03-19 18:04:46 -03:00
Felipe Braz
480742cc15 Merge branch 'master' of github.com:Neilpang/acme.sh 2018-03-19 13:52:49 -03:00
Felipe Braz
48bdfa2377 added doc header to dns_kinghost.sh 2018-03-19 13:49:58 -03:00
Felipe Braz
2ff6f4d3cf updated docs for dns_kinghost api usage 2018-03-19 12:26:54 -03:00
Felipe Braz
ae32938531 added dnsapi/dns_kinghost.sh 2018-03-19 12:17:47 -03:00
neil
d3da603292 Merge pull request #1418 from itssimple/patch-1
Patch for #1192
2018-03-19 19:47:30 +08:00
Chris Gårdenberg
912bcf9487 Fixed HTTPS-url with regard to #1192 2018-03-19 11:15:25 +01:00
Ivar Larsson
413f071861 use echo 2018-03-18 10:00:10 -04:00
neilpang
668c43abf3 add more debug info 2018-03-18 21:06:37 +08:00
neil
43e9553ebc Merge pull request #1413 from Neilpang/dev
sync
2018-03-18 20:06:19 +08:00
neilpang
e8b54a5087 fix ACCOUNT_URL 2018-03-18 19:32:45 +08:00
neilpang
39852662a6 fix content type 2018-03-18 19:29:02 +08:00
neilpang
6a66ba8a21 fix https://github.com/Neilpang/acme.sh/issues/1411 2018-03-18 18:57:56 +08:00
neilpang
36a7a84080 fix https://github.com/Neilpang/acme.sh/issues/1411 2018-03-18 18:34:35 +08:00
neilpang
7e0b334b38 fix empty ACCOUNT_URL for v2 for the first time use 2018-03-18 18:20:29 +08:00
neilpang
5d8d217a13 add more debug info 2018-03-18 11:36:04 +08:00
neilpang
f2aa5c0235 update doc 2018-03-18 11:18:37 +08:00
neilpang
323febe8c7 add more debug log 2018-03-18 11:14:03 +08:00
neilpang
32d8f349c9 add debug info 2018-03-18 11:04:14 +08:00
neil
3910495cce Merge pull request #1394 from rafaelgieschke/pdns-root
dns_pdns.sh: Allow "." as root zone
2018-03-17 22:02:51 +08:00
neil
fe69afdefb Merge pull request #1401 from casperklein/patch-1
Updated --accountemail help
2018-03-17 22:01:50 +08:00
Casper
9082862b9d Updated --accountemail help
https://github.com/Neilpang/acme.sh/issues/1074#issuecomment-337672763
2018-03-17 14:45:49 +01:00
Rafael Gieschke
4ae108009c dns_pdns.sh: Allow "." as root zone 2018-03-16 14:32:05 +01:00
neilpang
a5c1c30368 update doc 2018-03-16 21:29:38 +08:00
neil
8cd3086be0 Merge pull request #1350 from martgras/dev
Fix missing success return value from dns_azure_add/rm
2018-03-16 20:29:03 +08:00
neil
dd37ae26a5 Merge pull request #1388 from Rid/dev
Fixed grammatical errors in CF api
2018-03-16 19:58:37 +08:00
neil
fdaebc7365 Merge pull request #1392 from cfstras/patch-1
DNS-Manual: better documentation in script
2018-03-16 18:29:24 +08:00
Claus F. Strasburger
a8b62261f6 Documentation: what to do when using dns-manual
Change the hint that tells you how to use DNS manual (second run needs to be --renew)
2018-03-16 11:21:03 +01:00
neil
47eb913c22 Merge pull request #1142 from maomihz/dev
Fix problem that digitalocean api failed to remove record
2018-03-16 17:16:48 +08:00
Ivar Larsson
7a46293f7a loopia documentation 2018-03-15 10:55:31 -04:00
Rid
6b26d2b62d Fixed grammatical errors 2018-03-15 09:50:54 +00:00
Ivar Larsson
cac3b3ea35 add dns_loopia 2018-03-14 12:32:02 -04:00
neil
dff4d03bd4 Merge pull request #1376 from Neilpang/dev
sync
2018-03-14 22:12:11 +08:00
neilpang
28d83d42e2 remove tls mode from doc
https://github.com/Neilpang/acme.sh/issues/1322
2018-03-14 22:09:34 +08:00
neilpang
38f1b4d205 fix wildcard interpretation 2018-03-14 22:03:58 +08:00
neilpang
931d19eece fix for wildcard domain interpretation 2018-03-14 21:56:40 +08:00
neilpang
88bbe55b85 fix wrong wildcard domain interpretation 2018-03-14 21:54:32 +08:00
neilpang
dd17124ec6 fix error 2018-03-14 21:45:16 +08:00
neilpang
674b50889e fix wildcard domains 2018-03-14 21:42:12 +08:00
neilpang
263c38caec add more debug info 2018-03-14 21:27:29 +08:00
neilpang
3881f22192 fix https://github.com/Neilpang/acme.sh/issues/1375
add more info
2018-03-14 21:20:27 +08:00
neilpang
664446631f add debug info 2018-03-14 20:52:18 +08:00
neilpang
c5f1cca3a0 fix https://github.com/Neilpang/acme.sh/issues/1372 2018-03-14 20:30:51 +08:00
neil
a7407097e1 Merge pull request #1374 from Neilpang/master
sync
2018-03-14 20:13:14 +08:00
neil
14bb60c61f Merge pull request #1370 from anabis/patch-1
fix syntax error missing space
2018-03-14 20:11:55 +08:00
neilpang
749c0e51e6 start 2.7.8 2018-03-14 19:42:02 +08:00
anabis
0f120c41f1 fix syntax error missing space 2018-03-14 11:05:57 +01:00
martgras
65a7d56957 remove local keyword 2018-03-14 09:52:58 +01:00
neil
8ab8a6eefb Merge pull request #1362 from Neilpang/dev
sync
2018-03-14 09:41:03 +08:00
martgras
52351d7dc8 avoid side effects in _printargs
A possible fix for https://github.com/Neilpang/acme.sh/issues/1356
2018-03-13 12:43:07 +01:00
martgras
224e0c298a Fix missing success return value from dns_azure_add/rm 2018-03-12 11:50:28 +01:00
neilpang
a5a0e564dd fix https://github.com/Neilpang/acme.sh/issues/1322 2018-03-10 10:33:33 +08:00
neil
b8c94fc7cf Merge pull request #1343 from dkerr64/Support-acme-v2-in-freedns
Adding support for API v2 (multiple TXT records)
2018-03-10 08:59:20 +08:00
David Kerr
62dd3a5380 Fix Travis CI errors. 2018-03-09 16:54:42 -05:00
David Kerr
e3ddb677e1 Adding support for API v2 (multiple TXT records) 2018-03-09 16:39:08 -05:00
neilpang
716f727753 fix https://github.com/Neilpang/acme.sh/issues/1105 2018-03-09 20:14:41 +08:00
neilpang
7e381f8e5d fix format 2018-03-09 08:09:32 +08:00
neilpang
183063a244 add more safe check 2018-03-09 08:06:42 +08:00
neilpang
ef871775b7 fix https://github.com/Neilpang/acme.sh/issues/1336 for wget 2018-03-08 21:27:52 +08:00
neilpang
45e386b26d fix https://github.com/Neilpang/acme.sh/issues/1336 2018-03-08 19:49:53 +08:00
neilpang
e1db5db8ac fix https://github.com/Neilpang/acme.sh/issues/1105 2018-03-07 21:25:07 +08:00
neil
c3a289cebc Merge pull request #1332 from Neilpang/dev
sync
2018-03-07 09:38:54 +08:00
neil
20e51f0b4d Merge pull request #1319 from TigerP/master
Add support for DirectAdmin
2018-03-07 09:34:36 +08:00
neil
464dc93751 Merge pull request #1331 from jim-p/acme-fix-1330
Test ACME v2 before copying certificate to fullchain (again)
2018-03-07 09:33:39 +08:00
jim-p
7445a3be59 Add ACME v2 test around cert copy. Fixes #1330
Without this, the work done a few lines above is clobbered, leaving
the fullchain.cer containing only the certificate, not the CA and
certificate chain.
2018-03-06 17:00:57 -05:00
TigerP
2bbc25c1eb Add DirectAdmin to the main README 2018-03-06 17:00:19 +01:00
neil
fd56fe6eb2 Merge pull request #1318 from raidenii/master
New DNS plugin for name.com for new API.
2018-03-06 20:25:29 +08:00
neil
92dfa8becc Merge pull request #1324 from jwilk-forks/spelling
Fix typos
2018-03-05 09:44:57 +08:00
neil
ae8f9561ad Merge pull request #1248 from skid9000/patch-1
Fix the command to generate tsig key for knot api
2018-03-05 09:36:42 +08:00
raidenii
3052ba433a Fix an obvious stupidity. 2018-03-04 17:27:34 -05:00
raidenii
508012342d Make sure the removal of DNS record is the desired one (i.e., by txtvalue) 2018-03-04 17:22:13 -05:00
raidenii
9fa207e613 Move code to fit DNS API dev guide. 2018-03-04 14:13:14 -05:00
Jakub Wilk
2d7b9817cb Fix typos 2018-03-03 16:27:17 +01:00
TigerP
e8d808d708 Remove empty line at the end 2018-03-03 14:40:23 +01:00
neil
d71595fc75 Merge pull request #1320 from Neilpang/dev
sync
2018-03-02 09:02:36 +08:00
TigerP
399d6592b8 Fix some quotes and a check 2018-03-01 21:25:24 +01:00
raidenii
628a6ffa07 Tried to fix some weird problems 2018-03-01 15:03:28 -05:00
raidenii
3e1a94cbcd Yet another fix. 2018-03-01 14:43:08 -05:00
raidenii
a6c2d4b0e2 Another fix. 2018-03-01 14:38:49 -05:00
raidenii
19277aec87 Use printf instead of echo, hopefully fix SC2039. 2018-03-01 14:29:14 -05:00
TigerP
14c2755436 Add support for DirectAdmin 2018-03-01 20:19:55 +01:00
raidenii
50a9145386 Rewrote to adapt the new name.com v4 API. 2018-03-01 14:19:43 -05:00
raidenii
9046509b95 Merge remote-tracking branch 'upstream/master' 2018-03-01 14:09:36 -05:00
neil
61eaa44cf8 Merge pull request #1316 from Neilpang/alias
Alias
2018-03-01 22:38:05 +08:00
neilpang
2d1e9abb60 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2018-03-01 22:01:11 +08:00
neilpang
d064260bf1 fix https://github.com/Neilpang/acme.sh/issues/1315 2018-03-01 21:59:46 +08:00
neil
a19ad3fd1d Merge pull request #1305 from justmwa/master
DNSMadeEasy ACMEv2 support
2018-02-27 13:43:05 +08:00
nytral
3bc59a0327 first attempt to fix CI errors 2018-02-26 21:47:51 +01:00
nytral
5a883889a2 fixes 2018-02-26 14:53:31 +01:00
neil
fbaa7a4d67 Merge pull request #586 from dkerr64/ssh-deploy
Ssh deploy
2018-02-25 22:56:09 +08:00
nytral
6baa6d488b Merge remote-tracking branch 'upstream/master' 2018-02-24 09:09:00 +01:00
nytral
e26f9b8095 DNSMadeEasy ACMEv2 support 2018-02-24 09:08:44 +01:00
neil
f92fae7625 Merge pull request #1291 from ClouDNS/master
Update dns api to support v2 wildcard cert #1261
2018-02-23 20:05:00 +08:00
neil
3d0e269241 Merge pull request #1287 from martgras/dev
Azure DNS API- support for ACME v2
2018-02-23 20:02:57 +08:00
neil
c17c47f18a Merge pull request #1300 from mal/aws-use-container-role
Pull AWS creds from container role
2018-02-23 19:56:01 +08:00
David Kerr
98b8bfb3fa Merge branch 'dev' of https://github.com/Neilpang/acme.sh into ssh-deploy 2018-02-22 11:46:34 -05:00
martgras
83b1a98db1 Azure DNS API - support for ACME v2 and reliability improvments
support adding 2 txt records
Adding retry logic for REST API calls
Reusing bearer token removes 50% of required REST calls
2018-02-22 12:32:42 +01:00
Mal Graty
f49f55f4a5 Pull AWS creds from container role
Extend the AWS DNS API driver to support ECS container metadata by using
the special environment variable ECS sets in containers.
2018-02-21 11:49:03 +00:00
neil
e58d19b420 Merge pull request #1299 from hebbet/patch-2
small typo
2018-02-21 16:13:15 +08:00
hebbet
58f753136a small typo 2018-02-21 09:01:56 +01:00
neil
22d827adf1 Merge pull request #1292 from mal/aws-use-instance-role
Let AWS DNS API driver pull creds from instance metadata
2018-02-21 10:20:35 +08:00
neil
d3de50e0f9 Merge pull request #1270 from rbelnap/vault-deploy
Vault deploy
2018-02-21 10:17:27 +08:00
neil
432037d20d Merge pull request #1298 from Neilpang/dev
sync
2018-02-21 10:08:17 +08:00
neilpang
86ef0a2609 fix https://github.com/Neilpang/acme.sh/issues/1295 2018-02-21 10:05:27 +08:00
neilpang
bae50da799 fix https://github.com/Neilpang/acme.sh/issues/1266 2018-02-21 09:45:36 +08:00
Bob Belnap
2c45f27356 rename deploy hook vault to vault_cli 2018-02-20 09:11:45 -05:00
Mal Graty
759f4f2c62 Make the instance metadata fetcher self-contained
This is to provide a clean path to future extension work such as adding
a _use_container_role function to offer similar support for ECS
containers.

The $_using_role flag has also been made generic so that future role
providers can also make use of it.
2018-02-20 12:40:24 +00:00
Boyan Peychev
28355335f8 Update dns api to support v2 wildcard cert #1261 2018-02-20 11:22:06 +02:00
Boyan Peychev
9f6832d636 Update dns api to support v2 wildcard cert #1261 2018-02-20 11:16:42 +02:00
Boyan Peychev
5309afc347 Update dns api to support v2 wildcard cert #1261 2018-02-20 11:09:37 +02:00
Mal Graty
693627a858 Emulate Boto when using role metadata
Use the behavior established in the botocore python library to inform
how and when instance metadata is fetched in an attempt to acquire valid
AWS credentials.

- Use it as a fallback when no other credentials are provided
- Set the timeout of metadata requests to 1 second
2018-02-20 00:34:55 +00:00
Mal Graty
48eaa0e5bf Let AWS DNS API code pull creds from instance role
Add option (AWS_USE_INSTANCE_ROLE) to have the AWS DNS API driver pull
the necessary credentials from the AWS EC2 instance metadata endpoint
when required.

This is a non-breaking change as it only takes effect when explicitly
turned on via the environment variable, and fails safe back to the
normal code path.
2018-02-19 19:03:29 +00:00
neilpang
9ad7ac632a fix https://github.com/Neilpang/acme.sh/issues/1284#issuecomment-366616855 2018-02-19 21:07:01 +08:00
Boyan Peychev
41e3ecad46 Update dns api to support v2 wildcard cert #1261 2018-02-19 14:14:08 +02:00
neilpang
d6f8d63742 fix https://github.com/Neilpang/acme.sh/issues/1286 2018-02-19 12:43:56 +08:00
neil
28b0929554 Merge pull request #1283 from justmwa/master
Fixes
2018-02-19 12:34:18 +08:00
nytral
55787ff7b9 other fixes 2018-02-17 15:12:19 +01:00
nytral
b00919c692 various fixes 2018-02-17 15:08:13 +01:00
neil
d43392628b Merge pull request #1273 from jlduran/add-strongswan-freebsd
Add support for strongSwan deploys in FreeBSD
2018-02-17 11:43:42 +08:00
neil
aa831fee5b Merge pull request #1279 from Neilpang/1277
https://github.com/Neilpang/acme.sh/issues/1277
2018-02-17 10:45:44 +08:00
neilpang
5c568d6999 https://github.com/Neilpang/acme.sh/issues/1277 2018-02-17 10:31:34 +08:00
neilpang
d84665cb64 fix https://github.com/Neilpang/acme.sh/issues/1271 2018-02-17 10:16:04 +08:00
neil
4bb5d27c59 Merge pull request #1218 from hcouplet/standalone-listen-address-fix
Standalone listen address fix. #1217
2018-02-17 10:14:12 +08:00
neil
11a9f1d1f0 Merge pull request #1274 from jlduran/add-account-key-permissions
Set the account key file permissions
2018-02-17 10:04:06 +08:00
Jose Luis Duran
123e8f21b5 Set the account key file permissions 2018-02-16 15:42:32 -02:00
neilpang
6d6b2efdb5 fix he for solaris 2018-02-16 23:16:25 +08:00
Boyan Peychev
94b925f5ef Merge branch 'dev' of https://github.com/Neilpang/acme.sh 2018-02-16 16:36:32 +02:00
Bob Belnap
c86755f1ab format fix 2018-02-16 09:19:47 -05:00
Bob Belnap
b8418ced44 syntax fixes 2018-02-16 09:01:26 -05:00
Jose Luis Duran
fac0beaa0a Add support for strongSwan deploys in FreeBSD
Related to 8ea800205c
2018-02-16 11:29:10 -02:00
neilpang
c1f5229906 update doc 2018-02-16 11:21:14 +08:00
neilpang
d5865989cf update doc 2018-02-16 10:48:25 +08:00
Bob Belnap
90e587a974 add vault deploy hook script 2018-02-15 15:34:47 -05:00
neil
4a6b31fbe2 Merge pull request #1268 from Neilpang/dev
fix format
2018-02-15 21:16:41 +08:00
neilpang
a63766a005 fix format 2018-02-15 21:04:53 +08:00
neil
47359c1a3b Merge pull request #1267 from Neilpang/dev
sync
2018-02-15 20:37:15 +08:00
neilpang
abd0dad2bf fix https://github.com/Neilpang/acme.sh/issues/1145#issuecomment-365863118 2018-02-15 20:35:31 +08:00
neilpang
54a52f7048 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2018-02-15 12:39:06 +08:00
neilpang
f213215c81 fix lua 2018-02-15 12:38:45 +08:00
neil
96cde120b4 Merge pull request #1258 from wickerwaka/dreamhost_dns
Added DreamHost DNS API
2018-02-15 12:35:37 +08:00
neilpang
0096ef4ddb fix ali 2018-02-15 12:26:35 +08:00
neilpang
ce6c7d4b59 fix dp 2018-02-15 10:51:13 +08:00
neilpang
b51ed9bbb7 https://github.com/Neilpang/acme.sh/issues/1251 2018-02-15 10:29:03 +08:00
neil
5c6af92a0d Merge pull request #1264 from Neilpang/dev
sync
2018-02-14 22:56:13 +08:00
neilpang
d8eb08e214 fix format 2018-02-14 22:36:17 +08:00
neilpang
c6f5c7f1a3 fix gd 2018-02-14 22:31:02 +08:00
neilpang
a6b6e31cda fix dp 2018-02-14 20:52:06 +08:00
neilpang
28145a9deb fix ovh 2018-02-14 20:40:49 +08:00
neilpang
fa991c8501 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2018-02-14 19:40:16 +08:00
neilpang
5f345d2089 fix https://github.com/Neilpang/acme.sh/issues/1262 2018-02-14 19:39:47 +08:00
Boyan Peychev
520c454f22 Merge branch 'dev' of https://github.com/Neilpang/acme.sh 2018-02-14 13:29:36 +02:00
neil
cc81668c8f Merge pull request #1094 from Daniel15/cloudns-sub
[cloudns] Add support for sub user IDs
2018-02-14 19:23:07 +08:00
neil
6426e044d6 Merge pull request #1263 from jlduran/fix-key-file-permissions
Fix key file permissions
2018-02-14 17:31:40 +08:00
Jose Luis Duran
7b92371a03 Fix key file permissions
Introduced in 8201458332.

Related to #1256.
2018-02-14 06:46:48 -02:00
Martin Donlon
6105d4a4e6 Merge branch 'dev' into dreamhost_dns 2018-02-13 21:04:09 -08:00
Martin Donlon
84649e9d20 Addressing PR feedback
Replace printf with echo
Move dreamhost to bottom of DNS API list
2018-02-13 21:02:38 -08:00
neilpang
1f7df33e28 fix format 2018-02-13 22:26:36 +08:00
neilpang
3c394f08b0 fix format 2018-02-13 22:23:36 +08:00
neilpang
64f07d9bf3 fix aws for acme v2 2018-02-13 22:17:20 +08:00
neilpang
849a6c12be fix for acme v2 2018-02-13 20:08:05 +08:00
neilpang
9144ce746e fix for v2 wildcard 2018-02-13 19:30:54 +08:00
neilpang
64821ad4f5 support "--domain-alias" 2018-02-12 21:49:22 +08:00
neilpang
2655e726c9 update dns he 2018-02-12 20:40:24 +08:00
neil
de2970d7ef Merge pull request #1259 from Neilpang/dev
sync
2018-02-12 20:07:57 +08:00
neilpang
012dd6986b nginx 2018-02-12 20:01:40 +08:00
Martin Donlon
2ef9904d00 Merge branch 'dev' into dreamhost_dns 2018-02-11 07:54:10 -08:00
Martin Donlon
2c83224f07 Fixup dns_dreamhost travis failures 2018-02-11 07:37:15 -08:00
neilpang
0c63090a23 fix format 2018-02-10 23:34:34 +08:00
neilpang
0159277dbf fix format 2018-02-10 23:24:43 +08:00
neilpang
6ca5f3d8f6 support Zonomi.com dns api: https://github.com/Neilpang/acme.sh/issues/1255 2018-02-10 23:23:31 +08:00
neilpang
875625b147 Support domain alias mode 2018-02-10 10:45:29 +08:00
neilpang
da0bd5a9dc begin 2.7.7 2018-02-10 09:03:55 +08:00
neil
ce02ad641b Merge pull request #1257 from Neilpang/dev
minor, fix error message
2018-02-10 08:54:37 +08:00
neilpang
78915896d5 minor, fix error message 2018-02-07 23:49:08 +08:00
neil
4a5d2e16d0 Merge pull request #1249 from Neilpang/dev
sync
2018-02-07 22:31:03 +08:00
neilpang
3e3161c747 fix format 2018-02-07 22:18:04 +08:00
neilpang
694af4aeb1 fix https://github.com/Neilpang/acme.sh/issues/1234 2018-02-07 21:12:49 +08:00
Skid
7f59d7ea48 Fix the command to generate tsig key for knot api 2018-02-07 14:07:14 +01:00
neilpang
52b945164c fix https://github.com/Neilpang/acme.sh/issues/1247 2018-02-07 20:54:05 +08:00
neilpang
584fb2904b fix https://github.com/Neilpang/acme.sh/issues/1191
https://github.com/Neilpang/acme.sh/issues/1246
2018-02-06 21:23:08 +08:00
neil
71013b372d Merge pull request #1245 from jim-p/acme-fix-1243
Add braces around ACCOUNT_URL when forming the protected parameters. Fixes #1243
2018-02-06 09:29:56 +08:00
neil
338b3ba590 Merge pull request #1244 from jim-p/acme-fix-1242
Consider a 200 final response code as an account that already exists. Fixes #1242
2018-02-06 09:28:22 +08:00
jim-p
6b798b01a8 Add braces around ACCOUNT_URL when forming the protected= line. Fixes #1243 2018-02-05 16:38:42 -05:00
jim-p
7df20e5049 When registering, consider a 200 final response code as an account that already exists. Fixes #1242 2018-02-05 16:37:57 -05:00
neil
7128d79935 Merge pull request #1239 from Neilpang/dev
sync
2018-02-05 22:10:37 +08:00
neilpang
e27dfbb0bb update doc 2018-02-05 21:19:48 +08:00
neilpang
a51f109930 fix https://github.com/Neilpang/acme.sh/issues/1234 2018-02-05 20:28:50 +08:00
neil
3e101521dd Merge pull request #1232 from Neilpang/dev
sync
2018-02-02 22:29:56 +08:00
neil
726c7a4d32 Merge pull request #1225 from Neilpang/2
merge v2
2018-02-02 22:20:50 +08:00
neil
767f05cfa7 Merge pull request #1231 from fwolfst/1137-doc_cert_removal
1137 doc cert removal
2018-02-02 09:16:51 +08:00
Felix Wolfsteller
47b49f1be9 Slightly improved --help output, fixes #1137 . 2018-02-01 18:07:29 +01:00
Felix Wolfsteller
a4964b9073 Add Readme-section about cert removal (#1137) 2018-02-01 18:06:26 +01:00
neil
40e2ec3ae9 Merge pull request #1229 from Neilpang/dev
sync
2018-02-01 09:16:08 +08:00
neilpang
120cde169b fix format 2018-01-27 17:20:38 +08:00
neilpang
1c35f46b45 fix https://github.com/Neilpang/acme.sh/issues/1212 2018-01-26 21:37:30 +08:00
neilpang
eea713eed2 Merge branch 'dev' into 2 2018-01-26 21:05:36 +08:00
neilpang
8c88757451 fix format 2018-01-26 20:39:41 +08:00
neilpang
dd171ca44a fix format 2018-01-26 20:14:51 +08:00
neil
cfd086a140 Merge pull request #1224 from martgras/patch-1
dns_azure - spelling  mistake in error message
2018-01-26 14:58:05 +08:00
martgras
72fe7396d6 spelling mistake in error message 2018-01-26 07:53:47 +01:00
neilpang
03140865f0 fix for existing record 2018-01-25 23:25:50 +08:00
neilpang
a4fc802d1b Add selectel.com(selectel.ru) DNS API. fix https://github.com/Neilpang/acme.sh/issues/1220 2018-01-25 23:18:37 +08:00
neil
b6d760b903 Merge pull request #1219 from martgras/master
Add Azure DNS API
2018-01-25 23:11:00 +08:00
neil
e4b24d20ac Update dns_azure.sh 2018-01-25 23:08:56 +08:00
neil
91607bb2a1 Update dns_azure.sh 2018-01-25 22:58:11 +08:00
neil
fce8223663 Merge pull request #1222 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/1193#issuecomment-3600…
2018-01-25 21:17:43 +08:00
neilpang
d1067c60bf fix https://github.com/Neilpang/acme.sh/issues/1193#issuecomment-360025170 2018-01-25 21:08:20 +08:00
martgras
441c26dd32 Update dns_azure.sh 2018-01-25 07:40:35 +01:00
martgras
00781dd4e1 Update README.md 2018-01-25 07:06:42 +01:00
martgras
c7b8debb6e fix travis issues 2018-01-25 07:01:39 +01:00
martgras
d51c383866 remove unused code and fix error handling 2018-01-24 15:08:06 +01:00
martgras
f7d4698ef0 improve error checking 2018-01-24 13:39:38 +01:00
martgras
3fdbbafcb5 fix getroot with multiple dns zones 2018-01-24 09:59:05 +01:00
martgras
c82cd90ed6 Relative link to Azure DNS wiki page 2018-01-23 18:46:59 +01:00
martgras
b6fc8398cf Usage instructions for Azure DNS 2018-01-23 18:25:52 +01:00
martgras
e90f3b84c1 Add support for Azure DNS
Adding support for Azure DNS 
See https://docs.microsoft.com/en-us/azure/dns/
2018-01-23 18:24:08 +01:00
Herve Couplet
9134b6ea98 if local-address is present, bind to that ip instead of 0.0.0.0 2018-01-23 17:53:40 +01:00
neil
4a380ad7fc Merge pull request #1216 from Neilpang/dev
fx format
2018-01-23 19:50:20 +08:00
neilpang
c05eb0b1b2 fx format 2018-01-23 19:42:57 +08:00
neil
66feebfc0e Merge pull request #1211 from Neilpang/dev
Dev
2018-01-21 20:22:36 +08:00
neilpang
04a609b51f fix https://github.com/Neilpang/acme.sh/issues/1209 2018-01-21 20:20:54 +08:00
neilpang
258cf20c92 minor 2018-01-19 22:48:06 +08:00
neil
41c8d88217 Merge pull request #1206 from Neilpang/dev
Dev
2018-01-19 22:42:48 +08:00
neilpang
37f39c0870 minor 2018-01-19 22:41:42 +08:00
neilpang
6ba4f8b54c fix https://github.com/Neilpang/acme.sh/issues/1204 2018-01-18 21:04:06 +08:00
MaomiHz
c1f8ffa386 Use [0-9] instead 2018-01-17 21:39:13 -06:00
neil
97893d293b Merge pull request #1201 from hmb/dev
fix bug in the --ca-bundle param of passing -f to _readlink
2018-01-18 09:28:51 +08:00
Holger Böhnke
78d1cfb464 fix bug in the --ca-bundle param of passing -f to _readlink
When _readlink is called the -f param must not be passed. _readlink (with
leading underscore) is a wrapper around readlink (without leading
underscore). _readlink already passes -f to readlink, that's why it must
not be passed to _readlink.
2018-01-17 19:21:14 +01:00
neilpang
b5fdfe27d5 Merge branch '2' of https://github.com/Neilpang/acme.sh into 2 2018-01-16 21:31:28 +08:00
neilpang
cd9fb3b635 fix https://github.com/Neilpang/acme.sh/issues/1189 2018-01-16 21:29:53 +08:00
neilpang
9e9f839d96 support only one wildcard domain.
fix https://github.com/Neilpang/acme.sh/issues/1188#issuecomment-357684744
2018-01-16 21:29:52 +08:00
neilpang
60814ecfe1 typo 2018-01-16 21:29:52 +08:00
neilpang
0170c20e9a fix format 2018-01-16 21:29:51 +08:00
neilpang
01cc2e13d8 add more sleep for ovh 2018-01-16 21:29:51 +08:00
neilpang
f823f170e6 fix ovh 2018-01-16 21:29:50 +08:00
neilpang
be186bd39b support dns_ovh_rm() 2018-01-16 21:29:50 +08:00
neilpang
ea25492c28 we should not use "updating" to support wildcard 2018-01-16 21:29:49 +08:00
neilpang
79a2bed640 update doc for v2 2018-01-16 21:29:49 +08:00
neilpang
cd8fc35968 fix dns manual mode. 2018-01-16 21:29:48 +08:00
neilpang
d2cde379ad fix ACME v2: deactivate/deactivate-account/revoke 2018-01-16 21:29:48 +08:00
neilpang
506c41cb15 fix format 2018-01-16 21:29:47 +08:00
neilpang
72f54ca6c1 support ACME v2 wildcard cert 2018-01-16 21:29:47 +08:00
neilpang
f8d22c486e fix format 2018-01-16 21:29:46 +08:00
neilpang
c1151b0d45 first version to support ACME v2 2018-01-16 21:29:45 +08:00
neil
0e65fdd6f7 Merge pull request #1196 from Neilpang/dev
sync
2018-01-16 21:28:43 +08:00
neilpang
3164b5ab13 fix https://github.com/Neilpang/acme.sh/issues/1189 2018-01-16 20:55:07 +08:00
neilpang
e6cda79ee8 support only one wildcard domain.
fix https://github.com/Neilpang/acme.sh/issues/1188#issuecomment-357684744
2018-01-15 21:55:40 +08:00
neil
45e21d5000 Merge pull request #1187 from auerswald/dev
Add InternetX autoDNS dns api support
2018-01-15 20:17:19 +08:00
neilpang
7e212c4d40 typo 2018-01-15 19:48:57 +08:00
AA
775aae7082 Update README.md 2018-01-15 11:15:26 +01:00
AA
a01da2fd92 Update README.md 2018-01-15 11:00:44 +01:00
AA
cd2fe698bb Create dns_autodns.sh 2018-01-15 10:59:50 +01:00
neil
4f209e8992 Merge pull request #1182 from meowthink/dev
Add namesilo.com dns api support
2018-01-15 11:16:33 +08:00
Meowthink
eb207322d3 Add namesilo.com dns api support 2018-01-14 18:52:44 +08:00
neilpang
06a2e5fc82 fix format 2018-01-09 23:05:55 +08:00
neilpang
a8ae23d0a2 add more sleep for ovh 2018-01-09 22:47:01 +08:00
neilpang
2befb5e784 fix ovh 2018-01-09 22:04:03 +08:00
neilpang
6d5e7826ae support dns_ovh_rm() 2018-01-09 21:36:48 +08:00
neilpang
c99d4948b7 we should not use "updating" to support wildcard 2018-01-09 20:43:23 +08:00
neilpang
ee6f78805f update doc for v2 2018-01-07 12:12:40 +08:00
neil
9a419bd63f Merge pull request #1167 from Neilpang/dev
sync
2018-01-07 12:07:44 +08:00
neilpang
4a139934f6 fix dns manual mode. 2018-01-06 21:50:57 +08:00
neilpang
2823306810 fix ACME v2: deactivate/deactivate-account/revoke 2018-01-06 21:33:27 +08:00
neilpang
4f3b3a273f fix format 2018-01-06 19:42:29 +08:00
neilpang
6ae3911972 support ACME v2 wildcard cert 2018-01-06 17:39:15 +08:00
neilpang
136aebc009 fix format 2018-01-06 13:57:35 +08:00
neilpang
6541492a55 first version to support ACME v2 2018-01-06 12:45:24 +08:00
neil
59e9750602 Merge pull request #1161 from hiskang/deploy/strongswan
support both debian and redhat
2018-01-05 14:15:08 +08:00
hiska
8ea800205c support both debian and redhat 2018-01-04 19:01:57 +09:00
neil
59bb9268a1 Merge pull request #1159 from sjau/master
dns_ispconfig.sh: Remove unnecessary permission in api user
2018-01-03 13:26:59 +08:00
sjau
a582e7c2fb dns_ispconfig.sh: remove unnecessary permission in api user 2018-01-02 15:05:26 +01:00
sjau
6e2669ed1d Merge pull request #1 from Neilpang/master
Update from original
2018-01-02 15:03:02 +01:00
neil
7b8a82ce90 Merge pull request #1144 from Neilpang/dev
Dev
2017-12-12 20:18:20 +08:00
neil
a8bad622ff Merge pull request #1140 from jhartlep/dev
added dns api support for servercow
2017-12-12 20:08:42 +08:00
MaomiHz
9c4f7aa688 check for env var exist in DigitalOcean API 2017-12-11 16:33:44 -06:00
MaomiHz
e75b56073b Fix digitalocean api not remove record 2017-12-11 16:33:42 -06:00
Jens
a95ccc7e4c Update dns_servercow.sh
... didn't see this line in spellcheck ... :S
2017-12-09 20:22:09 +01:00
Jens
8101aceab5 Update dns_servercow.sh
fixed remaining issues from shellcheck
2017-12-09 20:18:05 +01:00
Jens
1c9b19833c Update dns_servercow.sh
replaced tab with space
2017-12-09 20:14:46 +01:00
Jens
488745f378 Update README.md 2017-12-09 20:05:05 +01:00
Jens Hartlep
b140e2553b added Servercow to supported list 2017-12-09 19:33:48 +01:00
Jens Hartlep
ae29929714 added dns api for servercow 2017-12-09 19:32:53 +01:00
neilpang
9f80909f6a Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2017-12-09 21:51:10 +08:00
neilpang
8201458332 fix https://github.com/Neilpang/acme.sh/issues/1123 2017-12-09 21:50:45 +08:00
neil
7a88d80a10 Merge pull request #1138 from Neilpang/dev
Dev
2017-12-09 21:28:12 +08:00
neil
3ced411769 Merge pull request #1134 from speedmann/master
Add support for inwx.de API
2017-12-09 21:23:25 +08:00
speedmann
f7c346de09 Fix order in README and add link to inwx.de and apidocs 2017-12-09 14:20:36 +01:00
speedmann
731ed6952f Fix shebang 2017-12-09 14:13:05 +01:00
speedmann
454ad6f8bd Merge branch 'dev' into master 2017-12-09 14:10:01 +01:00
neil
8a3b6bf0e6 Merge pull request #1132 from Aarup/master
Added support for UnoEuro API
2017-12-08 21:11:25 +08:00
Aarup
fb6e0658cf update README 2017-12-08 14:09:04 +01:00
Aarup
f9b8d7a9d8 renamed uno_user and uno_key 2017-12-08 13:22:17 +01:00
Aarup
f763e1edd7 fix contains usage 2017-12-08 13:20:25 +01:00
Aarup
dbc3ad1304 use _math 2017-12-08 12:59:02 +01:00
neilpang
4249e13eb4 fix format 2017-12-08 19:54:25 +08:00
neilpang
ca7ebd9333 fix typo 2017-12-08 19:49:18 +08:00
Aarup
3f1e6c128f Try again 2017-12-08 08:31:24 +01:00
Aarup
1f635b90e7 Try to fix build 2017-12-08 08:26:52 +01:00
JAA
db3043553c Also don't use sed 2017-12-07 14:52:09 +01:00
neilpang
f87890cb4b v2.7.6 fix ECC 384 signature
https://github.com/Neilpang/acme.sh/issues/1130
https://github.com/Neilpang/acme.sh/issues/990
2017-12-07 21:32:17 +08:00
speedmann
5911594906 Fix egrep invocation 2017-12-07 14:21:37 +01:00
speedmann
9a1f769828 Avoid usage of sed -E grep -q and printf -v 2017-12-07 14:18:54 +01:00
JAA
b91c0a0616 Don't use grep -B 2017-12-07 13:53:40 +01:00
JAA
4a9f607d31 Cleanup 2017-12-07 13:53:27 +01:00
speedmann
a00169451f Change bash to sh to fit project requirements 2017-12-07 13:10:59 +01:00
speedmann
ecba959dd9 Fix missed whitespaces 2017-12-07 13:07:05 +01:00
speedmann
a8202d4b37 Fix CI issues 2017-12-07 12:05:03 +01:00
speedmann
657334fb67 Add support for inwx.de API 2017-12-07 11:47:01 +01:00
Aarup
78712245f7 Add UnoEuro to README 2017-12-06 12:13:40 +01:00
Aarup
70702e41e9 Use _head_n 2017-12-06 11:55:29 +01:00
Aarup
0ca3141088 Added support for UnoEuro api 2017-12-06 11:50:54 +01:00
neil
ac0970abba Merge pull request #1131 from Neilpang/dev
Dev
2017-12-03 21:36:06 +08:00
neilpang
9eeebb147f fix osx build 2017-12-03 20:57:25 +08:00
neilpang
dcf8457f4d fix format 2017-12-03 13:16:37 +08:00
neilpang
534a5ad688 Merge branch 'fixci' into dev 2017-12-03 13:11:53 +08:00
neilpang
529cbc0379 run ci in docker 2017-12-03 12:51:51 +08:00
neil
b6aff65997 Merge pull request #1128 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/1127
2017-12-02 19:56:39 +08:00
neilpang
b615cce92d fix https://github.com/Neilpang/acme.sh/issues/1127 2017-12-02 19:54:33 +08:00
neil
aea631d9d2 Merge pull request #1126 from Neilpang/dev
Dev
2017-12-02 11:16:18 +08:00
neil
bf942a4cb3 Merge pull request #1125 from Neilpang/freedns
fix https://github.com/Neilpang/acme.sh/issues/1109
2017-12-02 11:15:31 +08:00
neilpang
ceafe389af fix https://github.com/Neilpang/acme.sh/issues/1109 2017-11-26 20:57:02 +08:00
neilpang
f62457a24e fix 2017-11-13 20:54:29 +08:00
Daniel Lo Nigro
bab4f691c5 Fix lint warning 2017-11-12 18:38:30 -08:00
David Kerr
c7becddb78 Merge branch 'master' of https://github.com/Neilpang/acme.sh into ssh-deploy 2017-11-11 12:52:53 -05:00
neil
cc3660e259 Merge pull request #1107 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/1106
2017-11-10 23:06:05 +08:00
neilpang
6e93ff8bca fix https://github.com/Neilpang/acme.sh/issues/1106 2017-11-10 23:01:29 +08:00
Daniel Lo Nigro
212d0f24d8 [cloudns] Add support for sub user IDs 2017-10-31 22:36:17 -07:00
neil
114003406d Merge pull request #1093 from Neilpang/dev
add dev guide
2017-11-01 10:15:36 +08:00
neilpang
4c99c0127b add dev guide 2017-11-01 10:14:44 +08:00
David Kerr
c809b33161 Merge branch 'master' of https://github.com/Neilpang/acme.sh into ssh-deploy 2017-10-29 21:03:05 -04:00
neil
3f1c7da15e Merge pull request #1079 from Neilpang/dev
Dev
2017-10-20 22:30:26 +08:00
neil
a46695581e Merge pull request #1077 from max2711/master
small Docker output enhancement
2017-10-20 22:13:51 +08:00
max2711
7902d10a3a remove unused crontab jobs 2017-10-20 14:22:20 +02:00
neil
8aff2bd74c Merge pull request #1075 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/1074
2017-10-18 20:30:40 +08:00
neilpang
352dd907ac fix https://github.com/Neilpang/acme.sh/issues/1074 2017-10-18 20:27:09 +08:00
neil
43f195160e Merge pull request #1072 from Neilpang/dev
Dev
2017-10-12 21:54:13 +08:00
neilpang
872bfe4757 fix for PR https://github.com/Neilpang/acme.sh/pull/1069 2017-10-11 20:34:56 +08:00
neil
70bd493a25 Merge pull request #1061 from sahsanu/patch-1
Update ClouDNS.net API doc
2017-10-10 22:02:36 +08:00
neil
bd065838fa Merge pull request #1063 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/1062
2017-10-08 19:48:19 +08:00
neilpang
5f6e3da766 fix https://github.com/Neilpang/acme.sh/issues/1062
change back to use openssl for tls mode.
2017-10-08 19:45:50 +08:00
sahsanu
ee56b9cd4e Update ClouDNS.net API doc
Update ClouDNS.net API doc to show that CLOUDNS_AUTH_ID and CLOUDNS_AUTH_PASSWORD will be saved in ~/.acme.sh/account.conf
2017-10-07 21:31:24 +02:00
neil
1a27172f20 Merge pull request #1059 from Neilpang/dev
Dev
2017-10-06 09:56:29 +08:00
neil
4ef1159666 Merge pull request #1055 from hiskang/deploy/strongswan
Deploy/strongswan
2017-10-04 08:59:05 +08:00
hiska
c924e7c537 remove "return 0" 2017-10-04 06:44:02 +09:00
neil
814bd7cb0d Merge pull request #1056 from hebbet/patch-1
unify headlines
2017-10-03 22:11:05 +08:00
neil
5f2d8c0155 Merge pull request #1052 from sahsanu/patch-1
Update dns_cloudns.sh to be able to save ID and PASSWORD
2017-10-03 22:09:48 +08:00
hebbet
372f691fd6 unify headlines
unify headlines in deploy readme
2017-10-02 15:04:02 +02:00
hiska
5f05a452fc Merge branch 'dev' into deploy/strongswan 2017-10-02 08:39:55 +09:00
hiska
afe3283c53 Update README.md 2017-10-02 08:34:32 +09:00
hiska
641a2895a6 Create strongswan.sh 2017-10-02 08:32:36 +09:00
sahsanu
c73c33f94c Update dns_cloudns.sh 2017-10-01 10:31:38 +02:00
sahsanu
6c7da215e7 Update dns_cloudns.sh 2017-10-01 10:06:38 +02:00
sahsanu
754a4a7c8b Update dns_cloudns.sh
Added code to save CLOUDNS_AUTH_ID and CLOUDNS_AUTH_PASSWORD on account.conf file so the id and password for cloudns can be reused.
2017-09-30 20:12:53 +02:00
neil
0427e8bbb4 Merge pull request #993 from fritteli/deploy-fritzbox
Deploy fritzbox
2017-09-29 21:00:07 +08:00
neil
c47f6ed30a Merge pull request #1048 from Neilpang/dev
Dev
2017-09-27 09:07:26 +08:00
neil
3bdc317fc8 Merge pull request #1046 from techdad/patch-1
Remove stray single-quote
2017-09-27 09:04:40 +08:00
neil
20cce349e4 Merge pull request #1044 from 2globalnomads/patch-5
#1042
2017-09-27 08:56:41 +08:00
Daniel
5261162fdf Remove stray single-quote
Get rid of a single stray erroneous single-quote that is breaking socat when using standalone mode.
2017-09-26 19:43:06 +04:00
Santeri Kannisto
acf117584b #1042
Apparently UAPI does not return any error code, just JSON output that has a string "status: 0" whenever the command fails.
2017-09-26 07:04:30 +04:00
neil
7b4bbed553 Merge pull request #1038 from Neilpang/dev
add debug info
2017-09-23 22:13:14 +08:00
neilpang
270ce87582 add debug info 2017-09-23 22:12:17 +08:00
Manuel Friedli
2fc0225bc9 Make command line example consistent with env variable example. 2017-09-12 11:35:21 +02:00
Manuel Friedli
3536cd336d Merge branch 'dev' into deploy-fritzbox 2017-09-12 11:32:54 +02:00
neil
86dd290c1d Merge pull request #1020 from Neilpang/dev
minor
2017-09-11 21:43:57 +08:00
neilpang
95949b6519 minor 2017-09-11 21:40:56 +08:00
neil
6499a7298d Merge pull request #1019 from Neilpang/dev
Dev
2017-09-11 21:30:02 +08:00
neilpang
042e09d29f Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2017-09-11 21:28:57 +08:00
neilpang
36309e6dbc minor, fix debug info 2017-09-11 21:28:37 +08:00
neil
e1ac201de1 Merge pull request #1014 from 2globalnomads/patch-4
1 cert per 1 domain for cpanel_uapi
2017-09-11 20:44:28 +08:00
neil
f0c4e44d2f Merge pull request #1015 from baloo/patch-1
Use stable gandi API url
2017-09-11 20:43:23 +08:00
neil
1dc3036822 Merge pull request #1017 from Neilpang/dev
Dev
2017-09-10 16:47:42 +08:00
neilpang
a6b399286e add socat 2017-09-09 14:15:11 +08:00
Arthur Gautier
856811bd2e Use stable gandi API url
The gandi api has changed its url for a more stable
one. Although https://dns.beta.gandi.net will continue to 
work for the foreseable future, this commits updates the
url to new official one.
2017-09-06 17:04:40 +00:00
neilpang
53273a15bf use socat for tls mode 2017-09-06 21:18:02 +08:00
neilpang
3eeb090578 fix tls mode back to use openssl 2017-09-06 20:50:31 +08:00
Santeri Kannisto
a9726fde19 1 cert per domain
for cpanel_uapi
2017-09-05 17:42:17 +04:00
Santeri Kannisto
f81d4033fa One cert per domain
Deploy works only for the first domain
2017-09-05 17:37:48 +04:00
neil
5e864ea3b5 Merge pull request #1013 from Neilpang/dev
Dev
2017-09-05 20:49:07 +08:00
neilpang
8148bfeacf fix https://github.com/Neilpang/acme.sh/issues/998 2017-09-05 20:32:14 +08:00
Manuel Friedli
1e30718df6 Try and work around shellcheck error SC2039: In POSIX sh, printf -%s-- is undefined. 2017-09-04 14:48:27 +02:00
Manuel Friedli
72e1eb88d9 Don't use individual redirects, but do it all in one block. 2017-09-04 14:40:28 +02:00
Manuel Friedli
8ee5ede834 Fix more formatting errors 2017-09-04 14:30:40 +02:00
Manuel Friedli
bd8b1a2501 Don't use wget directly, but instead use _get and _post. 2017-09-04 14:27:22 +02:00
Manuel Friedli
a098167bdb Fix more formatting errors 2017-09-04 14:07:10 +02:00
neil
7790208126 Merge pull request #1010 from 2globalnomads/patch-3
cpanel_uapi doc
2017-09-03 17:38:51 +08:00
Santeri
e52304edb4 cpanel_uapi
tried to make it a bit less confusing
2017-09-03 13:35:20 +04:00
neil
afdd02a80d Merge pull request #1006 from Neilpang/dev
Dev
2017-09-03 08:47:27 +08:00
neilpang
c73fdd4022 minor 2017-09-03 08:45:58 +08:00
neilpang
4356eefbb1 fix https://github.com/Neilpang/acme.sh/issues/1005#event-1232471561 2017-09-03 08:42:44 +08:00
neilpang
6104680caa fix https://github.com/Neilpang/acme.sh/issues/999 2017-09-02 20:46:04 +08:00
neil
4373fdf48c Merge pull request #1003 from Neilpang/dev
fix for behind proxy
2017-09-02 19:10:08 +08:00
neilpang
f9cdfd3e5b fix for behind proxy 2017-09-02 18:58:07 +08:00
neil
b6c2fc5a69 Merge pull request #1001 from Neilpang/socat
Socat
2017-09-02 17:56:15 +08:00
neilpang
cc6610edc2 add socat 2017-09-02 17:32:40 +08:00
neilpang
7b8ddfdd96 use socat 2017-09-02 08:59:30 +08:00
neilpang
443a5ca0c2 socat tls mode 2017-09-01 23:44:52 +08:00
neilpang
3794b5cb58 fix changes for :https://community.letsencrypt.org/t/acme-sh-standalone-fails-multiple-validation-requests-staging-multi-va/41249/8
use socat instead of nc.
2017-09-01 23:01:37 +08:00
Manuel Friedli
6cb5377d73 Fix bugs and more/new formatting errors. 2017-08-31 17:25:08 +02:00
Manuel Friedli
a3a92ff1df Fix formatting errors. 2017-08-31 17:12:11 +02:00
neil
2068efdb38 Merge pull request #995 from Neilpang/dev
Dev
2017-08-30 22:22:50 +08:00
neil
258ca1b434 Merge pull request #991 from fritteli/fritteli-typos
Fritteli typos
2017-08-30 21:57:30 +08:00
Manuel Friedli
103fa959cb Typo 2017-08-30 00:47:31 +02:00
Manuel Friedli
b6d48b7a14 Update README.md for the deploy hooks. 2017-08-30 00:45:03 +02:00
Manuel Friedli
412e4e6cf9 Add acknowledgement note 2017-08-30 00:24:31 +02:00
Manuel Friedli
e6f81173a3 Delete auto-backup file 2017-08-29 23:58:20 +02:00
Manuel Friedli
d50281453d Add --no-check-certificate option to wget, or else the initial deployment won't work because there isn't a valid certificate installed on the router yet. 2017-08-29 23:57:24 +02:00
Manuel Friedli
4bb488258d - Bugfixes
- Make sure the login actually worked
- Less output
2017-08-29 23:53:41 +02:00
Manuel Friedli
f6da19ba83 add deploy script for the AVM FRITZ!Box 2017-08-29 23:14:21 +02:00
fritteli
88bb7b780d Typos 2017-08-29 22:35:11 +02:00
neil
3805e5d37e Merge pull request #988 from Neilpang/dev
Dev
2017-08-25 20:56:23 +08:00
neilpang
a2d6daaef4 fix cpanel_uapi.sh 2017-08-25 20:54:10 +08:00
neilpang
48e9006cd1 fix cpanel uapi 2017-08-25 20:51:31 +08:00
neil
a25a4b5d11 Merge pull request #986 from Neilpang/dev
Dev
2017-08-22 20:28:35 +08:00
neilpang
309bec474f add warning for dns manual mode 2017-08-22 20:27:13 +08:00
neil
d36440a06d Merge pull request #940 from 2globalnomads/patch-1
cpanel_uapi.sh
2017-08-22 09:17:07 +08:00
neil
2a2f772412 Merge pull request #975 from Neilpang/dev
Dev
2017-08-17 22:06:10 +08:00
neil
6a524bff9d Merge pull request #973 from mvanini/master
Support for busybox in time2str()
2017-08-17 22:04:49 +08:00
neil
5def1169db Merge pull request #974 from Neilpang/dev
Dev
2017-08-17 21:52:33 +08:00
Michele
a07395fb56 Added support for busybox in time2str()
awk fallback if none of preceding method works
2017-08-17 12:50:28 +02:00
neil
e25a375f43 Merge pull request #969 from abelbeck/dns_duckdns
Update DuckDNS support, fix failure on first call, no longer save the…
2017-08-14 21:36:43 +08:00
Lonnie Abelbeck
96801e3478 Update DuckDNS support, fix failure on first call, no longer save the domain/username as a global, and other tweaks 2017-08-11 16:46:29 -05:00
neil
90100aa169 Merge pull request #967 from Neilpang/dev
support fcrontab, fix https://github.com/Neilpang/acme.sh/issues/966
2017-08-10 21:38:12 +08:00
neilpang
415f375ce6 support fcrontab, fix https://github.com/Neilpang/acme.sh/issues/966 2017-08-10 21:31:28 +08:00
David Kerr
94e9844179 Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-08-06 11:13:06 -04:00
neil
50d238b60f Merge pull request #963 from Neilpang/dev
format
2017-08-04 21:58:55 +08:00
neilpang
5c3b41bd93 format 2017-08-04 21:57:45 +08:00
neil
3e0971c159 Merge pull request #961 from Neilpang/dev
Dev
2017-08-03 23:40:05 +08:00
neil
57740fbd18 Merge pull request #960 from jfro/dev
Fix Linode DNS API to work on BSD
2017-08-03 22:38:17 +08:00
neil
16bc8f7040 Merge pull request #949 from candlerb/candlerb/unifi
Candlerb/unifi
2017-08-03 21:52:28 +08:00
Jeremy Knope
c145f24621 Remove extra space 2017-08-03 09:47:45 -04:00
Jeremy Knope
cd3a4573f2 Fix shell check errors 2017-07-31 08:37:30 -04:00
Brian Candler
8eab77f3c6 Add deployment script for unifi controller 2017-07-30 12:21:20 +01:00
neil
4af339424a Merge pull request #953 from angel333/master
Add DNS API script for Hurricane Electric DNS service
2017-07-30 10:45:40 +08:00
Ondrej Simek
4dd69a8b1a Exit codes, exit codes... Exit codes everywhere... 2017-07-29 14:40:56 +02:00
Ondrej Simek
baa1160594 Make Shellcheck happier about exit codes 2017-07-29 14:31:27 +02:00
Ondrej Simek
f438ff4bab Fix an improbable corner case. 2017-07-29 14:29:13 +02:00
Ondrej Simek
a25b2af66c Get rid of _find_num 2017-07-29 14:25:07 +02:00
Ondrej Simek
31b67ab92e Few non-critical fixes. 2017-07-29 13:52:28 +02:00
neil
5303b36913 Merge pull request #958 from Neilpang/dev
Dev
2017-07-29 15:25:16 +08:00
neilpang
a5c56c547d minor, fix dns param 2017-07-29 15:23:50 +08:00
Ondrej Simek
ccf9a9976c Fix the previous rushed commit. 2017-07-28 18:33:25 +02:00
Jeremy Knope
ab1efd923b back to sed 2017-07-28 10:26:56 -04:00
Ondrej Simek
d6780f9e49 Retain an exit code 2017-07-28 15:29:35 +02:00
Ondrej Simek
8534e3b2f7 Make shellcheck happier 2017-07-28 13:58:47 +02:00
Jeremy Knope
8e6cf669ad Try awk instead for \n replacements 2017-07-27 14:15:19 -04:00
Ondrej Simek
577380e98e Few fixes for shellcheck 2017-07-27 18:44:55 +02:00
Ondrej Simek
235b5b0c15 Small cosmetic fixes. 2017-07-27 18:06:19 +02:00
Ondrej Simek
aefed1d1b9 Get rid of shell arrays. 2017-07-27 18:04:53 +02:00
Jeremy Knope
d39649f30d Revert non-linode scripts since they're untested 2017-07-27 08:52:46 -04:00
Ondrej Simek
1546b7e5a9 Missing quotes 2017-07-26 20:21:36 +02:00
Ondrej Simek
ff74778dea Fix few issues from Travis 2017-07-26 20:15:34 +02:00
Jeremy Knope
29b21b828b Fix DNS API scripts on *BSD
\n isn't available in all regex/sed
2017-07-26 09:44:11 -04:00
neil
a6a0495392 Merge pull request #952 from candlerb/candlerb/isecc
Clarify keylength parameter to _isEccKey() and _initpath()
2017-07-25 19:05:51 +08:00
Brian Candler
3281043e27 Clarify keylength parameter to _isEccKey() and _initpath()
Closes #950
2017-07-25 09:39:19 +01:00
Ondrej Simek
f7299403f7 Incorporate Neilpang's comments 2017-07-23 07:31:55 +02:00
Ondrej Simek
a0d251a336 Merge remote-tracking branch 'upstream/dev' 2017-07-23 05:15:27 +02:00
Ondrej Simek
8ca45d3d03 Add HE to README 2017-07-23 05:13:33 +02:00
Ondrej Simek
d988542afc Sync with upstream 2017-07-23 05:09:48 +02:00
Ondrej Simek
4285d81ca9 Get rid of curl. 2017-07-23 05:00:02 +02:00
Santeri
4286b2917e renamed function 2017-07-19 12:22:00 +04:00
Santeri
d09b5cb80e Rename cpanel_uapi.sh to cpanel_deploy.sh 2017-07-19 07:39:21 +04:00
Santeri
90fd18bf42 Renamed script to cpanel_uapi.sh
As per Neil's request.
2017-07-18 15:48:17 +04:00
neil
cae6c8e5f5 Merge pull request #943 from Neilpang/dev
Dev
2017-07-14 20:38:11 +08:00
neil
473340c53b Merge pull request #936 from non7top/yandex
Add pdd.yandex.ru dns api support
2017-07-14 20:28:29 +08:00
Vladimir Berezhnoy
ae302ee600 reformat docs 2017-07-14 03:51:08 +03:00
Vladimir Berezhnoy
27934ac4ca Merge branch 'yandex' of github.com:non7top/acme.sh into yandex 2017-07-14 03:27:11 +03:00
Vladimir Berezhnoy
283ef9adb7 minor fixes 2017-07-14 03:26:36 +03:00
Vladimir Berezhnoy
377fe5ecde add documentation 2017-07-14 03:26:36 +03:00
Vladimir Berezhnoy
c848d3ee22 fix formatting 2017-07-14 03:26:36 +03:00
Vladimir Berezhnoy
eb6be88fac rework root domain detection 2017-07-14 03:26:36 +03:00
Vladimir Berezhnoy
fceb728501 fix egrep and exit 2017-07-14 03:26:36 +03:00
Vladimir Berezhnoy
a0df46258d remove python 2017-07-14 03:26:36 +03:00
Vladimir Berezhnoy
57d1db58db shfmt fixes 2017-07-14 03:26:36 +03:00
Vladimir Berezhnoy
d61b687853 remove awk 2017-07-14 03:26:36 +03:00
Vladimir Berezhnoy
42ab7a5d72 add newline and checks 2017-07-14 03:26:36 +03:00
Vladimir Berezhnoy
18cb11dcbf fix formatting 2017-07-14 03:26:36 +03:00
Vladimir Berezhnoy
e9d5407792 fix syntax 2017-07-14 03:26:36 +03:00
Vladimir Berezhnoy
a09b2c0074 fix syntax 2017-07-14 03:26:36 +03:00
Vladimir Berezhnoy
a460ac021f add pdd.yandex.ru dns api 2017-07-14 03:26:36 +03:00
Vladimir Berezhnoy
bdee66fe29 minor fixes 2017-07-13 18:37:13 +03:00
Vladimir Berezhnoy
84a251c8c7 add documentation 2017-07-13 17:05:57 +03:00
neil
cea763bb11 Merge pull request #942 from Neilpang/dev
output log
2017-07-13 20:56:53 +08:00
neilpang
accbda9d2f output log 2017-07-13 20:52:44 +08:00
Ondrej Simek
7d64e141e4 Add dns_he - DNS API script for Hurricane Electric DNS service
... Although not yet fully Posix compatible.
2017-07-12 20:24:54 +02:00
Vladimir Berezhnoy
6a9b4db448 fix formatting 2017-07-12 04:07:18 +03:00
Vladimir Berezhnoy
e6a95ecd08 rework root domain detection 2017-07-12 03:51:48 +03:00
Vladimir Berezhnoy
10cb7585a7 fix egrep and exit 2017-07-11 02:19:39 +03:00
Santeri
a577c7215f One more change to pass the check shellcheck test
Now it is tested and works also when run as a root.
2017-07-10 16:43:42 +04:00
neil
e5244cf3c0 Merge pull request #941 from Neilpang/dev
do not retry for a invalid cert in cronjob.
2017-07-10 19:58:22 +08:00
neilpang
c4d0aec536 do not retry for a invalid cert in cronjob.
fix https://github.com/Neilpang/acme.sh/issues/939
2017-07-10 19:51:55 +08:00
Santeri
796647158e Removed double quotes from _opt
Broke GoDaddy cpanel causing error (thanks Hedgehog)
2017-07-10 15:36:16 +04:00
Vladimir Berezhnoy
266e9d0619 remove python 2017-07-09 20:00:02 +03:00
Vladimir Berezhnoy
9ec54ef89b shfmt fixes 2017-07-09 13:21:55 +03:00
Vladimir Berezhnoy
256cb90f3c remove awk 2017-07-09 13:15:01 +03:00
Vladimir Berezhnoy
8f3a3b293d add newline and checks 2017-07-09 13:00:42 +03:00
neil
975a7359a2 Merge pull request #937 from Neilpang/dev
Dev
2017-07-09 09:48:37 +08:00
neil
ac7361a55e Merge pull request #935 from abelbeck/dns_dyn
Add 'dns_dyn' DNS challenge validation script for Dyn Managed DNS API, Issue #594
2017-07-09 09:20:34 +08:00
Vladimir Berezhnoy
bd41f50ba5 fix formatting 2017-07-08 22:02:34 +03:00
Vladimir Berezhnoy
a2038ab07e fix syntax 2017-07-08 21:57:27 +03:00
Vladimir Berezhnoy
6445a7674b fix syntax 2017-07-08 21:52:47 +03:00
Vladimir Berezhnoy
3bf2e89a1a add pdd.yandex.ru dns api 2017-07-08 21:35:22 +03:00
Lonnie Abelbeck
e6a13bf386 Merge branch 'dns_dyn' of github.com:abelbeck/acme.sh into dns_dyn 2017-07-08 07:10:09 -05:00
Lonnie Abelbeck
42b2adc03e Add 'dns_dyn' DNS challenge validation script for Dyn Managed DNS API
dns_dyn.sh, remove empty line at end

dns_dyn.sh, remove trailing spaces at end of line

Replace 'head -n' with the '_head_n' function

Update main README.md DNS API list
2017-07-08 07:06:51 -05:00
Lonnie Abelbeck
f2b9af01e8 Merge remote-tracking branch 'upstream/dev' into dns_dyn 2017-07-08 06:48:25 -05:00
Lonnie Abelbeck
9bd2d92755 Update main README.md DNS API list 2017-07-08 06:43:21 -05:00
Lonnie Abelbeck
babe884b7c Replace 'head -n' with the '_head_n' function 2017-07-08 06:39:18 -05:00
neilpang
200287254b add deactivate-account 2017-07-08 17:25:01 +08:00
neilpang
0b797f5964 fix new shellcheck error 2017-07-08 14:12:31 +08:00
neilpang
13a8c309f5 fix new shellcheck errors 2017-07-08 09:20:12 +08:00
Lonnie Abelbeck
528d2f29d3 dns_dyn.sh, remove trailing spaces at end of line 2017-07-07 10:33:24 -05:00
Lonnie Abelbeck
0aba5dc8de dns_dyn.sh, remove empty line at end 2017-07-07 10:22:20 -05:00
Lonnie Abelbeck
72fcf5ab85 Add 'dns_dyn' DNS challenge validation script for Dyn Managed DNS API 2017-07-07 09:51:43 -05:00
neil
dd9df068b0 Merge pull request #928 from Neilpang/dev
minor, fix format
2017-07-04 09:10:00 +08:00
neil
81772fb703 minor, fix format 2017-07-04 09:08:54 +08:00
neil
6304566603 Merge pull request #927 from Neilpang/dev
Dev
2017-07-04 08:29:38 +08:00
neilpang
5f8b60a0e5 fix https://github.com/Neilpang/acme.sh/issues/926
don't trigger validation for dns manually mode
2017-07-04 08:24:30 +08:00
raidenii
4964e075df Merge remote-tracking branch 'upstream/master' 2017-07-03 11:40:32 -04:00
neil
e2accaf70e Merge pull request #925 from raidenii/master
Fix for Name.com API
2017-07-03 20:55:36 +08:00
RaidenII
7b32bbfc26 Fix for SC2086. 2017-07-03 08:22:16 -04:00
RaidenII
6963f3880d Fixes the get_root function so that when domain doesn't exist it will correctly return error. 2017-07-03 03:28:28 -07:00
2globalnomads
6c3430b6e5 Wrote missing cpanel.sh
This script I wrote works for me on GoDaddy, but I don't have any other hosting services or cpanel version to test it. Hope it's better than nothing for you. Thanks for your great script!
Cheers,
Santeri
2017-07-02 23:24:14 +04:00
neil
c53f36a777 Merge pull request #920 from Neilpang/dev
Dev
2017-07-02 21:52:30 +08:00
neil
bb4d378733 Merge pull request #921 from raidenii/master
Fix README.md for DNS API.
2017-07-02 21:49:17 +08:00
RaidenII
333090a967 Fix README.md for DNS API. 2017-07-02 06:38:25 -07:00
neil
c8f5646d53 Merge pull request #919 from raidenii/master
Updated README.md for Name.com API application.
2017-07-02 21:34:19 +08:00
RaidenII
3002f6dfd5 Updated README.md for Name.com API application. 2017-07-02 06:02:44 -07:00
neil
3f8a50e2ae Merge pull request #909 from raidenii/master
DuckDNS.org and Name.com DNS API support
2017-07-02 20:13:12 +08:00
RaidenII
1a504118e5 Updated DNS API support list. 2017-07-02 04:55:06 -07:00
RaidenII
2e602ef6b0 Added ret value verification. 2017-07-02 04:45:07 -07:00
neil
d55c3faaeb Merge pull request #918 from Neilpang/dev
Dev
2017-07-02 19:20:59 +08:00
neilpang
6b185d20c0 fix format 2017-07-02 18:40:11 +08:00
neilpang
1bbc33a0cf minor fix CA_DIR 2017-07-02 18:24:55 +08:00
neilpang
a71eba07a1 minor, fix resource name 2017-07-02 18:05:55 +08:00
neilpang
422dd1fa4f Implement deactivate account: --deactivate-account 2017-07-02 17:02:54 +08:00
neilpang
c4b2e5829e add always-force-new-domain-key. fix https://github.com/Neilpang/acme.sh/issues/914 2017-07-02 15:25:35 +08:00
neilpang
1be222f6ed minor 2017-07-02 13:38:44 +08:00
neil
5463f459e6 Merge pull request #917 from Neilpang/dev
Dev
2017-07-01 22:44:29 +08:00
neilpang
14d7bfdab2 fix deactivate for lower rate limit 2017-07-01 21:47:30 +08:00
neilpang
ea722da3de add debug info 2017-07-01 20:31:42 +08:00
RaidenII
9aed1e2d17 Argh. Double quotes. 2017-07-01 05:18:12 -07:00
RaidenII
63c6ed3fd0 Fixes to follow coding standards. 2017-07-01 05:14:52 -07:00
neil
744bfc1982 Merge pull request #915 from Neilpang/dev
fix alias
2017-07-01 12:31:42 +08:00
neilpang
d04434e3ec fix alias 2017-07-01 10:54:14 +08:00
RaidenII
dc3b7b5775 Merge remote-tracking branch 'upstream/master' 2017-06-30 09:39:13 -04:00
RaidenII
17fbfd14db Minor fixes. 2017-06-30 08:32:39 -04:00
RaidenII
d0f5aece5f Fix SC2170. 2017-06-29 15:43:58 -04:00
RaidenII
eeda3062e1 Fix against POSIX standard. 2017-06-29 15:40:29 -04:00
RaidenII
168d712dec Fixed URL of Name.com API and removed useless debug for retcode. 2017-06-29 09:43:11 -04:00
RaidenII
e64ad5176e Added Name.com API support.
Minor change to DuckDNS API support.
2017-06-28 16:15:57 -04:00
neil
0e1469f359 Merge pull request #907 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/905
2017-06-28 19:47:40 +08:00
neilpang
7d2b6cfeaf fix https://github.com/Neilpang/acme.sh/issues/905 2017-06-28 19:46:51 +08:00
neil
8e7d029946 Merge pull request #906 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/900
2017-06-28 19:21:45 +08:00
neilpang
9dd62ae0f8 fix https://github.com/Neilpang/acme.sh/issues/900 2017-06-28 19:21:03 +08:00
RaidenII
e7dff4756f Using HTTPS for DuckDNS API and added instruction. 2017-06-27 15:28:10 -04:00
RaidenII
fa98d72f3a Added preliminary support for DuckDNS TXT record API, a free Dynamic DNS provider 2017-06-27 09:21:39 -04:00
neil
ccf0492890 Merge pull request #904 from Neilpang/dev
Dev
2017-06-27 19:57:50 +08:00
neilpang
eb0ef6bd3d fix https://github.com/Neilpang/acme.sh/issues/614#issuecomment-311160843 2017-06-27 19:56:43 +08:00
dkerr64
19aa2ccf4d Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-06-24 12:18:07 -04:00
neil
841b762796 minor 2017-06-23 18:11:11 +08:00
neil
63fb90806c Merge pull request #896 from Neilpang/dev
support --server
2017-06-20 21:59:08 +08:00
neilpang
88ada80686 step to 2.7.3 2017-06-20 21:51:18 +08:00
neilpang
7d5ddf5e6a Merge branch 'server' of https://github.com/Neilpang/acme.sh into server 2017-06-19 20:36:33 +08:00
neilpang
8f01919f62 minor 2017-06-19 20:34:49 +08:00
neilpang
98394f99b5 fix server host 2017-06-19 20:34:49 +08:00
neilpang
cae50e16a7 fix https://github.com/Neilpang/acme.sh/issues/882#issuecomment-309383956 2017-06-19 20:34:48 +08:00
neilpang
4a2ac7bd2e fix renew for stage cert 2017-06-19 20:34:48 +08:00
neilpang
a3bdaa85f2 minor 2017-06-19 20:34:47 +08:00
neilpang
40ef86f475 fix for deactivate function 2017-06-19 20:34:47 +08:00
neilpang
4cee14f3c5 fix format 2017-06-19 20:34:47 +08:00
neilpang
48d9a8c180 support --server 2017-06-19 20:34:46 +08:00
neilpang
1d384e3192 minor 2017-06-19 20:24:31 +08:00
neilpang
87f3dc4558 fix server host 2017-06-19 20:19:30 +08:00
neilpang
8afec596aa fix https://github.com/Neilpang/acme.sh/issues/882#issuecomment-309383956 2017-06-19 20:05:43 +08:00
neil
26e3263aec Merge pull request #894 from Neilpang/dev
Dev
2017-06-18 22:16:34 +08:00
neilpang
08b4e1a744 add ACME_NO_COLOR and --no-color not to ouput color text 2017-06-18 22:13:33 +08:00
neil
d68f0999a4 Merge pull request #891 from Neilpang/aix
fix https://github.com/Neilpang/acme.sh/issues/805
2017-06-18 10:19:25 +08:00
neilpang
2c9ed4c565 check invalid subject cn in the csr
fix https://github.com/Neilpang/acme.sh/issues/805
2017-06-18 10:18:20 +08:00
neil
be4f87c760 Merge pull request #890 from Neilpang/dev
fix format
2017-06-18 10:08:10 +08:00
neilpang
b963dadc14 fix format 2017-06-18 10:07:23 +08:00
neil
26e7fd8b80 Merge pull request #889 from Neilpang/dev
fix openssl 1.1.0 for https://github.com/Neilpang/acme.sh/issues/888
2017-06-18 09:56:11 +08:00
neilpang
b9a972bccd fix openssl 1.1.0 for https://github.com/Neilpang/acme.sh/issues/888 2017-06-18 09:52:59 +08:00
neil
bb7b9280d3 Merge pull request #887 from Neilpang/dev
fix cron
2017-06-17 20:50:43 +08:00
neilpang
395fbbfd14 fix cron 2017-06-17 20:49:45 +08:00
neil
896dfe3def Merge pull request #886 from Neilpang/dev
Dev
2017-06-17 17:31:32 +08:00
neil
6c4f33910c Merge pull request #871 from hajhatten/master
Added views to infoblox dnsapi script
2017-06-17 17:30:51 +08:00
Rikard Gynnerstedt
0a301cdd21 added new line at the end of the file 2017-06-17 11:28:49 +02:00
neilpang
ce59fc6c10 fix renew for stage cert 2017-06-17 17:15:37 +08:00
neilpang
cbb74c984f minor 2017-06-17 16:30:04 +08:00
neilpang
287623df58 fix for deactivate function 2017-06-17 16:20:32 +08:00
neilpang
f8c1d97a25 fix format 2017-06-17 15:59:27 +08:00
neilpang
2a188905da support --server 2017-06-17 15:49:45 +08:00
neil
c2b1e38d7f Merge pull request #884 from Neilpang/dev
Dev
2017-06-17 11:41:16 +08:00
neilpang
fcc0aef7f4 start 2.7.2 2017-06-16 22:41:33 +08:00
neil
eaa3de2dce Merge pull request #883 from Neilpang/url
fix https://github.com/Neilpang/acme.sh/issues/881#issuecomment-30902…
2017-06-16 22:38:39 +08:00
neilpang
f3dc5dd12f fix https://github.com/Neilpang/acme.sh/issues/881#issuecomment-309026385 2017-06-16 21:45:14 +08:00
neil
d2f0178fab Merge pull request #879 from Neilpang/dev
add debug message
2017-06-15 22:25:18 +08:00
neilpang
326c386b2e add debug message 2017-06-15 21:44:10 +08:00
neil
6e68c4e2d6 Merge pull request #878 from Neilpang/dev
Dev
2017-06-15 21:28:22 +08:00
neil
a79e96802f Merge pull request #877 from Neilpang/master
sync
2017-06-15 21:27:30 +08:00
neilpang
65b22b493c minor, debug info 2017-06-15 21:26:14 +08:00
Rikard Gynnerstedt
b73f5a4e94 missed one egrep command 2017-06-15 00:16:26 +02:00
Rikard Gynnerstedt
3b74ac841e save Infoblox_View to account config 2017-06-14 23:52:48 +02:00
neil
253bf776b5 Merge pull request #876 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/874
2017-06-14 23:31:58 +08:00
neilpang
eef4acd07d fix https://github.com/Neilpang/acme.sh/issues/874 2017-06-14 23:25:20 +08:00
Rikard Gynnerstedt
b6f00ea241 changed path to env 2017-06-08 13:35:27 +02:00
Rikard Gynnerstedt
0bd4a4f98f formated for sh instead of bash 2017-06-08 13:34:29 +02:00
Rikard Gynnerstedt
0b52645bb6 added view variable to infoblox integration script 2017-06-08 13:32:05 +02:00
neil
8e845d9f21 make install command respect LE_CONFIG_HOME env 2017-06-06 10:08:09 +08:00
neil
d29aa43ba4 Merge pull request #869 from Neilpang/dev
Dev
2017-06-05 22:59:41 +08:00
neilpang
450efea191 fix format 2017-06-05 22:55:16 +08:00
neilpang
241cfc4342 fix nginx mode issue for multiple entries 2017-06-05 22:29:21 +08:00
neilpang
7c67e3d7e2 fix typo 2017-06-05 22:18:03 +08:00
neilpang
674790a511 add more detect for nginx mode 2017-06-05 22:14:58 +08:00
neil
4e3c82e329 Merge pull request #868 from Neilpang/dev
minor, add debug info
2017-06-05 21:02:38 +08:00
neilpang
df711b0ea2 minor, add debug info 2017-06-04 22:04:43 +08:00
neil
1019fd9a9d Merge pull request #866 from Neilpang/dev
Dev
2017-05-29 18:02:43 +08:00
neilpang
8a420dd853 fix https://github.com/Neilpang/acme.sh/issues/865#issuecomment-304599955 2017-05-29 17:17:14 +08:00
neilpang
f8bcfeb2ab fix xargs issue for freebsd
https://github.com/Neilpang/acme.sh/issues/865#issuecomment-304599955
2017-05-29 17:07:59 +08:00
neil
34e5beda6a Merge pull request #864 from Neilpang/dev
fix doc
2017-05-27 19:29:13 +08:00
neilpang
6185244754 fix doc 2017-05-27 19:28:12 +08:00
neil
60d9509e39 Merge branch 'dev' 2017-05-26 15:02:30 +08:00
neil
ded4469efe fix for openbsd, sed doesn't support I option. 2017-05-26 14:58:52 +08:00
neil
1f95d8eedf Merge pull request #863 from Neilpang/dev
Dev
2017-05-25 21:08:04 +08:00
neilpang
aa66dfff57 fix doc 2017-05-25 21:06:59 +08:00
neil
25263ce40f Merge pull request #862 from Neilpang/master
sync
2017-05-23 20:46:50 +08:00
neil
e85deb54e1 Merge pull request #860 from feld/patch-1
Update README.md
2017-05-23 20:43:33 +08:00
neil
4750fd159e Merge pull request #861 from Neilpang/dev
Dev
2017-05-23 09:15:18 +08:00
Mark Felder
7eea9533e8 Update README.md
Fix usage documentation for dns_nsupdate. The NSUPDATE_KEY env needs to be a path to a file.
2017-05-22 14:53:26 -05:00
neil
ec675b9ad2 Merge pull request #858 from yadutaf/jt-dns-ovh-scoped-credentials
Support OVH credentials scoped to a specific zone
2017-05-22 21:40:15 +08:00
Jean-Tiare Le Bigot
486e77f474 Support OVH credentials scoped to a specific zone
When creating OVH API credentials, one can scope them to a specific subset of routes. Specifically, this allows to limit acme.sh to a specific zone as the zone is part of the URL. This is an important security/safety net feature.
2017-05-22 14:16:08 +02:00
neil
048059ba1f Merge pull request #854 from Neilpang/dev
Dev
2017-05-20 11:28:26 +08:00
neilpang
ed3dda7da9 fix format 2017-05-20 11:15:26 +08:00
neilpang
fa93d68b08 promote performance 2017-05-20 11:02:48 +08:00
dkerr64
6093a4f9f8 Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-05-19 21:25:39 -04:00
neil
4e20d89d9c Merge pull request #851 from Neilpang/dev
fix for performance of _h2b() function
2017-05-17 13:26:54 +08:00
neil
b420ec6cb9 fix for performance of _h2b() function 2017-05-17 13:16:53 +08:00
neil
375f6101e9 Merge pull request #848 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/844
2017-05-15 20:50:35 +08:00
neil
2844d73dc7 fix https://github.com/Neilpang/acme.sh/issues/844 2017-05-15 20:46:02 +08:00
neil
6c1176f853 Merge pull request #843 from Neilpang/dev
Dev
2017-05-14 10:24:19 +08:00
neilpang
df037db0bb clean cache 2017-05-14 10:15:40 +08:00
neil
949cc7d21b Merge pull request #841 from Neilpang/master
gitter
2017-05-12 13:40:01 +08:00
neil
9244529007 Merge pull request #840 from gitter-badger/gitter-badge
Add a Gitter chat badge to README.md
2017-05-12 13:39:01 +08:00
The Gitter Badger
319d49ddbe Add Gitter badge 2017-05-12 05:37:15 +00:00
neil
96fcfdb6c6 Merge branch 'dev' 2017-05-12 11:30:49 +08:00
neil
d61ef6b49a gandi dns api updated. 2017-05-12 11:27:06 +08:00
neil
804a6c8d47 Merge pull request #838 from Neilpang/dev
add VOLUME
2017-05-11 20:56:48 +08:00
neilpang
c487cd6af2 add VOLUME 2017-05-11 20:51:16 +08:00
neil
6a2592a9d9 Merge pull request #835 from Neilpang/dev
update doc
2017-05-09 13:34:39 +08:00
neil
0f48b15695 update doc 2017-05-09 13:33:54 +08:00
neil
4320b8a5a5 Merge pull request #833 from Neilpang/dev
Dev
2017-05-08 22:58:00 +08:00
neilpang
a20707cd73 fix format 2017-05-08 22:57:23 +08:00
neilpang
5da1d3b73b minor fix format 2017-05-08 22:55:21 +08:00
neil
be15e63d41 Merge pull request #832 from Neilpang/dev
fix list order
2017-05-08 22:25:56 +08:00
neilpang
9bc5f686eb fix list order 2017-05-08 22:25:06 +08:00
neil
5bed21dace Merge pull request #831 from Neilpang/dev
Dev
2017-05-08 22:15:32 +08:00
neil
a97e651582 Merge pull request #714 from justmwa/master
NS1. API support
2017-05-08 22:13:42 +08:00
nytral
dff641a665 I can do it... just discovered vmdiff 2017-05-08 16:07:45 +02:00
nytral
47a25cc3e8 Merge github.com:justmwa/acme.sh
Conflicts:
	dnsapi/README.md
	dnsapi/dns_nsone.sh
2017-05-08 16:02:31 +02:00
nytral
5e3a5f627a last but not least 2017-05-08 15:51:01 +02:00
justmwa
9201e0a5b9 Merge branch 'dev' into master 2017-05-08 15:32:02 +02:00
neil
4c80ed3208 Merge pull request #827 from Neilpang/dev
Dev
2017-05-05 20:26:32 +08:00
neil
f34579e921 Merge pull request #826 from wizard1024/patch-1
Update dns_aws.sh to work only with public zones
2017-05-05 20:25:52 +08:00
wizard1024
cc1d3b20b6 Update dns_aws.sh to work only with public zones 2017-05-05 14:55:51 +03:00
Pål Håland
8c56356459 Merge remote-tracking branch 'upstream/dev' into dev 2017-05-03 21:49:55 +02:00
David Kerr
21f728f0ea Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-05-03 11:15:46 -04:00
neil
8051b6e8b6 Merge pull request #822 from Neilpang/dev
update doc
2017-05-03 23:08:11 +08:00
neilpang
4c38fec3b5 update doc 2017-05-03 23:07:30 +08:00
neil
c4cdcf44c5 Merge pull request #819 from Neilpang/dev
Dev
2017-05-03 13:16:09 +08:00
neil
347dab0c14 Merge pull request #443 from pho3nixf1re/dnsimple
include dnsimple api
2017-05-03 13:15:11 +08:00
neil
a3d3ea2b4b Merge pull request #815 from ka2er/dev
less permissive permission on OVH API
2017-05-03 13:12:47 +08:00
Matthew Turney
5332387125 Use _post to send a DELETE request for DNSimple record removal. 2017-05-02 09:04:21 -05:00
Matthew Turney
5b21cbe0de Revert "provide a more general purpose request function"
This reverts commit aa86652db8d3132fb7fe0c0253dded7deb7dce2c.

This is not actually necessary and can be accomplished with the post
function.
2017-05-02 08:59:37 -05:00
Matthew Turney
2f4111a2e2 fixup shellcheck style issues 2017-05-02 08:59:37 -05:00
Matthew Turney
326ac485b3 link to repo for dnsimple integration support 2017-05-02 08:59:37 -05:00
Matthew Turney
f9b419d1e4 cleanup dns in dnsimple api integration
Implement the `_rm()` method for the DNSimple integration. This also
required some changes and cleanup to DRY up the code.
2017-05-02 08:59:37 -05:00
Matthew Turney
f4e81953ce provide a more general purpose request function
This allows for more flexibility in the future. Most importantly being
able to do more than just GET requests but any HTTP method. Specifically
needed for DELETE requests.
2017-05-02 08:59:37 -05:00
Matthew Turney
2b09253961 link to contributor repo for support issues relating to the dnsimple API integration 2017-05-02 08:59:37 -05:00
Matthew Turney
1994c6828e include dnsimple api
Even though DNSimple is technically covered with lexicon not all
systems can install python pip's easily. For these systems it is useful
to have pure shell script API interactions.
2017-05-02 08:59:37 -05:00
ka2er
f5c381d5b4 less permissive permission on OVH API
restrict authorization request to OVH /domain API and not whole OVH API.
Not perfect due to some limitations in regex with *, but better security as the token don't give full access to the API.
2017-05-02 00:45:29 +02:00
neil
7e2af8364f Merge pull request #814 from Neilpang/dev
Dev
2017-05-01 13:54:45 +08:00
neil
0a2ab2aed2 Merge pull request #813 from shar0119/patch-4
Removed grep -Po
2017-05-01 13:54:10 +08:00
shar0119
2310a9bbc0 Removed grep -Po
Removed usage of grep -Po.
2017-04-30 10:32:56 -07:00
neilpang
5b3e3d9cf4 fix https://github.com/Neilpang/acme.sh/issues/812 2017-04-30 16:29:20 +08:00
neil
c97c79ab2f Merge pull request #809 from thecantero/patch-1
Update to support Kong-v0.10.x
2017-04-28 10:14:53 +08:00
Andre Cantero
1231b71245 Update the notes 2017-04-28 00:25:30 +08:00
Andre Cantero
824ffa24f4 Add shebang 2017-04-28 00:21:21 +08:00
neilpang
148f869bec fix https://github.com/Neilpang/acme.sh/issues/805 2017-04-27 22:21:59 +08:00
thecantero
c140fe9bae Typo Fix 2017-04-27 20:51:02 +08:00
thecantero
4b02ee5b46 Typo fix 2017-04-27 20:38:08 +08:00
thecantero
de3bac53bf update README 2017-04-27 20:06:47 +08:00
neil
3f1a76d9e4 fix https://github.com/Neilpang/acme.sh/issues/808 2017-04-27 18:29:29 +08:00
thecantero
0138e167e9 Update to support Kong-v0.10.x
The previous one is for Kong-v0.9.x only.

This change will allow it to work with v0.10.x.

More info at:
4f960abe33/UPGRADE.md (upgrade-to-010x)
https://getkong.org/docs/0.10.x/admin-api/#add-certificate
2017-04-27 18:23:43 +08:00
neil
bcd2ee6204 Merge pull request #768 from shar0119/patch-2
Updated Readme.md file (1 of 2)
2017-04-27 11:11:34 +08:00
neil
4c1d521711 Merge pull request #767 from shar0119/patch-3
Patch 3
2017-04-27 11:11:12 +08:00
shar0119
90c70fa5bf Merge branch 'dev' into patch-3 2017-04-26 15:58:58 -07:00
shar0119
8e15c48092 Merge branch 'master' into patch-2 2017-04-26 15:51:03 -07:00
shar0119
9cf65e31cd Resolved conflict.
Resolved conflict.
2017-04-25 19:37:56 -07:00
shar0119
a6e5876d96 Resolved conflict.
Resolved conflict.
2017-04-25 19:33:54 -07:00
neil
937e723036 Merge pull request #726 from shar0119/patch-1
Create dns_dynu.sh
2017-04-26 09:24:48 +08:00
David Kerr
3a439063a6 Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-04-22 11:45:03 -04:00
neil
12d876a005 Merge pull request #804 from Neilpang/dev
Dev
2017-04-21 20:19:13 +08:00
neil
4e2426a2b4 Merge pull request #803 from LAV45/dev
small Fix readme [skip ci]
2017-04-21 18:52:00 +08:00
Aleksey Loban
020f9cd2a6 small Fix readme [skip ci] 2017-04-21 13:15:39 +03:00
neil
d7eebe9df0 Merge pull request #802 from Neilpang/dev
Dev
2017-04-21 17:53:14 +08:00
neil
cebc5bf9fc Merge pull request #792 from LAV45/dev
Add dns_vscale.sh
2017-04-21 17:52:21 +08:00
Aleksey Loban
dbe68684a0 Fix readme 'Use VSCALE API' [skip ci] 2017-04-21 12:30:21 +03:00
LAV45
27a05ff271 Add dns_vscale.sh 2017-04-19 23:34:14 +03:00
neil
1489ddc49a Merge pull request #800 from Neilpang/dev
update doc
2017-04-19 23:14:06 +08:00
neilpang
9be2c1beb9 update doc 2017-04-19 23:12:37 +08:00
David Kerr
9964e6eba3 Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-04-17 15:28:36 -04:00
neil
8bcc19d91e Merge pull request #797 from Neilpang/dev
minor remove spaces
2017-04-17 19:09:28 +08:00
neil
3c07f57aad minor remove spaces 2017-04-17 19:08:34 +08:00
neil
3262a916e0 Merge pull request #796 from Neilpang/dev
fix docker cronjob
2017-04-16 11:27:00 +08:00
neilpang
7883cc5891 fix docker cronjob 2017-04-16 11:16:48 +08:00
neil
ded7a5438c Merge pull request #795 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/794#issuecomment-29431…
2017-04-16 09:42:08 +08:00
neilpang
cd98951001 fix https://github.com/Neilpang/acme.sh/issues/794#issuecomment-294314606 2017-04-16 09:36:59 +08:00
shar0119
8470c60e06 Using _egrep_o() instead of grep -o -e
Modified code to use egrep instead of grep -o -e.
2017-04-14 12:46:00 -07:00
shar0119
394b1002b3 Corrected formatting error.
Part of dns_dynu_rm() impementation.
2017-04-13 20:54:57 -07:00
shar0119
9a61d6293d Implemented dns_dynu_rm()
Implemented dns_dynu_rm() method.
2017-04-13 20:48:39 -07:00
neil
192ad27f8f Merge pull request #786 from Neilpang/dev
fix format
2017-04-11 22:30:37 +08:00
neilpang
eb0fc67461 fix format 2017-04-11 22:29:49 +08:00
neil
adbe5e9048 Merge pull request #785 from Neilpang/dev
support change account conf from env
2017-04-11 21:39:33 +08:00
neilpang
fcdf41ba29 support change account conf from env 2017-04-11 21:37:56 +08:00
neil
7b40cbe8c1 Merge pull request #778 from Neilpang/dev
Dev
2017-04-08 14:54:29 +08:00
neil
0933929cfe Merge pull request #777 from gidcs/fix-bug-of-if-statement
fix missing space bug on if statement
2017-04-08 14:54:00 +08:00
Kok Suan Lim
7f618e7ecc fix missing space bug on if statement 2017-04-08 14:50:39 +08:00
neilpang
482cb73702 fix https://github.com/Neilpang/acme.sh/issues/758 2017-04-06 19:29:09 +08:00
David Kerr
fd1598017a Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-04-05 16:47:56 -04:00
neil
96f79475f1 Merge pull request #774 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/549
2017-04-05 21:13:07 +08:00
neilpang
3576754c21 fix https://github.com/Neilpang/acme.sh/issues/549 2017-04-05 20:54:53 +08:00
neil
6c3a0bc72c Merge pull request #773 from Neilpang/dev
minor, add more error message
2017-04-05 20:48:21 +08:00
neilpang
49d75a0cd4 minor, add more error message 2017-04-05 20:46:17 +08:00
neil
756dbac39f Merge pull request #771 from Neilpang/dev
add more debug info
2017-04-04 22:34:19 +08:00
neilpang
7df062b7d7 add more debug info 2017-04-04 22:33:26 +08:00
neil
e485e8f60d Merge pull request #770 from Neilpang/dev
Dev
2017-04-04 15:55:53 +08:00
neil
fde8ea081a Merge pull request #769 from Neilpang/aws
Aws
2017-04-04 15:55:30 +08:00
neilpang
f7217c5f26 fix format 2017-04-04 15:54:45 +08:00
neilpang
fd77e463a1 fix aws 2017-04-04 14:34:23 +08:00
shar0119
6d7f6750e9 Updated author name and link to report bugs 2017-04-03 21:22:58 -07:00
shar0119
695482ded7 Added author name and link to report bugs 2017-04-03 21:21:50 -07:00
neilpang
fc9649dbc4 fix aws 2017-04-04 10:02:45 +08:00
shar0119
afb67d375f Updated README.md (2 of 2) 2017-04-03 14:01:40 -07:00
shar0119
66e38ae69e Updated Readme.md file (1 of 2) 2017-04-03 13:46:39 -07:00
neilpang
1f4e64f81d Truncated request for more than 100 domains. 2017-04-04 00:21:39 +08:00
neil
ad541f713d Merge pull request #764 from Neilpang/dev
v2.6.8 support Docker
2017-04-03 12:23:00 +08:00
neilpang
f3b434397b v2.6.8 support Docker 2017-04-03 12:08:38 +08:00
neil
1d5d49312c Merge pull request #757 from Neilpang/dev
fix format
2017-03-30 21:34:50 +08:00
neilpang
232c7361a9 fix format 2017-03-30 21:34:15 +08:00
neil
721543653b Merge pull request #756 from Neilpang/dev
add retry for issuer cert
2017-03-30 21:26:23 +08:00
neilpang
d8ba26e664 add retry for issuer cert 2017-03-30 21:16:25 +08:00
neil
7ecabeac97 Merge pull request #753 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/751
2017-03-29 10:02:55 +08:00
neil
6cf7be4b7e fix https://github.com/Neilpang/acme.sh/issues/751 2017-03-29 09:16:22 +08:00
neil
5f2e56674c Merge pull request #752 from Neilpang/dev
export Le_Domain for reloadcmd
2017-03-29 09:11:20 +08:00
neil
58d4c74b0b export Le_Domain for reloadcmd
fix https://github.com/Neilpang/acme.sh/issues/558#issuecomment-289926193
2017-03-29 09:10:42 +08:00
shar0119
e137792efd Commented out Dynu_ClientId and Dynu_Secret 2017-03-28 08:11:04 -07:00
shar0119
b7b934913e Removed unnecessary spaces 2017-03-27 13:39:31 -07:00
shar0119
cd8fcbf9c6 Spaces in assignment removed. 2017-03-27 12:38:12 -07:00
shar0119
d0300d4443 Changes as requested per Commit 9c90b21
In dnsapi/dns_dynu.sh line 115:
  export _H1="Authorization: Basic $(printf "%s" "$Dynu_ClientId:$Dynu_Secret" | _base64)"
         ^-- SC2155: Declare and assign separately to avoid masking return values.
2017-03-27 12:27:21 -07:00
neil
40acd9a4c3 Merge pull request #746 from Neilpang/dev
Dev
2017-03-26 14:02:38 +08:00
neil
e66b4d5390 Merge pull request #745 from jsoref/spelling
Spelling fixes
2017-03-26 13:53:56 +08:00
Josh Soref
f94433e504 spelling: validation 2017-03-26 05:32:29 +00:00
Josh Soref
7f32488b78 spelling: subdomain 2017-03-26 05:31:35 +00:00
Josh Soref
8f73e24175 spelling: specifies 2017-03-26 05:31:12 +00:00
Josh Soref
f3c984281c spelling: specified 2017-03-26 05:30:58 +00:00
Josh Soref
00777a10ae spelling: security 2017-03-26 05:30:43 +00:00
Josh Soref
0d6ce9f977 spelling: satisfy 2017-03-26 05:30:26 +00:00
Josh Soref
997c517ba2 spelling: return 2017-03-26 05:30:15 +00:00
Josh Soref
849bed4bef spelling: requires 2017-03-26 05:30:03 +00:00
Josh Soref
61a48a5b9f spelling: please 2017-03-26 05:29:30 +00:00
Josh Soref
df14085ec8 spelling: oops 2017-03-26 05:29:11 +00:00
Josh Soref
00b34eb2a4 spelling: occurred 2017-03-26 05:28:57 +00:00
Josh Soref
84a6730b1a spelling: obtain 2017-03-26 05:28:37 +00:00
Josh Soref
357b514bc9 spelling: lines 2017-03-26 05:28:04 +00:00
Josh Soref
d39b108274 spelling: function 2017-03-26 05:27:04 +00:00
Josh Soref
39f3239682 spelling: following 2017-03-26 05:26:55 +00:00
Josh Soref
506f36b26d spelling: embedded 2017-03-26 05:26:43 +00:00
Josh Soref
4cedbf80df spelling: delimiter 2017-03-26 05:26:20 +00:00
Josh Soref
b54ce31078 spelling: changing 2017-03-26 05:25:23 +00:00
Josh Soref
9b2aa974ba spelling: changed 2017-03-26 05:25:31 +00:00
Josh Soref
291c97dc81 spelling: challenge 2017-03-26 05:25:04 +00:00
Josh Soref
bcbecff6f6 spelling: certificate 2017-03-26 05:24:52 +00:00
Josh Soref
3d22708f67 spelling: automatically 2017-03-26 05:24:38 +00:00
Josh Soref
8afd31902f spelling: application 2017-03-26 05:24:26 +00:00
David Kerr
89f66ebf6d Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-03-24 10:55:42 -04:00
neil
d1a2208196 Merge pull request #744 from Neilpang/dev
Dev
2017-03-24 19:20:46 +08:00
neil
42d1fe5422 Merge pull request #742 from jasonkeller/dev
Add infoblox api support
2017-03-24 09:22:03 +08:00
Jason
1424e8a2de Added attribution 2017-03-23 20:20:04 -05:00
Jason
7dc548b4b8 MORE bs 2017-03-23 15:06:37 -05:00
Jason
2c37d94611 More bs 2017-03-23 14:40:09 -05:00
Jason
b1e4a7c615 Fixed (hopefully) TravisCI errors 2017-03-23 14:34:29 -05:00
Jason
b0561058c6 Infoblox API 2017-03-23 14:16:31 -05:00
Jason
d039295070 Added Infoblox references 2017-03-23 14:15:17 -05:00
Jason
4ddafb8e84 Added Infoblox reference 2017-03-23 14:14:28 -05:00
neil
a536231ded Merge pull request #741 from Neilpang/dev
update doc
2017-03-22 22:59:13 +08:00
neilpang
13fe54c938 update doc 2017-03-22 22:58:03 +08:00
neil
d54ffdd187 Merge pull request #740 from Neilpang/dev
rename parameters
2017-03-22 21:53:36 +08:00
neilpang
5c539af7d7 rename parameters 2017-03-22 21:20:35 +08:00
neil
47d9a9cf20 Merge pull request #738 from Neilpang/dev
Dev
2017-03-22 20:54:21 +08:00
neil
7f25205aeb Merge pull request #732 from jtbr/curl-patch
--ca-path patch for curl/wget ssl support
2017-03-22 20:53:58 +08:00
David Kerr
688973fa44 Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-03-21 16:30:46 -04:00
Pål Håland
400661d432 Merge remote-tracking branch 'upstream/dev' into dev 2017-03-21 20:14:31 +01:00
neil
7ebecf3851 Merge pull request #737 from Neilpang/dev
Dev
2017-03-21 22:42:29 +08:00
neil
0a5eaec0f2 Merge pull request #733 from jtbr/busybox-netstat
Busybox netstat
2017-03-21 22:26:39 +08:00
jtbr
4bdab73dd5 formatting 2017-03-20 18:53:08 +01:00
jtbr
f19f21007c formatting 2017-03-20 18:51:45 +01:00
Pål Håland
e4e60ed654 Merge remote-tracking branch 'upstream/dev' into dev 2017-03-19 21:17:21 +01:00
jtbr
f21dd9117d Handle case of busybox netstat, with no pid support 2017-03-19 17:55:26 +01:00
jtbr
2aa75f034f Adds support for --ca-path option for using non-default curl/wget CA certs 2017-03-19 16:10:09 +01:00
shar0119
5c78e0a462 removed source acme.sh 2017-03-16 13:42:30 -07:00
neil
52cdedcba0 Merge pull request #730 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/729 https://github.com…
2017-03-16 18:43:38 +08:00
neil
c87cd0de73 fix https://github.com/Neilpang/acme.sh/issues/729 https://github.com/Neilpang/acme.sh/issues/721 2017-03-16 18:02:36 +08:00
neil
12530655df Merge pull request #727 from Neilpang/dev
Dev
2017-03-16 13:06:11 +08:00
neil
7479706b29 Merge pull request #723 from ClouDNS/master
Add DNS API support for ClouDNS
2017-03-16 13:05:12 +08:00
David Kerr
070a141601 Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-03-15 18:37:46 -04:00
shar0119
7044236824 Create dns_dynu.sh
Add DNS API support for Dynu.
2017-03-15 11:40:32 -07:00
boyanpeychev
3e9478b58d Update README information for ClouDNS 2017-03-15 17:25:01 +02:00
boyanpeychev
5ffca2d138 Update cotnact details 2017-03-15 17:16:54 +02:00
neil
a8d4a98621 Merge pull request #725 from Neilpang/dev
Dev
2017-03-15 23:09:55 +08:00
neilpang
905f7f4ecc Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2017-03-15 22:53:27 +08:00
neilpang
819d2bc560 fix for wget. fix https://github.com/Neilpang/acme.sh/issues/724#issuecomment-286761682 2017-03-15 22:52:57 +08:00
boyanpeychev
c0b2027588 add ClouDNS to the list in the main README file 2017-03-15 15:58:04 +02:00
boyanpeychev
136d1b04b5 some additional fixes and removed awk 2017-03-15 15:52:05 +02:00
boyanpeychev
f063dd195e some additional fixes and removed awk 2017-03-15 15:49:14 +02:00
boyanpeychev
be972fc0b5 fixes for the comments in #723 2017-03-15 10:00:21 +02:00
Pål Håland
ff90a5d321 Merge branch 'dev' of github.com:Neilpang/acme.sh into dev 2017-03-14 20:20:36 +01:00
boyanpeychev
ac11ba3d60 Add DNS API for ClouDNS 2017-03-14 15:12:02 +02:00
boyanpeychev
3d8598654c Add DNS API for ClouDNS 2017-03-14 14:43:43 +02:00
boyanpeychev
55a5da2102 Add DNS API for ClouDNS 2017-03-14 14:42:51 +02:00
boyanpeychev
f881d6c44f Add DNS API for ClouDNS 2017-03-14 14:40:18 +02:00
boyanpeychev
5df2ca3ef3 Add DNS API for ClouDNS 2017-03-14 14:38:02 +02:00
boyanpeychev
a15f87ae39 Add DNS API for ClouDNS 2017-03-14 14:26:57 +02:00
boyanpeychev
0dd6377fe6 Add DNS API for ClouDNS 2017-03-14 14:25:50 +02:00
boyanpeychev
c7257e0a3c Add DNS API for ClouDNS 2017-03-14 14:20:58 +02:00
boyanpeychev
3b7fbcd0c3 Add DNS API support for ClouDNS 2017-03-14 13:24:09 +02:00
neil
5fe91af6c3 Merge pull request #720 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/719
2017-03-13 11:21:33 +08:00
neil
4dd646a424 fix https://github.com/Neilpang/acme.sh/issues/719 2017-03-13 11:18:04 +08:00
neil
dcbd90ce04 Merge pull request #718 from Neilpang/dev
fix cloudxns api https://github.com/Neilpang/acme.sh/issues/717
2017-03-11 10:08:00 +08:00
neilpang
04683338a2 fix cloudxns api https://github.com/Neilpang/acme.sh/issues/717 2017-03-11 10:06:40 +08:00
neil
b778f9c40e Merge pull request #716 from Neilpang/dev
Dev
2017-03-09 21:29:11 +08:00
neil
e0a96be378 Merge pull request #715 from gitwer/dev
Add DigitalOcean automatic DNS API support (native)
2017-03-09 21:27:06 +08:00
thewer
ac690fceaf Added DigitalOcean (native) API that requires only a read/write API key for DigitalOcean, updated 2 reads files. 2017-03-09 22:28:30 +10:00
nytral
1e5e03cc46 typo... 2017-03-08 22:22:48 +01:00
nytral
d3c4cd8270 bugfix 2017-03-08 22:21:25 +01:00
nytral
17361df66b cleanup 2017-03-08 22:15:07 +01:00
nytral
7d0452c7e3 added NS1. support 2017-03-08 22:12:37 +01:00
palhaland
cee0ab87fc Merge branch 'dev' into dev 2017-03-08 15:06:23 +01:00
neilpang
dd0b0cae93 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2017-03-08 21:51:54 +08:00
neilpang
c4bf5eef73 add _upper_case and _lower_case 2017-03-08 21:51:25 +08:00
neil
2587639914 Merge pull request #713 from Neilpang/dev
Dev
2017-03-08 21:36:45 +08:00
neil
bfa1ae59cc Merge pull request #701 from csmk/knot_dns_api
Add support for Knot DNS API
2017-03-08 21:36:08 +08:00
neil
9e8575c315 Merge pull request #712 from Neilpang/dev
Dev
2017-03-08 21:24:33 +08:00
neil
e36340ce64 Merge pull request #711 from Neilpang/links
Links
2017-03-08 21:24:13 +08:00
neilpang
63ec05a66c fix links 2017-03-08 21:23:12 +08:00
neilpang
6f1c72f5b4 add links 2017-03-08 21:21:15 +08:00
neil
27924ffd5b Merge pull request #710 from Neilpang/dev
Dev
2017-03-08 20:51:53 +08:00
neil
527029574c Merge pull request #702 from hiskang/deploy/keychain
deploy for OSX Keychain
2017-03-08 20:51:23 +08:00
neil
cf3aeafcdb Merge pull request #709 from Neilpang/dev
fix nginx mode
2017-03-08 16:02:45 +08:00
neil
f08a79d372 fix nginx mode 2017-03-08 16:01:14 +08:00
neil
eb2a26cfaa Merge pull request #708 from Neilpang/dev
fix nginx mode
2017-03-08 13:57:01 +08:00
neil
5378d9ca26 fix nginx mode 2017-03-08 13:55:01 +08:00
hiska
bce11af09a Update README.md for OSX Keychain 2017-03-08 08:00:17 +09:00
David Kerr
158abf5c6c Remove line from README.md that I mistakenly added during
merge with master.
2017-03-07 12:09:07 -05:00
David Kerr
b30c1daf72 Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-03-07 12:04:35 -05:00
David Kerr
0649206796 remove _ACME prefix from all exported variables. 2017-03-07 11:57:03 -05:00
csmk
f589a1d245 Fix format: use double quote to prevent globbing and word splitting 2017-03-07 22:21:22 +09:00
Pål Håland
8a604bd2a1 Fixing syntax for schell script checking 2017-03-06 19:39:55 +01:00
hiska
68eb627d62 deploy for OSX Keychain 2017-03-06 11:09:12 +09:00
csmk
9c87a5890d Add support for Knot DNS API
The script is actually an adapted version of the `dns_nsupdate.sh` script,
as the `knsupdate` utility is quite similar to `nsupdate`.
2017-03-05 22:18:31 +09:00
Pål Håland
b8a8e2280d Added deploy script to deploy to the routeros system 2017-03-05 13:43:01 +01:00
neil
e538a13e28 Merge pull request #698 from Neilpang/dev
minor fix comments
2017-03-05 19:56:43 +08:00
neilpang
6fb2a1ed39 minor fix comments 2017-03-05 19:56:06 +08:00
neil
6b00787f45 Merge pull request #695 from Neilpang/dev
Dev
2017-03-03 22:04:09 +08:00
neilpang
e735d8d4e5 minor 2017-03-03 22:03:19 +08:00
neil
8cd4fd0b50 Merge pull request #692 from fwolfst/issue690_COSMETIC-COMMENT-APACHE-FIX
Issue690 cosmetic comment apache fix
2017-03-02 16:00:08 +08:00
Felix Wolfsteller
8f4b0559ce Merge branch 'issue690_COSMETIC-COMMENT-APACHE-FIX' of github.com:fwolfst/acme.sh into issue690_COSMETIC-COMMENT-APACHE-FIX 2017-03-02 08:39:56 +01:00
Felix Wolfsteller
5288c54aad deploy apache script: fix comment (dovecot/apache)
Closes #690 .
2017-03-02 08:39:31 +01:00
Felix Wolfsteller
51f8bec81b deploy apache script: fix comment (dovecot/apache) 2017-03-02 08:38:25 +01:00
neil
49d3e5d324 Merge pull request #689 from Neilpang/dev
Dev
2017-03-02 13:19:29 +08:00
neil
1fff0e5592 Merge pull request #686 from justmwa/master
Adding delete support for DNSMadeEasy and LUA API
2017-03-02 13:18:29 +08:00
nytral
8d53ec5353 fixed validation, added LUA while I'm at it 2017-03-01 19:38:02 +01:00
nytral
a1e1bfc71b removed useless code 2017-03-01 19:20:16 +01:00
nytral
29992f54a3 delete support for dns_me 2017-03-01 18:28:39 +01:00
nytral
4ab6786163 Merge remote-tracking branch 'upstream/master' 2017-03-01 18:03:39 +01:00
neil
eaad34a69a Merge pull request #685 from Neilpang/dev
Dev
2017-03-01 19:20:12 +08:00
neilpang
839f18d052 fix format 2017-03-01 19:17:20 +08:00
neil
58ef6d8385 fix wget error message 2017-03-01 13:12:29 +08:00
neil
a0037c9333 Merge pull request #683 from Neilpang/dev
Dev
2017-02-28 22:16:58 +08:00
neilpang
177b57e1c0 fix wget content on 404 error 2017-02-28 21:35:20 +08:00
neilpang
810c129ca9 minor fix error message 2017-02-28 21:08:20 +08:00
neilpang
f731a4c704 fix 404 for wget 2017-02-28 21:06:02 +08:00
neilpang
39a1f1ef64 fix 404 for wget 2017-02-28 21:04:33 +08:00
neilpang
d24a87caf1 minor 2017-02-28 20:56:11 +08:00
neilpang
9683ffe13a minor fix error message 2017-02-28 20:39:23 +08:00
Frederic Crozat
fab2d9dc6a add API for Gandi LiveDNS (#680)
* add API for Gandi LiveDNS

* ensure Gandi API key is saved for renewing certificate.

* gandi_livedns: use PUT instead of POST for creating DNS record

* gandi_livedns: fix formatting

* dns_gandi_livedns: fix shellcheck errors
2017-02-28 19:58:04 +08:00
neil
59f7a2f6ef Wget (#678) (#679)
* --use-wget force to use wget

* fix force wget
2017-02-27 20:54:38 +08:00
neil
9b12407028 Wget (#678)
* --use-wget force to use wget

* fix force wget
2017-02-27 20:48:48 +08:00
neil
96c4bb7fd0 Merge pull request #677 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/667#issuecomment-28262…
2017-02-27 13:44:15 +08:00
neil
81532f375e fix https://github.com/Neilpang/acme.sh/issues/667#issuecomment-282629936 2017-02-27 13:38:29 +08:00
neil
79eb8e2b35 Merge pull request #676 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/675
2017-02-26 22:23:39 +08:00
neilpang
7c2e875494 fix https://github.com/Neilpang/acme.sh/issues/675 2017-02-26 22:20:08 +08:00
neil
c715b4637d Merge pull request #674 from Neilpang/dev
Dev
2017-02-26 12:48:53 +08:00
neilpang
c719a61ea7 fix format 2017-02-26 12:15:39 +08:00
neilpang
58e4d337e4 clear the pending authz when issue error
fix bug https://github.com/Neilpang/acme.sh/issues/663
2017-02-26 12:07:06 +08:00
neil
509c802045 Merge pull request #673 from Neilpang/dev
fix ci
2017-02-25 21:49:29 +08:00
neilpang
4fd63f4e30 fix ci 2017-02-25 21:22:56 +08:00
neil
f5c28c72fd Merge pull request #672 from Neilpang/dev
fix format
2017-02-25 21:09:43 +08:00
neilpang
342128a457 fix format 2017-02-25 21:09:06 +08:00
neil
b1931828e1 Merge pull request #671 from Neilpang/dev
add --toPkcs8 command
2017-02-25 19:34:29 +08:00
neilpang
4410226db1 add --toPkcs8 command
fix https://github.com/Neilpang/acme.sh/issues/664
2017-02-25 19:31:52 +08:00
neil
945bd4b1b0 Merge pull request #670 from Neilpang/dev
fix format
2017-02-25 19:12:47 +08:00
neilpang
77f1ea40cd fix format 2017-02-25 19:12:20 +08:00
neil
98c8c7ce0d Merge pull request #669 from Neilpang/dev
Dev
2017-02-25 19:10:19 +08:00
neilpang
795bf9e101 Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev 2017-02-25 19:08:16 +08:00
neilpang
851fedf751 rename OPENSSL_BIN to ACME_OPENSSL_BIN 2017-02-25 19:08:00 +08:00
neil
5be6ab8c89 Merge pull request #432 from seidler2547/dev
add API for www.do.de/www.resellerinterface.de
2017-02-25 18:27:59 +08:00
neil
3670412c7c Merge pull request #668 from Neilpang/dev
Dev
2017-02-25 18:03:38 +08:00
neilpang
e6cd596dc9 add debug info 2017-02-25 18:02:23 +08:00
Stefan Seidel
abf4278d09 resolve conflicts 2017-02-23 21:02:21 +00:00
seidler2547
2b2b65fe18 Declare and assign separately to avoid masking return values 2017-02-23 21:00:40 +00:00
Stefan Seidel
3d6a125bdc add documentation 2017-02-23 21:00:40 +00:00
seidler2547
9efd40a366 use export for headers 2017-02-23 20:59:12 +00:00
seidler2547
383fa8401d Remove stray characater
fixes issue where the first listed domain would not work
2017-02-23 20:59:12 +00:00
seidler2547
bf8ffade29 replace head -1, add link to GitHub 2017-02-23 20:59:12 +00:00
seidler2547
1633d14547 forgot dollar sign 2017-02-23 20:59:12 +00:00
seidler2547
e55605dbe9 remove _all_ mktemp 2017-02-23 20:59:12 +00:00
seidler2547
cdec38ba12 return error if any removal failed 2017-02-23 20:59:12 +00:00
seidler2547
1cb6e9e7d0 remove cookiejar file
d'oh
2017-02-23 20:59:12 +00:00
Stefan Seidel
d1d2f6f451 avoid temp file for domain list 2017-02-23 20:59:12 +00:00
Stefan Seidel
743f821f1e improve error message on failed authentication 2017-02-23 20:59:12 +00:00
Stefan Seidel
b95a99e0c2 remove cookiejar temp file 2017-02-23 20:59:12 +00:00
Stefan Seidel
3ebbeb103c old habits 2017-02-23 20:59:12 +00:00
Stefan Seidel
0d4035e996 remove fgrep, escape regex chars instead 2017-02-23 20:59:12 +00:00
Stefan Seidel
88ed5e506a fix whitespace and UUOC 2017-02-23 20:59:12 +00:00
Stefan Seidel
76a3371b40 remove non-POSIX sed -r and use built-in functions 2017-02-23 20:59:12 +00:00
Stefan Seidel
7b2fa1edb4 add API for www.do.de/www.resellerinterface.de 2017-02-23 20:59:12 +00:00
neilpang
1965035166 support exim4 deploy 2017-02-23 20:03:03 +08:00
neil
76d4ff056a Merge pull request #660 from Neilpang/dev
fix doc
2017-02-23 19:05:43 +08:00
neilpang
a239a9efd5 fix doc 2017-02-23 19:04:08 +08:00
neil
4747e7c5b9 Merge pull request #659 from Neilpang/dev
fix doc
2017-02-23 19:02:38 +08:00
neilpang
35ca729cb9 fix doc 2017-02-23 19:01:48 +08:00
neil
a0fa7421d1 Merge pull request #658 from Neilpang/dev
support deploy vsftpd
2017-02-23 19:00:38 +08:00
neilpang
ddf293bbcd reload only for renewal 2017-02-22 20:40:33 +08:00
neilpang
45d6e00ff1 fix format 2017-02-22 20:17:36 +08:00
neilpang
6dfc8fe0ea support vsftpd hook 2017-02-21 23:18:11 +08:00
neil
96f106d6aa Merge pull request #654 from Neilpang/dev
change installcert parameter order
2017-02-21 21:40:09 +08:00
neilpang
044da37c95 change installcert parameter order 2017-02-21 21:34:43 +08:00
David Kerr
e0b00ee11a Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-02-20 15:27:10 -05:00
neil
086444c73a Merge pull request #650 from Neilpang/dev
Dev
2017-02-20 20:19:48 +08:00
neilpang
1efb2085e9 fix debug info 2017-02-20 20:18:58 +08:00
neil
e1c42eb6cc Merge pull request #414 from noplanman/cyon_dns_api
Cyon.ch DNS API
2017-02-20 19:13:35 +08:00
neil
a2da26cbdd Merge pull request #648 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/614
2017-02-20 19:11:22 +08:00
neil
8796adfd63 fix https://github.com/Neilpang/acme.sh/issues/614 2017-02-20 18:03:16 +08:00
neil
95a6c28d98 Merge pull request #645 from Neilpang/dev
Dev
2017-02-19 22:44:51 +08:00
neilpang
85e1f4ea13 refactor parameters 2017-02-19 22:09:22 +08:00
neilpang
d9c9114b3b refactor key length 2017-02-19 21:21:11 +08:00
neilpang
02140ce763 refactor alt domains 2017-02-19 21:18:00 +08:00
neilpang
af1cc3b331 refactor params 2017-02-19 21:13:00 +08:00
neil
e852044b64 Merge pull request #644 from Neilpang/dev
Dev
2017-02-19 20:54:19 +08:00
neilpang
f845b371ce fix format 2017-02-19 20:40:53 +08:00
neilpang
3a1bd3114b add hooks, not implemented yet. 2017-02-19 20:35:32 +08:00
Armando Lüscher
a6d2e3a1e6 Suppress shellcheck warnings. 2017-02-19 13:26:32 +01:00
neilpang
93bce1b24c support multiple deploy hook
fix https://github.com/Neilpang/acme.sh/issues/508
2017-02-19 20:15:00 +08:00
neil
7b87f29c9c Merge pull request #643 from Neilpang/dev
Dev
2017-02-19 18:20:29 +08:00
neil
cb6f622957 Update README.md 2017-02-19 18:19:24 +08:00
neil
43d3b51bde Update README.md 2017-02-19 18:16:12 +08:00
neil
57e015155a Merge pull request #642 from Neilpang/dev
Dev
2017-02-19 13:31:27 +08:00
neil
2436d7e0ba Merge pull request #641 from Neilpang/secure
secure debug message
2017-02-19 13:30:59 +08:00
neilpang
e6e85b0c55 secure debug message 2017-02-19 13:24:00 +08:00
neil
e43fd39594 Merge pull request #640 from Neilpang/dev
fix syslog doc
2017-02-19 12:56:07 +08:00
neilpang
52765466c1 fix syslog doc 2017-02-19 12:55:05 +08:00
David Kerr
fa9afb0860 Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-02-18 23:45:36 -05:00
neil
e02bede4f5 Merge pull request #639 from Neilpang/dev
fix syslog level
2017-02-19 12:43:26 +08:00
neilpang
113089be5d fix syslog level 2017-02-19 12:42:37 +08:00
David Kerr
712b895170 Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-02-18 23:38:59 -05:00
neil
dca163f54d Merge pull request #638 from Neilpang/dev
fix syslog
2017-02-19 12:18:52 +08:00
neilpang
fc6cf4d963 fix syslog 2017-02-19 12:13:18 +08:00
neil
4126c7e188 Merge pull request #636 from Neilpang/dev
minor use interactive _sleep
2017-02-18 12:04:11 +08:00
neilpang
db50462920 minor use interactive _sleep 2017-02-18 12:03:21 +08:00
neil
9310b44cef Merge pull request #635 from Neilpang/dev
fix for freebsd
2017-02-18 10:32:51 +08:00
neilpang
6480250221 fix for freebsd 2017-02-18 10:31:18 +08:00
David Kerr
710ce7c2e9 Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-02-17 14:28:50 -05:00
neil
b88e64f0d0 Merge pull request #632 from Neilpang/dev
compatible to openssl 0.9 for hmac function
2017-02-17 23:20:59 +08:00
neilpang
c70432996a compatible to openssl 0.9 for hmac function 2017-02-17 23:06:39 +08:00
neil
c6dcf2a0e2 Merge pull request #631 from Neilpang/dev
Dev
2017-02-17 20:13:55 +08:00
neil
2aec627503 Merge pull request #630 from Neilpang/nonce
Nonce
2017-02-17 20:13:13 +08:00
neil
b7924ce58b fix format 2017-02-17 14:40:58 +08:00
neil
0bc745f68f retry if nonce is invalid
fix https://github.com/Neilpang/acme.sh/issues/627
2017-02-17 13:51:17 +08:00
neil
8acdf823a2 Merge pull request #626 from Neilpang/dev
Dev
2017-02-16 22:56:19 +08:00
neilpang
52f8b787c9 fix https://github.com/Neilpang/acme.sh/issues/622 2017-02-16 22:37:32 +08:00
neilpang
ad153ae041 fix https://github.com/Neilpang/acme.sh/issues/622 2017-02-16 22:29:08 +08:00
neil
2527f8f599 Merge pull request #621 from Neilpang/dev
fix https://github.com/Neilpang/acme.sh/issues/614
2017-02-15 21:09:46 +08:00
neilpang
72af092cc1 fix https://github.com/Neilpang/acme.sh/issues/614 2017-02-15 21:09:01 +08:00
neil
2751060b91 Merge pull request #620 from Neilpang/dev
support nginx mode
2017-02-15 20:33:22 +08:00
neil
b3449db2f8 Merge pull request #619 from Neilpang/nginx
support nginx mode
2017-02-15 20:31:02 +08:00
neilpang
7db28745c8 start v2.6.7 2017-02-15 20:28:50 +08:00
neilpang
6921211461 fix debug message 2017-02-15 20:24:24 +08:00
neilpang
9f90618a70 fix https://github.com/Neilpang/acme.sh/issues/617 2017-02-14 23:57:00 +08:00
neilpang
302c41edc9 fix format 2017-02-14 22:41:34 +08:00
neilpang
5d943a35f8 fix https://github.com/Neilpang/acme.sh/issues/616 2017-02-14 22:12:58 +08:00
neilpang
03f8d6e946 fix https://github.com/Neilpang/acme.sh/issues/615 2017-02-14 22:03:48 +08:00
David Kerr
68a35155e4 Improve documentation in readme 2017-02-13 20:32:12 -05:00
neilpang
9d725af602 support nginx mode 2017-02-13 23:29:37 +08:00
David Kerr
d04ccb7a3f fix spelling error in readme 2017-02-12 18:20:43 -05:00
David Kerr
76c1ed6628 Additional documentation for the unifi example. 2017-02-12 18:08:17 -05:00
David Kerr
6f4abe95cb update markdown examples. 2017-02-12 11:24:00 -05:00
David Kerr
e35e313240 Fix error in Unifi example 2017-02-12 11:20:16 -05:00
David Kerr
3a77a6eded cleanup documentation and suppress some remote messages. 2017-02-12 11:17:23 -05:00
David Kerr
0a7a1b9bfb Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-02-12 10:45:51 -05:00
Armando Lüscher
3e1418d662 Use gloo item key for environment change, to support different account types.
(this isn't working 100% yet, still looking for a solution)
2017-02-12 12:30:06 +01:00
Armando Lüscher
884f70fb39 Remove square brackets from ranges.
Export curl header variables.
2017-02-12 12:24:58 +01:00
Armando Lüscher
9499a1142b Remove custom URL encoding and use library's implementation. 2017-02-12 12:24:58 +01:00
Armando Lüscher
6e8dcdce78 Satisfy shellcheck. 2017-02-12 12:24:58 +01:00
Armando Lüscher
ce9fae82bd Update cookie retrieval using _egrep_o (thanks @Neilpang) 2017-02-12 12:24:57 +01:00
Armando Lüscher
afa3fc8bf9 Adapt to use general naming rule for account variables. 2017-02-12 12:24:57 +01:00
Armando Lüscher
09eccf6fc0 Use more flexible version of uppercase to lowercase conversion. 2017-02-12 12:24:57 +01:00
Armando Lüscher
edfefb6763 Add usage instructions and repo link to post issues. 2017-02-12 12:24:57 +01:00
Armando Lüscher
98b3dcbf37 Prefix all private functions with _cyon.
Satisfy shellcheck.
2017-02-12 12:22:50 +01:00
Armando Lüscher
2698ef6c5f Return instead of exit.
Clear OTP secret if environment variable is set to empty. This is for when the 2FA is disabled.
Rename `_is_idn` function to `_is_idn_cyon`.
Remove usage of curl (except for URL encoding of data).
Instead of cleaning up the cookie jar, get rid of it completely and logout of cyon instead.
2017-02-12 12:22:49 +01:00
Armando Lüscher
46b2ee3bae Replace all echos with printf. 2017-02-12 12:22:49 +01:00
Armando Lüscher
e7ee3a7dd5 Remove jq completely to not require it as a dependency. 2017-02-12 12:22:49 +01:00
Armando Lüscher
0085e6f83b Don't use jq to fetch list of DNS entries to be deleted. 2017-02-12 12:22:49 +01:00
Armando Lüscher
c90fa3bcfc Fix problems found by travis. 2017-02-12 12:22:49 +01:00
Armando Lüscher
0ec9b9823f Add DNS API for cyon.ch 2017-02-12 12:22:48 +01:00
David Kerr
18a90734d9 Alternate backup cleanup after 180 days method. 2017-02-11 17:55:05 -05:00
David Kerr
a4b2cebef6 Make backup of certs on remote server optional. Defaults to yes. 2017-02-11 16:42:44 -05:00
David Kerr
68d708e56d Reduce and simplify number of exported variables. Also allow any cert file to
append to previous file.
2017-02-11 16:11:27 -05:00
David Kerr
e925ab0999 Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-02-11 14:37:02 -05:00
David Kerr
e3feac3fd8 Documentation updates 2017-02-08 21:13:00 -05:00
David Kerr
1a5989350f Some documentation in README 2017-02-08 21:02:00 -05:00
David Kerr
3365df7778 Make certificate domain name part of the backup directory name. 2017-02-08 10:15:39 -05:00
David Kerr
3be5a68e12 Rename sshdeploy.sh to ssh.sh 2017-02-07 13:05:22 -05:00
David Kerr
f158caa2eb Updates from code review 2017-02-06 21:49:20 -05:00
David Kerr
e02c94eb00 Merge remote-tracking branch 'upstream/master' into ssh-deploy 2017-02-06 21:31:55 -05:00
David Kerr
9507b121ac More selective pruning of certificate backup directories. 2017-02-05 15:34:03 -05:00
David Kerr
3812b275e9 Moving on to the next batch of travis errors. 2017-02-05 15:26:55 -05:00
David Kerr
6c1561f415 Grasping at straws now !! 2017-02-05 15:20:06 -05:00
David Kerr
9ab6353d73 Trying again. 2017-02-05 15:16:05 -05:00
David Kerr
ff60dc4d24 More Travis issues !!! 2017-02-05 15:12:23 -05:00
David Kerr
62e7d904b4 Travis errors 2017-02-05 15:02:59 -05:00
David Kerr
5d3de4b670 Additional info messages for backup management 2017-02-05 14:39:25 -05:00
David Kerr
7d75ad4c56 Backup old certificates before overwriting. Add userid export parameter.
And generate error if nothing to do at remote server.
2017-02-05 14:35:05 -05:00
nytral
e82ea94bb6 Merge remote-tracking branch 'upstream/master' 2017-02-05 13:56:10 +01:00
David Kerr
989651c23b Initial version 2017-02-04 23:17:24 -05:00
nytral
a9b15f1c36 Merge remote-tracking branch 'upstream/master' 2016-11-14 22:06:58 +01:00
nytral
764963e986 sync upstream 2016-11-09 16:25:24 +01:00
nytral
22b83d7630 _hmac use and generic date 2016-11-08 15:56:46 +01:00
nytral
0b5bff01e1 s/bash/sh/ 2016-11-08 14:13:05 +01:00
nytral
4fe7b6cd65 better bugfix 2016-11-07 22:16:53 +01:00
nytral
49e1f7d8bf bugfix 2016-11-07 22:16:00 +01:00
nytral
803fb243bf adding DNSMadeEasy API 2016-11-07 21:50:59 +01:00
122 changed files with 18932 additions and 1929 deletions

View File

@@ -1,5 +1,7 @@
<!--
请确保已经更新到最新的代码, 然后贴上来 `--debug 2` 的调试输出. 没有调试输出,我帮不了你.
我很忙, 每天可能只有 几秒钟 时间看你的 issue, 如果不按照我的要求写 issue, 你可能不会得到任何回复, 石沉大海.
请确保已经更新到最新的代码, 然后贴上来 `--debug 2` 的调试输出. 没有调试信息. 我做不了什么.
如何调试 https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh
If it is a bug report:

View File

@@ -1,9 +1,9 @@
<!--
Do NOT send pull request to `master` branch.
1. Do NOT send pull request to `master` branch.
Please send to `dev` branch instead.
Any PR to `master` branch will NOT be merged.
2. For dns api support, read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide
You will NOT get any review without passing this guide. You also need to fix the CI errors.
-->

View File

@@ -1,51 +1,36 @@
language: shell
sudo: required
dist: trusty
os:
- linux
- osx
services:
- docker
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";
brew update && brew install socat;
export PATH="/usr/local/opt/openssl@1.1/bin:$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 curl -sSL $SHFMT_URL -o ~/shfmt && chmod +x ~/shfmt && ~/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
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -e SC2181 **/*.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
- if [ "$TRAVIS_OS_NAME" = "linux" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./rundocker.sh testplat ubuntu:latest ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ACME_OPENSSL_BIN="$ACME_OPENSSL_BIN" ./letest.sh ; fi
matrix:
fast_finish: true

69
Dockerfile Normal file
View File

@@ -0,0 +1,69 @@
FROM alpine:3.10
RUN apk update -f \
&& apk --no-cache add -f \
openssl \
coreutils \
bind-tools \
curl \
socat \
tzdata \
oath-toolkit-oathtool \
tar \
&& rm -rf /var/cache/apk/*
ENV LE_CONFIG_HOME /acme.sh
ENV AUTO_UPGRADE 1
#Install
ADD ./ /install_acme.sh/
RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/
RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh && crontab -l | grep acme.sh | sed 's#> /dev/null##' | crontab -
RUN for verb in help \
version \
install \
uninstall \
upgrade \
issue \
signcsr \
deploy \
install-cert \
renew \
renew-all \
revoke \
remove \
list \
showcsr \
install-cronjob \
uninstall-cronjob \
cron \
toPkcs \
toPkcs8 \
update-account \
register-account \
create-account-key \
create-domain-key \
createCSR \
deactivate \
deactivate-account \
set-notify \
; do \
printf -- "%b" "#!/usr/bin/env sh\n/root/.acme.sh/acme.sh --${verb} --config-home /acme.sh \"\$@\"" >/usr/local/bin/--${verb} && chmod +x /usr/local/bin/--${verb} \
; done
RUN printf "%b" '#!'"/usr/bin/env sh\n \
if [ \"\$1\" = \"daemon\" ]; then \n \
trap \"echo stop && killall crond && exit 0\" SIGTERM SIGINT \n \
crond && while true; do sleep 1; done;\n \
else \n \
exec -- \"\$@\"\n \
fi" >/entry.sh && chmod +x /entry.sh
VOLUME /acme.sh
ENTRYPOINT ["/entry.sh"]
CMD ["--help"]

674
LICENSE.md Normal file
View File

@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

270
README.md
View File

@@ -1,60 +1,91 @@
# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)
[![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
- An ACME protocol client written purely in Shell (Unix shell) language.
- Full ACME protocol implementation.
- Support ACME v1 and ACME v2
- Support ACME v2 wildcard certs
- 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 the official Let's Encrypt client.
- Just one script to issue, renew and install your certificates automatically.
- DOES NOT require `root/sudoer` access.
- Docker friendly
- IPv6 support
- Cron job notifications for renewal or error etc.
It's probably the `easiest&smallest&smartest` shell script to automatically issue & renew the free certificates from Let's Encrypt.
It's probably the `easiest & smartest` shell script to automatically issue & renew the free certificates from Let's Encrypt.
Wiki: https://github.com/Neilpang/acme.sh/wiki
For Docker Fans: [acme.sh :two_hearts: Docker ](https://github.com/Neilpang/acme.sh/wiki/Run-acme.sh-in-docker)
Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
# [中文说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E)
# Who:
- [FreeBSD.org](https://blog.crashed.org/letsencrypt-in-freebsd-org/)
- [ruby-china.org](https://ruby-china.org/topics/31983)
- [Proxmox](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x_and_newer))
- [pfsense](https://github.com/pfsense/FreeBSD-ports/pull/89)
- [webfaction](https://community.webfaction.com/questions/19988/using-letsencrypt)
- [Loadbalancer.org](https://www.loadbalancer.org/blog/loadbalancer-org-with-lets-encrypt-quick-and-dirty)
- [discourse.org](https://meta.discourse.org/t/setting-up-lets-encrypt/40709)
- [Centminmod](https://centminmod.com/letsencrypt-acmetool-https.html)
- [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297)
- [archlinux](https://www.archlinux.org/packages/community/any/acme.sh)
- [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient)
- [CentOS Web Panel](http://centos-webpanel.com/)
- [lnmp.org](https://lnmp.org/)
- [more...](https://github.com/Neilpang/acme.sh/wiki/Blogs-and-tutorials)
# 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
|2|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/debian-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Debian
|3|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/centos-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|CentOS
|4|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/windows-cygwin.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included)
|5|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/freebsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|FreeBSD
|6|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/pfsense.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|pfsense
|7|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/opensuse-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|openSUSE
|8|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/alpine-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Alpine Linux (with curl)
|9|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/base-archlinux.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Archlinux
|10|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/fedora-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|fedora
|11|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/kalilinux-kali-linux-docker.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Kali Linux
|12|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/oraclelinux-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Oracle Linux
|13|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/proxmox.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Proxmox https://pve.proxmox.com/wiki/HTTPSCertificateConfiguration#Let.27s_Encrypt_using_acme.sh
|1|[![](https://neilpang.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Ubuntu
|2|[![](https://neilpang.github.io/acmetest/status/debian-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Debian
|3|[![](https://neilpang.github.io/acmetest/status/centos-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|CentOS
|4|[![](https://neilpang.github.io/acmetest/status/windows-cygwin.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included)
|5|[![](https://neilpang.github.io/acmetest/status/freebsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|FreeBSD
|6|[![](https://neilpang.github.io/acmetest/status/pfsense.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|pfsense
|7|[![](https://neilpang.github.io/acmetest/status/opensuse-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|openSUSE
|8|[![](https://neilpang.github.io/acmetest/status/alpine-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Alpine Linux (with curl)
|9|[![](https://neilpang.github.io/acmetest/status/base-archlinux.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Archlinux
|10|[![](https://neilpang.github.io/acmetest/status/fedora-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|fedora
|11|[![](https://neilpang.github.io/acmetest/status/kalilinux-kali-linux-docker.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Kali Linux
|12|[![](https://neilpang.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Oracle Linux
|13|[![](https://neilpang.github.io/acmetest/status/proxmox.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Proxmox https://pve.proxmox.com/wiki/HTTPSCertificateConfiguration#Let.27s_Encrypt_using_acme.sh
|14|-----| Cloud Linux https://github.com/Neilpang/le/issues/111
|15|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/openbsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|OpenBSD
|16|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/mageia.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Mageia
|15|[![](https://neilpang.github.io/acmetest/status/openbsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|OpenBSD
|16|[![](https://neilpang.github.io/acmetest/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
|18|[![](https://neilpang.github.io/acmetest/status/solaris.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|SunOS/Solaris
|19|[![](https://neilpang.github.io/acmetest/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 [weekly build project](https://github.com/Neilpang/acmetest):
https://github.com/Neilpang/acmetest
# Supported CA
- Letsencrypt.org CA(default)
- [BuyPass.com CA](https://github.com/Neilpang/acme.sh/wiki/BuyPass.com-CA)
- [Pebble strict Mode](https://github.com/letsencrypt/pebble)
# Supported modes
- Webroot mode
- Standalone mode
- Standalone tls-alpn mode
- Apache mode
- Nginx mode
- DNS mode
- [DNS alias mode](https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode)
- [Stateless mode](https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode)
@@ -108,7 +139,7 @@ Ok, you are ready to issue certs now.
Show help message:
```
```sh
root@v1:~# acme.sh -h
```
@@ -120,57 +151,71 @@ root@v1:~# acme.sh -h
acme.sh --issue -d example.com -w /home/wwwroot/example.com
```
or:
```bash
acme.sh --issue -d example.com -w /home/username/public_html
```
or:
```bash
acme.sh --issue -d example.com -w /var/www/html
```
**Example 2:** Multiple domains in the same cert.
```bash
acme.sh --issue -d example.com -d www.example.com -d cp.example.com -w /home/wwwroot/example.com
```
The parameter `/home/wwwroot/example.com` is the web root folder. You **MUST** have `write access` to this folder.
The parameter `/home/wwwroot/example.com` or `/home/username/public_html` or `/var/www/html` is the web root folder where you host your website files. You **MUST** have `write access` to this folder.
Second argument **"example.com"** is the main domain you want to issue the cert for.
You must have at least one domain there.
You must point and bind all the domains to the same webroot dir: `/home/wwwroot/example.com`.
Generated/issued certs will be placed in `~/.acme.sh/example.com/`
The certs will be placed in `~/.acme.sh/example.com/`
The issued cert will be renewed automatically every **60** days.
The certs will be renewed automatically every **60** days.
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
# 3. Install the issued cert to Apache/Nginx etc.
# 3. Install the cert to Apache/Nginx etc.
After you issue a cert, you probably want to install/copy the cert to your Apache/Nginx or other servers.
After the cert is generated, 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 --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 \
--cert-file /path/to/certfile/in/apache/cert.pem \
--key-file /path/to/keyfile/in/apache/key.pem \
--fullchain-file /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 \
--key-file /path/to/keyfile/in/nginx/key.pem \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd "service nginx force-reload"
```
Only the domain is required, all the other parameters are optional.
The ownership and permission info of existing files are preserved. You may want to precreate the files to have defined ownership and permission.
The ownership and permission info of existing files are preserved. You can pre-create the files to define the ownership and permission.
Install/copy the issued cert/key to the production Apache or Nginx path.
Install/copy the cert/key to the production Apache or Nginx path.
The cert will be `renewed every **60** days by default` (which is configurable). Once the cert is renewed, the Apache/Nginx service will be restarted automatically by the command: `service apache2 restart` or `service nginx restart`.
The cert will be renewed every **60** days by default (which is configurable). Once the cert is renewed, the Apache/Nginx service will be reloaded automatically by the command: `service apache2 force-reload` or `service nginx force-reload`.
**Please take care: The reloadcmd is very important. The cert can be automatically renewed, but, without a correct 'reloadcmd' the cert may not be flushed to your server(like nginx or apache), then your website will not be able to show renewed cert in 60 days.**
# 4. Use Standalone server to issue cert
**(requires you to be root/sudoer or have permission to listen on port 80 (TCP))**
@@ -183,17 +228,14 @@ acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
# 5. Use Standalone TLS server to issue cert
# 5. Use Standalone ssl 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.
Port `443` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again.
```bash
acme.sh --issue --tls -d example.com -d www.example.com -d cp.example.com
acme.sh --issue --alpn -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
@@ -205,20 +247,59 @@ More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
If you are running a web server, Apache or Nginx, it is recommended to use the `Webroot mode`.
Particularly, if you are running an Apache server, you should use Apache mode instead. This mode doesn't write any files to your web root folder.
Particularly, if you are running an Apache server, you can use Apache mode instead. This mode doesn't write any files to your web root folder.
Just set string "apache" as the second argument and it will force use of apache plugin automatically.
```
```sh
acme.sh --issue --apache -d example.com -d www.example.com -d cp.example.com
```
**This apache mode is only to issue the cert, it will not change your apache config files.
You will need to configure your website config files to use the cert by yourself.
We don't want to mess your apache server, don't worry.**
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
# 7. Use Nginx mode
# 7. Use DNS mode:
**(requires you to be root/sudoer, since it is required to interact with Nginx server)**
Support the `dns-01` challenge.
If you are running a web server, Apache or Nginx, it is recommended to use the `Webroot mode`.
Particularly, if you are running an nginx server, you can use nginx mode instead. This mode doesn't write any files to your web root folder.
Just set string "nginx" as the second argument.
It will configure nginx server automatically to verify the domain and then restore the nginx config to the original version.
So, the config is not changed.
```sh
acme.sh --issue --nginx -d example.com -d www.example.com -d cp.example.com
```
**This nginx mode is only to issue the cert, it will not change your nginx config files.
You will need to configure your website config files to use the cert by yourself.
We don't want to mess your nginx server, don't worry.**
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
# 8. Automatic DNS API integration
If your DNS provider supports API access, we can use that API to automatically issue the certs.
You don't have to do anything manually!
### Currently acme.sh supports most of the dns providers:
https://github.com/Neilpang/acme.sh/wiki/dnsapi
# 9. Use DNS manual mode:
See: https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode first.
If your dns provider doesn't support any api access, you can add the txt record by your hand.
```bash
acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com
@@ -226,7 +307,7 @@ acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com
You should get an output like below:
```
```sh
Add the following txt record:
Domain:_acme-challenge.example.com
Txt value:9ihDbjYfTExAYeDs4DBUeuTo18KBzwvTEjUnSwd32-c
@@ -244,53 +325,23 @@ Then just rerun with `renew` argument:
acme.sh --renew -d example.com
```
Ok, it's finished.
Ok, it's done.
**Take care, this is dns manual mode, it can not be renewed automatically. you will have to add a new txt record to your domain by your hand when you renew your cert.**
# 8. Automatic DNS API integration
**Please use dns api mode instead.**
If your DNS provider supports API access, we can use that API to automatically issue the certs.
You don't have to do anything manually!
### Currently acme.sh supports:
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 coming soon...**
If your DNS provider is not on the supported list above, you can write your own DNS API script easily. If you do, please consider submitting a [Pull Request](https://github.com/Neilpang/acme.sh/pulls) and contribute it to the project.
For more details: [How to use DNS API](dnsapi)
# 9. Issue ECC certificates
# 10. Issue ECC certificates
`Let's Encrypt` can now issue **ECDSA** certificates.
And we support them too!
Just set the `length` parameter with a prefix `ec-`.
Just set the `keylength` parameter with a prefix `ec-`.
For example:
### Single domain ECC cerfiticate
### Single domain ECC certificate
```bash
acme.sh --issue -w /home/wwwroot/example.com -d example.com --keylength ec-256
@@ -302,7 +353,7 @@ acme.sh --issue -w /home/wwwroot/example.com -d example.com --keylength ec-256
acme.sh --issue -w /home/wwwroot/example.com -d example.com -d www.example.com --keylength ec-256
```
Please look at the last parameter above.
Please look at the `keylength` parameter above.
Valid values are:
@@ -311,36 +362,60 @@ Valid values are:
3. **ec-521 (secp521r1, "ECDSA P-521", which is not supported by Let's Encrypt yet.)**
# 10. How to renew the issued certs
# 11. Issue Wildcard certificates
It's simple, just give a wildcard domain as the `-d` parameter.
```sh
acme.sh --issue -d example.com -d '*.example.com' --dns dns_cf
```
# 12. How to renew the certs
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:
However, you can also force to renew a cert:
```
```sh
acme.sh --renew -d example.com --force
```
or, for ECC cert:
```
```sh
acme.sh --renew -d example.com --force --ecc
```
# 11. How to upgrade `acme.sh`
# 13. How to stop cert renewal
To stop renewal of a cert, you can execute the following to remove the cert from the renewal list:
```sh
acme.sh --remove -d example.com [--ecc]
```
The cert/key file is not removed from the disk.
You can remove the respective directory (e.g. `~/.acme.sh/example.com`) by yourself.
# 14. How to upgrade `acme.sh`
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:
```
```sh
acme.sh --upgrade
```
You can also enable auto upgrade:
```
```sh
acme.sh --upgrade --auto-upgrade
```
@@ -348,31 +423,35 @@ Then **acme.sh** will be kept up to date automatically.
Disable auto upgrade:
```
```sh
acme.sh --upgrade --auto-upgrade 0
```
# 12. Issue a cert from an existing CSR
# 15. Issue a cert from an existing CSR
https://github.com/Neilpang/acme.sh/wiki/Issue-a-cert-from-existing-CSR
# Under the Hood
# 16. Send notifications in cronjob
https://github.com/Neilpang/acme.sh/wiki/notify
# 17. Under the Hood
Speak ACME language using shell, directly to "Let's Encrypt".
TODO:
# Acknowledgments
# 18. Acknowledgments
1. Acme-tiny: https://github.com/diafygi/acme-tiny
2. ACME protocol: https://github.com/ietf-wg-acme/acme
3. Certbot: https://github.com/certbot/certbot
# License & Others
# 19. License & Others
License is GPLv3
@@ -381,8 +460,9 @@ Please Star and Fork me.
[Issues](https://github.com/Neilpang/acme.sh/issues) and [pull requests](https://github.com/Neilpang/acme.sh/pulls) are welcome.
# Donate
# 20. Donate
Your donation makes **acme.sh** better:
1. PayPal: donate@acme.sh
1. PayPal/Alipay(支付宝)/Wechat(微信): [https://donate.acme.sh/](https://donate.acme.sh/)
[Donate List](https://github.com/Neilpang/acme.sh/wiki/Donate-list)

3642
acme.sh

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,6 @@
# 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)
deploy hook usage:
https://github.com/Neilpang/acme.sh/wiki/deployhooks

26
deploy/apache.sh Normal file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env sh
#Here is a script to deploy cert to apache server.
#returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
apache_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 "Deploy cert to apache server, Not implemented yet"
return 1
}

62
deploy/cpanel_uapi.sh Normal file
View File

@@ -0,0 +1,62 @@
#!/usr/bin/env sh
# Here is the script to deploy the cert to your cpanel using the cpanel API.
# Uses command line uapi. --user option is needed only if run as root.
# Returns 0 when success.
#
# Please note that I am no longer using Github. If you want to report an issue
# or contact me, visit https://forum.webseodesigners.com/web-design-seo-and-hosting-f16/
#
# Written by Santeri Kannisto <santeri.kannisto@webseodesigners.com>
# Public domain, 2017-2018
#export DEPLOY_CPANEL_USER=myusername
######## Public functions #####################
#domain keyfile certfile cafile fullchain
cpanel_uapi_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"
if ! _exists uapi; then
_err "The command uapi is not found."
return 1
fi
# read cert and key files and urlencode both
_cert=$(_url_encode <"$_ccert")
_key=$(_url_encode <"$_ckey")
_debug _cert "$_cert"
_debug _key "$_key"
if [ "$(id -u)" = 0 ]; then
if [ -z "$DEPLOY_CPANEL_USER" ]; then
_err "It seems that you are root, please define the target user name: export DEPLOY_CPANEL_USER=username"
return 1
fi
_savedomainconf DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER"
_response=$(uapi --user="$DEPLOY_CPANEL_USER" SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
else
_response=$(uapi SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
fi
error_response="status: 0"
if test "${_response#*$error_response}" != "$_response"; then
_err "Error in deploying certificate:"
_err "$_response"
return 1
fi
_debug response "$_response"
_info "Certificate successfully deployed"
return 0
}

285
deploy/docker.sh Executable file
View File

@@ -0,0 +1,285 @@
#!/usr/bin/env sh
#DEPLOY_DOCKER_CONTAINER_LABEL="xxxxxxx"
#DEPLOY_DOCKER_CONTAINER_KEY_FILE="/path/to/key.pem"
#DEPLOY_DOCKER_CONTAINER_CERT_FILE="/path/to/cert.pem"
#DEPLOY_DOCKER_CONTAINER_CA_FILE="/path/to/ca.pem"
#DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/path/to/fullchain.pem"
#DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="service nginx force-reload"
_DEPLOY_DOCKER_WIKI="https://github.com/Neilpang/acme.sh/wiki/deploy-to-docker-containers"
_DOCKER_HOST_DEFAULT="/var/run/docker.sock"
docker_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_getdeployconf DEPLOY_DOCKER_CONTAINER_LABEL
_debug2 DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL"
if [ -z "$DEPLOY_DOCKER_CONTAINER_LABEL" ]; then
_err "The DEPLOY_DOCKER_CONTAINER_LABEL variable is not defined, we use this label to find the container."
_err "See: $_DEPLOY_DOCKER_WIKI"
fi
_savedeployconf DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL"
if [ "$DOCKER_HOST" ]; then
_saveaccountconf DOCKER_HOST "$DOCKER_HOST"
fi
if _exists docker && docker version | grep -i docker >/dev/null; then
_info "Using docker command"
export _USE_DOCKER_COMMAND=1
else
export _USE_DOCKER_COMMAND=
fi
export _USE_UNIX_SOCKET=
if [ -z "$_USE_DOCKER_COMMAND" ]; then
export _USE_REST=
if [ "$DOCKER_HOST" ]; then
_debug "Try use docker host: $DOCKER_HOST"
export _USE_REST=1
else
export _DOCKER_SOCK="$_DOCKER_HOST_DEFAULT"
_debug "Try use $_DOCKER_SOCK"
if [ ! -e "$_DOCKER_SOCK" ] || [ ! -w "$_DOCKER_SOCK" ]; then
_err "$_DOCKER_SOCK is not available"
return 1
fi
export _USE_UNIX_SOCKET=1
if ! _exists "curl"; then
_err "Please install curl first."
_err "We need curl to work."
return 1
fi
if ! _check_curl_version; then
return 1
fi
fi
fi
_getdeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE
_debug2 DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"
if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then
_savedeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"
fi
_getdeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE
_debug2 DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"
if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then
_savedeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"
fi
_getdeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE
_debug2 DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE"
if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then
_savedeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE"
fi
_getdeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE
_debug2 DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"
if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then
_savedeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"
fi
_getdeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD
_debug2 DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then
_savedeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
fi
_cid="$(_get_id "$DEPLOY_DOCKER_CONTAINER_LABEL")"
_info "Container id: $_cid"
if [ -z "$_cid" ]; then
_err "can not find container id"
return 1
fi
if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then
if ! _docker_cp "$_cid" "$_ckey" "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"; then
return 1
fi
fi
if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then
if ! _docker_cp "$_cid" "$_ccert" "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"; then
return 1
fi
fi
if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then
if ! _docker_cp "$_cid" "$_cca" "$DEPLOY_DOCKER_CONTAINER_CA_FILE"; then
return 1
fi
fi
if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then
if ! _docker_cp "$_cid" "$_cfullchain" "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"; then
return 1
fi
fi
if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then
if ! _docker_exec "$_cid" "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"; then
return 1
fi
fi
return 0
}
#label
_get_id() {
_label="$1"
if [ "$_USE_DOCKER_COMMAND" ]; then
docker ps -f label="$_label" --format "{{.ID}}"
elif [ "$_USE_REST" ]; then
_err "Not implemented yet."
return 1
elif [ "$_USE_UNIX_SOCKET" ]; then
_req="{\"label\":[\"$_label\"]}"
_debug2 _req "$_req"
_req="$(printf "%s" "$_req" | _url_encode)"
_debug2 _req "$_req"
listjson="$(_curl_unix_sock "${_DOCKER_SOCK:-$_DOCKER_HOST_DEFAULT}" GET "/containers/json?filters=$_req")"
_debug2 "listjson" "$listjson"
echo "$listjson" | tr '{,' '\n' | grep -i '"id":' | _head_n 1 | cut -d '"' -f 4
else
_err "Not implemented yet."
return 1
fi
}
#id cmd
_docker_exec() {
_eargs="$*"
_debug2 "_docker_exec $_eargs"
_dcid="$1"
shift
if [ "$_USE_DOCKER_COMMAND" ]; then
docker exec -i "$_dcid" sh -c "$*"
elif [ "$_USE_REST" ]; then
_err "Not implemented yet."
return 1
elif [ "$_USE_UNIX_SOCKET" ]; then
_cmd="$*"
#_cmd="$(printf "%s" "$_cmd" | sed 's/ /","/g')"
_debug2 _cmd "$_cmd"
#create exec instance:
cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"sh\", \"-c\", \"$_cmd\"]}")"
_debug2 cjson "$cjson"
execid="$(echo "$cjson" | cut -d '"' -f 4)"
_debug execid "$execid"
ejson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/exec/$execid/start" "{\"Detach\": false,\"Tty\": false}")"
_debug2 ejson "$ejson"
if [ "$ejson" ]; then
_err "$ejson"
return 1
fi
else
_err "Not implemented yet."
return 1
fi
}
#id from to
_docker_cp() {
_dcid="$1"
_from="$2"
_to="$3"
_info "Copying file from $_from to $_to"
_dir="$(dirname "$_to")"
_debug2 _dir "$_dir"
if ! _docker_exec "$_dcid" mkdir -p "$_dir"; then
_err "Can not create dir: $_dir"
return 1
fi
if [ "$_USE_DOCKER_COMMAND" ]; then
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
_docker_exec "$_dcid" tee "$_to" <"$_from"
else
_docker_exec "$_dcid" tee "$_to" <"$_from" >/dev/null
fi
if [ "$?" = "0" ]; then
_info "Success"
return 0
else
_info "Error"
return 1
fi
elif [ "$_USE_REST" ]; then
_err "Not implemented yet."
return 1
elif [ "$_USE_UNIX_SOCKET" ]; then
_frompath="$_from"
if _startswith "$_frompath" '/'; then
_frompath="$(echo "$_from" | cut -b 2-)" #remove the first '/' char
fi
_debug2 "_frompath" "$_frompath"
_toname="$(basename "$_to")"
_debug2 "_toname" "$_toname"
if ! tar --transform="s,$_frompath,$_toname," -cz "$_from" 2>/dev/null | _curl_unix_sock "$_DOCKER_SOCK" PUT "/containers/$_dcid/archive?noOverwriteDirNonDir=1&path=$(printf "%s" "$_dir" | _url_encode)" '@-' "Content-Type: application/octet-stream"; then
_err "copy error"
return 1
fi
return 0
else
_err "Not implemented yet."
return 1
fi
}
#sock method endpoint data content-type
_curl_unix_sock() {
_socket="$1"
_method="$2"
_endpoint="$3"
_data="$4"
_ctype="$5"
if [ -z "$_ctype" ]; then
_ctype="Content-Type: application/json"
fi
_debug _data "$_data"
_debug2 "url" "http://localhost$_endpoint"
if [ "$_CURL_NO_HOST" ]; then
_cux_url="http:$_endpoint"
else
_cux_url="http://localhost$_endpoint"
fi
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
curl -vvv --silent --unix-socket "$_socket" -X "$_method" --data-binary "$_data" --header "$_ctype" "$_cux_url"
else
curl --silent --unix-socket "$_socket" -X "$_method" --data-binary "$_data" --header "$_ctype" "$_cux_url"
fi
}
_check_curl_version() {
_cversion="$(curl -V | grep '^curl ' | cut -d ' ' -f 2)"
_debug2 "_cversion" "$_cversion"
_major="$(_getfield "$_cversion" 1 '.')"
_debug2 "_major" "$_major"
_minor="$(_getfield "$_cversion" 2 '.')"
_debug2 "_minor" "$_minor"
if [ "$_major$_minor" -lt "740" ]; then
_err "curl v$_cversion doesn't support unit socket"
return 1
fi
if [ "$_major$_minor" -lt "750" ]; then
_debug "Use short host name"
export _CURL_NO_HOST=1
else
export _CURL_NO_HOST=
fi
return 0
}

View File

@@ -1,16 +1,13 @@
#!/usr/bin/env sh
#Here is the script to deploy the cert to your cpanel account by the cpanel APIs.
#Here is a script to deploy cert to dovecot server.
#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() {
dovecot_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"

114
deploy/exim4.sh Normal file
View File

@@ -0,0 +1,114 @@
#!/usr/bin/env sh
#Here is a script to deploy cert to exim4 server.
#returns 0 means success, otherwise error.
#DEPLOY_EXIM4_CONF="/etc/exim/exim.conf"
#DEPLOY_EXIM4_RELOAD="service exim4 restart"
######## Public functions #####################
#domain keyfile certfile cafile fullchain
exim4_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"
_ssl_path="/etc/acme.sh/exim4"
if ! mkdir -p "$_ssl_path"; then
_err "Can not create folder:$_ssl_path"
return 1
fi
_info "Copying key and cert"
_real_key="$_ssl_path/exim4.key"
if ! cat "$_ckey" >"$_real_key"; then
_err "Error: write key file to: $_real_key"
return 1
fi
_real_fullchain="$_ssl_path/exim4.pem"
if ! cat "$_cfullchain" >"$_real_fullchain"; then
_err "Error: write key file to: $_real_fullchain"
return 1
fi
DEFAULT_EXIM4_RELOAD="service exim4 restart"
_reload="${DEPLOY_EXIM4_RELOAD:-$DEFAULT_EXIM4_RELOAD}"
if [ -z "$IS_RENEW" ]; then
DEFAULT_EXIM4_CONF="/etc/exim/exim.conf"
if [ ! -f "$DEFAULT_EXIM4_CONF" ]; then
DEFAULT_EXIM4_CONF="/etc/exim4/exim4.conf.template"
fi
_exim4_conf="${DEPLOY_EXIM4_CONF:-$DEFAULT_EXIM4_CONF}"
_debug _exim4_conf "$_exim4_conf"
if [ ! -f "$_exim4_conf" ]; then
if [ -z "$DEPLOY_EXIM4_CONF" ]; then
_err "exim4 conf is not found, please define DEPLOY_EXIM4_CONF"
return 1
else
_err "It seems that the specified exim4 conf is not valid, please check."
return 1
fi
fi
if [ ! -w "$_exim4_conf" ]; then
_err "The file $_exim4_conf is not writable, please change the permission."
return 1
fi
_backup_conf="$DOMAIN_BACKUP_PATH/exim4.conf.bak"
_info "Backup $_exim4_conf to $_backup_conf"
cp "$_exim4_conf" "$_backup_conf"
_info "Modify exim4 conf: $_exim4_conf"
if _setopt "$_exim4_conf" "tls_certificate" "=" "$_real_fullchain" \
&& _setopt "$_exim4_conf" "tls_privatekey" "=" "$_real_key"; then
_info "Set config success!"
else
_err "Config exim4 server error, please report bug to us."
_info "Restoring exim4 conf"
if cat "$_backup_conf" >"$_exim4_conf"; then
_info "Restore conf success"
eval "$_reload"
else
_err "Oops, error restore exim4 conf, please report bug to us."
fi
return 1
fi
fi
_info "Run reload: $_reload"
if eval "$_reload"; then
_info "Reload success!"
if [ "$DEPLOY_EXIM4_CONF" ]; then
_savedomainconf DEPLOY_EXIM4_CONF "$DEPLOY_EXIM4_CONF"
else
_cleardomainconf DEPLOY_EXIM4_CONF
fi
if [ "$DEPLOY_EXIM4_RELOAD" ]; then
_savedomainconf DEPLOY_EXIM4_RELOAD "$DEPLOY_EXIM4_RELOAD"
else
_cleardomainconf DEPLOY_EXIM4_RELOAD
fi
return 0
else
_err "Reload error, restoring"
if cat "$_backup_conf" >"$_exim4_conf"; then
_info "Restore conf success"
eval "$_reload"
else
_err "Oops, error restore exim4 conf, please report bug to us."
fi
return 1
fi
return 0
}

114
deploy/fritzbox.sh Normal file
View File

@@ -0,0 +1,114 @@
#!/usr/bin/env sh
#Here is a script to deploy cert to an AVM FRITZ!Box router.
#returns 0 means success, otherwise error.
#DEPLOY_FRITZBOX_USERNAME="username"
#DEPLOY_FRITZBOX_PASSWORD="password"
#DEPLOY_FRITZBOX_URL="https://fritz.box"
# Kudos to wikrie at Github for his FRITZ!Box update script:
# https://gist.github.com/wikrie/f1d5747a714e0a34d0582981f7cb4cfb
######## Public functions #####################
#domain keyfile certfile cafile fullchain
fritzbox_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"
if ! _exists iconv; then
if ! _exists perl; then
_err "iconv or perl not found"
return 1
fi
fi
_fritzbox_username="${DEPLOY_FRITZBOX_USERNAME}"
_fritzbox_password="${DEPLOY_FRITZBOX_PASSWORD}"
_fritzbox_url="${DEPLOY_FRITZBOX_URL}"
_debug _fritzbox_url "$_fritzbox_url"
_debug _fritzbox_username "$_fritzbox_username"
_secure_debug _fritzbox_password "$_fritzbox_password"
if [ -z "$_fritzbox_username" ]; then
_err "FRITZ!Box username is not found, please define DEPLOY_FRITZBOX_USERNAME."
return 1
fi
if [ -z "$_fritzbox_password" ]; then
_err "FRITZ!Box password is not found, please define DEPLOY_FRITZBOX_PASSWORD."
return 1
fi
if [ -z "$_fritzbox_url" ]; then
_err "FRITZ!Box url is not found, please define DEPLOY_FRITZBOX_URL."
return 1
fi
_saveaccountconf DEPLOY_FRITZBOX_USERNAME "${_fritzbox_username}"
_saveaccountconf DEPLOY_FRITZBOX_PASSWORD "${_fritzbox_password}"
_saveaccountconf DEPLOY_FRITZBOX_URL "${_fritzbox_url}"
# Do not check for a valid SSL certificate, because initially the cert is not valid, so it could not install the LE generated certificate
export HTTPS_INSECURE=1
_info "Log in to the FRITZ!Box"
_fritzbox_challenge="$(_get "${_fritzbox_url}/login_sid.lua" | sed -e 's/^.*<Challenge>//' -e 's/<\/Challenge>.*$//')"
if _exists iconv; then
_fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | iconv -f ASCII -t UTF16LE | md5sum | awk '{print $1}')"
else
_fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | perl -p -e 'use Encode qw/encode/; print encode("UTF-16LE","$_"); $_="";' | md5sum | awk '{print $1}')"
fi
_fritzbox_sid="$(_get "${_fritzbox_url}/login_sid.lua?sid=0000000000000000&username=${_fritzbox_username}&response=${_fritzbox_challenge}-${_fritzbox_hash}" | sed -e 's/^.*<SID>//' -e 's/<\/SID>.*$//')"
if [ -z "${_fritzbox_sid}" ] || [ "${_fritzbox_sid}" = "0000000000000000" ]; then
_err "Logging in to the FRITZ!Box failed. Please check username, password and URL."
return 1
fi
_info "Generate form POST request"
_post_request="$(_mktemp)"
_post_boundary="---------------------------$(date +%Y%m%d%H%M%S)"
# _CERTPASSWORD_ is unset because Let's Encrypt certificates don't have a password. But if they ever do, here's the place to use it!
_CERTPASSWORD_=
{
printf -- "--"
printf -- "%s\r\n" "${_post_boundary}"
printf "Content-Disposition: form-data; name=\"sid\"\r\n\r\n%s\r\n" "${_fritzbox_sid}"
printf -- "--"
printf -- "%s\r\n" "${_post_boundary}"
printf "Content-Disposition: form-data; name=\"BoxCertPassword\"\r\n\r\n%s\r\n" "${_CERTPASSWORD_}"
printf -- "--"
printf -- "%s\r\n" "${_post_boundary}"
printf "Content-Disposition: form-data; name=\"BoxCertImportFile\"; filename=\"BoxCert.pem\"\r\n"
printf "Content-Type: application/octet-stream\r\n\r\n"
cat "${_ckey}" "${_cfullchain}"
printf "\r\n"
printf -- "--"
printf -- "%s--" "${_post_boundary}"
} >>"${_post_request}"
_info "Upload certificate to the FRITZ!Box"
export _H1="Content-type: multipart/form-data boundary=${_post_boundary}"
_post "$(cat "${_post_request}")" "${_fritzbox_url}/cgi-bin/firmwarecfg" | grep SSL
retval=$?
if [ $retval = 0 ]; then
_info "Upload successful"
else
_err "Upload failed"
fi
rm "${_post_request}"
return $retval
}

140
deploy/gcore_cdn.sh Normal file
View File

@@ -0,0 +1,140 @@
#!/usr/bin/env sh
# Here is the script to deploy the cert to G-Core CDN service (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/).
# Uses command line curl for send requests and jq for parse responses.
# Returns 0 when success.
#
# Written by temoffey <temofffey@gmail.com>
# Public domain, 2019
#export DEPLOY_GCORE_CDN_USERNAME=myusername
#export DEPLOY_GCORE_CDN_PASSWORD=mypassword
######## Public functions #####################
#domain keyfile certfile cafile fullchain
gcore_cdn_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"
_fullchain=$(tr '\r\n' '*#' <"$_cfullchain" | sed 's/*#/#/g;s/##/#/g;s/#/\\n/g')
_key=$(tr '\r\n' '*#' <"$_ckey" | sed 's/*#/#/g;s/#/\\n/g')
_debug _fullchain "$_fullchain"
_debug _key "$_key"
if [ -z "$DEPLOY_GCORE_CDN_USERNAME" ]; then
if [ -z "$Le_Deploy_gcore_cdn_username" ]; then
_err "Please define the target username: export DEPLOY_GCORE_CDN_USERNAME=username"
return 1
fi
else
Le_Deploy_gcore_cdn_username="$DEPLOY_GCORE_CDN_USERNAME"
_savedomainconf Le_Deploy_gcore_cdn_username "$Le_Deploy_gcore_cdn_username"
fi
if [ -z "$DEPLOY_GCORE_CDN_PASSWORD" ]; then
if [ -z "$Le_Deploy_gcore_cdn_password" ]; then
_err "Please define the target password: export DEPLOY_GCORE_CDN_PASSWORD=password"
return 1
fi
else
Le_Deploy_gcore_cdn_password="$DEPLOY_GCORE_CDN_PASSWORD"
_savedomainconf Le_Deploy_gcore_cdn_password "$Le_Deploy_gcore_cdn_password"
fi
_info "Get authorization token"
_request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}"
_debug _request "$_request"
export _H1="Content-Type:application/json"
_response=$(_post "$_request" "https://api.gcdn.co/auth/signin")
_debug _response "$_response"
_regex=".*\"token\":\"\([-._0-9A-Za-z]*\)\".*$"
_debug _regex "$_regex"
_token=$(echo "$_response" | sed -n "s/$_regex/\1/p")
_debug _token "$_token"
if [ -z "$_token" ]; then
_err "Error G-Core Labs API authorization"
return 1
fi
_info "Find CDN resource with cname $_cdomain"
export _H2="Authorization:Token $_token"
_response=$(_get "https://api.gcdn.co/resources")
_debug _response "$_response"
_regex=".*(\"id\".*?\"cname\":\"$_cdomain\".*?})"
_regex="^.*\"cname\":\"$_cdomain\".*$"
_debug _regex "$_regex"
_resource=$(echo "$_response" | sed 's/},{/},\n{/g' | _egrep_o "$_regex")
_debug _resource "$_resource"
_regex=".*\"id\":\([0-9]*\),.*$"
_debug _regex "$_regex"
_resourceId=$(echo "$_resource" | sed -n "s/$_regex/\1/p")
_debug _resourceId "$_resourceId"
_regex=".*\"sslData\":\([0-9]*\)}.*$"
_debug _regex "$_regex"
_sslDataOld=$(echo "$_resource" | sed -n "s/$_regex/\1/p")
_debug _sslDataOld "$_sslDataOld"
_regex=".*\"originGroup\":\([0-9]*\),.*$"
_debug _regex "$_regex"
_originGroup=$(echo "$_resource" | sed -n "s/$_regex/\1/p")
_debug _originGroup "$_originGroup"
if [ -z "$_resourceId" ] || [ -z "$_originGroup" ]; then
_err "Not found CDN resource with cname $_cdomain"
return 1
fi
_info "Add new SSL certificate"
_date=$(date "+%d.%m.%Y %H:%M:%S")
_request="{\"name\":\"$_cdomain ($_date)\",\"sslCertificate\":\"$_fullchain\",\"sslPrivateKey\":\"$_key\"}"
_debug _request "$_request"
_response=$(_post "$_request" "https://api.gcdn.co/sslData")
_debug _response "$_response"
_regex=".*\"id\":\([0-9]*\),.*$"
_debug _regex "$_regex"
_sslDataAdd=$(echo "$_response" | sed -n "s/$_regex/\1/p")
_debug _sslDataAdd "$_sslDataAdd"
if [ -z "$_sslDataAdd" ]; then
_err "Error new SSL certificate add"
return 1
fi
_info "Update CDN resource"
_request="{\"originGroup\":$_originGroup,\"sslData\":$_sslDataAdd}"
_debug _request "$_request"
_response=$(_post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT")
_debug _response "$_response"
_regex=".*\"sslData\":\([0-9]*\)}.*$"
_debug _regex "$_regex"
_sslDataNew=$(echo "$_response" | sed -n "s/$_regex/\1/p")
_debug _sslDataNew "$_sslDataNew"
if [ "$_sslDataNew" != "$_sslDataAdd" ]; then
_err "Error CDN resource update"
return 1
fi
if [ -z "$_sslDataOld" ] || [ "$_sslDataOld" = "null" ]; then
_info "Not found old SSL certificate"
else
_info "Delete old SSL certificate"
_response=$(_post '' "https://api.gcdn.co/sslData/$_sslDataOld" '' "DELETE")
_debug _response "$_response"
fi
_info "Certificate successfully deployed"
return 0
}

80
deploy/gitlab.sh Normal file
View File

@@ -0,0 +1,80 @@
#!/usr/bin/env sh
# Script to deploy certificate to a Gitlab hosted page
# The following variables exported from environment will be used.
# If not set then values previously saved in domain.conf file are used.
# All the variables are required
# export GITLAB_TOKEN="xxxxxxx"
# export GITLAB_PROJECT_ID=012345
# export GITLAB_DOMAIN="mydomain.com"
gitlab_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"
if [ -z "$GITLAB_TOKEN" ]; then
if [ -z "$Le_Deploy_gitlab_token" ]; then
_err "GITLAB_TOKEN not defined."
return 1
fi
else
Le_Deploy_gitlab_token="$GITLAB_TOKEN"
_savedomainconf Le_Deploy_gitlab_token "$Le_Deploy_gitlab_token"
fi
if [ -z "$GITLAB_PROJECT_ID" ]; then
if [ -z "$Le_Deploy_gitlab_project_id" ]; then
_err "GITLAB_PROJECT_ID not defined."
return 1
fi
else
Le_Deploy_gitlab_project_id="$GITLAB_PROJECT_ID"
_savedomainconf Le_Deploy_gitlab_project_id "$Le_Deploy_gitlab_project_id"
fi
if [ -z "$GITLAB_DOMAIN" ]; then
if [ -z "$Le_Deploy_gitlab_domain" ]; then
_err "GITLAB_DOMAIN not defined."
return 1
fi
else
Le_Deploy_gitlab_domain="$GITLAB_DOMAIN"
_savedomainconf Le_Deploy_gitlab_domain "$Le_Deploy_gitlab_domain"
fi
string_fullchain=$(_url_encode <"$_cfullchain")
string_key=$(_url_encode <"$_ckey")
body="certificate=$string_fullchain&key=$string_key"
export _H1="PRIVATE-TOKEN: $Le_Deploy_gitlab_token"
gitlab_url="https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain"
_response=$(_post "$body" "$gitlab_url" 0 PUT | _dbase64 "multiline")
error_response="error"
if test "${_response#*$error_response}" != "$_response"; then
_err "Error in deploying certificate:"
_err "$_response"
return 1
fi
_debug response "$_response"
_info "Certificate successfully deployed"
return 0
}

272
deploy/haproxy.sh Normal file
View File

@@ -0,0 +1,272 @@
#!/usr/bin/env sh
# Script for acme.sh to deploy certificates to haproxy
#
# The following variables can be exported:
#
# export DEPLOY_HAPROXY_PEM_NAME="${domain}.pem"
#
# Defines the name of the PEM file.
# Defaults to "<domain>.pem"
#
# export DEPLOY_HAPROXY_PEM_PATH="/etc/haproxy"
#
# Defines location of PEM file for HAProxy.
# Defaults to /etc/haproxy
#
# export DEPLOY_HAPROXY_RELOAD="systemctl reload haproxy"
#
# OPTIONAL: Reload command used post deploy
# This defaults to be a no-op (ie "true").
# It is strongly recommended to set this something that makes sense
# for your distro.
#
# export DEPLOY_HAPROXY_ISSUER="no"
#
# OPTIONAL: Places CA file as "${DEPLOY_HAPROXY_PEM}.issuer"
# Note: Required for OCSP stapling to work
#
# export DEPLOY_HAPROXY_BUNDLE="no"
#
# OPTIONAL: Deploy this certificate as part of a multi-cert bundle
# This adds a suffix to the certificate based on the certificate type
# eg RSA certificates will have .rsa as a suffix to the file name
# HAProxy will load all certificates and provide one or the other
# depending on client capabilities
# Note: This functionality requires HAProxy was compiled against
# a version of OpenSSL that supports this.
#
######## Public functions #####################
#domain keyfile certfile cafile fullchain
haproxy_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
# Some defaults
DEPLOY_HAPROXY_PEM_PATH_DEFAULT="/etc/haproxy"
DEPLOY_HAPROXY_PEM_NAME_DEFAULT="${_cdomain}.pem"
DEPLOY_HAPROXY_BUNDLE_DEFAULT="no"
DEPLOY_HAPROXY_ISSUER_DEFAULT="no"
DEPLOY_HAPROXY_RELOAD_DEFAULT="true"
if [ -f "${DOMAIN_CONF}" ]; then
# shellcheck disable=SC1090
. "${DOMAIN_CONF}"
fi
_debug _cdomain "${_cdomain}"
_debug _ckey "${_ckey}"
_debug _ccert "${_ccert}"
_debug _cca "${_cca}"
_debug _cfullchain "${_cfullchain}"
# PEM_PATH is optional. If not provided then assume "${DEPLOY_HAPROXY_PEM_PATH_DEFAULT}"
if [ -n "${DEPLOY_HAPROXY_PEM_PATH}" ]; then
Le_Deploy_haproxy_pem_path="${DEPLOY_HAPROXY_PEM_PATH}"
_savedomainconf Le_Deploy_haproxy_pem_path "${Le_Deploy_haproxy_pem_path}"
elif [ -z "${Le_Deploy_haproxy_pem_path}" ]; then
Le_Deploy_haproxy_pem_path="${DEPLOY_HAPROXY_PEM_PATH_DEFAULT}"
fi
# Ensure PEM_PATH exists
if [ -d "${Le_Deploy_haproxy_pem_path}" ]; then
_debug "PEM_PATH ${Le_Deploy_haproxy_pem_path} exists"
else
_err "PEM_PATH ${Le_Deploy_haproxy_pem_path} does not exist"
return 1
fi
# PEM_NAME is optional. If not provided then assume "${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}"
if [ -n "${DEPLOY_HAPROXY_PEM_NAME}" ]; then
Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME}"
_savedomainconf Le_Deploy_haproxy_pem_name "${Le_Deploy_haproxy_pem_name}"
elif [ -z "${Le_Deploy_haproxy_pem_name}" ]; then
Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}"
fi
# BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}"
if [ -n "${DEPLOY_HAPROXY_BUNDLE}" ]; then
Le_Deploy_haproxy_bundle="${DEPLOY_HAPROXY_BUNDLE}"
_savedomainconf Le_Deploy_haproxy_bundle "${Le_Deploy_haproxy_bundle}"
elif [ -z "${Le_Deploy_haproxy_bundle}" ]; then
Le_Deploy_haproxy_bundle="${DEPLOY_HAPROXY_BUNDLE_DEFAULT}"
fi
# ISSUER is optional. If not provided then assume "${DEPLOY_HAPROXY_ISSUER_DEFAULT}"
if [ -n "${DEPLOY_HAPROXY_ISSUER}" ]; then
Le_Deploy_haproxy_issuer="${DEPLOY_HAPROXY_ISSUER}"
_savedomainconf Le_Deploy_haproxy_issuer "${Le_Deploy_haproxy_issuer}"
elif [ -z "${Le_Deploy_haproxy_issuer}" ]; then
Le_Deploy_haproxy_issuer="${DEPLOY_HAPROXY_ISSUER_DEFAULT}"
fi
# RELOAD is optional. If not provided then assume "${DEPLOY_HAPROXY_RELOAD_DEFAULT}"
if [ -n "${DEPLOY_HAPROXY_RELOAD}" ]; then
Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD}"
_savedomainconf Le_Deploy_haproxy_reload "${Le_Deploy_haproxy_reload}"
elif [ -z "${Le_Deploy_haproxy_reload}" ]; then
Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD_DEFAULT}"
fi
# Set the suffix depending if we are creating a bundle or not
if [ "${Le_Deploy_haproxy_bundle}" = "yes" ]; then
_info "Bundle creation requested"
# Initialise $Le_Keylength if its not already set
if [ -z "${Le_Keylength}" ]; then
Le_Keylength=""
fi
if _isEccKey "${Le_Keylength}"; then
_info "ECC key type detected"
_suffix=".ecdsa"
else
_info "RSA key type detected"
_suffix=".rsa"
fi
else
_suffix=""
fi
_debug _suffix "${_suffix}"
# Set variables for later
_pem="${Le_Deploy_haproxy_pem_path}/${Le_Deploy_haproxy_pem_name}${_suffix}"
_issuer="${_pem}.issuer"
_ocsp="${_pem}.ocsp"
_reload="${Le_Deploy_haproxy_reload}"
_info "Deploying PEM file"
# Create a temporary PEM file
_temppem="$(_mktemp)"
_debug _temppem "${_temppem}"
cat "${_ckey}" "${_ccert}" "${_cca}" >"${_temppem}"
_ret="$?"
# Check that we could create the temporary file
if [ "${_ret}" != "0" ]; then
_err "Error code ${_ret} returned during PEM file creation"
[ -f "${_temppem}" ] && rm -f "${_temppem}"
return ${_ret}
fi
# Move PEM file into place
_info "Moving new certificate into place"
_debug _pem "${_pem}"
cat "${_temppem}" >"${_pem}"
_ret=$?
# Clean up temp file
[ -f "${_temppem}" ] && rm -f "${_temppem}"
# Deal with any failure of moving PEM file into place
if [ "${_ret}" != "0" ]; then
_err "Error code ${_ret} returned while moving new certificate into place"
return ${_ret}
fi
# Update .issuer file if requested
if [ "${Le_Deploy_haproxy_issuer}" = "yes" ]; then
_info "Updating .issuer file"
_debug _issuer "${_issuer}"
cat "${_cca}" >"${_issuer}"
_ret="$?"
if [ "${_ret}" != "0" ]; then
_err "Error code ${_ret} returned while copying issuer/CA certificate into place"
return ${_ret}
fi
else
[ -f "${_issuer}" ] && _err "Issuer file update not requested but .issuer file exists"
fi
# Update .ocsp file if certificate was requested with --ocsp/--ocsp-must-staple option
if [ -z "${Le_OCSP_Staple}" ]; then
Le_OCSP_Staple="0"
fi
if [ "${Le_OCSP_Staple}" = "1" ]; then
_info "Updating OCSP stapling info"
_debug _ocsp "${_ocsp}"
_info "Extracting OCSP URL"
_ocsp_url=$(openssl x509 -noout -ocsp_uri -in "${_pem}")
_debug _ocsp_url "${_ocsp_url}"
# Only process OCSP if URL was present
if [ "${_ocsp_url}" != "" ]; then
# Extract the hostname from the OCSP URL
_info "Extracting OCSP URL"
_ocsp_host=$(echo "${_ocsp_url}" | cut -d/ -f3)
_debug _ocsp_host "${_ocsp_host}"
# Only process the certificate if we have a .issuer file
if [ -r "${_issuer}" ]; then
# Check if issuer cert is also a root CA cert
_subjectdn=$(openssl x509 -in "${_issuer}" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)
_debug _subjectdn "${_subjectdn}"
_issuerdn=$(openssl x509 -in "${_issuer}" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)
_debug _issuerdn "${_issuerdn}"
_info "Requesting OCSP response"
# Request the OCSP response from the issuer and store it
if [ "${_subjectdn}" = "${_issuerdn}" ]; then
# If the issuer is a CA cert then our command line has "-CAfile" added
openssl ocsp \
-issuer "${_issuer}" \
-cert "${_pem}" \
-url "${_ocsp_url}" \
-header Host "${_ocsp_host}" \
-respout "${_ocsp}" \
-verify_other "${_issuer}" \
-no_nonce \
-CAfile "${_issuer}" \
| grep -q "${_pem}: good"
_ret=$?
else
# Issuer is not a root CA so no "-CAfile" option
openssl ocsp \
-issuer "${_issuer}" \
-cert "${_pem}" \
-url "${_ocsp_url}" \
-header Host "${_ocsp_host}" \
-respout "${_ocsp}" \
-verify_other "${_issuer}" \
-no_nonce \
| grep -q "${_pem}: good"
_ret=$?
fi
else
# Non fatal: No issuer file was present so no OCSP stapling file created
_err "OCSP stapling in use but no .issuer file was present"
fi
else
# Non fatal: No OCSP url was found int the certificate
_err "OCSP update requested but no OCSP URL was found in certificate"
fi
# Non fatal: Check return code of openssl command
if [ "${_ret}" != "0" ]; then
_err "Updating OCSP stapling failed with return code ${_ret}"
fi
else
# An OCSP file was already present but certificate did not have OCSP extension
if [ -f "${_ocsp}" ]; then
_err "OCSP was not requested but .ocsp file exists."
# Could remove the file at this step, although HAProxy just ignores it in this case
# rm -f "${_ocsp}" || _err "Problem removing stale .ocsp file"
fi
fi
# Reload HAProxy
_debug _reload "${_reload}"
eval "${_reload}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_err "Error code ${_ret} during reload"
return ${_ret}
else
_info "Reload successful"
fi
return 0
}

25
deploy/keychain.sh Normal file
View File

@@ -0,0 +1,25 @@
#!/usr/bin/env sh
######## Public functions #####################
#domain keyfile certfile cafile fullchain
keychain_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"
/usr/bin/security import "$_ckey" -k "/Library/Keychains/System.keychain"
/usr/bin/security import "$_ccert" -k "/Library/Keychains/System.keychain"
/usr/bin/security import "$_cca" -k "/Library/Keychains/System.keychain"
/usr/bin/security import "$_cfullchain" -k "/Library/Keychains/System.keychain"
return 0
}

View File

@@ -1,13 +1,7 @@
#!/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
# If certificate already exist it will update only cert and key not touching other parameter
# If certificate doesn't exist it will only upload cert and key and not set other parameter
# Note that we deploy full chain
# Written by Geoffroi Genot <ggenot@voxbone.com>
######## Public functions #####################
@@ -31,29 +25,32 @@ kong_deploy() {
_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
#Get ssl_uuid linked to the domain
ssl_uuid=$(_get "$KONG_URL/certificates/$_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 "$ssl_uuid" ]; then
_debug "Unable to get Kong ssl_uuid for domain $_cdomain"
_debug "Make sure that KONG_URL is correctly configured"
_debug "Make sure that a Kong certificate match the sni"
_debug "Kong url: $KONG_URL"
_info "No existing certificate, creating..."
#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")"
delim="-----MultipartDelimiter$(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"
if [ -z "$ssl_uuid" ]; then
#set sni to domain
content="--$delim${nl}Content-Disposition: form-data; name=\"snis\"${nl}${nl}$_cdomain"
fi
#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")"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"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")"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"cert\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")"
#Close multipart
content="$content${nl}--$delim--${nl}"
#Convert CRLF
@@ -61,18 +58,17 @@ kong_deploy() {
#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"
#Check if sslcreated (if not => POST else => PATCH)
if [ -z "$ssl_uuid" ]; then
#Post certificate to Kong
response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins" "" "POST")
response=$(_post "$content" "$KONG_URL/certificates" "" "POST")
else
#patch
response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins/$ssl_uuid" "" "PATCH")
response=$(_post "$content" "$KONG_URL/certificates/$ssl_uuid" "" "PATCH")
fi
if ! [ "$(echo "$response" | _egrep_o "ssl")" = "ssl" ]; then
_err "An error occured with cert upload. Check response:"
if ! [ "$(echo "$response" | _egrep_o "created_at")" = "created_at" ]; then
_err "An error occurred with cert upload. Check response:"
_err "$response"
return 1
fi

58
deploy/mailcow.sh Normal file
View File

@@ -0,0 +1,58 @@
#!/usr/bin/env sh
#Here is a script to deploy cert to mailcow.
#returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
mailcow_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"
_mailcow_path="${DEPLOY_MAILCOW_PATH}"
if [ -z "$_mailcow_path" ]; then
_err "Mailcow path is not found, please define DEPLOY_MAILCOW_PATH."
return 1
fi
_ssl_path="${_mailcow_path}/data/assets/ssl/"
if [ ! -d "$_ssl_path" ]; then
_err "Cannot find mailcow ssl path: $_ssl_path"
return 1
fi
_info "Copying key and cert"
_real_key="$_ssl_path/key.pem"
if ! cat "$_ckey" >"$_real_key"; then
_err "Error: write key file to: $_real_key"
return 1
fi
_real_fullchain="$_ssl_path/cert.pem"
if ! cat "$_cfullchain" >"$_real_fullchain"; then
_err "Error: write cert file to: $_real_fullchain"
return 1
fi
DEFAULT_MAILCOW_RELOAD="cd ${_mailcow_path} && docker-compose restart postfix-mailcow dovecot-mailcow nginx-mailcow"
_reload="${DEPLOY_MAILCOW_RELOAD:-$DEFAULT_MAILCOW_RELOAD}"
_info "Run reload: $_reload"
if eval "$_reload"; then
_info "Reload success!"
fi
return 0
}

59
deploy/mydevil.sh Executable file
View File

@@ -0,0 +1,59 @@
#!/usr/bin/env sh
# MyDevil.net API (2019-02-03)
#
# MyDevil.net already supports automatic Let's Encrypt certificates,
# except for wildcard domains.
#
# This script depends on `devil` command that MyDevil.net provides,
# which means that it works only on server side.
#
# Author: Marcin Konicki <https://ahwayakchih.neoni.net>
#
######## Public functions #####################
# Usage: mydevil_deploy domain keyfile certfile cafile fullchain
mydevil_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
ip=""
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
if ! _exists "devil"; then
_err "Could not find 'devil' command."
return 1
fi
ip=$(mydevil_get_ip "$_cdomain")
if [ -z "$ip" ]; then
_err "Could not find IP for domain $_cdomain."
return 1
fi
# Delete old certificate first
_info "Removing old certificate for $_cdomain at $ip"
devil ssl www del "$ip" "$_cdomain"
# Add new certificate
_info "Adding new certificate for $_cdomain at $ip"
devil ssl www add "$ip" "$_cfullchain" "$_ckey" "$_cdomain" || return 1
return 0
}
#################### Private functions below ##################################
# Usage: ip=$(mydevil_get_ip domain.com)
# echo $ip
mydevil_get_ip() {
devil dns list "$1" | cut -w -s -f 3,7 | grep "^A$(printf '\t')" | cut -w -s -f 2 || return 1
return 0
}

26
deploy/mysqld.sh Normal file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env sh
#Here is a script to deploy cert to mysqld server.
#returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
mysqld_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 "deploy cert to mysqld server, Not implemented yet"
return 1
}

26
deploy/nginx.sh Normal file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env sh
#Here is a script to deploy cert to nginx server.
#returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
nginx_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 "deploy cert to nginx server, Not implemented yet"
return 1
}

26
deploy/opensshd.sh Normal file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env sh
#Here is a script to deploy cert to opensshd server.
#returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
opensshd_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 "deploy cert to opensshd server, Not implemented yet"
return 1
}

26
deploy/pureftpd.sh Normal file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env sh
#Here is a script to deploy cert to pureftpd server.
#returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
pureftpd_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 "deploy cert to pureftpd server, Not implemented yet"
return 1
}

92
deploy/qiniu.sh Normal file
View File

@@ -0,0 +1,92 @@
#!/usr/bin/env sh
# Script to create certificate to qiniu.com
#
# This deployment required following variables
# export QINIU_AK="QINIUACCESSKEY"
# export QINIU_SK="QINIUSECRETKEY"
# export QINIU_CDN_DOMAIN="cdn.example.com"
QINIU_API_BASE="https://api.qiniu.com"
qiniu_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"
if [ -z "$QINIU_AK" ]; then
_err "QINIU_AK is not defined."
return 1
else
_savedomainconf QINIU_AK "$QINIU_AK"
fi
if [ -z "$QINIU_SK" ]; then
_err "QINIU_SK is not defined."
return 1
else
_savedomainconf QINIU_SK "$QINIU_SK"
fi
if [ "$QINIU_CDN_DOMAIN" ]; then
_savedomainconf QINIU_CDN_DOMAIN "$QINIU_CDN_DOMAIN"
else
QINIU_CDN_DOMAIN="$_cdomain"
fi
## upload certificate
string_fullchain=$(sed 's/$/\\n/' "$_cfullchain" | tr -d '\n')
string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n')
sslcert_path="/sslcert"
sslcerl_body="{\"name\":\"$_cdomain\",\"common_name\":\"$QINIU_CDN_DOMAIN\",\"ca\":\"$string_fullchain\",\"pri\":\"$string_key\"}"
sslcert_access_token="$(_make_access_token "$sslcert_path")"
_debug sslcert_access_token "$sslcert_access_token"
export _H1="Authorization: QBox $sslcert_access_token"
sslcert_response=$(_post "$sslcerl_body" "$QINIU_API_BASE$sslcert_path" 0 "POST" "application/json" | _dbase64 "multiline")
if ! _contains "$sslcert_response" "certID"; then
_err "Error in creating certificate:"
_err "$sslcert_response"
return 1
fi
_debug sslcert_response "$sslcert_response"
_info "Certificate successfully uploaded, updating domain $_cdomain"
## extract certId
_certId="$(printf "%s" "$sslcert_response" | _normalizeJson | _egrep_o "certID\": *\"[^\"]*\"" | cut -d : -f 2)"
_debug certId "$_certId"
## update domain ssl config
update_path="/domain/$QINIU_CDN_DOMAIN/httpsconf"
update_body="{\"certid\":$_certId,\"forceHttps\":false}"
update_access_token="$(_make_access_token "$update_path")"
_debug update_access_token "$update_access_token"
export _H1="Authorization: QBox $update_access_token"
update_response=$(_post "$update_body" "$QINIU_API_BASE$update_path" 0 "PUT" "application/json" | _dbase64 "multiline")
if _contains "$update_response" "error"; then
_err "Error in updating domain httpsconf:"
_err "$update_response"
return 1
fi
_debug update_response "$update_response"
_info "Certificate successfully deployed"
return 0
}
_make_access_token() {
_token="$(printf "%s\n" "$1" | _hmac "sha1" "$(printf "%s" "$QINIU_SK" | _hex_dump | tr -d " ")" | _base64 | tr -- '+/' '-_')"
echo "$QINIU_AK:$_token"
}

111
deploy/routeros.sh Normal file
View File

@@ -0,0 +1,111 @@
#!/usr/bin/env sh
# Here is a script to deploy cert to routeros router.
# Deploy the cert to remote routeros
#
# ```sh
# acme.sh --deploy -d ftp.example.com --deploy-hook routeros
# ```
#
# Before you can deploy the certificate to router os, you need
# to add the id_rsa.pub key to the routeros and assign a user
# to that key.
#
# The user need to have access to ssh, ftp, read and write.
#
# There are no need to enable ftp service for the script to work,
# as they are transmitted over SCP, however ftp is needed to store
# the files on the router.
#
# Then you need to set the environment variables for the
# deploy script to work.
#
# ```sh
# export ROUTER_OS_USERNAME=certuser
# export ROUTER_OS_HOST=router.example.com
#
# acme.sh --deploy -d ftp.example.com --deploy-hook routeros
# ```
#
# The deploy script will remove previously deployed certificates,
# and it does this with an assumption on how RouterOS names imported
# certificates, adding a "cer_0" suffix at the end. This is true for
# versions 6.32 -> 6.41.3, but it is not guaranteed that it will be
# true for future versions when upgrading.
#
# If the router have other certificates with the same name as the one
# beeing deployed, then this script will remove those certificates.
#
# At the end of the script, the services that use those certificates
# could be updated. Currently only the www-ssl service is beeing
# updated, but more services could be added.
#
# For instance:
# ```sh
# export ROUTER_OS_ADDITIONAL_SERVICES="/ip service set api-ssl certificate=$_cdomain.cer_0"
# ```
#
# One optional thing to do as well is to create a script that updates
# all the required services and run that script in a single command.
#
# returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
routeros_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"
if [ -z "$ROUTER_OS_HOST" ]; then
_debug "Using _cdomain as ROUTER_OS_HOST, please set if not correct."
ROUTER_OS_HOST="$_cdomain"
fi
if [ -z "$ROUTER_OS_USERNAME" ]; then
_err "Need to set the env variable ROUTER_OS_USERNAME"
return 1
fi
if [ -z "$ROUTER_OS_ADDITIONAL_SERVICES" ]; then
_debug "Not enabling additional services"
ROUTER_OS_ADDITIONAL_SERVICES=""
fi
_info "Trying to push key '$_ckey' to router"
scp "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key"
_info "Trying to push cert '$_cfullchain' to router"
scp "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer"
DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=admin policy=ftp,read,write,password,sensitive
source=\"## generated by routeros deploy script in acme.sh
\n/certificate remove [ find name=$_cdomain.cer_0 ]
\n/certificate remove [ find name=$_cdomain.cer_1 ]
\ndelay 1
\n/certificate import file-name=$_cdomain.cer passphrase=\\\"\\\"
\n/certificate import file-name=$_cdomain.key passphrase=\\\"\\\"
\ndelay 1
\n/file remove $_cdomain.cer
\n/file remove $_cdomain.key
\ndelay 2
\n/ip service set www-ssl certificate=$_cdomain.cer_0
\n$ROUTER_OS_ADDITIONAL_SERVICES
\n\"
"
# shellcheck disable=SC2029
ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "$DEPLOY_SCRIPT_CMD"
# shellcheck disable=SC2029
ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script run \"LE Cert Deploy - $_cdomain\""
# shellcheck disable=SC2029
ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script remove \"LE Cert Deploy - $_cdomain\""
return 0
}

205
deploy/ssh.sh Normal file
View File

@@ -0,0 +1,205 @@
#!/usr/bin/env sh
# Script to deploy certificates to remote server by SSH
# Note that SSH must be able to login to remote host without a password...
# SSH Keys must have been exchanged with the remote host. Validate and
# test that you can login to USER@SERVER from the host running acme.sh before
# using this script.
#
# The following variables exported from environment will be used.
# If not set then values previously saved in domain.conf file are used.
#
# Only a username is required. All others are optional.
#
# The following examples are for QNAP NAS running QTS 4.2
# export DEPLOY_SSH_CMD="" # defaults to ssh
# export DEPLOY_SSH_USER="admin" # required
# export DEPLOY_SSH_SERVER="qnap" # defaults to domain name
# export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem"
# export DEPLOY_SSH_CERTFILE="/etc/stunnel/stunnel.pem"
# export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem"
# export DEPLOY_SSH_FULLCHAIN=""
# export DEPLOY_SSH_REMOTE_CMD="/etc/init.d/stunnel.sh restart"
# export DEPLOY_SSH_BACKUP="" # yes or no, default to yes
#
######## Public functions #####################
#domain keyfile certfile cafile fullchain
ssh_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_cmdstr=""
_homedir='~'
_backupprefix="$_homedir/.acme_ssh_deploy/$_cdomain-backup"
_backupdir="$_backupprefix-$(_utc_date | tr ' ' '-')"
if [ -f "$DOMAIN_CONF" ]; then
# shellcheck disable=SC1090
. "$DOMAIN_CONF"
fi
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
# USER is required to login by SSH to remote host.
if [ -z "$DEPLOY_SSH_USER" ]; then
if [ -z "$Le_Deploy_ssh_user" ]; then
_err "DEPLOY_SSH_USER not defined."
return 1
fi
else
Le_Deploy_ssh_user="$DEPLOY_SSH_USER"
_savedomainconf Le_Deploy_ssh_user "$Le_Deploy_ssh_user"
fi
# SERVER is optional. If not provided then use _cdomain
if [ -n "$DEPLOY_SSH_SERVER" ]; then
Le_Deploy_ssh_server="$DEPLOY_SSH_SERVER"
_savedomainconf Le_Deploy_ssh_server "$Le_Deploy_ssh_server"
elif [ -z "$Le_Deploy_ssh_server" ]; then
Le_Deploy_ssh_server="$_cdomain"
fi
# CMD is optional. If not provided then use ssh
if [ -n "$DEPLOY_SSH_CMD" ]; then
Le_Deploy_ssh_cmd="$DEPLOY_SSH_CMD"
_savedomainconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd"
elif [ -z "$Le_Deploy_ssh_cmd" ]; then
Le_Deploy_ssh_cmd="ssh"
fi
# BACKUP is optional. If not provided then default to yes
if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then
Le_Deploy_ssh_backup="no"
elif [ -z "$Le_Deploy_ssh_backup" ]; then
Le_Deploy_ssh_backup="yes"
fi
_savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup"
_info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server"
# KEYFILE is optional.
# If provided then private key will be copied to provided filename.
if [ -n "$DEPLOY_SSH_KEYFILE" ]; then
Le_Deploy_ssh_keyfile="$DEPLOY_SSH_KEYFILE"
_savedomainconf Le_Deploy_ssh_keyfile "$Le_Deploy_ssh_keyfile"
fi
if [ -n "$Le_Deploy_ssh_keyfile" ]; then
if [ "$Le_Deploy_ssh_backup" = "yes" ]; then
# backup file we are about to overwrite.
_cmdstr="$_cmdstr cp $Le_Deploy_ssh_keyfile $_backupdir >/dev/null;"
fi
# copy new certificate into file.
_cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;"
_info "will copy private key to remote file $Le_Deploy_ssh_keyfile"
fi
# CERTFILE is optional.
# If provided then certificate will be copied or appended to provided filename.
if [ -n "$DEPLOY_SSH_CERTFILE" ]; then
Le_Deploy_ssh_certfile="$DEPLOY_SSH_CERTFILE"
_savedomainconf Le_Deploy_ssh_certfile "$Le_Deploy_ssh_certfile"
fi
if [ -n "$Le_Deploy_ssh_certfile" ]; then
_pipe=">"
if [ "$Le_Deploy_ssh_certfile" = "$Le_Deploy_ssh_keyfile" ]; then
# if filename is same as previous file then append.
_pipe=">>"
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
# backup file we are about to overwrite.
_cmdstr="$_cmdstr cp $Le_Deploy_ssh_certfile $_backupdir >/dev/null;"
fi
# copy new certificate into file.
_cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;"
_info "will copy certificate to remote file $Le_Deploy_ssh_certfile"
fi
# CAFILE is optional.
# If provided then CA intermediate certificate will be copied or appended to provided filename.
if [ -n "$DEPLOY_SSH_CAFILE" ]; then
Le_Deploy_ssh_cafile="$DEPLOY_SSH_CAFILE"
_savedomainconf Le_Deploy_ssh_cafile "$Le_Deploy_ssh_cafile"
fi
if [ -n "$Le_Deploy_ssh_cafile" ]; then
_pipe=">"
if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] \
|| [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then
# if filename is same as previous file then append.
_pipe=">>"
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
# backup file we are about to overwrite.
_cmdstr="$_cmdstr cp $Le_Deploy_ssh_cafile $_backupdir >/dev/null;"
fi
# copy new certificate into file.
_cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;"
_info "will copy CA file to remote file $Le_Deploy_ssh_cafile"
fi
# FULLCHAIN is optional.
# If provided then fullchain certificate will be copied or appended to provided filename.
if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then
Le_Deploy_ssh_fullchain="$DEPLOY_SSH_FULLCHAIN"
_savedomainconf Le_Deploy_ssh_fullchain "$Le_Deploy_ssh_fullchain"
fi
if [ -n "$Le_Deploy_ssh_fullchain" ]; then
_pipe=">"
if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] \
|| [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ] \
|| [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then
# if filename is same as previous file then append.
_pipe=">>"
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
# backup file we are about to overwrite.
_cmdstr="$_cmdstr cp $Le_Deploy_ssh_fullchain $_backupdir >/dev/null;"
fi
# copy new certificate into file.
_cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;"
_info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain"
fi
# REMOTE_CMD is optional.
# If provided then this command will be executed on remote host.
if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then
Le_Deploy_ssh_remote_cmd="$DEPLOY_SSH_REMOTE_CMD"
_savedomainconf Le_Deploy_ssh_remote_cmd "$Le_Deploy_ssh_remote_cmd"
fi
if [ -n "$Le_Deploy_ssh_remote_cmd" ]; then
_cmdstr="$_cmdstr $Le_Deploy_ssh_remote_cmd;"
_info "Will execute remote command $Le_Deploy_ssh_remote_cmd"
fi
if [ -z "$_cmdstr" ]; then
_err "No remote commands to excute. Failed to deploy certificates to remote server"
return 1
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
# run cleanup on the backup directory, erase all older
# than 180 days (15552000 seconds).
_cmdstr="{ now=\"\$(date -u +%s)\"; for fn in $_backupprefix*; \
do if [ -d \"\$fn\" ] && [ \"\$(expr \$now - \$(date -ur \$fn +%s) )\" -ge \"15552000\" ]; \
then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; done; }; $_cmdstr"
# Alternate version of above... _cmdstr="find $_backupprefix* -type d -mtime +180 2>/dev/null | xargs rm -rf; $_cmdstr"
# Create our backup directory for overwritten cert files.
_cmdstr="mkdir -p $_backupdir; $_cmdstr"
_info "Backup of old certificate files will be placed in remote directory $_backupdir"
_info "Backup directories erased after 180 days."
fi
_secure_debug "Remote commands to execute: " "$_cmdstr"
_info "Submitting sequence of commands to remote server by ssh"
# quotations in bash cmd below intended. Squash travis spellcheck error
# shellcheck disable=SC2029
$Le_Deploy_ssh_cmd -T "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmdstr'"
_ret="$?"
if [ "$_ret" != "0" ]; then
_err "Error code $_ret returned from $Le_Deploy_ssh_cmd"
fi
return $_ret
}

55
deploy/strongswan.sh Normal file
View File

@@ -0,0 +1,55 @@
#!/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
strongswan_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_info "Using strongswan"
if [ -x /usr/sbin/ipsec ]; then
_ipsec=/usr/sbin/ipsec
elif [ -x /usr/sbin/strongswan ]; then
_ipsec=/usr/sbin/strongswan
elif [ -x /usr/local/sbin/ipsec ]; then
_ipsec=/usr/local/sbin/ipsec
else
_err "no strongswan or ipsec command is detected"
return 1
fi
_info _ipsec "$_ipsec"
_confdir=$($_ipsec --confdir)
if [ $? -ne 0 ] || [ -z "$_confdir" ]; then
_err "no strongswan --confdir is detected"
return 1
fi
_info _confdir "$_confdir"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
cat "$_ckey" >"${_confdir}/ipsec.d/private/$(basename "$_ckey")"
cat "$_ccert" >"${_confdir}/ipsec.d/certs/$(basename "$_ccert")"
cat "$_cca" >"${_confdir}/ipsec.d/cacerts/$(basename "$_cca")"
cat "$_cfullchain" >"${_confdir}/ipsec.d/cacerts/$(basename "$_cfullchain")"
$_ipsec reload
}

100
deploy/unifi.sh Normal file
View File

@@ -0,0 +1,100 @@
#!/usr/bin/env sh
#Here is a script to deploy cert to unifi server.
#returns 0 means success, otherwise error.
#DEPLOY_UNIFI_KEYSTORE="/usr/lib/unifi/data/keystore"
#DEPLOY_UNIFI_KEYPASS="aircontrolenterprise"
#DEPLOY_UNIFI_RELOAD="service unifi restart"
######## Public functions #####################
#domain keyfile certfile cafile fullchain
unifi_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"
if ! _exists keytool; then
_err "keytool not found"
return 1
fi
DEFAULT_UNIFI_KEYSTORE="/usr/lib/unifi/data/keystore"
_unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-$DEFAULT_UNIFI_KEYSTORE}"
DEFAULT_UNIFI_KEYPASS="aircontrolenterprise"
_unifi_keypass="${DEPLOY_UNIFI_KEYPASS:-$DEFAULT_UNIFI_KEYPASS}"
DEFAULT_UNIFI_RELOAD="service unifi restart"
_reload="${DEPLOY_UNIFI_RELOAD:-$DEFAULT_UNIFI_RELOAD}"
_debug _unifi_keystore "$_unifi_keystore"
if [ ! -f "$_unifi_keystore" ]; then
if [ -z "$DEPLOY_UNIFI_KEYSTORE" ]; then
_err "unifi keystore is not found, please define DEPLOY_UNIFI_KEYSTORE"
return 1
else
_err "It seems that the specified unifi keystore is not valid, please check."
return 1
fi
fi
if [ ! -w "$_unifi_keystore" ]; then
_err "The file $_unifi_keystore is not writable, please change the permission."
return 1
fi
_info "Generate import pkcs12"
_import_pkcs12="$(_mktemp)"
_toPkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca" "$_unifi_keypass" unifi root
if [ "$?" != "0" ]; then
_err "Oops, error creating import pkcs12, please report bug to us."
return 1
fi
_info "Modify unifi keystore: $_unifi_keystore"
if keytool -importkeystore \
-deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \
-srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \
-alias unifi -noprompt; then
_info "Import keystore success!"
rm "$_import_pkcs12"
else
_err "Import unifi keystore error, please report bug to us."
rm "$_import_pkcs12"
return 1
fi
_info "Run reload: $_reload"
if eval "$_reload"; then
_info "Reload success!"
if [ "$DEPLOY_UNIFI_KEYSTORE" ]; then
_savedomainconf DEPLOY_UNIFI_KEYSTORE "$DEPLOY_UNIFI_KEYSTORE"
else
_cleardomainconf DEPLOY_UNIFI_KEYSTORE
fi
if [ "$DEPLOY_UNIFI_KEYPASS" ]; then
_savedomainconf DEPLOY_UNIFI_KEYPASS "$DEPLOY_UNIFI_KEYPASS"
else
_cleardomainconf DEPLOY_UNIFI_KEYPASS
fi
if [ "$DEPLOY_UNIFI_RELOAD" ]; then
_savedomainconf DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD"
else
_cleardomainconf DEPLOY_UNIFI_RELOAD
fi
return 0
else
_err "Reload error"
return 1
fi
return 0
}

61
deploy/vault_cli.sh Normal file
View File

@@ -0,0 +1,61 @@
#!/usr/bin/env sh
# Here is a script to deploy cert to hashicorp vault
# (https://www.vaultproject.io/)
#
# it requires the vault binary to be available in PATH, and the following
# environment variables:
#
# VAULT_PREFIX - this contains the prefix path in vault
# VAULT_ADDR - vault requires this to find your vault server
#
# additionally, you need to ensure that VAULT_TOKEN is avialable or
# `vault auth` has applied the appropriate authorization for the vault binary
# to access the vault server
#returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
vault_cli_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"
# validate required env vars
if [ -z "$VAULT_PREFIX" ]; then
_err "VAULT_PREFIX needs to be defined (contains prefix path in vault)"
return 1
fi
if [ -z "$VAULT_ADDR" ]; then
_err "VAULT_ADDR needs to be defined (contains vault connection address)"
return 1
fi
VAULT_CMD=$(which vault)
if [ ! $? ]; then
_err "cannot find vault binary!"
return 1
fi
if [ -n "$FABIO" ]; then
$VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1
else
$VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1
$VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1
$VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1
$VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1
fi
}

110
deploy/vsftpd.sh Normal file
View File

@@ -0,0 +1,110 @@
#!/usr/bin/env sh
#Here is a script to deploy cert to vsftpd server.
#returns 0 means success, otherwise error.
#DEPLOY_VSFTPD_CONF="/etc/vsftpd.conf"
#DEPLOY_VSFTPD_RELOAD="service vsftpd restart"
######## Public functions #####################
#domain keyfile certfile cafile fullchain
vsftpd_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"
_ssl_path="/etc/acme.sh/vsftpd"
if ! mkdir -p "$_ssl_path"; then
_err "Can not create folder:$_ssl_path"
return 1
fi
_info "Copying key and cert"
_real_key="$_ssl_path/vsftpd.key"
if ! cat "$_ckey" >"$_real_key"; then
_err "Error: write key file to: $_real_key"
return 1
fi
_real_fullchain="$_ssl_path/vsftpd.chain.pem"
if ! cat "$_cfullchain" >"$_real_fullchain"; then
_err "Error: write key file to: $_real_fullchain"
return 1
fi
DEFAULT_VSFTPD_RELOAD="service vsftpd restart"
_reload="${DEPLOY_VSFTPD_RELOAD:-$DEFAULT_VSFTPD_RELOAD}"
if [ -z "$IS_RENEW" ]; then
DEFAULT_VSFTPD_CONF="/etc/vsftpd.conf"
_vsftpd_conf="${DEPLOY_VSFTPD_CONF:-$DEFAULT_VSFTPD_CONF}"
if [ ! -f "$_vsftpd_conf" ]; then
if [ -z "$DEPLOY_VSFTPD_CONF" ]; then
_err "vsftpd conf is not found, please define DEPLOY_VSFTPD_CONF"
return 1
else
_err "It seems that the specified vsftpd conf is not valid, please check."
return 1
fi
fi
if [ ! -w "$_vsftpd_conf" ]; then
_err "The file $_vsftpd_conf is not writable, please change the permission."
return 1
fi
_backup_conf="$DOMAIN_BACKUP_PATH/vsftpd.conf.bak"
_info "Backup $_vsftpd_conf to $_backup_conf"
cp "$_vsftpd_conf" "$_backup_conf"
_info "Modify vsftpd conf: $_vsftpd_conf"
if _setopt "$_vsftpd_conf" "rsa_cert_file" "=" "$_real_fullchain" \
&& _setopt "$_vsftpd_conf" "rsa_private_key_file" "=" "$_real_key" \
&& _setopt "$_vsftpd_conf" "ssl_enable" "=" "YES"; then
_info "Set config success!"
else
_err "Config vsftpd server error, please report bug to us."
_info "Restoring vsftpd conf"
if cat "$_backup_conf" >"$_vsftpd_conf"; then
_info "Restore conf success"
eval "$_reload"
else
_err "Oops, error restore vsftpd conf, please report bug to us."
fi
return 1
fi
fi
_info "Run reload: $_reload"
if eval "$_reload"; then
_info "Reload success!"
if [ "$DEPLOY_VSFTPD_CONF" ]; then
_savedomainconf DEPLOY_VSFTPD_CONF "$DEPLOY_VSFTPD_CONF"
else
_cleardomainconf DEPLOY_VSFTPD_CONF
fi
if [ "$DEPLOY_VSFTPD_RELOAD" ]; then
_savedomainconf DEPLOY_VSFTPD_RELOAD "$DEPLOY_VSFTPD_RELOAD"
else
_cleardomainconf DEPLOY_VSFTPD_RELOAD
fi
return 0
else
_err "Reload error, restoring"
if cat "$_backup_conf" >"$_vsftpd_conf"; then
_info "Restore conf success"
eval "$_reload"
else
_err "Oops, error restore vsftpd conf, please report bug to us."
fi
return 1
fi
return 0
}

View File

@@ -1,327 +1,6 @@
# How to use DNS API
DNS api usage:
## 1. Use CloudFlare domain API to automatically issue cert
First you need to login to your CloudFlare account to get your API key.
https://github.com/Neilpang/acme.sh/wiki/dnsapi
```
export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export CF_Email="xxxx@sss.com"
```
Ok, let's issue a cert now:
```
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` and will be reused when needed.
## 2. Use DNSPod.cn domain API to automatically issue cert
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 a cert now:
```
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` and will be reused when needed.
## 3. Use CloudXNS.com domain API to automatically issue cert
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 a cert now:
```
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` and will be reused when needed.
## 4. Use GoDaddy.com domain API to automatically issue cert
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.
```
export GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export GD_Secret="asdfsdafdsfdsfdsfdsfdsafd"
```
Ok, let's issue a cert now:
```
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` and will be reused when needed.
## 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
## 7. Use nsupdate to automatically issue cert
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}
```
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`
```
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
https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api

55
dnsapi/dns_acmedns.sh Normal file
View File

@@ -0,0 +1,55 @@
#!/usr/bin/env sh
#
#Author: Wolfgang Ebner
#Report Bugs here: https://github.com/webner/acme.sh
#
######## Public functions #####################
#Usage: dns_acmedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_acmedns_add() {
fulldomain=$1
txtvalue=$2
_info "Using acme-dns"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
ACMEDNS_UPDATE_URL="${ACMEDNS_UPDATE_URL:-$(_readaccountconf_mutable ACMEDNS_UPDATE_URL)}"
ACMEDNS_USERNAME="${ACMEDNS_USERNAME:-$(_readaccountconf_mutable ACMEDNS_USERNAME)}"
ACMEDNS_PASSWORD="${ACMEDNS_PASSWORD:-$(_readaccountconf_mutable ACMEDNS_PASSWORD)}"
ACMEDNS_SUBDOMAIN="${ACMEDNS_SUBDOMAIN:-$(_readaccountconf_mutable ACMEDNS_SUBDOMAIN)}"
if [ "$ACMEDNS_UPDATE_URL" = "" ]; then
ACMEDNS_UPDATE_URL="https://auth.acme-dns.io/update"
fi
_saveaccountconf_mutable ACMEDNS_UPDATE_URL "$ACMEDNS_UPDATE_URL"
_saveaccountconf_mutable ACMEDNS_USERNAME "$ACMEDNS_USERNAME"
_saveaccountconf_mutable ACMEDNS_PASSWORD "$ACMEDNS_PASSWORD"
_saveaccountconf_mutable ACMEDNS_SUBDOMAIN "$ACMEDNS_SUBDOMAIN"
export _H1="X-Api-User: $ACMEDNS_USERNAME"
export _H2="X-Api-Key: $ACMEDNS_PASSWORD"
data="{\"subdomain\":\"$ACMEDNS_SUBDOMAIN\", \"txt\": \"$txtvalue\"}"
_debug data "$data"
response="$(_post "$data" "$ACMEDNS_UPDATE_URL" "" "POST")"
_debug response "$response"
if ! echo "$response" | grep "\"$txtvalue\"" >/dev/null; then
_err "invalid response of acme-dns"
return 1
fi
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_acmedns_rm() {
fulldomain=$1
txtvalue=$2
_info "Using acme-dns"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
}
#################### Private functions below ##################################

83
dnsapi/dns_acmeproxy.sh Normal file
View File

@@ -0,0 +1,83 @@
#!/usr/bin/env sh
## Acmeproxy DNS provider to be used with acmeproxy (http://github.com/mdbraber/acmeproxy)
## API integration by Maarten den Braber
##
## Report any bugs via https://github.com/mdbraber/acme.sh
dns_acmeproxy_add() {
fulldomain="${1}"
txtvalue="${2}"
action="present"
_debug "Calling: _acmeproxy_request() '${fulldomain}' '${txtvalue}' '${action}'"
_acmeproxy_request "$fulldomain" "$txtvalue" "$action"
}
dns_acmeproxy_rm() {
fulldomain="${1}"
txtvalue="${2}"
action="cleanup"
_debug "Calling: _acmeproxy_request() '${fulldomain}' '${txtvalue}' '${action}'"
_acmeproxy_request "$fulldomain" "$txtvalue" "$action"
}
_acmeproxy_request() {
## Nothing to see here, just some housekeeping
fulldomain=$1
txtvalue=$2
action=$3
_info "Using acmeproxy"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
ACMEPROXY_ENDPOINT="${ACMEPROXY_ENDPOINT:-$(_readaccountconf_mutable ACMEPROXY_ENDPOINT)}"
ACMEPROXY_USERNAME="${ACMEPROXY_USERNAME:-$(_readaccountconf_mutable ACMEPROXY_USERNAME)}"
ACMEPROXY_PASSWORD="${ACMEPROXY_PASSWORD:-$(_readaccountconf_mutable ACMEPROXY_PASSWORD)}"
## Check for the endpoint
if [ -z "$ACMEPROXY_ENDPOINT" ]; then
ACMEPROXY_ENDPOINT=""
_err "You didn't specify the endpoint"
_err "Please set them via 'export ACMEPROXY_ENDPOINT=https://ip:port' and try again."
return 1
fi
## Save the credentials to the account file
_saveaccountconf_mutable ACMEPROXY_ENDPOINT "$ACMEPROXY_ENDPOINT"
_saveaccountconf_mutable ACMEPROXY_USERNAME "$ACMEPROXY_USERNAME"
_saveaccountconf_mutable ACMEPROXY_PASSWORD "$ACMEPROXY_PASSWORD"
if [ -z "$ACMEPROXY_USERNAME" ] || [ -z "$ACMEPROXY_PASSWORD" ]; then
_info "ACMEPROXY_USERNAME and/or ACMEPROXY_PASSWORD not set - using without client authentication! Make sure you're using server authentication (e.g. IP-based)"
export _H1="Accept: application/json"
export _H2="Content-Type: application/json"
else
## Base64 encode the credentials
credentials=$(printf "%b" "$ACMEPROXY_USERNAME:$ACMEPROXY_PASSWORD" | _base64)
## Construct the HTTP Authorization header
export _H1="Authorization: Basic $credentials"
export _H2="Accept: application/json"
export _H3="Content-Type: application/json"
fi
## Add the challenge record to the acmeproxy grid member
response="$(_post "{\"fqdn\": \"$fulldomain.\", \"value\": \"$txtvalue\"}" "$ACMEPROXY_ENDPOINT/$action" "" "POST")"
## Let's see if we get something intelligible back from the unit
if echo "$response" | grep "\"$txtvalue\"" >/dev/null; then
_info "Successfully updated the txt record"
return 0
else
_err "Error encountered during record addition"
_err "$response"
return 1
fi
}
#################### Private functions below ##################################

141
dnsapi/dns_active24.sh Executable file
View File

@@ -0,0 +1,141 @@
#!/usr/bin/env sh
#ACTIVE24_Token="sdfsdfsdfljlbjkljlkjsdfoiwje"
ACTIVE24_Api="https://api.active24.com"
######## Public functions #####################
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Used to add txt record
dns_active24_add() {
fulldomain=$1
txtvalue=$2
_active24_init
_info "Adding txt record"
if _active24_rest POST "dns/$_domain/txt/v1" "{\"name\":\"$_sub_domain\",\"text\":\"$txtvalue\",\"ttl\":0}"; then
if _contains "$response" "errors"; then
_err "Add txt record error."
return 1
else
_info "Added, OK"
return 0
fi
fi
_err "Add txt record error."
return 1
}
# Usage: fulldomain txtvalue
# Used to remove the txt record after validation
dns_active24_rm() {
fulldomain=$1
txtvalue=$2
_active24_init
_debug "Getting txt records"
_active24_rest GET "dns/$_domain/records/v1"
if _contains "$response" "errors"; then
_err "Error"
return 1
fi
hash_ids=$(echo "$response" | _egrep_o "[^{]+${txtvalue}[^}]+" | _egrep_o "hashId\":\"[^\"]+" | cut -c10-)
for hash_id in $hash_ids; do
_debug "Removing hash_id" "$hash_id"
if _active24_rest DELETE "dns/$_domain/$hash_id/v1" ""; then
if _contains "$response" "errors"; then
_err "Unable to remove txt record."
return 1
else
_info "Removed txt record."
return 0
fi
fi
done
_err "No txt records found."
return 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
if ! _active24_rest GET "dns/domains/v1"; then
return 1
fi
i=2
p=1
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" "\"$h\"" >/dev/null; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_active24_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
export _H1="Authorization: Bearer $ACTIVE24_Token"
if [ "$m" != "GET" ]; then
_debug "data" "$data"
response="$(_post "$data" "$ACTIVE24_Api/$ep" "" "$m" "application/json")"
else
response="$(_get "$ACTIVE24_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}
_active24_init() {
ACTIVE24_Token="${ACTIVE24_Token:-$(_readaccountconf_mutable ACTIVE24_Token)}"
if [ -z "$ACTIVE24_Token" ]; then
ACTIVE24_Token=""
_err "You didn't specify a Active24 api token yet."
_err "Please create the token and try again."
return 1
fi
_saveaccountconf_mutable ACTIVE24_Token "$ACTIVE24_Token"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
}

View File

@@ -10,6 +10,8 @@ dns_ali_add() {
fulldomain=$1
txtvalue=$2
Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}"
Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}"
if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then
Ali_Key=""
Ali_Secret=""
@@ -18,8 +20,8 @@ dns_ali_add() {
fi
#save the api key and secret to the account conf file.
_saveaccountconf Ali_Key "$Ali_Key"
_saveaccountconf Ali_Secret "$Ali_Secret"
_saveaccountconf_mutable Ali_Key "$Ali_Key"
_saveaccountconf_mutable Ali_Secret "$Ali_Secret"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
@@ -32,6 +34,15 @@ dns_ali_add() {
dns_ali_rm() {
fulldomain=$1
txtvalue=$2
Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}"
Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
return 1
fi
_clean
}
@@ -76,16 +87,14 @@ _ali_rest() {
return 1
fi
_debug2 response "$response"
if [ -z "$2" ]; then
message="$(printf "%s" "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")"
if [ -n "$message" ]; then
message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")"
if [ "$message" ]; then
_err "$message"
return 1
fi
fi
_debug2 response "$response"
return 0
}
_ali_urlencode() {
@@ -112,12 +121,14 @@ _ali_nonce() {
}
_check_exist_query() {
_qdomain="$1"
_qsubdomain="$2"
query=''
query=$query'AccessKeyId='$Ali_Key
query=$query'&Action=DescribeDomainRecords'
query=$query'&DomainName='$1
query=$query'&DomainName='$_qdomain
query=$query'&Format=json'
query=$query'&RRKeyWord=_acme-challenge'
query=$query'&RRKeyWord='$_qsubdomain
query=$query'&SignatureMethod=HMAC-SHA1'
query=$query"&SignatureNonce=$(_ali_nonce)"
query=$query'&SignatureVersion=1.0'
@@ -169,17 +180,21 @@ _describe_records_query() {
}
_clean() {
_check_exist_query "$_domain"
_check_exist_query "$_domain" "$_sub_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
record_id="$(echo "$response" | tr '{' "\n" | grep "$_sub_domain" | grep "$txtvalue" | tr "," "\n" | grep RecordId | cut -d '"' -f 4)"
_debug2 record_id "$record_id"
if [ -z "$record_id" ]; then
_debug "record not found, skip"
else
_delete_record_query "$record_id"
_ali_rest "Delete record $record_id" "ignore"
fi
}
_timestamp() {

264
dnsapi/dns_autodns.sh Normal file
View File

@@ -0,0 +1,264 @@
#!/usr/bin/env sh
# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*-
# This is the InternetX autoDNS xml api wrapper for acme.sh
# Author: auerswald@gmail.com
# Created: 2018-01-14
#
# export AUTODNS_USER="username"
# export AUTODNS_PASSWORD="password"
# export AUTODNS_CONTEXT="context"
#
# Usage:
# acme.sh --issue --dns dns_autodns -d example.com
AUTODNS_API="https://gateway.autodns.com"
# Arguments:
# txtdomain
# txt
dns_autodns_add() {
fulldomain="$1"
txtvalue="$2"
AUTODNS_USER="${AUTODNS_USER:-$(_readaccountconf_mutable AUTODNS_USER)}"
AUTODNS_PASSWORD="${AUTODNS_PASSWORD:-$(_readaccountconf_mutable AUTODNS_PASSWORD)}"
AUTODNS_CONTEXT="${AUTODNS_CONTEXT:-$(_readaccountconf_mutable AUTODNS_CONTEXT)}"
if [ -z "$AUTODNS_USER" ] || [ -z "$AUTODNS_CONTEXT" ] || [ -z "$AUTODNS_PASSWORD" ]; then
_err "You don't specify autodns user, password and context."
return 1
fi
_saveaccountconf_mutable AUTODNS_USER "$AUTODNS_USER"
_saveaccountconf_mutable AUTODNS_PASSWORD "$AUTODNS_PASSWORD"
_saveaccountconf_mutable AUTODNS_CONTEXT "$AUTODNS_CONTEXT"
_debug "First detect the root zone"
if ! _get_autodns_zone "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _zone "$_zone"
_debug _system_ns "$_system_ns"
_info "Adding TXT record"
autodns_response="$(_autodns_zone_update "$_zone" "$_sub_domain" "$txtvalue" "$_system_ns")"
if [ "$?" -eq "0" ]; then
_info "Added, OK"
return 0
fi
return 1
}
# Arguments:
# txtdomain
# txt
dns_autodns_rm() {
fulldomain="$1"
txtvalue="$2"
AUTODNS_USER="${AUTODNS_USER:-$(_readaccountconf_mutable AUTODNS_USER)}"
AUTODNS_PASSWORD="${AUTODNS_PASSWORD:-$(_readaccountconf_mutable AUTODNS_PASSWORD)}"
AUTODNS_CONTEXT="${AUTODNS_CONTEXT:-$(_readaccountconf_mutable AUTODNS_CONTEXT)}"
if [ -z "$AUTODNS_USER" ] || [ -z "$AUTODNS_CONTEXT" ] || [ -z "$AUTODNS_PASSWORD" ]; then
_err "You don't specify autodns user, password and context."
return 1
fi
_debug "First detect the root zone"
if ! _get_autodns_zone "$fulldomain"; then
_err "zone not found"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _zone "$_zone"
_debug _system_ns "$_system_ns"
_info "Delete TXT record"
autodns_response="$(_autodns_zone_cleanup "$_zone" "$_sub_domain" "$txtvalue" "$_system_ns")"
if [ "$?" -eq "0" ]; then
_info "Deleted, OK"
return 0
fi
return 1
}
#################### Private functions below ##################################
# Arguments:
# fulldomain
# Returns:
# _sub_domain=_acme-challenge.www
# _zone=domain.com
# _system_ns
_get_autodns_zone() {
domain="$1"
i=2
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
# not valid
return 1
fi
autodns_response="$(_autodns_zone_inquire "$h")"
if [ "$?" -ne "0" ]; then
_err "invalid domain"
return 1
fi
if _contains "$autodns_response" "<summary>1</summary>" >/dev/null; then
_zone="$(echo "$autodns_response" | _egrep_o '<name>[^<]*</name>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
_system_ns="$(echo "$autodns_response" | _egrep_o '<system_ns>[^<]*</system_ns>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_build_request_auth_xml() {
printf "<auth>
<user>%s</user>
<password>%s</password>
<context>%s</context>
</auth>" "$AUTODNS_USER" "$AUTODNS_PASSWORD" "$AUTODNS_CONTEXT"
}
# Arguments:
# zone
_build_zone_inquire_xml() {
printf "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<request>
%s
<task>
<code>0205</code>
<view>
<children>1</children>
<limit>1</limit>
</view>
<where>
<key>name</key>
<operator>eq</operator>
<value>%s</value>
</where>
</task>
</request>" "$(_build_request_auth_xml)" "$1"
}
# Arguments:
# zone
# subdomain
# txtvalue
# system_ns
_build_zone_update_xml() {
printf "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<request>
%s
<task>
<code>0202001</code>
<default>
<rr_add>
<name>%s</name>
<ttl>600</ttl>
<type>TXT</type>
<value>%s</value>
</rr_add>
</default>
<zone>
<name>%s</name>
<system_ns>%s</system_ns>
</zone>
</task>
</request>" "$(_build_request_auth_xml)" "$2" "$3" "$1" "$4"
}
# Arguments:
# zone
_autodns_zone_inquire() {
request_data="$(_build_zone_inquire_xml "$1")"
autodns_response="$(_autodns_api_call "$request_data")"
ret="$?"
printf "%s" "$autodns_response"
return "$ret"
}
# Arguments:
# zone
# subdomain
# txtvalue
# system_ns
_autodns_zone_update() {
request_data="$(_build_zone_update_xml "$1" "$2" "$3" "$4")"
autodns_response="$(_autodns_api_call "$request_data")"
ret="$?"
printf "%s" "$autodns_response"
return "$ret"
}
# Arguments:
# zone
# subdomain
# txtvalue
# system_ns
_autodns_zone_cleanup() {
request_data="$(_build_zone_update_xml "$1" "$2" "$3" "$4")"
# replace 'rr_add>' with 'rr_rem>' in request_data
request_data="$(printf -- "%s" "$request_data" | sed 's/rr_add>/rr_rem>/g')"
autodns_response="$(_autodns_api_call "$request_data")"
ret="$?"
printf "%s" "$autodns_response"
return "$ret"
}
# Arguments:
# request_data
_autodns_api_call() {
request_data="$1"
_debug request_data "$request_data"
autodns_response="$(_post "$request_data" "$AUTODNS_API")"
ret="$?"
_debug autodns_response "$autodns_response"
if [ "$ret" -ne "0" ]; then
_err "error"
return 1
fi
if _contains "$autodns_response" "<type>success</type>" >/dev/null; then
_info "success"
printf "%s" "$autodns_response"
return 0
fi
return 1
}

View File

@@ -19,17 +19,25 @@ dns_aws_add() {
fulldomain=$1
txtvalue=$2
AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-$(_readaccountconf_mutable AWS_ACCESS_KEY_ID)}"
AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SECRET_ACCESS_KEY)}"
if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then
_use_container_role || _use_instance_role
fi
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)"
_err "You haven't specifed the aws route53 api key id and and api key secret yet."
_err "Please create your 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"
#save for future use, unless using a role which will be fetched as needed
if [ -z "$_using_role" ]; then
_saveaccountconf_mutable AWS_ACCESS_KEY_ID "$AWS_ACCESS_KEY_ID"
_saveaccountconf_mutable AWS_SECRET_ACCESS_KEY "$AWS_SECRET_ACCESS_KEY"
fi
_debug "First detect the root zone"
@@ -41,10 +49,29 @@ dns_aws_add() {
_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>"
_info "Getting existing records for $fulldomain"
if ! aws_rest GET "2013-04-01$_domain_id/rrset" "name=$fulldomain&type=TXT"; then
return 1
fi
if _contains "$response" "<Name>$fulldomain.</Name>"; then
_resource_record="$(echo "$response" | sed 's/<ResourceRecordSet>/"/g' | tr '"' "\n" | grep "<Name>$fulldomain.</Name>" | _egrep_o "<ResourceRecords.*</ResourceRecords>" | sed "s/<ResourceRecords>//" | sed "s#</ResourceRecords>##")"
_debug "_resource_record" "$_resource_record"
else
_debug "single new add"
fi
if [ "$_resource_record" ] && _contains "$response" "$txtvalue"; then
_info "The TXT record already exists. Skipping."
return 0
fi
_debug "Adding records"
_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>$_resource_record<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."
_info "TXT record updated successfully."
return 0
fi
@@ -56,6 +83,13 @@ dns_aws_rm() {
fulldomain=$1
txtvalue=$2
AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-$(_readaccountconf_mutable AWS_ACCESS_KEY_ID)}"
AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SECRET_ACCESS_KEY)}"
if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then
_use_container_role || _use_instance_role
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
@@ -65,10 +99,23 @@ dns_aws_rm() {
_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>"
_info "Getting existing records for $fulldomain"
if ! aws_rest GET "2013-04-01$_domain_id/rrset" "name=$fulldomain&type=TXT"; then
return 1
fi
if _contains "$response" "<Name>$fulldomain.</Name>"; then
_resource_record="$(echo "$response" | sed 's/<ResourceRecordSet>/"/g' | tr '"' "\n" | grep "<Name>$fulldomain.</Name>" | _egrep_o "<ResourceRecords.*</ResourceRecords>" | sed "s/<ResourceRecords>//" | sed "s#</ResourceRecords>##")"
_debug "_resource_record" "$_resource_record"
else
_debug "no records exist, skip"
return 0
fi
_aws_tmpl_xml="<ChangeResourceRecordSetsRequest xmlns=\"https://route53.amazonaws.com/doc/2013-04-01/\"><ChangeBatch><Changes><Change><Action>DELETE</Action><ResourceRecordSet><ResourceRecords>$_resource_record</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."
_info "TXT record deleted successfully."
return 0
fi
@@ -84,28 +131,41 @@ _get_root() {
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)
_debug2 "Checking domain: $h"
if [ -z "$h" ]; then
if _contains "$response" "<IsTruncated>true</IsTruncated>" && _contains "$response" "<NextMarker>"; then
_debug "IsTruncated"
_nextMarker="$(echo "$response" | _egrep_o "<NextMarker>.*</NextMarker>" | cut -d '>' -f 2 | cut -d '<' -f 1)"
_debug "NextMarker" "$_nextMarker"
if aws_rest GET "2013-04-01/hostedzone" "marker=$_nextMarker"; then
_debug "Truncated request OK"
i=2
p=1
continue
else
_err "Truncated request error."
fi
fi
#not valid
_err "Invalid domain"
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>")"
hostedzone="$(echo "$response" | sed 's/<HostedZone>/#&/g' | tr '#' '\n' | _egrep_o "<HostedZone><Id>[^<]*<.Id><Name>$h.<.Name>.*<PrivateZone>false<.PrivateZone>.*<.HostedZone>")"
_debug hostedzone "$hostedzone"
if [ -z "$hostedzone" ]; then
_err "Error, can not get hostedzone."
if [ "$hostedzone" ]; then
_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
_err "Can't find domain with id: $h"
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)
@@ -114,6 +174,55 @@ _get_root() {
return 1
}
_use_container_role() {
# automatically set if running inside ECS
if [ -z "$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" ]; then
_debug "No ECS environment variable detected"
return 1
fi
_use_metadata "169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
}
_use_instance_role() {
_url="http://169.254.169.254/latest/meta-data/iam/security-credentials/"
_debug "_url" "$_url"
if ! _get "$_url" true 1 | _head_n 1 | grep -Fq 200; then
_debug "Unable to fetch IAM role from instance metadata"
return 1
fi
_aws_role=$(_get "$_url" "" 1)
_debug "_aws_role" "$_aws_role"
_use_metadata "$_url$_aws_role"
}
_use_metadata() {
_aws_creds="$(
_get "$1" "" 1 \
| _normalizeJson \
| tr '{,}' '\n' \
| while read -r _line; do
_key="$(echo "${_line%%:*}" | tr -d '"')"
_value="${_line#*:}"
_debug3 "_key" "$_key"
_secure_debug3 "_value" "$_value"
case "$_key" in
AccessKeyId) echo "AWS_ACCESS_KEY_ID=$_value" ;;
SecretAccessKey) echo "AWS_SECRET_ACCESS_KEY=$_value" ;;
Token) echo "AWS_SESSION_TOKEN=$_value" ;;
esac
done \
| paste -sd' ' -
)"
_secure_debug "_aws_creds" "$_aws_creds"
if [ -z "$_aws_creds" ]; then
return 1
fi
eval "$_aws_creds"
_using_role=true
}
#method uri qstr data
aws_rest() {
mtd="$1"
@@ -143,7 +252,7 @@ aws_rest() {
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"
export _H3="x-amz-security-token: $AWS_SESSION_TOKEN"
CanonicalHeaders="${CanonicalHeaders}x-amz-security-token:$AWS_SESSION_TOKEN\n"
SignedHeaders="${SignedHeaders};x-amz-security-token"
fi
@@ -181,10 +290,10 @@ aws_rest() {
#kSecret="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY" ############################
_debug2 kSecret "$kSecret"
_secure_debug2 kSecret "$kSecret"
kSecretH="$(printf "%s" "$kSecret" | _hex_dump | tr -d " ")"
_debug2 kSecretH "$kSecretH"
_secure_debug2 kSecretH "$kSecretH"
kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)"
_debug2 kDateH "$kDateH"
@@ -195,7 +304,7 @@ aws_rest() {
kServiceH="$(printf "$Service%s" | _hmac "$Hash" "$kRegionH" hex)"
_debug2 kServiceH "$kServiceH"
kSigningH="$(printf "aws4_request%s" | _hmac "$Hash" "$kServiceH" hex)"
kSigningH="$(printf "%s" "aws4_request" | _hmac "$Hash" "$kServiceH" hex)"
_debug2 kSigningH "$kSigningH"
signature="$(printf "$StringToSign%s" | _hmac "$Hash" "$kSigningH" hex)"
@@ -204,10 +313,13 @@ aws_rest() {
Authorization="$Algorithm Credential=$AWS_ACCESS_KEY_ID/$CredentialScope, SignedHeaders=$SignedHeaders, Signature=$signature"
_debug2 Authorization "$Authorization"
_H3="Authorization: $Authorization"
_debug _H3 "$_H3"
_H2="Authorization: $Authorization"
_debug _H2 "$_H2"
url="$AWS_URL/$ep"
if [ "$qsr" ]; then
url="$AWS_URL/$ep?$qsr"
fi
if [ "$mtd" = "GET" ]; then
response="$(_get "$url")"
@@ -216,6 +328,7 @@ aws_rest() {
fi
_ret="$?"
_debug2 response "$response"
if [ "$_ret" = "0" ]; then
if _contains "$response" "<ErrorResponse"; then
_err "Response error:$response"

348
dnsapi/dns_azure.sh Normal file
View File

@@ -0,0 +1,348 @@
#!/usr/bin/env sh
WIKI="https://github.com/Neilpang/acme.sh/wiki/How-to-use-Azure-DNS"
######## Public functions #####################
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Used to add txt record
#
# Ref: https://docs.microsoft.com/en-us/rest/api/dns/recordsets/createorupdate
#
dns_azure_add() {
fulldomain=$1
txtvalue=$2
AZUREDNS_SUBSCRIPTIONID="${AZUREDNS_SUBSCRIPTIONID:-$(_readaccountconf_mutable AZUREDNS_SUBSCRIPTIONID)}"
AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}"
AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}"
AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}"
if [ -z "$AZUREDNS_SUBSCRIPTIONID" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
_err "You didn't specify the Azure Subscription ID "
return 1
fi
if [ -z "$AZUREDNS_TENANTID" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
_err "You didn't specify the Azure Tenant ID "
return 1
fi
if [ -z "$AZUREDNS_APPID" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
_err "You didn't specify the Azure App ID"
return 1
fi
if [ -z "$AZUREDNS_CLIENTSECRET" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
_err "You didn't specify the Azure Client Secret"
return 1
fi
#save account details to account conf file.
_saveaccountconf_mutable AZUREDNS_SUBSCRIPTIONID "$AZUREDNS_SUBSCRIPTIONID"
_saveaccountconf_mutable AZUREDNS_TENANTID "$AZUREDNS_TENANTID"
_saveaccountconf_mutable AZUREDNS_APPID "$AZUREDNS_APPID"
_saveaccountconf_mutable AZUREDNS_CLIENTSECRET "$AZUREDNS_CLIENTSECRET"
accesstoken=$(_azure_getaccess_token "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET")
if ! _get_root "$fulldomain" "$AZUREDNS_SUBSCRIPTIONID" "$accesstoken"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
acmeRecordURI="https://management.azure.com$(printf '%s' "$_domain_id" | sed 's/\\//g')/TXT/$_sub_domain?api-version=2017-09-01"
_debug "$acmeRecordURI"
# Get existing TXT record
_azure_rest GET "$acmeRecordURI" "" "$accesstoken"
values="{\"value\":[\"$txtvalue\"]}"
timestamp="$(_time)"
if [ "$_code" = "200" ]; then
vlist="$(echo "$response" | _egrep_o "\"value\"\\s*:\\s*\\[\\s*\"[^\"]*\"\\s*]" | cut -d : -f 2 | tr -d "[]\"")"
_debug "existing TXT found"
_debug "$vlist"
existingts="$(echo "$response" | _egrep_o "\"acmetscheck\"\\s*:\\s*\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d "\"")"
if [ -z "$existingts" ]; then
# the record was not created by acme.sh. Copy the exisiting entires
existingts=$timestamp
fi
_diff="$(_math "$timestamp - $existingts")"
_debug "existing txt age: $_diff"
# only use recently added records and discard if older than 2 hours because they are probably orphaned
if [ "$_diff" -lt 7200 ]; then
_debug "existing txt value: $vlist"
for v in $vlist; do
values="$values ,{\"value\":[\"$v\"]}"
done
fi
fi
# Add the txtvalue TXT Record
body="{\"properties\":{\"metadata\":{\"acmetscheck\":\"$timestamp\"},\"TTL\":10, \"TXTRecords\":[$values]}}"
_azure_rest PUT "$acmeRecordURI" "$body" "$accesstoken"
if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then
_info "validation value added"
return 0
else
_err "error adding validation value ($_code)"
return 1
fi
}
# Usage: fulldomain txtvalue
# Used to remove the txt record after validation
#
# Ref: https://docs.microsoft.com/en-us/rest/api/dns/recordsets/delete
#
dns_azure_rm() {
fulldomain=$1
txtvalue=$2
AZUREDNS_SUBSCRIPTIONID="${AZUREDNS_SUBSCRIPTIONID:-$(_readaccountconf_mutable AZUREDNS_SUBSCRIPTIONID)}"
AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}"
AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}"
AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}"
if [ -z "$AZUREDNS_SUBSCRIPTIONID" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
_err "You didn't specify the Azure Subscription ID "
return 1
fi
if [ -z "$AZUREDNS_TENANTID" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
_err "You didn't specify the Azure Tenant ID "
return 1
fi
if [ -z "$AZUREDNS_APPID" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
_err "You didn't specify the Azure App ID"
return 1
fi
if [ -z "$AZUREDNS_CLIENTSECRET" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
_err "You didn't specify the Azure Client Secret"
return 1
fi
accesstoken=$(_azure_getaccess_token "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET")
if ! _get_root "$fulldomain" "$AZUREDNS_SUBSCRIPTIONID" "$accesstoken"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
acmeRecordURI="https://management.azure.com$(printf '%s' "$_domain_id" | sed 's/\\//g')/TXT/$_sub_domain?api-version=2017-09-01"
_debug "$acmeRecordURI"
# Get existing TXT record
_azure_rest GET "$acmeRecordURI" "" "$accesstoken"
timestamp="$(_time)"
if [ "$_code" = "200" ]; then
vlist="$(echo "$response" | _egrep_o "\"value\"\\s*:\\s*\\[\\s*\"[^\"]*\"\\s*]" | cut -d : -f 2 | tr -d "[]\"" | grep -v "$txtvalue")"
values=""
comma=""
for v in $vlist; do
values="$values$comma{\"value\":[\"$v\"]}"
comma=","
done
if [ -z "$values" ]; then
# No values left remove record
_debug "removing validation record completely $acmeRecordURI"
_azure_rest DELETE "$acmeRecordURI" "" "$accesstoken"
if [ "$_code" = "200" ] || [ "$_code" = '204' ]; then
_info "validation record removed"
else
_err "error removing validation record ($_code)"
return 1
fi
else
# Remove only txtvalue from the TXT Record
body="{\"properties\":{\"metadata\":{\"acmetscheck\":\"$timestamp\"},\"TTL\":10, \"TXTRecords\":[$values]}}"
_azure_rest PUT "$acmeRecordURI" "$body" "$accesstoken"
if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then
_info "validation value removed"
return 0
else
_err "error removing validation value ($_code)"
return 1
fi
fi
fi
}
################### Private functions below ##################################
_azure_rest() {
m=$1
ep="$2"
data="$3"
accesstoken="$4"
MAX_REQUEST_RETRY_TIMES=5
_request_retry_times=0
while [ "${_request_retry_times}" -lt "$MAX_REQUEST_RETRY_TIMES" ]; do
_debug3 _request_retry_times "$_request_retry_times"
export _H1="authorization: Bearer $accesstoken"
export _H2="accept: application/json"
export _H3="Content-Type: application/json"
# clear headers from previous request to avoid getting wrong http code on timeouts
:>"$HTTP_HEADER"
_debug "$ep"
if [ "$m" != "GET" ]; then
_secure_debug2 "data $data"
response="$(_post "$data" "$ep" "" "$m")"
else
response="$(_get "$ep")"
fi
_ret="$?"
_secure_debug2 "response $response"
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
_debug "http response code $_code"
if [ "$_code" = "401" ]; then
# we have an invalid access token set to expired
_saveaccountconf_mutable AZUREDNS_TOKENVALIDTO "0"
_err "access denied make sure your Azure settings are correct. See $WIKI"
return 1
fi
# See https://docs.microsoft.com/en-us/azure/architecture/best-practices/retry-service-specific#general-rest-and-retry-guidelines for retryable HTTP codes
if [ "$_ret" != "0" ] || [ -z "$_code" ] || [ "$_code" = "408" ] || [ "$_code" = "500" ] || [ "$_code" = "503" ] || [ "$_code" = "504" ]; then
_request_retry_times="$(_math "$_request_retry_times" + 1)"
_info "REST call error $_code retrying $ep in $_request_retry_times s"
_sleep "$_request_retry_times"
continue
fi
break
done
if [ "$_request_retry_times" = "$MAX_REQUEST_RETRY_TIMES" ]; then
_err "Error Azure REST called was retried $MAX_REQUEST_RETRY_TIMES times."
_err "Calling $ep failed."
return 1
fi
response="$(echo "$response" | _normalizeJson)"
return 0
}
## Ref: https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-service-to-service#request-an-access-token
_azure_getaccess_token() {
tenantID=$1
clientID=$2
clientSecret=$3
accesstoken="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}"
expires_on="${AZUREDNS_TOKENVALIDTO:-$(_readaccountconf_mutable AZUREDNS_TOKENVALIDTO)}"
# can we reuse the bearer token?
if [ -n "$accesstoken" ] && [ -n "$expires_on" ]; then
if [ "$(_time)" -lt "$expires_on" ]; then
# brearer token is still valid - reuse it
_debug "reusing bearer token"
printf "%s" "$accesstoken"
return 0
else
_debug "bearer token expired"
fi
fi
_debug "getting new bearer token"
export _H1="accept: application/json"
export _H2="Content-Type: application/x-www-form-urlencoded"
body="resource=$(printf "%s" 'https://management.core.windows.net/' | _url_encode)&client_id=$(printf "%s" "$clientID" | _url_encode)&client_secret=$(printf "%s" "$clientSecret" | _url_encode)&grant_type=client_credentials"
_secure_debug2 "data $body"
response="$(_post "$body" "https://login.microsoftonline.com/$tenantID/oauth2/token" "" "POST")"
_ret="$?"
_secure_debug2 "response $response"
response="$(echo "$response" | _normalizeJson)"
accesstoken=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
expires_on=$(echo "$response" | _egrep_o "\"expires_on\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
if [ -z "$accesstoken" ]; then
_err "no acccess token received. Check your Azure settings see $WIKI"
return 1
fi
if [ "$_ret" != "0" ]; then
_err "error $response"
return 1
fi
_saveaccountconf_mutable AZUREDNS_BEARERTOKEN "$accesstoken"
_saveaccountconf_mutable AZUREDNS_TOKENVALIDTO "$expires_on"
printf "%s" "$accesstoken"
return 0
}
_get_root() {
domain=$1
subscriptionId=$2
accesstoken=$3
i=1
p=1
## Ref: https://docs.microsoft.com/en-us/rest/api/dns/zones/list
## returns up to 100 zones in one response therefore handling more results is not not implemented
## (ZoneListResult with continuation token for the next page of results)
## Per https://docs.microsoft.com/en-us/azure/azure-subscription-service-limits#dns-limits you are limited to 100 Zone/subscriptions anyways
##
_azure_rest GET "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Network/dnszones?\$top=500&api-version=2017-09-01" "" "$accesstoken"
# Find matching domain name in Json response
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug2 "Checking domain: $h"
if [ -z "$h" ]; then
#not valid
_err "Invalid domain"
return 1
fi
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
_domain_id=$(echo "$response" | _egrep_o "\\{\"id\":\"[^\"]*\\/$h\"" | head -n 1 | cut -d : -f 2 | tr -d \")
if [ "$_domain_id" ]; then
if [ "$i" = 1 ]; then
#create the record at the domain apex (@) if only the domain name was provided as --domain-alias
_sub_domain="@"
else
_sub_domain=$(echo "$domain" | cut -d . -f 1-$p)
fi
_domain=$h
return 0
fi
return 1
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}

View File

@@ -14,11 +14,14 @@ dns_cf_add() {
fulldomain=$1
txtvalue=$2
_getdnsapiconf CF_Key
_getdnsapiconf CF_Email
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."
_err "You didn't specify a Cloudflare api key and email yet."
_err "You can get yours from here https://dash.cloudflare.com/profile."
return 1
fi
@@ -29,8 +32,8 @@ dns_cf_add() {
fi
#save the api key and email to the account conf file.
_saveaccountconf CF_Key "$CF_Key"
_saveaccountconf CF_Email "$CF_Email"
_savednsapiconf CF_Key "$CF_Key"
_savednsapiconf CF_Email "$CF_Email"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
@@ -49,33 +52,39 @@ dns_cf_add() {
return 1
fi
count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2)
_debug count "$count"
if [ "$count" = "0" ]; then
_info "Adding record"
if _cf_rest POST "zones/$_domain_id/dns_records" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
if printf -- "%s" "$response" | grep "$fulldomain" >/dev/null; then
_info "Added, OK"
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 | 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, OK"
# For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so
# we can not use updating anymore.
# count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2)
# _debug count "$count"
# if [ "$count" = "0" ]; then
_info "Adding record"
if _cf_rest POST "zones/$_domain_id/dns_records" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
if _contains "$response" "$txtvalue"; then
_info "Added, OK"
return 0
elif _contains "$response" "The record already exists"; then
_info "Already exists, OK"
return 0
else
_err "Add txt record error."
return 1
fi
_err "Update error"
return 1
fi
_err "Add txt record error."
return 1
# else
# _info "Updating record"
# record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1)
# _debug "record_id" "$record_id"
#
# _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, OK"
# return 0
# fi
# _err "Update error"
# return 1
# fi
}
@@ -83,6 +92,17 @@ dns_cf_add() {
dns_cf_rm() {
fulldomain=$1
txtvalue=$2
_getdnsapiconf CF_Key
_getdnsapiconf CF_Email
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
CF_Key=""
CF_Email=""
_err "You didn't specify a Cloudflare api key and email yet."
_err "You can get yours from here https://dash.cloudflare.com/profile."
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
@@ -128,7 +148,7 @@ dns_cf_rm() {
# _domain_id=sdjkglgdfewsdfg
_get_root() {
domain=$1
i=2
i=1
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
@@ -142,8 +162,8 @@ _get_root() {
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 _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_count":1'; then
_domain_id=$(echo "$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
@@ -163,8 +183,11 @@ _cf_rest() {
data="$3"
_debug "$ep"
export _H1="X-Auth-Email: $CF_Email"
export _H2="X-Auth-Key: $CF_Key"
email_trimmed=$(echo $CF_Email | tr -d '"')
key_trimmed=$(echo $CF_Key | tr -d '"')
export _H1="X-Auth-Email: $email_trimmed"
export _H2="X-Auth-Key: $key_trimmed"
export _H3="Content-Type: application/json"
if [ "$m" != "GET" ]; then

184
dnsapi/dns_cloudns.sh Executable file
View File

@@ -0,0 +1,184 @@
#!/usr/bin/env sh
# Author: Boyan Peychev <boyan at cloudns dot net>
# Repository: https://github.com/ClouDNS/acme.sh/
#CLOUDNS_AUTH_ID=XXXXX
#CLOUDNS_SUB_AUTH_ID=XXXXX
#CLOUDNS_AUTH_PASSWORD="YYYYYYYYY"
CLOUDNS_API="https://api.cloudns.net"
######## Public functions #####################
#Usage: dns_cloudns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_cloudns_add() {
_info "Using cloudns"
if ! _dns_cloudns_init_check; then
return 1
fi
zone="$(_dns_cloudns_get_zone_name "$1")"
if [ -z "$zone" ]; then
_err "Missing DNS zone at ClouDNS. Please log into your control panel and create the required DNS zone for the initial setup."
return 1
fi
host="$(echo "$1" | sed "s/\.$zone\$//")"
record=$2
_debug zone "$zone"
_debug host "$host"
_debug record "$record"
_info "Adding the TXT record for $1"
_dns_cloudns_http_api_call "dns/add-record.json" "domain-name=$zone&record-type=TXT&host=$host&record=$record&ttl=60"
if ! _contains "$response" "\"status\":\"Success\""; then
_err "Record cannot be added."
return 1
fi
_info "Added."
return 0
}
#Usage: dns_cloudns_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_cloudns_rm() {
_info "Using cloudns"
if ! _dns_cloudns_init_check; then
return 1
fi
if [ -z "$zone" ]; then
zone="$(_dns_cloudns_get_zone_name "$1")"
if [ -z "$zone" ]; then
_err "Missing DNS zone at ClouDNS. Please log into your control panel and create the required DNS zone for the initial setup."
return 1
fi
fi
host="$(echo "$1" | sed "s/\.$zone\$//")"
record=$2
_dns_cloudns_http_api_call "dns/records.json" "domain-name=$zone&host=$host&type=TXT"
if ! _contains "$response" "\"id\":"; then
return 1
fi
for i in $(echo "$response" | tr '{' "\n" | grep "$record"); do
record_id=$(echo "$i" | tr ',' "\n" | grep -E '^"id"' | sed -re 's/^\"id\"\:\"([0-9]+)\"$/\1/g')
if [ ! -z "$record_id" ]; then
_debug zone "$zone"
_debug host "$host"
_debug record "$record"
_debug record_id "$record_id"
_info "Deleting the TXT record for $1"
_dns_cloudns_http_api_call "dns/delete-record.json" "domain-name=$zone&record-id=$record_id"
if ! _contains "$response" "\"status\":\"Success\""; then
_err "The TXT record for $1 cannot be deleted."
else
_info "Deleted."
fi
fi
done
return 0
}
#################### Private functions below ##################################
_dns_cloudns_init_check() {
if [ ! -z "$CLOUDNS_INIT_CHECK_COMPLETED" ]; then
return 0
fi
CLOUDNS_AUTH_ID="${CLOUDNS_AUTH_ID:-$(_readaccountconf_mutable CLOUDNS_AUTH_ID)}"
CLOUDNS_SUB_AUTH_ID="${CLOUDNS_SUB_AUTH_ID:-$(_readaccountconf_mutable CLOUDNS_SUB_AUTH_ID)}"
CLOUDNS_AUTH_PASSWORD="${CLOUDNS_AUTH_PASSWORD:-$(_readaccountconf_mutable CLOUDNS_AUTH_PASSWORD)}"
if [ -z "$CLOUDNS_AUTH_ID$CLOUDNS_SUB_AUTH_ID" ] || [ -z "$CLOUDNS_AUTH_PASSWORD" ]; then
CLOUDNS_AUTH_ID=""
CLOUDNS_SUB_AUTH_ID=""
CLOUDNS_AUTH_PASSWORD=""
_err "You don't specify cloudns api id and password yet."
_err "Please create you id and password and try again."
return 1
fi
if [ -z "$CLOUDNS_AUTH_ID" ] && [ -z "$CLOUDNS_SUB_AUTH_ID" ]; then
_err "CLOUDNS_AUTH_ID or CLOUDNS_SUB_AUTH_ID is not configured"
return 1
fi
if [ -z "$CLOUDNS_AUTH_PASSWORD" ]; then
_err "CLOUDNS_AUTH_PASSWORD is not configured"
return 1
fi
_dns_cloudns_http_api_call "dns/login.json" ""
if ! _contains "$response" "\"status\":\"Success\""; then
_err "Invalid CLOUDNS_AUTH_ID or CLOUDNS_AUTH_PASSWORD. Please check your login credentials."
return 1
fi
# save the api id and password to the account conf file.
_saveaccountconf_mutable CLOUDNS_AUTH_ID "$CLOUDNS_AUTH_ID"
_saveaccountconf_mutable CLOUDNS_SUB_AUTH_ID "$CLOUDNS_SUB_AUTH_ID"
_saveaccountconf_mutable CLOUDNS_AUTH_PASSWORD "$CLOUDNS_AUTH_PASSWORD"
CLOUDNS_INIT_CHECK_COMPLETED=1
return 0
}
_dns_cloudns_get_zone_name() {
i=2
while true; do
zoneForCheck=$(printf "%s" "$1" | cut -d . -f $i-100)
if [ -z "$zoneForCheck" ]; then
return 1
fi
_debug zoneForCheck "$zoneForCheck"
_dns_cloudns_http_api_call "dns/get-zone-info.json" "domain-name=$zoneForCheck"
if ! _contains "$response" "\"status\":\"Failed\""; then
echo "$zoneForCheck"
return 0
fi
i=$(_math "$i" + 1)
done
return 1
}
_dns_cloudns_http_api_call() {
method=$1
_debug CLOUDNS_AUTH_ID "$CLOUDNS_AUTH_ID"
_debug CLOUDNS_SUB_AUTH_ID "$CLOUDNS_SUB_AUTH_ID"
_debug CLOUDNS_AUTH_PASSWORD "$CLOUDNS_AUTH_PASSWORD"
if [ ! -z "$CLOUDNS_SUB_AUTH_ID" ]; then
auth_user="sub-auth-id=$CLOUDNS_SUB_AUTH_ID"
else
auth_user="auth-id=$CLOUDNS_AUTH_ID"
fi
if [ -z "$2" ]; then
data="$auth_user&auth-password=$CLOUDNS_AUTH_PASSWORD"
else
data="$auth_user&auth-password=$CLOUDNS_AUTH_PASSWORD&$2"
fi
response="$(_get "$CLOUDNS_API/$method?$data")"
_debug response "$response"
return 0
}

157
dnsapi/dns_cn.sh Normal file
View File

@@ -0,0 +1,157 @@
#!/usr/bin/env sh
# DNS API for acme.sh for Core-Networks (https://beta.api.core-networks.de/doc/).
# created by 5ll and francis
CN_API="https://beta.api.core-networks.de"
######## Public functions #####################
dns_cn_add() {
fulldomain=$1
txtvalue=$2
if ! _cn_login; then
_err "login failed"
return 1
fi
_debug "First detect the root zone"
if ! _cn_get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug "_sub_domain $_sub_domain"
_debug "_domain $_domain"
_info "Adding record"
curData="{\"name\":\"$_sub_domain\",\"ttl\":120,\"type\":\"TXT\",\"data\":\"$txtvalue\"}"
curResult="$(_post "${curData}" "${CN_API}/dnszones/${_domain}/records/")"
_debug "curData $curData"
_debug "curResult $curResult"
if _contains "$curResult" ""; then
_info "Added, OK"
if ! _cn_commit; then
_err "commiting changes failed"
return 1
fi
return 0
else
_err "Add txt record error."
_debug "curData is $curData"
_debug "curResult is $curResult"
_err "error adding text record, response was $curResult"
return 1
fi
}
dns_cn_rm() {
fulldomain=$1
txtvalue=$2
if ! _cn_login; then
_err "login failed"
return 1
fi
_debug "First detect the root zone"
if ! _cn_get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_info "Deleting record"
curData="{\"name\":\"$_sub_domain\",\"data\":\"$txtvalue\"}"
curResult="$(_post "${curData}" "${CN_API}/dnszones/${_domain}/records/delete")"
_debug curData is "$curData"
_info "commiting changes"
if ! _cn_commit; then
_err "commiting changes failed"
return 1
fi
_info "Deletet txt record"
return 0
}
################### Private functions below ##################################
_cn_login() {
CN_User="${CN_User:-$(_readaccountconf_mutable CN_User)}"
CN_Password="${CN_Password:-$(_readaccountconf_mutable CN_Password)}"
if [ -z "$CN_User" ] || [ -z "$CN_Password" ]; then
CN_User=""
CN_Password=""
_err "You must export variables: CN_User and CN_Password"
return 1
fi
#save the config variables to the account conf file.
_saveaccountconf_mutable CN_User "$CN_User"
_saveaccountconf_mutable CN_Password "$CN_Password"
_info "Getting an AUTH-Token"
curData="{\"login\":\"${CN_User}\",\"password\":\"${CN_Password}\"}"
curResult="$(_post "${curData}" "${CN_API}/auth/token")"
_debug "Calling _CN_login: '${curData}' '${CN_API}/auth/token'"
if _contains "${curResult}" '"token":"'; then
authToken=$(echo "${curResult}" | cut -d ":" -f2 | cut -d "," -f1 | sed 's/^.\(.*\).$/\1/')
export _H1="Authorization: Bearer $authToken"
_info "Successfully acquired AUTH-Token"
_debug "AUTH-Token: '${authToken}'"
_debug "_H1 '${_H1}'"
else
_err "Couldn't acquire an AUTH-Token"
return 1
fi
}
# Commit changes
_cn_commit() {
_info "Commiting changes"
_post "" "${CN_API}/dnszones/$h/records/commit"
}
_cn_get_root() {
domain=$1
i=2
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
_debug _H1 "${_H1}"
if [ -z "$h" ]; then
#not valid
return 1
fi
_cn_zonelist="$(_get ${CN_API}/dnszones/)"
_debug _cn_zonelist "${_cn_zonelist}"
if [ "$?" != "0" ]; then
_err "something went wrong while getting the zone list"
return 1
fi
if _contains "$_cn_zonelist" "\"name\":\"$h\"" >/dev/null; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
else
_debug "Zonelist does not contain domain - iterating "
fi
p=$i
i=$(_math "$i" + 1)
done
_err "Zonelist does not contain domain - exiting"
return 1
}

253
dnsapi/dns_conoha.sh Executable file
View File

@@ -0,0 +1,253 @@
#!/usr/bin/env sh
CONOHA_DNS_EP_PREFIX_REGEXP="https://dns-service\."
######## Public functions #####################
#Usage: dns_conoha_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_conoha_add() {
fulldomain=$1
txtvalue=$2
_info "Using conoha"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_debug "Check uesrname and password"
CONOHA_Username="${CONOHA_Username:-$(_readaccountconf_mutable CONOHA_Username)}"
CONOHA_Password="${CONOHA_Password:-$(_readaccountconf_mutable CONOHA_Password)}"
CONOHA_TenantId="${CONOHA_TenantId:-$(_readaccountconf_mutable CONOHA_TenantId)}"
CONOHA_IdentityServiceApi="${CONOHA_IdentityServiceApi:-$(_readaccountconf_mutable CONOHA_IdentityServiceApi)}"
if [ -z "$CONOHA_Username" ] || [ -z "$CONOHA_Password" ] || [ -z "$CONOHA_TenantId" ] || [ -z "$CONOHA_IdentityServiceApi" ]; then
CONOHA_Username=""
CONOHA_Password=""
CONOHA_TenantId=""
CONOHA_IdentityServiceApi=""
_err "You didn't specify a conoha api username and password yet."
_err "Please create the user and try again."
return 1
fi
_saveaccountconf_mutable CONOHA_Username "$CONOHA_Username"
_saveaccountconf_mutable CONOHA_Password "$CONOHA_Password"
_saveaccountconf_mutable CONOHA_TenantId "$CONOHA_TenantId"
_saveaccountconf_mutable CONOHA_IdentityServiceApi "$CONOHA_IdentityServiceApi"
if token="$(_conoha_get_accesstoken "$CONOHA_IdentityServiceApi/tokens" "$CONOHA_Username" "$CONOHA_Password" "$CONOHA_TenantId")"; then
accesstoken="$(printf "%s" "$token" | sed -n 1p)"
CONOHA_Api="$(printf "%s" "$token" | sed -n 2p)"
else
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain" "$CONOHA_Api" "$accesstoken"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_info "Adding record"
body="{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"data\":\"$txtvalue\",\"ttl\":60}"
if _conoha_rest POST "$CONOHA_Api/v1/domains/$_domain_id/records" "$body" "$accesstoken"; then
if _contains "$response" '"data":"'"$txtvalue"'"'; then
_info "Added, OK"
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
return 1
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_conoha_rm() {
fulldomain=$1
txtvalue=$2
_info "Using conoha"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_debug "Check uesrname and password"
CONOHA_Username="${CONOHA_Username:-$(_readaccountconf_mutable CONOHA_Username)}"
CONOHA_Password="${CONOHA_Password:-$(_readaccountconf_mutable CONOHA_Password)}"
CONOHA_TenantId="${CONOHA_TenantId:-$(_readaccountconf_mutable CONOHA_TenantId)}"
CONOHA_IdentityServiceApi="${CONOHA_IdentityServiceApi:-$(_readaccountconf_mutable CONOHA_IdentityServiceApi)}"
if [ -z "$CONOHA_Username" ] || [ -z "$CONOHA_Password" ] || [ -z "$CONOHA_TenantId" ] || [ -z "$CONOHA_IdentityServiceApi" ]; then
CONOHA_Username=""
CONOHA_Password=""
CONOHA_TenantId=""
CONOHA_IdentityServiceApi=""
_err "You didn't specify a conoha api username and password yet."
_err "Please create the user and try again."
return 1
fi
_saveaccountconf_mutable CONOHA_Username "$CONOHA_Username"
_saveaccountconf_mutable CONOHA_Password "$CONOHA_Password"
_saveaccountconf_mutable CONOHA_TenantId "$CONOHA_TenantId"
_saveaccountconf_mutable CONOHA_IdentityServiceApi "$CONOHA_IdentityServiceApi"
if token="$(_conoha_get_accesstoken "$CONOHA_IdentityServiceApi/tokens" "$CONOHA_Username" "$CONOHA_Password" "$CONOHA_TenantId")"; then
accesstoken="$(printf "%s" "$token" | sed -n 1p)"
CONOHA_Api="$(printf "%s" "$token" | sed -n 2p)"
else
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain" "$CONOHA_Api" "$accesstoken"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
if ! _conoha_rest GET "$CONOHA_Api/v1/domains/$_domain_id/records" "" "$accesstoken"; then
_err "Error"
return 1
fi
record_id=$(printf "%s" "$response" | _egrep_o '{[^}]*}' \
| grep '"type":"TXT"' | grep "\"data\":\"$txtvalue\"" | _egrep_o "\"id\":\"[^\"]*\"" \
| _head_n 1 | cut -d : -f 2 | tr -d \")
if [ -z "$record_id" ]; then
_err "Can not get record id to remove."
return 1
fi
_debug record_id "$record_id"
_info "Removing the txt record"
if ! _conoha_rest DELETE "$CONOHA_Api/v1/domains/$_domain_id/records/$record_id" "" "$accesstoken"; then
_err "Delete record error."
return 1
fi
return 0
}
#################### Private functions below ##################################
_conoha_rest() {
m="$1"
ep="$2"
data="$3"
accesstoken="$4"
export _H1="Accept: application/json"
export _H2="Content-Type: application/json"
if [ -n "$accesstoken" ]; then
export _H3="X-Auth-Token: $accesstoken"
fi
_debug "$ep"
if [ "$m" != "GET" ]; then
_secure_debug2 data "$data"
response="$(_post "$data" "$ep" "" "$m")"
else
response="$(_get "$ep")"
fi
_ret="$?"
_secure_debug2 response "$response"
if [ "$_ret" != "0" ]; then
_err "error $ep"
return 1
fi
response="$(printf "%s" "$response" | _normalizeJson)"
return 0
}
_conoha_get_accesstoken() {
ep="$1"
username="$2"
password="$3"
tenantId="$4"
accesstoken="$(_readaccountconf_mutable conoha_accesstoken)"
expires="$(_readaccountconf_mutable conoha_tokenvalidto)"
CONOHA_Api="$(_readaccountconf_mutable conoha_dns_ep)"
# can we reuse the access token?
if [ -n "$accesstoken" ] && [ -n "$expires" ] && [ -n "$CONOHA_Api" ]; then
utc_date="$(_utc_date | sed "s/ /T/")"
if expr "$utc_date" "<" "$expires" >/dev/null; then
# access token is still valid - reuse it
_debug "reusing access token"
printf "%s\n%s\n" "$accesstoken" "$CONOHA_Api"
return 0
else
_debug "access token expired"
fi
fi
_debug "getting new access token"
body="$(printf '{"auth":{"passwordCredentials":{"username":"%s","password":"%s"},"tenantId":"%s"}}' "$username" "$password" "$tenantId")"
if ! _conoha_rest POST "$ep" "$body" ""; then
_err error "$response"
return 1
fi
accesstoken=$(printf "%s" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
expires=$(printf "%s" "$response" | _egrep_o "\"expires\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2-4 | tr -d \" | tr -d Z) #expect UTC
if [ -z "$accesstoken" ] || [ -z "$expires" ]; then
_err "no acccess token received. Check your Conoha settings see $WIKI"
return 1
fi
_saveaccountconf_mutable conoha_accesstoken "$accesstoken"
_saveaccountconf_mutable conoha_tokenvalidto "$expires"
CONOHA_Api=$(printf "%s" "$response" | _egrep_o 'publicURL":"'"$CONOHA_DNS_EP_PREFIX_REGEXP"'[^"]*"' | _head_n 1 | cut -d : -f 2-3 | tr -d \")
if [ -z "$CONOHA_Api" ]; then
_err "failed to get conoha dns endpoint url"
return 1
fi
_saveaccountconf_mutable conoha_dns_ep "$CONOHA_Api"
printf "%s\n%s\n" "$accesstoken" "$CONOHA_Api"
return 0
}
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
# _domain_id=sdjkglgdfewsdfg
_get_root() {
domain="$1"
ep="$2"
accesstoken="$3"
i=2
p=1
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 ! _conoha_rest GET "$ep/v1/domains?name=$h" "" "$accesstoken"; 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=$(_math "$i" + 1)
done
return 1
}

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env sh
# Cloudxns.com Domain api
# CloudXNS Domain api
#
#CX_Key="1234"
#
@@ -16,10 +16,12 @@ dns_cx_add() {
fulldomain=$1
txtvalue=$2
CX_Key="${CX_Key:-$(_readaccountconf_mutable CX_Key)}"
CX_Secret="${CX_Secret:-$(_readaccountconf_mutable CX_Secret)}"
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 "You don't specify cloudxns.net api key or secret yet."
_err "Please create you key and try again."
return 1
fi
@@ -27,8 +29,8 @@ dns_cx_add() {
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"
_saveaccountconf_mutable CX_Key "$CX_Key"
_saveaccountconf_mutable CX_Secret "$CX_Secret"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
@@ -36,33 +38,20 @@ dns_cx_add() {
return 1
fi
existing_records "$_domain" "$_sub_domain"
_debug count "$count"
if [ "$?" != "0" ]; then
_err "Error get existing records."
return 1
fi
if [ "$count" = "0" ]; then
add_record "$_domain" "$_sub_domain" "$txtvalue"
else
update_record "$_domain" "$_sub_domain" "$txtvalue"
fi
if [ "$?" = "0" ]; then
return 0
fi
return 1
add_record "$_domain" "$_sub_domain" "$txtvalue"
}
#fulldomain
#fulldomain txtvalue
dns_cx_rm() {
fulldomain=$1
txtvalue=$2
CX_Key="${CX_Key:-$(_readaccountconf_mutable CX_Key)}"
CX_Secret="${CX_Secret:-$(_readaccountconf_mutable CX_Secret)}"
REST_API="$CX_Api"
if _get_root "$fulldomain"; then
record_id=""
existing_records "$_domain" "$_sub_domain"
if ! [ "$record_id" = "" ]; then
existing_records "$_domain" "$_sub_domain" "$txtvalue"
if [ "$record_id" ]; then
_rest DELETE "record/$record_id/$_domain_id" "{}"
_info "Deleted record ${fulldomain}"
fi
@@ -77,7 +66,6 @@ existing_records() {
_debug "Getting txt records"
root=$1
sub=$2
count=0
if ! _rest GET "record/$_domain_id?:domain_id?host_id=0&offset=0&row_num=100"; then
return 1
fi
@@ -89,7 +77,6 @@ existing_records() {
fi
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 \" | _head_n 1)
_debug record_id "$record_id"
return 0
@@ -114,23 +101,6 @@ add_record() {
return 0
}
#update the txt record
#Usage: root sub txtvalue
update_record() {
root=$1
sub=$2
txtvalue=$3
fulldomain="$sub.$root"
_info "Updating record"
if _rest PUT "record/$record_id" "{\"domain_id\": $_domain_id, \"host\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"type\":\"TXT\",\"ttl\":600, \"line_id\":1}"; then
return 0
fi
return 1
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
@@ -209,8 +179,7 @@ _rest() {
return 1
fi
_debug2 response "$response"
if ! _contains "$response" '"message":"success"'; then
return 1
fi
return 0
_contains "$response" '"code":1'
}

328
dnsapi/dns_cyon.sh Normal file
View File

@@ -0,0 +1,328 @@
#!/usr/bin/env sh
########
# Custom cyon.ch DNS API for use with [acme.sh](https://github.com/Neilpang/acme.sh)
#
# Usage: acme.sh --issue --dns dns_cyon -d www.domain.com
#
# Dependencies:
# -------------
# - oathtool (When using 2 Factor Authentication)
#
# Issues:
# -------
# Any issues / questions / suggestions can be posted here:
# https://github.com/noplanman/cyon-api/issues
#
# Author: Armando Lüscher <armando@noplanman.ch>
########
dns_cyon_add() {
_cyon_load_credentials \
&& _cyon_load_parameters "$@" \
&& _cyon_print_header "add" \
&& _cyon_login \
&& _cyon_change_domain_env \
&& _cyon_add_txt \
&& _cyon_logout
}
dns_cyon_rm() {
_cyon_load_credentials \
&& _cyon_load_parameters "$@" \
&& _cyon_print_header "delete" \
&& _cyon_login \
&& _cyon_change_domain_env \
&& _cyon_delete_txt \
&& _cyon_logout
}
#########################
### PRIVATE FUNCTIONS ###
#########################
_cyon_load_credentials() {
# Convert loaded password to/from base64 as needed.
if [ "${CY_Password_B64}" ]; then
CY_Password="$(printf "%s" "${CY_Password_B64}" | _dbase64 "multiline")"
elif [ "${CY_Password}" ]; then
CY_Password_B64="$(printf "%s" "${CY_Password}" | _base64)"
fi
if [ -z "${CY_Username}" ] || [ -z "${CY_Password}" ]; then
# Dummy entries to satisfy script checker.
CY_Username=""
CY_Password=""
CY_OTP_Secret=""
_err ""
_err "You haven't set your cyon.ch login credentials yet."
_err "Please set the required cyon environment variables."
_err ""
return 1
fi
# Save the login credentials to the account.conf file.
_debug "Save credentials to account.conf"
_saveaccountconf CY_Username "${CY_Username}"
_saveaccountconf CY_Password_B64 "$CY_Password_B64"
if [ ! -z "${CY_OTP_Secret}" ]; then
_saveaccountconf CY_OTP_Secret "$CY_OTP_Secret"
else
_clearaccountconf CY_OTP_Secret
fi
}
_cyon_is_idn() {
_idn_temp="$(printf "%s" "${1}" | tr -d "0-9a-zA-Z.,-_")"
_idn_temp2="$(printf "%s" "${1}" | grep -o "xn--")"
[ "$_idn_temp" ] || [ "$_idn_temp2" ]
}
_cyon_load_parameters() {
# Read the required parameters to add the TXT entry.
# shellcheck disable=SC2018,SC2019
fulldomain="$(printf "%s" "${1}" | tr "A-Z" "a-z")"
fulldomain_idn="${fulldomain}"
# Special case for IDNs, as cyon needs a domain environment change,
# which uses the "pretty" instead of the punycode version.
if _cyon_is_idn "${fulldomain}"; then
if ! _exists idn; then
_err "Please install idn to process IDN names."
_err ""
return 1
fi
fulldomain="$(idn -u "${fulldomain}")"
fulldomain_idn="$(idn -a "${fulldomain}")"
fi
_debug fulldomain "${fulldomain}"
_debug fulldomain_idn "${fulldomain_idn}"
txtvalue="${2}"
_debug txtvalue "${txtvalue}"
# This header is required for curl calls.
_H1="X-Requested-With: XMLHttpRequest"
export _H1
}
_cyon_print_header() {
if [ "${1}" = "add" ]; then
_info ""
_info "+---------------------------------------------+"
_info "| Adding DNS TXT entry to your cyon.ch domain |"
_info "+---------------------------------------------+"
_info ""
_info " * Full Domain: ${fulldomain}"
_info " * TXT Value: ${txtvalue}"
_info ""
elif [ "${1}" = "delete" ]; then
_info ""
_info "+-------------------------------------------------+"
_info "| Deleting DNS TXT entry from your cyon.ch domain |"
_info "+-------------------------------------------------+"
_info ""
_info " * Full Domain: ${fulldomain}"
_info ""
fi
}
_cyon_get_cookie_header() {
printf "Cookie: %s" "$(grep "cyon=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'cyon=[^;]*;' | tr -d ';')"
}
_cyon_login() {
_info " - Logging in..."
username_encoded="$(printf "%s" "${CY_Username}" | _url_encode)"
password_encoded="$(printf "%s" "${CY_Password}" | _url_encode)"
login_url="https://my.cyon.ch/auth/index/dologin-async"
login_data="$(printf "%s" "username=${username_encoded}&password=${password_encoded}&pathname=%2F")"
login_response="$(_post "$login_data" "$login_url")"
_debug login_response "${login_response}"
# Bail if login fails.
if [ "$(printf "%s" "${login_response}" | _cyon_get_response_success)" != "success" ]; then
_err " $(printf "%s" "${login_response}" | _cyon_get_response_message)"
_err ""
return 1
fi
_info " success"
# NECESSARY!! Load the main page after login, to get the new cookie.
_H2="$(_cyon_get_cookie_header)"
export _H2
_get "https://my.cyon.ch/" >/dev/null
# todo: instead of just checking if the env variable is defined, check if we actually need to do a 2FA auth request.
# 2FA authentication with OTP?
if [ ! -z "${CY_OTP_Secret}" ]; then
_info " - Authorising with OTP code..."
if ! _exists oathtool; then
_err "Please install oathtool to use 2 Factor Authentication."
_err ""
return 1
fi
# Get OTP code with the defined secret.
otp_code="$(oathtool --base32 --totp "${CY_OTP_Secret}" 2>/dev/null)"
login_otp_url="https://my.cyon.ch/auth/multi-factor/domultifactorauth-async"
login_otp_data="totpcode=${otp_code}&pathname=%2F&rememberme=0"
login_otp_response="$(_post "$login_otp_data" "$login_otp_url")"
_debug login_otp_response "${login_otp_response}"
# Bail if OTP authentication fails.
if [ "$(printf "%s" "${login_otp_response}" | _cyon_get_response_success)" != "success" ]; then
_err " $(printf "%s" "${login_otp_response}" | _cyon_get_response_message)"
_err ""
return 1
fi
_info " success"
fi
_info ""
}
_cyon_logout() {
_info " - Logging out..."
_get "https://my.cyon.ch/auth/index/dologout" >/dev/null
_info " success"
_info ""
}
_cyon_change_domain_env() {
_info " - Changing domain environment..."
# Get the "example.com" part of the full domain name.
domain_env="$(printf "%s" "${fulldomain}" | sed -E -e 's/.*\.(.*\..*)$/\1/')"
_debug "Changing domain environment to ${domain_env}"
gloo_item_key="$(_get "https://my.cyon.ch/domain/" | tr '\n' ' ' | sed -E -e "s/.*data-domain=\"${domain_env}\"[^<]*data-itemkey=\"([^\"]*).*/\1/")"
_debug gloo_item_key "${gloo_item_key}"
domain_env_url="https://my.cyon.ch/user/environment/setdomain/d/${domain_env}/gik/${gloo_item_key}"
domain_env_response="$(_get "${domain_env_url}")"
_debug domain_env_response "${domain_env_response}"
if ! _cyon_check_if_2fa_missed "${domain_env_response}"; then return 1; fi
domain_env_success="$(printf "%s" "${domain_env_response}" | _egrep_o '"authenticated":\w*' | cut -d : -f 2)"
# Bail if domain environment change fails.
if [ "${domain_env_success}" != "true" ]; then
_err " $(printf "%s" "${domain_env_response}" | _cyon_get_response_message)"
_err ""
return 1
fi
_info " success"
_info ""
}
_cyon_add_txt() {
_info " - Adding DNS TXT entry..."
add_txt_url="https://my.cyon.ch/domain/dnseditor/add-record-async"
add_txt_data="zone=${fulldomain_idn}.&ttl=900&type=TXT&value=${txtvalue}"
add_txt_response="$(_post "$add_txt_data" "$add_txt_url")"
_debug add_txt_response "${add_txt_response}"
if ! _cyon_check_if_2fa_missed "${add_txt_response}"; then return 1; fi
add_txt_message="$(printf "%s" "${add_txt_response}" | _cyon_get_response_message)"
add_txt_status="$(printf "%s" "${add_txt_response}" | _cyon_get_response_status)"
# Bail if adding TXT entry fails.
if [ "${add_txt_status}" != "true" ]; then
_err " ${add_txt_message}"
_err ""
return 1
fi
_info " success (TXT|${fulldomain_idn}.|${txtvalue})"
_info ""
}
_cyon_delete_txt() {
_info " - Deleting DNS TXT entry..."
list_txt_url="https://my.cyon.ch/domain/dnseditor/list-async"
list_txt_response="$(_get "${list_txt_url}" | sed -e 's/data-hash/\\ndata-hash/g')"
_debug list_txt_response "${list_txt_response}"
if ! _cyon_check_if_2fa_missed "${list_txt_response}"; then return 1; fi
# Find and delete all acme challenge entries for the $fulldomain.
_dns_entries="$(printf "%b\n" "${list_txt_response}" | sed -n 's/data-hash=\\"\([^"]*\)\\" data-identifier=\\"\([^"]*\)\\".*/\1 \2/p')"
printf "%s" "${_dns_entries}" | while read -r _hash _identifier; do
dns_type="$(printf "%s" "$_identifier" | cut -d'|' -f1)"
dns_domain="$(printf "%s" "$_identifier" | cut -d'|' -f2)"
if [ "${dns_type}" != "TXT" ] || [ "${dns_domain}" != "${fulldomain_idn}." ]; then
continue
fi
hash_encoded="$(printf "%s" "${_hash}" | _url_encode)"
identifier_encoded="$(printf "%s" "${_identifier}" | _url_encode)"
delete_txt_url="https://my.cyon.ch/domain/dnseditor/delete-record-async"
delete_txt_data="$(printf "%s" "hash=${hash_encoded}&identifier=${identifier_encoded}")"
delete_txt_response="$(_post "$delete_txt_data" "$delete_txt_url")"
_debug delete_txt_response "${delete_txt_response}"
if ! _cyon_check_if_2fa_missed "${delete_txt_response}"; then return 1; fi
delete_txt_message="$(printf "%s" "${delete_txt_response}" | _cyon_get_response_message)"
delete_txt_status="$(printf "%s" "${delete_txt_response}" | _cyon_get_response_status)"
# Skip if deleting TXT entry fails.
if [ "${delete_txt_status}" != "true" ]; then
_err " ${delete_txt_message} (${_identifier})"
else
_info " success (${_identifier})"
fi
done
_info " done"
_info ""
}
_cyon_get_response_message() {
_egrep_o '"message":"[^"]*"' | cut -d : -f 2 | tr -d '"'
}
_cyon_get_response_status() {
_egrep_o '"status":\w*' | cut -d : -f 2
}
_cyon_get_response_success() {
_egrep_o '"onSuccess":"[^"]*"' | cut -d : -f 2 | tr -d '"'
}
_cyon_check_if_2fa_missed() {
# Did we miss the 2FA?
if test "${1#*multi_factor_form}" != "${1}"; then
_err " Missed OTP authentication!"
_err ""
return 1
fi
}

184
dnsapi/dns_da.sh Executable file
View File

@@ -0,0 +1,184 @@
#!/usr/bin/env sh
# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*-
# vim: et ts=2 sw=2
#
# DirectAdmin 1.41.0 API
# The DirectAdmin interface has it's own Let's encrypt functionality, but this
# script can be used to generate certificates for names which are not hosted on
# DirectAdmin
#
# User must provide login data and URL to DirectAdmin incl. port.
# You can create login key, by using the Login Keys function
# ( https://da.example.com:8443/CMD_LOGIN_KEYS ), which only has access to
# - CMD_API_DNS_CONTROL
# - CMD_API_SHOW_DOMAINS
#
# See also https://www.directadmin.com/api.php and
# https://www.directadmin.com/features.php?id=1298
#
# Report bugs to https://github.com/TigerP/acme.sh/issues
#
# Values to export:
# export DA_Api="https://remoteUser:remotePassword@da.example.com:8443"
# export DA_Api_Insecure=1
#
# Set DA_Api_Insecure to 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.example.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Used to add txt record
dns_da_add() {
fulldomain="${1}"
txtvalue="${2}"
_debug "Calling: dns_da_add() '${fulldomain}' '${txtvalue}'"
_DA_credentials && _DA_getDomainInfo && _DA_addTxt
}
# Usage: dns_da_rm _acme-challenge.www.example.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Used to remove the txt record after validation
dns_da_rm() {
fulldomain="${1}"
txtvalue="${2}"
_debug "Calling: dns_da_rm() '${fulldomain}' '${txtvalue}'"
_DA_credentials && _DA_getDomainInfo && _DA_rmTxt
}
#################### Private functions below ##################################
# Usage: _DA_credentials
# It will check if the needed settings are available
_DA_credentials() {
DA_Api="${DA_Api:-$(_readaccountconf_mutable DA_Api)}"
DA_Api_Insecure="${DA_Api_Insecure:-$(_readaccountconf_mutable DA_Api_Insecure)}"
if [ -z "${DA_Api}" ] || [ -z "${DA_Api_Insecure}" ]; then
DA_Api=""
DA_Api_Insecure=""
_err "You haven't specified the DirectAdmin Login data, URL and whether you want check the DirectAdmin SSL cert. Please try again."
return 1
else
_saveaccountconf_mutable DA_Api "${DA_Api}"
_saveaccountconf_mutable DA_Api_Insecure "${DA_Api_Insecure}"
# Set whether curl should use secure or insecure mode
export HTTPS_INSECURE="${DA_Api_Insecure}"
fi
}
# Usage: _get_root _acme-challenge.www.example.com
# Split the full domain to a domain and subdomain
#returns
# _sub_domain=_acme-challenge.www
# _domain=example.com
_get_root() {
domain=$1
i=2
p=1
# Get a list of all the domains
# response will contain "list[]=example.com&list[]=example.org"
_da_api CMD_API_SHOW_DOMAINS "" "${domain}"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
# not valid
_debug "The given domain $h is not valid"
return 1
fi
if _contains "$response" "$h" >/dev/null; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
_debug "Stop on 100"
return 1
}
# Usage: _da_api CMD_API_* data example.com
# Use the DirectAdmin API and check the result
# returns
# response="error=0&text=Result text&details="
_da_api() {
cmd=$1
data=$2
domain=$3
_debug "$domain; $data"
response="$(_post "$data" "$DA_Api/$cmd" "" "POST")"
if [ "$?" != "0" ]; then
_err "error $cmd"
return 1
fi
_debug response "$response"
case "${cmd}" in
CMD_API_DNS_CONTROL)
# Parse the result in general
# error=0&text=Records Deleted&details=
# error=1&text=Cannot View Dns Record&details=No domain provided
err_field="$(_getfield "$response" 1 '&')"
txt_field="$(_getfield "$response" 2 '&')"
details_field="$(_getfield "$response" 3 '&')"
error="$(_getfield "$err_field" 2 '=')"
text="$(_getfield "$txt_field" 2 '=')"
details="$(_getfield "$details_field" 2 '=')"
_debug "error: ${error}, text: ${text}, details: ${details}"
if [ "$error" != "0" ]; then
_err "error $response"
return 1
fi
;;
CMD_API_SHOW_DOMAINS) ;;
esac
return 0
}
# Usage: _DA_getDomainInfo
# Get the root zone if possible
_DA_getDomainInfo() {
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
else
_debug "The root domain: $_domain"
_debug "The sub domain: $_sub_domain"
fi
return 0
}
# Usage: _DA_addTxt
# Use the API to add a record
_DA_addTxt() {
curData="domain=${_domain}&action=add&type=TXT&name=${_sub_domain}&value=\"${txtvalue}\""
_debug "Calling _DA_addTxt: '${curData}' '${DA_Api}/CMD_API_DNS_CONTROL'"
_da_api CMD_API_DNS_CONTROL "${curData}" "${_domain}"
_debug "Result of _DA_addTxt: '$response'"
if _contains "${response}" 'error=0'; then
_debug "Add TXT succeeded"
return 0
fi
_debug "Add TXT failed"
return 1
}
# Usage: _DA_rmTxt
# Use the API to remove a record
_DA_rmTxt() {
curData="domain=${_domain}&action=select&txtrecs0=name=${_sub_domain}&amp;value=\"${txtvalue}\""
_debug "Calling _DA_rmTxt: '${curData}' '${DA_Api}/CMD_API_DNS_CONTROL'"
if _da_api CMD_API_DNS_CONTROL "${curData}" "${_domain}"; then
_debug "Result of _DA_rmTxt: '$response'"
else
_err "Result of _DA_rmTxt: '$response'"
fi
if _contains "${response}" 'error=0'; then
_debug "RM TXT succeeded"
return 0
fi
_debug "RM TXT failed"
return 1
}

130
dnsapi/dns_ddnss.sh Normal file
View File

@@ -0,0 +1,130 @@
#!/usr/bin/env sh
#Created by RaidenII, to use DuckDNS's API to add/remove text records
#modified by helbgd @ 03/13/2018 to support ddnss.de
#modified by mod242 @ 04/24/2018 to support different ddnss domains
#Please note: the Wildcard Feature must be turned on for the Host record
#and the checkbox for TXT needs to be enabled
# Pass credentials before "acme.sh --issue --dns dns_ddnss ..."
# --
# export DDNSS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
# --
#
DDNSS_DNS_API="https://ddnss.de/upd.php"
######## Public functions #####################
#Usage: dns_ddnss_add _acme-challenge.domain.ddnss.de "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_ddnss_add() {
fulldomain=$1
txtvalue=$2
DDNSS_Token="${DDNSS_Token:-$(_readaccountconf_mutable DDNSS_Token)}"
if [ -z "$DDNSS_Token" ]; then
_err "You must export variable: DDNSS_Token"
_err "The token for your DDNSS account is necessary."
_err "You can look it up in your DDNSS account."
return 1
fi
# Now save the credentials.
_saveaccountconf_mutable DDNSS_Token "$DDNSS_Token"
# Unfortunately, DDNSS does not seems to support lookup domain through API
# So I assume your credentials (which are your domain and token) are correct
# If something goes wrong, we will get a KO response from DDNSS
if ! _ddnss_get_domain; then
return 1
fi
# Now add the TXT record to DDNSS DNS
_info "Trying to add TXT record"
if _ddnss_rest GET "key=$DDNSS_Token&host=$_ddnss_domain&txtm=1&txt=$txtvalue"; then
if [ "$response" = "Updated 1 hostname." ]; then
_info "TXT record has been successfully added to your DDNSS domain."
_info "Note that all subdomains under this domain uses the same TXT record."
return 0
else
_err "Errors happened during adding the TXT record, response=$response"
return 1
fi
else
_err "Errors happened during adding the TXT record."
return 1
fi
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_ddnss_rm() {
fulldomain=$1
txtvalue=$2
DDNSS_Token="${DDNSS_Token:-$(_readaccountconf_mutable DDNSS_Token)}"
if [ -z "$DDNSS_Token" ]; then
_err "You must export variable: DDNSS_Token"
_err "The token for your DDNSS account is necessary."
_err "You can look it up in your DDNSS account."
return 1
fi
if ! _ddnss_get_domain; then
return 1
fi
# Now remove the TXT record from DDNS DNS
_info "Trying to remove TXT record"
if _ddnss_rest GET "key=$DDNSS_Token&host=$_ddnss_domain&txtm=1&txt=."; then
if [ "$response" = "Updated 1 hostname." ]; then
_info "TXT record has been successfully removed from your DDNSS domain."
return 0
else
_err "Errors happened during removing the TXT record, response=$response"
return 1
fi
else
_err "Errors happened during removing the TXT record."
return 1
fi
}
#################### Private functions below ##################################
#fulldomain=_acme-challenge.domain.ddnss.de
#returns
# _ddnss_domain=domain
_ddnss_get_domain() {
# We'll extract the domain/username from full domain
_ddnss_domain="$(echo "$fulldomain" | _lower_case | _egrep_o '[.][^.][^.]*[.](ddnss|dyn-ip24|dyndns|dyn|dyndns1|home-webserver|myhome-server|dynip)\..*' | cut -d . -f 2-)"
if [ -z "$_ddnss_domain" ]; then
_err "Error extracting the domain."
return 1
fi
return 0
}
#Usage: method URI
_ddnss_rest() {
method=$1
param="$2"
_debug param "$param"
url="$DDNSS_DNS_API?$param"
_debug url "$url"
# DDNSS uses GET to update domain info
if [ "$method" = "GET" ]; then
response="$(_get "$url" | sed 's/<[a-zA-Z\/][^>]*>//g' | _tail_n 1)"
else
_err "Unsupported method"
return 1
fi
_debug2 response "$response"
return 0
}

204
dnsapi/dns_desec.sh Normal file
View File

@@ -0,0 +1,204 @@
#!/usr/bin/env sh
#
# deSEC.io Domain API
#
# Author: Zheng Qian
#
# deSEC API doc
# https://desec.readthedocs.io/en/latest/
REST_API="https://desec.io/api/v1/domains"
######## Public functions #####################
#Usage: dns_desec_add _acme-challenge.foobar.dedyn.io "d41d8cd98f00b204e9800998ecf8427e"
dns_desec_add() {
fulldomain=$1
txtvalue=$2
_info "Using desec.io api"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
DEDYN_TOKEN="${DEDYN_TOKEN:-$(_readaccountconf_mutable DEDYN_TOKEN)}"
DEDYN_NAME="${DEDYN_NAME:-$(_readaccountconf_mutable DEDYN_NAME)}"
if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then
DEDYN_TOKEN=""
DEDYN_NAME=""
_err "You don't specify DEDYN_TOKEN and DEDYN_NAME yet."
_err "Please create you key and try again."
_err "e.g."
_err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e"
_err "export DEDYN_NAME=foobar.dedyn.io"
return 1
fi
#save the api token and name to the account conf file.
_saveaccountconf_mutable DEDYN_TOKEN "$DEDYN_TOKEN"
_saveaccountconf_mutable DEDYN_NAME "$DEDYN_NAME"
_debug "First detect the root zone"
if ! _get_root "$fulldomain" "$REST_API/"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
# Get existing TXT record
_debug "Getting txt records"
txtvalues="\"\\\"$txtvalue\\\"\""
_desec_rest GET "$REST_API/$DEDYN_NAME/rrsets/$_sub_domain/TXT/"
if [ "$_code" = "200" ]; then
oldtxtvalues="$(echo "$response" | _egrep_o "\"records\":\\[\"\\S*\"\\]" | cut -d : -f 2 | tr -d "[]\\\\\"" | sed "s/,/ /g")"
_debug "existing TXT found"
_debug oldtxtvalues "$oldtxtvalues"
if [ -n "$oldtxtvalues" ]; then
for oldtxtvalue in $oldtxtvalues; do
txtvalues="$txtvalues, \"\\\"$oldtxtvalue\\\"\""
done
fi
fi
_debug txtvalues "$txtvalues"
_info "Adding record"
body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":60}]"
if _desec_rest PUT "$REST_API/$DEDYN_NAME/rrsets/" "$body"; then
if _contains "$response" "$txtvalue"; then
_info "Added, OK"
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
return 1
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_desec_rm() {
fulldomain=$1
txtvalue=$2
_info "Using desec.io api"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
DEDYN_TOKEN="${DEDYN_TOKEN:-$(_readaccountconf_mutable DEDYN_TOKEN)}"
DEDYN_NAME="${DEDYN_NAME:-$(_readaccountconf_mutable DEDYN_NAME)}"
if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then
DEDYN_TOKEN=""
DEDYN_NAME=""
_err "You don't specify DEDYN_TOKEN and DEDYN_NAME yet."
_err "Please create you key and try again."
_err "e.g."
_err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e"
_err "export DEDYN_NAME=foobar.dedyn.io"
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain" "$REST_API/"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
# Get existing TXT record
_debug "Getting txt records"
txtvalues=""
_desec_rest GET "$REST_API/$DEDYN_NAME/rrsets/$_sub_domain/TXT/"
if [ "$_code" = "200" ]; then
oldtxtvalues="$(echo "$response" | _egrep_o "\"records\":\\[\"\\S*\"\\]" | cut -d : -f 2 | tr -d "[]\\\\\"" | sed "s/,/ /g")"
_debug "existing TXT found"
_debug oldtxtvalues "$oldtxtvalues"
if [ -n "$oldtxtvalues" ]; then
for oldtxtvalue in $oldtxtvalues; do
if [ "$txtvalue" != "$oldtxtvalue" ]; then
txtvalues="$txtvalues, \"\\\"$oldtxtvalue\\\"\""
fi
done
fi
fi
txtvalues="$(echo "$txtvalues" | cut -c3-)"
_debug txtvalues "$txtvalues"
_info "Deleting record"
body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":60}]"
_desec_rest PUT "$REST_API/$DEDYN_NAME/rrsets/" "$body"
if [ "$_code" = "200" ]; then
_info "Deleted, OK"
return 0
fi
_err "Delete txt record error."
return 1
}
#################### Private functions below ##################################
_desec_rest() {
m="$1"
ep="$2"
data="$3"
export _H1="Authorization: Token $DEDYN_TOKEN"
export _H2="Accept: application/json"
export _H3="Content-Type: application/json"
if [ "$m" != "GET" ]; then
_secure_debug2 data "$data"
response="$(_post "$data" "$ep" "" "$m")"
else
response="$(_get "$ep")"
fi
_ret="$?"
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
_debug "http response code $_code"
_secure_debug2 response "$response"
if [ "$_ret" != "0" ]; then
_err "error $ep"
return 1
fi
response="$(printf "%s" "$response" | _normalizeJson)"
return 0
}
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain="$1"
ep="$2"
i=2
p=1
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 ! _desec_rest GET "$ep"; then
return 1
fi
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}

250
dnsapi/dns_dgon.sh Executable file
View File

@@ -0,0 +1,250 @@
#!/usr/bin/env sh
## Will be called by acme.sh to add the txt record to your api system.
## returns 0 means success, otherwise error.
## Author: thewer <github at thewer.com>
## GitHub: https://github.com/gitwer/acme.sh
##
## Environment Variables Required:
##
## DO_API_KEY="75310dc4ca779ac39a19f6355db573b49ce92ae126553ebd61ac3a3ae34834cc"
##
##################### Public functions #####################
## Create the text record for validation.
## Usage: fulldomain txtvalue
## EG: "_acme-challenge.www.other.domain.com" "XKrxpRBosdq0HG9i01zxXp5CPBs"
dns_dgon_add() {
fulldomain="$(echo "$1" | _lower_case)"
txtvalue=$2
DO_API_KEY="${DO_API_KEY:-$(_readaccountconf_mutable DO_API_KEY)}"
# Check if API Key Exist
if [ -z "$DO_API_KEY" ]; then
DO_API_KEY=""
_err "You did not specify DigitalOcean API key."
_err "Please export DO_API_KEY and try again."
return 1
fi
_info "Using digitalocean dns validation - add record"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
## save the env vars (key and domain split location) for later automated use
_saveaccountconf_mutable DO_API_KEY "$DO_API_KEY"
## split the domain for DO API
if ! _get_base_domain "$fulldomain"; then
_err "domain not found in your account for addition"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
## Set the header with our post type and key auth key
export _H1="Content-Type: application/json"
export _H2="Authorization: Bearer $DO_API_KEY"
PURL='https://api.digitalocean.com/v2/domains/'$_domain'/records'
PBODY='{"type":"TXT","name":"'$_sub_domain'","data":"'$txtvalue'","ttl":120}'
_debug PURL "$PURL"
_debug PBODY "$PBODY"
## the create request - post
## args: BODY, URL, [need64, httpmethod]
response="$(_post "$PBODY" "$PURL")"
## check response
if [ "$?" != "0" ]; then
_err "error in response: $response"
return 1
fi
_debug2 response "$response"
## finished correctly
return 0
}
## Remove the txt record after validation.
## Usage: fulldomain txtvalue
## EG: "_acme-challenge.www.other.domain.com" "XKrxpRBosdq0HG9i01zxXp5CPBs"
dns_dgon_rm() {
fulldomain="$(echo "$1" | _lower_case)"
txtvalue=$2
DO_API_KEY="${DO_API_KEY:-$(_readaccountconf_mutable DO_API_KEY)}"
# Check if API Key Exist
if [ -z "$DO_API_KEY" ]; then
DO_API_KEY=""
_err "You did not specify DigitalOcean API key."
_err "Please export DO_API_KEY and try again."
return 1
fi
_info "Using digitalocean dns validation - remove record"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
## split the domain for DO API
if ! _get_base_domain "$fulldomain"; then
_err "domain not found in your account for removal"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
## Set the header with our post type and key auth key
export _H1="Content-Type: application/json"
export _H2="Authorization: Bearer $DO_API_KEY"
## get URL for the list of domains
## may get: "links":{"pages":{"last":".../v2/domains/DOM/records?page=2","next":".../v2/domains/DOM/records?page=2"}}
GURL="https://api.digitalocean.com/v2/domains/$_domain/records"
## Get all the matching records
while true; do
## 1) get the URL
## the create request - get
## args: URL, [onlyheader, timeout]
domain_list="$(_get "$GURL")"
## check response
if [ "$?" != "0" ]; then
_err "error in domain_list response: $domain_list"
return 1
fi
_debug2 domain_list "$domain_list"
## 2) find records
## check for what we are looking for: "type":"A","name":"$_sub_domain"
record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*[0-9]+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")"
if [ ! -z "$record" ]; then
## we found records
rec_ids="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")"
_debug rec_ids "$rec_ids"
if [ ! -z "$rec_ids" ]; then
echo "$rec_ids" | while IFS= read -r rec_id; do
## delete the record
## delete URL for removing the one we dont want
DURL="https://api.digitalocean.com/v2/domains/$_domain/records/$rec_id"
## the create request - delete
## args: BODY, URL, [need64, httpmethod]
response="$(_post "" "$DURL" "" "DELETE")"
## check response (sort of)
if [ "$?" != "0" ]; then
_err "error in remove response: $response"
return 1
fi
_debug2 response "$response"
done
fi
fi
## 3) find the next page
nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=[0-9]+")"
if [ -z "$nextpage" ]; then
break
fi
_debug2 nextpage "$nextpage"
GURL="$nextpage"
done
## finished correctly
return 0
}
##################### Private functions below #####################
## Split the domain provided into the "bade domain" and the "start prefix".
## This function searches for the longest subdomain in your account
## for the full domain given and splits it into the base domain (zone)
## and the prefix/record to be added/removed
## USAGE: fulldomain
## EG: "_acme-challenge.two.three.four.domain.com"
## returns
## _sub_domain="_acme-challenge.two"
## _domain="three.four.domain.com" *IF* zone "three.four.domain.com" exists
## if only "domain.com" exists it will return
## _sub_domain="_acme-challenge.two.three.four"
## _domain="domain.com"
_get_base_domain() {
# args
fulldomain="$(echo "$1" | _lower_case)"
_debug fulldomain "$fulldomain"
# domain max legal length = 253
MAX_DOM=255
## get a list of domains for the account to check thru
## Set the headers
export _H1="Content-Type: application/json"
export _H2="Authorization: Bearer $DO_API_KEY"
_debug DO_API_KEY "$DO_API_KEY"
## get URL for the list of domains
## may get: "links":{"pages":{"last":".../v2/domains/DOM/records?page=2","next":".../v2/domains/DOM/records?page=2"}}
DOMURL="https://api.digitalocean.com/v2/domains"
## while we dont have a matching domain we keep going
while [ -z "$found" ]; do
## get the domain list (current page)
domain_list="$(_get "$DOMURL")"
## check response
if [ "$?" != "0" ]; then
_err "error in domain_list response: $domain_list"
return 1
fi
_debug2 domain_list "$domain_list"
## for each shortening of our $fulldomain, check if it exists in the $domain_list
## can never start on 1 (aka whole $fulldomain) as $fulldomain starts with "_acme-challenge"
i=2
while [ $i -gt 0 ]; do
## get next longest domain
_domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM")
## check we got something back from our cut (or are we at the end)
if [ -z "$_domain" ]; then
break
fi
## we got part of a domain back - grep it out
found="$(echo "$domain_list" | _egrep_o "\"name\"\s*\:\s*\"$_domain\"")"
## check if it exists
if [ ! -z "$found" ]; then
## exists - exit loop returning the parts
sub_point=$(_math $i - 1)
_sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point")
_debug _domain "$_domain"
_debug _sub_domain "$_sub_domain"
return 0
fi
## increment cut point $i
i=$(_math $i + 1)
done
if [ -z "$found" ]; then
## find the next page if we dont have a match
nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=[0-9]+")"
if [ -z "$nextpage" ]; then
_err "no record and no nextpage in digital ocean DNS removal"
return 1
fi
_debug2 nextpage "$nextpage"
DOMURL="$nextpage"
fi
done
## we went through the entire domain zone list and dint find one that matched
## doesnt look like we can add in the record
_err "domain not found in DigitalOcean account, but we should never get here"
return 1
}

198
dnsapi/dns_dnsimple.sh Normal file
View File

@@ -0,0 +1,198 @@
#!/usr/bin/env sh
# DNSimple domain api
# https://github.com/pho3nixf1re/acme.sh/issues
#
# This is your oauth token which can be acquired on the account page. Please
# note that this must be an _account_ token and not a _user_ token.
# https://dnsimple.com/a/<your account id>/account/access_tokens
# DNSimple_OAUTH_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje"
DNSimple_API="https://api.dnsimple.com/v2"
######## Public functions #####################
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_dnsimple_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$DNSimple_OAUTH_TOKEN" ]; then
DNSimple_OAUTH_TOKEN=""
_err "You have not set the dnsimple oauth token yet."
_err "Please visit https://dnsimple.com/user to generate it."
return 1
fi
# save the oauth token for later
_saveaccountconf DNSimple_OAUTH_TOKEN "$DNSimple_OAUTH_TOKEN"
if ! _get_account_id; then
_err "failed to retrive account id"
return 1
fi
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_get_records "$_account_id" "$_domain" "$_sub_domain"
_info "Adding record"
if _dnsimple_rest POST "$_account_id/zones/$_domain/records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
if printf -- "%s" "$response" | grep "\"name\":\"$_sub_domain\"" >/dev/null; then
_info "Added"
return 0
else
_err "Unexpected response while adding text record."
return 1
fi
fi
_err "Add txt record error."
}
# fulldomain
dns_dnsimple_rm() {
fulldomain=$1
if ! _get_account_id; then
_err "failed to retrive account id"
return 1
fi
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_get_records "$_account_id" "$_domain" "$_sub_domain"
_extract_record_id "$_records" "$_sub_domain"
if [ "$_record_id" ]; then
echo "$_record_id" | while read -r item; do
if _dnsimple_rest DELETE "$_account_id/zones/$_domain/records/$item"; then
_info "removed record" "$item"
return 0
else
_err "failed to remove record" "$item"
return 1
fi
done
fi
}
#################### Private functions bellow ##################################
# _acme-challenge.www.domain.com
# returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain=$1
i=2
previous=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
# not valid
return 1
fi
if ! _dnsimple_rest GET "$_account_id/zones/$h"; then
return 1
fi
if _contains "$response" 'not found'; then
_debug "$h not found"
else
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$previous)
_domain="$h"
_debug _domain "$_domain"
_debug _sub_domain "$_sub_domain"
return 0
fi
previous="$i"
i=$(_math "$i" + 1)
done
return 1
}
# returns _account_id
_get_account_id() {
_debug "retrive account id"
if ! _dnsimple_rest GET "whoami"; then
return 1
fi
if _contains "$response" "\"account\":null"; then
_err "no account associated with this token"
return 1
fi
if _contains "$response" "timeout"; then
_err "timeout retrieving account id"
return 1
fi
_account_id=$(printf "%s" "$response" | _egrep_o "\"id\":[^,]*,\"email\":" | cut -d: -f2 | cut -d, -f1)
_debug _account_id "$_account_id"
return 0
}
# returns
# _records
# _records_count
_get_records() {
account_id=$1
domain=$2
sub_domain=$3
_debug "fetching txt records"
_dnsimple_rest GET "$account_id/zones/$domain/records?per_page=5000&sort=id:desc"
if ! _contains "$response" "\"id\":"; then
_err "failed to retrieve records"
return 1
fi
_records_count=$(printf "%s" "$response" | _egrep_o "\"name\":\"$sub_domain\"" | wc -l | _egrep_o "[0-9]+")
_records=$response
_debug _records_count "$_records_count"
}
# returns _record_id
_extract_record_id() {
_record_id=$(printf "%s" "$_records" | _egrep_o "\"id\":[^,]*,\"zone_id\":\"[^,]*\",\"parent_id\":null,\"name\":\"$_sub_domain\"" | cut -d: -f2 | cut -d, -f1)
_debug "_record_id" "$_record_id"
}
# returns response
_dnsimple_rest() {
method=$1
path="$2"
data="$3"
request_url="$DNSimple_API/$path"
_debug "$path"
export _H1="Accept: application/json"
export _H2="Authorization: Bearer $DNSimple_OAUTH_TOKEN"
if [ "$data" ] || [ "$method" = "DELETE" ]; then
_H1="Content-Type: application/json"
_debug data "$data"
response="$(_post "$data" "$request_url" "" "$method")"
else
response="$(_get "$request_url" "" "" "$method")"
fi
if [ "$?" != "0" ]; then
_err "error $request_url"
return 1
fi
_debug2 response "$response"
return 0
}

148
dnsapi/dns_do.sh Executable file
View File

@@ -0,0 +1,148 @@
#!/usr/bin/env sh
# DNS API for Domain-Offensive / Resellerinterface / Domainrobot
# Report bugs at https://github.com/seidler2547/acme.sh/issues
# set these environment variables to match your customer ID and password:
# DO_PID="KD-1234567"
# DO_PW="cdfkjl3n2"
DO_URL="https://soap.resellerinterface.de/"
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_do_add() {
fulldomain=$1
txtvalue=$2
if _dns_do_authenticate; then
_info "Adding TXT record to ${_domain} as ${fulldomain}"
_dns_do_soap createRR origin "${_domain}" name "${fulldomain}" type TXT data "${txtvalue}" ttl 300
if _contains "${response}" '>success<'; then
return 0
fi
_err "Could not create resource record, check logs"
fi
return 1
}
#fulldomain
dns_do_rm() {
fulldomain=$1
if _dns_do_authenticate; then
if _dns_do_list_rrs; then
_dns_do_had_error=0
for _rrid in ${_rr_list}; do
_info "Deleting resource record $_rrid for $_domain"
_dns_do_soap deleteRR origin "${_domain}" rrid "${_rrid}"
if ! _contains "${response}" '>success<'; then
_dns_do_had_error=1
_err "Could not delete resource record for ${_domain}, id ${_rrid}"
fi
done
return $_dns_do_had_error
fi
fi
return 1
}
#################### Private functions below ##################################
_dns_do_authenticate() {
_info "Authenticating as ${DO_PID}"
_dns_do_soap authPartner partner "${DO_PID}" password "${DO_PW}"
if _contains "${response}" '>success<'; then
_get_root "$fulldomain"
_debug "_domain $_domain"
return 0
else
_err "Authentication failed, are DO_PID and DO_PW set correctly?"
fi
return 1
}
_dns_do_list_rrs() {
_dns_do_soap getRRList origin "${_domain}"
if ! _contains "${response}" 'SOAP-ENC:Array'; then
_err "getRRList origin ${_domain} failed"
return 1
fi
_rr_list="$(echo "${response}" \
| tr -d "\n\r\t" \
| sed -e 's/<item xsi:type="ns2:Map">/\n/g' \
| grep ">$(_regexcape "$fulldomain")</value>" \
| sed -e 's/<\/item>/\n/g' \
| grep '>id</key><value' \
| _egrep_o '>[0-9]{1,16}<' \
| tr -d '><')"
[ "${_rr_list}" ]
}
_dns_do_soap() {
func="$1"
shift
# put the parameters to xml
body="<tns:${func} xmlns:tns=\"${DO_URL}\">"
while [ "$1" ]; do
_k="$1"
shift
_v="$1"
shift
body="$body<$_k>$_v</$_k>"
done
body="$body</tns:${func}>"
_debug2 "SOAP request ${body}"
# build SOAP XML
_xml='<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body>'"$body"'</env:Body>
</env:Envelope>'
# set SOAP headers
export _H1="SOAPAction: ${DO_URL}#${func}"
if ! response="$(_post "${_xml}" "${DO_URL}")"; then
_err "Error <$1>"
return 1
fi
_debug2 "SOAP response $response"
# retrieve cookie header
_H2="$(_egrep_o 'Cookie: [^;]+' <"$HTTP_HEADER" | _head_n 1)"
export _H2
return 0
}
_get_root() {
domain=$1
i=1
_dns_do_soap getDomainList
_all_domains="$(echo "${response}" \
| tr -d "\n\r\t " \
| _egrep_o 'domain</key><value[^>]+>[^<]+' \
| sed -e 's/^domain<\/key><value[^>]*>//g')"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
return 1
fi
if _contains "${_all_domains}" "^$(_regexcape "$h")\$"; then
_domain="$h"
return 0
fi
i=$(_math $i + 1)
done
_debug "$domain not found"
return 1
}
_regexcape() {
echo "$1" | sed -e 's/\([]\.$*^[]\)/\\\1/g'
}

59
dnsapi/dns_doapi.sh Executable file
View File

@@ -0,0 +1,59 @@
#!/usr/bin/env sh
# Official Let's Encrypt API for do.de / Domain-Offensive
#
# This is different from the dns_do adapter, because dns_do is only usable for enterprise customers
# This API is also available to private customers/individuals
#
# Provide the required LetsEncrypt token like this:
# DO_LETOKEN="FmD408PdqT1E269gUK57"
DO_API="https://www.do.de/api/letsencrypt"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_doapi_add() {
fulldomain=$1
txtvalue=$2
DO_LETOKEN="${DO_LETOKEN:-$(_readaccountconf_mutable DO_LETOKEN)}"
if [ -z "$DO_LETOKEN" ]; then
DO_LETOKEN=""
_err "You didn't configure a do.de API token yet."
_err "Please set DO_LETOKEN and try again."
return 1
fi
_saveaccountconf_mutable DO_LETOKEN "$DO_LETOKEN"
_info "Adding TXT record to ${fulldomain}"
response="$(_get "$DO_API?token=$DO_LETOKEN&domain=${fulldomain}&value=${txtvalue}")"
if _contains "${response}" 'success'; then
return 0
fi
_err "Could not create resource record, check logs"
_err "${response}"
return 1
}
dns_doapi_rm() {
fulldomain=$1
DO_LETOKEN="${DO_LETOKEN:-$(_readaccountconf_mutable DO_LETOKEN)}"
if [ -z "$DO_LETOKEN" ]; then
DO_LETOKEN=""
_err "You didn't configure a do.de API token yet."
_err "Please set DO_LETOKEN and try again."
return 1
fi
_saveaccountconf_mutable DO_LETOKEN "$DO_LETOKEN"
_info "Deleting resource record $fulldomain"
response="$(_get "$DO_API?token=$DO_LETOKEN&domain=${fulldomain}&action=delete")"
if _contains "${response}" 'success'; then
return 0
fi
_err "Could not delete resource record, check logs"
_err "${response}"
return 1
}

View File

@@ -15,6 +15,8 @@ dns_dp_add() {
fulldomain=$1
txtvalue=$2
DP_Id="${DP_Id:-$(_readaccountconf_mutable DP_Id)}"
DP_Key="${DP_Key:-$(_readaccountconf_mutable DP_Key)}"
if [ -z "$DP_Id" ] || [ -z "$DP_Key" ]; then
DP_Id=""
DP_Key=""
@@ -24,8 +26,8 @@ dns_dp_add() {
fi
#save the api key and email to the account conf file.
_saveaccountconf DP_Id "$DP_Id"
_saveaccountconf DP_Key "$DP_Key"
_saveaccountconf_mutable DP_Id "$DP_Id"
_saveaccountconf_mutable DP_Key "$DP_Key"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
@@ -33,24 +35,18 @@ dns_dp_add() {
return 1
fi
existing_records "$_domain" "$_sub_domain"
_debug count "$count"
if [ "$?" != "0" ]; then
_err "Error get existing records."
return 1
fi
add_record "$_domain" "$_sub_domain" "$txtvalue"
if [ "$count" = "0" ]; then
add_record "$_domain" "$_sub_domain" "$txtvalue"
else
update_record "$_domain" "$_sub_domain" "$txtvalue"
fi
}
#fulldomain txtvalue
dns_dp_rm() {
fulldomain=$1
txtvalue=$2
DP_Id="${DP_Id:-$(_readaccountconf_mutable DP_Id)}"
DP_Key="${DP_Key:-$(_readaccountconf_mutable DP_Key)}"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
@@ -67,7 +63,7 @@ dns_dp_rm() {
return 0
fi
record_id=$(echo "$response" | _egrep_o '{[^{]*"value":"'"$txtvalue"'"' | cut -d , -f 1 | cut -d : -f 2 | tr -d \")
record_id=$(echo "$response" | tr "{" "\n" | grep "$txtvalue" | grep '^"id"' | cut -d : -f 2 | cut -d '"' -f 2)
_debug record_id "$record_id"
if [ -z "$record_id" ]; then
_err "Can not get record id."
@@ -83,37 +79,6 @@ dns_dp_rm() {
}
#usage: root sub
#return if the sub record already exists.
#echos the existing records count.
# '0' means doesn't exist
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
fi
if _contains "$response" 'No records'; then
count=0
return 0
fi
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
}
#add the txt record.
#usage: root sub txtvalue
add_record() {
@@ -128,34 +93,7 @@ add_record() {
return 1
fi
if _contains "$response" "Action completed successful"; then
return 0
fi
return 1 #error
}
#update the txt record
#Usage: root sub txtvalue
update_record() {
root=$1
sub=$2
txtvalue=$3
fulldomain="$sub.$root"
_info "Updating record"
if ! _rest POST "Record.Modify" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=默认&record_id=$record_id"; then
return 1
fi
if _contains "$response" "Action completed successful"; then
return 0
fi
return 1 #error
_contains "$response" "Action completed successful" || _contains "$response" "Domain record already exists"
}
#################### Private functions below ##################################

161
dnsapi/dns_dpi.sh Executable file
View File

@@ -0,0 +1,161 @@
#!/usr/bin/env sh
# Dnspod.com Domain api
#
#DPI_Id="1234"
#
#DPI_Key="sADDsdasdgdsf"
REST_API="https://api.dnspod.com"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_dpi_add() {
fulldomain=$1
txtvalue=$2
DPI_Id="${DPI_Id:-$(_readaccountconf_mutable DPI_Id)}"
DPI_Key="${DPI_Key:-$(_readaccountconf_mutable DPI_Key)}"
if [ -z "$DPI_Id" ] || [ -z "$DPI_Key" ]; then
DPI_Id=""
DPI_Key=""
_err "You don't specify dnspod api key and key id yet."
_err "Please create you key and try again."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf_mutable DPI_Id "$DPI_Id"
_saveaccountconf_mutable DPI_Key "$DPI_Key"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
add_record "$_domain" "$_sub_domain" "$txtvalue"
}
#fulldomain txtvalue
dns_dpi_rm() {
fulldomain=$1
txtvalue=$2
DPI_Id="${DPI_Id:-$(_readaccountconf_mutable DPI_Id)}"
DPI_Key="${DPI_Key:-$(_readaccountconf_mutable DPI_Key)}"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
if ! _rest POST "Record.List" "user_token=$DPI_Id,$DPI_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" "user_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&record_id=$record_id"; then
_err "Record.Remove error."
return 1
fi
_contains "$response" "Action completed successful"
}
#add the txt record.
#usage: root sub txtvalue
add_record() {
root=$1
sub=$2
txtvalue=$3
fulldomain="$sub.$root"
_info "Adding record"
if ! _rest POST "Record.Create" "user_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=default"; then
return 1
fi
_contains "$response" "Action completed successful" || _contains "$response" "Domain record already exists"
}
#################### 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 ! _rest POST "Domain.Info" "user_token=$DPI_Id,$DPI_Key&format=json&domain=$h"; then
return 1
fi
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 "%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=$(_math "$i" + 1)
done
return 1
}
#Usage: method URI data
_rest() {
m="$1"
ep="$2"
data="$3"
_debug "$ep"
url="$REST_API/$ep"
_debug url "$url"
if [ "$m" = "GET" ]; then
response="$(_get "$url" | tr -d '\r')"
else
_debug2 data "$data"
response="$(_post "$data" "$url" | tr -d '\r')"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

97
dnsapi/dns_dreamhost.sh Normal file
View File

@@ -0,0 +1,97 @@
#!/usr/bin/env sh
#Author: RhinoLance
#Report Bugs here: https://github.com/RhinoLance/acme.sh
#
#define the api endpoint
DH_API_ENDPOINT="https://api.dreamhost.com/"
querystring=""
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_dreamhost_add() {
fulldomain=$1
txtvalue=$2
if ! validate "$fulldomain" "$txtvalue"; then
return 1
fi
querystring="key=$DH_API_KEY&cmd=dns-add_record&record=$fulldomain&type=TXT&value=$txtvalue"
if ! submit "$querystring"; then
return 1
fi
return 0
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_dreamhost_rm() {
fulldomain=$1
txtvalue=$2
if ! validate "$fulldomain" "$txtvalue"; then
return 1
fi
querystring="key=$DH_API_KEY&cmd=dns-remove_record&record=$fulldomain&type=TXT&value=$txtvalue"
if ! submit "$querystring"; then
return 1
fi
return 0
}
#################### Private functions below ##################################
#send the command to the api endpoint.
submit() {
querystring=$1
url="$DH_API_ENDPOINT?$querystring"
_debug url "$url"
if ! response="$(_get "$url")"; then
_err "Error <$1>"
return 1
fi
if [ -z "$2" ]; then
message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")"
if [ -n "$message" ]; then
_err "$message"
return 1
fi
fi
_debug response "$response"
return 0
}
#check that we have a valid API Key
validate() {
fulldomain=$1
txtvalue=$2
_info "Using dreamhost"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
#retrieve the API key from the environment variable if it exists, otherwise look for a saved key.
DH_API_KEY="${DH_API_KEY:-$(_readaccountconf_mutable DH_API_KEY)}"
if [ -z "$DH_API_KEY" ]; then
DH_API_KEY=""
_err "You didn't specify the DreamHost api key yet (export DH_API_KEY=\"<api key>\")"
_err "Please login to your control panel, create a key and try again."
return 1
fi
#save the api key to the account conf file.
_saveaccountconf_mutable DH_API_KEY "$DH_API_KEY"
}

128
dnsapi/dns_duckdns.sh Executable file
View File

@@ -0,0 +1,128 @@
#!/usr/bin/env sh
#Created by RaidenII, to use DuckDNS's API to add/remove text records
#06/27/2017
# Pass credentials before "acme.sh --issue --dns dns_duckdns ..."
# --
# export DuckDNS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
# --
#
# Due to the fact that DuckDNS uses StartSSL as cert provider, --insecure may need to be used with acme.sh
DuckDNS_API="https://www.duckdns.org/update"
######## Public functions #####################
#Usage: dns_duckdns_add _acme-challenge.domain.duckdns.org "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_duckdns_add() {
fulldomain=$1
txtvalue=$2
DuckDNS_Token="${DuckDNS_Token:-$(_readaccountconf_mutable DuckDNS_Token)}"
if [ -z "$DuckDNS_Token" ]; then
_err "You must export variable: DuckDNS_Token"
_err "The token for your DuckDNS account is necessary."
_err "You can look it up in your DuckDNS account."
return 1
fi
# Now save the credentials.
_saveaccountconf_mutable DuckDNS_Token "$DuckDNS_Token"
# Unfortunately, DuckDNS does not seems to support lookup domain through API
# So I assume your credentials (which are your domain and token) are correct
# If something goes wrong, we will get a KO response from DuckDNS
if ! _duckdns_get_domain; then
return 1
fi
# Now add the TXT record to DuckDNS
_info "Trying to add TXT record"
if _duckdns_rest GET "domains=$_duckdns_domain&token=$DuckDNS_Token&txt=$txtvalue"; then
if [ "$response" = "OK" ]; then
_info "TXT record has been successfully added to your DuckDNS domain."
_info "Note that all subdomains under this domain uses the same TXT record."
return 0
else
_err "Errors happened during adding the TXT record, response=$response"
return 1
fi
else
_err "Errors happened during adding the TXT record."
return 1
fi
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_duckdns_rm() {
fulldomain=$1
txtvalue=$2
DuckDNS_Token="${DuckDNS_Token:-$(_readaccountconf_mutable DuckDNS_Token)}"
if [ -z "$DuckDNS_Token" ]; then
_err "You must export variable: DuckDNS_Token"
_err "The token for your DuckDNS account is necessary."
_err "You can look it up in your DuckDNS account."
return 1
fi
if ! _duckdns_get_domain; then
return 1
fi
# Now remove the TXT record from DuckDNS
_info "Trying to remove TXT record"
if _duckdns_rest GET "domains=$_duckdns_domain&token=$DuckDNS_Token&txt=&clear=true"; then
if [ "$response" = "OK" ]; then
_info "TXT record has been successfully removed from your DuckDNS domain."
return 0
else
_err "Errors happened during removing the TXT record, response=$response"
return 1
fi
else
_err "Errors happened during removing the TXT record."
return 1
fi
}
#################### Private functions below ##################################
#fulldomain=_acme-challenge.domain.duckdns.org
#returns
# _duckdns_domain=domain
_duckdns_get_domain() {
# We'll extract the domain/username from full domain
_duckdns_domain="$(printf "%s" "$fulldomain" | _lower_case | _egrep_o '[.][^.][^.]*[.]duckdns.org' | cut -d . -f 2)"
if [ -z "$_duckdns_domain" ]; then
_err "Error extracting the domain."
return 1
fi
return 0
}
#Usage: method URI
_duckdns_rest() {
method=$1
param="$2"
_debug param "$param"
url="$DuckDNS_API?$param"
_debug url "$url"
# DuckDNS uses GET to update domain info
if [ "$method" = "GET" ]; then
response="$(_get "$url")"
else
_err "Unsupported method"
return 1
fi
_debug2 response "$response"
return 0
}

176
dnsapi/dns_durabledns.sh Normal file
View File

@@ -0,0 +1,176 @@
#!/usr/bin/env sh
#DD_API_User="xxxxx"
#DD_API_Key="xxxxxx"
_DD_BASE="https://durabledns.com/services/dns"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_durabledns_add() {
fulldomain=$1
txtvalue=$2
DD_API_User="${DD_API_User:-$(_readaccountconf_mutable DD_API_User)}"
DD_API_Key="${DD_API_Key:-$(_readaccountconf_mutable DD_API_Key)}"
if [ -z "$DD_API_User" ] || [ -z "$DD_API_Key" ]; then
DD_API_User=""
DD_API_Key=""
_err "You didn't specify a durabledns api user or key yet."
_err "You can get yours from here https://durabledns.com/dashboard/index.php"
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf_mutable DD_API_User "$DD_API_User"
_saveaccountconf_mutable DD_API_Key "$DD_API_Key"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_dd_soap createRecord string zonename "$_domain." string name "$_sub_domain" string type "TXT" string data "$txtvalue" int aux 0 int ttl 10 string ddns_enabled N
_contains "$response" "createRecordResponse"
}
dns_durabledns_rm() {
fulldomain=$1
txtvalue=$2
DD_API_User="${DD_API_User:-$(_readaccountconf_mutable DD_API_User)}"
DD_API_Key="${DD_API_Key:-$(_readaccountconf_mutable DD_API_Key)}"
if [ -z "$DD_API_User" ] || [ -z "$DD_API_Key" ]; then
DD_API_User=""
DD_API_Key=""
_err "You didn't specify a durabledns api user or key yet."
_err "You can get yours from here https://durabledns.com/dashboard/index.php"
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Find record id"
if ! _dd_soap listRecords string zonename "$_domain."; then
_err "can not listRecords"
return 1
fi
subtxt="$(echo "$txtvalue" | cut -c 1-30)"
record="$(echo "$response" | sed 's/<item\>/#<item>/g' | tr '#' '\n' | grep ">$subtxt")"
_debug record "$record"
if [ -z "$record" ]; then
_err "can not find record for txtvalue" "$txtvalue"
_err "$response"
return 1
fi
recordid="$(echo "$record" | _egrep_o '<id xsi:type="xsd:int">[0-9]*</id>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
_debug recordid "$recordid"
if [ -z "$recordid" ]; then
_err "can not find record id"
return 1
fi
if ! _dd_soap deleteRecord string zonename "$_domain." int id "$recordid"; then
_err "delete error"
return 1
fi
_contains "$response" "Success"
}
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain=$1
if ! _dd_soap "listZones"; then
return 1
fi
i=1
p=1
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" ">$h.</origin>"; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
#method
_dd_soap() {
_method="$1"
shift
_urn="${_method}wsdl"
# put the parameters to xml
body="<tns:$_method>
<apiuser xsi:type=\"xsd:string\">$DD_API_User</apiuser>
<apikey xsi:type=\"xsd:string\">$DD_API_Key</apikey>
"
while [ "$1" ]; do
_t="$1"
shift
_k="$1"
shift
_v="$1"
shift
body="$body<$_k xsi:type=\"xsd:$_t\">$_v</$_k>"
done
body="$body</tns:$_method>"
_debug2 "SOAP request ${body}"
# build SOAP XML
_xml='<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="urn:'$_urn'"
xmlns:types="urn:'$_urn'/encodedTypes"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'"$body"'</soap:Body>
</soap:Envelope>'
_debug2 _xml "$_xml"
# set SOAP headers
_action="SOAPAction: \"urn:$_urn#$_method\""
_debug2 "_action" "$_action"
export _H1="$_action"
export _H2="Content-Type: text/xml; charset=utf-8"
_url="$_DD_BASE/$_method.php"
_debug "_url" "$_url"
if ! response="$(_post "${_xml}" "${_url}")"; then
_err "Error <$1>"
return 1
fi
_debug2 "response" "$response"
response="$(echo "$response" | tr -d "\r\n" | _egrep_o ":${_method}Response .*:${_method}Response><")"
_debug2 "response" "$response"
return 0
}

339
dnsapi/dns_dyn.sh Normal file
View File

@@ -0,0 +1,339 @@
#!/usr/bin/env sh
#
# Dyn.com Domain API
#
# Author: Gerd Naschenweng
# https://github.com/magicdude4eva
#
# Dyn Managed DNS API
# https://help.dyn.com/dns-api-knowledge-base/
#
# It is recommended to add a "Dyn Managed DNS" user specific for API access.
# The "Zones & Records Permissions" required by this script are:
# --
# RecordAdd
# RecordUpdate
# RecordDelete
# RecordGet
# ZoneGet
# ZoneAddNode
# ZoneRemoveNode
# ZonePublish
# --
#
# Pass credentials before "acme.sh --issue --dns dns_dyn ..."
# --
# export DYN_Customer="customer"
# export DYN_Username="apiuser"
# export DYN_Password="secret"
# --
DYN_API="https://api.dynect.net/REST"
#REST_API
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "Challenge-code"
dns_dyn_add() {
fulldomain="$1"
txtvalue="$2"
DYN_Customer="${DYN_Customer:-$(_readaccountconf_mutable DYN_Customer)}"
DYN_Username="${DYN_Username:-$(_readaccountconf_mutable DYN_Username)}"
DYN_Password="${DYN_Password:-$(_readaccountconf_mutable DYN_Password)}"
if [ -z "$DYN_Customer" ] || [ -z "$DYN_Username" ] || [ -z "$DYN_Password" ]; then
DYN_Customer=""
DYN_Username=""
DYN_Password=""
_err "You must export variables: DYN_Customer, DYN_Username and DYN_Password"
return 1
fi
#save the config variables to the account conf file.
_saveaccountconf_mutable DYN_Customer "$DYN_Customer"
_saveaccountconf_mutable DYN_Username "$DYN_Username"
_saveaccountconf_mutable DYN_Password "$DYN_Password"
if ! _dyn_get_authtoken; then
return 1
fi
if [ -z "$_dyn_authtoken" ]; then
_dyn_end_session
return 1
fi
if ! _dyn_get_zone; then
_dyn_end_session
return 1
fi
if ! _dyn_add_record; then
_dyn_end_session
return 1
fi
if ! _dyn_publish_zone; then
_dyn_end_session
return 1
fi
_dyn_end_session
return 0
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_dyn_rm() {
fulldomain="$1"
txtvalue="$2"
DYN_Customer="${DYN_Customer:-$(_readaccountconf_mutable DYN_Customer)}"
DYN_Username="${DYN_Username:-$(_readaccountconf_mutable DYN_Username)}"
DYN_Password="${DYN_Password:-$(_readaccountconf_mutable DYN_Password)}"
if [ -z "$DYN_Customer" ] || [ -z "$DYN_Username" ] || [ -z "$DYN_Password" ]; then
DYN_Customer=""
DYN_Username=""
DYN_Password=""
_err "You must export variables: DYN_Customer, DYN_Username and DYN_Password"
return 1
fi
if ! _dyn_get_authtoken; then
return 1
fi
if [ -z "$_dyn_authtoken" ]; then
_dyn_end_session
return 1
fi
if ! _dyn_get_zone; then
_dyn_end_session
return 1
fi
if ! _dyn_get_record_id; then
_dyn_end_session
return 1
fi
if [ -z "$_dyn_record_id" ]; then
_dyn_end_session
return 1
fi
if ! _dyn_rm_record; then
_dyn_end_session
return 1
fi
if ! _dyn_publish_zone; then
_dyn_end_session
return 1
fi
_dyn_end_session
return 0
}
#################### Private functions below ##################################
#get Auth-Token
_dyn_get_authtoken() {
_info "Start Dyn API Session"
data="{\"customer_name\":\"$DYN_Customer\", \"user_name\":\"$DYN_Username\", \"password\":\"$DYN_Password\"}"
dyn_url="$DYN_API/Session/"
method="POST"
_debug data "$data"
_debug dyn_url "$dyn_url"
export _H1="Content-Type: application/json"
response="$(_post "$data" "$dyn_url" "" "$method")"
sessionstatus="$(printf "%s\n" "$response" | _egrep_o '"status" *: *"[^"]*' | _head_n 1 | sed 's#^"status" *: *"##')"
_debug response "$response"
_debug sessionstatus "$sessionstatus"
if [ "$sessionstatus" = "success" ]; then
_dyn_authtoken="$(printf "%s\n" "$response" | _egrep_o '"token" *: *"[^"]*' | _head_n 1 | sed 's#^"token" *: *"##')"
_info "Token received"
_debug _dyn_authtoken "$_dyn_authtoken"
return 0
fi
_dyn_authtoken=""
_err "get token failed"
return 1
}
#fulldomain=_acme-challenge.www.domain.com
#returns
# _dyn_zone=domain.com
_dyn_get_zone() {
i=2
while true; do
domain="$(printf "%s" "$fulldomain" | cut -d . -f "$i-100")"
if [ -z "$domain" ]; then
break
fi
dyn_url="$DYN_API/Zone/$domain/"
export _H1="Auth-Token: $_dyn_authtoken"
export _H2="Content-Type: application/json"
response="$(_get "$dyn_url" "" "")"
sessionstatus="$(printf "%s\n" "$response" | _egrep_o '"status" *: *"[^"]*' | _head_n 1 | sed 's#^"status" *: *"##')"
_debug dyn_url "$dyn_url"
_debug response "$response"
_debug sessionstatus "$sessionstatus"
if [ "$sessionstatus" = "success" ]; then
_dyn_zone="$domain"
return 0
fi
i=$(_math "$i" + 1)
done
_dyn_zone=""
_err "get zone failed"
return 1
}
#add TXT record
_dyn_add_record() {
_info "Adding TXT record"
data="{\"rdata\":{\"txtdata\":\"$txtvalue\"},\"ttl\":\"300\"}"
dyn_url="$DYN_API/TXTRecord/$_dyn_zone/$fulldomain/"
method="POST"
export _H1="Auth-Token: $_dyn_authtoken"
export _H2="Content-Type: application/json"
response="$(_post "$data" "$dyn_url" "" "$method")"
sessionstatus="$(printf "%s\n" "$response" | _egrep_o '"status" *: *"[^"]*' | _head_n 1 | sed 's#^"status" *: *"##')"
_debug response "$response"
_debug sessionstatus "$sessionstatus"
if [ "$sessionstatus" = "success" ]; then
_info "TXT Record successfully added"
return 0
fi
_err "add TXT record failed"
return 1
}
#publish the zone
_dyn_publish_zone() {
_info "Publishing zone"
data="{\"publish\":\"true\"}"
dyn_url="$DYN_API/Zone/$_dyn_zone/"
method="PUT"
export _H1="Auth-Token: $_dyn_authtoken"
export _H2="Content-Type: application/json"
response="$(_post "$data" "$dyn_url" "" "$method")"
sessionstatus="$(printf "%s\n" "$response" | _egrep_o '"status" *: *"[^"]*' | _head_n 1 | sed 's#^"status" *: *"##')"
_debug response "$response"
_debug sessionstatus "$sessionstatus"
if [ "$sessionstatus" = "success" ]; then
_info "Zone published"
return 0
fi
_err "publish zone failed"
return 1
}
#get record_id of TXT record so we can delete the record
_dyn_get_record_id() {
_info "Getting record_id of TXT record"
dyn_url="$DYN_API/TXTRecord/$_dyn_zone/$fulldomain/"
export _H1="Auth-Token: $_dyn_authtoken"
export _H2="Content-Type: application/json"
response="$(_get "$dyn_url" "" "")"
sessionstatus="$(printf "%s\n" "$response" | _egrep_o '"status" *: *"[^"]*' | _head_n 1 | sed 's#^"status" *: *"##')"
_debug response "$response"
_debug sessionstatus "$sessionstatus"
if [ "$sessionstatus" = "success" ]; then
_dyn_record_id="$(printf "%s\n" "$response" | _egrep_o "\"data\" *: *\[\"/REST/TXTRecord/$_dyn_zone/$fulldomain/[^\"]*" | _head_n 1 | sed "s#^\"data\" *: *\[\"/REST/TXTRecord/$_dyn_zone/$fulldomain/##")"
_debug _dyn_record_id "$_dyn_record_id"
return 0
fi
_dyn_record_id=""
_err "getting record_id failed"
return 1
}
#delete TXT record
_dyn_rm_record() {
_info "Deleting TXT record"
dyn_url="$DYN_API/TXTRecord/$_dyn_zone/$fulldomain/$_dyn_record_id/"
method="DELETE"
_debug dyn_url "$dyn_url"
export _H1="Auth-Token: $_dyn_authtoken"
export _H2="Content-Type: application/json"
response="$(_post "" "$dyn_url" "" "$method")"
sessionstatus="$(printf "%s\n" "$response" | _egrep_o '"status" *: *"[^"]*' | _head_n 1 | sed 's#^"status" *: *"##')"
_debug response "$response"
_debug sessionstatus "$sessionstatus"
if [ "$sessionstatus" = "success" ]; then
_info "TXT record successfully deleted"
return 0
fi
_err "delete TXT record failed"
return 1
}
#logout
_dyn_end_session() {
_info "End Dyn API Session"
dyn_url="$DYN_API/Session/"
method="DELETE"
_debug dyn_url "$dyn_url"
export _H1="Auth-Token: $_dyn_authtoken"
export _H2="Content-Type: application/json"
response="$(_post "" "$dyn_url" "" "$method")"
_debug response "$response"
_dyn_authtoken=""
return 0
}

228
dnsapi/dns_dynu.sh Normal file
View File

@@ -0,0 +1,228 @@
#!/usr/bin/env sh
#Client ID
#Dynu_ClientId="0b71cae7-a099-4f6b-8ddf-94571cdb760d"
#
#Secret
#Dynu_Secret="aCUEY4BDCV45KI8CSIC3sp2LKQ9"
#
#Token
Dynu_Token=""
#
#Endpoint
Dynu_EndPoint="https://api.dynu.com/v2"
#
#Author: Dynu Systems, Inc.
#Report Bugs here: https://github.com/shar0119/acme.sh
#
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_dynu_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$Dynu_ClientId" ] || [ -z "$Dynu_Secret" ]; then
Dynu_ClientId=""
Dynu_Secret=""
_err "Dynu client id and secret is not specified."
_err "Please create you API client id and secret and try again."
return 1
fi
#save the client id and secret to the account conf file.
_saveaccountconf Dynu_ClientId "$Dynu_ClientId"
_saveaccountconf Dynu_Secret "$Dynu_Secret"
if [ -z "$Dynu_Token" ]; then
_info "Getting Dynu token."
if ! _dynu_authentication; then
_err "Can not get token."
fi
fi
_debug "Detect root zone"
if ! _get_root "$fulldomain"; then
_err "Invalid domain."
return 1
fi
_debug _node "$_node"
_debug _domain_name "$_domain_name"
_info "Creating TXT record."
if ! _dynu_rest POST "dns/$dnsId/record" "{\"domainId\":\"$dnsId\",\"nodeName\":\"$_node\",\"recordType\":\"TXT\",\"textData\":\"$txtvalue\",\"state\":true,\"ttl\":90}"; then
return 1
fi
if ! _contains "$response" "200"; then
_err "Could not add TXT record."
return 1
fi
return 0
}
#Usage: rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_dynu_rm() {
fulldomain=$1
txtvalue=$2
if [ -z "$Dynu_ClientId" ] || [ -z "$Dynu_Secret" ]; then
Dynu_ClientId=""
Dynu_Secret=""
_err "Dynu client id and secret is not specified."
_err "Please create you API client id and secret and try again."
return 1
fi
#save the client id and secret to the account conf file.
_saveaccountconf Dynu_ClientId "$Dynu_ClientId"
_saveaccountconf Dynu_Secret "$Dynu_Secret"
if [ -z "$Dynu_Token" ]; then
_info "Getting Dynu token."
if ! _dynu_authentication; then
_err "Can not get token."
fi
fi
_debug "Detect root zone."
if ! _get_root "$fulldomain"; then
_err "Invalid domain."
return 1
fi
_debug _node "$_node"
_debug _domain_name "$_domain_name"
_info "Checking for TXT record."
if ! _get_recordid "$fulldomain" "$txtvalue"; then
_err "Could not get TXT record id."
return 1
fi
if [ "$_dns_record_id" = "" ]; then
_err "TXT record not found."
return 1
fi
_info "Removing TXT record."
if ! _delete_txt_record "$_dns_record_id"; then
_err "Could not remove TXT record $_dns_record_id."
fi
return 0
}
######## Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _node=_acme-challenge.www
# _domain_name=domain.com
_get_root() {
domain=$1
i=2
p=1
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 ! _dynu_rest GET "dns/getroot/$h"; then
return 1
fi
if _contains "$response" "\"domainName\":\"$h\"" >/dev/null; then
dnsId=$(printf "%s" "$response" | tr -d "{}" | cut -d , -f 2 | cut -d : -f 2)
_domain_name=$h
_node=$(printf "%s" "$domain" | cut -d . -f 1-$p)
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_get_recordid() {
fulldomain=$1
txtvalue=$2
if ! _dynu_rest GET "dns/$dnsId/record"; then
return 1
fi
if ! _contains "$response" "$txtvalue"; then
_dns_record_id=0
return 0
fi
_dns_record_id=$(printf "%s" "$response" | sed -e 's/[^{]*\({[^}]*}\)[^{]*/\1\n/g' | grep "\"textData\":\"$txtvalue\"" | sed -e 's/.*"id":\([^,]*\).*/\1/')
return 0
}
_delete_txt_record() {
_dns_record_id=$1
if ! _dynu_rest DELETE "dns/$dnsId/record/$_dns_record_id"; then
return 1
fi
if ! _contains "$response" "200"; then
return 1
fi
return 0
}
_dynu_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
export _H1="Authorization: Bearer $Dynu_Token"
export _H2="Content-Type: application/json"
if [ "$data" ] || [ "$m" = "DELETE" ]; then
_debug data "$data"
response="$(_post "$data" "$Dynu_EndPoint/$ep" "" "$m")"
else
_info "Getting $Dynu_EndPoint/$ep"
response="$(_get "$Dynu_EndPoint/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}
_dynu_authentication() {
realm="$(printf "%s" "$Dynu_ClientId:$Dynu_Secret" | _base64)"
export _H1="Authorization: Basic $realm"
export _H2="Content-Type: application/json"
response="$(_get "$Dynu_EndPoint/oauth2/token")"
if [ "$?" != "0" ]; then
_err "Authentication failed."
return 1
fi
if _contains "$response" "access_token"; then
Dynu_Token=$(printf "%s" "$response" | tr -d "{}" | cut -d , -f 1 | cut -d : -f 2 | cut -d '"' -f 2)
fi
if _contains "$Dynu_Token" "null"; then
Dynu_Token=""
fi
_debug2 response "$response"
return 0
}

358
dnsapi/dns_euserv.sh Normal file
View File

@@ -0,0 +1,358 @@
#!/usr/bin/env sh
#This is the euserv.eu api wrapper for acme.sh
#
#Author: Michael Brueckner
#Report Bugs: https://www.github.com/initit/acme.sh or mbr@initit.de
#
#EUSERV_Username="username"
#
#EUSERV_Password="password"
#
# Dependencies:
# -------------
# - none -
EUSERV_Api="https://api.euserv.net"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_euserv_add() {
fulldomain="$(echo "$1" | _lower_case)"
txtvalue=$2
EUSERV_Username="${EUSERV_Username:-$(_readaccountconf_mutable EUSERV_Username)}"
EUSERV_Password="${EUSERV_Password:-$(_readaccountconf_mutable EUSERV_Password)}"
if [ -z "$EUSERV_Username" ] || [ -z "$EUSERV_Password" ]; then
EUSERV_Username=""
EUSERV_Password=""
_err "You don't specify euserv user and password yet."
_err "Please create your key and try again."
return 1
fi
#save the user and email to the account conf file.
_saveaccountconf_mutable EUSERV_Username "$EUSERV_Username"
_saveaccountconf_mutable EUSERV_Password "$EUSERV_Password"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug "_sub_domain" "$_sub_domain"
_debug "_domain" "$_domain"
_info "Adding record"
if ! _euserv_add_record "$_domain" "$_sub_domain" "$txtvalue"; then
return 1
fi
}
#fulldomain txtvalue
dns_euserv_rm() {
fulldomain="$(echo "$1" | _lower_case)"
txtvalue=$2
EUSERV_Username="${EUSERV_Username:-$(_readaccountconf_mutable EUSERV_Username)}"
EUSERV_Password="${EUSERV_Password:-$(_readaccountconf_mutable EUSERV_Password)}"
if [ -z "$EUSERV_Username" ] || [ -z "$EUSERV_Password" ]; then
EUSERV_Username=""
EUSERV_Password=""
_err "You don't specify euserv user and password yet."
_err "Please create your key and try again."
return 1
fi
#save the user and email to the account conf file.
_saveaccountconf_mutable EUSERV_Username "$EUSERV_Username"
_saveaccountconf_mutable EUSERV_Password "$EUSERV_Password"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug "_sub_domain" "$_sub_domain"
_debug "_domain" "$_domain"
_debug "Getting txt records"
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>domain.dns_get_active_records</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>login</name>
<value>
<string>%s</string>
</value>
</member>
<member>
<name>password</name>
<value>
<string>%s</string>
</value>
</member>
<member>
<name>domain_id</name>
<value>
<int>%s</int>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>' "$EUSERV_Username" "$EUSERV_Password" "$_euserv_domain_id")
export _H1="Content-Type: text/xml"
response="$(_post "$xml_content" "$EUSERV_Api" "" "POST")"
if ! _contains "$response" "<member><name>status</name><value><i4>100</i4></value></member>"; then
_err "Error could not get txt records"
_debug "xml_content" "$xml_content"
_debug "response" "$response"
return 1
fi
if ! echo "$response" | grep '>dns_record_content<.*>'"$txtvalue"'<' >/dev/null; then
_info "Do not need to delete record"
else
# find XML block where txtvalue is in. The record_id is allways prior this line!
_endLine=$(echo "$response" | grep -n '>dns_record_content<.*>'"$txtvalue"'<' | cut -d ':' -f 1)
# record_id is the last <name> Tag with a number before the row _endLine, identified by </name><value><struct>
_record_id=$(echo "$response" | sed -n '1,'"$_endLine"'p' | grep '</name><value><struct>' | _tail_n 1 | sed 's/.*<name>\([0-9]*\)<\/name>.*/\1/')
_info "Deleting record"
_euserv_delete_record "$_record_id"
fi
}
#################### Private functions below ##################################
_get_root() {
domain=$1
_debug "get root"
# Just to read the domain_orders once
domain=$1
i=2
p=1
if ! _euserv_get_domain_orders; then
return 1
fi
# Get saved response with domain_orders
response="$_euserv_domain_orders"
while true; do
h=$(echo "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
if _contains "$response" "$h"; then
_sub_domain=$(echo "$domain" | cut -d . -f 1-$p)
_domain="$h"
if ! _euserv_get_domain_id "$_domain"; then
_err "invalid domain"
return 1
fi
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_euserv_get_domain_orders() {
# returns: _euserv_domain_orders
_debug "get domain_orders"
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>domain.get_domain_orders</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>login</name>
<value><string>%s</string></value>
</member>
<member>
<name>password</name>
<value><string>%s</string></value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>' "$EUSERV_Username" "$EUSERV_Password")
export _H1="Content-Type: text/xml"
response="$(_post "$xml_content" "$EUSERV_Api" "" "POST")"
if ! _contains "$response" "<member><name>status</name><value><i4>100</i4></value></member>"; then
_err "Error could not get domain orders"
_debug "xml_content" "$xml_content"
_debug "response" "$response"
return 1
fi
# save response to reduce API calls
_euserv_domain_orders="$response"
return 0
}
_euserv_get_domain_id() {
# returns: _euserv_domain_id
domain=$1
_debug "get domain_id"
# find line where the domain name is within the $response
_startLine=$(echo "$_euserv_domain_orders" | grep -n '>domain_name<.*>'"$domain"'<' | cut -d ':' -f 1)
# next occurency of domain_id after the domain_name is the correct one
_euserv_domain_id=$(echo "$_euserv_domain_orders" | sed -n "$_startLine"',$p' | grep '>domain_id<' | _head_n 1 | sed 's/.*<i4>\([0-9]*\)<\/i4>.*/\1/')
if [ -z "$_euserv_domain_id" ]; then
_err "Could not find domain_id for domain $domain"
_debug "_euserv_domain_orders" "$_euserv_domain_orders"
return 1
fi
return 0
}
_euserv_delete_record() {
record_id=$1
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>domain.dns_delete_record</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>login</name>
<value>
<string>%s</string>
</value>
</member>
<member>
<name>password</name>
<value>
<string>%s</string>
</value>
</member>
<member>
<name>dns_record_id</name>
<value>
<int>%s</int>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>' "$EUSERV_Username" "$EUSERV_Password" "$record_id")
export _H1="Content-Type: text/xml"
response="$(_post "$xml_content" "$EUSERV_Api" "" "POST")"
if ! _contains "$response" "<member><name>status</name><value><i4>100</i4></value></member>"; then
_err "Error deleting record"
_debug "xml_content" "$xml_content"
_debug "response" "$response"
return 1
fi
return 0
}
_euserv_add_record() {
domain=$1
sub_domain=$2
txtval=$3
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>domain.dns_create_record</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>login</name>
<value>
<string>%s</string>
</value>
</member>
<member>
<name>password</name>
<value>
<string>%s</string></value>
</member>
<member>
<name>domain_id</name>
<value>
<int>%s</int>
</value>
</member>
<member>
<name>dns_record_subdomain</name>
<value>
<string>%s</string>
</value>
</member>
<member>
<name>dns_record_type</name>
<value>
<string>TXT</string>
</value>
</member>
<member>
<name>dns_record_value</name>
<value>
<string>%s</string>
</value>
</member>
<member>
<name>dns_record_ttl</name>
<value>
<int>300</int>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>' "$EUSERV_Username" "$EUSERV_Password" "$_euserv_domain_id" "$sub_domain" "$txtval")
export _H1="Content-Type: text/xml"
response="$(_post "$xml_content" "$EUSERV_Api" "" "POST")"
if ! _contains "$response" "<member><name>status</name><value><i4>100</i4></value></member>"; then
_err "Error could not create record"
_debug "xml_content" "$xml_content"
_debug "response" "$response"
return 1
fi
return 0
}

168
dnsapi/dns_exoscale.sh Executable file
View File

@@ -0,0 +1,168 @@
#!/usr/bin/env sh
EXOSCALE_API=https://api.exoscale.com/dns/v1
######## Public functions #####################
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Used to add txt record
dns_exoscale_add() {
fulldomain=$1
txtvalue=$2
if ! _checkAuth; then
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_info "Adding record"
if _exoscale_rest POST "domains/$_domain_id/records" "{\"record\":{\"name\":\"$_sub_domain\",\"record_type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":120}}" "$_domain_token"; then
if _contains "$response" "$txtvalue"; then
_info "Added, OK"
return 0
fi
fi
_err "Add txt record error."
return 1
}
# Usage: fulldomain txtvalue
# Used to remove the txt record after validation
dns_exoscale_rm() {
fulldomain=$1
txtvalue=$2
if ! _checkAuth; then
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_exoscale_rest GET "domains/${_domain_id}/records?type=TXT&name=$_sub_domain" "" "$_domain_token"
if _contains "$response" "\"name\":\"$_sub_domain\"" >/dev/null; then
_record_id=$(echo "$response" | tr '{' "\n" | grep "\"content\":\"$txtvalue\"" | _egrep_o "\"id\":[^,]+" | _head_n 1 | cut -d : -f 2 | tr -d \")
fi
if [ -z "$_record_id" ]; then
_err "Can not get record id to remove."
return 1
fi
_debug "Deleting record $_record_id"
if ! _exoscale_rest DELETE "domains/$_domain_id/records/$_record_id" "" "$_domain_token"; then
_err "Delete record error."
return 1
fi
return 0
}
#################### Private functions below ##################################
_checkAuth() {
EXOSCALE_API_KEY="${EXOSCALE_API_KEY:-$(_readaccountconf_mutable EXOSCALE_API_KEY)}"
EXOSCALE_SECRET_KEY="${EXOSCALE_SECRET_KEY:-$(_readaccountconf_mutable EXOSCALE_SECRET_KEY)}"
if [ -z "$EXOSCALE_API_KEY" ] || [ -z "$EXOSCALE_SECRET_KEY" ]; then
EXOSCALE_API_KEY=""
EXOSCALE_SECRET_KEY=""
_err "You don't specify Exoscale application key and application secret yet."
_err "Please create you key and try again."
return 1
fi
_saveaccountconf_mutable EXOSCALE_API_KEY "$EXOSCALE_API_KEY"
_saveaccountconf_mutable EXOSCALE_SECRET_KEY "$EXOSCALE_SECRET_KEY"
return 0
}
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
# _domain_id=sdjkglgdfewsdfg
# _domain_token=sdjkglgdfewsdfg
_get_root() {
if ! _exoscale_rest GET "domains"; then
return 1
fi
domain=$1
i=2
p=1
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\"" >/dev/null; then
_domain_id=$(echo "$response" | tr '{' "\n" | grep "\"name\":\"$h\"" | _egrep_o "\"id\":[^,]+" | _head_n 1 | cut -d : -f 2 | tr -d \")
_domain_token=$(echo "$response" | tr '{' "\n" | grep "\"name\":\"$h\"" | _egrep_o "\"token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
if [ "$_domain_token" ] && [ "$_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
}
# returns response
_exoscale_rest() {
method=$1
path="$2"
data="$3"
token="$4"
request_url="$EXOSCALE_API/$path"
_debug "$path"
export _H1="Accept: application/json"
if [ "$token" ]; then
export _H2="X-DNS-Domain-Token: $token"
else
export _H2="X-DNS-Token: $EXOSCALE_API_KEY:$EXOSCALE_SECRET_KEY"
fi
if [ "$data" ] || [ "$method" = "DELETE" ]; then
export _H3="Content-Type: application/json"
_debug data "$data"
response="$(_post "$data" "$request_url" "" "$method")"
else
response="$(_get "$request_url" "" "" "$method")"
fi
if [ "$?" != "0" ]; then
_err "error $request_url"
return 1
fi
_debug2 response "$response"
return 0
}

View File

@@ -7,10 +7,11 @@
#
#Author: David Kerr
#Report Bugs here: https://github.com/dkerr64/acme.sh
#or here... https://github.com/Neilpang/acme.sh/issues/2305
#
######## Public functions #####################
# Export FreeDNS userid and password in folowing variables...
# Export FreeDNS userid and password in following variables...
# FREEDNS_User=username
# FREEDNS_Password=password
# login cookie is saved in acme account config file so userid / pw
@@ -46,138 +47,38 @@ dns_freedns_add() {
_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")"
# We may have to cycle through the domain name to find the
# TLD that we own...
i=1
wmax="$(echo "$fulldomain" | tr '.' ' ' | wc -w)"
while [ "$i" -lt "$wmax" ]; do
# split our full domain name into two parts...
sub_domain="$(echo "$fulldomain" | cut -d. -f -"$i")"
i="$(_math "$i" + 1)"
top_domain="$(echo "$fulldomain" | cut -d. -f "$i"-100)"
_debug "sub_domain: $sub_domain"
_debug "top_domain: $top_domain"
# 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
DNSdomainid="$(_freedns_domain_id "$top_domain")"
if [ "$?" = "0" ]; then
_info "Domain $top_domain found at FreeDNS, domain_id $DNSdomainid"
break
else
_info "Domain $top_domain not found at FreeDNS, try with next level of TLD"
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
if [ -z "$DNSdomainid" ]; then
# If domain ID is empty then something went wrong (top level
# domain not found at FreeDNS).
_err "Domain $top_domain not found at FreeDNS"
return 1
fi
return 0
# Add in new TXT record with the value provided
_debug "Adding TXT record for $fulldomain, $txtvalue"
_freedns_add_txt_record "$FREEDNS_COOKIE" "$DNSdomainid" "$sub_domain" "$txtvalue"
return $?
}
#Usage: fulldomain txtvalue
@@ -192,72 +93,48 @@ dns_freedns_rm() {
# 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")"
FREEDNS_COOKIE="$(_readaccountconf "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)"
TXTdataid="$(_freedns_data_id "$fulldomain" "TXT")"
if [ "$?" != "0" ]; then
_info "Cannot delete TXT record for $fulldomain, record does not exist at FreeDNS"
return 1
fi
_debug "Data ID's found, $TXTdataid"
htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")"
# now we have one (or more) TXT record data ID's. Load the page
# for that record and search for the record txt value. If match
# then we can delete it.
lines="$(echo "$TXTdataid" | wc -l)"
_debug "Found $lines TXT data records for $fulldomain"
i=0
while [ "$i" -lt "$lines" ]; do
i="$(_math "$i" + 1)"
dataid="$(echo "$TXTdataid" | sed -n "${i}p")"
_debug "$dataid"
htmlpage="$(_freedns_retrieve_data_page "$FREEDNS_COOKIE" "$dataid")"
if [ "$?" != "0" ]; then
if [ "$using_cached_cookies" = "true" ]; then
_err "Has your FreeDNS username and password changed? 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 "$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
echo "$htmlpage" | grep "value=\"&quot;$txtvalue&quot;\"" >/dev/null
if [ "$?" = "0" ]; then
# Found a match... delete the record and return
_info "Deleting TXT record for $fulldomain, $txtvalue"
_freedns_delete_txt_record "$FREEDNS_COOKIE" "$dataid"
return $?
fi
done
# If we get this far we did not find a match (after two attempts)
# If we get this far we did not find a match
# Not necessarily an error, but log anyway.
_debug2 "$subdomain_csv"
_info "Cannot delete TXT record for $fulldomain/$txtvalue. Does not exist at FreeDNS"
_info "Cannot delete TXT record for $fulldomain, $txtvalue. Does not exist at FreeDNS"
return 0
}
@@ -285,7 +162,7 @@ _freedns_login() {
# if cookies is not empty then logon successful
if [ -z "$cookies" ]; then
_debug "$htmlpage"
_debug3 "htmlpage: $htmlpage"
_err "FreeDNS login failed for user $username. Check $HTTP_HEADER file"
return 1
fi
@@ -302,19 +179,46 @@ _freedns_retrieve_subdomain_page() {
export _H2="Accept-Language:en-US"
url="https://freedns.afraid.org/subdomain/"
_debug "Retrieve subdmoain page from FreeDNS"
_debug "Retrieve subdomain page from FreeDNS"
htmlpage="$(_get "$url")"
if [ "$?" != "0" ]; then
_err "FreeDNS retrieve subdomins failed bad RC from _get"
_err "FreeDNS retrieve subdomains failed bad RC from _get"
return 1
elif [ -z "$htmlpage" ]; then
_err "FreeDNS returned empty subdomain page"
return 1
fi
_debug2 "$htmlpage"
_debug3 "htmlpage: $htmlpage"
printf "%s" "$htmlpage"
return 0
}
# usage _freedns_retrieve_data_page login_cookies data_id
# echo page retrieved (html)
# returns 0 success
_freedns_retrieve_data_page() {
export _H1="Cookie:$1"
export _H2="Accept-Language:en-US"
data_id="$2"
url="https://freedns.afraid.org/subdomain/edit.php?data_id=$2"
_debug "Retrieve data page for ID $data_id from FreeDNS"
htmlpage="$(_get "$url")"
if [ "$?" != "0" ]; then
_err "FreeDNS retrieve data page failed bad RC from _get"
return 1
elif [ -z "$htmlpage" ]; then
_err "FreeDNS returned empty data page"
return 1
fi
_debug3 "htmlpage: $htmlpage"
printf "%s" "$htmlpage"
return 0
@@ -328,7 +232,7 @@ _freedns_add_txt_record() {
domain_id="$2"
subdomain="$3"
value="$(printf '%s' "$4" | _url_encode)"
url="http://freedns.afraid.org/subdomain/save.php?step=2"
url="https://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")"
@@ -336,17 +240,17 @@ _freedns_add_txt_record() {
_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"
_debug3 "htmlpage: $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"
_debug3 "htmlpage: $htmlpage"
_err "FreeDNS failed to add TXT record for $subdomain as FreeDNS requested security code"
_err "Note that you cannot use automatic DNS validation for FreeDNS public domains"
return 1
fi
_debug2 "$htmlpage"
_debug3 "htmlpage: $htmlpage"
_info "Added acme challenge TXT record for $fulldomain at FreeDNS"
return 0
}
@@ -365,7 +269,7 @@ _freedns_delete_txt_record() {
_err "FreeDNS failed to delete TXT record for $data_id bad RC from _get"
return 1
elif ! _contains "$htmlheader" "200 OK"; then
_debug "$htmlheader"
_debug2 "htmlheader: $htmlheader"
_err "FreeDNS failed to delete TXT record $data_id"
return 1
fi
@@ -373,3 +277,95 @@ _freedns_delete_txt_record() {
_info "Deleted acme challenge TXT record for $fulldomain at FreeDNS"
return 0
}
# usage _freedns_domain_id domain_name
# echo the domain_id if found
# return 0 success
_freedns_domain_id() {
# Start by escaping the dots in the domain name
search_domain="$(echo "$1" | sed 's/\./\\./g')"
# Sometimes FreeDNS does not return 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 changed? If so..."
_err "Please export as FREEDNS_User / FREEDNS_Password and try again."
fi
return 1
fi
domain_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's/<tr>/@<tr>/g' | tr '@' '\n' \
| grep "<td>$search_domain</td>\|<td>$search_domain(.*)</td>" \
| _egrep_o "edit\.php\?edit_domain_id=[0-9a-zA-Z]+" \
| cut -d = -f 2)"
# The above beauty extracts domain ID from the html page...
# strip out all blank space and new lines. Then insert newlines
# before each table row <tr>
# search for the domain within each row (which may or may not have
# a text string in brackets (.*) after it.
# And finally extract the domain ID.
if [ -n "$domain_id" ]; then
printf "%s" "$domain_id"
return 0
fi
_debug "Domain $search_domain not found. Retry loading subdomain page ($attempts attempts remaining)"
done
_debug "Domain $search_domain not found after retry"
return 1
}
# usage _freedns_data_id domain_name record_type
# echo the data_id(s) if found
# return 0 success
_freedns_data_id() {
# Start by escaping the dots in the domain name
search_domain="$(echo "$1" | sed 's/\./\\./g')"
record_type="$2"
# Sometimes FreeDNS does not return 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 changed? If so..."
_err "Please export as FREEDNS_User / FREEDNS_Password and try again."
fi
return 1
fi
data_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's/<tr>/@<tr>/g' | tr '@' '\n' \
| grep "<td[a-zA-Z=#]*>$record_type</td>" \
| grep "<ahref.*>$search_domain</a>" \
| _egrep_o "edit\.php\?data_id=[0-9a-zA-Z]+" \
| cut -d = -f 2)"
# The above beauty extracts data ID from the html page...
# strip out all blank space and new lines. Then insert newlines
# before each table row <tr>
# search for the record type withing each row (e.g. TXT)
# search for the domain within each row (which is within a <a..>
# </a> anchor. And finally extract the domain ID.
if [ -n "$data_id" ]; then
printf "%s" "$data_id"
return 0
fi
_debug "Domain $search_domain not found. Retry loading subdomain page ($attempts attempts remaining)"
done
_debug "Domain $search_domain not found after retry"
return 1
}

175
dnsapi/dns_gandi_livedns.sh Normal file
View File

@@ -0,0 +1,175 @@
#!/usr/bin/env sh
# Gandi LiveDNS v5 API
# http://doc.livedns.gandi.net/
# currently under beta
#
# Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable
#
#Author: Frédéric Crozat <fcrozat@suse.com>
# Dominik Röttsches <drott@google.com>
#Report Bugs here: https://github.com/fcrozat/acme.sh
#
######## Public functions #####################
GANDI_LIVEDNS_API="https://dns.api.gandi.net/api/v5"
#Usage: dns_gandi_livedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_gandi_livedns_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$GANDI_LIVEDNS_KEY" ]; then
_err "No API key specified for Gandi LiveDNS."
_err "Create your key and export it as GANDI_LIVEDNS_KEY"
return 1
fi
_saveaccountconf GANDI_LIVEDNS_KEY "$GANDI_LIVEDNS_KEY"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_debug domain "$_domain"
_debug sub_domain "$_sub_domain"
_dns_gandi_append_record "$_domain" "$_sub_domain" "$txtvalue"
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_gandi_livedns_rm() {
fulldomain=$1
txtvalue=$2
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug fulldomain "$fulldomain"
_debug domain "$_domain"
_debug sub_domain "$_sub_domain"
_debug txtvalue "$txtvalue"
if ! _dns_gandi_existing_rrset_values "$_domain" "$_sub_domain"; then
return 1
fi
_new_rrset_values=$(echo "$_rrset_values" | sed "s/...$txtvalue...//g")
# Cleanup dangling commata.
_new_rrset_values=$(echo "$_new_rrset_values" | sed "s/, ,/ ,/g")
_new_rrset_values=$(echo "$_new_rrset_values" | sed "s/, *\]/\]/g")
_new_rrset_values=$(echo "$_new_rrset_values" | sed "s/\[ *,/\[/g")
_debug "New rrset_values" "$_new_rrset_values"
_gandi_livedns_rest PUT \
"domains/$_domain/records/$_sub_domain/TXT" \
"{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" \
&& _contains "$response" '{"message": "DNS Record Created"}' \
&& _info "Removing record $(__green "success")"
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain=$1
i=2
p=1
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 ! _gandi_livedns_rest GET "domains/$h"; then
return 1
fi
if _contains "$response" '"code": 401'; then
_err "$response"
return 1
elif _contains "$response" '"code": 404'; then
_debug "$h not found"
else
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
return 0
fi
p="$i"
i=$(_math "$i" + 1)
done
return 1
}
_dns_gandi_append_record() {
domain=$1
sub_domain=$2
txtvalue=$3
if _dns_gandi_existing_rrset_values "$domain" "$sub_domain"; then
_debug "Appending new value"
_rrset_values=$(echo "$_rrset_values" | sed "s/\"]/\",\"$txtvalue\"]/")
else
_debug "Creating new record" "$_rrset_values"
_rrset_values="[\"$txtvalue\"]"
fi
_debug new_rrset_values "$_rrset_values"
_gandi_livedns_rest PUT "domains/$_domain/records/$sub_domain/TXT" \
"{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" \
&& _contains "$response" '{"message": "DNS Record Created"}' \
&& _info "Adding record $(__green "success")"
}
_dns_gandi_existing_rrset_values() {
domain=$1
sub_domain=$2
if ! _gandi_livedns_rest GET "domains/$domain/records/$sub_domain"; then
return 1
fi
if ! _contains "$response" '"rrset_type": "TXT"'; then
_debug "Does not have a _acme-challenge TXT record yet."
return 1
fi
if _contains "$response" '"rrset_values": \[\]'; then
_debug "Empty rrset_values for TXT record, no previous TXT record."
return 1
fi
_debug "Already has TXT record."
_rrset_values=$(echo "$response" | _egrep_o 'rrset_values.*\[.*\]' \
| _egrep_o '\[".*\"]')
return 0
}
_gandi_livedns_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
export _H1="Content-Type: application/json"
export _H2="X-Api-Key: $GANDI_LIVEDNS_KEY"
if [ "$m" = "GET" ]; then
response="$(_get "$GANDI_LIVEDNS_API/$ep")"
else
_debug data "$data"
response="$(_post "$data" "$GANDI_LIVEDNS_API/$ep" "" "$m")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

167
dnsapi/dns_gcloud.sh Executable file
View File

@@ -0,0 +1,167 @@
#!/usr/bin/env sh
# Author: Janos Lenart <janos@lenart.io>
######## Public functions #####################
# Usage: dns_gcloud_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_gcloud_add() {
fulldomain=$1
txtvalue=$2
_info "Using gcloud"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_dns_gcloud_find_zone || return $?
# Add an extra RR
_dns_gcloud_start_tr || return $?
_dns_gcloud_get_rrdatas || return $?
echo "$rrdatas" | _dns_gcloud_remove_rrs || return $?
printf "%s\n%s\n" "$rrdatas" "\"$txtvalue\"" | grep -v '^$' | _dns_gcloud_add_rrs || return $?
_dns_gcloud_execute_tr || return $?
_info "$fulldomain record added"
}
# Usage: dns_gcloud_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Remove the txt record after validation.
dns_gcloud_rm() {
fulldomain=$1
txtvalue=$2
_info "Using gcloud"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_dns_gcloud_find_zone || return $?
# Remove one RR
_dns_gcloud_start_tr || return $?
_dns_gcloud_get_rrdatas || return $?
echo "$rrdatas" | _dns_gcloud_remove_rrs || return $?
echo "$rrdatas" | grep -F -v "\"$txtvalue\"" | _dns_gcloud_add_rrs || return $?
_dns_gcloud_execute_tr || return $?
_info "$fulldomain record added"
}
#################### Private functions below ##################################
_dns_gcloud_start_tr() {
if ! trd=$(mktemp -d); then
_err "_dns_gcloud_start_tr: failed to create temporary directory"
return 1
fi
tr="$trd/tr.yaml"
_debug tr "$tr"
if ! gcloud dns record-sets transaction start \
--transaction-file="$tr" \
--zone="$managedZone"; then
rm -r "$trd"
_err "_dns_gcloud_start_tr: failed to execute transaction"
return 1
fi
}
_dns_gcloud_execute_tr() {
if ! gcloud dns record-sets transaction execute \
--transaction-file="$tr" \
--zone="$managedZone"; then
_debug tr "$(cat "$tr")"
rm -r "$trd"
_err "_dns_gcloud_execute_tr: failed to execute transaction"
return 1
fi
rm -r "$trd"
for i in $(seq 1 120); do
if gcloud dns record-sets changes list \
--zone="$managedZone" \
--filter='status != done' \
| grep -q '^.*'; then
_info "_dns_gcloud_execute_tr: waiting for transaction to be comitted ($i/120)..."
sleep 5
else
return 0
fi
done
_err "_dns_gcloud_execute_tr: transaction is still pending after 10 minutes"
rm -r "$trd"
return 1
}
_dns_gcloud_remove_rrs() {
if ! xargs -r gcloud dns record-sets transaction remove \
--name="$fulldomain." \
--ttl="$ttl" \
--type=TXT \
--zone="$managedZone" \
--transaction-file="$tr"; then
_debug tr "$(cat "$tr")"
rm -r "$trd"
_err "_dns_gcloud_remove_rrs: failed to remove RRs"
return 1
fi
}
_dns_gcloud_add_rrs() {
ttl=60
if ! xargs -r gcloud dns record-sets transaction add \
--name="$fulldomain." \
--ttl="$ttl" \
--type=TXT \
--zone="$managedZone" \
--transaction-file="$tr"; then
_debug tr "$(cat "$tr")"
rm -r "$trd"
_err "_dns_gcloud_add_rrs: failed to add RRs"
return 1
fi
}
_dns_gcloud_find_zone() {
# Prepare a filter that matches zones that are suiteable for this entry.
# For example, _acme-challenge.something.domain.com might need to go into something.domain.com or domain.com;
# this function finds the longest postfix that has a managed zone.
part="$fulldomain"
filter="dnsName=( "
while [ "$part" != "" ]; do
filter="$filter$part. "
part="$(echo "$part" | sed 's/[^.]*\.*//')"
done
filter="$filter)"
_debug filter "$filter"
# List domains and find the zone with the deepest sub-domain (in case of some levels of delegation)
if ! match=$(gcloud dns managed-zones list \
--format="value(name, dnsName)" \
--filter="$filter" \
| while read -r dnsName name; do
printf "%s\t%s\t%s\n" "$(echo "$name" | awk -F"." '{print NF-1}')" "$dnsName" "$name"
done \
| sort -n -r | _head_n 1 | cut -f2,3 | grep '^.*'); then
_err "_dns_gcloud_find_zone: Can't find a matching managed zone! Perhaps wrong project or gcloud credentials?"
return 1
fi
dnsName=$(echo "$match" | cut -f2)
_debug dnsName "$dnsName"
managedZone=$(echo "$match" | cut -f1)
_debug managedZone "$managedZone"
}
_dns_gcloud_get_rrdatas() {
if ! rrdatas=$(gcloud dns record-sets list \
--zone="$managedZone" \
--name="$fulldomain." \
--type=TXT \
--format="value(ttl,rrdatas)"); then
_err "_dns_gcloud_get_rrdatas: Failed to list record-sets"
rm -r "$trd"
return 1
fi
ttl=$(echo "$rrdatas" | cut -f1)
rrdatas=$(echo "$rrdatas" | cut -f2 | sed 's/","/"\n"/g')
}

View File

@@ -15,6 +15,8 @@ dns_gd_add() {
fulldomain=$1
txtvalue=$2
GD_Key="${GD_Key:-$(_readaccountconf_mutable GD_Key)}"
GD_Secret="${GD_Secret:-$(_readaccountconf_mutable GD_Secret)}"
if [ -z "$GD_Key" ] || [ -z "$GD_Secret" ]; then
GD_Key=""
GD_Secret=""
@@ -24,8 +26,8 @@ dns_gd_add() {
fi
#save the api key and email to the account conf file.
_saveaccountconf GD_Key "$GD_Key"
_saveaccountconf GD_Secret "$GD_Secret"
_saveaccountconf_mutable GD_Key "$GD_Key"
_saveaccountconf_mutable GD_Secret "$GD_Secret"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
@@ -36,27 +38,80 @@ dns_gd_add() {
_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
_info "Added, sleeping 10 seconds"
sleep 10
#todo: check if the record takes effect
return 0
else
_err "Add txt record error."
_err "$response"
return 1
_debug "Getting existing records"
if ! _gd_rest GET "domains/$_domain/records/TXT/$_sub_domain"; then
return 1
fi
if _contains "$response" "$txtvalue"; then
_info "The record is existing, skip"
return 0
fi
_add_data="{\"data\":\"$txtvalue\"}"
for t in $(echo "$response" | tr '{' "\n" | grep "\"name\":\"$_sub_domain\"" | tr ',' "\n" | grep '"data"' | cut -d : -f 2); do
_debug2 t "$t"
if [ "$t" ]; then
_add_data="$_add_data,{\"data\":$t}"
fi
done
_debug2 _add_data "$_add_data"
_info "Adding record"
if _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"; then
_info "Added, sleeping 10 seconds"
_sleep 10
#todo: check if the record takes effect
return 0
fi
_err "Add txt record error."
return 1
}
#fulldomain
dns_gd_rm() {
fulldomain=$1
txtvalue=$2
GD_Key="${GD_Key:-$(_readaccountconf_mutable GD_Key)}"
GD_Secret="${GD_Secret:-$(_readaccountconf_mutable GD_Secret)}"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting existing records"
if ! _gd_rest GET "domains/$_domain/records/TXT/$_sub_domain"; then
return 1
fi
if ! _contains "$response" "$txtvalue"; then
_info "The record is not existing, skip"
return 0
fi
_add_data=""
for t in $(echo "$response" | tr '{' "\n" | grep "\"name\":\"$_sub_domain\"" | tr ',' "\n" | grep '"data"' | cut -d : -f 2); do
_debug2 t "$t"
if [ "$t" ] && [ "$t" != "\"$txtvalue\"" ]; then
if [ "$_add_data" ]; then
_add_data="$_add_data,{\"data\":$t}"
else
_add_data="{\"data\":$t}"
fi
fi
done
if [ -z "$_add_data" ]; then
_add_data="{\"data\":\"\"}"
fi
_debug2 _add_data "$_add_data"
_gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"
}
#################### Private functions below ##################################
@@ -113,5 +168,9 @@ _gd_rest() {
return 1
fi
_debug2 response "$response"
if _contains "$response" "UNABLE_TO_AUTHENTICATE"; then
_err "It seems that your api key or secret is not correct."
return 1
fi
return 0
}

168
dnsapi/dns_gdnsdk.sh Executable file
View File

@@ -0,0 +1,168 @@
#!/usr/bin/env sh
#Author: Herman Sletteng
#Report Bugs here: https://github.com/loial/acme.sh
#
#
# Note, gratisdns requires a login first, so the script needs to handle
# temporary cookies. Since acme.sh _get/_post currently don't directly support
# cookies, I've defined wrapper functions _myget/_mypost to set the headers
GDNSDK_API="https://admin.gratisdns.com"
######## Public functions #####################
#Usage: dns_gdnsdk_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_gdnsdk_add() {
fulldomain=$1
txtvalue=$2
_info "Using gratisdns.dk"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
if ! _gratisdns_login; then
_err "Login failed!"
return 1
fi
#finding domain zone
if ! _get_domain; then
_err "No matching root domain for $fulldomain found"
return 1
fi
# adding entry
_info "Adding the entry"
_mypost "action=dns_primary_record_added_txt&user_domain=$_domain&name=$fulldomain&txtdata=$txtvalue&ttl=1"
if _successful_update; then return 0; fi
_err "Couldn't create entry!"
return 1
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_gdnsdk_rm() {
fulldomain=$1
txtvalue=$2
_info "Using gratisdns.dk"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
if ! _gratisdns_login; then
_err "Login failed!"
return 1
fi
if ! _get_domain; then
_err "No matching root domain for $fulldomain found"
return 1
fi
_findentry "$fulldomain" "$txtvalue"
if [ -z "$_id" ]; then
_info "Entry doesn't exist, nothing to delete"
return 0
fi
_debug "Deleting record..."
_mypost "action=dns_primary_delete_txt&user_domain=$_domain&id=$_id"
# removing entry
if _successful_update; then return 0; fi
_err "Couldn't delete entry!"
return 1
}
#################### Private functions below ##################################
_checkcredentials() {
GDNSDK_Username="${GDNSDK_Username:-$(_readaccountconf_mutable GDNSDK_Username)}"
GDNSDK_Password="${GDNSDK_Password:-$(_readaccountconf_mutable GDNSDK_Password)}"
if [ -z "$GDNSDK_Username" ] || [ -z "$GDNSDK_Password" ]; then
GDNSDK_Username=""
GDNSDK_Password=""
_err "You haven't specified gratisdns.dk username and password yet."
_err "Please add credentials and try again."
return 1
fi
#save the credentials to the account conf file.
_saveaccountconf_mutable GDNSDK_Username "$GDNSDK_Username"
_saveaccountconf_mutable GDNSDK_Password "$GDNSDK_Password"
return 0
}
_checkcookie() {
GDNSDK_Cookie="${GDNSDK_Cookie:-$(_readaccountconf_mutable GDNSDK_Cookie)}"
if [ -z "$GDNSDK_Cookie" ]; then
_debug "No cached cookie found"
return 1
fi
_myget "action="
if (echo "$_result" | grep -q "logmeout"); then
_debug "Cached cookie still valid"
return 0
fi
_debug "Cached cookie no longer valid"
GDNSDK_Cookie=""
_saveaccountconf_mutable GDNSDK_Cookie "$GDNSDK_Cookie"
return 1
}
_gratisdns_login() {
if ! _checkcredentials; then return 1; fi
if _checkcookie; then
_debug "Already logged in"
return 0
fi
_debug "Logging into GratisDNS with user $GDNSDK_Username"
if ! _mypost "login=$GDNSDK_Username&password=$GDNSDK_Password&action=logmein"; then
_err "GratisDNS login failed for user $GDNSDK_Username bad RC from _post"
return 1
fi
GDNSDK_Cookie="$(grep -A 15 '302 Found' "$HTTP_HEADER" | _egrep_o 'Cookie: [^;]*' | _head_n 1 | cut -d ' ' -f2)"
if [ -z "$GDNSDK_Cookie" ]; then
_err "GratisDNS login failed for user $GDNSDK_Username. Check $HTTP_HEADER file"
return 1
fi
export GDNSDK_Cookie
_saveaccountconf_mutable GDNSDK_Cookie "$GDNSDK_Cookie"
return 0
}
_myget() {
#Adds cookie to request
export _H1="Cookie: $GDNSDK_Cookie"
_result=$(_get "$GDNSDK_API?$1")
}
_mypost() {
#Adds cookie to request
export _H1="Cookie: $GDNSDK_Cookie"
_result=$(_post "$1" "$GDNSDK_API")
}
_get_domain() {
_myget 'action=dns_primarydns'
_domains=$(echo "$_result" | _egrep_o ' domain="[[:alnum:]._-]+' | sed 's/^.*"//')
if [ -z "$_domains" ]; then
_err "Primary domain list not found!"
return 1
fi
for _domain in $_domains; do
if (_endswith "$fulldomain" "$_domain"); then
_debug "Root domain: $_domain"
return 0
fi
done
return 1
}
_successful_update() {
if (echo "$_result" | grep -q 'table-success'); then return 0; fi
return 1
}
_findentry() {
#returns id of dns entry, if it exists
_myget "action=dns_primary_changeDNSsetup&user_domain=$_domain"
_id=$(echo "$_result" | _egrep_o "<td>$1</td>\s*<td>$2</td>[^?]*[^&]*&id=[^&]*" | sed 's/^.*=//')
if [ -n "$_id" ]; then
_debug "Entry found with _id=$_id"
return 0
fi
return 1
}

169
dnsapi/dns_he.sh Executable file
View File

@@ -0,0 +1,169 @@
#!/usr/bin/env sh
########################################################################
# Hurricane Electric hook script for acme.sh
#
# Environment variables:
#
# - $HE_Username (your dns.he.net username)
# - $HE_Password (your dns.he.net password)
#
# Author: Ondrej Simek <me@ondrejsimek.com>
# Git repo: https://github.com/angel333/acme.sh
#-- dns_he_add() - Add TXT record --------------------------------------
# Usage: dns_he_add _acme-challenge.subdomain.domain.com "XyZ123..."
dns_he_add() {
_full_domain=$1
_txt_value=$2
_info "Using DNS-01 Hurricane Electric hook"
HE_Username="${HE_Username:-$(_readaccountconf_mutable HE_Username)}"
HE_Password="${HE_Password:-$(_readaccountconf_mutable HE_Password)}"
if [ -z "$HE_Username" ] || [ -z "$HE_Password" ]; then
HE_Username=
HE_Password=
_err "No auth details provided. Please set user credentials using the \$HE_Username and \$HE_Password envoronment variables."
return 1
fi
_saveaccountconf_mutable HE_Username "$HE_Username"
_saveaccountconf_mutable HE_Password "$HE_Password"
# Fills in the $_zone_id
_find_zone "$_full_domain" || return 1
_debug "Zone id \"$_zone_id\" will be used."
username_encoded="$(printf "%s" "${HE_Username}" | _url_encode)"
password_encoded="$(printf "%s" "${HE_Password}" | _url_encode)"
body="email=${username_encoded}&pass=${password_encoded}"
body="$body&account="
body="$body&menu=edit_zone"
body="$body&Type=TXT"
body="$body&hosted_dns_zoneid=$_zone_id"
body="$body&hosted_dns_recordid="
body="$body&hosted_dns_editzone=1"
body="$body&Priority="
body="$body&Name=$_full_domain"
body="$body&Content=$_txt_value"
body="$body&TTL=300"
body="$body&hosted_dns_editrecord=Submit"
response="$(_post "$body" "https://dns.he.net/")"
exit_code="$?"
if [ "$exit_code" -eq 0 ]; then
_info "TXT record added successfully."
else
_err "Couldn't add the TXT record."
fi
_debug2 response "$response"
return "$exit_code"
}
#-- dns_he_rm() - Remove TXT record ------------------------------------
# Usage: dns_he_rm _acme-challenge.subdomain.domain.com "XyZ123..."
dns_he_rm() {
_full_domain=$1
_txt_value=$2
_info "Cleaning up after DNS-01 Hurricane Electric hook"
HE_Username="${HE_Username:-$(_readaccountconf_mutable HE_Username)}"
HE_Password="${HE_Password:-$(_readaccountconf_mutable HE_Password)}"
# fills in the $_zone_id
_find_zone "$_full_domain" || return 1
_debug "Zone id \"$_zone_id\" will be used."
# Find the record id to clean
username_encoded="$(printf "%s" "${HE_Username}" | _url_encode)"
password_encoded="$(printf "%s" "${HE_Password}" | _url_encode)"
body="email=${username_encoded}&pass=${password_encoded}"
body="$body&hosted_dns_zoneid=$_zone_id"
body="$body&menu=edit_zone"
body="$body&hosted_dns_editzone="
response="$(_post "$body" "https://dns.he.net/")"
_debug2 "response" "$response"
if ! _contains "$response" "$_txt_value"; then
_debug "The txt record is not found, just skip"
return 0
fi
_record_id="$(echo "$response" | tr -d "#" | sed "s/<tr/#<tr/g" | tr -d "\n" | tr "#" "\n" | grep "$_full_domain" | grep '"dns_tr"' | grep "$_txt_value" | cut -d '"' -f 4)"
_debug2 _record_id "$_record_id"
if [ -z "$_record_id" ]; then
_err "Can not find record id"
return 1
fi
# Remove the record
username_encoded="$(printf "%s" "${HE_Username}" | _url_encode)"
password_encoded="$(printf "%s" "${HE_Password}" | _url_encode)"
body="email=${username_encoded}&pass=${password_encoded}"
body="$body&menu=edit_zone"
body="$body&hosted_dns_zoneid=$_zone_id"
body="$body&hosted_dns_recordid=$_record_id"
body="$body&hosted_dns_editzone=1"
body="$body&hosted_dns_delrecord=1"
body="$body&hosted_dns_delconfirm=delete"
_post "$body" "https://dns.he.net/" \
| grep '<div id="dns_status" onClick="hideThis(this);">Successfully removed record.</div>' \
>/dev/null
exit_code="$?"
if [ "$exit_code" -eq 0 ]; then
_info "Record removed successfully."
else
_err "Could not clean (remove) up the record. Please go to HE administration interface and clean it by hand."
return "$exit_code"
fi
}
########################## PRIVATE FUNCTIONS ###########################
_find_zone() {
_domain="$1"
username_encoded="$(printf "%s" "${HE_Username}" | _url_encode)"
password_encoded="$(printf "%s" "${HE_Password}" | _url_encode)"
body="email=${username_encoded}&pass=${password_encoded}"
response="$(_post "$body" "https://dns.he.net/")"
_debug2 response "$response"
if _contains "$response" '>Incorrect<'; then
_err "Unable to login to dns.he.net please check username and password"
return 1
fi
_table="$(echo "$response" | tr -d "#" | sed "s/<table/#<table/g" | tr -d "\n" | tr "#" "\n" | grep 'id="domains_table"')"
_debug2 _table "$_table"
_matches="$(echo "$_table" | sed "s/<tr/#<tr/g" | tr "#" "\n" | grep 'alt="edit"' | tr -d " " | sed "s/<td/#<td/g" | tr "#" "\n" | grep 'hosted_dns_zoneid')"
_debug2 _matches "$_matches"
# Zone names and zone IDs are in same order
_zone_ids=$(echo "$_matches" | _egrep_o "hosted_dns_zoneid=[0-9]*&" | cut -d = -f 2 | tr -d '&')
_zone_names=$(echo "$_matches" | _egrep_o "name=.*onclick" | cut -d '"' -f 2)
_debug2 "These are the zones on this HE account:"
_debug2 "$_zone_names"
_debug2 "And these are their respective IDs:"
_debug2 "$_zone_ids"
if [ -z "$_zone_names" ] || [ -z "$_zone_ids" ]; then
_err "Can not get zone names."
return 1
fi
# Walk through all possible zone names
_strip_counter=1
while true; do
_attempted_zone=$(echo "$_domain" | cut -d . -f ${_strip_counter}-)
# All possible zone names have been tried
if [ -z "$_attempted_zone" ]; then
_err "No zone for domain \"$_domain\" found."
return 1
fi
_debug "Looking for zone \"${_attempted_zone}\""
line_num="$(echo "$_zone_names" | grep -n "^$_attempted_zone" | cut -d : -f 1)"
if [ "$line_num" ]; then
_zone_id=$(echo "$_zone_ids" | sed -n "${line_num}p")
_debug "Found relevant zone \"$_attempted_zone\" with id \"$_zone_id\" - will be used for domain \"$_domain\"."
return 0
fi
_debug "Zone \"$_attempted_zone\" doesn't exist, let's try a less specific zone."
_strip_counter=$(_math "$_strip_counter" + 1)
done
}
# vim: et:ts=2:sw=2:

178
dnsapi/dns_hostingde.sh Normal file
View File

@@ -0,0 +1,178 @@
#!/usr/bin/env sh
# hosting.de API
# Values to export:
# export HOSTINGDE_ENDPOINT='https://secure.hosting.de'
# export HOSTINGDE_APIKEY='xxxxx'
######## Public functions #####################
dns_hostingde_add() {
fulldomain="${1}"
txtvalue="${2}"
_debug "Calling: _hostingde_addRecord() '${fulldomain}' '${txtvalue}'"
_hostingde_apiKey && _hostingde_getZoneConfig && _hostingde_addRecord
return $?
}
dns_hostingde_rm() {
fulldomain="${1}"
txtvalue="${2}"
_debug "Calling: _hostingde_removeRecord() '${fulldomain}' '${txtvalue}'"
_hostingde_apiKey && _hostingde_getZoneConfig && _hostingde_removeRecord
return $?
}
#################### own Private functions below ##################################
_hostingde_apiKey() {
HOSTINGDE_APIKEY="${HOSTINGDE_APIKEY:-$(_readaccountconf_mutable HOSTINGDE_APIKEY)}"
HOSTINGDE_ENDPOINT="${HOSTINGDE_ENDPOINT:-$(_readaccountconf_mutable HOSTINGDE_ENDPOINT)}"
if [ -z "$HOSTINGDE_APIKEY" ] || [ -z "$HOSTINGDE_ENDPOINT" ]; then
HOSTINGDE_APIKEY=""
HOSTINGDE_ENDPOINT=""
_err "You haven't specified hosting.de API key or endpoint yet."
_err "Please create your key and try again."
return 1
fi
_saveaccountconf_mutable HOSTINGDE_APIKEY "$HOSTINGDE_APIKEY"
_saveaccountconf_mutable HOSTINGDE_ENDPOINT "$HOSTINGDE_ENDPOINT"
}
_hostingde_parse() {
find="${1}"
if [ "${2}" ]; then
notfind="${2}"
fi
if [ "${notfind}" ]; then
_egrep_o \""${find}\":.*" | grep -v "${notfind}" | cut -d ':' -f 2 | cut -d ',' -f 1 | tr -d ' '
else
_egrep_o \""${find}\":.*" | cut -d ':' -f 2 | cut -d ',' -f 1 | tr -d ' '
fi
}
_hostingde_getZoneConfig() {
_info "Getting ZoneConfig"
curZone="${fulldomain#*.}"
returnCode=1
while _contains "${curZone}" "\\."; do
curData="{\"filter\":{\"field\":\"zoneName\",\"value\":\"${curZone}\"},\"limit\":1,\"authToken\":\"${HOSTINGDE_APIKEY}\"}"
curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneConfigsFind")"
_debug "Calling zoneConfigsFind: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneConfigsFind'"
_debug "Result of zoneConfigsFind: '$curResult'"
if _contains "${curResult}" '"status": "error"'; then
if _contains "${curResult}" '"code": 10109'; then
_err "The API-Key is invalid or could not be found"
else
_err "UNKNOWN API ERROR"
fi
returnCode=1
break
fi
if _contains "${curResult}" '"totalEntries": 1'; then
_info "Retrieved zone data."
_debug "Zone data: '${curResult}'"
zoneConfigId=$(echo "${curResult}" | _hostingde_parse "id")
zoneConfigName=$(echo "${curResult}" | _hostingde_parse "name")
zoneConfigType=$(echo "${curResult}" | _hostingde_parse "type" "FindZoneConfigsResult")
zoneConfigExpire=$(echo "${curResult}" | _hostingde_parse "expire")
zoneConfigNegativeTtl=$(echo "${curResult}" | _hostingde_parse "negativeTtl")
zoneConfigRefresh=$(echo "${curResult}" | _hostingde_parse "refresh")
zoneConfigRetry=$(echo "${curResult}" | _hostingde_parse "retry")
zoneConfigTtl=$(echo "${curResult}" | _hostingde_parse "ttl")
zoneConfigDnsServerGroupId=$(echo "${curResult}" | _hostingde_parse "dnsServerGroupId")
zoneConfigEmailAddress=$(echo "${curResult}" | _hostingde_parse "emailAddress")
zoneConfigDnsSecMode=$(echo "${curResult}" | _hostingde_parse "dnsSecMode")
zoneConfigTemplateValues=$(echo "${curResult}" | _hostingde_parse "templateValues")
if [ "$zoneConfigTemplateValues" != "null" ]; then
_debug "Zone is tied to a template."
zoneConfigTemplateValuesTemplateId=$(echo "${curResult}" | _hostingde_parse "templateId")
zoneConfigTemplateValuesTemplateName=$(echo "${curResult}" | _hostingde_parse "templateName")
zoneConfigTemplateValuesTemplateReplacementsIPv4=$(echo "${curResult}" | _hostingde_parse "ipv4Replacement")
zoneConfigTemplateValuesTemplateReplacementsIPv6=$(echo "${curResult}" | _hostingde_parse "ipv6Replacement")
zoneConfigTemplateValuesTemplateReplacementsMailIPv4=$(echo "${curResult}" | _hostingde_parse "mailIpv4Replacement")
zoneConfigTemplateValuesTemplateReplacementsMailIPv6=$(echo "${curResult}" | _hostingde_parse "mailIpv6Replacement")
zoneConfigTemplateValuesTemplateTieToTemplate=$(echo "${curResult}" | _hostingde_parse "tieToTemplate")
zoneConfigTemplateValues="{\"templateId\":${zoneConfigTemplateValuesTemplateId},\"templateName\":${zoneConfigTemplateValuesTemplateName},\"templateReplacements\":{\"ipv4Replacement\":${zoneConfigTemplateValuesTemplateReplacementsIPv4},\"ipv6Replacement\":${zoneConfigTemplateValuesTemplateReplacementsIPv6},\"mailIpv4Replacement\":${zoneConfigTemplateValuesTemplateReplacementsMailIPv4},\"mailIpv6Replacement\":${zoneConfigTemplateValuesTemplateReplacementsMailIPv6}},\"tieToTemplate\":${zoneConfigTemplateValuesTemplateTieToTemplate}}"
_debug "Template values: '{$zoneConfigTemplateValues}'"
fi
if [ "${zoneConfigType}" != "\"NATIVE\"" ]; then
_err "Zone is not native"
returnCode=1
break
fi
_debug "zoneConfigId '${zoneConfigId}'"
returnCode=0
break
fi
curZone="${curZone#*.}"
done
if [ $returnCode -ne 0 ]; then
_info "ZoneEnd reached, Zone ${curZone} not found in hosting.de API"
fi
return $returnCode
}
_hostingde_getZoneStatus() {
_debug "Checking Zone status"
curData="{\"filter\":{\"field\":\"zoneConfigId\",\"value\":${zoneConfigId}},\"limit\":1,\"authToken\":\"${HOSTINGDE_APIKEY}\"}"
curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zonesFind")"
_debug "Calling zonesFind '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zonesFind'"
_debug "Result of zonesFind '$curResult'"
zoneStatus=$(echo "${curResult}" | _hostingde_parse "status" "success")
_debug "zoneStatus '${zoneStatus}'"
return 0
}
_hostingde_addRecord() {
_info "Adding record to zone"
_hostingde_getZoneStatus
_debug "Result of zoneStatus: '${zoneStatus}'"
while [ "${zoneStatus}" != "\"active\"" ]; do
_sleep 5
_hostingde_getZoneStatus
_debug "Result of zoneStatus: '${zoneStatus}'"
done
curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":${zoneConfigId},\"name\":${zoneConfigName},\"type\":${zoneConfigType},\"dnsServerGroupId\":${zoneConfigDnsServerGroupId},\"dnsSecMode\":${zoneConfigDnsSecMode},\"emailAddress\":${zoneConfigEmailAddress},\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}},\"templateValues\":${zoneConfigTemplateValues}},\"recordsToAdd\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\",\"ttl\":3600}]}"
curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")"
_debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'"
_debug "Result of zoneUpdate: '$curResult'"
if _contains "${curResult}" '"status": "error"'; then
if _contains "${curResult}" '"code": 10109'; then
_err "The API-Key is invalid or could not be found"
else
_err "UNKNOWN API ERROR"
fi
return 1
fi
return 0
}
_hostingde_removeRecord() {
_info "Removing record from zone"
_hostingde_getZoneStatus
_debug "Result of zoneStatus: '$zoneStatus'"
while [ "$zoneStatus" != "\"active\"" ]; do
_sleep 5
_hostingde_getZoneStatus
_debug "Result of zoneStatus: '$zoneStatus'"
done
curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":${zoneConfigId},\"name\":${zoneConfigName},\"type\":${zoneConfigType},\"dnsServerGroupId\":${zoneConfigDnsServerGroupId},\"dnsSecMode\":${zoneConfigDnsSecMode},\"emailAddress\":${zoneConfigEmailAddress},\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}},\"templateValues\":${zoneConfigTemplateValues}},\"recordsToDelete\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\"}]}"
curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")"
_debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'"
_debug "Result of zoneUpdate: '$curResult'"
if _contains "${curResult}" '"status": "error"'; then
if _contains "${curResult}" '"code": 10109'; then
_err "The API-Key is invalid or could not be found"
else
_err "UNKNOWN API ERROR"
fi
return 1
fi
return 0
}

102
dnsapi/dns_infoblox.sh Normal file
View File

@@ -0,0 +1,102 @@
#!/usr/bin/env sh
## Infoblox API integration by Jason Keller and Elijah Tenai
##
## Report any bugs via https://github.com/jasonkeller/acme.sh
dns_infoblox_add() {
## Nothing to see here, just some housekeeping
fulldomain=$1
txtvalue=$2
baseurlnObject="https://$Infoblox_Server/wapi/v2.2.2/record:txt?name=$fulldomain&text=$txtvalue&view=$Infoblox_View"
_info "Using Infoblox API"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
## Check for the credentials
if [ -z "$Infoblox_Creds" ] || [ -z "$Infoblox_Server" ]; then
Infoblox_Creds=""
Infoblox_Server=""
_err "You didn't specify the credentials, server or infoblox view yet (Infoblox_Creds, Infoblox_Server and Infoblox_View)."
_err "Please set them via EXPORT ([username:password], [ip or hostname]) and try again."
return 1
fi
if [ -z "$Infoblox_View" ]; then
Infoblox_View="default"
fi
## Save the credentials to the account file
_saveaccountconf Infoblox_Creds "$Infoblox_Creds"
_saveaccountconf Infoblox_Server "$Infoblox_Server"
_saveaccountconf Infoblox_View "$Infoblox_View"
## Base64 encode the credentials
Infoblox_CredsEncoded=$(printf "%b" "$Infoblox_Creds" | _base64)
## Construct the HTTP Authorization header
export _H1="Accept-Language:en-US"
export _H2="Authorization: Basic $Infoblox_CredsEncoded"
## Add the challenge record to the Infoblox grid member
result="$(_post "" "$baseurlnObject" "" "POST")"
## Let's see if we get something intelligible back from the unit
if [ "$(echo "$result" | _egrep_o "record:txt/.*:.*/$Infoblox_View")" ]; then
_info "Successfully created the txt record"
return 0
else
_err "Error encountered during record addition"
_err "$result"
return 1
fi
}
dns_infoblox_rm() {
## Nothing to see here, just some housekeeping
fulldomain=$1
txtvalue=$2
_info "Using Infoblox API"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
## Base64 encode the credentials
Infoblox_CredsEncoded="$(printf "%b" "$Infoblox_Creds" | _base64)"
## Construct the HTTP Authorization header
export _H1="Accept-Language:en-US"
export _H2="Authorization: Basic $Infoblox_CredsEncoded"
## Does the record exist? Let's check.
baseurlnObject="https://$Infoblox_Server/wapi/v2.2.2/record:txt?name=$fulldomain&text=$txtvalue&view=$Infoblox_View&_return_type=xml-pretty"
result="$(_get "$baseurlnObject")"
## Let's see if we get something intelligible back from the grid
if [ "$(echo "$result" | _egrep_o "record:txt/.*:.*/$Infoblox_View")" ]; then
## Extract the object reference
objRef="$(printf "%b" "$result" | _egrep_o "record:txt/.*:.*/$Infoblox_View")"
objRmUrl="https://$Infoblox_Server/wapi/v2.2.2/$objRef"
## Delete them! All the stale records!
rmResult="$(_post "" "$objRmUrl" "" "DELETE")"
## Let's see if that worked
if [ "$(echo "$rmResult" | _egrep_o "record:txt/.*:.*/$Infoblox_View")" ]; then
_info "Successfully deleted $objRef"
return 0
else
_err "Error occurred during txt record delete"
_err "$rmResult"
return 1
fi
else
_err "Record to delete didn't match an existing record"
_err "$result"
return 1
fi
}
#################### Private functions below ##################################

180
dnsapi/dns_internetbs.sh Executable file
View File

@@ -0,0 +1,180 @@
#!/usr/bin/env sh
#This is the Internet.BS api wrapper for acme.sh
#
#Author: <alexey@nelexa.ru> Ne-Lexa
#Report Bugs here: https://github.com/Ne-Lexa/acme.sh
#INTERNETBS_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje"
#INTERNETBS_API_PASSWORD="sdfsdfsdfljlbjkljlkjsdfoiwje"
INTERNETBS_API_URL="https://api.internet.bs"
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_internetbs_add() {
fulldomain=$1
txtvalue=$2
INTERNETBS_API_KEY="${INTERNETBS_API_KEY:-$(_readaccountconf_mutable INTERNETBS_API_KEY)}"
INTERNETBS_API_PASSWORD="${INTERNETBS_API_PASSWORD:-$(_readaccountconf_mutable INTERNETBS_API_PASSWORD)}"
if [ -z "$INTERNETBS_API_KEY" ] || [ -z "$INTERNETBS_API_PASSWORD" ]; then
INTERNETBS_API_KEY=""
INTERNETBS_API_PASSWORD=""
_err "You didn't specify the INTERNET.BS api key and password yet."
_err "Please create you key and try again."
return 1
fi
_saveaccountconf_mutable INTERNETBS_API_KEY "$INTERNETBS_API_KEY"
_saveaccountconf_mutable INTERNETBS_API_PASSWORD "$INTERNETBS_API_PASSWORD"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
# https://testapi.internet.bs/Domain/DnsRecord/Add?ApiKey=testapi&Password=testpass&FullRecordName=w3.test-api-domain7.net&Type=CNAME&Value=www.internet.bs%&ResponseFormat=json
if _internetbs_rest POST "Domain/DnsRecord/Add" "FullRecordName=${_sub_domain}.${_domain}&Type=TXT&Value=${txtvalue}&ResponseFormat=json"; then
if ! _contains "$response" "\"status\":\"SUCCESS\""; then
_err "ERROR add TXT record"
_err "$response"
return 1
fi
_info "txt record add success."
return 0
fi
return 1
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_internetbs_rm() {
fulldomain=$1
txtvalue=$2
INTERNETBS_API_KEY="${INTERNETBS_API_KEY:-$(_readaccountconf_mutable INTERNETBS_API_KEY)}"
INTERNETBS_API_PASSWORD="${INTERNETBS_API_PASSWORD:-$(_readaccountconf_mutable INTERNETBS_API_PASSWORD)}"
if [ -z "$INTERNETBS_API_KEY" ] || [ -z "$INTERNETBS_API_PASSWORD" ]; then
INTERNETBS_API_KEY=""
INTERNETBS_API_PASSWORD=""
_err "You didn't specify the INTERNET.BS api key and password yet."
_err "Please create you key and try again."
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
# https://testapi.internet.bs/Domain/DnsRecord/List?ApiKey=testapi&Password=testpass&Domain=test-api-domain7.net&FilterType=CNAME&ResponseFormat=json
_internetbs_rest POST "Domain/DnsRecord/List" "Domain=$_domain&FilterType=TXT&ResponseFormat=json"
if ! _contains "$response" "\"status\":\"SUCCESS\""; then
_err "ERROR list dns records"
_err "$response"
return 1
fi
if _contains "$response" "\name\":\"${_sub_domain}.${_domain}\""; then
_info "txt record find."
# https://testapi.internet.bs/Domain/DnsRecord/Remove?ApiKey=testapi&Password=testpass&FullRecordName=www.test-api-domain7.net&Type=cname&ResponseFormat=json
_internetbs_rest POST "Domain/DnsRecord/Remove" "FullRecordName=${_sub_domain}.${_domain}&Type=TXT&ResponseFormat=json"
if ! _contains "$response" "\"status\":\"SUCCESS\""; then
_err "ERROR remove dns record"
_err "$response"
return 1
fi
_info "txt record deleted success."
return 0
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
# https://testapi.internet.bs/Domain/List?ApiKey=testapi&Password=testpass&CompactList=yes&ResponseFormat=json
if _internetbs_rest POST "Domain/List" "CompactList=yes&ResponseFormat=json"; then
if ! _contains "$response" "\"status\":\"SUCCESS\""; then
_err "ERROR fetch domain list"
_err "$response"
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" "\"$h\""; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-${p})
_domain=${h}
return 0
fi
p=${i}
i=$(_math "$i" + 1)
done
fi
return 1
}
#Usage: method URI data
_internetbs_rest() {
m="$1"
ep="$2"
data="$3"
url="${INTERNETBS_API_URL}/${ep}"
_debug url "$url"
apiKey="$(printf "%s" "${INTERNETBS_API_KEY}" | _url_encode)"
password="$(printf "%s" "${INTERNETBS_API_PASSWORD}" | _url_encode)"
if [ "$m" = "GET" ]; then
response="$(_get "${url}?ApiKey=${apiKey}&Password=${password}&${data}" | tr -d '\r')"
else
_debug2 data "$data"
response="$(_post "$data" "${url}?ApiKey=${apiKey}&Password=${password}" | tr -d '\r')"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

356
dnsapi/dns_inwx.sh Executable file
View File

@@ -0,0 +1,356 @@
#!/usr/bin/env sh
#
#INWX_User="username"
#
#INWX_Password="password"
#
# Dependencies:
# -------------
# - oathtool (When using 2 Factor Authentication)
INWX_Api="https://api.domrobot.com/xmlrpc/"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_inwx_add() {
fulldomain=$1
txtvalue=$2
INWX_User="${INWX_User:-$(_readaccountconf_mutable INWX_User)}"
INWX_Password="${INWX_Password:-$(_readaccountconf_mutable INWX_Password)}"
INWX_Shared_Secret="${INWX_Shared_Secret:-$(_readaccountconf_mutable INWX_Shared_Secret)}"
if [ -z "$INWX_User" ] || [ -z "$INWX_Password" ]; then
INWX_User=""
INWX_Password=""
_err "You don't specify inwx user and password yet."
_err "Please create you key and try again."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf_mutable INWX_User "$INWX_User"
_saveaccountconf_mutable INWX_Password "$INWX_Password"
_saveaccountconf_mutable INWX_Shared_Secret "$INWX_Shared_Secret"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_info "Adding record"
_inwx_add_record "$_domain" "$_sub_domain" "$txtvalue"
}
#fulldomain txtvalue
dns_inwx_rm() {
fulldomain=$1
txtvalue=$2
INWX_User="${INWX_User:-$(_readaccountconf_mutable INWX_User)}"
INWX_Password="${INWX_Password:-$(_readaccountconf_mutable INWX_Password)}"
if [ -z "$INWX_User" ] || [ -z "$INWX_Password" ]; then
INWX_User=""
INWX_Password=""
_err "You don't specify inwx user and password yet."
_err "Please create you key and try again."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf_mutable INWX_User "$INWX_User"
_saveaccountconf_mutable INWX_Password "$INWX_Password"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>nameserver.info</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>domain</name>
<value>
<string>%s</string>
</value>
</member>
<member>
<name>type</name>
<value>
<string>TXT</string>
</value>
</member>
<member>
<name>name</name>
<value>
<string>%s</string>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>' "$_domain" "$_sub_domain")
response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
if ! _contains "$response" "Command completed successfully"; then
_err "Error could not get txt records"
return 1
fi
if ! printf "%s" "$response" | grep "count" >/dev/null; then
_info "Do not need to delete record"
else
_record_id=$(printf '%s' "$response" | _egrep_o '.*(<member><name>record){1}(.*)([0-9]+){1}' | _egrep_o '<name>id<\/name><value><int>[0-9]+' | _egrep_o '[0-9]+')
_info "Deleting record"
_inwx_delete_record "$_record_id"
fi
}
#################### Private functions below ##################################
_inwx_login() {
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>account.login</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>user</name>
<value>
<string>%s</string>
</value>
</member>
<member>
<name>pass</name>
<value>
<string>%s</string>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>' $INWX_User $INWX_Password)
response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
_H1=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')")
export _H1
#https://github.com/inwx/php-client/blob/master/INWX/Domrobot.php#L71
if _contains "$response" "<member><name>code</name><value><int>1000</int></value></member>" \
&& _contains "$response" "<member><name>tfa</name><value><string>GOOGLE-AUTH</string></value></member>"; then
if [ -z "$INWX_Shared_Secret" ]; then
_err "Mobile TAN detected."
_err "Please define a shared secret."
return 1
fi
if ! _exists oathtool; then
_err "Please install oathtool to use 2 Factor Authentication."
_err ""
return 1
fi
tan="$(oathtool --base32 --totp "${INWX_Shared_Secret}" 2>/dev/null)"
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>account.unlock</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>tan</name>
<value>
<string>%s</string>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>' "$tan")
response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
fi
}
_get_root() {
domain=$1
_debug "get root"
domain=$1
i=2
p=1
_inwx_login
xml_content='<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>nameserver.list</methodName>
</methodCall>'
response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
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" "$h"; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_inwx_delete_record() {
record_id=$1
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>nameserver.deleteRecord</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>id</name>
<value>
<int>%s</int>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>' "$record_id")
response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
if ! printf "%s" "$response" | grep "Command completed successfully" >/dev/null; then
_err "Error"
return 1
fi
return 0
}
_inwx_update_record() {
record_id=$1
txtval=$2
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>nameserver.updateRecord</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>content</name>
<value>
<string>%s</string>
</value>
</member>
<member>
<name>id</name>
<value>
<int>%s</int>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>' "$txtval" "$record_id")
response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
if ! printf "%s" "$response" | grep "Command completed successfully" >/dev/null; then
_err "Error"
return 1
fi
return 0
}
_inwx_add_record() {
domain=$1
sub_domain=$2
txtval=$3
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>nameserver.createRecord</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>domain</name>
<value>
<string>%s</string>
</value>
</member>
<member>
<name>type</name>
<value>
<string>TXT</string>
</value>
</member>
<member>
<name>content</name>
<value>
<string>%s</string>
</value>
</member>
<member>
<name>name</name>
<value>
<string>%s</string>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>' "$domain" "$txtval" "$sub_domain")
response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
if ! printf "%s" "$response" | grep "Command completed successfully" >/dev/null; then
_err "Error"
return 1
fi
return 0
}

View File

@@ -2,7 +2,6 @@
# 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
@@ -129,7 +128,7 @@ _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}}}"
curData="{\"session_id\":\"${sessionID}\",\"client_id\":\"${client_id}\",\"params\":{${params}},\"update_serial\":true}"
curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_add")"
_debug "Calling _ISPC_addTxt: '${curData}' '${ISPC_Api}?dns_txt_add'"
_debug "Result of _ISPC_addTxt: '$curResult'"
@@ -161,7 +160,7 @@ _ISPC_rmTxt() {
*)
unset IFS
_info "Retrieved Record ID."
curData="{\"session_id\":\"${sessionID}\",\"primary_id\":\"${record_id}\"}"
curData="{\"session_id\":\"${sessionID}\",\"primary_id\":\"${record_id}\",\"update_serial\":true}"
curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_delete")"
_debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_delete'"
_debug "Result of _ISPC_rmTxt: '$curResult'"

286
dnsapi/dns_jd.sh Normal file
View File

@@ -0,0 +1,286 @@
#!/usr/bin/env sh
#
#JD_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje"
#JD_ACCESS_KEY_SECRET="xxxxxxx"
#JD_REGION="cn-north-1"
_JD_ACCOUNT="https://uc.jdcloud.com/account/accesskey"
_JD_PROD="clouddnsservice"
_JD_API="jdcloud-api.com"
_JD_API_VERSION="v1"
_JD_DEFAULT_REGION="cn-north-1"
_JD_HOST="$_JD_PROD.$_JD_API"
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_jd_add() {
fulldomain=$1
txtvalue=$2
JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}"
JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}"
JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}"
if [ -z "$JD_ACCESS_KEY_ID" ] || [ -z "$JD_ACCESS_KEY_SECRET" ]; then
JD_ACCESS_KEY_ID=""
JD_ACCESS_KEY_SECRET=""
_err "You haven't specifed the jdcloud api key id or api key secret yet."
_err "Please create your key and try again. see $(__green $_JD_ACCOUNT)"
return 1
fi
_saveaccountconf_mutable JD_ACCESS_KEY_ID "$JD_ACCESS_KEY_ID"
_saveaccountconf_mutable JD_ACCESS_KEY_SECRET "$JD_ACCESS_KEY_SECRET"
if [ -z "$JD_REGION" ]; then
_debug "Using default region: $_JD_DEFAULT_REGION"
JD_REGION="$_JD_DEFAULT_REGION"
else
_saveaccountconf_mutable JD_REGION "$JD_REGION"
fi
_JD_BASE_URI="$_JD_API_VERSION/regions/$JD_REGION"
_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 getViewTree"
_debug "Adding records"
_addrr="{\"req\":{\"hostRecord\":\"$_sub_domain\",\"hostValue\":\"$txtvalue\",\"ttl\":300,\"type\":\"TXT\",\"viewValue\":-1},\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}"
#_addrr='{"req":{"hostRecord":"xx","hostValue":"\"value4\"","jcloudRes":false,"mxPriority":null,"port":null,"ttl":300,"type":"TXT","weight":null,"viewValue":-1},"regionId":"cn-north-1","domainId":"8824"}'
if jd_rest POST "domain/$_domain_id/RRAdd" "" "$_addrr"; then
_rid="$(echo "$response" | tr '{},' '\n' | grep '"id":' | cut -d : -f 2)"
if [ -z "$_rid" ]; then
_err "Can not find record id from the result."
return 1
fi
_info "TXT record added successfully."
_srid="$(_readdomainconf "JD_CLOUD_RIDS")"
if [ "$_srid" ]; then
_rid="$_srid,$_rid"
fi
_savedomainconf "JD_CLOUD_RIDS" "$_rid"
return 0
fi
return 1
}
dns_jd_rm() {
fulldomain=$1
txtvalue=$2
JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}"
JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}"
JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}"
if [ -z "$JD_REGION" ]; then
_debug "Using default region: $_JD_DEFAULT_REGION"
JD_REGION="$_JD_DEFAULT_REGION"
fi
_JD_BASE_URI="$_JD_API_VERSION/regions/$JD_REGION"
_info "Getting existing records for $fulldomain"
_srid="$(_readdomainconf "JD_CLOUD_RIDS")"
_debug _srid "$_srid"
if [ -z "$_srid" ]; then
_err "Not rid skip"
return 0
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"
_cleardomainconf JD_CLOUD_RIDS
_aws_tmpl_xml="{\"ids\":[$_srid],\"action\":\"del\",\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}"
if jd_rest POST "domain/$_domain_id/RROperate" "" "$_aws_tmpl_xml" && _contains "$response" "\"code\":\"OK\""; then
_info "TXT record deleted successfully."
return 0
fi
return 1
}
#################### Private functions below ##################################
_get_root() {
domain=$1
i=1
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug2 "Checking domain: $h"
if ! jd_rest GET "domain"; then
_err "error get domain list"
return 1
fi
if [ -z "$h" ]; then
#not valid
_err "Invalid domain"
return 1
fi
if _contains "$response" "\"domainName\":\"$h\""; then
hostedzone="$(echo "$response" | tr '{}' '\n' | grep "\"domainName\":\"$h\"")"
_debug hostedzone "$hostedzone"
if [ "$hostedzone" ]; then
_domain_id="$(echo "$hostedzone" | tr ',' '\n' | grep "\"id\":" | cut -d : -f 2)"
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
fi
_err "Can't find domain with id: $h"
return 1
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
#method uri qstr data
jd_rest() {
mtd="$1"
ep="$2"
qsr="$3"
data="$4"
_debug mtd "$mtd"
_debug ep "$ep"
_debug qsr "$qsr"
_debug data "$data"
CanonicalURI="/$_JD_BASE_URI/$ep"
_debug2 CanonicalURI "$CanonicalURI"
CanonicalQueryString="$qsr"
_debug2 CanonicalQueryString "$CanonicalQueryString"
RequestDate="$(date -u +"%Y%m%dT%H%M%SZ")"
#RequestDate="20190713T082155Z" ######################################################
_debug2 RequestDate "$RequestDate"
export _H1="X-Jdcloud-Date: $RequestDate"
RequestNonce="2bd0852a-8bae-4087-b2d5-$(_time)"
#RequestNonce="894baff5-72d4-4244-883a-7b2eb51e7fbe" #################################
_debug2 RequestNonce "$RequestNonce"
export _H2="X-Jdcloud-Nonce: $RequestNonce"
if [ "$data" ]; then
CanonicalHeaders="content-type:application/json\n"
SignedHeaders="content-type;"
else
CanonicalHeaders=""
SignedHeaders=""
fi
CanonicalHeaders="${CanonicalHeaders}host:$_JD_HOST\nx-jdcloud-date:$RequestDate\nx-jdcloud-nonce:$RequestNonce\n"
SignedHeaders="${SignedHeaders}host;x-jdcloud-date;x-jdcloud-nonce"
_debug2 CanonicalHeaders "$CanonicalHeaders"
_debug2 SignedHeaders "$SignedHeaders"
Hash="sha256"
RequestPayload="$data"
_debug2 RequestPayload "$RequestPayload"
RequestPayloadHash="$(printf "%s" "$RequestPayload" | _digest "$Hash" hex | _lower_case)"
_debug2 RequestPayloadHash "$RequestPayloadHash"
CanonicalRequest="$mtd\n$CanonicalURI\n$CanonicalQueryString\n$CanonicalHeaders\n$SignedHeaders\n$RequestPayloadHash"
_debug2 CanonicalRequest "$CanonicalRequest"
HashedCanonicalRequest="$(printf "$CanonicalRequest%s" | _digest "$Hash" hex)"
_debug2 HashedCanonicalRequest "$HashedCanonicalRequest"
Algorithm="JDCLOUD2-HMAC-SHA256"
_debug2 Algorithm "$Algorithm"
RequestDateOnly="$(echo "$RequestDate" | cut -c 1-8)"
_debug2 RequestDateOnly "$RequestDateOnly"
Region="$JD_REGION"
Service="$_JD_PROD"
CredentialScope="$RequestDateOnly/$Region/$Service/jdcloud2_request"
_debug2 CredentialScope "$CredentialScope"
StringToSign="$Algorithm\n$RequestDate\n$CredentialScope\n$HashedCanonicalRequest"
_debug2 StringToSign "$StringToSign"
kSecret="JDCLOUD2$JD_ACCESS_KEY_SECRET"
_secure_debug2 kSecret "$kSecret"
kSecretH="$(printf "%s" "$kSecret" | _hex_dump | tr -d " ")"
_secure_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 "%s" "jdcloud2_request" | _hmac "$Hash" "$kServiceH" hex)"
_debug2 kSigningH "$kSigningH"
signature="$(printf "$StringToSign%s" | _hmac "$Hash" "$kSigningH" hex)"
_debug2 signature "$signature"
Authorization="$Algorithm Credential=$JD_ACCESS_KEY_ID/$CredentialScope, SignedHeaders=$SignedHeaders, Signature=$signature"
_debug2 Authorization "$Authorization"
_H3="Authorization: $Authorization"
_debug _H3 "$_H3"
url="https://$_JD_HOST$CanonicalURI"
if [ "$qsr" ]; then
url="https://$_JD_HOST$CanonicalURI?$qsr"
fi
if [ "$mtd" = "GET" ]; then
response="$(_get "$url")"
else
response="$(_post "$data" "$url" "" "$mtd" "application/json")"
fi
_ret="$?"
_debug2 response "$response"
if [ "$_ret" = "0" ]; then
if _contains "$response" "\"error\""; then
_err "Response error:$response"
return 1
fi
fi
return "$_ret"
}

107
dnsapi/dns_kinghost.sh Normal file
View File

@@ -0,0 +1,107 @@
#!/usr/bin/env sh
############################################################
# KingHost API support #
# http://api.kinghost.net/doc/ #
# #
# Author: Felipe Keller Braz <felipebraz@kinghost.com.br> #
# Report Bugs here: https://github.com/kinghost/acme.sh #
# #
# Values to export: #
# export KINGHOST_Username="email@provider.com" #
# export KINGHOST_Password="xxxxxxxxxx" #
############################################################
KING_Api="https://api.kinghost.net/acme"
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Used to add txt record
dns_kinghost_add() {
fulldomain=$1
txtvalue=$2
KINGHOST_Username="${KINGHOST_Username:-$(_readaccountconf_mutable KINGHOST_Username)}"
KINGHOST_Password="${KINGHOST_Password:-$(_readaccountconf_mutable KINGHOST_Password)}"
if [ -z "$KINGHOST_Username" ] || [ -z "$KINGHOST_Password" ]; then
KINGHOST_Username=""
KINGHOST_Password=""
_err "You don't specify KingHost api password and email yet."
_err "Please create you key and try again."
return 1
fi
#save the credentials to the account conf file.
_saveaccountconf_mutable KINGHOST_Username "$KINGHOST_Username"
_saveaccountconf_mutable KINGHOST_Password "$KINGHOST_Password"
_debug "Getting txt records"
_kinghost_rest GET "dns" "name=$fulldomain&content=$txtvalue"
#This API call returns "status":"ok" if dns record does not exists
#We are creating a new txt record here, so we expect the "ok" status
if ! echo "$response" | grep '"status":"ok"' >/dev/null; then
_err "Error"
_err "$response"
return 1
fi
_kinghost_rest POST "dns" "name=$fulldomain&content=$txtvalue"
if ! echo "$response" | grep '"status":"ok"' >/dev/null; then
_err "Error"
_err "$response"
return 1
fi
return 0
}
# Usage: fulldomain txtvalue
# Used to remove the txt record after validation
dns_kinghost_rm() {
fulldomain=$1
txtvalue=$2
KINGHOST_Password="${KINGHOST_Password:-$(_readaccountconf_mutable KINGHOST_Password)}"
KINGHOST_Username="${KINGHOST_Username:-$(_readaccountconf_mutable KINGHOST_Username)}"
if [ -z "$KINGHOST_Password" ] || [ -z "$KINGHOST_Username" ]; then
KINGHOST_Password=""
KINGHOST_Username=""
_err "You don't specify KingHost api key and email yet."
_err "Please create you key and try again."
return 1
fi
_kinghost_rest DELETE "dns" "name=$fulldomain&content=$txtvalue"
if ! echo "$response" | grep '"status":"ok"' >/dev/null; then
_err "Error"
_err "$response"
return 1
fi
return 0
}
#################### Private functions below ##################################
_kinghost_rest() {
method=$1
uri="$2"
data="$3"
_debug "$uri"
export _H1="X-Auth-Email: $KINGHOST_Username"
export _H2="X-Auth-Key: $KINGHOST_Password"
if [ "$method" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$KING_Api/$uri.json" "" "$method")"
else
response="$(_get "$KING_Api/$uri.json?$data")"
fi
if [ "$?" != "0" ]; then
_err "error $uri"
return 1
fi
_debug2 response "$response"
return 0
}

95
dnsapi/dns_knot.sh Normal file
View File

@@ -0,0 +1,95 @@
#!/usr/bin/env sh
######## Public functions #####################
#Usage: dns_knot_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_knot_add() {
fulldomain=$1
txtvalue=$2
_checkKey || return 1
[ -n "${KNOT_SERVER}" ] || KNOT_SERVER="localhost"
# save the dns server and key to the account.conf file.
_saveaccountconf KNOT_SERVER "${KNOT_SERVER}"
_saveaccountconf KNOT_KEY "${KNOT_KEY}"
if ! _get_root "$fulldomain"; then
_err "Domain does not exist."
return 1
fi
_info "Adding ${fulldomain}. 60 TXT \"${txtvalue}\""
knsupdate -y "${KNOT_KEY}" <<EOF
server ${KNOT_SERVER}
zone ${_domain}.
update add ${fulldomain}. 60 TXT "${txtvalue}"
send
quit
EOF
if [ $? -ne 0 ]; then
_err "Error updating domain."
return 1
fi
_info "Domain TXT record successfully added."
return 0
}
#Usage: dns_knot_rm _acme-challenge.www.domain.com
dns_knot_rm() {
fulldomain=$1
_checkKey || return 1
[ -n "${KNOT_SERVER}" ] || KNOT_SERVER="localhost"
if ! _get_root "$fulldomain"; then
_err "Domain does not exist."
return 1
fi
_info "Removing ${fulldomain}. TXT"
knsupdate -y "${KNOT_KEY}" <<EOF
server ${KNOT_SERVER}
zone ${_domain}.
update del ${fulldomain}. TXT
send
quit
EOF
if [ $? -ne 0 ]; then
_err "error updating domain"
return 1
fi
_info "Domain TXT record successfully deleted."
return 0
}
#################### Private functions below ##################################
# _acme-challenge.www.domain.com
# returns
# _domain=domain.com
_get_root() {
domain=$1
i="$(echo "$fulldomain" | tr '.' ' ' | wc -w)"
i=$(_math "$i" - 1)
while true; do
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
if [ -z "$h" ]; then
return 1
fi
_domain="$h"
return 0
done
_debug "$domain not found"
return 1
}
_checkKey() {
if [ -z "${KNOT_KEY}" ]; then
_err "You must specify a TSIG key to authenticate the request."
return 1
fi
}

View File

@@ -7,20 +7,13 @@ lexicon_cmd="lexicon"
wiki="https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_lexicon_add() {
fulldomain=$1
txtvalue=$2
domain=$(printf "%s" "$fulldomain" | cut -d . -f 2-999)
_lexicon_init() {
if ! _exists "$lexicon_cmd"; then
_err "Please install $lexicon_cmd first: $wiki"
return 1
fi
PROVIDER="${PROVIDER:-$(_readdomainconf PROVIDER)}"
if [ -z "$PROVIDER" ]; then
PROVIDER=""
_err "Please define env PROVIDER first: $wiki"
@@ -33,46 +26,78 @@ dns_lexicon_add() {
# e.g. busybox-ash does not know [:upper:]
# shellcheck disable=SC2018,SC2019
Lx_name=$(echo LEXICON_"${PROVIDER}"_USERNAME | tr 'a-z' 'A-Z')
eval "$Lx_name=\${$Lx_name:-$(_readaccountconf_mutable "$Lx_name")}"
Lx_name_v=$(eval echo \$"$Lx_name")
_debug "$Lx_name" "$Lx_name_v"
_secure_debug "$Lx_name" "$Lx_name_v"
if [ "$Lx_name_v" ]; then
_saveaccountconf "$Lx_name" "$Lx_name_v"
_saveaccountconf_mutable "$Lx_name" "$Lx_name_v"
eval export "$Lx_name"
fi
# shellcheck disable=SC2018,SC2019
Lx_token=$(echo LEXICON_"${PROVIDER}"_TOKEN | tr 'a-z' 'A-Z')
eval "$Lx_token=\${$Lx_token:-$(_readaccountconf_mutable "$Lx_token")}"
Lx_token_v=$(eval echo \$"$Lx_token")
_debug "$Lx_token" "$Lx_token_v"
_secure_debug "$Lx_token" "$Lx_token_v"
if [ "$Lx_token_v" ]; then
_saveaccountconf "$Lx_token" "$Lx_token_v"
_saveaccountconf_mutable "$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')
eval "$Lx_password=\${$Lx_password:-$(_readaccountconf_mutable "$Lx_password")}"
Lx_password_v=$(eval echo \$"$Lx_password")
_debug "$Lx_password" "$Lx_password_v"
_secure_debug "$Lx_password" "$Lx_password_v"
if [ "$Lx_password_v" ]; then
_saveaccountconf "$Lx_password" "$Lx_password_v"
_saveaccountconf_mutable "$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')
eval "$Lx_domaintoken=\${$Lx_domaintoken:-$(_readaccountconf_mutable "$Lx_domaintoken")}"
Lx_domaintoken_v=$(eval echo \$"$Lx_domaintoken")
_debug "$Lx_domaintoken" "$Lx_domaintoken_v"
_secure_debug "$Lx_domaintoken" "$Lx_domaintoken_v"
if [ "$Lx_domaintoken_v" ]; then
_saveaccountconf_mutable "$Lx_domaintoken" "$Lx_domaintoken_v"
eval export "$Lx_domaintoken"
_saveaccountconf "$Lx_domaintoken" "$Lx_domaintoken_v"
fi
}
######## Public functions #####################
#Usage: dns_lexicon_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_lexicon_add() {
fulldomain=$1
txtvalue=$2
if ! _lexicon_init; then
return 1
fi
$lexicon_cmd "$PROVIDER" create "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}"
domain=$(printf "%s" "$fulldomain" | cut -d . -f 2-999)
_secure_debug LEXICON_OPTS "$LEXICON_OPTS"
_savedomainconf LEXICON_OPTS "$LEXICON_OPTS"
# shellcheck disable=SC2086
$lexicon_cmd "$PROVIDER" $LEXICON_OPTS create "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}"
}
#fulldomain
#Usage: dns_lexicon_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_lexicon_rm() {
fulldomain=$1
txtvalue=$2
if ! _lexicon_init; then
return 1
fi
domain=$(printf "%s" "$fulldomain" | cut -d . -f 2-999)
# shellcheck disable=SC2086
$lexicon_cmd "$PROVIDER" $LEXICON_OPTS delete "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}"
}

View File

@@ -68,7 +68,7 @@ dns_linode_rm() {
_parameters="&DomainID=$_domain_id"
if _rest GET "domain.resource.list" "$_parameters" && [ -n "$response" ]; then
response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')"
response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")"
resource="$(echo "$response" | _egrep_o "{.*\"NAME\":\s*\"$_sub_domain\".*}")"
if [ "$resource" ]; then
@@ -128,7 +128,7 @@ _get_root() {
p=1
if _rest GET "domain.list"; then
response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')"
response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"

185
dnsapi/dns_linode_v4.sh Executable file
View File

@@ -0,0 +1,185 @@
#!/usr/bin/env sh
#Original Author: Philipp Grosswiler <philipp.grosswiler@swiss-design.net>
#v4 Update Author: Aaron W. Swenson <aaron@grandmasfridge.org>
LINODE_V4_API_URL="https://api.linode.com/v4/domains"
######## Public functions #####################
#Usage: dns_linode_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_linode_v4_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"
_payload="{
\"type\": \"TXT\",
\"name\": \"$_sub_domain\",
\"target\": \"$txtvalue\"
}"
if _rest POST "/$_domain_id/records" "$_payload" && [ -n "$response" ]; then
_resource_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\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_v4_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"
if _rest GET "/$_domain_id/records" && [ -n "$response" ]; then
response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")"
resource="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$_sub_domain\".*}")"
if [ "$resource" ]; then
_resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
if [ "$_resource_id" ]; then
_debug _resource_id "$_resource_id"
if _rest DELETE "/$_domain_id/records/$_resource_id" && [ -n "$response" ]; then
# On 200/OK, empty set is returned. Check for error, if any.
_error_response=$(printf "%s\n" "$response" | _egrep_o "\"errors\"" | cut -d : -f 2 | tr -d " " | _head_n 1)
if [ -n "$_error_response" ]; then
_err "Error deleting the domain resource: $_error_response"
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_V4_API_KEY" ]; then
LINODE_V4_API_KEY=""
_err "You didn't specify the Linode v4 API key yet."
_err "Please create your key and try again."
return 1
fi
_saveaccountconf LINODE_V4_API_KEY "$LINODE_V4_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; then
response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")"
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 "\"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 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"
export _H3="Authorization: Bearer $LINODE_V4_API_KEY"
if [ "$mtd" != "GET" ]; then
# both POST and DELETE.
_debug data "$data"
response="$(_post "$data" "$LINODE_V4_API_URL$ep" "" "$mtd")"
else
response="$(_get "$LINODE_V4_API_URL$ep$data")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

302
dnsapi/dns_loopia.sh Normal file
View File

@@ -0,0 +1,302 @@
#!/usr/bin/env sh
#
#LOOPIA_User="username"
#
#LOOPIA_Password="password"
#
#LOOPIA_Api="https://api.loopia.<TLD>/RPCSERV"
LOOPIA_Api_Default="https://api.loopia.se/RPCSERV"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_loopia_add() {
fulldomain=$1
txtvalue=$2
if ! _loopia_load_config; then
return 1
fi
_loopia_save_config
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_info "Adding record"
_loopia_add_sub_domain "$_domain" "$_sub_domain"
_loopia_add_record "$_domain" "$_sub_domain" "$txtvalue"
}
dns_loopia_rm() {
fulldomain=$1
txtvalue=$2
if ! _loopia_load_config; then
return 1
fi
_loopia_save_config
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>removeSubdomain</methodName>
<params>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
</params>
</methodCall>' "$LOOPIA_User" "$LOOPIA_Password" "$_domain" "$_sub_domain")
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
if ! _contains "$response" "OK"; then
_err "Error could not get txt records"
return 1
fi
}
#################### Private functions below ##################################
_loopia_load_config() {
LOOPIA_Api="${LOOPIA_Api:-$(_readaccountconf_mutable LOOPIA_Api)}"
LOOPIA_User="${LOOPIA_User:-$(_readaccountconf_mutable LOOPIA_User)}"
LOOPIA_Password="${LOOPIA_Password:-$(_readaccountconf_mutable LOOPIA_Password)}"
if [ -z "$LOOPIA_Api" ]; then
LOOPIA_Api="$LOOPIA_Api_Default"
fi
if [ -z "$LOOPIA_User" ] || [ -z "$LOOPIA_Password" ]; then
LOOPIA_User=""
LOOPIA_Password=""
_err "A valid Loopia API user and password not provided."
_err "Please provide a valid API user and try again."
return 1
fi
return 0
}
_loopia_save_config() {
if [ "$LOOPIA_Api" != "$LOOPIA_Api_Default" ]; then
_saveaccountconf_mutable LOOPIA_Api "$LOOPIA_Api"
fi
_saveaccountconf_mutable LOOPIA_User "$LOOPIA_User"
_saveaccountconf_mutable LOOPIA_Password "$LOOPIA_Password"
}
_loopia_get_records() {
domain=$1
sub_domain=$2
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>getZoneRecords</methodName>
<params>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
</params>
</methodCall>' $LOOPIA_User $LOOPIA_Password "$domain" "$sub_domain")
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
if ! _contains "$response" "<array>"; then
_err "Error"
return 1
fi
return 0
}
_get_root() {
domain=$1
_debug "get root"
domain=$1
i=2
p=1
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>getDomains</methodName>
<params>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
</params>
</methodCall>' $LOOPIA_User $LOOPIA_Password)
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
while true; do
h=$(echo "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1
fi
if _contains "$response" "$h"; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_loopia_add_record() {
domain=$1
sub_domain=$2
txtval=$3
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>addZoneRecord</methodName>
<params>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
<param>
<struct>
<member>
<name>type</name>
<value><string>TXT</string></value>
</member>
<member>
<name>priority</name>
<value><int>0</int></value>
</member>
<member>
<name>ttl</name>
<value><int>60</int></value>
</member>
<member>
<name>rdata</name>
<value><string>%s</string></value>
</member>
</struct>
</param>
</params>
</methodCall>' $LOOPIA_User $LOOPIA_Password "$domain" "$sub_domain" "$txtval")
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
if ! _contains "$response" "OK"; then
_err "Error"
return 1
fi
return 0
}
_sub_domain_exists() {
domain=$1
sub_domain=$2
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>getSubdomains</methodName>
<params>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
</params>
</methodCall>' $LOOPIA_User $LOOPIA_Password "$domain")
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
if _contains "$response" "$sub_domain"; then
return 0
fi
return 1
}
_loopia_add_sub_domain() {
domain=$1
sub_domain=$2
if _sub_domain_exists "$domain" "$sub_domain"; then
return 0
fi
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>addSubdomain</methodName>
<params>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
<param>
<value><string>%s</string></value>
</param>
</params>
</methodCall>' $LOOPIA_User $LOOPIA_Password "$domain" "$sub_domain")
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
if ! _contains "$response" "OK"; then
_err "Error"
return 1
fi
return 0
}

View File

@@ -8,7 +8,6 @@
#LUA_Email="user@luadns.net"
LUA_Api="https://api.luadns.com/v1"
LUA_auth=$(printf "%s" "$LUA_Email:$LUA_Key" | _base64)
######## Public functions #####################
@@ -17,6 +16,10 @@ dns_lua_add() {
fulldomain=$1
txtvalue=$2
LUA_Key="${LUA_Key:-$(_readaccountconf_mutable LUA_Key)}"
LUA_Email="${LUA_Email:-$(_readaccountconf_mutable LUA_Email)}"
LUA_auth=$(printf "%s" "$LUA_Email:$LUA_Key" | _base64)
if [ -z "$LUA_Key" ] || [ -z "$LUA_Email" ]; then
LUA_Key=""
LUA_Email=""
@@ -26,8 +29,8 @@ dns_lua_add() {
fi
#save the api key and email to the account conf file.
_saveaccountconf LUA_Key "$LUA_Key"
_saveaccountconf LUA_Email "$LUA_Email"
_saveaccountconf_mutable LUA_Key "$LUA_Key"
_saveaccountconf_mutable LUA_Email "$LUA_Email"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
@@ -38,50 +41,56 @@ dns_lua_add() {
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_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
}
#fulldomain
dns_lua_rm() {
fulldomain=$1
txtvalue=$2
LUA_Key="${LUA_Key:-$(_readaccountconf_mutable LUA_Key)}"
LUA_Email="${LUA_Email:-$(_readaccountconf_mutable LUA_Email)}"
LUA_auth=$(printf "%s" "$LUA_Email:$LUA_Key" | _base64)
_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."
_info "Don't need to remove."
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
if [ -z "$record_id" ]; then
_err "Can not get record id to remove."
return 1
fi
_err "Update error"
return 1
if ! _LUA_rest DELETE "/zones/$_domain_id/records/$record_id"; then
_err "Delete record error."
return 1
fi
_contains "$response" "$record_id"
fi
}
#fulldomain
dns_lua_rm() {
fulldomain=$1
}
#################### Private functions below ##################################
@@ -129,7 +138,7 @@ _LUA_rest() {
export _H1="Accept: application/json"
export _H2="Authorization: Basic $LUA_auth"
if [ "$data" ]; then
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$LUA_Api/$ep" "" "$m")"
else

69
dnsapi/dns_maradns.sh Executable file
View File

@@ -0,0 +1,69 @@
#!/usr/bin/env sh
#Usage: dns_maradns_add _acme-challenge.www.domain.com "token"
dns_maradns_add() {
fulldomain="$1"
txtvalue="$2"
MARA_ZONE_FILE="${MARA_ZONE_FILE:-$(_readaccountconf_mutable MARA_ZONE_FILE)}"
MARA_DUENDE_PID_PATH="${MARA_DUENDE_PID_PATH:-$(_readaccountconf_mutable MARA_DUENDE_PID_PATH)}"
_check_zone_file "$MARA_ZONE_FILE" || return 1
_check_duende_pid_path "$MARA_DUENDE_PID_PATH" || return 1
_saveaccountconf_mutable MARA_ZONE_FILE "$MARA_ZONE_FILE"
_saveaccountconf_mutable MARA_DUENDE_PID_PATH "$MARA_DUENDE_PID_PATH"
printf "%s. TXT '%s' ~\n" "$fulldomain" "$txtvalue" >>"$MARA_ZONE_FILE"
_reload_maradns "$MARA_DUENDE_PID_PATH" || return 1
}
#Usage: dns_maradns_rm _acme-challenge.www.domain.com "token"
dns_maradns_rm() {
fulldomain="$1"
txtvalue="$2"
MARA_ZONE_FILE="${MARA_ZONE_FILE:-$(_readaccountconf_mutable MARA_ZONE_FILE)}"
MARA_DUENDE_PID_PATH="${MARA_DUENDE_PID_PATH:-$(_readaccountconf_mutable MARA_DUENDE_PID_PATH)}"
_check_zone_file "$MARA_ZONE_FILE" || return 1
_check_duende_pid_path "$MARA_DUENDE_PID_PATH" || return 1
_saveaccountconf_mutable MARA_ZONE_FILE "$MARA_ZONE_FILE"
_saveaccountconf_mutable MARA_DUENDE_PID_PATH "$MARA_DUENDE_PID_PATH"
_sed_i "/^$fulldomain.\+TXT '$txtvalue' ~/d" "$MARA_ZONE_FILE"
_reload_maradns "$MARA_DUENDE_PID_PATH" || return 1
}
_check_zone_file() {
zonefile="$1"
if [ -z "$zonefile" ]; then
_err "MARA_ZONE_FILE not passed!"
return 1
elif [ ! -w "$zonefile" ]; then
_err "MARA_ZONE_FILE not writable: $zonefile"
return 1
fi
}
_check_duende_pid_path() {
pidpath="$1"
if [ -z "$pidpath" ]; then
_err "MARA_DUENDE_PID_PATH not passed!"
return 1
fi
if [ ! -r "$pidpath" ]; then
_err "MARA_DUENDE_PID_PATH not readable: $pidpath"
return 1
fi
}
_reload_maradns() {
pidpath="$1"
kill -s HUP -- "$(cat "$pidpath")"
if [ $? -ne 0 ]; then
_err "Unable to reload MaraDNS, kill returned $?"
return 1
fi
}

65
dnsapi/dns_me.sh Executable file → Normal file
View File

@@ -43,34 +43,16 @@ dns_me_add() {
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"
_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
_err "Update error"
return 1
fi
}
@@ -78,7 +60,36 @@ dns_me_add() {
#fulldomain
dns_me_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"
_me_rest GET "${_domain_id}/records?recordName=$_sub_domain&type=TXT"
count=$(printf "%s\n" "$response" | _egrep_o "\"totalRecords\":[^,]*" | 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 ",\"value\":\"..$txtvalue..\",\"id\":[^,]*" | cut -d : -f 3 | 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 ! _me_rest DELETE "$_domain_id/records/$record_id"; then
_err "Delete record error."
return 1
fi
_contains "$response" ''
fi
}
#################### Private functions below ##################################
@@ -123,14 +134,14 @@ _me_rest() {
data="$3"
_debug "$ep"
cdate=$(date -u +"%a, %d %b %Y %T %Z")
cdate=$(LANG=C 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
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$ME_Api/$ep" "" "$m")"
else

View File

@@ -11,6 +11,8 @@
#
######## Public functions #####################
# Please Read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_myapi_add() {
fulldomain=$1

97
dnsapi/dns_mydevil.sh Executable file
View File

@@ -0,0 +1,97 @@
#!/usr/bin/env sh
# MyDevil.net API (2019-02-03)
#
# MyDevil.net already supports automatic Let's Encrypt certificates,
# except for wildcard domains.
#
# This script depends on `devil` command that MyDevil.net provides,
# which means that it works only on server side.
#
# Author: Marcin Konicki <https://ahwayakchih.neoni.net>
#
######## Public functions #####################
#Usage: dns_mydevil_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_mydevil_add() {
fulldomain=$1
txtvalue=$2
domain=""
if ! _exists "devil"; then
_err "Could not find 'devil' command."
return 1
fi
_info "Using mydevil"
domain=$(mydevil_get_domain "$fulldomain")
if [ -z "$domain" ]; then
_err "Invalid domain name: could not find root domain of $fulldomain."
return 1
fi
# No need to check if record name exists, `devil` always adds new record.
# In worst case scenario, we end up with multiple identical records.
_info "Adding $fulldomain record for domain $domain"
if devil dns add "$domain" "$fulldomain" TXT "$txtvalue"; then
_info "Successfully added TXT record, ready for validation."
return 0
else
_err "Unable to add DNS record."
return 1
fi
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_mydevil_rm() {
fulldomain=$1
txtvalue=$2
domain=""
if ! _exists "devil"; then
_err "Could not find 'devil' command."
return 1
fi
_info "Using mydevil"
domain=$(mydevil_get_domain "$fulldomain")
if [ -z "$domain" ]; then
_err "Invalid domain name: could not find root domain of $fulldomain."
return 1
fi
# catch one or more numbers
num='[0-9][0-9]*'
# catch one or more whitespace
w=$(printf '[\t ][\t ]*')
# catch anything, except newline
any='.*'
# filter to make sure we do not delete other records
validRecords="^${num}${w}${fulldomain}${w}TXT${w}${any}${txtvalue}$"
for id in $(devil dns list "$domain" | tail -n+2 | grep "${validRecords}" | cut -w -s -f 1); do
_info "Removing record $id from domain $domain"
devil dns del "$domain" "$id" || _err "Could not remove DNS record."
done
}
#################### Private functions below ##################################
# Usage: domain=$(mydevil_get_domain "_acme-challenge.www.domain.com" || _err "Invalid domain name")
# echo $domain
mydevil_get_domain() {
fulldomain=$1
domain=""
for domain in $(devil dns list | cut -w -s -f 1 | tail -n+2); do
if _endswith "$fulldomain" "$domain"; then
printf -- "%s" "$domain"
return 0
fi
done
return 1
}

210
dnsapi/dns_mydnsjp.sh Executable file
View File

@@ -0,0 +1,210 @@
#!/usr/bin/env sh
#Here is a api script for MyDNS.JP.
#This file name is "dns_mydnsjp.sh"
#So, here must be a method dns_mydnsjp_add()
#Which will be called by acme.sh to add the txt record to your api system.
#returns 0 means success, otherwise error.
#
#Author: epgdatacapbon
#Report Bugs here: https://github.com/epgdatacapbon/acme.sh
#
######## Public functions #####################
# Export MyDNS.JP MasterID and Password in following variables...
# MYDNSJP_MasterID=MasterID
# MYDNSJP_Password=Password
MYDNSJP_API="https://www.mydns.jp"
#Usage: dns_mydnsjp_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_mydnsjp_add() {
fulldomain=$1
txtvalue=$2
_info "Using mydnsjp"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
# Load the credentials from the account conf file
MYDNSJP_MasterID="${MYDNSJP_MasterID:-$(_readaccountconf_mutable MYDNSJP_MasterID)}"
MYDNSJP_Password="${MYDNSJP_Password:-$(_readaccountconf_mutable MYDNSJP_Password)}"
if [ -z "$MYDNSJP_MasterID" ] || [ -z "$MYDNSJP_Password" ]; then
MYDNSJP_MasterID=""
MYDNSJP_Password=""
_err "You don't specify mydnsjp api MasterID and Password yet."
_err "Please export as MYDNSJP_MasterID / MYDNSJP_Password and try again."
return 1
fi
# Save the credentials to the account conf file
_saveaccountconf_mutable MYDNSJP_MasterID "$MYDNSJP_MasterID"
_saveaccountconf_mutable MYDNSJP_Password "$MYDNSJP_Password"
_debug "First detect the root zone."
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
if _mydnsjp_api "REGIST" "$_domain" "$txtvalue"; then
if printf -- "%s" "$response" | grep "OK." >/dev/null; then
_info "Added, OK"
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
return 1
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_mydnsjp_rm() {
fulldomain=$1
txtvalue=$2
_info "Removing TXT record"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
# Load the credentials from the account conf file
MYDNSJP_MasterID="${MYDNSJP_MasterID:-$(_readaccountconf_mutable MYDNSJP_MasterID)}"
MYDNSJP_Password="${MYDNSJP_Password:-$(_readaccountconf_mutable MYDNSJP_Password)}"
if [ -z "$MYDNSJP_MasterID" ] || [ -z "$MYDNSJP_Password" ]; then
MYDNSJP_MasterID=""
MYDNSJP_Password=""
_err "You don't specify mydnsjp api MasterID and Password yet."
_err "Please export as MYDNSJP_MasterID / MYDNSJP_Password and try again."
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
if _mydnsjp_api "DELETE" "$_domain" "$txtvalue"; then
if printf -- "%s" "$response" | grep "OK." >/dev/null; then
_info "Deleted, OK"
return 0
else
_err "Delete txt record error."
return 1
fi
fi
_err "Delete txt record error."
return 1
}
#################### Private functions below ##################################
# _acme-challenge.www.domain.com
# returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
fulldomain=$1
i=2
p=1
# Get the root domain
_mydnsjp_retrieve_domain
if [ "$?" != "0" ]; then
# not valid
return 1
fi
while true; do
_domain=$(printf "%s" "$fulldomain" | cut -d . -f $i-100)
if [ -z "$_domain" ]; then
# not valid
return 1
fi
if [ "$_domain" = "$_root_domain" ]; then
_sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-$p)
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
# Retrieve the root domain
# returns 0 success
_mydnsjp_retrieve_domain() {
_debug "Login to MyDNS.JP"
response="$(_post "masterid=$MYDNSJP_MasterID&masterpwd=$MYDNSJP_Password" "$MYDNSJP_API/?MENU=100")"
cookie="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2)"
# If cookies is not empty then logon successful
if [ -z "$cookie" ]; then
_err "Fail to get a cookie."
return 1
fi
_debug "Retrieve DOMAIN INFO page"
export _H1="Cookie:${cookie}"
response="$(_get "$MYDNSJP_API/?MENU=300")"
if [ "$?" != "0" ]; then
_err "Fail to retrieve DOMAIN INFO."
return 1
fi
_root_domain=$(echo "$response" | grep "DNSINFO\[domainname\]" | sed 's/^.*value="\([^"]*\)".*/\1/')
# Logout
response="$(_get "$MYDNSJP_API/?MENU=090")"
_debug _root_domain "$_root_domain"
if [ -z "$_root_domain" ]; then
_err "Fail to get the root domain."
return 1
fi
return 0
}
_mydnsjp_api() {
cmd=$1
domain=$2
txtvalue=$3
# Base64 encode the credentials
credentials=$(printf "%s:%s" "$MYDNSJP_MasterID" "$MYDNSJP_Password" | _base64)
# Construct the HTTP Authorization header
export _H1="Content-Type: application/x-www-form-urlencoded"
export _H2="Authorization: Basic ${credentials}"
response="$(_post "CERTBOT_DOMAIN=$domain&CERTBOT_VALIDATION=$txtvalue&EDIT_CMD=$cmd" "$MYDNSJP_API/directedit.html")"
if [ "$?" != "0" ]; then
_err "error $domain"
return 1
fi
_debug2 response "$response"
return 0
}

407
dnsapi/dns_namecheap.sh Executable file
View File

@@ -0,0 +1,407 @@
#!/usr/bin/env sh
# Namecheap API
# https://www.namecheap.com/support/api/intro.aspx
#
# Requires Namecheap API key set in
#NAMECHEAP_API_KEY,
#NAMECHEAP_USERNAME,
#NAMECHEAP_SOURCEIP
# Due to Namecheap's API limitation all the records of your domain will be read and re applied, make sure to have a backup of your records you could apply if any issue would arise.
######## Public functions #####################
NAMECHEAP_API="https://api.namecheap.com/xml.response"
#Usage: dns_namecheap_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_namecheap_add() {
fulldomain=$1
txtvalue=$2
if ! _namecheap_check_config; then
_err "$error"
return 1
fi
if ! _namecheap_set_publicip; then
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_debug domain "$_domain"
_debug sub_domain "$_sub_domain"
_set_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue"
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_namecheap_rm() {
fulldomain=$1
txtvalue=$2
if ! _namecheap_set_publicip; then
return 1
fi
if ! _namecheap_check_config; then
_err "$error"
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_debug domain "$_domain"
_debug sub_domain "$_sub_domain"
_del_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue"
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
fulldomain=$1
if ! _get_root_by_getList "$fulldomain"; then
_debug "Failed domain lookup via domains.getList api call. Trying domain lookup via domains.dns.getHosts api."
# The above "getList" api will only return hosts *owned* by the calling user. However, if the calling
# user is not the owner, but still has administrative rights, we must query the getHosts api directly.
# See this comment and the official namecheap response: http://disq.us/p/1q6v9x9
if ! _get_root_by_getHosts "$fulldomain"; then
return 1
fi
fi
return 0
}
_get_root_by_getList() {
domain=$1
if ! _namecheap_post "namecheap.domains.getList"; then
_err "$error"
return 1
fi
i=2
p=1
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 "$h" "\\."; then
#not valid
return 1
fi
if ! _contains "$response" "$h"; then
_debug "$h not found"
else
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
return 0
fi
p="$i"
i=$(_math "$i" + 1)
done
return 1
}
_get_root_by_getHosts() {
i=100
p=99
while [ $p -ne 0 ]; do
h=$(printf "%s" "$1" | cut -d . -f $i-100)
if [ -n "$h" ]; then
if _contains "$h" "\\."; then
_debug h "$h"
if _namecheap_set_tld_sld "$h"; then
_sub_domain=$(printf "%s" "$1" | cut -d . -f 1-$p)
_domain="$h"
return 0
else
_debug "$h not found"
fi
fi
fi
i="$p"
p=$(_math "$p" - 1)
done
return 1
}
_namecheap_set_publicip() {
if [ -z "$NAMECHEAP_SOURCEIP" ]; then
_err "No Source IP specified for Namecheap API."
_err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
return 1
else
_saveaccountconf NAMECHEAP_SOURCEIP "$NAMECHEAP_SOURCEIP"
_debug sourceip "$NAMECHEAP_SOURCEIP"
ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https):\/\/.*')
_debug2 ip "$ip"
_debug2 addr "$addr"
if [ -n "$ip" ]; then
_publicip="$ip"
elif [ -n "$addr" ]; then
_publicip=$(_get "$addr")
else
_err "No Source IP specified for Namecheap API."
_err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
return 1
fi
fi
_debug publicip "$_publicip"
return 0
}
_namecheap_post() {
command=$1
data="ApiUser=${NAMECHEAP_USERNAME}&ApiKey=${NAMECHEAP_API_KEY}&ClientIp=${_publicip}&UserName=${NAMECHEAP_USERNAME}&Command=${command}"
_debug2 "_namecheap_post data" "$data"
response="$(_post "$data" "$NAMECHEAP_API" "" "POST")"
_debug2 response "$response"
if _contains "$response" "Status=\"ERROR\"" >/dev/null; then
error=$(echo "$response" | _egrep_o ">.*<\\/Error>" | cut -d '<' -f 1 | tr -d '>')
_err "error $error"
return 1
fi
return 0
}
_namecheap_parse_host() {
_host=$1
_debug _host "$_host"
_hostid=$(echo "$_host" | _egrep_o ' HostId="[^"]*' | cut -d '"' -f 2)
_hostname=$(echo "$_host" | _egrep_o ' Name="[^"]*' | cut -d '"' -f 2)
_hosttype=$(echo "$_host" | _egrep_o ' Type="[^"]*' | cut -d '"' -f 2)
_hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2)
_hostmxpref=$(echo "$_host" | _egrep_o ' MXPref="[^"]*' | cut -d '"' -f 2)
_hostttl=$(echo "$_host" | _egrep_o ' TTL="[^"]*' | cut -d '"' -f 2)
_debug hostid "$_hostid"
_debug hostname "$_hostname"
_debug hosttype "$_hosttype"
_debug hostaddress "$_hostaddress"
_debug hostmxpref "$_hostmxpref"
_debug hostttl "$_hostttl"
}
_namecheap_check_config() {
if [ -z "$NAMECHEAP_API_KEY" ]; then
_err "No API key specified for Namecheap API."
_err "Create your key and export it as NAMECHEAP_API_KEY"
return 1
fi
if [ -z "$NAMECHEAP_USERNAME" ]; then
_err "No username key specified for Namecheap API."
_err "Create your key and export it as NAMECHEAP_USERNAME"
return 1
fi
_saveaccountconf NAMECHEAP_API_KEY "$NAMECHEAP_API_KEY"
_saveaccountconf NAMECHEAP_USERNAME "$NAMECHEAP_USERNAME"
return 0
}
_set_namecheap_TXT() {
subdomain=$2
txt=$3
if ! _namecheap_set_tld_sld "$1"; then
return 1
fi
request="namecheap.domains.dns.getHosts&SLD=${_sld}&TLD=${_tld}"
if ! _namecheap_post "$request"; then
_err "$error"
return 1
fi
hosts=$(echo "$response" | _egrep_o '<host[^>]*')
_debug hosts "$hosts"
if [ -z "$hosts" ]; then
_error "Hosts not found"
return 1
fi
_namecheap_reset_hostList
while read -r host; do
if _contains "$host" "<host"; then
_namecheap_parse_host "$host"
_debug2 _hostname "_hostname"
_debug2 _hosttype "_hosttype"
_debug2 _hostaddress "_hostaddress"
_debug2 _hostmxpref "_hostmxpref"
_hostaddress="$(printf "%s" "$_hostaddress" | _url_encode)"
_debug2 "encoded _hostaddress" "_hostaddress"
_namecheap_add_host "$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl"
fi
done <<EOT
echo "$hosts"
EOT
_namecheap_add_host "$subdomain" "TXT" "$txt" 10 120
_debug hostrequestfinal "$_hostrequest"
request="namecheap.domains.dns.setHosts&SLD=${_sld}&TLD=${_tld}${_hostrequest}"
if ! _namecheap_post "$request"; then
_err "$error"
return 1
fi
return 0
}
_del_namecheap_TXT() {
subdomain=$2
txt=$3
if ! _namecheap_set_tld_sld "$1"; then
return 1
fi
request="namecheap.domains.dns.getHosts&SLD=${_sld}&TLD=${_tld}"
if ! _namecheap_post "$request"; then
_err "$error"
return 1
fi
hosts=$(echo "$response" | _egrep_o '<host[^>]*')
_debug hosts "$hosts"
if [ -z "$hosts" ]; then
_error "Hosts not found"
return 1
fi
_namecheap_reset_hostList
found=0
while read -r host; do
if _contains "$host" "<host"; then
_namecheap_parse_host "$host"
if [ "$_hosttype" = "TXT" ] && [ "$_hostname" = "$subdomain" ] && [ "$_hostaddress" = "$txt" ]; then
_debug "TXT entry found"
found=1
else
_hostaddress="$(printf "%s" "$_hostaddress" | _url_encode)"
_namecheap_add_host "$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl"
fi
fi
done <<EOT
echo "$hosts"
EOT
if [ $found -eq 0 ]; then
_debug "TXT entry not found"
return 0
fi
_debug hostrequestfinal "$_hostrequest"
request="namecheap.domains.dns.setHosts&SLD=${_sld}&TLD=${_tld}${_hostrequest}"
if ! _namecheap_post "$request"; then
_err "$error"
return 1
fi
return 0
}
_namecheap_reset_hostList() {
_hostindex=0
_hostrequest=""
}
#Usage: _namecheap_add_host HostName RecordType Address MxPref TTL
_namecheap_add_host() {
_hostindex=$(_math "$_hostindex" + 1)
_hostrequest=$(printf '%s&HostName%d=%s&RecordType%d=%s&Address%d=%s&MXPref%d=%d&TTL%d=%d' "$_hostrequest" "$_hostindex" "$1" "$_hostindex" "$2" "$_hostindex" "$3" "$_hostindex" "$4" "$_hostindex" "$5")
}
_namecheap_set_tld_sld() {
domain=$1
_tld=""
_sld=""
i=2
while true; do
_tld=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug tld "$_tld"
if [ -z "$_tld" ]; then
_debug "invalid tld"
return 1
fi
j=$(_math "$i" - 1)
_sld=$(printf "%s" "$domain" | cut -d . -f 1-"$j")
_debug sld "$_sld"
if [ -z "$_sld" ]; then
_debug "invalid sld"
return 1
fi
request="namecheap.domains.dns.getHosts&SLD=$_sld&TLD=$_tld"
if ! _namecheap_post "$request"; then
_debug "sld($_sld)/tld($_tld) not found"
else
_debug "sld($_sld)/tld($_tld) found"
return 0
fi
i=$(_math "$i" + 1)
done
}

173
dnsapi/dns_namecom.sh Executable file
View File

@@ -0,0 +1,173 @@
#!/usr/bin/env sh
#Author: RaidenII
#Created 06/28/2017
#Updated 03/01/2018, rewrote to support name.com API v4
#Utilize name.com API to finish dns-01 verifications.
######## Public functions #####################
Namecom_API="https://api.name.com/v4"
#Usage: dns_namecom_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_namecom_add() {
fulldomain=$1
txtvalue=$2
Namecom_Username="${Namecom_Username:-$(_readaccountconf_mutable Namecom_Username)}"
Namecom_Token="${Namecom_Token:-$(_readaccountconf_mutable Namecom_Token)}"
# First we need name.com credentials.
if [ -z "$Namecom_Username" ]; then
Namecom_Username=""
_err "Username for name.com is missing."
_err "Please specify that in your environment variable."
return 1
fi
if [ -z "$Namecom_Token" ]; then
Namecom_Token=""
_err "API token for name.com is missing."
_err "Please specify that in your environment variable."
return 1
fi
_debug Namecom_Username "$Namecom_Username"
_secure_debug Namecom_Token "$Namecom_Token"
# Save them in configuration.
_saveaccountconf_mutable Namecom_Username "$Namecom_Username"
_saveaccountconf_mutable Namecom_Token "$Namecom_Token"
# Login in using API
if ! _namecom_login; then
return 1
fi
# Find domain in domain list.
if ! _namecom_get_root "$fulldomain"; then
_err "Unable to find domain specified."
return 1
fi
# Add TXT record.
_namecom_addtxt_json="{\"host\":\"$_sub_domain\",\"type\":\"TXT\",\"answer\":\"$txtvalue\",\"ttl\":\"300\"}"
if _namecom_rest POST "domains/$_domain/records" "$_namecom_addtxt_json"; then
_retvalue=$(echo "$response" | _egrep_o "\"$_sub_domain\"")
if [ "$_retvalue" ]; then
_info "Successfully added TXT record, ready for validation."
return 0
else
_err "Unable to add the DNS record."
return 1
fi
fi
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_namecom_rm() {
fulldomain=$1
txtvalue=$2
Namecom_Username="${Namecom_Username:-$(_readaccountconf_mutable Namecom_Username)}"
Namecom_Token="${Namecom_Token:-$(_readaccountconf_mutable Namecom_Token)}"
if ! _namecom_login; then
return 1
fi
# Find domain in domain list.
if ! _namecom_get_root "$fulldomain"; then
_err "Unable to find domain specified."
return 1
fi
# Get the record id.
if _namecom_rest GET "domains/$_domain/records"; then
_record_id=$(echo "$response" | _egrep_o "\"id\":[0-9]+,\"domainName\":\"$_domain\",\"host\":\"$_sub_domain\",\"fqdn\":\"$fulldomain.\",\"type\":\"TXT\",\"answer\":\"$txtvalue\"" | cut -d \" -f 3 | _egrep_o [0-9]+)
_debug record_id "$_record_id"
if [ "$_record_id" ]; then
_info "Successfully retrieved the record id for ACME challenge."
else
_err "Unable to retrieve the record id."
return 1
fi
fi
# Remove the DNS record using record id.
if _namecom_rest DELETE "domains/$_domain/records/$_record_id"; then
_info "Successfully removed the TXT record."
return 0
else
_err "Unable to delete record id."
return 1
fi
}
#################### Private functions below ##################################
_namecom_rest() {
method=$1
param=$2
data=$3
export _H1="Authorization: Basic $_namecom_auth"
export _H2="Content-Type: application/json"
if [ "$method" != "GET" ]; then
response="$(_post "$data" "$Namecom_API/$param" "" "$method")"
else
response="$(_get "$Namecom_API/$param")"
fi
if [ "$?" != "0" ]; then
_err "error $param"
return 1
fi
_debug2 response "$response"
return 0
}
_namecom_login() {
# Auth string
# Name.com API v4 uses http basic auth to authenticate
# need to convert the token for http auth
_namecom_auth=$(printf "%s:%s" "$Namecom_Username" "$Namecom_Token" | _base64)
if _namecom_rest GET "hello"; then
retcode=$(echo "$response" | _egrep_o "\"username\"\:\"$Namecom_Username\"")
if [ "$retcode" ]; then
_info "Successfully logged in."
else
_err "$response"
_err "Please add your ip to api whitelist"
_err "Logging in failed."
return 1
fi
fi
}
_namecom_get_root() {
domain=$1
i=2
p=1
if ! _namecom_rest GET "domains"; then
return 1
fi
# Need to exclude the last field (tld)
numfields=$(echo "$domain" | _egrep_o "\." | wc -l)
while [ $i -le "$numfields" ]; do
host=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug host "$host"
if [ -z "$host" ]; then
return 1
fi
if _contains "$response" "$host"; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$host"
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}

137
dnsapi/dns_namesilo.sh Executable file
View File

@@ -0,0 +1,137 @@
#!/usr/bin/env sh
#Author: meowthink
#Created 01/14/2017
#Utilize namesilo.com API to finish dns-01 verifications.
Namesilo_API="https://www.namesilo.com/api"
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_namesilo_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$Namesilo_Key" ]; then
Namesilo_Key=""
_err "API token for namesilo.com is missing."
_err "Please specify that in your environment variable."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf Namesilo_Key "$Namesilo_Key"
if ! _get_root "$fulldomain"; then
_err "Unable to find domain specified."
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug txtvalue "$txtvalue"
if _namesilo_rest GET "dnsAddRecord?version=1&type=xml&key=$Namesilo_Key&domain=$_domain&rrtype=TXT&rrhost=$_sub_domain&rrvalue=$txtvalue"; then
retcode=$(printf "%s\n" "$response" | _egrep_o "<code>300")
if [ "$retcode" ]; then
_info "Successfully added TXT record, ready for validation."
return 0
else
_err "Unable to add the DNS record."
return 1
fi
fi
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_namesilo_rm() {
fulldomain=$1
txtvalue=$2
if ! _get_root "$fulldomain"; then
_err "Unable to find domain specified."
return 1
fi
# Get the record id.
if _namesilo_rest GET "dnsListRecords?version=1&type=xml&key=$Namesilo_Key&domain=$_domain"; then
retcode=$(printf "%s\n" "$response" | _egrep_o "<code>300")
if [ "$retcode" ]; then
_record_id=$(printf "%s\n" "$response" | _egrep_o "<record_id>([^<]*)</record_id><type>TXT</type><host>$fulldomain</host>" | _egrep_o "<record_id>([^<]*)</record_id>" | sed -r "s/<record_id>([^<]*)<\/record_id>/\1/" | tail -n 1)
_debug record_id "$_record_id"
_info "Successfully retrieved the record id for ACME challenge."
else
_err "Unable to retrieve the record id."
return 1
fi
fi
# Remove the DNS record using record id.
if _namesilo_rest GET "dnsDeleteRecord?version=1&type=xml&key=$Namesilo_Key&domain=$_domain&rrid=$_record_id"; then
retcode=$(printf "%s\n" "$response" | _egrep_o "<code>300")
if [ "$retcode" ]; then
_info "Successfully removed the TXT record."
return 0
else
_err "Unable to remove the DNS record."
return 1
fi
fi
}
#################### Private functions below ##################################
# _acme-challenge.www.domain.com
# returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain=$1
i=2
p=1
if ! _namesilo_rest GET "listDomains?version=1&type=xml&key=$Namesilo_Key"; then
return 1
fi
# Need to exclude the last field (tld)
numfields=$(echo "$domain" | _egrep_o "\." | wc -l)
while [ $i -le "$numfields" ]; do
host=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug host "$host"
if [ -z "$host" ]; then
return 1
fi
if _contains "$response" "$host"; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$host"
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_namesilo_rest() {
method=$1
param=$2
data=$3
if [ "$method" != "GET" ]; then
response="$(_post "$data" "$Namesilo_API/$param" "" "$method")"
else
response="$(_get "$Namesilo_API/$param")"
fi
if [ "$?" != "0" ]; then
_err "error $param"
return 1
fi
_debug2 response "$response"
return 0
}

131
dnsapi/dns_nederhost.sh Executable file
View File

@@ -0,0 +1,131 @@
#!/usr/bin/env sh
#NederHost_Key="sdfgikogfdfghjklkjhgfcdcfghjk"
NederHost_Api="https://api.nederhost.nl/dns/v1"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_nederhost_add() {
fulldomain=$1
txtvalue=$2
NederHost_Key="${NederHost_Key:-$(_readaccountconf_mutable NederHost_Key)}"
if [ -z "$NederHost_Key" ]; then
NederHost_Key=""
_err "You didn't specify a NederHost api key."
_err "You can get yours from https://www.nederhost.nl/mijn_nederhost"
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf_mutable NederHost_Key "$NederHost_Key"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_info "Adding record"
if _nederhost_rest PATCH "zones/$_domain/records/$fulldomain/TXT" "[{\"content\":\"$txtvalue\",\"ttl\":60}]"; then
if _contains "$response" "$fulldomain"; then
_info "Added, OK"
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
return 1
}
#fulldomain txtvalue
dns_nederhost_rm() {
fulldomain=$1
txtvalue=$2
NederHost_Key="${NederHost_Key:-$(_readaccountconf_mutable NederHost_Key)}"
if [ -z "$NederHost_Key" ]; then
NederHost_Key=""
_err "You didn't specify a NederHost api key."
_err "You can get yours from https://www.nederhost.nl/mijn_nederhost"
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Removing txt record"
_nederhost_rest DELETE "zones/${_domain}/records/$fulldomain/TXT?content=$txtvalue"
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain=$1
i=2
p=1
while true; do
_domain=$(printf "%s" "$domain" | cut -d . -f $i-100)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_debug _domain "$_domain"
if [ -z "$_domain" ]; then
#not valid
return 1
fi
if _nederhost_rest GET "zones/${_domain}"; then
if [ "${_code}" = "204" ]; then
return 0
fi
else
return 1
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_nederhost_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
export _H1="Authorization: Bearer $NederHost_Key"
export _H2="Content-Type: application/json"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$NederHost_Api/$ep" "" "$m")"
else
response="$(_get "$NederHost_Api/$ep")"
fi
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
_debug "http response code $_code"
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

181
dnsapi/dns_neodigit.sh Normal file
View File

@@ -0,0 +1,181 @@
#!/usr/bin/env sh
#
# NEODIGIT_API_TOKEN="jasdfhklsjadhflnhsausdfas"
# This is Neodigit.net api wrapper for acme.sh
#
# Author: Adrian Almenar
# Report Bugs here: https://github.com/tecnocratica/acme.sh
#
NEODIGIT_API_URL="https://api.neodigit.net/v1"
#
######## Public functions #####################
# Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_neodigit_add() {
fulldomain=$1
txtvalue=$2
NEODIGIT_API_TOKEN="${NEODIGIT_API_TOKEN:-$(_readaccountconf_mutable NEODIGIT_API_TOKEN)}"
if [ -z "$NEODIGIT_API_TOKEN" ]; then
NEODIGIT_API_TOKEN=""
_err "You haven't specified a Token api key."
_err "Please create the key and try again."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf_mutable NEODIGIT_API_TOKEN "$NEODIGIT_API_TOKEN"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_debug domain "$_domain"
_debug sub_domain "$_sub_domain"
_debug "Getting txt records"
_neo_rest GET "dns/zones/${_domain_id}/records?type=TXT&name=$fulldomain"
_debug _code "$_code"
if [ "$_code" != "200" ]; then
_err "error retrieving data!"
return 1
fi
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_debug domain "$_domain"
_debug sub_domain "$_sub_domain"
_info "Adding record"
if _neo_rest POST "dns/zones/$_domain_id/records" "{\"record\":{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":60}}"; then
if printf -- "%s" "$response" | grep "$_sub_domain" >/dev/null; then
_info "Added, OK"
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
return 1
}
#fulldomain txtvalue
dns_neodigit_rm() {
fulldomain=$1
txtvalue=$2
NEODIGIT_API_TOKEN="${NEODIGIT_API_TOKEN:-$(_readaccountconf_mutable NEODIGIT_API_TOKEN)}"
if [ -z "$NEODIGIT_API_TOKEN" ]; then
NEODIGIT_API_TOKEN=""
_err "You haven't specified a Token api key."
_err "Please create the key and try again."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf_mutable NEODIGIT_API_TOKEN "$NEODIGIT_API_TOKEN"
_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"
_neo_rest GET "dns/zones/${_domain_id}/records?type=TXT&name=$fulldomain&content=$txtvalue"
if [ "$_code" != "200" ]; then
_err "error retrieving data!"
return 1
fi
record_id=$(echo "$response" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d: -f2 | cut -d, -f1)
_debug "record_id" "$record_id"
if [ -z "$record_id" ]; then
_err "Can not get record id to remove."
return 1
fi
if ! _neo_rest DELETE "dns/zones/$_domain_id/records/$record_id"; then
_err "Delete record error."
return 1
fi
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
# _domain_id=dasfdsafsadg5ythd
_get_root() {
domain=$1
i=2
p=1
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 ! _neo_rest GET "dns/zones?name=$h"; then
return 1
fi
_debug p "$p"
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
_domain_id=$(echo "$response" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d: -f2 | cut -d, -f1)
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
}
_neo_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
export _H1="X-TCPanel-Token: $NEODIGIT_API_TOKEN"
export _H2="Content-Type: application/json"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$NEODIGIT_API_URL/$ep" "" "$m")"
else
response="$(_get "$NEODIGIT_API_URL/$ep")"
fi
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

134
dnsapi/dns_netcup.sh Normal file
View File

@@ -0,0 +1,134 @@
#!/usr/bin/env sh
#developed by linux-insideDE
NC_Apikey="${NC_Apikey:-$(_readaccountconf_mutable NC_Apikey)}"
NC_Apipw="${NC_Apipw:-$(_readaccountconf_mutable NC_Apipw)}"
NC_CID="${NC_CID:-$(_readaccountconf_mutable NC_CID)}"
end="https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON"
client=""
dns_netcup_add() {
_debug NC_Apikey "$NC_Apikey"
login
if [ "$NC_Apikey" = "" ] || [ "$NC_Apipw" = "" ] || [ "$NC_CID" = "" ]; then
_err "No Credentials given"
return 1
fi
_saveaccountconf_mutable NC_Apikey "$NC_Apikey"
_saveaccountconf_mutable NC_Apipw "$NC_Apipw"
_saveaccountconf_mutable NC_CID "$NC_CID"
fulldomain=$1
txtvalue=$2
domain=""
exit=$(echo "$fulldomain" | tr -dc '.' | wc -c)
exit=$(_math "$exit" + 1)
i=$exit
while
[ "$exit" -gt 0 ]
do
tmp=$(echo "$fulldomain" | cut -d'.' -f"$exit")
if [ "$(_math "$i" - "$exit")" -eq 0 ]; then
domain="$tmp"
else
domain="$tmp.$domain"
fi
if [ "$(_math "$i" - "$exit")" -ge 1 ]; then
msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$domain\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"\", \"hostname\": \"$fulldomain.\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"false\", \"state\": \"yes\"} ]}}}" "$end" "" "POST")
_debug "$msg"
if [ "$(_getfield "$msg" "5" | sed 's/"statuscode"://g')" != 5028 ]; then
if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then
_err "$msg"
return 1
else
break
fi
fi
fi
exit=$(_math "$exit" - 1)
done
logout
}
dns_netcup_rm() {
login
fulldomain=$1
txtvalue=$2
domain=""
exit=$(echo "$fulldomain" | tr -dc '.' | wc -c)
exit=$(_math "$exit" + 1)
i=$exit
rec=""
while
[ "$exit" -gt 0 ]
do
tmp=$(echo "$fulldomain" | cut -d'.' -f"$exit")
if [ "$(_math "$i" - "$exit")" -eq 0 ]; then
domain="$tmp"
else
domain="$tmp.$domain"
fi
if [ "$(_math "$i" - "$exit")" -ge 1 ]; then
msg=$(_post "{\"action\": \"infoDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\", \"domainname\": \"$domain\"}}" "$end" "" "POST")
rec=$(echo "$msg" | sed 's/\[//g' | sed 's/\]//g' | sed 's/{\"serverrequestid\".*\"dnsrecords\"://g' | sed 's/},{/};{/g' | sed 's/{//g' | sed 's/}//g')
_debug "$msg"
if [ "$(_getfield "$msg" "5" | sed 's/"statuscode"://g')" != 5028 ]; then
if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then
_err "$msg"
return 1
else
break
fi
fi
fi
exit=$(_math "$exit" - 1)
done
ida=0000
idv=0001
ids=0000000000
i=1
while
[ "$i" -ne 0 ]
do
specrec=$(_getfield "$rec" "$i" ";")
idv="$ida"
ida=$(_getfield "$specrec" "1" "," | sed 's/\"id\":\"//g' | sed 's/\"//g')
txtv=$(_getfield "$specrec" "5" "," | sed 's/\"destination\":\"//g' | sed 's/\"//g')
i=$(_math "$i" + 1)
if [ "$txtvalue" = "$txtv" ]; then
i=0
ids="$ida"
fi
if [ "$ida" = "$idv" ]; then
i=0
fi
done
msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$domain\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"$ids\", \"hostname\": \"$fulldomain.\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"TRUE\", \"state\": \"yes\"} ]}}}" "$end" "" "POST")
_debug "$msg"
if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then
_err "$msg"
return 1
fi
logout
}
login() {
tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST")
sid=$(echo "$tmp" | tr '{}' '\n' | grep apisessionid | cut -d '"' -f 4)
_debug "$tmp"
if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then
_err "$msg"
return 1
fi
}
logout() {
tmp=$(_post "{\"action\": \"logout\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST")
_debug "$tmp"
if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then
_err "$msg"
return 1
fi
}

64
dnsapi/dns_nsd.sh Normal file
View File

@@ -0,0 +1,64 @@
#!/usr/bin/env sh
#Nsd_ZoneFile="/etc/nsd/zones/example.com.zone"
#Nsd_Command="sudo nsd-control reload"
# args: fulldomain txtvalue
dns_nsd_add() {
fulldomain=$1
txtvalue=$2
ttlvalue=300
Nsd_ZoneFile="${Nsd_ZoneFile:-$(_readdomainconf Nsd_ZoneFile)}"
Nsd_Command="${Nsd_Command:-$(_readdomainconf Nsd_Command)}"
# Arg checks
if [ -z "$Nsd_ZoneFile" ] || [ -z "$Nsd_Command" ]; then
Nsd_ZoneFile=""
Nsd_Command=""
_err "Specify ENV vars Nsd_ZoneFile and Nsd_Command"
return 1
fi
if [ ! -f "$Nsd_ZoneFile" ]; then
Nsd_ZoneFile=""
Nsd_Command=""
_err "No such file: $Nsd_ZoneFile"
return 1
fi
_savedomainconf Nsd_ZoneFile "$Nsd_ZoneFile"
_savedomainconf Nsd_Command "$Nsd_Command"
echo "$fulldomain. $ttlvalue IN TXT \"$txtvalue\"" >>"$Nsd_ZoneFile"
_info "Added TXT record for $fulldomain"
_debug "Running $Nsd_Command"
if eval "$Nsd_Command"; then
_info "Successfully updated the zone"
return 0
else
_err "Problem updating the zone"
return 1
fi
}
# args: fulldomain txtvalue
dns_nsd_rm() {
fulldomain=$1
txtvalue=$2
ttlvalue=300
Nsd_ZoneFile="${Nsd_ZoneFile:-$(_readdomainconf Nsd_ZoneFile)}"
Nsd_Command="${Nsd_Command:-$(_readdomainconf Nsd_Command)}"
sed -i "/$fulldomain. $ttlvalue IN TXT \"$txtvalue\"/d" "$Nsd_ZoneFile"
_info "Removed TXT record for $fulldomain"
_debug "Running $Nsd_Command"
if eval "$Nsd_Command"; then
_info "Successfully reloaded NSD "
return 0
else
_err "Problem reloading NSD"
return 1
fi
}

158
dnsapi/dns_nsone.sh Normal file
View File

@@ -0,0 +1,158 @@
#!/usr/bin/env sh
# bug reports to dev@1e.ca
#
#NS1_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
NS1_Api="https://api.nsone.net/v1"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_nsone_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$NS1_Key" ]; then
NS1_Key=""
_err "You didn't specify nsone dns api key yet."
_err "Please create you key and try again."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf NS1_Key "$NS1_Key"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_nsone_rest GET "zones/${_domain}"
if ! _contains "$response" "\"records\":"; then
_err "Error"
return 1
fi
count=$(printf "%s\n" "$response" | _egrep_o "\"domain\":\"$fulldomain\",[^{]*\"type\":\"TXT\"" | wc -l | tr -d " ")
_debug count "$count"
if [ "$count" = "0" ]; then
_info "Adding record"
if _nsone_rest PUT "zones/$_domain/$fulldomain/TXT" "{\"answers\":[{\"answer\":[\"$txtvalue\"]}],\"type\":\"TXT\",\"domain\":\"$fulldomain\",\"zone\":\"$_domain\",\"ttl\":0}"; 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"
prev_txt=$(printf "%s\n" "$response" | _egrep_o "\"domain\":\"$fulldomain\",\"short_answers\":\[\"[^,]*\]" | _head_n 1 | cut -d: -f3 | cut -d, -f1)
_debug "prev_txt" "$prev_txt"
_nsone_rest POST "zones/$_domain/$fulldomain/TXT" "{\"answers\": [{\"answer\": [\"$txtvalue\"]},{\"answer\": $prev_txt}],\"type\": \"TXT\",\"domain\":\"$fulldomain\",\"zone\": \"$_domain\",\"ttl\":0}"
if [ "$?" = "0" ] && _contains "$response" "$fulldomain"; then
_info "Updated!"
#todo: check if the record takes effect
return 0
fi
_err "Update error"
return 1
fi
}
#fulldomain
dns_nsone_rm() {
fulldomain=$1
txtvalue=$2
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_nsone_rest GET "zones/${_domain}/$fulldomain/TXT"
count=$(printf "%s\n" "$response" | _egrep_o "\"domain\":\"$fulldomain\",.*\"type\":\"TXT\"" | wc -l | tr -d " ")
_debug count "$count"
if [ "$count" = "0" ]; then
_info "Don't need to remove."
else
if ! _nsone_rest DELETE "zones/${_domain}/$fulldomain/TXT"; then
_err "Delete record error."
return 1
fi
_contains "$response" ""
fi
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
# _domain_id=sdjkglgdfewsdfg
_get_root() {
domain=$1
i=2
p=1
if ! _nsone_rest GET "zones"; then
return 1
fi
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
if _contains "$response" "\"zone\":\"$h\""; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_nsone_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
export _H1="Accept: application/json"
export _H2="X-NSONE-Key: $NS1_Key"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$NS1_Api/$ep" "" "$m")"
else
response="$(_get "$NS1_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

View File

@@ -6,17 +6,39 @@
dns_nsupdate_add() {
fulldomain=$1
txtvalue=$2
NSUPDATE_SERVER="${NSUPDATE_SERVER:-$(_readaccountconf_mutable NSUPDATE_SERVER)}"
NSUPDATE_SERVER_PORT="${NSUPDATE_SERVER_PORT:-$(_readaccountconf_mutable NSUPDATE_SERVER_PORT)}"
NSUPDATE_KEY="${NSUPDATE_KEY:-$(_readaccountconf_mutable NSUPDATE_KEY)}"
NSUPDATE_ZONE="${NSUPDATE_ZONE:-$(_readaccountconf_mutable NSUPDATE_ZONE)}"
_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}"
_saveaccountconf_mutable NSUPDATE_SERVER "${NSUPDATE_SERVER}"
_saveaccountconf_mutable NSUPDATE_SERVER_PORT "${NSUPDATE_SERVER_PORT}"
_saveaccountconf_mutable NSUPDATE_KEY "${NSUPDATE_KEY}"
_saveaccountconf_mutable NSUPDATE_ZONE "${NSUPDATE_ZONE}"
[ -n "${NSUPDATE_SERVER}" ] || NSUPDATE_SERVER="localhost"
[ -n "${NSUPDATE_SERVER_PORT}" ] || NSUPDATE_SERVER_PORT=53
_info "adding ${fulldomain}. 60 in txt \"${txtvalue}\""
nsupdate -k "${NSUPDATE_KEY}" <<EOF
server ${NSUPDATE_SERVER}
[ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_1" ] && nsdebug="-d"
[ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_2" ] && nsdebug="-D"
if [ -z "${NSUPDATE_ZONE}" ]; then
nsupdate -k "${NSUPDATE_KEY}" $nsdebug <<EOF
server ${NSUPDATE_SERVER} ${NSUPDATE_SERVER_PORT}
update add ${fulldomain}. 60 in txt "${txtvalue}"
send
EOF
else
nsupdate -k "${NSUPDATE_KEY}" $nsdebug <<EOF
server ${NSUPDATE_SERVER} ${NSUPDATE_SERVER_PORT}
zone ${NSUPDATE_ZONE}.
update add ${fulldomain}. 60 in txt "${txtvalue}"
send
EOF
fi
if [ $? -ne 0 ]; then
_err "error updating domain"
return 1
@@ -28,14 +50,32 @@ EOF
#Usage: dns_nsupdate_rm _acme-challenge.www.domain.com
dns_nsupdate_rm() {
fulldomain=$1
NSUPDATE_SERVER="${NSUPDATE_SERVER:-$(_readaccountconf_mutable NSUPDATE_SERVER)}"
NSUPDATE_SERVER_PORT="${NSUPDATE_SERVER_PORT:-$(_readaccountconf_mutable NSUPDATE_SERVER_PORT)}"
NSUPDATE_KEY="${NSUPDATE_KEY:-$(_readaccountconf_mutable NSUPDATE_KEY)}"
NSUPDATE_ZONE="${NSUPDATE_ZONE:-$(_readaccountconf_mutable NSUPDATE_ZONE)}"
_checkKeyFile || return 1
[ -n "${NSUPDATE_SERVER}" ] || NSUPDATE_SERVER="localhost"
[ -n "${NSUPDATE_SERVER_PORT}" ] || NSUPDATE_SERVER_PORT=53
_info "removing ${fulldomain}. txt"
nsupdate -k "${NSUPDATE_KEY}" <<EOF
server ${NSUPDATE_SERVER}
[ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_1" ] && nsdebug="-d"
[ -n "$DEBUG" ] && [ "$DEBUG" -ge "$DEBUG_LEVEL_2" ] && nsdebug="-D"
if [ -z "${NSUPDATE_ZONE}" ]; then
nsupdate -k "${NSUPDATE_KEY}" $nsdebug <<EOF
server ${NSUPDATE_SERVER} ${NSUPDATE_SERVER_PORT}
update delete ${fulldomain}. txt
send
EOF
else
nsupdate -k "${NSUPDATE_KEY}" $nsdebug <<EOF
server ${NSUPDATE_SERVER} ${NSUPDATE_SERVER_PORT}
zone ${NSUPDATE_ZONE}.
update delete ${fulldomain}. txt
send
EOF
fi
if [ $? -ne 0 ]; then
_err "error updating domain"
return 1

211
dnsapi/dns_nw.sh Normal file
View File

@@ -0,0 +1,211 @@
#!/usr/bin/env sh
########################################################################
# NocWorx script for acme.sh
#
# Handles DNS Updates for the Following vendors:
# - Nexcess.net
# - Thermo.io
# - Futurehosting.com
#
# Environment variables:
#
# - NW_API_TOKEN (Your API Token)
# - NW_API_ENDPOINT (One of the following listed below)
#
# Endpoints:
# - https://portal.nexcess.net (default)
# - https://core.thermo.io
# - https://my.futurehosting.com
#
# Note: If you do not have an API token, one can be generated at one
# of the following URLs:
# - https://portal.nexcess.net/api-token
# - https://core.thermo.io/api-token
# - https://my.futurehosting.com/api-token
#
# Author: Frank Laszlo <flaszlo@nexcess.net>
NW_API_VERSION="0"
# dns_nw_add() - Add TXT record
# Usage: dns_nw_add _acme-challenge.subdomain.domain.com "XyZ123..."
dns_nw_add() {
host="${1}"
txtvalue="${2}"
_debug host "${host}"
_debug txtvalue "${txtvalue}"
if ! _check_nw_api_creds; then
return 1
fi
_info "Using NocWorx (${NW_API_ENDPOINT})"
_debug "Calling: dns_nw_add() '${host}' '${txtvalue}'"
_debug "Detecting root zone"
if ! _get_root "${host}"; then
_err "Zone for domain does not exist."
return 1
fi
_debug _zone_id "${_zone_id}"
_debug _sub_domain "${_sub_domain}"
_debug _domain "${_domain}"
_post_data="{\"zone_id\": \"${_zone_id}\", \"type\": \"TXT\", \"host\": \"${host}\", \"target\": \"${txtvalue}\", \"ttl\": \"300\"}"
if _rest POST "dns-record" "${_post_data}" && [ -n "${response}" ]; then
_record_id=$(printf "%s\n" "${response}" | _egrep_o "\"record_id\": *[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1)
_debug _record_id "${_record_id}"
if [ -z "$_record_id" ]; then
_err "Error adding the TXT record."
return 1
fi
_info "TXT record successfully added."
return 0
fi
return 1
}
# dns_nw_rm() - Remove TXT record
# Usage: dns_nw_rm _acme-challenge.subdomain.domain.com "XyZ123..."
dns_nw_rm() {
host="${1}"
txtvalue="${2}"
_debug host "${host}"
_debug txtvalue "${txtvalue}"
if ! _check_nw_api_creds; then
return 1
fi
_info "Using NocWorx (${NW_API_ENDPOINT})"
_debug "Calling: dns_nw_rm() '${host}'"
_debug "Detecting root zone"
if ! _get_root "${host}"; then
_err "Zone for domain does not exist."
return 1
fi
_debug _zone_id "${_zone_id}"
_debug _sub_domain "${_sub_domain}"
_debug _domain "${_domain}"
_parameters="?zone_id=${_zone_id}"
if _rest GET "dns-record" "${_parameters}" && [ -n "${response}" ]; then
response="$(echo "${response}" | tr -d "\n" | sed 's/^\[\(.*\)\]$/\1/' | sed -e 's/{"record_id":/|"record_id":/g' | sed 's/|/&{/g' | tr "|" "\n")"
_debug response "${response}"
record="$(echo "${response}" | _egrep_o "{.*\"host\": *\"${_sub_domain}\", *\"target\": *\"${txtvalue}\".*}")"
_debug record "${record}"
if [ "${record}" ]; then
_record_id=$(printf "%s\n" "${record}" | _egrep_o "\"record_id\": *[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
if [ "${_record_id}" ]; then
_debug _record_id "${_record_id}"
_rest DELETE "dns-record/${_record_id}"
_info "TXT record successfully deleted."
return 0
fi
return 1
fi
return 0
fi
return 1
}
_check_nw_api_creds() {
NW_API_TOKEN="${NW_API_TOKEN:-$(_readaccountconf_mutable NW_API_TOKEN)}"
NW_API_ENDPOINT="${NW_API_ENDPOINT:-$(_readaccountconf_mutable NW_API_ENDPOINT)}"
if [ -z "${NW_API_ENDPOINT}" ]; then
NW_API_ENDPOINT="https://portal.nexcess.net"
fi
if [ -z "${NW_API_TOKEN}" ]; then
_err "You have not defined your NW_API_TOKEN."
_err "Please create your token and try again."
_err "If you need to generate a new token, please visit one of the following URLs:"
_err " - https://portal.nexcess.net/api-token"
_err " - https://core.thermo.io/api-token"
_err " - https://my.futurehosting.com/api-token"
return 1
fi
_saveaccountconf_mutable NW_API_TOKEN "${NW_API_TOKEN}"
_saveaccountconf_mutable NW_API_ENDPOINT "${NW_API_ENDPOINT}"
}
_get_root() {
domain="${1}"
i=2
p=1
if _rest GET "dns-zone"; then
response="$(echo "${response}" | tr -d "\n" | sed 's/^\[\(.*\)\]$/\1/' | sed -e 's/{"zone_id":/|"zone_id":/g' | sed 's/|/&{/g' | tr "|" "\n")"
_debug response "${response}"
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\": *\"${h}\".*}")"
if [ "${hostedzone}" ]; then
_zone_id=$(printf "%s\n" "${hostedzone}" | _egrep_o "\"zone_id\": *[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
if [ "${_zone_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
}
_rest() {
method="${1}"
ep="/${2}"
data="${3}"
_debug method "${method}"
_debug ep "${ep}"
export _H1="Accept: application/json"
export _H2="Content-Type: application/json"
export _H3="Api-Version: ${NW_API_VERSION}"
export _H4="User-Agent: NW-ACME-CLIENT"
export _H5="Authorization: Bearer ${NW_API_TOKEN}"
if [ "${method}" != "GET" ]; then
_debug data "${data}"
response="$(_post "${data}" "${NW_API_ENDPOINT}${ep}" "" "${method}")"
else
response="$(_get "${NW_API_ENDPOINT}${ep}${data}")"
fi
if [ "${?}" != "0" ]; then
_err "error ${ep}"
return 1
fi
_debug2 response "${response}"
return 0
}

179
dnsapi/dns_one.sh Normal file
View File

@@ -0,0 +1,179 @@
#!/usr/bin/env sh
# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*-
# one.com ui wrapper for acme.sh
# Author: github: @diseq
# Created: 2019-02-17
# Fixed by: @der-berni
# Modified: 2019-05-31
#
# export ONECOM_User="username"
# export ONECOM_Password="password"
#
# Usage:
# acme.sh --issue --dns dns_one -d example.com
#
# only single domain supported atm
dns_one_add() {
fulldomain=$1
txtvalue=$2
if ! _dns_one_login; then
_err "login failed"
return 1
fi
_debug "detect the root domain"
if ! _get_root "$fulldomain"; then
_err "root domain not found"
return 1
fi
mysubdomain=$_sub_domain
mydomain=$_domain
_debug mysubdomain "$mysubdomain"
_debug mydomain "$mydomain"
# get entries
response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")"
_debug response "$response"
# Update the IP address for domain entry
postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"TXT\",\"prefix\":\"$mysubdomain\",\"content\":\"$txtvalue\"}}"
_debug postdata "$postdata"
response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records" "" "POST" "application/json")"
response="$(echo "$response" | _normalizeJson)"
_debug response "$response"
id=$(echo "$response" | sed -n "s/{\"result\":{\"data\":{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}}},\"metadata\":null}/\1/p")
if [ -z "$id" ]; then
_err "Add txt record error."
return 1
else
_info "Added, OK ($id)"
return 0
fi
}
dns_one_rm() {
fulldomain=$1
txtvalue=$2
if ! _dns_one_login; then
_err "login failed"
return 1
fi
_debug "detect the root domain"
if ! _get_root "$fulldomain"; then
_err "root domain not found"
return 1
fi
mysubdomain=$_sub_domain
mydomain=$_domain
_debug mysubdomain "$mysubdomain"
_debug mydomain "$mydomain"
# get entries
response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")"
response="$(echo "$response" | _normalizeJson)"
_debug response "$response"
id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}.*/\1/p")
if [ -z "$id" ]; then
_err "Txt record not found."
return 1
fi
# delete entry
response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records/$id" "" "DELETE" "application/json")"
response="$(echo "$response" | _normalizeJson)"
_debug response "$response"
if [ "$response" = '{"result":null,"metadata":null}' ]; then
_info "Removed, OK"
return 0
else
_err "Removing txt record error."
return 1
fi
}
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_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
response="$(_get "https://www.one.com/admin/api/domains/$h/dns/custom_records")"
if ! _contains "$response" "CRMRST_000302"; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
_err "Unable to parse this domain"
return 1
}
_dns_one_login() {
# get credentials
ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}"
ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}"
if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then
ONECOM_User=""
ONECOM_Password=""
_err "You didn't specify a one.com username and password yet."
_err "Please create the key and try again."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf_mutable ONECOM_User "$ONECOM_User"
_saveaccountconf_mutable ONECOM_Password "$ONECOM_Password"
# Login with user and password
postdata="loginDomain=true"
postdata="$postdata&displayUsername=$ONECOM_User"
postdata="$postdata&username=$ONECOM_User"
postdata="$postdata&targetDomain="
postdata="$postdata&password1=$ONECOM_Password"
postdata="$postdata&loginTarget="
#_debug postdata "$postdata"
response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")"
#_debug response "$response"
# Get SessionID
JSESSIONID="$(grep "OneSIDCrmAdmin" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _head_n 1 | _egrep_o 'OneSIDCrmAdmin=[^;]*;' | tr -d ';')"
_debug jsessionid "$JSESSIONID"
if [ -z "$JSESSIONID" ]; then
_err "error sessionid cookie not found"
return 1
fi
export _H1="Cookie: ${JSESSIONID}"
return 0
}

217
dnsapi/dns_online.sh Executable file
View File

@@ -0,0 +1,217 @@
#!/usr/bin/env sh
# Online API
# https://console.online.net/en/api/
#
# Requires Online API key set in ONLINE_API_KEY
######## Public functions #####################
ONLINE_API="https://api.online.net/api/v1"
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_online_add() {
fulldomain=$1
txtvalue=$2
if ! _online_check_config; then
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug _real_dns_version "$_real_dns_version"
_info "Creating temporary zone version"
_online_create_temporary_zone_version
_info "Enabling temporary zone version"
_online_enable_zone "$_temporary_dns_version"
_info "Adding record"
_online_create_TXT_record "$_real_dns_version" "$_sub_domain" "$txtvalue"
_info "Disabling temporary version"
_online_enable_zone "$_real_dns_version"
_info "Destroying temporary version"
_online_destroy_zone "$_temporary_dns_version"
_info "Record added."
return 0
}
#fulldomain
dns_online_rm() {
fulldomain=$1
txtvalue=$2
if ! _online_check_config; then
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug _real_dns_version "$_real_dns_version"
_debug "Getting txt records"
if ! _online_rest GET "domain/$_domain/version/active"; then
return 1
fi
rid=$(echo "$response" | _egrep_o "\"id\":[0-9]+,\"name\":\"$_sub_domain\",\"data\":\"\\\u0022$txtvalue\\\u0022\"" | cut -d ':' -f 2 | cut -d ',' -f 1)
_debug rid "$rid"
if [ -z "$rid" ]; then
return 1
fi
_info "Creating temporary zone version"
_online_create_temporary_zone_version
_info "Enabling temporary zone version"
_online_enable_zone "$_temporary_dns_version"
_info "Removing DNS record"
_online_rest DELETE "domain/$_domain/version/$_real_dns_version/zone/$rid"
_info "Disabling temporary version"
_online_enable_zone "$_real_dns_version"
_info "Destroying temporary version"
_online_destroy_zone "$_temporary_dns_version"
return 0
}
#################### Private functions below ##################################
_online_check_config() {
ONLINE_API_KEY="${ONLINE_API_KEY:-$(_readaccountconf_mutable ONLINE_API_KEY)}"
if [ -z "$ONLINE_API_KEY" ]; then
_err "No API key specified for Online API."
_err "Create your key and export it as ONLINE_API_KEY"
return 1
fi
if ! _online_rest GET "domain/"; then
_err "Invalid API key specified for Online API."
return 1
fi
_saveaccountconf_mutable ONLINE_API_KEY "$ONLINE_API_KEY"
return 0
}
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_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
_online_rest GET "domain/$h/version/active"
if ! _contains "$response" "Domain not found" >/dev/null; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
_real_dns_version=$(echo "$response" | _egrep_o '"uuid_ref":.*' | cut -d ':' -f 2 | cut -d '"' -f 2)
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
_err "Unable to retrive DNS zone matching this domain"
return 1
}
# this function create a temporary zone version
# as online.net does not allow updating an active version
_online_create_temporary_zone_version() {
_online_rest POST "domain/$_domain/version" "name=acme.sh"
if [ "$?" != "0" ]; then
return 1
fi
_temporary_dns_version=$(echo "$response" | _egrep_o '"uuid_ref":.*' | cut -d ':' -f 2 | cut -d '"' -f 2)
# Creating a dummy record in this temporary version, because online.net doesn't accept enabling an empty version
_online_create_TXT_record "$_temporary_dns_version" "dummy.acme.sh" "dummy"
return 0
}
_online_destroy_zone() {
version_id=$1
_online_rest DELETE "domain/$_domain/version/$version_id"
if [ "$?" != "0" ]; then
return 1
fi
return 0
}
_online_enable_zone() {
version_id=$1
_online_rest PATCH "domain/$_domain/version/$version_id/enable"
if [ "$?" != "0" ]; then
return 1
fi
return 0
}
_online_create_TXT_record() {
version=$1
txt_name=$2
txt_value=$3
_online_rest POST "domain/$_domain/version/$version/zone" "type=TXT&name=$txt_name&data=%22$txt_value%22&ttl=60&priority=0"
# Note : the normal, expected response SHOULD be "Unknown method".
# this happens because the API HTTP response contains a Location: header, that redirect
# to an unknown online.net endpoint.
if [ "$?" != "0" ] || _contains "$response" "Unknown method" || _contains "$response" "\$ref"; then
return 0
else
_err "error $response"
return 1
fi
}
_online_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
_online_url="$ONLINE_API/$ep"
_debug2 _online_url "$_online_url"
export _H1="Authorization: Bearer $ONLINE_API_KEY"
export _H2="X-Pretty-JSON: 1"
if [ "$data" ] || [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$_online_url" "" "$m")"
else
response="$(_get "$_online_url")"
fi
if [ "$?" != "0" ] || _contains "$response" "invalid_grant" || _contains "$response" "Method not allowed"; then
_err "error $response"
return 1
fi
_debug2 response "$response"
return 0
}

244
dnsapi/dns_openprovider.sh Executable file
View File

@@ -0,0 +1,244 @@
#!/usr/bin/env sh
# This is the OpenProvider API wrapper for acme.sh
#
# Author: Sylvia van Os
# Report Bugs here: https://github.com/Neilpang/acme.sh/issues/2104
#
# export OPENPROVIDER_USER="username"
# export OPENPROVIDER_PASSWORDHASH="hashed_password"
#
# Usage:
# acme.sh --issue --dns dns_openprovider -d example.com
OPENPROVIDER_API="https://api.openprovider.eu/"
#OPENPROVIDER_API="https://api.cte.openprovider.eu/" # Test API
######## Public functions #####################
#Usage: dns_openprovider_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_openprovider_add() {
fulldomain="$1"
txtvalue="$2"
OPENPROVIDER_USER="${OPENPROVIDER_USER:-$(_readaccountconf_mutable OPENPROVIDER_USER)}"
OPENPROVIDER_PASSWORDHASH="${OPENPROVIDER_PASSWORDHASH:-$(_readaccountconf_mutable OPENPROVIDER_PASSWORDHASH)}"
if [ -z "$OPENPROVIDER_USER" ] || [ -z "$OPENPROVIDER_PASSWORDHASH" ]; then
_err "You didn't specify the openprovider user and/or password hash."
return 1
fi
# save the username and password to the account conf file.
_saveaccountconf_mutable OPENPROVIDER_USER "$OPENPROVIDER_USER"
_saveaccountconf_mutable OPENPROVIDER_PASSWORDHASH "$OPENPROVIDER_PASSWORDHASH"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_name "$_domain_name"
_debug _domain_extension "$_domain_extension"
_debug "Getting current records"
existing_items=""
results_retrieved=0
while true; do
_openprovider_request "$(printf '<searchZoneRecordDnsRequest><name>%s.%s</name><offset>%s</offset></searchZoneRecordDnsRequest>' "$_domain_name" "$_domain_extension" "$results_retrieved")"
items="$response"
while true; do
item="$(echo "$items" | _egrep_o '<openXML>.*<\/openXML>' | sed -n 's/.*\(<item>.*<\/item>\).*/\1/p')"
_debug existing_items "$existing_items"
_debug results_retrieved "$results_retrieved"
_debug item "$item"
if [ -z "$item" ]; then
break
fi
items="$(echo "$items" | sed "s|${item}||")"
results_retrieved="$(_math "$results_retrieved" + 1)"
new_item="$(echo "$item" | sed -n 's/.*<item>.*\(<name>\(.*\)\.'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(<type>.*<\/type>\).*\(<value>.*<\/value>\).*\(<prio>.*<\/prio>\).*\(<ttl>.*<\/ttl>\)\).*<\/item>.*/<item><name>\2<\/name>\3\4\5\6<\/item>/p')"
if [ -z "$new_item" ]; then
# Base record
new_item="$(echo "$item" | sed -n 's/.*<item>.*\(<name>\(.*\)'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(<type>.*<\/type>\).*\(<value>.*<\/value>\).*\(<prio>.*<\/prio>\).*\(<ttl>.*<\/ttl>\)\).*<\/item>.*/<item><name>\2<\/name>\3\4\5\6<\/item>/p')"
fi
if [ -z "$(echo "$new_item" | _egrep_o ".*<type>(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then
_debug "not an allowed record type, skipping" "$new_item"
continue
fi
existing_items="$existing_items$new_item"
done
total="$(echo "$response" | _egrep_o '<total>.*?<\/total>' | sed -n 's/.*<total>\(.*\)<\/total>.*/\1/p')"
_debug total "$total"
if [ "$results_retrieved" -eq "$total" ]; then
break
fi
done
_debug "Creating acme record"
acme_record="$(echo "$fulldomain" | sed -e "s/.$_domain_name.$_domain_extension$//")"
_openprovider_request "$(printf '<modifyZoneDnsRequest><domain><name>%s</name><extension>%s</extension></domain><type>master</type><records><array>%s<item><name>%s</name><type>TXT</type><value>%s</value><ttl>86400</ttl></item></array></records></modifyZoneDnsRequest>' "$_domain_name" "$_domain_extension" "$existing_items" "$acme_record" "$txtvalue")"
return 0
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_openprovider_rm() {
fulldomain="$1"
txtvalue="$2"
OPENPROVIDER_USER="${OPENPROVIDER_USER:-$(_readaccountconf_mutable OPENPROVIDER_USER)}"
OPENPROVIDER_PASSWORDHASH="${OPENPROVIDER_PASSWORDHASH:-$(_readaccountconf_mutable OPENPROVIDER_PASSWORDHASH)}"
if [ -z "$OPENPROVIDER_USER" ] || [ -z "$OPENPROVIDER_PASSWORDHASH" ]; then
_err "You didn't specify the openprovider user and/or password hash."
return 1
fi
# save the username and password to the account conf file.
_saveaccountconf_mutable OPENPROVIDER_USER "$OPENPROVIDER_USER"
_saveaccountconf_mutable OPENPROVIDER_PASSWORDHASH "$OPENPROVIDER_PASSWORDHASH"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_name "$_domain_name"
_debug _domain_extension "$_domain_extension"
_debug "Getting current records"
existing_items=""
results_retrieved=0
while true; do
_openprovider_request "$(printf '<searchZoneRecordDnsRequest><name>%s.%s</name><offset>%s</offset></searchZoneRecordDnsRequest>' "$_domain_name" "$_domain_extension" "$results_retrieved")"
# Remove acme records from items
items="$response"
while true; do
item="$(echo "$items" | _egrep_o '<openXML>.*<\/openXML>' | sed -n 's/.*\(<item>.*<\/item>\).*/\1/p')"
_debug existing_items "$existing_items"
_debug results_retrieved "$results_retrieved"
_debug item "$item"
if [ -z "$item" ]; then
break
fi
items="$(echo "$items" | sed "s|${item}||")"
results_retrieved="$(_math "$results_retrieved" + 1)"
if ! echo "$item" | grep -v "$fulldomain"; then
_debug "acme record, skipping" "$item"
continue
fi
new_item="$(echo "$item" | sed -n 's/.*<item>.*\(<name>\(.*\)\.'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(<type>.*<\/type>\).*\(<value>.*<\/value>\).*\(<prio>.*<\/prio>\).*\(<ttl>.*<\/ttl>\)\).*<\/item>.*/<item><name>\2<\/name>\3\4\5\6<\/item>/p')"
if [ -z "$new_item" ]; then
# Base record
new_item="$(echo "$item" | sed -n 's/.*<item>.*\(<name>\(.*\)'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(<type>.*<\/type>\).*\(<value>.*<\/value>\).*\(<prio>.*<\/prio>\).*\(<ttl>.*<\/ttl>\)\).*<\/item>.*/<item><name>\2<\/name>\3\4\5\6<\/item>/p')"
fi
if [ -z "$(echo "$new_item" | _egrep_o ".*<type>(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then
_debug "not an allowed record type, skipping" "$new_item"
continue
fi
existing_items="$existing_items$new_item"
done
total="$(echo "$response" | _egrep_o '<total>.*?<\/total>' | sed -n 's/.*<total>\(.*\)<\/total>.*/\1/p')"
_debug total "$total"
if [ "$results_retrieved" -eq "$total" ]; then
break
fi
done
_debug "Removing acme record"
_openprovider_request "$(printf '<modifyZoneDnsRequest><domain><name>%s</name><extension>%s</extension></domain><type>master</type><records><array>%s</array></records></modifyZoneDnsRequest>' "$_domain_name" "$_domain_extension" "$existing_items")"
return 0
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _domain_name=domain
# _domain_extension=com
_get_root() {
domain=$1
i=2
results_retrieved=0
while true; do
h=$(echo "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
_openprovider_request "$(printf '<searchDomainRequest><domainNamePattern>%s</domainNamePattern><offset>%s</offset></searchDomainRequest>' "$(echo "$h" | cut -d . -f 1)" "$results_retrieved")"
items="$response"
while true; do
item="$(echo "$items" | _egrep_o '<openXML>.*<\/openXML>' | sed -n 's/.*\(<domain>.*<\/domain>\).*/\1/p')"
_debug existing_items "$existing_items"
_debug results_retrieved "$results_retrieved"
_debug item "$item"
if [ -z "$item" ]; then
break
fi
items="$(echo "$items" | sed "s|${item}||")"
results_retrieved="$(_math "$results_retrieved" + 1)"
_domain_name="$(echo "$item" | sed -n 's/.*<domain>.*<name>\(.*\)<\/name>.*<\/domain>.*/\1/p')"
_domain_extension="$(echo "$item" | sed -n 's/.*<domain>.*<extension>\(.*\)<\/extension>.*<\/domain>.*/\1/p')"
_debug _domain_name "$_domain_name"
_debug _domain_extension "$_domain_extension"
if [ "$_domain_name.$_domain_extension" = "$h" ]; then
return 0
fi
done
total="$(echo "$response" | _egrep_o '<total>.*?<\/total>' | sed -n 's/.*<total>\(.*\)<\/total>.*/\1/p')"
_debug total "$total"
if [ "$results_retrieved" -eq "$total" ]; then
results_retrieved=0
i="$(_math "$i" + 1)"
fi
done
return 1
}
_openprovider_request() {
request_xml=$1
xml_prefix='<?xml version="1.0" encoding="UTF-8"?>'
xml_content=$(printf '<openXML><credentials><username>%s</username><hash>%s</hash></credentials>%s</openXML>' "$OPENPROVIDER_USER" "$OPENPROVIDER_PASSWORDHASH" "$request_xml")
response="$(_post "$(echo "$xml_prefix$xml_content" | tr -d '\n')" "$OPENPROVIDER_API" "" "POST" "application/xml")"
_debug response "$response"
if ! _contains "$response" "<openXML><reply><code>0</code>.*</reply></openXML>"; then
_err "API request failed."
return 1
fi
}

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env sh
#Applcation Key
#Application Key
#OVH_AK="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
#Application Secret
@@ -14,7 +14,7 @@
#'ovh-eu'
OVH_EU='https://eu.api.ovh.com/1.0'
#'ovh-ca':
#'ovh-ca':
OVH_CA='https://ca.api.ovh.com/1.0'
#'kimsufi-eu'
@@ -78,12 +78,9 @@ _ovh_get_api() {
esac
}
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_ovh_add() {
fulldomain=$1
txtvalue=$2
_initAuth() {
OVH_AK="${OVH_AK:-$(_readaccountconf_mutable OVH_AK)}"
OVH_AS="${OVH_AS:-$(_readaccountconf_mutable OVH_AS)}"
if [ -z "$OVH_AK" ] || [ -z "$OVH_AS" ]; then
OVH_AK=""
@@ -93,21 +90,26 @@ dns_ovh_add() {
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 [ "$OVH_AK" != "$(_readaccountconf OVH_AK)" ]; then
_info "It seems that your ovh key is changed, let's clear consumer key first."
_clearaccountconf OVH_CK
fi
_saveaccountconf_mutable OVH_AK "$OVH_AK"
_saveaccountconf_mutable OVH_AS "$OVH_AS"
OVH_END_POINT="${OVH_END_POINT:-$(_readaccountconf_mutable OVH_END_POINT)}"
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"
_saveaccountconf_mutable OVH_END_POINT "$OVH_END_POINT"
fi
OVH_API="$(_ovh_get_api $OVH_END_POINT)"
_debug OVH_API "$OVH_API"
OVH_CK="${OVH_CK:-$(_readaccountconf_mutable OVH_CK)}"
if [ -z "$OVH_CK" ]; then
_info "OVH consumer key is empty, Let's get one:"
if ! _ovh_authentication; then
@@ -119,14 +121,26 @@ dns_ovh_add() {
_info "Checking authentication"
response="$(_ovh_rest GET "domain/")"
if _contains "$response" "INVALID_CREDENTIAL"; then
if ! _ovh_rest GET "domain" || _contains "$response" "INVALID_CREDENTIAL" || _contains "$response" "NOT_CREDENTIAL"; then
_err "The consumer key is invalid: $OVH_CK"
_err "Please retry to create a new one."
_clearaccountconf OVH_CK
return 1
fi
_info "Consumer key is ok."
return 0
}
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_ovh_add() {
fulldomain=$1
txtvalue=$2
if ! _initAuth; then
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
@@ -137,49 +151,58 @@ dns_ovh_add() {
_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
_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
_ovh_rest POST "domain/zone/$_domain/refresh"
_debug "Refresh:$response"
_info "Added, sleeping 10 seconds"
sleep 10
return 0
fi
_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
_ovh_rest POST "domain/zone/$_domain/refresh"
_debug "Refresh:$response"
_info "Added, sleep 10 seconds."
_sleep 10
return 0
fi
_err "Add txt record error."
else
_info "Updating record"
record_id=$(printf "%s" "$response" | tr -d "[]" | cut -d , -f 1)
if [ -z "$record_id" ]; then
_err "Can not get record id."
return 1
fi
_debug "record_id" "$record_id"
if _ovh_rest PUT "domain/zone/$_domain/record/$record_id" "{\"target\":\"$txtvalue\",\"subDomain\":\"$_sub_domain\",\"ttl\":60}"; then
if _contains "$response" "null"; then
_ovh_rest POST "domain/zone/$_domain/refresh"
_debug "Refresh:$response"
_info "Updated, sleeping 10 seconds"
sleep 10
return 0
fi
fi
_err "Update error"
return 1
fi
_err "Add txt record error."
return 1
}
#fulldomain
dns_ovh_rm() {
fulldomain=$1
txtvalue=$2
if ! _initAuth; then
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
if ! _ovh_rest GET "domain/zone/$_domain/record?fieldType=TXT&subDomain=$_sub_domain"; then
return 1
fi
for rid in $(echo "$response" | tr '][,' ' '); do
_debug rid "$rid"
if ! _ovh_rest GET "domain/zone/$_domain/record/$rid"; then
return 1
fi
if _contains "$response" "\"target\":\"$txtvalue\""; then
_debug "Found txt id:$rid"
if ! _ovh_rest DELETE "domain/zone/$_domain/record/$rid"; then
return 1
fi
return 0
fi
done
return 1
}
#################### Private functions below ##################################
@@ -191,7 +214,7 @@ _ovh_authentication() {
_H3=""
_H4=""
_ovhdata='{"accessRules": [{"method": "GET","path": "/*"},{"method": "POST","path": "/*"},{"method": "PUT","path": "/*"},{"method": "DELETE","path": "/*"}],"redirection":"'$ovh_success'"}'
_ovhdata='{"accessRules": [{"method": "GET","path": "/auth/time"},{"method": "GET","path": "/domain"},{"method": "GET","path": "/domain/zone/*"},{"method": "GET","path": "/domain/zone/*/record"},{"method": "POST","path": "/domain/zone/*/record"},{"method": "POST","path": "/domain/zone/*/refresh"},{"method": "PUT","path": "/domain/zone/*/record/*"},{"method": "DELETE","path": "/domain/zone/*/record/*"}],"redirection":"'$ovh_success'"}'
response="$(_post "$_ovhdata" "$OVH_API/auth/credential")"
_debug3 response "$response"
@@ -207,7 +230,7 @@ _ovh_authentication() {
_err "Unable to get consumerKey"
return 1
fi
_debug consumerKey "$consumerKey"
_secure_debug consumerKey "$consumerKey"
OVH_CK="$consumerKey"
_saveaccountconf OVH_CK "$OVH_CK"
@@ -238,7 +261,7 @@ _get_root() {
return 1
fi
if ! _contains "$response" "This service does not exist" >/dev/null; then
if ! _contains "$response" "This service does not exist" >/dev/null && ! _contains "$response" "NOT_GRANTED_CALL" >/dev/null; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
return 0
@@ -269,7 +292,7 @@ _ovh_rest() {
_ovh_t="$(_ovh_timestamp)"
_debug2 _ovh_t "$_ovh_t"
_ovh_p="$OVH_AS+$OVH_CK+$m+$_ovh_url+$data+$_ovh_t"
_debug _ovh_p "$_ovh_p"
_secure_debug _ovh_p "$_ovh_p"
_ovh_hex="$(printf "%s" "$_ovh_p" | _digest sha1 hex)"
_debug2 _ovh_hex "$_ovh_hex"
@@ -279,15 +302,15 @@ _ovh_rest() {
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
if [ "$data" ] || [ "$m" = "POST" ] || [ "$m" = "PUT" ] || [ "$m" = "DELETE" ]; then
_debug data "$data"
response="$(_post "$data" "$_ovh_url" "" "$m")"
else
response="$(_get "$_ovh_url")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
if [ "$?" != "0" ] || _contains "$response" "INVALID_CREDENTIAL"; then
_err "error $response"
return 1
fi
_debug2 response "$response"

Some files were not shown because too many files have changed in this diff Show More