1
0
mirror of https://github.com/hiskang/acme.sh synced 2025-07-08 14:56:09 +00:00

Compare commits

...

225 Commits

Author SHA1 Message Date
hiska
408ca03c3f Merge remote-tracking branch 'upstream/dev' 2018-02-09 12:07:00 +09: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
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
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
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
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
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
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
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
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
24 changed files with 2566 additions and 532 deletions

View File

@ -1,10 +1,14 @@
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
@ -18,20 +22,10 @@ addons:
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 ACME_OPENSSL_BIN="/usr/local/openssl";
openssl version 2>&1 || true;
$ACME_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
@ -43,7 +37,7 @@ script:
- 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" = "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

View File

@ -1,10 +1,10 @@
FROM alpine
FROM alpine:3.6
RUN apk update -f \
&& apk --no-cache add -f \
openssl \
curl \
netcat-openbsd \
socat \
&& rm -rf /var/cache/apk/*
ENV LE_CONFIG_HOME /acme.sh
@ -16,7 +16,7 @@ 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 | sed 's#> /dev/null##' | crontab -
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 \

148
README.md
View File

@ -3,6 +3,8 @@
[![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.
@ -127,7 +129,7 @@ Ok, you are ready to issue certs now.
Show help message:
```
```sh
root@v1:~# acme.sh -h
```
@ -164,16 +166,16 @@ 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:
@ -195,9 +197,9 @@ acme.sh --install-cert -d example.com \
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 reloaded automatically by the command: `service apache2 force-reload` or `service nginx force-reload`.
@ -240,7 +242,7 @@ Particularly, if you are running an Apache server, you should use Apache mode in
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
```
@ -260,47 +262,13 @@ It will configure nginx server automatically to verify the domain and then resto
So, the config is not changed.
```
```sh
acme.sh --issue --nginx -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
# 8. Use DNS mode:
Support the `dns-01` challenge.
```bash
acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com
```
You should get an output like below:
```
Add the following txt record:
Domain:_acme-challenge.example.com
Txt value:9ihDbjYfTExAYeDs4DBUeuTo18KBzwvTEjUnSwd32-c
Add the following txt record:
Domain:_acme-challenge.www.example.com
Txt value:9ihDbjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Please add those txt records to the domains. Waiting for the dns to take effect.
```
Then just rerun with `renew` argument:
```bash
acme.sh --renew -d example.com
```
Ok, it's finished.
**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.**
**Please use dns api mode instead.**
# 9. Automatic DNS API integration
# 8. Automatic DNS API integration
If your DNS provider supports API access, we can use that API to automatically issue the certs.
@ -339,7 +307,13 @@ You don't have to do anything manually!
1. Dyn Managed DNS API
1. Yandex PDD API (https://pdd.yandex.ru)
1. Hurricane Electric DNS service (https://dns.he.net)
1. UnoEuro API (https://www.unoeuro.com/)
1. INWX (https://www.inwx.de/)
1. Servercow (https://servercow.de)
1. Namesilo (https://www.namesilo.com)
1. InternetX autoDNS API (https://internetx.com)
1. Azure DNS
1. selectel.com(selectel.ru) DNS API
And:
@ -354,6 +328,39 @@ If your DNS provider is not on the supported list above, you can write your own
For more details: [How to use DNS API](dnsapi)
# 9. Use DNS manual mode:
If your dns provider doesn't support any api access, you will have to add the txt record by your hand.
```bash
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
Add the following txt record:
Domain:_acme-challenge.www.example.com
Txt value:9ihDbjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Please add those txt records to the domains. Waiting for the dns to take effect.
```
Then just rerun with `renew` argument:
```bash
acme.sh --renew -d example.com
```
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.**
**Please use dns api mode instead.**
# 10. Issue ECC certificates
@ -386,36 +393,60 @@ Valid values are:
3. **ec-521 (secp521r1, "ECDSA P-521", which is not supported by Let's Encrypt yet.)**
# 11. 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
```
# 12. 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
```
@ -423,31 +454,30 @@ Then **acme.sh** will be kept up to date automatically.
Disable auto upgrade:
```
```sh
acme.sh --upgrade --auto-upgrade 0
```
# 13. 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
# 14. Under the Hood
# 16. Under the Hood
Speak ACME language using shell, directly to "Let's Encrypt".
TODO:
# 15. Acknowledgments
# 17. 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
# 16. License & Others
# 18. License & Others
License is GPLv3
@ -456,7 +486,7 @@ 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.
# 17. Donate
# 19. Donate
Your donation makes **acme.sh** better:
1. PayPal/Alipay(支付宝)/Wechat(微信): [https://donate.acme.sh/](https://donate.acme.sh/)

814
acme.sh

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,9 @@ Before you can deploy your cert, you must [issue the cert first](https://github.
Here are the scripts to deploy the certs/key to the server/services.
## 1. Deploy the certs to your cpanel host.
## 1. Deploy the certs to your cpanel host
If you want to deploy using cpanel UAPI see 7.
(cpanel deploy hook is not finished yet, this is just an example.)
@ -18,7 +20,7 @@ export DEPLOY_CPANEL_PASSWORD=PASSWORD
acme.sh --deploy -d example.com --deploy-hook cpanel
```
## 2. Deploy ssl cert on kong proxy engine based on api.
## 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.
@ -27,11 +29,11 @@ Currently supports Kong-v0.10.x.
acme.sh --deploy -d ftp.example.com --deploy-hook kong
```
## 3. Deploy the cert to remote server through SSH access.
## 3. Deploy the cert to remote server through SSH access
(TODO)
## 4. Deploy the cert to local vsftpd server.
## 4. Deploy the cert to local vsftpd server
```sh
acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd
@ -53,7 +55,7 @@ export DEPLOY_VSFTPD_RELOAD="/etc/init.d/vsftpd restart"
acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd
```
## 5. Deploy the cert to local exim4 server.
## 5. Deploy the cert to local exim4 server
```sh
acme.sh --deploy -d ftp.example.com --deploy-hook exim4
@ -81,20 +83,36 @@ acme.sh --deploy -d ftp.example.com --deploy-hook exim4
acme.sh --deploy -d ftp.example.com --deploy-hook keychain
```
## 7. Deploy to cpanel host.
## 7. Deploy to cpanel host using UAPI
This hook is using UAPI and works in cPanel & WHM version 56 or newer.
```
acme.sh --deploy -d example.com --deploy-hook cpanel_uapi
```
If you are login as root, please specify the username to deploy cert to:
DEPLOY_CPANEL_USER is required only if you run the script as root and it should contain cpanel username.
```sh
export DEPLOY_CPANEL_USER=username
acme.sh --deploy -d example.com --deploy-hook cpanel_uapi
```
Please note, that the cpanel_uapi hook will deploy only the first domain when your certificate will automatically renew. Therefore you should issue a separete certificate for each domain.
## 8. Deploy the cert to your FRITZ!Box router
You must specify the credentials that have administrative privileges on the FRITZ!Box in order to deploy the certificate, plus the URL of your FRITZ!Box, through the following environment variables:
```sh
$ export DEPLOY_FRITZBOX_USERNAME=my_username
$ export DEPLOY_FRITZBOX_PASSWORD=the_password
$ export DEPLOY_FRITZBOX_URL=https://fritzbox.example.com
```
After the first deployment, these values will be stored in your $HOME/.acme.sh/account.conf. You may now deploy the certificate like this:
```sh
acme.sh --deploy -d fritzbox.example.com --deploy-hook fritzbox
```
## 9. Deploy the cert to strongswan
```sh
acme.sh --deploy -d ftp.example.com --deploy-hook strongswan
```

View File

@ -51,8 +51,8 @@ cpanel_uapi_deploy() {
else
_response=$(uapi SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
fi
if [ $? -ne 0 ]; then
error_response="status: 0"
if test "${_response#*$error_response}" != "$_response"; then
_err "Error in deploying certificate:"
_err "$_response"
return 1

108
deploy/fritzbox.sh Normal file
View File

@ -0,0 +1,108 @@
#!/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
_err "iconv not found"
return 1
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>.*$//')"
_fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | iconv -f ASCII -t UTF16LE | md5sum | awk '{print $1}')"
_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
}

53
deploy/strongswan.sh Normal file
View File

@ -0,0 +1,53 @@
#!/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
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
}

View File

@ -420,6 +420,7 @@ Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_cloudns -d example.com -d www.example.com
```
The `CLOUDNS_AUTH_ID` and `CLOUDNS_AUTH_PASSWORD` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 22. Use Infoblox API
@ -601,6 +602,124 @@ The `HE_Username` and `HE_Password` settings will be saved in `~/.acme.sh/accoun
Please report any issues to https://github.com/angel333/acme.sh or to <me@ondrejsimek.com>.
## 32. Use UnoEuro API to automatically issue cert
First you need to login to your UnoEuro account to get your API key.
```
export UNO_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export UNO_User="UExxxxxx"
```
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_unoeuro -d example.com -d www.example.com
```
The `UNO_Key` and `UNO_User` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 33. Use INWX
[INWX](https://www.inwx.de/) offers an [xmlrpc api](https://www.inwx.de/de/help/apidoc) with your standard login credentials, set them like so:
```
export INWX_User="yourusername"
export INWX_Password="password"
```
Then you can issue your certificates with:
```
acme.sh --issue --dns dns_inwx -d example.com -d www.example.com
```
The `INWX_User` and `INWX_Password` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 34. User Servercow API v1
Create a new user from the servercow control center. Don't forget to activate **DNS API** for this user.
```
export SERVERCOW_API_Username=username
export SERVERCOW_API_Password=password
```
Now you cann issue a cert:
```
acme.sh --issue --dns dns_servercow -d example.com -d www.example.com
```
Both, `SERVERCOW_API_Username` and `SERVERCOW_API_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 35. Use Namesilo.com API
You'll need to generate an API key at https://www.namesilo.com/account_api.php
Optionally you may restrict the access to an IP range there.
```
export Namesilo_Key="xxxxxxxxxxxxxxxxxxxxxxxx"
```
And now you can issue certs with:
```
acme.sh --issue --dns dns_namesilo --dnssleep 900 -d example.com -d www.example.com
```
## 36. Use autoDNS (InternetX)
[InternetX](https://www.internetx.com/) offers an [xml api](https://help.internetx.com/display/API/AutoDNS+XML-API) with your standard login credentials, set them like so:
```
export AUTODNS_USER="yourusername"
export AUTODNS_PASSWORD="password"
export AUTODNS_CONTEXT="context"
```
Then you can issue your certificates with:
```
acme.sh --issue --dns dns_autodns -d example.com -d www.example.com
```
The `AUTODNS_USER`, `AUTODNS_PASSWORD` and `AUTODNS_CONTEXT` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 37. Use Azure DNS
You have to create a service principal first. See:[How to use Azure DNS](../../../wiki/How-to-use-Azure-DNS)
```
export AZUREDNS_SUBSCRIPTIONID="12345678-9abc-def0-1234-567890abcdef"
export AZUREDNS_TENANTID="11111111-2222-3333-4444-555555555555"
export AZUREDNS_APPID="3b5033b5-7a66-43a5-b3b9-a36b9e7c25ed"
export AZUREDNS_CLIENTSECRET="1b0224ef-34d4-5af9-110f-77f527d561bd"
```
Then you can issue your certificates with:
```
acme.sh --issue --dns dns_azure -d example.com -d www.example.com
```
`AZUREDNS_SUBSCRIPTIONID`, `AZUREDNS_TENANTID`,`AZUREDNS_APPID` and `AZUREDNS_CLIENTSECRET` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
## 38. Use selectel.com(selectel.ru) domain API to automatically issue cert
First you need to login to your account to get your API key from: https://my.selectel.ru/profile/apikeys.
```sh
export SL_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
```
Ok, let's issue a cert now:
```
acme.sh --issue --dns dns_selectel -d example.com -d www.example.com
```
The `SL_Key` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
# Use custom API
If your API is not supported yet, you can write your own DNS API.
@ -617,6 +736,7 @@ 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)
See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide
# Use lexicon DNS API

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,18 +19,19 @@ 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
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 "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"
fi
#save for future use
_saveaccountconf_mutable AWS_ACCESS_KEY_ID "$AWS_ACCESS_KEY_ID"
_saveaccountconf_mutable AWS_SECRET_ACCESS_KEY "$AWS_SECRET_ACCESS_KEY"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
@ -56,6 +57,8 @@ 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)}"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
@ -87,6 +90,7 @@ _get_root() {
_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"
@ -102,23 +106,23 @@ _get_root() {
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>.*<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 not find domain 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)

249
dnsapi/dns_azure.sh Normal file
View File

@ -0,0 +1,249 @@
#!/usr/bin/env sh
######## 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"
body="{\"properties\": {\"TTL\": 3600, \"TXTRecords\": [{\"value\": [\"$txtvalue\"]}]}}"
_azure_rest PUT "$acmeRecordURI" "$body" "$accesstoken"
if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then
_info "validation record added"
else
_err "error adding validation record ($_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"
body="{\"properties\": {\"TTL\": 3600, \"TXTRecords\": [{\"value\": [\"$txtvalue\"]}]}}"
_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
}
################### Private functions below ##################################
_azure_rest() {
m=$1
ep="$2"
data="$3"
accesstoken="$4"
export _H1="authorization: Bearer $accesstoken"
export _H2="accept: application/json"
export _H3="Content-Type: application/json"
_debug "$ep"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$ep" "" "$m")"
else
response="$(_get "$ep")"
fi
_debug2 response "$response"
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
_debug2 "http response code $_code"
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
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
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"
_debug data "$body"
response="$(_post "$body" "https://login.windows.net/$TENANTID/oauth2/token" "" "POST")"
accesstoken=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
_debug2 "response $response"
if [ -z "$accesstoken" ]; then
_err "no acccess token received"
return 1
fi
if [ "$?" != "0" ]; then
_err "error $response"
return 1
fi
printf "%s" "$accesstoken"
return 0
}
_get_root() {
domain=$1
subscriptionId=$2
accesstoken=$3
i=2
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?api-version=2017-09-01" "" "$accesstoken"
# Find matching domain name is 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
_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

@ -51,33 +51,36 @@ 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 printf -- "%s" "$response" | grep "$fulldomain" >/dev/null; then
_info "Added, 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
}

View File

@ -96,6 +96,16 @@ _dns_cloudns_init_check() {
return 0
fi
CLOUDNS_AUTH_ID="${CLOUDNS_AUTH_ID:-$(_readaccountconf_mutable CLOUDNS_AUTH_ID)}"
CLOUDNS_AUTH_PASSWORD="${CLOUDNS_AUTH_PASSWORD:-$(_readaccountconf_mutable CLOUDNS_AUTH_PASSWORD)}"
if [ -z "$CLOUDNS_AUTH_ID" ] || [ -z "$CLOUDNS_AUTH_PASSWORD" ]; then
CLOUDNS_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" ]; then
_err "CLOUDNS_AUTH_ID is not configured"
return 1
@ -113,6 +123,10 @@ _dns_cloudns_init_check() {
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_AUTH_PASSWORD "$CLOUDNS_AUTH_PASSWORD"
CLOUDNS_INIT_CHECK_COMPLETED=1
return 0

View File

@ -53,6 +53,8 @@ dns_freedns_add() {
i="$(_math "$i" - 1)"
sub_domain="$(echo "$fulldomain" | cut -d. -f -"$i")"
_debug top_domain "$top_domain"
_debug sub_domain "$sub_domain"
# 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
@ -61,7 +63,6 @@ dns_freedns_add() {
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
@ -70,19 +71,11 @@ dns_freedns_add() {
fi
return 1
fi
_debug2 htmlpage "$htmlpage"
subdomain_csv="$(echo "$htmlpage" | tr -d "\n\r" | _egrep_o '<form .*</form>' | sed 's/<tr>/@<tr>/g' | tr '@' '\n' | grep edit.php | grep "$top_domain")"
_debug2 subdomain_csv "$subdomain_csv"
# 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
@ -90,30 +83,32 @@ dns_freedns_add() {
# 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
line="$(echo "$subdomain_csv" | sed -n "${i}p")"
_debug2 line "$line"
if [ $found = 0 ] && _contains "$line" "<td>$top_domain</td>"; then
# this line will contain DNSdomainid for the top_domain
DNSdomainid="$(echo "$line" | cut -d ',' -f 2 | sed 's/^.*domain_id=//;s/>.*//')"
DNSdomainid="$(echo "$line" | _egrep_o "edit_domain_id *= *.*>" | cut -d = -f 2 | cut -d '>' -f 1)"
_debug2 DNSdomainid "$DNSdomainid"
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)"
DNSname="$(echo "$line" | _egrep_o 'edit.php.*</a>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
_debug2 DNSname "$DNSname"
DNStype="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '4p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
_debug2 DNStype "$DNStype"
if [ "$DNSname" = "$fulldomain" ] && [ "$DNStype" = "TXT" ]; then
DNSdataid="$(echo "$line" | cut -d ',' -f 2 | sed 's/^.*data_id=//;s/>.*//')"
DNSdataid="$(echo "$line" | _egrep_o 'data_id=.*' | cut -d = -f 2 | cut -d '>' -f 1)"
# 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 challenge subdomain.
DNSvalue="$(echo "$line" | cut -d ',' -f 4 | sed 's/^[^&quot;]*&quot;//;s/&quot;.*//;s/<\/td>.*//')"
DNSvalue="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '5p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
_debug2 DNSvalue "$DNSvalue"
if [ $found != 0 ]; then
break
# we are breaking out of the loop at the first match of DNS name
@ -169,8 +164,7 @@ dns_freedns_add() {
return 0
else
# Delete the old TXT record (with the wrong value)
_freedns_delete_txt_record "$FREEDNS_COOKIE" "$DNSdataid"
if [ "$?" = "0" ]; then
if _freedns_delete_txt_record "$FREEDNS_COOKIE" "$DNSdataid"; then
# And add in new TXT record with the value provided
_freedns_add_txt_record "$FREEDNS_COOKIE" "$DNSdomainid" "$sub_domain" "$txtvalue"
fi
@ -210,18 +204,9 @@ dns_freedns_rm() {
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")"
subdomain_csv="$(echo "$htmlpage" | tr -d "\n\r" | _egrep_o '<form .*</form>' | sed 's/<tr>/@<tr>/g' | tr '@' '\n' | grep edit.php | grep "$fulldomain")"
_debug2 subdomain_csv "$subdomain_csv"
# 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
@ -229,19 +214,21 @@ dns_freedns_rm() {
# 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)"
line="$(echo "$subdomain_csv" | sed -n "${i}p")"
_debug2 line "$line"
DNSname="$(echo "$line" | _egrep_o 'edit.php.*</a>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
_debug2 DNSname "$DNSname"
DNStype="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '4p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
_debug2 DNStype "$DNStype"
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"
DNSdataid="$(echo "$line" | _egrep_o 'data_id=.*' | cut -d = -f 2 | cut -d '>' -f 1)"
_debug2 DNSdataid "$DNSdataid"
DNSvalue="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '5p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
_debug2 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

View File

@ -11,7 +11,7 @@
#
######## Public functions #####################
GANDI_LIVEDNS_API="https://dns.beta.gandi.net/api/v5"
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() {

311
dnsapi/dns_inwx.sh Executable file
View File

@ -0,0 +1,311 @@
#!/usr/bin/env sh
#
#INWX_User="username"
#
#INWX_Password="password"
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)}"
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"
_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")"
printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')"
}
_get_root() {
domain=$1
_debug "get root"
domain=$1
i=2
p=1
_H1=$(_inwx_login)
export _H1
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

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
}

View File

@ -78,13 +78,7 @@ _ovh_get_api() {
esac
}
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_ovh_add() {
fulldomain=$1
txtvalue=$2
_initAuth() {
if [ -z "$OVH_AK" ] || [ -z "$OVH_AS" ]; then
OVH_AK=""
OVH_AS=""
@ -119,14 +113,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"; 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 +143,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 +206,7 @@ _ovh_authentication() {
_H3=""
_H4=""
_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'"}'
_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"
@ -279,15 +294,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"

161
dnsapi/dns_selectel.sh Normal file
View File

@ -0,0 +1,161 @@
#!/usr/bin/env sh
#
#SL_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
SL_Api="https://api.selectel.ru/domains/v1"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_selectel_add() {
fulldomain=$1
txtvalue=$2
SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}"
if [ -z "$SL_Key" ]; then
SL_Key=""
_err "You don't specify selectel.ru api key yet."
_err "Please create you key and try again."
return 1
fi
#save the api key to the account conf file.
_saveaccountconf_mutable SL_Key "$SL_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"
_info "Adding record"
if _sl_rest POST "/$_domain_id/records/" "{\"type\": \"TXT\", \"ttl\": 60, \"name\": \"$fulldomain\", \"content\": \"$txtvalue\"}"; then
if _contains "$response" "$txtvalue" || _contains "$response" "record_already_exists"; then
_info "Added, OK"
return 0
fi
fi
_err "Add txt record error."
return 1
}
#fulldomain txtvalue
dns_selectel_rm() {
fulldomain=$1
txtvalue=$2
SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}"
if [ -z "$SL_Key" ]; then
SL_Key=""
_err "You don't specify slectel api key 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 _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_sl_rest GET "/${_domain_id}/records/"
if ! _contains "$response" "$txtvalue"; then
_err "Txt record not found"
return 1
fi
_record_seg="$(echo "$response" | _egrep_o "\"content\" *: *\"$txtvalue\"[^}]*}")"
_debug2 "_record_seg" "$_record_seg"
if [ -z "$_record_seg" ]; then
_err "can not find _record_seg"
return 1
fi
_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)"
_debug2 "_record_id" "$_record_id"
if [ -z "$_record_id" ]; then
_err "can not find _record_id"
return 1
fi
if ! _sl_rest DELETE "/$_domain_id/records/$_record_id"; then
_err "Delete record error."
return 1
fi
return 0
}
#################### 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 ! _sl_rest GET "/"; 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" "\"name\": \"$h\","; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
_debug "Getting domain id for $h"
if ! _sl_rest GET "/$h"; then
return 1
fi
_domain_id="$(echo "$response" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\":" | cut -d : -f 2)"
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_sl_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
export _H1="X-Token: $SL_Key"
export _H2="Content-Type: application/json"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$SL_Api/$ep" "" "$m")"
else
response="$(_get "$SL_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

