154 Commits
2.6.8 ... 2.7.2

Author SHA1 Message Date
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
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
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
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
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
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
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
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
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
shar0119
5c78e0a462 removed source acme.sh 2017-03-16 13:42:30 -07:00
shar0119
7044236824 Create dns_dynu.sh
Add DNS API support for Dynu.
2017-03-15 11:40:32 -07: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
16 changed files with 1058 additions and 124 deletions

View File

@@ -4,17 +4,17 @@ RUN apk update -f \
&& apk --no-cache add -f \
openssl \
curl \
netcat-openbsd
netcat-openbsd \
&& rm -rf /var/cache/apk/*
ENV LE_CONFIG_HOME /acme.sh
ENV AUTO_UPGRADE 1
#Install
RUN mkdir -p /install_acme.sh/
ADD ./ /install_acme.sh/
RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh)
RUN rm -rf /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
@@ -48,5 +48,14 @@ RUN for verb in help \
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
ENTRYPOINT ["/root/.acme.sh/acme.sh", "--config-home", "/acme.sh"]
RUN printf "%b" '#!'"/usr/bin/env sh\n \
if [ \"\$1\" = \"daemon\" ]; then \n \
crond -f\n \
else \n \
/root/.acme.sh/acme.sh --config-home /acme.sh \"\$@\"\n \
fi" >/entry.sh && chmod +x /entry.sh
VOLUME /acme.sh
ENTRYPOINT ["/entry.sh"]
CMD ["--help"]

View File

@@ -1,4 +1,6 @@
# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)
[![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.
- Simple, powerful and very easy to use. You only need 3 minutes to learn it.
@@ -8,8 +10,9 @@
- Just one script to issue, renew and install your certificates automatically.
- DOES NOT require `root/sudoer` access.
- Docker friendly
- IPv6 support
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
@@ -31,6 +34,7 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
- [Centminmod](http://centminmod.com/letsencrypt-acmetool-https.html)
- [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297)
- [archlinux](https://aur.archlinux.org/packages/acme.sh-git/)
- [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient)
- [more...](https://github.com/Neilpang/acme.sh/wiki/Blogs-and-tutorials)
# Tested OS
@@ -58,7 +62,7 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
|19|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/gentoo-stage3-amd64.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Gentoo Linux
|20|[![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)|Mac OSX
For all build statuses, check our [daily build project](https://github.com/Neilpang/acmetest):
For all build statuses, check our [weekly build project](https://github.com/Neilpang/acmetest):
https://github.com/Neilpang/acmetest
@@ -135,13 +139,25 @@ 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.
@@ -183,7 +199,7 @@ The ownership and permission info of existing files are preserved. You may want
Install/copy the issued cert/key to the production Apache or Nginx path.
The cert will be `renewed every **60** days by default` (which is configurable). Once the cert is renewed, the Apache/Nginx service will be restarted automatically by the command: `service apache2 restart` or `service nginx restart`.
The cert will be renewed every **60** days by default (which is configurable). Once the cert is renewed, the Apache/Nginx service will be reloaded automatically by the command: `service apache2 force-reload` or `service nginx force-reload`.
# 4. Use Standalone server to issue cert
@@ -293,14 +309,12 @@ You don't have to do anything manually!
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. OVH, kimsufi, soyoustart and runabove API
1. nsupdate API
1. LuaDNS.com API
1. DNSMadeEasy.com API
1. nsupdate API
1. AWS Route 53
1. aliyun.com(阿里云) API
1. ISPConfig 3.1 API
1. Alwaysdata.com API
@@ -313,7 +327,20 @@ You don't have to do anything manually!
1. DigitalOcean API (native)
1. ClouDNS.net API
1. Infoblox NIOS API (https://www.infoblox.com/)
1. VSCALE (https://vscale.io/)
1. Dynu API (https://www.dynu.com)
1. DNSimple API
1. NS1.com API
And:
1. lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api
(DigitalOcean, DNSimple, DNSMadeEasy, DNSPark, EasyDNS, Namesilo, NS1, PointHQ, Rage4 and Vultr etc.)
**More APIs coming soon...**
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.

180
acme.sh
View File

@@ -1,6 +1,6 @@
#!/usr/bin/env sh
VER=2.6.8
VER=2.7.2
PROJECT_NAME="acme.sh"
@@ -104,21 +104,21 @@ if [ -t 1 ]; then
fi
__green() {
if [ "$__INTERACTIVE" ]; then
if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" ]; then
printf '\033[1;31;32m'
fi
printf -- "%b" "$1"
if [ "$__INTERACTIVE" ]; then
if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" ]; then
printf '\033[0m'
fi
}
__red() {
if [ "$__INTERACTIVE" ]; then
if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" ]; then
printf '\033[1;31;40m'
fi
printf -- "%b" "$1"
if [ "$__INTERACTIVE" ]; then
if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" ]; then
printf '\033[0m'
fi
}
@@ -151,6 +151,13 @@ _dlg_versions() {
echo "apache doesn't exists."
fi
echo "nginx:"
if _exists "nginx"; then
nginx -V 2>&1
else
echo "nginx doesn't exists."
fi
echo "nc:"
if _exists "nc"; then
nc -h 2>&1
@@ -166,7 +173,14 @@ _syslog() {
fi
_logclass="$1"
shift
logger -i -t "$PROJECT_NAME" -p "$_logclass" "$(_printargs "$@")" >/dev/null 2>&1
if [ -z "$__logger_i" ]; then
if _contains "$(logger --help 2>&1)" "-i"; then
__logger_i="logger -i"
else
__logger_i="logger"
fi
fi
$__logger_i -t "$PROJECT_NAME" -p "$_logclass" "$(_printargs "$@")" >/dev/null 2>&1
}
_log() {
@@ -347,7 +361,7 @@ _hasfield() {
fi
done
_debug2 "'$_str' does not contain '$_field'"
return 1 #not contains
return 1 #not contains
}
_getfield() {
@@ -436,34 +450,48 @@ if [ "$(printf '\x41')" != 'A' ]; then
_URGLY_PRINTF=1
fi
_h2b() {
hex=$(cat)
i=1
j=2
_ESCAPE_XARGS=""
if [ "$(printf %s '\\x41' | xargs printf)" = 'A' ]; then
_ESCAPE_XARGS=1
fi
_debug3 _URGLY_PRINTF "$_URGLY_PRINTF"
while true; do
if [ -z "$_URGLY_PRINTF" ]; then
h="$(printf "%s" "$hex" | cut -c $i-$j)"
if [ -z "$h" ]; then
break
fi
printf "\x$h%s"
_h2b() {
if _exists xxd; then
xxd -r -p
return
fi
hex=$(cat)
ic=""
jc=""
_debug2 _URGLY_PRINTF "$_URGLY_PRINTF"
if [ -z "$_URGLY_PRINTF" ]; then
if [ "$_ESCAPE_XARGS" ] && _exists xargs; then
_debug2 "xargs"
echo "$hex" | _upper_case | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/g' | xargs printf
else
ic="$(printf "%s" "$hex" | cut -c $i)"
jc="$(printf "%s" "$hex" | cut -c $j)"
if [ -z "$ic$jc" ]; then
break
for h in $(echo "$hex" | _upper_case | sed 's/\([0-9A-F]\{2\}\)/ \1/g'); do
if [ -z "$h" ]; then
break
fi
printf "\x$h%s"
done
fi
else
for c in $(echo "$hex" | _upper_case | sed 's/\([0-9A-F]\)/ \1/g'); do
if [ -z "$ic" ]; then
ic=$c
continue
fi
jc=$c
ic="$(_h_char_2_dec "$ic")"
jc="$(_h_char_2_dec "$jc")"
printf '\'"$(printf "%o" "$(_math "$ic" \* 16 + $jc)")""%s"
fi
ic=""
jc=""
done
fi
i="$(_math "$i" + 2)"
j="$(_math "$j" + 2)"
done
}
_is_solaris() {
@@ -722,7 +750,7 @@ _url_encode() {
"7e")
printf "%s" "~"
;;
#other hex
#other hex
*)
printf '%%%s' "$_hex_code"
;;
@@ -1025,7 +1053,7 @@ _createcsr() {
else
alt="DNS:$domainlist"
fi
#multi
#multi
_info "Multi domain" "$alt"
printf -- "\nsubjectAltName=$alt" >>"$csrconf"
fi
@@ -1065,7 +1093,7 @@ _readSubjectFromCSR() {
_usage "_readSubjectFromCSR mycsr.csr"
return 1
fi
${ACME_OPENSSL_BIN:-openssl} req -noout -in "$_csrfile" -subject | _egrep_o "CN *=.*" | cut -d = -f 2 | cut -d / -f 1 | tr -d '\n'
${ACME_OPENSSL_BIN:-openssl} req -noout -in "$_csrfile" -subject | tr ',' "\n" | _egrep_o "CN *=.*" | cut -d = -f 2 | cut -d / -f 1 | tr -d ' \n'
}
#_csrfile
@@ -1093,7 +1121,7 @@ _readSubjectAltNamesFromCSR() {
printf "%s" "$_dnsAltnames" | sed "s/DNS://g"
}
#_csrfile
#_csrfile
_readKeyLengthFromCSR() {
_csrfile="$1"
if [ -z "$_csrfile" ]; then
@@ -1108,7 +1136,7 @@ _readKeyLengthFromCSR() {
echo "$_outcsr" | tr "\t" " " | _egrep_o "^ *ASN1 OID:.*" | cut -d ':' -f 2 | tr -d ' '
else
_debug "RSA CSR"
echo "$_outcsr" | tr "\t" " " | _egrep_o "(^ *|RSA )Public.Key:.*" | cut -d '(' -f 2 | cut -d ' ' -f 1
echo "$_outcsr" | tr "\t" " " | (_egrep_o "^ *Public.Key:.*" || _egrep_o "RSA Public.Key:.*") | cut -d '(' -f 2 | cut -d ' ' -f 1
fi
}
@@ -1192,7 +1220,7 @@ toPkcs8() {
}
#[2048]
#[2048]
createAccountKey() {
_info "Creating account key"
if [ -z "$1" ]; then
@@ -1237,17 +1265,20 @@ createDomainKey() {
fi
domain=$1
length=$2
_cdl=$2
if [ -z "$length" ]; then
if [ -z "$_cdl" ]; then
_debug "Use DEFAULT_DOMAIN_KEY_LENGTH=$DEFAULT_DOMAIN_KEY_LENGTH"
length="$DEFAULT_DOMAIN_KEY_LENGTH"
_cdl="$DEFAULT_DOMAIN_KEY_LENGTH"
fi
_initpath "$domain" "$length"
_initpath "$domain" "$_cdl"
if [ ! -f "$CERT_KEY_PATH" ] || ([ "$FORCE" ] && ! [ "$IS_RENEW" ]); then
_createkey "$length" "$CERT_KEY_PATH"
if _createkey "$_cdl" "$CERT_KEY_PATH"; then
_savedomainconf Le_Keylength "$_cdl"
_info "The domain key is here: $(__green $CERT_KEY_PATH)"
fi
else
if [ "$IS_RENEW" ]; then
_info "Domain key exists, skip"
@@ -1702,7 +1733,7 @@ _send_signed_request() {
nonce="$_CACHED_NONCE"
_debug2 nonce "$nonce"
protected="$JWK_HEADERPLACE_PART1$nonce$JWK_HEADERPLACE_PART2"
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2"
_debug3 protected "$protected"
protected64="$(printf "%s" "$protected" | _base64 | _url_replace)"
@@ -1847,6 +1878,24 @@ _saveaccountconf() {
_save_conf "$ACCOUNT_CONF_PATH" "$1" "$2"
}
#key value
_saveaccountconf_mutable() {
_save_conf "$ACCOUNT_CONF_PATH" "SAVED_$1" "$2"
#remove later
_clearaccountconf "$1"
}
#key
_readaccountconf() {
_read_conf "$ACCOUNT_CONF_PATH" "$1"
}
#key
_readaccountconf_mutable() {
_rac_key="$1"
_readaccountconf "SAVED_$_rac_key"
}
#_clearaccountconf key
_clearaccountconf() {
_clear_conf "$ACCOUNT_CONF_PATH" "$1"
@@ -2528,7 +2577,7 @@ _setNginx() {
location ~ \"^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)\$\" {
default_type text/plain;
return 200 \"\$1.$_thumbpt\";
}
}
#NGINX_START
" >>"$FOUND_REAL_NGINX_CONF"
@@ -2537,7 +2586,7 @@ location ~ \"^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)\$\" {
_err "write nginx conf error, but don't worry, the file is restored."
return 1
fi
_debug3 "Modified config:$(cat $FOUND_REAL_NGINX_CONF)"
_info "nginx conf is done, let's check it again."
if ! _exec "nginx -t" >/dev/null; then
_exec_err
@@ -2599,10 +2648,10 @@ _checkConf() {
_isRealNginxConf() {
_debug "_isRealNginxConf $1 $2"
if [ -f "$2" ]; then
for _fln in $(grep -n "^ *server_name.* $1" "$2" | cut -d : -f 1); do
for _fln in $(tr "\t" ' ' <"$2" | grep -n "^ *server_name.* $1" | cut -d : -f 1); do
_debug _fln "$_fln"
if [ "$_fln" ]; then
_start=$(cat "$2" | _head_n "$_fln" | grep -n "^ *server *{" | _tail_n 1)
_start=$(tr "\t" ' ' <"$2" | _head_n "$_fln" | grep -n "^ *server *{" | _tail_n 1)
_debug "_start" "$_start"
_start_n=$(echo "$_start" | cut -d : -f 1)
_start_nn=$(_math $_start_n + 1)
@@ -2611,8 +2660,8 @@ _isRealNginxConf() {
_left="$(sed -n "${_start_nn},99999p" "$2")"
_debug2 _left "$_left"
if echo "$_left" | grep -n "^ *server *{" >/dev/null; then
_end=$(echo "$_left" | grep -n "^ *server *{" | _head_n 1)
if echo "$_left" | tr "\t" ' ' | grep -n "^ *server *{" >/dev/null; then
_end=$(echo "$_left" | tr "\t" ' ' | grep -n "^ *server *{" | _head_n 1)
_debug "_end" "$_end"
_end_n=$(echo "$_end" | cut -d : -f 1)
_debug "_end_n" "$_end_n"
@@ -2623,12 +2672,14 @@ _isRealNginxConf() {
_debug "_seg_n" "$_seg_n"
if [ "$(echo "$_seg_n" | _egrep_o "^ *ssl *on *;")" ]; then
if [ "$(echo "$_seg_n" | _egrep_o "^ *ssl *on *;")" ] \
|| [ "$(echo "$_seg_n" | _egrep_o "listen .* ssl[ |;]")" ]; then
_debug "ssl on, skip"
return 1
else
FOUND_REAL_NGINX_CONF_LN=$_fln
_debug3 "found FOUND_REAL_NGINX_CONF_LN" "$FOUND_REAL_NGINX_CONF_LN"
return 0
fi
FOUND_REAL_NGINX_CONF_LN=$_fln
return 0
fi
done
fi
@@ -2679,7 +2730,7 @@ _clearup() {
_clearupdns() {
_debug "_clearupdns"
if [ "$dnsadded" != 1 ] || [ -z "$vlist" ]; then
_debug "Dns not added, skip."
_debug "skip dns."
return
fi
@@ -3115,7 +3166,7 @@ __trigger_validation() {
_send_signed_request "$_t_url" "{\"resource\": \"challenge\", \"keyAuthorization\": \"$_t_key_authz\"}"
}
#webroot, domain domainlist keylength
#webroot, domain domainlist keylength
issue() {
if [ -z "$2" ]; then
_usage "Usage: $PROJECT_ENTRY --issue -d a.com -w /path/to/webroot/a.com/ "
@@ -3648,7 +3699,7 @@ issue() {
#if ! _get "$Le_LinkCert" | _base64 "multiline" >> "$CERT_PATH" ; then
# _debug "Get cert failed. Let's try last response."
# printf -- "%s" "$_rcert" | _dbase64 "multiline" | _base64 "multiline" >> "$CERT_PATH"
# printf -- "%s" "$_rcert" | _dbase64 "multiline" | _base64 "multiline" >> "$CERT_PATH"
#fi
if ! printf -- "%s" "$_rcert" | _dbase64 "multiline" | _base64 "multiline" >>"$CERT_PATH"; then
@@ -3889,6 +3940,10 @@ signcsr() {
return 1
fi
_debug _csrsubj "$_csrsubj"
if _contains "$_csrsubj" ' ' || ! _contains "$_csrsubj" '.'; then
_info "It seems that the subject: $_csrsubj is not a valid domain name. Drop it."
_csrsubj=""
fi
_csrdomainlist=$(_readSubjectAltNamesFromCSR "$_csrfile")
if [ "$?" != "0" ]; then
@@ -4596,6 +4651,11 @@ install() {
return 1
fi
if [ -z "$_c_home" ] && [ "$LE_CONFIG_HOME" != "$LE_WORKING_DIR" ]; then
_info "Using config home: $LE_CONFIG_HOME"
_c_home="$LE_CONFIG_HOME"
fi
#convert from le
if [ -d "$HOME/.le" ]; then
for envfile in "le.env" "le.sh.env"; do
@@ -4789,7 +4849,7 @@ Commands:
--create-domain-key Create an domain private key, professional use.
--createCSR, -ccsr Create CSR , professional use.
--deactivate Deactivate the domain authz, professional use.
Parameters:
--domain, -d domain.tld Specifies a domain, used to issue, renew or revoke etc.
--force, -f Used to force to install or force to renew a cert immediately.
@@ -4803,20 +4863,20 @@ Parameters:
--apache Use apache mode.
--dns [dns_cf|dns_dp|dns_cx|/path/to/api/file] Use dns mode or dns api.
--dnssleep [$DEFAULT_DNS_SLEEP] The time in seconds to wait for all the txt records to take effect in dns api mode. Default $DEFAULT_DNS_SLEEP seconds.
--keylength, -k [2048] Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384.
--accountkeylength, -ak [2048] Specifies the account key length.
--log [/path/to/logfile] Specifies the log file. The default is: \"$DEFAULT_LOG_FILE\" if you don't give a file path here.
--log-level 1|2 Specifies the log level, default is 1.
--syslog [0|3|6|7] Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug.
These parameters are to install the cert to nginx/apache or anyother server after issue/renew a cert:
--cert-file After issue/renew, the cert will be copied to this path.
--key-file After issue/renew, the key will be copied to this path.
--ca-file After issue/renew, the intermediate cert will be copied to this path.
--fullchain-file After issue/renew, the fullchain cert will be copied to this path.
--reloadcmd \"service nginx reload\" After issue/renew, it's used to reload the server.
--accountconf Specifies a customized account config file.
@@ -4836,6 +4896,7 @@ Parameters:
--ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate.
--ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl.
--nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically.
--no-color Do not output color text.
--ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR'
--csr Specifies the input csr.
--pre-hook Command to be run before obtaining any certificates.
@@ -5283,6 +5344,9 @@ _process() {
--nocron)
_nocron="1"
;;
--no-color)
export ACME_NO_COLOR=1
;;
--ecc)
_ecc="isEcc"
;;

View File

@@ -21,8 +21,11 @@ acme.sh --deploy -d example.com --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).
Currently supports Kong-v0.10.x.
(TODO)
```sh
acme.sh --deploy -d ftp.example.com --deploy-hook kong
```
## 3. Deploy the cert to remote server through SSH access.

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,14 +25,15 @@ 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"
@@ -48,12 +43,14 @@ kong_deploy() {
#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,17 +58,16 @@ 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
if ! [ "$(echo "$response" | _egrep_o "created_at")" = "created_at" ]; then
_err "An error occurred with cert upload. Check response:"
_err "$response"
return 1

View File

@@ -140,7 +140,7 @@ Finally, make the DNS server and update Key available to `acme.sh`
```
export NSUPDATE_SERVER="dns.example.com"
export NSUPDATE_KEY="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=="
export NSUPDATE_KEY="/path/to/your/nsupdate.key"
```
Ok, let's issue a cert now:
@@ -422,22 +422,89 @@ acme.sh --issue --dns dns_cloudns -d example.com -d www.example.com
```
## 22. Use Infoblox API
First you need to create/obtain API credentials on your Infoblox appliance.
```
export Infoblox_Creds="username:password"
export Infoblox_Server="ip or fqdn of infoblox appliance"
```
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_infoblox -d example.com -d www.example.com
```
Note: This script will automatically create and delete the ephemeral txt record.
The `Infoblox_Creds` and `Infoblox_Server` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 23. Use VSCALE API
First you need to create/obtain API tokens on your [settings panel](https://vscale.io/panel/settings/tokens/).
```
VSCALE_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje"
```
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_vscale -d example.com -d www.example.com
```
## 24. Use Dynu API
First you need to create/obtain API credentials from your Dynu account. See: https://www.dynu.com/resources/api/documentation
```
export Dynu_ClientId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export Dynu_Secret="yyyyyyyyyyyyyyyyyyyyyyyyy"
```
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_dynu -d example.com -d www.example.com
```
The `Dynu_ClientId` and `Dynu_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 25. Use DNSimple API
First you need to login to your DNSimple account and generate a new oauth token.
https://dnsimple.com/a/{your account id}/account/access_tokens
Note that this is an _account_ token and not a user token. The account token is
needed to infer the `account_id` used in requests. A user token will not be able
to determine the correct account to use.
```
export DNSimple_OAUTH_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje"
```
To issue the cert just specify the `dns_dnsimple` API.
```
acme.sh --issue --dns dns_dnsimple -d example.com
```
The `DNSimple_OAUTH_TOKEN` will be saved in `~/.acme.sh/account.conf` and will
be reused when needed.
If you have any issues with this integration please report them to
https://github.com/pho3nixf1re/acme.sh/issues.
## 26. Use NS1.com API
```
export NS1_Key="fdmlfsdklmfdkmqsdfk"
```
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_nsone -d example.com -d www.example.com
```
# Use custom API
If your API is not supported yet, you can write your own DNS API.

View File

@@ -106,7 +106,7 @@ _get_root() {
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."

View File

@@ -14,6 +14,8 @@ dns_cf_add() {
fulldomain=$1
txtvalue=$2
CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}"
CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}"
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
CF_Key=""
CF_Email=""
@@ -29,8 +31,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"
_saveaccountconf_mutable CF_Key "$CF_Key"
_saveaccountconf_mutable CF_Email "$CF_Email"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
@@ -83,6 +85,17 @@ dns_cf_add() {
dns_cf_rm() {
fulldomain=$1
txtvalue=$2
CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}"
CF_Email="${CF_Email:-$(_readaccountconf_mutable 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."
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"

215
dnsapi/dns_dnsimple.sh Normal file
View File

@@ -0,0 +1,215 @@
#!/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"
if [ "$_records_count" = "0" ]; then
_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."
else
_info "Updating record"
_extract_record_id "$_records" "$_sub_domain"
if _dnsimple_rest \
PATCH \
"$_account_id/zones/$_domain/records/$_record_id" \
"{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
_info "Updated!"
return 0
fi
_err "Update error"
return 1
fi
}
# 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
if _dnsimple_rest DELETE "$_account_id/zones/$_domain/records/$_record_id"; then
_info "removed record" "$_record_id"
return 0
fi
fi
_err "failed to remove record" "$_record_id"
return 1
}
#################### 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=100"
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
}

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/v1"
#
#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/record/add" "{\"domain_name\":\"$_domain_name\",\"node_name\":\"$_node\",\"record_type\":\"TXT\",\"text_data\":\"$txtvalue\",\"state\":true,\"ttl\":90}"; then
return 1
fi
if ! _contains "$response" "text_data"; 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/get/$h"; then
return 1
fi
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
_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/record/get?hostname=$fulldomain&rrtype=TXT"; then
return 1
fi
if ! _contains "$response" "$txtvalue"; then
_dns_record_id=0
return 0
fi
_dns_record_id=$(printf "%s" "$response" | _egrep_o "{[^}]*}" | grep "\"text_data\":\"$txtvalue\"" | _egrep_o ",[^,]*," | grep ',"id":' | tr -d ",," | cut -d : -f 2)
return 0
}
_delete_txt_record() {
_dns_record_id=$1
if ! _dynu_rest GET "dns/record/delete/$_dns_record_id"; then
return 1
fi
if ! _contains "$response" "true"; 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" ]; 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" "accessToken"; then
Dynu_Token=$(printf "%s" "$response" | tr -d "[]" | cut -d , -f 2 | cut -d : -f 2 | cut -d '"' -f 2)
fi
if _contains "$Dynu_Token" "null"; then
Dynu_Token=""
fi
_debug2 response "$response"
return 0
}

View File

@@ -53,7 +53,7 @@ dns_freedns_add() {
i="$(_math "$i" - 1)"
sub_domain="$(echo "$fulldomain" | cut -d. -f -"$i")"
# Sometimes FreeDNS does not return the subdomain page but rather
# 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
@@ -72,7 +72,7 @@ dns_freedns_add() {
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
# 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' \
@@ -196,7 +196,7 @@ dns_freedns_rm() {
FREEDNS_COOKIE="$(_read_conf "$ACCOUNT_CONF_PATH" "FREEDNS_COOKIE")"
_debug "FreeDNS login cookies: $FREEDNS_COOKIE"
# Sometimes FreeDNS does not return the subdomain page but rather
# 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

View File

@@ -37,7 +37,7 @@ dns_gandi_livedns_add() {
_debug sub_domain "$_sub_domain"
_gandi_livedns_rest PUT "domains/$_domain/records/$_sub_domain/TXT" "{\"rrset_ttl\": 300, \"rrset_values\":[\"$txtvalue\"]}" \
&& _contains "$response" '{"message": "Zone Record Created"}' \
&& _contains "$response" '{"message": "DNS Record Created"}' \
&& _info "Add $(__green "success")"
}

View File

@@ -9,7 +9,7 @@ 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"
baseurlnObject="https://$Infoblox_Server/wapi/v2.2.2/record:txt?name=$fulldomain&text=$txtvalue&view=$Infoblox_View"
_info "Using Infoblox API"
_debug fulldomain "$fulldomain"
@@ -19,14 +19,19 @@ dns_infoblox_add() {
if [ -z "$Infoblox_Creds" ] || [ -z "$Infoblox_Server" ]; then
Infoblox_Creds=""
Infoblox_Server=""
_err "You didn't specify the credentials or server yet (Infoblox_Creds and Infoblox_Server)."
_err "Please set them via EXPORT ([username:password] and [ip or hostname]) and try again."
_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)
@@ -39,7 +44,7 @@ dns_infoblox_add() {
result=$(_post "" "$baseurlnObject" "" "POST")
## Let's see if we get something intelligible back from the unit
if echo "$result" | egrep 'record:txt/.*:.*/default'; then
if echo "$result" | egrep "record:txt/.*:.*/$Infoblox_View"; then
_info "Successfully created the txt record"
return 0
else
@@ -68,18 +73,18 @@ dns_infoblox_rm() {
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&_return_type=xml-pretty"
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 'record:txt/.*:.*/default'; then
if echo "$result" | egrep "record:txt/.*:.*/$Infoblox_View"; then
## Extract the object reference
objRef=$(printf "%b" "$result" | _egrep_o 'record:txt/.*:.*/default')
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 'record:txt/.*:.*/default'; then
if echo "$rmResult" | egrep "record:txt/.*:.*/$Infoblox_View"; then
_info "Successfully deleted $objRef"
return 0
else

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\"}"; then
if _contains "$response" "$fulldomain"; then
_info "Added"
#todo: check if the record takes effect
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
else
_info "Updating record"
record_id=$(printf "%s\n" "$response" | _egrep_o "\"domain\":\"$fulldomain.\",[^{]*\"type\":\"TXT\",\"id\":\"[^,]*\"" | _head_n 1 | cut -d: -f7 | cut -d, -f1)
_debug "record_id" "$record_id"
_nsone_rest POST "zones/$_domain/$fulldomain/TXT" "{\"answers\": [{\"answer\": [\"$txtvalue\"]}],\"type\": \"TXT\",\"domain\":\"$fulldomain\",\"zone\": \"$_domain\"}"
if [ "$?" = "0" ] && _contains "$response" "$fulldomain"; then
_info "Updated!"
#todo: check if the record takes effect
return 0
fi
_err "Update error"
return 1
fi
}
#fulldomain
dns_nsone_rm() {
fulldomain=$1
txtvalue=$2
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_nsone_rest GET "zones/${_domain}/$fulldomain/TXT"
count=$(printf "%s\n" "$response" | _egrep_o "\"domain\":\"$fulldomain\",.*\"type\":\"TXT\"" | wc -l | tr -d " ")
_debug count "$count"
if [ "$count" = "0" ]; then
_info "Don't need to remove."
else
if ! _nsone_rest DELETE "zones/${_domain}/$fulldomain/TXT"; then
_err "Delete record error."
return 1
fi
_contains "$response" ""
fi
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
# _domain_id=sdjkglgdfewsdfg
_get_root() {
domain=$1
i=2
p=1
if ! _nsone_rest GET "zones"; then
return 1
fi
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
if _contains "$response" "\"zone\":\"$h\""; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_nsone_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
export _H1="Accept: application/json"
export _H2="X-NSONE-Key: $NS1_Key"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$NS1_Api/$ep" "" "$m")"
else
response="$(_get "$NS1_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

View File

@@ -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'
@@ -119,7 +119,7 @@ dns_ovh_add() {
_info "Checking authentication"
response="$(_ovh_rest GET "domain/")"
response="$(_ovh_rest GET "domain")"
if _contains "$response" "INVALID_CREDENTIAL"; then
_err "The consumer key is invalid: $OVH_CK"
_err "Please retry to create a new one."
@@ -191,7 +191,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/*"}],"redirection":"'$ovh_success'"}'
response="$(_post "$_ovhdata" "$OVH_API/auth/credential")"
_debug3 response "$response"
@@ -238,7 +238,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

149
dnsapi/dns_vscale.sh Executable file
View File

@@ -0,0 +1,149 @@
#!/usr/bin/env sh
#This is the vscale.io api wrapper for acme.sh
#
#Author: Alex Loban
#Report Bugs here: https://github.com/LAV45/acme.sh
#VSCALE_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje"
VSCALE_API_URL="https://api.vscale.io/v1"
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_vscale_add() {
fulldomain=$1
txtvalue=$2
if [ -z "$VSCALE_API_KEY" ]; then
VSCALE_API_KEY=""
_err "You didn't specify the VSCALE api key yet."
_err "Please create you key and try again."
return 1
fi
_saveaccountconf VSCALE_API_KEY "$VSCALE_API_KEY"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_vscale_tmpl_json="{\"type\":\"TXT\",\"name\":\"$_sub_domain.$_domain\",\"content\":\"$txtvalue\"}"
if _vscale_rest POST "domains/$_domain_id/records/" "$_vscale_tmpl_json"; then
response=$(printf "%s\n" "$response" | _egrep_o "{\"error\": \".+\"" | cut -d : -f 2)
if [ -z "$response" ]; then
_info "txt record updated success."
return 0
fi
fi
return 1
}
#fulldomain txtvalue
dns_vscale_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"
_vscale_rest GET "domains/$_domain_id/records/"
if [ -n "$response" ]; then
record_id=$(printf "%s\n" "$response" | _egrep_o "\"TXT\", \"id\": [0-9]+, \"name\": \"$_sub_domain.$_domain\"" | cut -d : -f 2 | tr -d ", \"name\"")
_debug record_id "$record_id"
if [ -z "$record_id" ]; then
_err "Can not get record id to remove."
return 1
fi
if _vscale_rest DELETE "domains/$_domain_id/records/$record_id" && [ -z "$response" ]; then
_info "txt record deleted success."
return 0
fi
_debug response "$response"
return 1
fi
return 1
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
# _domain_id=12345
_get_root() {
domain=$1
i=2
p=1
if _vscale_rest GET "domains/"; then
response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
hostedzone="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$h\".*}")"
if [ "$hostedzone" ]; then
_domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
return 1
fi
p=$i
i=$(_math "$i" + 1)
done
fi
return 1
}
#method uri qstr data
_vscale_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="X-Token: ${VSCALE_API_KEY}"
if [ "$mtd" != "GET" ]; then
# both POST and DELETE.
_debug data "$data"
response="$(_post "$data" "$VSCALE_API_URL/$ep" "" "$mtd")"
else
response="$(_get "$VSCALE_API_URL/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}