170
dnsapi/dns_servercow.sh Executable file
View File

@ -0,0 +1,170 @@
#!/usr/bin/env sh
##########
# Custom servercow.de DNS API v1 for use with [acme.sh](https://github.com/Neilpang/acme.sh)
#
# Usage:
# export SERVERCOW_API_Username=username
# export SERVERCOW_API_Password=password
# acme.sh --issue -d example.com --dns dns_servercow
#
# Issues:
# Any issues / questions / suggestions can be posted here:
# https://github.com/jhartlep/servercow-dns-api/issues
#
# Author: Jens Hartlep
##########
SERVERCOW_API="https://api.servercow.de/dns/v1/domains"
# Usage dns_servercow_add _acme-challenge.www.domain.com "abcdefghijklmnopqrstuvwxyz"
dns_servercow_add() {
fulldomain=$1
txtvalue=$2
_info "Using servercow"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
SERVERCOW_API_Username="${SERVERCOW_API_Username:-$(_readaccountconf_mutable SERVERCOW_API_Username)}"
SERVERCOW_API_Password="${SERVERCOW_API_Password:-$(_readaccountconf_mutable SERVERCOW_API_Password)}"
if [ -z "$SERVERCOW_API_Username" ] || [ -z "$SERVERCOW_API_Password" ]; then
SERVERCOW_API_Username=""
SERVERCOW_API_Password=""
_err "You don't specify servercow api username and password yet."
_err "Please create your username and password and try again."
return 1
fi
# save the credentials to the account conf file
_saveaccountconf_mutable SERVERCOW_API_Username "$SERVERCOW_API_Username"
_saveaccountconf_mutable SERVERCOW_API_Password "$SERVERCOW_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"
if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; 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_servercow_rm() {
fulldomain=$1
txtvalue=$2
_info "Using servercow"
_debug fulldomain "$fulldomain"
_debug txtvalue "$fulldomain"
SERVERCOW_API_Username="${SERVERCOW_API_Username:-$(_readaccountconf_mutable SERVERCOW_API_Username)}"
SERVERCOW_API_Password="${SERVERCOW_API_Password:-$(_readaccountconf_mutable SERVERCOW_API_Password)}"
if [ -z "$SERVERCOW_API_Username" ] || [ -z "$SERVERCOW_API_Password" ]; then
SERVERCOW_API_Username=""
SERVERCOW_API_Password=""
_err "You don't specify servercow api username and password yet."
_err "Please create your username and 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 _servercow_api DELETE "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\"}"; then
if printf -- "%s" "$response" | grep "ok" >/dev/null; then
_info "Deleted, OK"
_contains "$response" '"message":"ok"'
else
_err "delete txt record error."
return 1
fi
fi
}
#################### 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
while true; do
_domain=$(printf "%s" "$fulldomain" | cut -d . -f $i-100)
_debug _domain "$_domain"
if [ -z "$_domain" ]; then
# not valid
return 1
fi
if ! _servercow_api GET "$_domain"; then
return 1
fi
if ! _contains "$response" '"error":"no such domain in user context"' >/dev/null; then
_sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-$p)
if [ -z "$_sub_domain" ]; then
# not valid
return 1
fi
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_servercow_api() {
method=$1
domain=$2
data="$3"
export _H1="Content-Type: application/json"
export _H2="X-Auth-Username: $SERVERCOW_API_Username"
export _H3="X-Auth-Password: $SERVERCOW_API_Password"
if [ "$method" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$SERVERCOW_API/$domain" "" "$method")"
else
response="$(_get "$SERVERCOW_API/$domain")"
fi
if [ "$?" != "0" ]; then
_err "error $domain"
return 1
fi
_debug2 response "$response"
return 0
}

202
dnsapi/dns_unoeuro.sh Normal file
View File

@ -0,0 +1,202 @@
#!/usr/bin/env sh
#
#UNO_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
#UNO_User="UExxxxxx"
Uno_Api="https://api.unoeuro.com/1"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_unoeuro_add() {
fulldomain=$1
txtvalue=$2
UNO_Key="${UNO_Key:-$(_readaccountconf_mutable UNO_Key)}"
UNO_User="${UNO_User:-$(_readaccountconf_mutable UNO_User)}"
if [ -z "$UNO_Key" ] || [ -z "$UNO_User" ]; then
UNO_Key=""
UNO_User=""
_err "You haven't specified a UnoEuro api key and account yet."
_err "Please create your key and try again."
return 1
fi
if ! _contains "$UNO_User" "UE"; then
_err "It seems that the UNO_User=$UNO_User is not a valid username."
_err "Please check and retry."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf_mutable UNO_Key "$UNO_Key"
_saveaccountconf_mutable UNO_User "$UNO_User"
_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"
_uno_rest GET "my/products/$h/dns/records"
if ! _contains "$response" "\"status\": 200" >/dev/null; then
_err "Error"
return 1
fi
if ! _contains "$response" "$_sub_domain" >/dev/null; then
_info "Adding record"
if _uno_rest POST "my/products/$h/dns/records" "{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"data\":\"$txtvalue\",\"ttl\":120}"; then
if _contains "$response" "\"status\": 200" >/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_line_number=$(echo "$response" | grep -n "$_sub_domain" | cut -d : -f 1)
record_line_number=$(_math "$record_line_number" - 1)
record_id=$(echo "$response" | _head_n "$record_line_number" | _tail_n 1 1 | _egrep_o "[0-9]{1,}")
_debug "record_id" "$record_id"
_uno_rest PUT "my/products/$h/dns/records/$record_id" "{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"data\":\"$txtvalue\",\"ttl\":120}"
if _contains "$response" "\"status\": 200" >/dev/null; then
_info "Updated, OK"
return 0
fi
_err "Update error"
return 1
fi
}
#fulldomain txtvalue
dns_unoeuro_rm() {
fulldomain=$1
txtvalue=$2
UNO_Key="${UNO_Key:-$(_readaccountconf_mutable UNO_Key)}"
UNO_User="${UNO_User:-$(_readaccountconf_mutable UNO_User)}"
if [ -z "$UNO_Key" ] || [ -z "$UNO_User" ]; then
UNO_Key=""
UNO_User=""
_err "You haven't specified a UnoEuro api key and account yet."
_err "Please create your key and try again."
return 1
fi
if ! _contains "$UNO_User" "UE"; then
_err "It seems that the UNO_User=$UNO_User is not a valid username."
_err "Please check and retry."
return 1
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"
_debug "Getting txt records"
_uno_rest GET "my/products/$h/dns/records"
if ! _contains "$response" "\"status\": 200"; then
_err "Error"
return 1
fi
if ! _contains "$response" "$_sub_domain"; then
_info "Don't need to remove."
else
record_line_number=$(echo "$response" | grep -n "$_sub_domain" | cut -d : -f 1)
record_line_number=$(_math "$record_line_number" - 1)
record_id=$(echo "$response" | _head_n "$record_line_number" | _tail_n 1 1 | _egrep_o "[0-9]{1,}")
_debug "record_id" "$record_id"
if [ -z "$record_id" ]; then
_err "Can not get record id to remove."
return 1
fi
if ! _uno_rest DELETE "my/products/$h/dns/records/$record_id"; then
_err "Delete record error."
return 1
fi
_contains "$response" "\"status\": 200"
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
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 ! _uno_rest GET "my/products/$h/dns/records"; then
return 1
fi
if _contains "$response" "\"status\": 200"; then
_domain_id=$h
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
}
_uno_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
export _H1="Content-Type: application/json"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$Uno_Api/$UNO_User/$UNO_Key/$ep" "" "$m")"
else
response="$(_get "$Uno_Api/$UNO_User/$UNO_Key/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

View File

@ -18,7 +18,6 @@ dns_yandex_add() {
curDomain=$(_PDD_get_domain "$fulldomain")
_debug "Found suitable domain in pdd: $curDomain"
curSubdomain="$(echo "${fulldomain}" | sed -e "s@.${curDomain}\$@@")"
curData="domain=${curDomain}&type=TXT&subdomain=${curSubdomain}&ttl=360&content=${txtvalue}"
curUri="https://pddimp.yandex.ru/api2/admin/dns/add"
curResult="$(_post "${curData}" "${curUri}")"
@ -36,7 +35,6 @@ dns_yandex_rm() {
curDomain=$(_PDD_get_domain "$fulldomain")
_debug "Found suitable domain in pdd: $curDomain"
curSubdomain="$(echo "${fulldomain}" | sed -e "s@.${curDomain}\$@@")"
curUri="https://pddimp.yandex.ru/api2/admin/dns/del"
curData="domain=${curDomain}&record_id=${record_id}"
@ -61,7 +59,7 @@ _PDD_get_domain() {
__last=1
fi
__all_domains="$__all_domains $(echo "$res1" | sed -e "s@,@\n@g" | grep '"name"' | cut -d: -f2 | sed -e 's@"@@g')"
__all_domains="$__all_domains $(echo "$res1" | tr "," "\n" | grep '"name"' | cut -d: -f2 | sed -e 's@"@@g')"
__page=$(_math $__page + 1)
done
@ -72,6 +70,8 @@ _PDD_get_domain() {
_debug "finding zone for domain $__t"
for d in $__all_domains; do
if [ "$d" = "$__t" ]; then
p=$(_math $k - 1)
curSubdomain="$(echo "$fulldomain" | cut -d . -f "1-$p")"
echo "$__t"
return
fi
@ -98,7 +98,6 @@ pdd_get_record_id() {
curDomain=$(_PDD_get_domain "$fulldomain")
_debug "Found suitable domain in pdd: $curDomain"
curSubdomain="$(echo "${fulldomain}" | sed -e "s@.${curDomain}\$@@")"
curUri="https://pddimp.yandex.ru/api2/admin/dns/list?domain=${curDomain}"
curResult="$(_get "${curUri}" | _normalizeJson)"