Compare commits

...

679 Commits
3.0.2 ... 3.0.6

Author SHA1 Message Date
neil
b7caf7a016 Merge pull request #4663 from acmesh-official/dev
sync
2023-06-09 21:09:23 +08:00
neil
891198e4f3 Merge pull request #4653 from stokito/dns_ovh_runabove
dns_ovh.sh Add ovh-us endpoint
2023-06-09 20:41:24 +08:00
neil
38c5910be4 Merge pull request #4658 from Justman10000/master
Update
2023-06-09 20:26:25 +08:00
neil
327e2fb0a4 remove all exec.
https://github.com/acmesh-official/acme.sh/issues/4659
2023-06-09 20:18:38 +08:00
neil
c20c219990 Merge pull request #4661 from acmesh-official/dev
sync
2023-06-09 20:04:51 +08:00
neil
4c30250782 fix https://github.com/acmesh-official/acme.sh/issues/4659 2023-06-09 19:59:29 +08:00
Justin Nogossek
caf23f9a04 Remove not anymore exists tutorials and websites 2023-06-07 23:36:18 +02:00
Justin Nogossek
beab808b76 Update URL 2023-06-07 23:35:47 +02:00
Sergey Ponomarev
6c8920f63e dns_ovh.sh Add ovh-us endpoint
Remove discontinued runabove.com
If any new env will be added then a user may spe

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2023-06-05 12:54:54 +03:00
neil
51be15f66d Merge pull request #4150 from defnull/patch-sectigo-wildcard
fix: Challenge not skipped for pre-validated wildcard domain orders
2023-05-12 09:42:52 +08:00
neil
110e25e784 Merge pull request #4158 from lufi42/dev
Plesk XMLAPI Compatibility with all Plesk editions
2023-05-12 09:26:58 +08:00
neil
8414100d0b Merge pull request #4629 from fichtner/dns_opnsense
dnsapi: fix OPNsense script to be compatible with upcoming 23.1.8
2023-05-12 09:26:01 +08:00
lufi42
a3f4cb154e Merge branch 'acmesh-official:dev' into dev 2023-05-09 21:59:18 +02:00
Franco Fichtner
e6e22a1ca1 dnsapi: fix OPNsense script to be compatible with upcoming 23.1.8
The current script is already broken due to Bind 9.16 -> 9.18 changes
due to their renaming scheme for primary/secondary so do not rely on the
compat layer (which was also broken for other reasons).
2023-05-09 08:47:24 +02:00
neilpang
b937665b90 minor 2023-04-23 13:18:17 +08:00
neilpang
a7bc2293c0 fix https://github.com/acmesh-official/acme.sh/issues/4612#issuecomment-1518929996 2023-04-23 13:16:12 +08:00
neil
0d25f7612b Merge pull request #4609 from acmesh-official/dev
sync
2023-04-21 20:21:30 +08:00
neilpang
84e4181ed7 fix https://github.com/acmesh-official/acme.sh/issues/4604 2023-04-20 18:11:55 +08:00
neilpang
f66a29d1c3 fix https://github.com/acmesh-official/acme.sh/issues/4606 2023-04-20 18:07:59 +08:00
neil
dbd3881cea Merge pull request #4515 from HRHDaniel/domain_conf_debug
Domain conf debug
2023-04-14 13:48:52 +08:00
neil
7eb6bbe65f Merge pull request #4579 from daschr/dev
Prevent whitespace splitting
2023-04-03 11:06:22 +08:00
David Schramm
a570fda1cb prevent whitespace splitting 2023-04-02 17:30:47 +02:00
David Schramm
3b06fa6523 merge upstream 2023-04-02 17:28:47 +02:00
neil
dcdbe2fbb8 fix https://github.com/acmesh-official/acme.sh/pull/4577 2023-04-02 12:04:58 +08:00
David Schramm
dc1f36da43 prevent whitespace splitting 2023-04-01 09:25:19 +02:00
neil
05dbd395e6 Merge pull request #4540 from Hobby-Student/dev
[KAS] improve deletion of records
2023-03-30 16:48:37 +08:00
neil
69e7360cc3 Merge pull request #4568 from imlonghao/patch-1
fix(cloudns): fix grep when TXT record start with hyphen symbol
2023-03-29 14:39:32 +08:00
imlonghao
7ef2533b98 fix(cloudns): fix grep when record start with hyphen symbol 2023-03-28 22:49:39 +08:00
neil
97f87c4229 Merge pull request #4542 from alexleigh/master
Add support for Google Domains DNS API.
2023-03-27 09:16:00 +08:00
neilpang
42a5cd961d fix https://github.com/acmesh-official/acme.sh/issues/4530#issuecomment-1473395845 2023-03-17 17:21:10 +08:00
neil
bf00d3157f Merge pull request #4544 from NCDGHA/bugfix/issue_4543_fix_retry-after
Fix Retry-After handling
2023-03-17 17:16:55 +08:00
neil
cf3ff4c136 Merge pull request #4551 from acmesh-official/dev
sync
2023-03-13 09:15:53 +08:00
neil
7fe06adcfd Merge pull request #4550 from eastonman/master
dnsapi(huaweicloud): fix DomainName not retreived properly
2023-03-13 09:14:32 +08:00
Easton Man
ae3e5dbf2c fix: fix DomainName not retreived properly
Co-Authored-By: idawnlight <idawn@live.com>
2023-03-12 12:41:29 +08:00
neil
20304590b4 Merge pull request #4547 from eastonman/master
dnsapi(huaweicloud): Add retry count to avoid infinite loop when things go wrong
2023-03-10 13:52:37 +08:00
Alex Leigh
2d8c0c0131 Add support for Google Domains DNS API.
https://domains.google/learn/gts-acme/

This is an ACME API for Google Domains customers, which is
different from the Google Cloud Domains API for Google Cloud
customers.
2023-03-08 11:13:25 -08:00
Markus Hoffrogge
70f4cad2ca Fix Retry-After handling
- closes #4543
2023-03-07 18:45:07 +01:00
Easton Man
1f777a94a7 fix: change some debug comments 2023-03-07 17:50:44 +08:00
Easton Man
7560c64f46 fix: fix typo 2023-03-07 11:30:32 +08:00
Easton Man
bddde60522 fix: use update instead of remove then add 2023-03-07 11:27:08 +08:00
Easton Man
e9366f8c76 fix: fix huaweicloud existing record 400 2023-03-07 10:56:10 +08:00
Easton Man
4dba84d09e fix: fix shfmt 2023-03-07 10:01:20 +08:00
Easton Man
0cce2d6098 fix: fix shellcheck 2023-03-07 09:57:39 +08:00
Easton Man
acbd8bce21 feat: add retry count for removing record set
This avoids infinite loop when something went wrong and throws a error
2023-03-07 09:48:13 +08:00
Hobby-Student
dea8a08b64 added missing new line at EOF 2023-03-06 20:36:53 +01:00
Hobby-Student
dde1bab1a8 improve deletion of records 2023-03-06 20:18:15 +01:00
neil
799e402077 Merge pull request #4536 from acmesh-official/dev
sync
2023-03-04 21:26:18 +08:00
neil
ce629e8e70 fix typo 2023-03-04 21:23:31 +08:00
neil
20cfc4ac66 fix https://github.com/acmesh-official/acme.sh/issues/4535 2023-03-04 21:22:17 +08:00
neil
132d5e8253 Merge pull request #4532 from acmesh-official/dev
sync
2023-03-02 22:07:16 +08:00
neilpang
cb8b341fb4 fix https://github.com/acmesh-official/acme.sh/issues/4530 2023-03-02 18:10:38 +08:00
neilpang
982c54b605 fix https://github.com/acmesh-official/acme.sh/issues/4530 2023-03-02 18:06:09 +08:00
neil
67f543332a Merge pull request #4531 from NCDGHA/bugfix/issue_4530_fix_http_status_503
Fix to handle LE overload status 503 appropriately
2023-03-02 18:00:36 +08:00
neil
88ac4086c2 Merge pull request #4518 from AnTheMaker/nanelo_dns
Add Nanelo DNS support
2023-03-02 09:40:47 +08:00
Markus Hoffrogge
15f96b7239 Fix to handle LE overload status 503 appropriately
- LE HTTP response status 503 is not an error, it must be handled via sleep and retry
- s. https://community.letsencrypt.org/t/new-service-busy-responses-beginning-during-high-load/184174

fixes #4530
2023-03-02 00:46:52 +01:00
neil
0ea84ad799 Merge pull request #4528 from chris03/bugfix/replace-expr
SMTP notify: Use grep -E instead of expr
2023-03-01 10:28:18 +08:00
Chris
1522b713da Use grep -E instead of expr
expr was printing  `expr: warning: '^.*[<>"]': using '^' as the first character of a basic regular expression is not portable;`
2023-02-28 21:08:33 -05:00
neil
fe6b27bb59 Merge pull request #4420 from romanlum/dev
Added dns provider for ipv64.net
2023-02-28 17:38:16 +08:00
Roman Lumetsberger
df14b15397 fix quote 2023-02-25 11:22:27 +00:00
Roman Lumetsberger
7dd12044de use _lower_case function 2023-02-25 11:18:33 +00:00
An | Anton Röhm
06e12a30e7 reduce nanelo dns ttl 2023-02-24 00:13:21 +01:00
An | Anton Röhm
d3fefd223d improve output 2023-02-24 00:01:39 +01:00
An | Anton Röhm
c0639c6608 Create first version of Nanelo DNS API integration
[create dnsapi/dns_nanelo.sh]
2023-02-23 23:29:46 +01:00
dharp
05a2eb3df4 add additional debug statement for DOMAIN_CONF 2023-02-21 10:19:07 -06:00
neil
d4befeb536 Merge pull request #4489 from acmesh-official/dev
sync
2023-02-04 20:08:11 +08:00
neil
f7f1168aad Merge pull request #4266 from skyksandr/master
Vultr DNS: fix "grep: repetition-operator operand invalid" on FreeBSD
2023-02-03 16:49:26 +08:00
Aleksandr Kunin
d6cf15368a Vultr DNS: fix "grep: repetition-operator operand invalid" on FreeBSD 2023-02-03 12:44:33 +07:00
neilpang
a5fbf3fb80 fix format 2023-02-03 09:59:42 +08:00
neilpang
3cf8f78745 fix format 2023-02-03 09:57:56 +08:00
neilpang
59dab6eac7 fix https://github.com/acmesh-official/acme.sh/issues/4485#issuecomment-1414022376
https://github.com/acmesh-official/acme.sh/issues/4483#issuecomment-1414460122
2023-02-03 09:55:51 +08:00
Roman Lumetsberger
553d861b8a fix shell check and formatting 2023-01-31 11:17:33 +01:00
Roman Lumetsberger
7b5d94d062 convert domain and subdomain to lower case 2023-01-31 11:10:42 +01:00
Roman Lumetsberger
cb021efaee Merge branch 'acmesh-official:dev' into dev 2023-01-31 10:34:29 +01:00
neilpang
c2344f3717 add log for doh
https://github.com/acmesh-official/acme.sh/issues/4481
2023-01-30 14:39:03 +08:00
neilpang
f537c606f7 fix warnings 2023-01-29 11:13:23 +08:00
neil
c8f48a4a90 Merge pull request #4478 from acmesh-official/dev
sync
2023-01-29 11:06:37 +08:00
neil
c2ad1b4e46 Merge pull request #4448 from PMExtra/feature/curl_fail
curl return fail if HTTP errors
2023-01-28 20:37:20 +08:00
neilpang
ba9d146d6c fix https://github.com/acmesh-official/acme.sh/issues/992 2023-01-28 17:29:03 +08:00
PMExtra
a5b04a0328 ensure curl --help backward compatible 2023-01-28 17:19:04 +08:00
neilpang
01249d0cb9 fix warning 2023-01-28 16:24:27 +08:00
neil
71c273fbcb Merge pull request #4476 from acmesh-official/dev
sync
2023-01-28 16:19:53 +08:00
neilpang
aa9cbf7c55 fix https://github.com/acmesh-official/acme.sh/issues/992 2023-01-28 16:18:27 +08:00
neil
429b18ed48 Merge pull request #4475 from acmesh-official/dev
sync
2023-01-28 15:31:55 +08:00
neilpang
2690c05781 fix format 2023-01-28 15:28:06 +08:00
neilpang
e3b688c9d8 fix format 2023-01-28 15:26:54 +08:00
neilpang
41b6f18a5d fix format 2023-01-28 15:25:50 +08:00
neilpang
5a59c39036 fix format 2023-01-28 15:24:21 +08:00
neil
a02dd18ad7 Merge pull request #4414 from beartom/master
Update truenas.sh to deploy certificate for TrueCharts
2023-01-28 15:20:10 +08:00
neil
16bdc7d0a3 fix from OpenAI https://github.com/acmesh-official/acme.sh/issues/992
https://github.com/acmesh-official/acme.sh/pull/2609
2023-01-27 11:44:20 +08:00
neil
40002e8040 Merge pull request #4447 from PMExtra/feature/vault
improve vault and vault_cli deployhooks
2023-01-24 18:49:18 +08:00
neil
6748c55c04 fix stepca 2023-01-24 18:00:09 +08:00
neil
deb63b4adf fix stepca 2023-01-24 17:58:46 +08:00
neil
015a9b9271 fix notify 2023-01-24 16:45:12 +08:00
neil
ab2305e259 fix stepca 2023-01-24 16:42:10 +08:00
neil
b99c998057 fix https://github.com/acmesh-official/acme.sh/issues/4463 2023-01-24 16:13:42 +08:00
neil
6c0a7144f6 fix https://github.com/acmesh-official/acme.sh/issues/4445 2023-01-24 15:45:25 +08:00
neil
bf50fce5bd fix https://github.com/acmesh-official/acme.sh/issues/4470 2023-01-24 15:17:48 +08:00
neil
8718b156c4 Merge pull request #4471 from vladislav-sharapov/patch-1
fix(dns_openstack): fix argparse error
2023-01-22 14:10:32 +08:00
Vladislav Sharapov
7bbdd1f839 fix(dns_openstack): fix argparse error
Add equal sign to '--record' option to fix argparse error
occurring when ACME token starts with '-'.
2023-01-20 23:56:14 +04:00
neil
ffed1a4afa Merge pull request #4468 from DreamOfIce/master
Update deploy script for gcore
2023-01-20 09:11:23 +08:00
冰雪殇璃陌梦
1bfd3642e8 Update gcore_cdn.sh 2023-01-19 10:19:05 +08:00
neil
577f4e0cc3 Merge pull request #4430 from zpeschke/gd_grammar
Minor grammar fixes for gd
2023-01-11 20:50:59 +08:00
neil
e2f05f3fc9 Merge pull request #4413 from trulyliu/dev
Add gcore dns support.
2023-01-11 20:46:07 +08:00
Gavin Leo
27f30631ed Add gcore dns support.
https://apidocs.gcore.com/dns
2023-01-05 14:30:02 +08:00
PMExtra
1ccfa96c2e improve logging 2022-12-28 02:47:49 +08:00
neil
a2c64e79ff fix for openbsd 2022-12-26 22:28:08 +08:00
neil
7b623f85cd minor 2022-12-26 21:43:02 +08:00
PMExtra
ed63eb6833 migrate FABIO to VAULT_FABIO_MODE and persist it 2022-12-23 19:34:31 +08:00
PMExtra
b8d0d3c242 improve chain.pem exists evaluating 2022-12-23 19:17:37 +08:00
PMExtra
fe1bfe9ae1 improve vault and vault_api deployhooks 2022-12-23 18:59:01 +08:00
PMExtra
7154c9ee5d improve curl --help predication 2022-12-23 17:42:27 +08:00
PMExtra
057c95bd1c improve wget --content-on-error condition 2022-12-23 17:39:51 +08:00
PMExtra
0cafc00c4f append --fail-with-body argument to curl if supported 2022-12-23 17:22:12 +08:00
neil
75d2898efd Merge pull request #4441 from plummer86/bugfix/_wget_out_fix
Fix assignment: _wget_out
2022-12-19 10:23:00 +08:00
plummer86
764a4c99fa Fix assignment to _wget_out 2022-12-18 22:32:49 +00:00
Zachary Peschke
160513c671 Minor grammar fixes for gd 2022-12-09 09:55:47 -07:00
neil
a2af26635f use ecc cert 2022-12-04 15:05:30 +08:00
neil
63869deeb2 Merge pull request #4091 from PMExtra/feature/ssh_scp
Refact ssh hook to use deploy config, support scp and support specifying port
2022-12-03 13:58:31 +08:00
Roman Lumetsberger
91e387e8b9 added doc for dns_ipv64_rm 2022-11-30 08:55:27 +01:00
Roman Lumetsberger
7d13146859 Added dns provider for ipv64.net 2022-11-30 08:35:03 +01:00
neil
699d2b7e7e Merge pull request #4409 from hatamiarash7/patch-1
Update ArvanCloud API URL - Security & CI problem
2022-11-29 21:12:47 +08:00
Arash Hatami
257de15c73 Fix export problems 2022-11-29 13:45:04 +03:30
Arash Hatami
5a0225d033 Fix export problem for special values 2022-11-29 12:21:49 +03:30
beartom
bd2d0e6ad3 Format
Format
2022-11-28 20:59:10 +08:00
Arash Hatami
0c0d1d4e52 Update duplicate message 2022-11-28 16:22:25 +03:30
Arash Hatami
eab9603921 Fix SH format 2022-11-28 16:11:17 +03:30
Arash Hatami
c07db3aa14 add 'Accept' header 2022-11-28 16:09:17 +03:30
neil
a19f7481b2 Merge pull request #4410 from kirisakow/patch-1
Trim trailing slash in `--home` argument's value from the get-go to avoid that subsequently created paths contain two adjacent slashes in the middle
2022-11-28 09:58:46 +08:00
lufi42
2905edce35 Merge branch 'acmesh-official:dev' into dev 2022-11-27 19:55:58 +01:00
beartom
04a5d794ac Update truenas.sh for certificate in chart release
Update certificate in chart release of TrueCharts if any chart release Apps is using the same certificate as TrueNAS web UI.
2022-11-27 21:55:01 +08:00
Kiril Isakov
264b9819ff Replace the BASH parameter substitution mechanism (unsupported by sh) with standard commands (supported by sh) 2022-11-27 09:22:06 +01:00
Arash Hatami
4610204c83 Test CI 2022-11-27 10:21:24 +03:30
neil
ecf1f17cf4 update key type 2022-11-27 11:10:14 +08:00
Kiril Isakov
9f942a6b65 Trim trailing slash in --home argument's value
# What's expected

Since in `acme.sh` path strings are concatenated with a hardcoded slash in between, the left operand must never end with a trailing slash for the resulting path to be valid. Otherwise, obviously, the resulting path will have two adjacent slashes in the middle and will not be valid.

# What actually happens

Even though I cannot tell for each of the input params, I know this for sure for the the `--home` argument's value.

If I run `acme.sh` with `--home` argument's value being a path ending in a trailing slash,

```sh
acme.sh ... --debug ... --home /some/path/ ... -d somedomainna.me ...
```

I get the following (distinct) occurrencies of resulting invalid paths containing two adjacent slashes:

```
[...] Using config home:/some/path/

[...] DOMAIN_PATH='/some/path//somedomainna.me'

[...] _CURL='curl --silent --dump-header /some/path//http.header  -L  -g '

[...] The domain key is here: /some/path//somedomainna.me/somedomainna.me.key

[...] _CURL='curl --silent --dump-header /some/path//http.header  -L  -g  -I  '

[...] Your cert is in: /some/path//somedomainna.me/somedomainna.me.cer

[...] Your cert key is in: /some/path//somedomainna.me/somedomainna.me.key

[...] The intermediate CA cert is in: /some/path//somedomainna.me/ca.cer

[...] And the full chain certs is there: /some/path//somedomainna.me/fullchain.cer

```

# Suggested fix

Trim trailing slash in `--home` argument's value from the get-go.
2022-11-26 16:00:03 +01:00
Arash Hatami
f4ed1b32b8 Update dns_arvan.sh
Update API URL
2022-11-26 18:12:11 +03:30
neil
ec0e871592 Use ec-256 as default key length
fix https://github.com/acmesh-official/acme.sh/issues/2350#issuecomment-1324029469
2022-11-23 21:57:38 +08:00
neil
7a756ebc4d start v3.0.6 2022-11-23 21:55:19 +08:00
neil
16dc21afff Merge pull request #4406 from acmesh-official/dev
sync
2022-11-23 21:44:53 +08:00
neil
3a1c6d84f0 fix shellcheck warnings 2022-11-23 21:40:34 +08:00
neil
e684abdacd fix checkout 2022-11-23 21:34:58 +08:00
neil
e275cb1efd fix shellcheck warnings 2022-11-23 21:33:29 +08:00
neil
60315e5b91 fix shellcheck warnings 2022-11-23 21:28:17 +08:00
neil
43b1a4bf5a Merge pull request #4405 from acmesh-official/dev
sync
2022-11-23 21:16:44 +08:00
neil
cdb238e41c fix cf-tunnel 2022-11-23 21:12:52 +08:00
neil
3871e44d9c Merge pull request #4400 from waja/docker_alpine_update
Docker alpine update
2022-11-20 19:47:44 +08:00
Jan Wagner
5a51454d13 Update Alpine to 1.16.3
With #4399 applied we can pick minor versions safely.
2022-11-17 15:20:11 +01:00
neil
d102943a32 upgrade actions/checkout@v3 2022-11-07 22:36:40 +08:00
neil
a0b27ddbd8 Merge pull request #4372 from PeterDaveHello/speedup-ci
Reduce `acmetest` `git clone` depth to speed up CI pipeline
2022-10-29 13:59:32 +08:00
neil
b950b04e89 Merge pull request #4371 from PeterDaveHello/use-https
Use encrypted https instead of plain-text http when we can
2022-10-29 13:58:20 +08:00
neil
c9a55f395b fix doh
https://github.com/acmesh-official/acme.sh/issues/4369
2022-10-29 10:08:42 +08:00
Peter Dave Hello
424da01878 Reduce acmetest git clone depth to speed up CI pipeline 2022-10-27 19:49:10 +08:00
Peter Dave Hello
3c933158c8 Use encrypted https instead of plain-text http when we can 2022-10-27 19:45:48 +08:00
neil
7221d488e5 Merge pull request #4365 from acmesh-official/dev
sync
2022-10-24 17:44:22 +08:00
neil
1c16931e26 add Le_Next_Domain_Key for tlsa
fix https://github.com/acmesh-official/acme.sh/issues/3096
Usage: https://github.com/acmesh-official/acme.sh/wiki/tlsa-next-key
2022-10-16 16:06:01 +08:00
neil
0a4b70dbd2 Merge pull request #4349 from tcx4c70/fix/save-conf
Fix error during saving conf
2022-10-12 08:17:08 +08:00
Adam Tao
666c716bda Fix error during saving conf
There might be '|' in __val (e.g., SYNO_Password), which will cause that
all content of the conf file is cleared. Fix it by escaping '|'
manually.

Signed-off-by: Adam Tao <tcx4c70@gmail.com>
2022-10-11 20:45:31 +08:00
neil
be477d7ae3 Merge pull request #4259 from Mon-ius/master
fix a issue, when profile not end with newline
2022-10-05 14:20:01 +08:00
neil
6c8a623b88 Merge pull request #4329 from lippertmarkus/patch-1
[Deploy: synology_dsm] Make usage of DID with 2FA working for DSM 7
2022-10-05 14:18:37 +08:00
neil
ff8de34415 Merge pull request #4335 from acmesh-official/dev
sync
2022-10-05 14:17:03 +08:00
neil
f8ca6d9833 fix https://github.com/acmesh-official/acme.sh/issues/1335 2022-10-05 13:14:25 +08:00
neil
dbab519004 Merge pull request #4252 from agowa338/agowa338-patch-1
Fix missing HTTP_HEADER for _get with wget
2022-10-04 11:20:12 +08:00
neil
e888c96591 Merge pull request #4331 from arnebjarne/dns_cpanel_newserial_fix
Dns cpanel newserial fix
2022-10-02 20:40:50 +08:00
neil
59519f0493 Merge pull request #4334 from sasburg/patch-1
Added parked_domans
2022-10-02 20:39:52 +08:00
sasburg
e02f07d356 add parked_domans 2022-10-01 18:11:46 -07:00
sasburg
2c90d220b8 Updated comment to reflect the change to function 2022-10-01 17:47:13 -07:00
Bjarne Saltbaek
9feeba8d4b Forgot to apply the changed default return value 2022-10-01 15:19:02 +02:00
Bjarne Saltbaek
45090fc897 Better way to catch success or failure 2022-10-01 14:58:12 +02:00
neilpang
d761bdc1b1 minor, just indent usage 2022-09-30 18:03:47 +08:00
neil
287a8c76b5 Merge pull request #4328 from srirams/srirams-patch-1
Add addon domains to cpanel_uapi
2022-09-30 17:15:22 +08:00
Markus Lippert
a7dd86de71 fix(deploy-synology_dsm): support DID with DSM 7 2022-09-29 12:22:45 +02:00
srirams
c541a2e5de add addon_domans 2022-09-28 18:22:13 -05:00
Klaus Frank
41dbf1ddac use _contains instead of grep 2022-09-27 22:47:35 +02:00
neil
70ed6b96d1 Merge pull request #4317 from acmesh-official/dev
sync
2022-09-25 00:02:58 +08:00
neil
ef26075a1c export TokenName 2022-09-24 23:58:56 +08:00
neil
91c87446be Merge pull request #4115 from koter84/dev
make ip-whitelisting configurable for DNS TransIP
2022-09-24 23:31:29 +08:00
neil
dd207e1f02 fix https://github.com/acmesh-official/acme.sh/issues/4285 2022-09-24 22:00:39 +08:00
neil
e947870da9 minor 2022-09-23 22:39:53 +08:00
neil
f0b5f592dc Merge pull request #4310 from mystix/patch-1
Prevent erasure of saved access token on DNS removal
2022-09-20 21:46:19 +08:00
Marc
773a2a6cfe Merge branch 'master' into patch-1 2022-09-19 13:08:07 +08:00
Klaus Frank
c2a7e384ba Fix linting issue 2022-09-18 22:03:52 +02:00
Klaus Frank
4a8b35ef5f Merge branch 'acmesh-official:master' into agowa338-patch-1 2022-09-18 22:00:49 +02:00
neil
5cd0db32df Merge pull request #4256 from dannytix/cpanel_auto
Cpanel auto
2022-09-18 20:52:11 +08:00
neil
ef01de6149 Merge pull request #4313 from acmesh-official/dev
sync
2022-09-18 20:25:26 +08:00
Marc
4e9749f655 Prevent erasure of saved access token 2022-09-16 14:10:10 +08:00
neil
abb7a1fd47 Merge pull request #4304 from SahAssar/rage4-dns
Add rage4 dns api
2022-09-13 17:14:23 +08:00
Svante Richter
60bcee8c1d Add rage4 dns api 2022-09-12 18:17:20 +02:00
neil
8ded524236 Merge pull request #4302 from acmesh-official/dev
sync
2022-09-08 22:12:10 +08:00
neil
0a47f48191 fix https://github.com/acmesh-official/acme.sh/issues/4301 2022-09-08 22:09:39 +08:00
neil
8601267b90 fix https://github.com/acmesh-official/acme.sh/issues/4301 2022-09-08 21:56:49 +08:00
neil
6767e0c52d Merge pull request #4267 from nixys/feature/dns_yc
Add Yandex Cloud DNS API
2022-09-08 13:54:58 +08:00
neil
5141d1775d Merge pull request #3873 from Marvo2011/dev
Added Selfhost DNS API
2022-09-08 13:47:13 +08:00
neil
374af996d9 Merge pull request #4297 from nosilver4u/dgon_found
add domain alias support for Digital Ocean API
2022-09-08 09:12:33 +08:00
Shane Bishop
dcc9624c15 Update dns_dgon.sh
Make sure to initialize 'found' so that it isn't contaminated from previous commands/requests.
2022-09-07 15:37:49 -06:00
Shane Bishop
b3df1a2bf8 'i' should start with 1
Since domain alias mode won't have the '_acme-challenge' prefix.
2022-09-07 13:42:30 -06:00
neil
3fc3c02a4f Merge pull request #4295 from NerLOR/master
Update dns_world4you
2022-09-07 23:22:46 +08:00
neil
874ddf9a32 Merge pull request #4294 from koelle25/dev
Fix OPNsense DNS plugin (again)
2022-09-07 22:58:29 +08:00
Kevin Köllmann
69aeb70cc3 Slightly modify regex to conform to new API response format 2022-09-07 13:07:29 +02:00
Kevin Köllmann
47e60cefe3 Use new searchMasterDomain API endpoint 2022-09-07 13:07:04 +02:00
neilpang
4ea7f3cda5 ignore https error for solaris 2022-09-07 18:20:09 +08:00
neil
03288b521a Merge pull request #4292 from nosilver4u/bunny
Add Bunny DNS API verification method
2022-09-07 18:18:15 +08:00
neil
4b0a7a6e1f Update dns_bunny.sh
`i` should start with `1`.
In dns alias mode, the fulldomain doesn't have a `_acme-challenge` prefix.
2022-09-07 18:15:21 +08:00
neil
383287adcd Merge pull request #4293 from bbruun/fix-multiple-tld
Fix for multiple TLDs in DNS API
2022-09-07 16:47:25 +08:00
Bjarke Bruun
5c00afc6fe Fix for multiple TLDs in DNS API 2022-09-07 03:46:28 +02:00
Shane Bishop
025e0e8093 fix the shebang 2022-09-06 11:38:15 -06:00
Shane Bishop
35fb1f8585 Create dns_bunny.sh 2022-09-06 07:35:06 -06:00
neil
9fb14eef0e support "secrets.HTTPS_INSECURE" for solaris 2022-09-06 20:33:51 +08:00
Lorenz Stechauner
5d6d0c6176 World4You: fix paketnr parsing
Signed-off-by: Lorenz Stechauner <lorenz.stechauner@necronda.net>
2022-09-06 13:25:14 +02:00
neil
dd707242ef the envs are moved to acmetest 2022-09-03 21:11:26 +08:00
neil
4f32f1285a Merge pull request #4190 from arnebjarne/dns_cpanel_multidomain
Dns cpanel multidomain
2022-08-31 15:07:37 +08:00
Marvo2011
a6ecdbae29 Merge pull request #7 from AlvinSchiller/dev
Dev - SELFHOSTDNS_MAP_LAST_USED_INTERNAL changes for readability
2022-08-31 06:55:30 +02:00
neil
4904d100ff Merge pull request #4279 from acmesh-official/dev
sync
2022-08-29 20:17:47 +08:00
AlvinSchiller
7a1f94bc20 set newLastUsedRidForDomainEntry after request was successfull 2022-08-28 20:44:17 +02:00
AlvinSchiller
f9320fff8f Changed lastUsedRidForDomainEntry seperator to space 2022-08-27 01:24:16 +02:00
neil
3dde83d8a0 fix https://github.com/acmesh-official/acme.sh/issues/4268 2022-08-26 19:47:45 +08:00
Marvo2011
f3e77a989c Merge branch 'acmesh-official:dev' into dev 2022-08-25 14:28:51 +02:00
Marvo2011
f3539b0354 Merge pull request #6 from AlvinSchiller/dev
Removed RID RID2 only allow Mapping
2022-08-25 14:16:12 +02:00
Viktor Sokhan
4e5d4b9695 Fix shellcheck and shfmt 2022-08-25 13:43:06 +07:00
Klaus Frank
864315f6d1 Use literal space
Replace [[:space:]] with " "
2022-08-24 19:34:37 +02:00
Klaus Frank
713b7338ea demultiplex wget debug output 2022-08-24 19:34:37 +02:00
Klaus Frank
53117b2f4c Fix missing HTTP_HEADER for _get with wget
Save http header to file for _get with wget.
2022-08-24 19:34:36 +02:00
Viktor Sokhan
90623142e1 Fix 2022-08-24 16:40:27 +07:00
Viktor Sokhan
43503a20e5 Fix 2022-08-24 14:12:57 +07:00
Viktor Sokhan
ec53b27dfe Add dns_yc.sh 2022-08-24 13:48:10 +07:00
neil
238ecfc539 fix issue message 2022-08-23 22:19:10 +08:00
neil
b888792940 fix concurrency 2022-08-23 22:15:50 +08:00
neil
e3d1ab52f8 Merge pull request #4264 from Hobby-Student/dev
Update KAS API - better error handling
2022-08-23 21:25:14 +08:00
Hobby-Student
f9c2874c35 removed unnecessary white space in empty line 2022-08-23 13:30:04 +02:00
Hobby-Student
2304f005e3 better error handling 2022-08-23 12:41:42 +02:00
Monius
b95f836256 final try 2022-08-23 06:30:09 +08:00
AlvinSchiller
c94f9f21af fixed shfmt 2022-08-23 00:28:52 +02:00
AlvinSchiller
fc336e3733 fixed RID usage for wildcard domains 2022-08-23 00:04:41 +02:00
neil
fc1df9f9a5 Merge pull request #4262 from acmesh-official/dev
sync
2022-08-22 21:17:19 +08:00
Monius
5a604bfdee shfmt check? 2022-08-22 15:16:30 +08:00
AlvinSchiller
281951a86b ShellCheck fixed 2022-08-22 06:51:17 +02:00
AlvinSchiller
35ec3adadc only use SELFHOSTDNS_MAP for configuration of RIDs. detect wildcard domain for use of additional RID 2022-08-22 00:55:05 +02:00
AlvinSchiller
b9256a1ba7 changed from *deployconf to *domainconf 2022-08-22 00:55:05 +02:00
AlvinSchiller
734c9a1aa5 Dns Challenge prefix removed. SELFHOSTDNS_MAP entries must be fullpath incl. prefix 2022-08-22 00:55:05 +02:00
Monius
6502a71083 fix, but remove debug info 2022-08-22 05:26:12 +08:00
Monius
f2634b44cd add EOF, if $__conf not end with one 2022-08-21 12:26:37 +08:00
Monius
dcf9c467c3 fix issue, when profile not end with newline 2022-08-20 19:37:51 +08:00
neil
3dcacc1f8d add pr_notify.yml 2022-08-20 12:32:53 +08:00
neil
7cb81b0f35 Merge pull request #4244 from awalon/master
dns_gd (GoDaddy) Remove complete TXT record instead of value only
2022-08-20 11:12:37 +08:00
neil
8155ba5224 fix issue.yml 2022-08-20 10:59:50 +08:00
neil
7169060425 fix https://github.com/acmesh-official/acme.sh/issues/4248#issuecomment-1217378906 2022-08-20 10:54:17 +08:00
neil
ddb9dd4e45 Merge pull request #4243 from sinostephen/master
dns.la official acme script
2022-08-19 21:44:37 +08:00
stephen
2a05f24cb6 Add dns.la api support
Add dns.la api support
2022-08-19 11:12:16 +08:00
neil
039e4c662d rename the csr/key file if the cert is revoked. 2022-08-18 21:10:38 +08:00
neil
70351677a1 add concurrency 2022-08-18 20:30:11 +08:00
neil
33cadfb97d Merge pull request #4254 from Hobby-Student/dev
Upgrade KAS API
2022-08-18 20:08:28 +08:00
neil
5fbaeda217 Update dns_la.sh 2022-08-18 19:48:09 +08:00
Danny Tix
b44ba0d21a Add wildcard deployment to cpanel_uapi 2022-08-17 23:51:23 -08:00
Hobby-Student
b42532afe9 forgot enabling github actions. forced commit 2022-08-17 19:58:34 +02:00
Hobby-Student
da6a335b87 new line EOF 2022-08-17 19:50:47 +02:00
Hobby-Student
0e8fef73bb error handling, minor changes to params, ... 2022-08-17 19:43:30 +02:00
Dennis Koot
7122a960fa make ip-whitelisting configurable for DNS TransIP and download keyfile if it is an url 2022-08-17 17:53:35 +02:00
neil
d5b649a1a4 add tests for wget 2022-08-17 23:49:30 +08:00
stephen
233c724b2d dns.la official acme script
dns.la official acme script
2022-08-17 18:18:42 +08:00
stephen
e1eb001872 dns.la official acme script
dns.la official acme script
2022-08-17 17:23:12 +08:00
stephen
5899d7034f dns.la official acme script
dns.la official acme script
2022-08-16 15:35:46 +08:00
stephen
23c3e9482f Delete dns_la.sh 2022-08-16 15:35:22 +08:00
stephen
dd980d9dca dns.la official acme script
dns.la official acme script
2022-08-16 15:30:10 +08:00
stephen
d4ed50a915 Delete dns_la.sh 2022-08-16 15:29:35 +08:00
stephen
d986c7d126 dns.la official acme script
dns.la official acme script
2022-08-16 15:26:13 +08:00
stephen
67a2a4f249 dns.la dns acme script
dns.la dns acme script
2022-08-16 15:14:27 +08:00
stephen
a6e87e7e08 Delete dns_la.sh 2022-08-16 15:11:55 +08:00
stephen
33da8a7f62 dns.la official acme script, error fixed
fixed shcheck error
2022-08-16 09:51:59 +08:00
Awalon
68c533f777 Merge branch 'acmesh-official:master' into master 2022-08-15 23:52:39 +02:00
stephen
671eecf203 www.dns.la official acme script
www.dns.la official acme script
2022-08-15 18:10:18 +08:00
neil
2454ac8ef1 don't upload log 2022-08-14 17:44:16 +08:00
neil
20f097faa4 typo 2022-08-14 16:33:48 +08:00
neil
5dba8b493d fix log pattern 2022-08-14 16:25:28 +08:00
neil
eb27013fba Merge pull request #4242 from acmesh-official/dev
fix ip test
2022-08-14 15:34:54 +08:00
neilpang
4f8d1c5c9d fix ip test 2022-08-14 15:29:28 +08:00
neilpang
74168c3e05 fix ip test for pebble 2022-08-14 15:25:48 +08:00
neil
cece848801 Merge pull request #4241 from acmesh-official/dev
sync
2022-08-13 19:21:23 +08:00
neil
7ddbeaa078 Merge pull request #4222 from Marco4223/master
Fix and Upgrade KAS API Call.
2022-08-13 17:57:48 +08:00
Awalon
2d4aa7ff8b Added example and URL for API key 2022-08-13 05:34:05 +02:00
neil
79e044ac31 fix format 2022-08-13 11:16:40 +08:00
neil
15ae5a5135 fix format 2022-08-13 11:14:22 +08:00
Awalon
5684b7c329 dns_gd (GoDaddy): Delete TXT record instead of just setting them to an empty value. Replaced "#todo: check if the record takes effect" by some error handling and validation. 2022-08-13 05:02:12 +02:00
neil
7e96120353 fix message 2022-08-13 09:33:43 +08:00
neil
cc36421fe5 fix typo 2022-08-13 09:31:36 +08:00
neil
683aa727d5 fix log path 2022-08-13 09:14:06 +08:00
neil
ea07b495ac change message 2022-08-13 09:09:08 +08:00
neil
8d211c3524 fix log name 2022-08-13 09:01:57 +08:00
neil
ab8df82563 fix log name 2022-08-11 22:15:38 +08:00
neil
8ba9c4ab97 support https_proxy for https://github.com/acmesh-official/acme.sh/pull/1838 2022-08-10 22:00:46 +08:00
neil
2f70b8682e add logs 2022-08-10 21:44:22 +08:00
neil
86dd4ea480 fix https://github.com/acmesh-official/acme.sh/issues/4231 2022-08-08 21:11:16 +08:00
neilpang
204e5f4418 fix https://github.com/acmesh-official/acme.sh/issues/4232 2022-08-08 18:22:07 +08:00
neilpang
044a9bb6d3 fix https://github.com/acmesh-official/acme.sh/issues/4231 2022-08-08 13:19:38 +08:00
neil
a31143328e Merge pull request #4187 from Spider84/fix/dns_regru
Unable to add TXT record to IDN domain on reg.ru
2022-08-07 12:20:10 +08:00
neil
2bb29a105c fix pr_dns.yml 2022-08-07 12:17:43 +08:00
neil
0013d98d04 Merge pull request #4229 from acmesh-official/dev
sync
2022-08-07 11:23:49 +08:00
neil
916743f44b fix pr_dns.yml 2022-08-07 11:07:04 +08:00
neil
edebe65d95 add pr_dns.yml 2022-08-07 10:54:38 +08:00
neil
c43fcd0af6 Merge pull request #4225 from acmesh-official/dev
sync
2022-08-06 23:41:13 +08:00
neil
9a5c2b88dc Update README.md 2022-08-06 23:40:12 +08:00
Marco
aaee0414c8 Fix and Upgrade
Switching from formula.php to SOAP
Now session-based login 
Only record entries with corresponding values will now be deleted
2022-08-04 09:44:35 +02:00
neil
d0c2fb9761 fix https://github.com/acmesh-official/acme.sh/issues/3833#issuecomment-1203652970 2022-08-03 23:07:13 +08:00
neil
4f076c6924 Merge pull request #4218 from billgertz/patch-1
Update dns_miab.sh
2022-08-03 21:16:20 +08:00
neil
51d4d1451a use ${{ secrets.DEBUG }}
https://github.com/acmesh-official/acme.sh/issues/4215
2022-08-03 20:55:25 +08:00
Bill Gertz
7b9d76dc65 Merge branch 'acmesh-official:master' into patch-1 2022-08-02 19:07:48 +02:00
Bill Gertz
f91aeea91c Update dns_miab.sh
Added an explicit no error (0) return on the internal _retrieve_miab_env() function. This was causing errors when acme.sh was not run with a debug level.
2022-08-02 19:01:16 +02:00
neil
4cabf84be9 Merge pull request #4214 from acmesh-official/dev
sync
2022-07-31 11:51:35 +08:00
neil
8a1f038a80 add issue.yml 2022-07-30 21:45:58 +08:00
neil
c9cab9ab74 Merge pull request #4212 from msys0843/master
Update dns_mydnsjp.sh
2022-07-30 21:19:11 +08:00
neil
bd78120bd5 Use major version of https://github.com/vmactions/freebsd-vm 2022-07-30 08:53:44 +08:00
msys0843
0de3bf0ac7 Update dns_mydnsjp.sh
To fit current mydns.jp web site.
2022-07-29 18:09:57 +09:00
neil
2d144a8b43 Add DragonFlyBSD test by https://github.com/vmactions/dragonflybsd-vm 2022-07-27 22:22:34 +08:00
neil
1a140a5515 upgrade OpenBSD by https://github.com/vmactions/openbsd-vm 2022-07-27 22:17:35 +08:00
neil
1ea8cfbfb0 Add DragonFlyBSD test by https://github.com/vmactions/dragonflybsd-vm 2022-07-27 22:15:38 +08:00
neil
64fda95186 Upgrade solaris by https://github.com/vmactions/solaris-vm 2022-07-27 22:09:22 +08:00
neil
7843c0c1b0 Upgrade VM versions from https://github.com/vmactions 2022-07-27 21:19:47 +08:00
neilpang
a3784854a7 fix https://github.com/acmesh-official/acme.sh/issues/3975 2022-07-26 13:20:00 +08:00
neil
8b7c000f47 Merge pull request #4189 from blablup/dev
Fix for issue #3735
2022-07-25 15:36:51 +08:00
neil
5b8d7a3f29 Merge pull request #4203 from acmesh-official/dev
sync
2022-07-24 23:33:46 +08:00
neil
328dbd57d4 fix for solaris 2022-07-24 16:20:44 +08:00
neil
a8c448f4cb Merge pull request #4194 from GameAnalytics/add-slack-app
Add Slack App notification hook
2022-07-19 10:54:49 +08:00
neil
de0419228f Merge pull request #4192 from skyksandr/master
Vultr Api: Update to v2
2022-07-19 10:51:04 +08:00
Grigory Starinkin
d8a4e47a13 disable "$response is referenced but not assigned" warning
the variable is assigned by the `_post` call
2022-07-18 17:20:25 +01:00
Grigory Starinkin
bc920949cb Add Slack App notification hook
Slack Incoming webhooks is a legacy custom integration - an outdated
way for teams to integrate with Slack. These integrations lack newer
features and they will be deprecated and possibly removed in the
future. Slack team do not recommend their use. Instead, it's suggested
to use Slack apps.
2022-07-18 10:50:50 +01:00
Aleksandr Kunin
0717f8591c Update to Vultr Api v2
- change endpoints
- change Api-Key header to Authorization: Bearer
2022-07-18 11:26:15 +07:00
lufi42
affb65219e Merge branch 'acmesh-official:dev' into dev 2022-07-17 13:30:37 +02:00
neil
3e628f2678 Upgrade NetBSD https://github.com/vmactions/netbsd-vm 2022-07-17 11:53:23 +08:00
neil
ddabc38e3f upgrade OpenBSD https://github.com/vmactions/openbsd-vm 2022-07-17 11:49:58 +08:00
neil
c0097497be Upgrade FreeBSD version https://github.com/vmactions/freebsd-vm 2022-07-17 11:48:58 +08:00
lufi42
78198bfdaf Merge branch 'acmesh-official:dev' into dev 2022-07-16 23:17:18 +02:00
Bjarne Saltbaek
2fb9c923f4 push for re-test 2022-07-16 14:35:49 +02:00
Bjarne Saltbaek
c485011ed1 Multidomain patch suggestion from Sandeep Mittal 2022-07-16 14:16:03 +02:00
Jesai Langenbach
0b8ae68213 Fix: cut for domain uuid with searchDOmain response 2022-07-15 16:50:38 +02:00
Jesai Langenbach
0e73128f40 Finaly found a regex wich works for sed and egrep -o and use searchDomain api for easier to parse response 2022-07-15 16:42:20 +02:00
Jesai Langenbach
927c003d22 More robust and shortend egrep 2022-07-15 14:17:32 +02:00
spider
bd73823828 reg.ru list unicode domains NOT in IDN code 2022-07-15 13:31:19 +06:00
neil
11582bc7d3 Merge pull request #4184 from Maxime-J/dnsapi-ovh
dns_ovh: save OVH_CK in all cases
2022-07-15 09:44:02 +08:00
neil
20ed4f96ba Merge pull request #4182 from NerLOR/master
Update dns_world4you
2022-07-15 09:38:31 +08:00
Maxime-J
19790e9011 dns_ovh: save OVH_CK in all cases 2022-07-14 10:54:37 +00:00
Lorenz Stechauner
3a29e03458 dns_world4you: Use _lower_case instead of tr
Signed-off-by: Lorenz Stechauner <lorenz.stechauner@necronda.net>
2022-07-14 11:25:59 +02:00
neil
e2eb685d76 upgrade FreeBSD 13.1 2022-07-13 21:06:57 +08:00
neil
86cb28fe34 Merge pull request #4151 from bbruun/new-dns-provider-dns_dnsservices
Added new 'dns' provider script for https://dns.services
2022-07-13 09:28:42 +08:00
Bjarke Bruun
bcc9679339 Removed spaces (shfmt) (missed one) 2022-07-12 22:21:38 +02:00
Bjarke Bruun
e5aeff50dc Removed spaces (shfmt) 2022-07-12 22:20:24 +02:00
Bjarke Bruun
5f44c195e9 Removed unused variable 2022-07-12 22:10:20 +02:00
Bjarke Bruun
e4387e4aad Updated delete function 2022-07-12 22:04:28 +02:00
Bjarke Bruun
b1b336804d Fixed a missed 'grep -o' to _egrep_o() 2022-07-12 16:26:45 +02:00
neil
9985c43817 Merge pull request #4165 from weidonggg/dev
Fix dns_huaweicloud provider
2022-07-12 16:32:18 +08:00
lufi42
190cac394c Merge branch 'acmesh-official:dev' into dev 2022-07-11 21:26:37 +02:00
Bjarke Bruun
ae71a5abf6 Added debug for API result 2022-07-11 18:16:03 +02:00
Bjarke Bruun
df199c5788 Updated API call for OpenBSD sed and tr as newlines does not work there 2022-07-11 18:11:55 +02:00
Bjarke Bruun
c1ba4f1b55 Added forced _log to debug deletion of records in GH Actions 2022-07-11 16:43:34 +02:00
neil
afc0097b12 Merge pull request #4139 from wsellitti/proxmoxve
deploy api script to upload certs to proxmox using proxmox api
2022-07-11 22:23:02 +08:00
neil
4e9f971c91 Merge pull request #4170 from SecT0uch/patch-1
Fix ecc certificates
2022-07-11 22:13:24 +08:00
Bjarke Bruun
b1cc28bbda Merge remote-tracking branch 'origin/master' into new-dns-provider-dns_dnsservices 2022-07-11 14:13:05 +02:00
Bjarke Bruun
80d30bdd30 Removed empty new line to trigger workflow 2022-07-11 14:08:37 +02:00
neil
f27566669b Merge pull request #4174 from Ry3nlNaToR/patch-1
Also restart Postfix container for Mailcow
2022-07-11 14:40:46 +08:00
Lorenz Stechauner
29f12ddaf4 dns_world4you: Improve error message handling
Signed-off-by: Lorenz Stechauner <lorenz.stechauner@necronda.net>
2022-07-10 22:22:12 +02:00
Lorenz Stechauner
ed15ff0515 dns_world4you: Fix upper case fqdn issues
Signed-off-by: Lorenz Stechauner <lorenz.stechauner@necronda.net>
2022-07-10 20:30:41 +02:00
Lorenz Stechauner
a8f71f79fe dns_world4you: Update error handling
Signed-off-by: Lorenz Stechauner <lorenz.stechauner@necronda.net>
2022-07-10 20:03:30 +02:00
Lorenz Stechauner
68c2478e0e dns_world4you: Handle already logged in sessions
Signed-off-by: Lorenz Stechauner <lorenz.stechauner@necronda.net>
2022-07-10 18:55:36 +02:00
lufi42
be07fe9e9f Merge branch 'acmesh-official:dev' into dev 2022-07-10 18:23:12 +02:00
Lorenz Stechauner
4d8b661d51 dns_world4you: Fix cookie parsing issue
Signed-off-by: Lorenz Stechauner <lorenz.stechauner@necronda.net>
2022-07-10 17:51:40 +02:00
lufi42
ca0981645f Fixed shfmt error 2022-07-10 17:34:30 +02:00
lufi42
bc7e02b47a Fixed removal of TXT record when subdomain is case-sensitive and improved debug logging
Plesk SPI return domain names always lower-case. Therefore the search for domain names in the API response must be case-insensitve. Set debug logging to the values that are reallys used for the spi calls.

added comment
2022-07-10 17:22:59 +02:00
lufi42
55a55e9f74 Fixed debug log to prevent globbing and word splitting. 2022-07-10 17:22:59 +02:00
lufi42
b41d40da40 Extended debug logging in dns_pleskxml_rm() 2022-07-10 17:22:59 +02:00
lufi42
ba3e088b23 Improved error handling
Improved error handling when result contains data-structure which might contain another status-flag that is related to the status of the related object and not the api call

Revert "Improved error handling"

This reverts commit fa6df1cfab134d38baad19fc1caa0842f00416d5.

Revert "Revert "Improved error handling""

This reverts commit 5a4b78392f063863ee9f56686f5c429e9376af1b.
2022-07-10 17:22:59 +02:00
neil
1b59b0b739 Merge pull request #4176 from acmesh-official/dev
sync
2022-07-10 18:19:02 +08:00
neil
093cfcdf42 Add NetBSD Test by: https://github.com/vmactions/netbsd-vm 2022-07-10 18:01:49 +08:00
Ry3nlNaToR
41801a60ad Also restart postfix 2022-07-09 14:30:18 +01:00
Bjarke Bruun
5ff0957861 Added empty new line to trigger workflow 2022-07-08 07:49:20 +02:00
Bjarke Bruun
6913b8beb5 Merge branch 'acmesh-official:master' into new-dns-provider-dns_dnsservices 2022-07-07 20:33:32 +02:00
Bjarke Bruun
c8d17bc363 Re-commit (removed non-needed #'tag) 2022-07-07 20:30:48 +02:00
Jordan ERNST
2cbf1259a8 Fix for ECC certificates 2022-07-07 17:20:23 +02:00
neil
59dc513ac3 add OpenBSD test 2022-07-07 22:30:35 +08:00
neil
87b110bb86 add OpenBSD CI test: https://vmactions.org 2022-07-07 22:27:18 +08:00
Bjarke Bruun
1b3e1a7abe Changed 'grep -E' to '_egrep_o' 'removed ()' 2022-07-07 15:05:12 +02:00
Bjarke Bruun
0afabc60ae Changed 'grep -E' to '_egrep_o' 2022-07-07 15:00:12 +02:00
neil
2d4ea720eb Merge pull request #2606 from ianw/no-exit-manual-dns
Don't exit with issue failure if in DNS manual mode
2022-07-07 20:02:55 +08:00
neil
9c757bbe6e Update acme.sh 2022-07-07 20:01:43 +08:00
lufi42
40e0d72105 Merge branch 'acmesh-official:dev' into dev 2022-07-07 13:27:40 +02:00
Bjarke Bruun
eba788e8c9 Removed check for _acme-challenge and acmetestXyzRandomName.github-test sub-domain 2022-07-07 10:59:25 +02:00
Bjarke Bruun
444b111a62 Fixed acmetest for domain acmetestXyzRandomName.github-test.<domain> that was explicitly disallowed as it is not _acme-challenge 2022-07-07 09:40:18 +02:00
Bjarke Bruun
a364ab4ea7 Added '.' to 'DNS Services' as that is the correct provider name 2022-07-06 12:10:19 +02:00
Ian Wienand
be7840c827 Exit with separate failure if in DNS manual mode
In our environment we use DNS manual mode and take the TXT record
output of acme.sh and process it with Ansible to install the records
(then we call renew later when the records have been pushed to the DNS
servers by a whole bunch of other bits).

One problem is that after getting/showing the TXT records, acme.sh
always returns 1.  This makes it difficult to tell if there is
actually an error condition.

Since we have set the manual-mode flag, not installing the DNS records
is an expected correct result.  This returns a separate error code for
this situation (3), which can be distinguished in automation.
2022-07-06 06:20:28 +10:00
nil
a46e51e8db Update format code. 2022-07-02 01:22:46 +00:00
nil
789ebb8990 Fix dns_huaweicloud provider
1. Fix huaweicloud api use iam account get token fail.
2. Default use ap-southeast-1 project name, don't need query project id.
2022-07-01 09:12:06 +00:00
neil
e3cd96bf19 Merge pull request #4164 from acmesh-official/dev
sync
2022-06-30 23:18:53 +08:00
neilpang
7746042adc fix https://github.com/acmesh-official/acme.sh/issues/4160
fix https://github.com/acmesh-official/acme.sh/issues/4160
2022-06-30 23:07:18 +08:00
lufi42
dfe80556d3 Merge branch 'acmesh-official:dev' into dev 2022-06-28 23:47:36 +02:00
Bjarke Bruun
543c4423a2 Added bug report link to dns_dnsservices.sh 2022-06-24 07:42:00 +02:00
Bjarke Bruun
3bd4d32b8d Updated bug report URL 2022-06-23 11:48:39 +02:00
Bjarke Bruun
56a686d3e0 Code formatting (shfmt) 2022-06-23 09:21:20 +02:00
Bjarke Bruun
2f97c789dd Code formatting (shellcheck/shfmt) 2022-06-23 09:14:17 +02:00
Bjarke Bruun
04ca808e80 Code formatting (shfmt) 2022-06-23 08:31:40 +02:00
neil
9b79743c5d Update proxmoxve.sh 2022-06-23 14:12:53 +08:00
neil
a386826808 Update proxmoxve.sh 2022-06-23 14:11:36 +08:00
neil
668894fc4d Update proxmoxve.sh 2022-06-23 14:08:24 +08:00
Bjarke Bruun
dc882e6279 Removed empty space 2022-06-23 08:06:28 +02:00
Bjarke Bruun
d6eebf82be Removed a few empty lines 2022-06-23 07:57:05 +02:00
William Sellitti
799f509ba9 typo 2022-06-22 23:19:12 -04:00
Bjarke Bruun
688a234127 Added new 'dns' provider script for https://dns.services 2022-06-22 18:56:25 +02:00
Marcel Hellkamp
095697900b fix: Challenge not skipped for pre-validated wildcard domain orders
Some CAs auto-validate orders based on account-level rules and do not
require a challenge at all. Sectigo introduced a non-standard challenges
named 'sectigo-dns-01', presumably to work around this issue in certbot.
This also works for non-wildcard domains in acme.sh, but wildcard domains
are rejected because acme.sh hard-codes 'dns-01' as the only allowed
challenge for wildcard domains, which is not offered by Sectigo.

This change simply moves the '"status":"valid"' check up a bit and ignores
challenge type mismatches or missing tokens if no challenge is needed anyway.
2022-06-22 18:18:20 +02:00
neilpang
6ccf617d62 clear CF_Zone_ID 2022-06-21 10:12:06 +08:00
William Sellitti
b3b4811b2c added savedeployconf to preserve environment variables usedi in initial deployments 2022-06-19 22:01:56 -04:00
William Sellitti
966e4246e5 Merge branch 'proxmoxve' of gitlab.lan.home.wesitcllc.com:software/upstream/acme.sh into proxmoxve 2022-06-19 01:49:51 -04:00
William Sellitti
9377c4f3ad Merge branch 'proxmoxve' of github.com:wsellitti/acme.sh into proxmoxve 2022-06-19 01:46:45 -04:00
William Sellitti
b876128635 forced content-type to json 2022-06-19 01:46:10 -04:00
William Sellitti
c0da801580 Revert "'+' are being converted to ' ' at some point"
This reverts commit 149310e1ec.
2022-06-18 17:00:36 -04:00
William Sellitti
149310e1ec '+' are being converted to ' ' at some point 2022-06-18 16:58:15 -04:00
William Sellitti
4e625c18dc Revert "seems like the escaped new lines aren't remaining escaped new lines with the new version of curl"
This reverts commit a5d5113be3.
2022-06-18 16:56:46 -04:00
William Sellitti
a5d5113be3 seems like the escaped new lines aren't remaining escaped new lines with the new version of curl 2022-06-18 16:55:12 -04:00
William Sellitti
7900c493af debugging for the payload 2022-06-18 16:43:25 -04:00
William Sellitti
76fe5d8831 those where flipped by mistake 2022-06-18 16:39:32 -04:00
William Sellitti
37031721dd typo 2022-06-18 15:52:18 -04:00
William Sellitti
3cc283cbee not generating files any more 2022-06-18 15:44:25 -04:00
William Sellitti
35cf98fff2 sensititive things debugged at a higher level 2022-06-18 15:41:38 -04:00
William Sellitti
ca41ea2d5c added _getdeployconf to set all of the environment variables 2022-06-18 15:40:05 -04:00
William Sellitti
daffc4e6a4 typo, using _H1 to provide header keys. 2022-06-18 12:21:14 -04:00
William Sellitti
5f3cb9019b fixed to use _post function instead of curl 2022-06-18 12:18:33 -04:00
neil
4951b58b21 Merge pull request #4086 from plett/aws-multiline-comments
Squash multiline responses. Fixes issue #4085
2022-06-18 15:55:10 +08:00
neil
7be7586971 Update proxmoxve.sh 2022-06-18 15:01:38 +08:00
William Sellitti
6d64098288 shell check war warning against unnecessary use of cat 2022-06-14 23:46:09 -04:00
William Sellitti
4351110082 properly quoted variable names 2022-06-14 22:38:06 -04:00
William Sellitti
6652138d3e fixed per shellcheck's preference for -n instead of ! -z 2022-06-14 22:33:38 -04:00
William Sellitti
c8d0d475e4 deploy api script to upload certs to proxmox using proxmox api 2022-06-11 13:49:31 -04:00
neil
39b25029fc Merge pull request #4128 from capile/dev
fixed compatibility for UltraDNS API v3
2022-06-09 13:13:43 +08:00
neil
b5cabd6d8e Merge pull request #4131 from ffy/master
change _dbase64 in deploy/qiniu.sh to single line
2022-06-09 13:12:56 +08:00
Debian Bear
b169a5c707 change _dbase64 to single line 2022-06-08 22:44:10 +08:00
Guilherme Capilé
4f816c06b0 variable expansion consistency & actions push 2022-06-07 11:59:34 -03:00
Guilherme Capilé
b5f49d9563 fixed compatibility for UltraDNS API v3: https://docs.ultradns.neustar/Content/REST%20API/Content/REST%20API/Zone%20API/Zone%20API.htm; also a minor bugfix for fecthing the domain_id using egrep 2022-06-06 20:10:05 -03:00
neil
274fd5ab8b Merge pull request #4124 from rmalchow/dev
check all pages first, then go up
2022-06-06 15:45:13 +08:00
rm
e48d7de763 push to run actions 2022-06-05 15:46:42 +02:00
rm
f426940bd2 check all pages first, the go up 2022-06-04 20:24:33 +02:00
neil
6c11dd12d7 Merge pull request #4118 from retoo/bugfix/google-dns-escape-arguments
dns_gcloud: disable argument parsing for challenges
2022-06-02 09:03:29 +08:00
Reto Schüttel
c2b14d3075 dns_gcloud: disable argument parsing for challenges
fixes #3596
2022-06-01 16:51:01 +02:00
neilpang
8a144ebfee fix https://github.com/acmesh-official/acme.sh/issues/4117 2022-06-01 18:06:14 +08:00
neilpang
5440fcdf54 check the file path before copying 2022-06-01 18:05:51 +08:00
neil
66b2d496af Merge pull request #4116 from rbelnap/dns_namecheap_error_fix
Dns namecheap error fix
2022-06-01 09:10:52 +08:00
Bob Belnap
444a0282d7 rename _error _err
When there are errors with namecheap hosts, acme.sh fails with:

dns_namecheap.sh: line 262: _error: command not found

Based on usage elsewhere in the file, I believe this should be _err
2022-05-31 11:41:22 -04:00
neil
f897ab4eb8 Merge pull request #4114 from acmesh-official/dev
sync
2022-05-31 09:29:20 +08:00
neilpang
993c187e37 fix https://github.com/acmesh-official/acme.sh/issues/4105
fix https://github.com/acmesh-official/acme.sh/issues/4105
2022-05-29 15:08:15 +08:00
neilpang
3ce67b282f merge https://github.com/acmesh-official/acme.sh/pull/4108
merge https://github.com/acmesh-official/acme.sh/pull/4108
2022-05-29 15:03:09 +08:00
neilpang
606e59a5d0 fix https://github.com/acmesh-official/acme.sh/issues/4110
fix https://github.com/acmesh-official/acme.sh/issues/4110
2022-05-29 14:56:30 +08:00
neil
0f26b1eafb Merge pull request #4096 from nederhost/dev
Fix dns_nederhost to work correctly with wget instead of curl.
2022-05-24 22:35:14 +08:00
neil
d2a9d731ed Update ssh.sh 2022-05-24 22:25:44 +08:00
neil
80e6b1fc01 Merge pull request #4102 from lbrocke/dns-api-ionos-v1.0.1
dnsapi/ionos: Update to API version 1.0.1
2022-05-23 11:44:50 +08:00
Lukas Brocke
58a89edad7 dnsapi/ionos: Update to API version 1.0.1
The REST API now sends back response bodies for UPDATE and CREATE
operations.
2022-05-22 13:24:18 +02:00
neil
bfe47eb152 Merge pull request #4101 from Djelibeybi/fix-dns-oci
Fix _dbase64 decode of OCI_CLI_KEY
2022-05-21 14:41:44 +08:00
Avi Miller
32adc38e94 Fix _dbase64 decode of OCI_CLI_KEY
The change made in #4057 broke the decoding of OCI_CLI_KEY from
the encoded OCI_CLI_KEY_FILE content so this removes the multiline
parameter to fix it.

Signed-off-by: Avi Miller <avi.miller@oracle.com>
2022-05-21 14:36:10 +10:00
Marvo2011
1584971908 Merge branch 'acmesh-official:dev' into dev 2022-05-20 08:52:05 +02:00
Marvo2011
025bebb3e2 Merge pull request #5 from AlvinSchiller/dev
domain lookup for DNS_MAP changed.
2022-05-20 08:51:06 +02:00
Sebastiaan Hoogeveen
4047adcc35 Force a commit. 2022-05-18 16:12:37 +02:00
AlvinSchiller
d4cf03c9fd changes due to inkompabilities of some distros 2022-05-18 11:48:48 +02:00
Sebastiaan Hoogeveen
5ba2068fc2 Fix dns_nederhost to work correctly with wget instead of curl.
The dns_nederhost DNS API relies on the exact HTTP status code to be
returned (e.g.  204); however, the _get function always returns 200 for a
succesful call when using wget instead of curl.  This patch fixes this by
using the _post function for all requests done by dns_nederhost.
2022-05-16 14:27:24 +02:00
PM Extra
3ce7d410c8 improve doc comments 2022-05-14 22:59:02 +08:00
PM Extra
74f28021e7 fix format again 2022-05-14 22:49:40 +08:00
PM Extra
f90cbb636a fix format 2022-05-14 22:41:59 +08:00
PM Extra
c8929ca0cb support specifying port for each host 2022-05-14 22:29:48 +08:00
PM Extra
9fb5bb620d refact ssh hook to use deploy config 2022-05-14 22:28:02 +08:00
PM Extra
ed58f32052 Merge branch 'dev' into feature/ssh_scp 2022-05-14 15:43:26 +08:00
Paul Lettington
6d5743c506 Squash new lines in API response 2022-05-12 18:57:32 +01:00
neil
a551619de6 Merge pull request #4080 from aorith/dev
dns_aws: Fix when _acme-challenge is a hostedzone
2022-05-12 21:34:37 +08:00
neil
873b113cb3 Update dns_aws.sh 2022-05-12 17:36:19 +08:00
Manuel Sanchez Pinar
2280e66d73 dns_aws: Fix when _acme-challenge is a hostedzone
The function '_get_root' tries to retrieve the
    hostedzone iterating the domains, eg:
      1. srv.prod.example.com
      2. prod.example.com
      3. example.com
    This doesn't work if '_acme-challenge' is in it's
    own hostedzone for security reasons.
    Starting that iteration with '_acme-challenge.srv.prod.example.com'
    fixes this issue.
2022-05-12 10:51:15 +02:00
neil
2133897bbe Merge pull request #4079 from acmesh-official/dev
sync
2022-05-11 13:36:35 +08:00
neilpang
bee5cb55a1 fix test 2022-05-11 10:20:49 +08:00
neil
0a0838b616 Merge pull request #4078 from cboylan/fix-key-length-check
Fix Le_Keylength checks during renewals
2022-05-11 09:09:28 +08:00
Clark Boylan
b376dfa1e6 Fix Le_Keylength checks during renewals
When performing renewals acme.sh checks key length values to determine
if a new key should be created with createDomainKey(). However, older
acme.sh stored key length as an empty value if the default of 2048 was
desired. Now it is explicit and the explict check of 2048 against "" is
causing createDomainKey() to always be called with fails without
--force.

Fix this by converting the keylength value to 2048 if an empty string is
returned from the config file. acme.sh will then write out 2048 updating
old keys and configs to the explicit version.

Issue: 4077
2022-05-10 10:42:19 -07:00
neil
7ac0577b34 Merge pull request #4076 from acmesh-official/dev
sync
2022-05-10 22:25:12 +08:00
denkristoffer
f16e060e87 Create dns_vercel.sh 2022-05-10 22:22:14 +08:00
Sandeep Mittal
9aaae24583 Update callmebotWhatsApp.sh
unused variable removed and cleaned.
2022-05-10 22:22:14 +08:00
neil
915ced7b92 Update callmebotWhatsApp.sh 2022-05-10 22:22:14 +08:00
neil
5a36b9075f Update callmebotWhatsApp.sh 2022-05-10 22:22:14 +08:00
Sandeep Mittal
b5a7f46ecc Update callmebotWhatsApp.sh
variable updated to caps
2022-05-10 22:22:13 +08:00
neil
4381657c5e Update callmebotWhatsApp.sh 2022-05-10 22:22:13 +08:00
Sandeep Mittal
d440b2f2b2 Update callmebotWhatsApp.sh
Added CallMeBot API for WhatsApp Notifications.
2022-05-10 22:22:13 +08:00
Sandeep Mittal
5b42aea9e7 Create callmebotWhatsApp.sh 2022-05-10 22:22:13 +08:00
neil
e1d7a6b9ac fix renew server 2022-05-10 22:22:13 +08:00
neil
38778f8adc fix renew server 2022-05-10 22:22:12 +08:00
neil
8b7a86bd17 support "server" for renew and renewall 2022-05-10 22:22:12 +08:00
neilpang
619bae745b start 3.0.5 2022-05-10 22:22:12 +08:00
AlvinSchiller
2cf72bad30 domain lookup for DNS_MAP changed. 2022-05-10 07:09:31 +02:00
neil
e6959f093c Merge pull request #4070 from acmesh-official/dev
sync
2022-05-06 18:06:37 +08:00
neilpang
8d783e8e1f fix https://github.com/acmesh-official/acme.sh/issues/4069 2022-05-06 18:04:29 +08:00
neilpang
f03098551e start 3.0.4 2022-05-04 18:44:37 +08:00
neil
6887805402 Merge pull request #4067 from acmesh-official/dev
sync
2022-05-04 18:36:45 +08:00
neil
7f9074adbf fix format 2022-05-03 21:35:26 +08:00
neil
64847afc3f save the default key length 2022-05-03 21:19:29 +08:00
Marvo2011
c4df8090e2 Merge branch 'acmesh-official-dev' into dev 2022-05-03 13:06:16 +02:00
AlvinSchiller
fe3523f47a Fix shfmt 2022-05-03 13:04:48 +02:00
AlvinSchiller
199d846acb Pseudo commit tp trigger Github Actions 2022-05-03 13:04:48 +02:00
AlvinSchiller
b07e479840 Save domain dependent values in domain.conf after successfull use 2022-05-03 13:04:48 +02:00
AlvinSchiller
9bf37fde02 Added variable checks 2022-05-03 13:04:48 +02:00
Marvo2011
1054325b2d Rename delete function, add info 2022-05-03 13:04:48 +02:00
Marvo2011
ef8cb11707 Fix shfmt 2022-05-03 13:04:48 +02:00
Marvo2011
c23c40df8a Fix shellcheck, use double quote 2022-05-03 13:04:48 +02:00
Marvo2011
77d606df34 Add custom option to map multidomain RIDs 2022-05-03 13:04:48 +02:00
Marvo2011
e717c9dba2 Start ShellCheck and CI Test 2022-05-03 13:04:48 +02:00
Marvo2011
3d312e2140 Added Selfhost DNS API
+ShellCheck 
+ACME v2 compatible

Example:
- Fist create 2 new TXT records on _acme-challenge.example.com
- Now note the ID in (...) from the edit page behind "_acme-challenge.example.com"

export SELFHOSTDNS_USERNAME=myname
export SELFHOSTDNS_PASSWORD=mypass
export SELFHOSTDNS_RID=id_of_txt_record
export SELFHOSTDNS_RID2=id_of_second_txt_record
acme.sh --issue -d example.com  --dns  dns_selfhost
2022-05-03 13:04:48 +02:00
neilpang
18de21f723 fix tunnel version 2022-05-03 12:54:49 +02:00
neilpang
6aebaf6f47 upgrade Solaris 2022-05-03 12:54:19 +02:00
neil
641f6977a9 Merge pull request #4065 from acmesh-official/dev
sync
2022-05-03 18:38:45 +08:00
Marvo2011
a092a2fa43 Merge pull request #3 from AlvinSchiller/dev
Save domain dependent values in domain.conf
2022-05-03 09:17:22 +02:00
neil
84c2b0c3d7 Merge pull request #4063 from nicolaspn/OVH_DNS_refresh_after_delete_txt_record
Ovh dns refresh after delete txt record
2022-05-02 23:34:14 +08:00
nicolaspn
24ce7c1991 Add call dns OVH API for refresh domain after delete TXT record 2022-05-02 16:16:56 +02:00
neil
8be3465f94 Merge pull request #4061 from acmesh-official/dev
Dev
2022-04-30 22:47:57 +08:00
AlvinSchiller
227eac10f1 Fix shfmt 2022-04-29 23:05:46 +02:00
AlvinSchiller
1cbd5485e7 Pseudo commit tp trigger Github Actions 2022-04-29 22:53:36 +02:00
AlvinSchiller
610c3cf681 Save domain dependent values in domain.conf after successfull use 2022-04-29 22:26:36 +02:00
AlvinSchiller
96d45cc341 Added variable checks 2022-04-29 22:23:39 +02:00
neil
8ba7d02fdb Merge pull request #4059 from NerLOR/master
dns_world4you: fix _parse_paket_nr
2022-04-29 14:48:31 +08:00
neil
ef8a199a5a Merge pull request #4057 from mrakopes/master
issue 3007 - fix base64 decoding logic for single- and multi-line encoded string
2022-04-29 09:25:39 +08:00
Lorenz Stechauner
db83643c1e dns_world4you: fix _parse_paket_nr
Signed-off-by: Lorenz Stechauner <lorenz.stechauner@necronda.net>
2022-04-28 20:49:55 +02:00
mrakopes
9b6f775276 fix base64 decoding logic for single- ane multi-line encoded string 2022-04-28 13:25:22 +02:00
neilpang
69040dd668 fix format 2022-04-28 18:09:26 +08:00
neilpang
14b5914233 fix renew bug 2022-04-28 18:06:07 +08:00
neil
a0eabd2298 Merge pull request #4049 from Aarup/dev
Removed GratisDNS api
2022-04-25 16:10:39 +08:00
Jakob Aarup Skov
9b27298d54 Removed GratisDNS api 2022-04-25 09:43:38 +02:00
neil
3075b4515a Merge pull request #4045 from axelhahn/4044-use-challenge-alias-false
handle challenge-alias "false"
2022-04-21 16:35:29 +08:00
neil
39bc417706 Update acme.sh 2022-04-21 07:02:53 +08:00
neil
e11e32cd52 Merge pull request #4035 from ccope-netgate/master
LoopiaAPI error handling isn't compatible with FreeBSD
2022-04-21 06:58:44 +08:00
Hahn Axel (hahn)
019a7bd66b handle challenge-alias "false" 2022-04-20 16:03:36 +02:00
neil
4d89ce5d50 read csr with empty subject
https://github.com/acmesh-official/acme.sh/issues/4024
2022-04-20 09:14:53 +08:00
Sing Yu Chan
c31027b284 use sleep infinity instead sleep 1 2022-04-20 09:04:13 +08:00
neil
f17ec7a4f5 Merge pull request #4037 from ahwayakchih/master
Update dns_mydevil.sh
2022-04-20 09:01:29 +08:00
neil
deec6aab1a Merge pull request #4039 from DerVerruckteFuchs/1984-update-URL
1984 update url
2022-04-20 09:00:14 +08:00
Bruce Lam
3e8d9a1987 added: ipv6 identifier support 2022-04-20 08:23:22 +08:00
DerVerruckteFuchs
5e465a298f Update 1984 Hosting's URL 2022-04-15 23:04:10 -04:00
Marcin Konicki
515c9e7811 Fix DNS handling for MyDevil.net
MyDevil updated their tool to require y|n confirmation when deleting record.
2022-04-15 10:38:45 +02:00
Christopher Cope
03c8309703 Fix dns_loopia on FreeBSD 2022-04-13 15:41:44 -04:00
neilpang
2c28d6b10c fix for renew server 2022-04-13 20:20:28 +08:00
neil
df79443ed8 Merge pull request #3997 from tumarov/fornex_com_support
fornex.com API support
2022-04-12 11:01:53 +08:00
neil
2b891f7f1d Update dns_fornex.sh 2022-04-12 10:11:05 +08:00
neil
e4ed0b1884 Merge pull request #4029 from quthla/patch-1
Store Mailcow deploy parameters
2022-04-12 10:06:35 +08:00
neil
c8c1c09189 Merge pull request #4032 from acmesh-official/dev
sync
2022-04-12 10:05:22 +08:00
quthla
08ae8cc3cb Fix 2022-04-11 11:39:21 +02:00
quthla
201673ca8a Store Mailcow deploy parameters 2022-04-11 00:29:55 +02:00
Bruce Lam
29e23ac9ce Due to down of cloudxns.net, remove dns_cx.sh 2022-04-10 19:57:25 +08:00
neilpang
00483e8cdd exclude zerossl tests in the CI
It's not stable
2022-04-10 19:42:49 +08:00
neil
83da01a2e1 Merge pull request #4027 from acmesh-official/dev
sync
2022-04-10 14:49:09 +08:00
neil
7cd6ff054b add 2022-04-10 14:48:10 +08:00
neilpang
6be2bb2289 Update acme.sh
revert only when there is no `--server` specified.
2022-04-08 22:28:21 +08:00
neilpang
439defca42 switch from staging api to production api
https://github.com/acmesh-official/acme.sh/issues/2401
2022-04-08 22:15:26 +08:00
neil
8a85bb2989 Merge pull request #4017 from exogee-technology/dev
Fix / Netlify API should only match exact domain matches.
2022-04-08 21:03:54 +08:00
neil
5e7519183d Merge pull request #4020 from sjau/dns_ispconfig_typo
dns_ispconfig: add missing brackets
2022-04-07 17:29:25 +08:00
hyper_ch
40e7eca1ee dns_ispconfig: adding missing brackets 2022-04-07 11:07:06 +02:00
Kevin Brown
481f02de88 Also check for the closing quote so that only exact domain matches are found. 2022-04-06 14:29:25 +10:00
neilpang
6a90856f0e don't renew cert if valid-to is set to an absolute date
don't renew cert if valid-to is set to an absolute date
2022-04-05 17:05:33 +08:00
neil
dcbbee8adb Merge pull request #4012 from acmesh-official/dev
Support "NotBefore" and NotAfter
2022-04-03 22:01:00 +08:00
neilpang
225adcc836 fix renewal for validto
fix renewal for validto
2022-04-03 21:58:41 +08:00
neilpang
0f607413d0 fix for solaris time format 2022-04-03 20:05:30 +08:00
neilpang
922553032b typo 2022-04-02 09:35:17 +08:00
neilpang
b49999721c Update acme.sh 2022-04-01 21:58:29 +08:00
neilpang
de4c4eedd8 Support NotBefore and NotAfter
Add `--valid-from` and `--valid-to`:
https://github.com/acmesh-official/acme.sh/wiki/Validity
2022-04-01 21:22:42 +08:00
neilpang
bcc984fc09 minor 2022-03-31 09:46:42 +08:00
neilpang
d53262fab6 fix update account
fix https://github.com/acmesh-official/acme.sh/issues/4009
2022-03-31 09:35:32 +08:00
neilpang
532e44bcea normalize domains
fix https://github.com/acmesh-official/acme.sh/issues/4005
2022-03-30 23:37:38 +08:00
neilpang
3fb67629c1 Update README.md 2022-03-30 23:06:07 +08:00
neil
6145465823 Merge pull request #4006 from acmesh-official/dev
sync
2022-03-30 23:03:44 +08:00
neilpang
fb5091a388 support Google ACME server
see: https://github.com/acmesh-official/acme.sh/wiki/Server
2022-03-30 22:47:12 +08:00
Marvo2011
d6c68f1a84 Rename delete function, add info 2022-03-28 13:03:02 +02:00
neilpang
0d05f9ba80 Update acme.sh
fix https://github.com/acmesh-official/acme.sh/issues/4001
2022-03-27 12:08:24 +08:00
neil
a300df0020 Update dns_fornex.sh 2022-03-25 15:48:17 +08:00
neil
a50158cbeb Merge pull request #3982 from waldner/master
Geoscaling: read credentials when removing records too
2022-03-24 15:15:58 +08:00
Timur Umarov
7278fd25e5 Added fornex.com api 2022-03-23 17:46:38 +03:00
neil
6fb8c0ec4c Merge pull request #3989 from abiessmann/deploy_routeros_handle_remote_errors
deploy/routeros: handle errors
2022-03-20 13:30:58 +08:00
neil
07cedc55e2 Merge pull request #3978 from nikolajbrinch/dev
Fixes Simply.com to use REST API version 2 with Basic Auth
2022-03-20 13:19:13 +08:00
neil
ae3cc81f03 Merge pull request #2924 from ianepperson/master
Add Discord notification
2022-03-20 12:43:43 +08:00
neil
97a45e3b02 Update discord.sh 2022-03-20 12:43:23 +08:00
neil
451b290b79 Update discord.sh 2022-03-20 12:42:35 +08:00
neil
499ea07934 Merge pull request #3993 from imgrant/deploy-truenas-s3-feature
feat: Configure TrueNAS S3 certificate
2022-03-20 12:34:58 +08:00
Ian Grant
afa06267a2 style: Neaten up some of the info & error messages, fix some typos 2022-03-19 20:39:48 +00:00
Ian Grant
d4a6d9c076 fix: Adjust the sed extraction of certificate ID from JSON response
Prior to this, an error in the regex didn't match. Resolves #3992 (TrueNAS deploy hook fails to set certificate for FTP or WebDAV)
2022-03-19 20:38:47 +00:00
Ian Grant
c3f6112443 feat: Configure certificate for TrueNAS S3 service (MinIO) 2022-03-19 20:36:11 +00:00
Andreas Bießmann
3411b736dd deploy/routeros: add error handling for scp
In order to stop processing on failure to copy certificate
to remote side, fail on error of scp command.

Signed-off-by: Andreas Bießmann <andreas@biessmann.org>
2022-03-18 09:10:12 +01:00
Andreas Bießmann
c603b9c40b deploy/routeros: add error handling for ssh
In order to detect errorneous scripts on remote side, catch return code
and handle it respectively.

Signed-off-by: Andreas Bießmann <andreas@biessmann.org>
Reviewed-by: Ross Shen @sjtuross
2022-03-18 09:07:59 +01:00
neil
1e2c5d038f Merge pull request #3986 from abiessmann/fix_depoly_routeros
deploy/routeros.sh: fix routeros script
2022-03-17 21:25:59 +08:00
Andreas Bießmann
9d6d96adf3 deploy/routeros.sh: fix routeros script
Commit c46ceb06b4 introduced an error in
routeros script.

Fix it!

Signed-off-by: Andreas Bießmann <andreas@biessmann.org>
2022-03-17 12:24:42 +01:00
waldner
8d574ecb34 Geoscaling: get creds for removal too 2022-03-15 18:56:54 +01:00
neil
9ebb2ac2e4 Merge pull request #3980 from acmesh-official/dev
sync
2022-03-14 23:02:08 +08:00
neil
7b935eec5d Merge pull request #3979 from dislazy/dev
fix(notify):remove nofity,move weixin_work.sh to notify
2022-03-11 13:56:53 +08:00
bosong
b209f66654 fix(notify):remove nofity,move weixin_work.sh to notify 2022-03-11 13:41:12 +08:00
neil
b98b4951b4 Merge pull request #3669 from youuy/master
Add Weixin Work notify hook
2022-03-11 12:21:55 +08:00
Nikolaj Brinch Jørgensen
227d62a5dc Fixes Simply.com to use REST API version 2 with Basic Auth 2022-03-10 11:13:38 +01:00
neil
7fae5553a8 Merge pull request #3977 from gabbe/Encode_password
Accept some special characters in password and some error handling
2022-03-10 09:10:17 +08:00
Gabriel Thörnblad
6ead019873 Accept some special characters in password and added a little bit better error handling 2022-03-09 17:12:09 +01:00
lufi42
6d2ab4d270 Merge branch 'dev' of https://github.com/lufi42/acme.sh into dev 2022-03-09 01:47:51 +01:00
lufi42
a6b58bc88d Corrected use of Plesk API calls to fetch all domain for all Plesk editions
This implementation of the Plesk API will add support for Plesk web admin edition and will now discover all domains ( of customers & administrative users) managed by the specific plesk instance.

The previous implementation of the Plesk API uses the customer API. This brings two problems:
1. The current API call only fetches the domains of resellers/customers and not the domains that are managed by administrative users.
compare:
https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-customer-accounts/retrieving-the-list-of-customer%E2%80%99s-domains.75309/
https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-plesk-server/getting-server-information/response-packet-structure-and-samples/list-of-domains.75294/

2. The customer API is only available in the web pro/host editions. The most common license on VPS/Dedicated Servers is nowadays the web admin edition. See: https://www.plesk.com/editions/

The correct way to get all domains in all Plesk editions is to use the Sites (Domains) API:
https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-sites-domains/getting-information-about-sites.66583/
This way is working for all plesk editions the same way.
2022-03-09 01:42:26 +01:00
lufi42
ea3c37d754 Corrected use of Plesk API calls to fetch all domain for all Plesk editions
This implementation of the Plesk API will add support for Plesk web admin edition and will now discover all domains managed by the specific plesk instance.

The existing implementation of the Plesk API uses the customer API. This brings two problems:
1. The current API call only fetches the domains of resellers/customers and not the domains that are managed by  administrative users.
compare:
https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-customer-accounts/retrieving-the-list-of-customer%E2%80%99s-domains.75309/
https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-plesk-server/getting-server-information/response-packet-structure-and-samples/list-of-domains.75294/

2. The customer API is only available in the pro/admin editions. The most common license on VPS/Dedicated Servers is the web host edition. See: https://www.plesk.com/editions/

The correct way to get all domains in all Plesk editions is to use the Sites (Domains) API:
https://docs.plesk.com/en-US/obsidian/api-rpc/about-xml-api/reference/managing-sites-domains/getting-information-about-sites.66583/
2022-03-09 01:36:06 +01:00
neil
e58b00d9a2 Merge pull request #3964 from gabbe/Loopia_API_is_updated
Update dns_loopia.sh
2022-03-07 21:52:03 +08:00
Gabriel Thörnblad
b75e90f8c9 Double quote variables (shellcheck suggestions) 2022-03-07 10:28:09 +01:00
Gabriel Thörnblad
e82f3439c3 Trigger CI 2022-03-07 10:13:45 +01:00
neil
0bc8e3bee5 Merge pull request #3965 from waldner/master
geoscaling DNS API
2022-03-07 09:08:01 +08:00
waldner
13f80acb2d geoscaling DNS API 2022-03-05 19:34:36 +01:00
neil
8fe813acff Merge pull request #3932 from peterlh/master
Added curanet dns support
2022-03-05 18:58:14 +08:00
Gabriel Thörnblad
0ed4fc6a12 Update dns_loopia.sh
Loopia API is now less tolerant so we need another <value> tag surrounding the <struct>
2022-03-04 13:38:05 +01:00
fradev
b37bf06de8 Update ssh.sh 2022-03-01 17:57:59 +01:00
fradev
27bbf0ccaf Merge branch 'acmesh-official:master' into master 2022-03-01 17:44:46 +01:00
neil
e88442cb46 Merge pull request #3947 from abiessmann/deploy_routeros_fixes
deploy/routeros.sh fixes
2022-02-22 21:52:36 +08:00
neil
930609e875 Merge pull request #3948 from richard-9000/richard-9000-patch-1
dns_opnsense.sh - Fixed the domain parse regex
2022-02-22 21:41:22 +08:00
richard-9000
8752d08ce9 dns_opnsense.sh - Fixed the domain parse regex
Extended the regex to skip the new transferkey and hmac sections of opnsense bind.
2022-02-19 10:52:24 -08:00
Andreas Bießmann
c46ceb06b4 deploy/routeros.sh: change DEPLOY_SCRIPT_CMD
This set the owner of script to ssh user, have the comment line in script
as real comment and removes policy since this is set from current user,
at least for RouterOS 7.x.

Signed-off-by: Andreas Bießmann <andreas@biessmann.org>
2022-02-19 14:13:01 +01:00
Andreas Bießmann
92e4ecce3b deploy/routeros.sh: remove all certificates
As the script is applying the fullchain which includes three certificates,
delete all of them before applying updated certificate.

Signed-off-by: Andreas Bießmann <andreas@biessmann.org>
2022-02-19 14:13:01 +01:00
Andreas Bießmann
8a2f673903 deploy/routeros.sh: make ssh/scp configurable
In order to modify ssh/scp commands make them configurable via
environment variables.

Signed-off-by: Andreas Bießmann <andreas@biessmann.org>
2022-02-19 14:12:59 +01:00
Marvo2011
ac0dd90c37 Fix shfmt 2022-02-17 19:30:56 +01:00
Marvo2011
9470850258 Fix shellcheck, use double quote 2022-02-17 19:08:58 +01:00
Marvo2011
2982e9943e Add custom option to map multidomain RIDs 2022-02-17 19:02:35 +01:00
Marvo2011
80e13bc24a Merge remote-tracking branch 'origin/dev' into dev 2022-02-17 18:17:19 +01:00
peter
9a677534a7 added more debug info when rm recordid is empty 2022-02-13 14:00:14 +01:00
peter
af08d67fad rem. ; 2022-02-12 23:41:26 +01:00
peter
a2901d61ea check for return values 2022-02-12 23:39:33 +01:00
peter
aaae83efec check for return values 2022-02-12 20:18:08 +01:00
neil
7369298638 Merge pull request #3921 from andischerer/master
Added united-domains Reselling DNS API
2022-02-11 21:24:40 +08:00
neil
a761bd20fa Merge pull request #3934 from mac-zhou/dev
Add environment variables ROUTER_OS_PORT
2022-02-11 21:13:27 +08:00
neilpang
01ace11293 Update dns_ispconfig.sh
fix https://github.com/acmesh-official/acme.sh/issues/3895#issuecomment-1035409954
2022-02-11 21:11:04 +08:00
Mac_Zhou
205e95a246 Add environment variables ROUTER_OS_PORT 2022-02-10 11:29:09 +08:00
neil
2c2a43e1ec Update dns_cf.sh
if CF_Zone_ID is used,  save it to domain conf instead.
2022-02-09 18:08:55 +08:00
peter
0c9a6da623 more specific delete of records 2022-02-08 17:18:48 +01:00
Andreas Scherer
888d91d14a FIX dns_udr api: loop variable 2022-02-08 15:57:19 +01:00
peter
2c0cc87b4c final commit 2022-02-08 13:49:04 +01:00
peter
ee0fadf247 shfmt 2022-02-08 13:34:42 +01:00
peter
9fb89d7fd2 shfmt 2022-02-08 13:33:43 +01:00
peter
af5c36e4ad shfmt' 2022-02-08 13:32:15 +01:00
peter
a5f943e227 removed unused variable 2022-02-08 13:24:31 +01:00
peter
f8532ba812 removed unused variable 2022-02-08 13:21:02 +01:00
peter
fac4e151cc description 2022-02-08 13:19:22 +01:00
Andreas Scherer
f3a0a25380 FIX dns_udr api: ttl, xargs, cleanup 2022-02-08 08:05:48 +01:00
neil
5a237795ea Merge pull request #3928 from johnelliott/missing-oathtool-dep-error
Add err log for missing oathtool in Synology
2022-02-08 14:26:06 +08:00
John Elliott
3a99a77104 Update return statement 2022-02-07 21:55:12 -08:00
John Elliott
5ce8050e46 Update missing oathtool check 2022-02-07 11:58:14 -08:00
John Elliott
5ae3a020bd Add err log for missing oathtool in Synology
Alerts the user that the oathtool is missing and the TOTP can't be
generated.
2022-02-07 11:53:24 -08:00
neilpang
af193291fa Update acme.sh
fix https://github.com/acmesh-official/acme.sh/issues/3127#issuecomment-1030742187
2022-02-06 16:17:04 +08:00
neil
b39df5cef0 Merge pull request #3906 from NerLOR/master
Adapt dns_world4you to new world4you website behaviour
2022-02-06 09:52:45 +08:00
peter
dc61c9e277 description 2022-02-05 22:21:18 +01:00
peter
10a15e1188 nothing 2022-02-05 21:12:36 +01:00
peterlh
a2bb6a4f1f changed gettoken to use _post
changed gettoken to use _post instead of curl+jq
2022-02-05 21:07:04 +01:00
peterlh
38a19fa574 created dns_curanet.sh 2022-02-05 20:54:30 +01:00
neilpang
9ec4b59afb start v3.0.3
start v3.0.3
2022-02-05 21:28:07 +08:00
Lorenz Stechauner
20877146df Merge branch 'acmesh-official:master' into master 2022-02-04 20:36:31 +01:00
Andreas Scherer
a7f2d89e3f Added united-domains Reselling DNS API 2022-02-01 14:46:20 +01:00
Lorenz Stechauner
190ec0c14c Adapt dns_world4you to new world4you website behaviour 2022-01-24 16:47:47 +01:00
Marvo2011
62dad721fc Start ShellCheck and CI Test 2022-01-09 11:04:15 +01:00
Marvo2011
cc5cfc7525 Added Selfhost DNS API
+ShellCheck 
+ACME v2 compatible

Example:
- Fist create 2 new TXT records on _acme-challenge.example.com
- Now note the ID in (...) from the edit page behind "_acme-challenge.example.com"

export SELFHOSTDNS_USERNAME=myname
export SELFHOSTDNS_PASSWORD=mypass
export SELFHOSTDNS_RID=id_of_txt_record
export SELFHOSTDNS_RID2=id_of_second_txt_record
acme.sh --issue -d example.com  --dns  dns_selfhost
2022-01-05 15:03:32 +01:00
neil
795dee85ef Merge pull request #3854 from pearj/dev
Allow optional "NEW" in CSR header and footer
2022-01-03 14:57:15 +08:00
neilpang
dbd5bef038 fix gentoo image 2022-01-03 13:41:57 +08:00
neilpang
dd2a420578 add --info command to show the global configs or domain configs.
https://github.com/acmesh-official/acme.sh/issues/2444
2022-01-03 12:38:59 +08:00
neilpang
eeee30ca03 fix https://github.com/acmesh-official/acme.sh/issues/3869 2022-01-03 11:46:12 +08:00
neilpang
82e8792737 send notifications for renew command
https://github.com/acmesh-official/acme.sh/issues/3869#issuecomment-1003546762
2022-01-03 11:20:53 +08:00
neil
6b18b3df34 Merge pull request #3868 from vktg/ispconfigargsfix
DNS-ISPConfig ISPC_Api_Insecure argument check fix
2022-01-03 10:56:38 +08:00
neil
fcebed19b9 Merge pull request #3849 from casesolved-co-uk/dev
Mythic Beasts DNS API script
2022-01-03 10:08:46 +08:00
neil
af5f6176b5 Merge pull request #3764 from wacki4/patch-1
Update dns_opnsense.sh
2022-01-03 10:05:59 +08:00
Viktor G
424cc46db0 DNS-ISPConfig ISPC_Api_Insecure argument check fix 2021-12-30 18:06:17 +03:00
racitup
ce47ccecc4 fix: Neilpang review 2021-12-28 14:45:02 +00:00
racitup
d940f17390 fix: token request body quoting 2021-12-25 23:41:43 +00:00
racitup
6351b5d0dc fix: github switch 2021-12-25 23:41:43 +00:00
racitup
9c4ac24a66 fix: debugging 2021-12-25 23:41:43 +00:00
racitup
bf66df2a29 fix: correct return value 2021-12-25 23:41:43 +00:00
racitup
962ce380cd fix: floating token for github 2021-12-25 23:41:43 +00:00
racitup
9769afb944 feat: Mythic Beasts DNS API script 2021-12-25 23:41:43 +00:00
neilpang
052b45a510 upgrade solaris vm 2021-12-25 09:57:58 +08:00
neil
84a96e862e Merge pull request #3861 from christianbur/patch-2
Update Dockerfile - alpine:3.12 -> alpine:3.15
2021-12-22 10:37:48 +08:00
Christian Burmeister
3105235a7a Update Dockerfile - alpine:3.12 -> alpine:3.15
The support for the base image alpine:3.12 will expire in 4 months (https://endoflife.date/alpine), so it would make sense to upgrade to the current version alpine:3.15. 
I was able to create the acme.sh image with the new alpine:3.15 version without errors and also create and deploy a certificate, but further testing would be useful.
2021-12-21 22:20:42 +01:00
fradev
71a32477e4 Merge branch 'acmesh-official:master' into master 2021-12-20 09:28:19 +01:00
Joel Pearson
342bce2168 Allow optional "NEW" in CSR header and footer
When generating a CSR in Windows it seems to create a CSR header that looks like "-----BEGIN NEW CERTIFICATE REQUEST-----", but the addition of "NEW" breaks the parsing of the CSR. Making "NEW " optional fixes the problem.

Apparently certbot is tolerant of both forms, see: https://community.letsencrypt.org/t/error-parsing-certificate-request-resolved/40039/6 for more information.
2021-12-17 19:32:35 +11:00
neil
86d8cbc4d2 Merge pull request #3852 from heptalium/dev
[dns_knot] Use key command instead of command line argument to transmit dns key data
2021-12-13 20:07:43 +08:00
neilpang
6b63bd6a44 fix tunnel version 2021-12-13 20:04:23 +08:00
Jens Meißner
225707c877 [dns_knot] Use key command instead of command line argument to transmit dns key data. 2021-12-12 14:17:13 +01:00
neilpang
66da6f18e3 add TEST_DNS_NO_SUBDOMAIN 2021-12-06 22:03:38 +08:00
neilpang
bdf8bf391c pass TEST_DNS_NO_SUBDOMAIN 2021-12-05 21:05:18 +08:00
neilpang
f66d9e1a22 fix for OpenBSD7
https://github.com/acmesh-official/acme.sh/issues/3833
2021-12-05 18:23:19 +08:00
neilpang
ccd3d96942 upgrade Solaris 2021-12-05 16:15:39 +08:00
wacki4
00b6c6a437 Update dns_opnsense.sh
Correction when having many zones.
2021-10-16 16:57:12 +02:00
wacki4
21ef3b0ecf Update dns_opnsense.sh
Update for opnsense regards to error in #3735
2021-10-16 14:08:03 +02:00
fradev
08d60fcbf2 Update ssh.sh
shfmt formatting
2021-08-30 11:32:07 +02:00
fradev
4cda54774a Update ssh.sh
SC2086 and SC2215
2021-08-30 11:17:03 +02:00
fradev
613475ac26 Update ssh.sh 2021-08-30 11:08:06 +02:00
fradev
20d23fcb92 Update ssh.sh
Added scp mode for copy the certs
2021-08-25 16:55:36 +02:00
Leo
6d84f59e6b Add Weixin Work notify hook 2021-08-21 04:11:21 +08:00
Ian Epperson
748cb28017 Add Discord notification 2020-05-13 10:39:11 -07:00
97 changed files with 5754 additions and 1558 deletions

2
.github/FUNDING.yml vendored
View File

@@ -3,7 +3,7 @@
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: acmesh
ko_fi: # Replace with a single Ko-fi username
ko_fi: neilpang
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username

View File

@@ -1,254 +1,465 @@
name: DNS
on:
push:
paths:
- 'dnsapi/*.sh'
- '.github/workflows/DNS.yml'
pull_request:
branches:
- 'dev'
paths:
- 'dnsapi/*.sh'
- '.github/workflows/DNS.yml'
jobs:
CheckToken:
runs-on: ubuntu-latest
outputs:
hasToken: ${{ steps.step_one.outputs.hasToken }}
steps:
- name: Set the value
id: step_one
run: |
if [ "${{secrets.TokenName1}}" ] ; then
echo "::set-output name=hasToken::true"
else
echo "::set-output name=hasToken::false"
fi
- name: Check the value
run: echo ${{ steps.step_one.outputs.hasToken }}
Fail:
runs-on: ubuntu-latest
needs: CheckToken
if: "contains(needs.CheckToken.outputs.hasToken, 'false')"
steps:
- name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test"
run: |
echo "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test"
if [ "${{github.repository_owner}}" != "acmesh-official" ]; then
false
fi
Docker:
runs-on: ubuntu-latest
needs: CheckToken
if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
env:
TEST_DNS : ${{ secrets.TEST_DNS }}
TestingDomain: ${{ secrets.TestingDomain }}
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
CASE: le_test_dnsapi
TEST_LOCAL: 1
DEBUG: 1
steps:
- uses: actions/checkout@v2
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Set env file
run: |
cd ../acmetest
if [ "${{ secrets.TokenName1}}" ] ; then
echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> docker.env
fi
if [ "${{ secrets.TokenName2}}" ] ; then
echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> docker.env
fi
if [ "${{ secrets.TokenName3}}" ] ; then
echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> docker.env
fi
if [ "${{ secrets.TokenName4}}" ] ; then
echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> docker.env
fi
if [ "${{ secrets.TokenName5}}" ] ; then
echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env
fi
echo "TEST_DNS_NO_WILDCARD" >> docker.env
echo "TEST_DNS_SLEEP" >> docker.env
- name: Run acmetest
run: cd ../acmetest && ./rundocker.sh testall
MacOS:
runs-on: macos-latest
needs: Docker
env:
TEST_DNS : ${{ secrets.TEST_DNS }}
TestingDomain: ${{ secrets.TestingDomain }}
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
CASE: le_test_dnsapi
TEST_LOCAL: 1
DEBUG: 1
steps:
- uses: actions/checkout@v2
- name: Install tools
run: brew install socat
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
run: |
if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
fi
if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
fi
if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
fi
if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
fi
if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
fi
cd ../acmetest
./letest.sh
Windows:
runs-on: windows-latest
needs: MacOS
env:
TEST_DNS : ${{ secrets.TEST_DNS }}
TestingDomain: ${{ secrets.TestingDomain }}
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
CASE: le_test_dnsapi
TEST_LOCAL: 1
DEBUG: 1
steps:
- name: Set git to use LF
run: |
git config --global core.autocrlf false
- uses: actions/checkout@v2
- name: Install cygwin base packages with chocolatey
run: |
choco config get cacheLocation
choco install --no-progress cygwin
shell: cmd
- name: Install cygwin additional packages
run: |
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git
shell: cmd
- name: Set ENV
shell: cmd
run: |
echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV%
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
shell: bash
run: |
if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
fi
if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
fi
if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
fi
if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
fi
if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
fi
cd ../acmetest
./letest.sh
FreeBSD:
runs-on: macos-10.15
needs: Windows
env:
TEST_DNS : ${{ secrets.TEST_DNS }}
TestingDomain: ${{ secrets.TestingDomain }}
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
CASE: le_test_dnsapi
TEST_LOCAL: 1
DEBUG: 1
steps:
- uses: actions/checkout@v2
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/freebsd-vm@v0.1.4
with:
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
prepare: pkg install -y socat curl
usesh: true
run: |
if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
fi
if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
fi
if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
fi
if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
fi
if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
fi
cd ../acmetest
./letest.sh
Solaris:
runs-on: macos-10.15
needs: FreeBSD
env:
TEST_DNS : ${{ secrets.TEST_DNS }}
TestingDomain: ${{ secrets.TestingDomain }}
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
CASE: le_test_dnsapi
TEST_LOCAL: 1
DEBUG: 1
steps:
- uses: actions/checkout@v2
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/solaris-vm@v0.0.5
with:
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
prepare: pkgutil -y -i socat
run: |
pkg set-mediator -v -I default@1.1 openssl
export PATH=/usr/gnu/bin:$PATH
if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
fi
if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
fi
if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
fi
if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
fi
if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
fi
cd ../acmetest
./letest.sh
name: DNS
on:
push:
paths:
- 'dnsapi/*.sh'
- '.github/workflows/DNS.yml'
pull_request:
branches:
- 'dev'
paths:
- 'dnsapi/*.sh'
- '.github/workflows/DNS.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
CheckToken:
runs-on: ubuntu-latest
outputs:
hasToken: ${{ steps.step_one.outputs.hasToken }}
steps:
- name: Set the value
id: step_one
run: |
if [ "${{secrets.TokenName1}}" ] ; then
echo "::set-output name=hasToken::true"
else
echo "::set-output name=hasToken::false"
fi
- name: Check the value
run: echo ${{ steps.step_one.outputs.hasToken }}
Fail:
runs-on: ubuntu-latest
needs: CheckToken
if: "contains(needs.CheckToken.outputs.hasToken, 'false')"
steps:
- name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test"
run: |
echo "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test"
if [ "${{github.repository_owner}}" != "acmesh-official" ]; then
false
fi
Docker:
runs-on: ubuntu-latest
needs: CheckToken
if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
env:
TEST_DNS : ${{ secrets.TEST_DNS }}
TestingDomain: ${{ secrets.TestingDomain }}
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
CASE: le_test_dnsapi
TEST_LOCAL: 1
DEBUG: ${{ secrets.DEBUG }}
http_proxy: ${{ secrets.http_proxy }}
https_proxy: ${{ secrets.https_proxy }}
TokenName1: ${{ secrets.TokenName1}}
TokenName2: ${{ secrets.TokenName2}}
TokenName3: ${{ secrets.TokenName3}}
TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}}
steps:
- uses: actions/checkout@v3
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Set env file
run: |
cd ../acmetest
if [ "${{ secrets.TokenName1}}" ] ; then
echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> docker.env
fi
if [ "${{ secrets.TokenName2}}" ] ; then
echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> docker.env
fi
if [ "${{ secrets.TokenName3}}" ] ; then
echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> docker.env
fi
if [ "${{ secrets.TokenName4}}" ] ; then
echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> docker.env
fi
if [ "${{ secrets.TokenName5}}" ] ; then
echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env
fi
- name: Run acmetest
run: cd ../acmetest && ./rundocker.sh testall
MacOS:
runs-on: macos-latest
needs: Docker
env:
TEST_DNS : ${{ secrets.TEST_DNS }}
TestingDomain: ${{ secrets.TestingDomain }}
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
CASE: le_test_dnsapi
TEST_LOCAL: 1
DEBUG: ${{ secrets.DEBUG }}
http_proxy: ${{ secrets.http_proxy }}
https_proxy: ${{ secrets.https_proxy }}
TokenName1: ${{ secrets.TokenName1}}
TokenName2: ${{ secrets.TokenName2}}
TokenName3: ${{ secrets.TokenName3}}
TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}}
steps:
- uses: actions/checkout@v3
- name: Install tools
run: brew install socat
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
run: |
if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
fi
if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}"
fi
if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}"
fi
if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}"
fi
if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}"
fi
cd ../acmetest
./letest.sh
Windows:
runs-on: windows-latest
needs: MacOS
env:
TEST_DNS : ${{ secrets.TEST_DNS }}
TestingDomain: ${{ secrets.TestingDomain }}
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
CASE: le_test_dnsapi
TEST_LOCAL: 1
DEBUG: ${{ secrets.DEBUG }}
http_proxy: ${{ secrets.http_proxy }}
https_proxy: ${{ secrets.https_proxy }}
TokenName1: ${{ secrets.TokenName1}}
TokenName2: ${{ secrets.TokenName2}}
TokenName3: ${{ secrets.TokenName3}}
TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}}
steps:
- name: Set git to use LF
run: |
git config --global core.autocrlf false
- uses: actions/checkout@v3
- name: Install cygwin base packages with chocolatey
run: |
choco config get cacheLocation
choco install --no-progress cygwin
shell: cmd
- name: Install cygwin additional packages
run: |
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s https://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git
shell: cmd
- name: Set ENV
shell: cmd
run: |
echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV%
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
shell: bash
run: |
if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
fi
if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}"
fi
if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}"
fi
if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}"
fi
if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}"
fi
cd ../acmetest
./letest.sh
FreeBSD:
runs-on: macos-12
needs: Windows
env:
TEST_DNS : ${{ secrets.TEST_DNS }}
TestingDomain: ${{ secrets.TestingDomain }}
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
CASE: le_test_dnsapi
TEST_LOCAL: 1
DEBUG: ${{ secrets.DEBUG }}
http_proxy: ${{ secrets.http_proxy }}
https_proxy: ${{ secrets.https_proxy }}
TokenName1: ${{ secrets.TokenName1}}
TokenName2: ${{ secrets.TokenName2}}
TokenName3: ${{ secrets.TokenName3}}
TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}}
steps:
- uses: actions/checkout@v3
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/freebsd-vm@v0
with:
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
prepare: pkg install -y socat curl
usesh: true
copyback: false
run: |
if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
fi
if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}"
fi
if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}"
fi
if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}"
fi
if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}"
fi
cd ../acmetest
./letest.sh
OpenBSD:
runs-on: macos-12
needs: FreeBSD
env:
TEST_DNS : ${{ secrets.TEST_DNS }}
TestingDomain: ${{ secrets.TestingDomain }}
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
CASE: le_test_dnsapi
TEST_LOCAL: 1
DEBUG: ${{ secrets.DEBUG }}
http_proxy: ${{ secrets.http_proxy }}
https_proxy: ${{ secrets.https_proxy }}
TokenName1: ${{ secrets.TokenName1}}
TokenName2: ${{ secrets.TokenName2}}
TokenName3: ${{ secrets.TokenName3}}
TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}}
steps:
- uses: actions/checkout@v3
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/openbsd-vm@v0
with:
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
prepare: pkg_add socat curl
usesh: true
copyback: false
run: |
if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
fi
if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}"
fi
if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}"
fi
if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}"
fi
if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}"
fi
cd ../acmetest
./letest.sh
NetBSD:
runs-on: macos-12
needs: OpenBSD
env:
TEST_DNS : ${{ secrets.TEST_DNS }}
TestingDomain: ${{ secrets.TestingDomain }}
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
CASE: le_test_dnsapi
TEST_LOCAL: 1
DEBUG: ${{ secrets.DEBUG }}
http_proxy: ${{ secrets.http_proxy }}
https_proxy: ${{ secrets.https_proxy }}
TokenName1: ${{ secrets.TokenName1}}
TokenName2: ${{ secrets.TokenName2}}
TokenName3: ${{ secrets.TokenName3}}
TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}}
steps:
- uses: actions/checkout@v3
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/netbsd-vm@v0
with:
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
prepare: |
pkg_add curl socat
usesh: true
copyback: false
run: |
if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
fi
if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}"
fi
if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}"
fi
if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}"
fi
if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}"
fi
cd ../acmetest
./letest.sh
DragonFlyBSD:
runs-on: macos-12
needs: NetBSD
env:
TEST_DNS : ${{ secrets.TEST_DNS }}
TestingDomain: ${{ secrets.TestingDomain }}
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
CASE: le_test_dnsapi
TEST_LOCAL: 1
DEBUG: ${{ secrets.DEBUG }}
http_proxy: ${{ secrets.http_proxy }}
https_proxy: ${{ secrets.https_proxy }}
TokenName1: ${{ secrets.TokenName1}}
TokenName2: ${{ secrets.TokenName2}}
TokenName3: ${{ secrets.TokenName3}}
TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}}
steps:
- uses: actions/checkout@v3
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/dragonflybsd-vm@v0
with:
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
prepare: |
pkg install -y curl socat
usesh: true
copyback: false
run: |
if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
fi
if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}"
fi
if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}"
fi
if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}"
fi
if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}"
fi
cd ../acmetest
./letest.sh
Solaris:
runs-on: macos-12
needs: DragonFlyBSD
env:
TEST_DNS : ${{ secrets.TEST_DNS }}
TestingDomain: ${{ secrets.TestingDomain }}
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
CASE: le_test_dnsapi
TEST_LOCAL: 1
DEBUG: ${{ secrets.DEBUG }}
http_proxy: ${{ secrets.http_proxy }}
https_proxy: ${{ secrets.https_proxy }}
HTTPS_INSECURE: 1 # always set to 1 to ignore https error, since Solaris doesn't accept the expired ISRG X1 root
TokenName1: ${{ secrets.TokenName1}}
TokenName2: ${{ secrets.TokenName2}}
TokenName3: ${{ secrets.TokenName3}}
TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}}
steps:
- uses: actions/checkout@v3
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/solaris-vm@v0
with:
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy HTTPS_INSECURE TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
copyback: false
prepare: pkgutil -y -i socat
run: |
pkg set-mediator -v -I default@1.1 openssl
export PATH=/usr/gnu/bin:$PATH
if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
fi
if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}"
fi
if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}"
fi
if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}"
fi
if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}"
fi
cd ../acmetest
./letest.sh

71
.github/workflows/DragonFlyBSD.yml vendored Normal file
View File

@@ -0,0 +1,71 @@
name: DragonFlyBSD
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/DragonFlyBSD.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/DragonFlyBSD.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
DragonFlyBSD:
strategy:
matrix:
include:
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: macos-12
env:
TEST_LOCAL: 1
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
CA_ECDSA: ${{ matrix.CA_ECDSA }}
CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
steps:
- uses: actions/checkout@v3
- uses: vmactions/cf-tunnel@v0
id: tunnel
with:
protocol: http
port: 8080
- name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/dragonflybsd-vm@v0
with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
copyback: "false"
nat: |
"8080": "80"
prepare: |
pkg install -y curl socat
usesh: true
run: |
cd ../acmetest \
&& ./letest.sh

View File

@@ -14,6 +14,11 @@ on:
- '*.sh'
- '.github/workflows/FreeBSD.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
FreeBSD:
@@ -25,12 +30,18 @@ jobs:
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "ZeroSSL.com"
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
CA: "ZeroSSL RSA Domain Secure Site CA"
CA_EMAIL: "githubtest@acme.sh"
TEST_PREFERRED_CHAIN: ""
runs-on: macos-10.15
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: macos-12
env:
TEST_LOCAL: 1
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
@@ -38,9 +49,10 @@ jobs:
CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
steps:
- uses: actions/checkout@v2
- uses: vmactions/cf-tunnel@v0.0.3
- uses: actions/checkout@v3
- uses: vmactions/cf-tunnel@v0
id: tunnel
with:
protocol: http
@@ -48,14 +60,15 @@ jobs:
- name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/freebsd-vm@v0.1.5
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/freebsd-vm@v0
with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: |
"8080": "80"
prepare: pkg install -y socat curl
prepare: pkg install -y socat curl wget
usesh: true
copyback: false
run: |
cd ../acmetest \
&& ./letest.sh

View File

@@ -15,6 +15,12 @@ on:
- '.github/workflows/Linux.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
Linux:
@@ -25,12 +31,13 @@ jobs:
env:
TEST_LOCAL: 1
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
TEST_ACME_Server: "LetsEncrypt.org_test"
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Clone acmetest
run: |
cd .. \
&& git clone https://github.com/acmesh-official/acmetest.git \
&& git clone --depth=1 https://github.com/acmesh-official/acmetest.git \
&& cp -r acme.sh acmetest/
- name: Run acmetest
run: |

View File

@@ -14,6 +14,11 @@ on:
- '*.sh'
- '.github/workflows/MacOS.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
MacOS:
@@ -25,11 +30,11 @@ jobs:
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "ZeroSSL.com"
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
CA: "ZeroSSL RSA Domain Secure Site CA"
CA_EMAIL: "githubtest@acme.sh"
TEST_PREFERRED_CHAIN: ""
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: macos-latest
env:
TEST_LOCAL: 1
@@ -39,13 +44,13 @@ jobs:
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install tools
run: brew install socat
- name: Clone acmetest
run: |
cd .. \
&& git clone https://github.com/acmesh-official/acmetest.git \
&& git clone --depth=1 https://github.com/acmesh-official/acmetest.git \
&& cp -r acme.sh acmetest/
- name: Run acmetest
run: |

71
.github/workflows/NetBSD.yml vendored Normal file
View File

@@ -0,0 +1,71 @@
name: NetBSD
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/NetBSD.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/NetBSD.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
NetBSD:
strategy:
matrix:
include:
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: macos-12
env:
TEST_LOCAL: 1
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
CA_ECDSA: ${{ matrix.CA_ECDSA }}
CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
steps:
- uses: actions/checkout@v3
- uses: vmactions/cf-tunnel@v0
id: tunnel
with:
protocol: http
port: 8080
- name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/netbsd-vm@v0
with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
nat: |
"8080": "80"
prepare: |
pkg_add curl socat
usesh: true
copyback: false
run: |
cd ../acmetest \
&& ./letest.sh

76
.github/workflows/OpenBSD.yml vendored Normal file
View File

@@ -0,0 +1,76 @@
name: OpenBSD
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/OpenBSD.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/OpenBSD.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
OpenBSD:
strategy:
matrix:
include:
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: macos-12
env:
TEST_LOCAL: 1
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
CA_ECDSA: ${{ matrix.CA_ECDSA }}
CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
steps:
- uses: actions/checkout@v3
- uses: vmactions/cf-tunnel@v0
id: tunnel
with:
protocol: http
port: 8080
- name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/openbsd-vm@v0
with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: |
"8080": "80"
prepare: pkg_add socat curl wget
usesh: true
copyback: false
run: |
cd ../acmetest \
&& ./letest.sh

View File

@@ -13,6 +13,13 @@ on:
- '*.sh'
- '.github/workflows/PebbleStrict.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
PebbleStrict:
runs-on: ubuntu-latest
@@ -26,7 +33,7 @@ jobs:
TEST_CA: "Pebble Intermediate CA"
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install tools
run: sudo apt-get install -y socat
- name: Run Pebble
@@ -34,15 +41,15 @@ jobs:
- name: Set up Pebble
run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
run: cd ../acmetest && ./letest.sh
PebbleStrict_IPCert:
runs-on: ubuntu-latest
env:
TestingDomain: 10.30.50.1
ACME_DIRECTORY: https://localhost:14000/dir
TestingDomain: 1.23.45.67
TEST_ACME_Server: https://localhost:14000/dir
HTTPS_INSECURE: 1
Le_HTTPPort: 5002
Le_TLSPort: 5001
@@ -51,12 +58,15 @@ jobs:
TEST_IPCERT: 1
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install tools
run: sudo apt-get install -y socat
- name: Run Pebble
run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d
run: |
docker run --rm -itd --name=pebble \
-e PEBBLE_VA_ALWAYS_VALID=1 \
-p 14000:14000 -p 15000:15000 letsencrypt/pebble:latest pebble -config /test/config/pebble-config.json -strict
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
run: cd ../acmetest && ./letest.sh

View File

@@ -15,6 +15,11 @@ on:
- '.github/workflows/Solaris.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
Solaris:
strategy:
@@ -25,12 +30,18 @@ jobs:
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "ZeroSSL.com"
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
CA: "ZeroSSL RSA Domain Secure Site CA"
CA_EMAIL: "githubtest@acme.sh"
TEST_PREFERRED_CHAIN: ""
runs-on: macos-10.15
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: macos-12
env:
TEST_LOCAL: 1
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
@@ -38,9 +49,10 @@ jobs:
CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
steps:
- uses: actions/checkout@v2
- uses: vmactions/cf-tunnel@v0.0.3
- uses: actions/checkout@v3
- uses: vmactions/cf-tunnel@v0
id: tunnel
with:
protocol: http
@@ -48,13 +60,14 @@ jobs:
- name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/solaris-vm@v0.0.5
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/solaris-vm@v0
with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
copyback: "false"
nat: |
"8080": "80"
prepare: pkgutil -y -i socat curl
prepare: pkgutil -y -i socat curl wget
run: |
cd ../acmetest \
&& ./letest.sh

View File

@@ -14,6 +14,11 @@ on:
- '*.sh'
- '.github/workflows/Ubuntu.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
Ubuntu:
@@ -25,6 +30,12 @@ jobs:
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
ACME_USE_WGET: 1
- TEST_ACME_Server: "ZeroSSL.com"
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
CA: "ZeroSSL RSA Domain Secure Site CA"
@@ -57,10 +68,11 @@ jobs:
NO_REVOKE: ${{ matrix.NO_REVOKE }}
TEST_IPCERT: ${{ matrix.TEST_IPCERT }}
TestingDomain: ${{ matrix.TestingDomain }}
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install tools
run: sudo apt-get install -y socat
run: sudo apt-get install -y socat wget
- name: Start StepCA
if: ${{ matrix.TEST_ACME_Server=='https://localhost:9000/acme/acme/directory' }}
run: |
@@ -68,15 +80,20 @@ jobs:
-p 9000:9000 \
-e "DOCKER_STEPCA_INIT_NAME=Smallstep" \
-e "DOCKER_STEPCA_INIT_DNS_NAMES=localhost,$(hostname -f)" \
-e "DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT=true" \
-e "DOCKER_STEPCA_INIT_PASSWORD=test" \
--name stepca \
smallstep/step-ca \
&& sleep 5 && docker exec stepca step ca provisioner add acme --type ACME \
smallstep/step-ca:0.23.1
sleep 5
docker exec stepca bash -c "echo test >test" \
&& docker exec stepca step ca provisioner add acme --type ACME --admin-subject step --admin-password-file=/home/step/test \
&& docker exec stepca kill -1 1 \
&& docker exec stepca cat /home/step/certs/root_ca.crt | sudo bash -c "cat - >>/etc/ssl/certs/ca-certificates.crt"
- name: Clone acmetest
run: |
cd .. \
&& git clone https://github.com/acmesh-official/acmetest.git \
&& git clone --depth=1 https://github.com/acmesh-official/acmetest.git \
&& cp -r acme.sh acmetest/
- name: Run acmetest
run: |

View File

@@ -15,6 +15,11 @@ on:
- '.github/workflows/Windows.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
Windows:
strategy:
@@ -25,11 +30,11 @@ jobs:
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "ZeroSSL.com"
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
CA: "ZeroSSL RSA Domain Secure Site CA"
CA_EMAIL: "githubtest@acme.sh"
TEST_PREFERRED_CHAIN: ""
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: windows-latest
env:
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
@@ -44,7 +49,7 @@ jobs:
- name: Set git to use LF
run: |
git config --global core.autocrlf false
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install cygwin base packages with chocolatey
run: |
choco config get cacheLocation
@@ -52,7 +57,7 @@ jobs:
shell: cmd
- name: Install cygwin additional packages
run: |
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git,xxd
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s https://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git,xxd
shell: cmd
- name: Set ENV
shell: cmd
@@ -64,7 +69,7 @@ jobs:
echo "PATH=%PATH%"
- name: Clone acmetest
shell: cmd
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
shell: cmd
run: cd ../acmetest && bash.exe -c ./letest.sh

View File

@@ -11,7 +11,11 @@ on:
- "Dockerfile"
- '.github/workflows/dockerhub.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
CheckToken:
runs-on: ubuntu-latest
@@ -24,9 +28,9 @@ jobs:
id: step_one
run: |
if [ "$DOCKER_PASSWORD" ] ; then
echo "::set-output name=hasToken::true"
echo "hasToken=true" >>$GITHUB_OUTPUT
else
echo "::set-output name=hasToken::false"
echo "hasToken=false" >>$GITHUB_OUTPUT
fi
- name: Check the value
run: echo ${{ steps.step_one.outputs.hasToken }}
@@ -37,11 +41,11 @@ jobs:
if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
steps:
- name: checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
- name: login to docker hub
run: |
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin

19
.github/workflows/issue.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: "Update issues"
on:
issues:
types: [opened]
jobs:
comment:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v6
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: "Please upgrade to the latest code and try again first. Maybe it's already fixed. ```acme.sh --upgrade``` If it's still not working, please provide the log with `--debug 2`, otherwise, nobody can help you."
})

30
.github/workflows/pr_dns.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Check dns api
on:
pull_request_target:
types:
- opened
branches:
- 'dev'
paths:
- 'dnsapi/*.sh'
jobs:
welcome:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v6
with:
script: |
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `**Welcome**
Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test).
Then reply on this message, otherwise, your code will not be reviewed or merged.
We look forward to reviewing your Pull request shortly ✨
`
})

30
.github/workflows/pr_notify.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Check dns api
on:
pull_request_target:
types:
- opened
branches:
- 'dev'
paths:
- 'notify/*.sh'
jobs:
welcome:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v6
with:
script: |
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `**Welcome**
Please make sure you're read our [Code-of-conduct](../wiki/Code-of-conduct) and add the usage here: [notify](../wiki/notify).
Then reply on this message, otherwise, your code will not be reviewed or merged.
We look forward to reviewing your Pull request shortly ✨
`
})

View File

@@ -13,20 +13,25 @@ on:
- '**.sh'
- '.github/workflows/shellcheck.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
ShellCheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install Shellcheck
run: sudo apt-get install -y shellcheck
- name: DoShellcheck
run: shellcheck -V && shellcheck -e SC2181 **/*.sh && echo "shellcheck OK"
run: shellcheck -V && shellcheck -e SC2181 -e SC2089 **/*.sh && echo "shellcheck OK"
shfmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install shfmt
run: curl -sSL https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 -o ~/shfmt && chmod +x ~/shfmt
- name: shfmt

View File

@@ -1,4 +1,4 @@
FROM alpine:3.15
FROM alpine:3.17
RUN apk --no-cache add -f \
openssl \
@@ -12,7 +12,8 @@ RUN apk --no-cache add -f \
oath-toolkit-oathtool \
tar \
libidn \
jq
jq \
cronie
ENV LE_CONFIG_HOME /acme.sh
@@ -25,7 +26,7 @@ COPY ./ /install_acme.sh/
RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/
RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh && crontab -l | grep acme.sh | sed 's#> /dev/null##' | crontab -
RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh && crontab -l | grep acme.sh | sed 's#> /dev/null#> /proc/1/fd/1 2>/proc/1/fd/2#' | crontab -
RUN for verb in help \
version \
@@ -64,11 +65,10 @@ RUN for verb in help \
RUN printf "%b" '#!'"/usr/bin/env sh\n \
if [ \"\$1\" = \"daemon\" ]; then \n \
trap \"echo stop && killall crond && exit 0\" SIGTERM SIGINT \n \
crond && while true; do sleep 1; done;\n \
exec crond -n -s -m off \n \
else \n \
exec -- \"\$@\"\n \
fi" >/entry.sh && chmod +x /entry.sh
fi\n" >/entry.sh && chmod +x /entry.sh
VOLUME /acme.sh

View File

@@ -1,10 +1,14 @@
# An ACME Shell script: acme.sh
[![FreeBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml)
[![OpenBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml)
[![NetBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml)
[![MacOS](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml)
[![Ubuntu](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml)
[![Windows](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml)
[![Solaris](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml)
[![DragonFlyBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml)
![Shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg)
![PebbleStrict](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg)
@@ -47,14 +51,12 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
- [ruby-china.org](https://ruby-china.org/topics/31983)
- [Proxmox](https://pve.proxmox.com/wiki/Certificate_Management)
- [pfsense](https://github.com/pfsense/FreeBSD-ports/pull/89)
- [webfaction](https://community.webfaction.com/questions/19988/using-letsencrypt)
- [Loadbalancer.org](https://www.loadbalancer.org/blog/loadbalancer-org-with-lets-encrypt-quick-and-dirty)
- [discourse.org](https://meta.discourse.org/t/setting-up-lets-encrypt/40709)
- [Centminmod](https://centminmod.com/letsencrypt-acmetool-https.html)
- [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297)
- [archlinux](https://www.archlinux.org/packages/community/any/acme.sh)
- [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient)
- [CentOS Web Panel](http://centos-webpanel.com/)
- [CentOS Web Panel](https://control-webpanel.com)
- [lnmp.org](https://lnmp.org/)
- [more...](https://github.com/acmesh-official/acme.sh/wiki/Blogs-and-tutorials)
@@ -68,21 +70,23 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
|4|[![Solaris](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml)|Solaris
|5|[![Ubuntu](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml)| Ubuntu
|6|NA|pfsense
|7|NA|OpenBSD
|8|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian
|9|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS
|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE
|11|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl)
|12|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Archlinux
|13|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora
|14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux
|15|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux
|16|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia
|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux
|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux
|19|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111
|20|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT)
|21|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management)
|7|[![OpenBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml)|OpenBSD
|8|[![NetBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml)|NetBSD
|9|[![DragonFlyBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml)|DragonFlyBSD
|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian
|11|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS
|12|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE
|13|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl)
|14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Archlinux
|15|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora
|16|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux
|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux
|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia
|19|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux
|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux
|11|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111
|22|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT)
|23|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management)
Check our [testing project](https://github.com/acmesh-official/acmetest):
@@ -95,6 +99,7 @@ https://github.com/acmesh-official/acmetest
- Letsencrypt.org CA
- [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA)
- [SSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/SSL.com-CA)
- [Google.com Public CA](https://github.com/acmesh-official/acme.sh/wiki/Google-Public-CA)
- [Pebble strict Mode](https://github.com/letsencrypt/pebble)
- Any other [RFC8555](https://tools.ietf.org/html/rfc8555)-compliant CA
@@ -354,10 +359,6 @@ Ok, it's done.
# 10. Issue ECC certificates
`Let's Encrypt` can now issue **ECDSA** certificates.
And we support them too!
Just set the `keylength` parameter with a prefix `ec-`.
For example:
@@ -378,10 +379,12 @@ Please look at the `keylength` parameter above.
Valid values are:
1. **ec-256 (prime256v1, "ECDSA P-256")**
1. **ec-256 (prime256v1, "ECDSA P-256", which is the default key type)**
2. **ec-384 (secp384r1, "ECDSA P-384")**
3. **ec-521 (secp521r1, "ECDSA P-521", which is not supported by Let's Encrypt yet.)**
4. **2048 (RSA2048)**
5. **3072 (RSA3072)**
6. **4096 (RSA4096)**
# 11. Issue Wildcard certificates
@@ -502,6 +505,12 @@ Support this project with your organization. Your logo will show up here with a
<a href="https://opencollective.com/acmesh/organization/8/website"><img src="https://opencollective.com/acmesh/organization/8/avatar.svg"></a>
<a href="https://opencollective.com/acmesh/organization/9/website"><img src="https://opencollective.com/acmesh/organization/9/avatar.svg"></a>
#### Sponsors
[![quantumca-acmesh-logo](https://user-images.githubusercontent.com/8305679/183255712-634ee1db-bb61-4c03-bca0-bacce99e078c.svg)](https://www.quantumca.com.cn/?__utm_source=acmesh-donation)
# 19. License & Others
License is GPLv3

749
acme.sh

File diff suppressed because it is too large Load Diff

View File

@@ -3,18 +3,29 @@
# Uses command line uapi. --user option is needed only if run as root.
# Returns 0 when success.
#
# Configure DEPLOY_CPANEL_AUTO_<...> options to enable or restrict automatic
# detection of deployment targets through UAPI (if not set, defaults below are used.)
# - ENABLED : 'true' for multi-site / wildcard capability; otherwise single-site mode.
# - NOMATCH : 'true' to allow deployment to sites that do not match the certificate.
# - INCLUDE : Comma-separated list - sites must match this field.
# - EXCLUDE : Comma-separated list - sites must NOT match this field.
# INCLUDE/EXCLUDE both support non-lexical, glob-style matches using '*'
#
# Please note that I am no longer using Github. If you want to report an issue
# or contact me, visit https://forum.webseodesigners.com/web-design-seo-and-hosting-f16/
#
# Written by Santeri Kannisto <santeri.kannisto@webseodesigners.com>
# Public domain, 2017-2018
#export DEPLOY_CPANEL_USER=myusername
#
# export DEPLOY_CPANEL_USER=myusername
# export DEPLOY_CPANEL_AUTO_ENABLED='true'
# export DEPLOY_CPANEL_AUTO_NOMATCH='false'
# export DEPLOY_CPANEL_AUTO_INCLUDE='*'
# export DEPLOY_CPANEL_AUTO_EXCLUDE=''
######## Public functions #####################
#domain keyfile certfile cafile fullchain
cpanel_uapi_deploy() {
_cdomain="$1"
_ckey="$2"
@@ -22,6 +33,9 @@ cpanel_uapi_deploy() {
_cca="$4"
_cfullchain="$5"
# re-declare vars inherited from acme.sh but not passed to make ShellCheck happy
: "${Le_Alt:=""}"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
@@ -32,31 +46,166 @@ cpanel_uapi_deploy() {
_err "The command uapi is not found."
return 1
fi
# declare useful constants
uapi_error_response='status: 0'
# read cert and key files and urlencode both
_cert=$(_url_encode <"$_ccert")
_key=$(_url_encode <"$_ckey")
_debug _cert "$_cert"
_debug _key "$_key"
_debug2 _cert "$_cert"
_debug2 _key "$_key"
if [ "$(id -u)" = 0 ]; then
if [ -z "$DEPLOY_CPANEL_USER" ]; then
_getdeployconf DEPLOY_CPANEL_USER
# fallback to _readdomainconf for old installs
if [ -z "${DEPLOY_CPANEL_USER:=$(_readdomainconf DEPLOY_CPANEL_USER)}" ]; then
_err "It seems that you are root, please define the target user name: export DEPLOY_CPANEL_USER=username"
return 1
fi
_savedomainconf DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER"
_response=$(uapi --user="$DEPLOY_CPANEL_USER" SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
else
_response=$(uapi SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
fi
error_response="status: 0"
if test "${_response#*$error_response}" != "$_response"; then
_err "Error in deploying certificate:"
_err "$_response"
return 1
_debug DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER"
_savedeployconf DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER"
_uapi_user="$DEPLOY_CPANEL_USER"
fi
_debug response "$_response"
_info "Certificate successfully deployed"
return 0
# Load all AUTO envars and set defaults - see above for usage
__cpanel_initautoparam ENABLED 'true'
__cpanel_initautoparam NOMATCH 'false'
__cpanel_initautoparam INCLUDE '*'
__cpanel_initautoparam EXCLUDE ''
# Auto mode
if [ "$DEPLOY_CPANEL_AUTO_ENABLED" = "true" ]; then
# call API for site config
_response=$(uapi DomainInfo list_domains)
# exit if error in response
if [ -z "$_response" ] || [ "${_response#*"$uapi_error_response"}" != "$_response" ]; then
_err "Error in deploying certificate - cannot retrieve sitelist:"
_err "\n$_response"
return 1
fi
# parse response to create site list
sitelist=$(__cpanel_parse_response "$_response")
_debug "UAPI sites found: $sitelist"
# filter sitelist using configured domains
# skip if NOMATCH is "true"
if [ "$DEPLOY_CPANEL_AUTO_NOMATCH" = "true" ]; then
_debug "DEPLOY_CPANEL_AUTO_NOMATCH is true"
_info "UAPI nomatch mode is enabled - Will not validate sites are valid for the certificate"
else
_debug "DEPLOY_CPANEL_AUTO_NOMATCH is false"
d="$(echo "${Le_Alt}," | sed -e "s/^$_cdomain,//" -e "s/,$_cdomain,/,/")"
d="$(echo "$_cdomain,$d" | tr ',' '\n' | sed -e 's/\./\\./g' -e 's/\*/\[\^\.\]\*/g')"
sitelist="$(echo "$sitelist" | grep -ix "$d")"
_debug2 "Matched UAPI sites: $sitelist"
fi
# filter sites that do not match $DEPLOY_CPANEL_AUTO_INCLUDE
_info "Applying sitelist filter DEPLOY_CPANEL_AUTO_INCLUDE: $DEPLOY_CPANEL_AUTO_INCLUDE"
sitelist="$(echo "$sitelist" | grep -ix "$(echo "$DEPLOY_CPANEL_AUTO_INCLUDE" | tr ',' '\n' | sed -e 's/\./\\./g' -e 's/\*/\.\*/g')")"
_debug2 "Remaining sites: $sitelist"
# filter sites that match $DEPLOY_CPANEL_AUTO_EXCLUDE
_info "Applying sitelist filter DEPLOY_CPANEL_AUTO_EXCLUDE: $DEPLOY_CPANEL_AUTO_EXCLUDE"
sitelist="$(echo "$sitelist" | grep -vix "$(echo "$DEPLOY_CPANEL_AUTO_EXCLUDE" | tr ',' '\n' | sed -e 's/\./\\./g' -e 's/\*/\.\*/g')")"
_debug2 "Remaining sites: $sitelist"
# counter for success / failure check
successes=0
if [ -n "$sitelist" ]; then
sitetotal="$(echo "$sitelist" | wc -l)"
_debug "$sitetotal sites to deploy"
else
sitetotal=0
_debug "No sites to deploy"
fi
# for each site: call uapi to publish cert and log result. Only return failure if all fail
for site in $sitelist; do
# call uapi to publish cert, check response for errors and log them.
if [ -n "$_uapi_user" ]; then
_response=$(uapi --user="$_uapi_user" SSL install_ssl domain="$site" cert="$_cert" key="$_key")
else
_response=$(uapi SSL install_ssl domain="$site" cert="$_cert" key="$_key")
fi
if [ "${_response#*"$uapi_error_response"}" != "$_response" ]; then
_err "Error in deploying certificate to $site:"
_err "$_response"
else
successes=$((successes + 1))
_debug "$_response"
_info "Succcessfully deployed to $site"
fi
done
# Raise error if all updates fail
if [ "$sitetotal" -gt 0 ] && [ "$successes" -eq 0 ]; then
_err "Could not deploy to any of $sitetotal sites via UAPI"
_debug "successes: $successes, sitetotal: $sitetotal"
return 1
fi
_info "Successfully deployed certificate to $successes of $sitetotal sites via UAPI"
return 0
else
# "classic" mode - will only try to deploy to the primary domain; will not check UAPI first
if [ -n "$_uapi_user" ]; then
_response=$(uapi --user="$_uapi_user" SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
else
_response=$(uapi SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
fi
if [ "${_response#*"$uapi_error_response"}" != "$_response" ]; then
_err "Error in deploying certificate:"
_err "$_response"
return 1
fi
_debug response "$_response"
_info "Certificate successfully deployed"
return 0
fi
}
######## Private functions #####################
# Internal utility to process YML from UAPI - looks at main_domain, sub_domains, addon domains and parked domains
#[response]
__cpanel_parse_response() {
if [ $# -gt 0 ]; then resp="$*"; else resp="$(cat)"; fi
echo "$resp" |
sed -En \
-e 's/\r$//' \
-e 's/^( *)([_.[:alnum:]]+) *: *(.*)/\1,\2,\3/p' \
-e 's/^( *)- (.*)/\1,-,\2/p' |
awk -F, '{
level = length($1)/2;
section[level] = $2;
for (i in section) {if (i > level) {delete section[i]}}
if (length($3) > 0) {
prefix="";
for (i=0; i < level; i++)
{ prefix = (prefix)(section[i])("/") }
printf("%s%s=%s\n", prefix, $2, $3);
}
}' |
sed -En -e 's/^result\/data\/(main_domain|sub_domains\/-|addon_domains\/-|parked_domains\/-)=(.*)$/\2/p'
}
# Load parameter by prefix+name - fallback to default if not set, and save to config
#pname pdefault
__cpanel_initautoparam() {
pname="$1"
pdefault="$2"
pkey="DEPLOY_CPANEL_AUTO_$pname"
_getdeployconf "$pkey"
[ -n "$(eval echo "\"\$$pkey\"")" ] || eval "$pkey=\"$pdefault\""
_debug2 "$pkey" "$(eval echo "\"\$$pkey\"")"
_savedeployconf "$pkey" "$(eval echo "\"\$$pkey\"")"
}

View File

@@ -273,16 +273,27 @@ _check_curl_version() {
_minor="$(_getfield "$_cversion" 2 '.')"
_debug2 "_minor" "$_minor"
if [ "$_major$_minor" -lt "740" ]; then
if [ "$_major" -ge "8" ]; then
#ok
return 0
fi
if [ "$_major" = "7" ]; then
if [ "$_minor" -lt "40" ]; then
_err "curl v$_cversion doesn't support unit socket"
_err "Please upgrade to curl 7.40 or later."
return 1
fi
if [ "$_minor" -lt "50" ]; then
_debug "Use short host name"
export _CURL_NO_HOST=1
else
export _CURL_NO_HOST=
fi
return 0
else
_err "curl v$_cversion doesn't support unit socket"
_err "Please upgrade to curl 7.40 or later."
return 1
fi
if [ "$_major$_minor" -lt "750" ]; then
_debug "Use short host name"
export _CURL_NO_HOST=1
else
export _CURL_NO_HOST=
fi
return 0
}

View File

@@ -1,10 +1,11 @@
#!/usr/bin/env sh
# Here is the script to deploy the cert to G-Core CDN service (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/).
# Here is the script to deploy the cert to G-Core CDN service (https://gcore.com/) using the G-Core Labs API (https://apidocs.gcore.com/cdn).
# Returns 0 when success.
#
# Written by temoffey <temofffey@gmail.com>
# Public domain, 2019
# Update by DreamOfIce <admin@dreamofice.cn> in 2023
#export DEPLOY_GCORE_CDN_USERNAME=myusername
#export DEPLOY_GCORE_CDN_PASSWORD=mypassword
@@ -56,7 +57,7 @@ gcore_cdn_deploy() {
_request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}"
_debug _request "$_request"
export _H1="Content-Type:application/json"
_response=$(_post "$_request" "https://api.gcdn.co/auth/jwt/login")
_response=$(_post "$_request" "https://api.gcore.com/auth/jwt/login")
_debug _response "$_response"
_regex=".*\"access\":\"\([-._0-9A-Za-z]*\)\".*$"
_debug _regex "$_regex"
@@ -69,8 +70,8 @@ gcore_cdn_deploy() {
fi
_info "Find CDN resource with cname $_cdomain"
export _H2="Authorization:Token $_token"
_response=$(_get "https://api.gcdn.co/resources")
export _H2="Authorization:Bearer $_token"
_response=$(_get "https://api.gcore.com/cdn/resources")
_debug _response "$_response"
_regex="\"primary_resource\":null},"
_debug _regex "$_regex"
@@ -102,7 +103,7 @@ gcore_cdn_deploy() {
_date=$(date "+%d.%m.%Y %H:%M:%S")
_request="{\"name\":\"$_cdomain ($_date)\",\"sslCertificate\":\"$_fullchain\",\"sslPrivateKey\":\"$_key\"}"
_debug _request "$_request"
_response=$(_post "$_request" "https://api.gcdn.co/sslData")
_response=$(_post "$_request" "https://api.gcore.com/cdn/sslData")
_debug _response "$_response"
_regex=".*\"id\":\([0-9]*\).*$"
_debug _regex "$_regex"
@@ -117,7 +118,7 @@ gcore_cdn_deploy() {
_info "Update CDN resource"
_request="{\"originGroup\":$_originGroup,\"sslData\":$_sslDataAdd}"
_debug _request "$_request"
_response=$(_post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT")
_response=$(_post "$_request" "https://api.gcore.com/cdn/resources/$_resourceId" '' "PUT")
_debug _response "$_response"
_regex=".*\"sslData\":\([0-9]*\).*$"
_debug _regex "$_regex"
@@ -133,7 +134,7 @@ gcore_cdn_deploy() {
_info "Not found old SSL certificate"
else
_info "Delete old SSL certificate"
_response=$(_post '' "https://api.gcdn.co/sslData/$_sslDataOld" '' "DELETE")
_response=$(_post '' "https://api.gcore.com/cdn/sslData/$_sslDataOld" '' "DELETE")
_debug _response "$_response"
fi

View File

@@ -67,7 +67,7 @@ gitlab_deploy() {
error_response="error"
if test "${_response#*$error_response}" != "$_response"; then
if test "${_response#*"$error_response"}" != "$_response"; then
_err "Error in deploying certificate:"
_err "$_response"
return 1

View File

@@ -20,18 +20,23 @@ mailcow_deploy() {
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
_mailcow_path="${DEPLOY_MAILCOW_PATH}"
_getdeployconf DEPLOY_MAILCOW_PATH
_getdeployconf DEPLOY_MAILCOW_RELOAD
if [ -z "$_mailcow_path" ]; then
_debug DEPLOY_MAILCOW_PATH "$DEPLOY_MAILCOW_PATH"
_debug DEPLOY_MAILCOW_RELOAD "$DEPLOY_MAILCOW_RELOAD"
if [ -z "$DEPLOY_MAILCOW_PATH" ]; then
_err "Mailcow path is not found, please define DEPLOY_MAILCOW_PATH."
return 1
fi
#Tests if _ssl_path is the mailcow root directory.
if [ -f "${_mailcow_path}/generate_config.sh" ]; then
_ssl_path="${_mailcow_path}/data/assets/ssl/"
else
_ssl_path="${_mailcow_path}"
_savedeployconf DEPLOY_MAILCOW_PATH "$DEPLOY_MAILCOW_PATH"
[ -n "$DEPLOY_MAILCOW_RELOAD" ] && _savedeployconf DEPLOY_MAILCOW_RELOAD "$DEPLOY_MAILCOW_RELOAD"
_ssl_path="$DEPLOY_MAILCOW_PATH"
if [ -f "$DEPLOY_MAILCOW_PATH/generate_config.sh" ]; then
_ssl_path="$DEPLOY_MAILCOW_PATH/data/assets/ssl/"
fi
if [ ! -d "$_ssl_path" ]; then
@@ -39,31 +44,20 @@ mailcow_deploy() {
return 1
fi
# ECC or RSA
if [ -z "${Le_Keylength}" ]; then
Le_Keylength=""
fi
if _isEccKey "${Le_Keylength}"; then
_info "ECC key type detected"
_cert_name_prefix="ecdsa-"
else
_info "RSA key type detected"
_cert_name_prefix=""
fi
_info "Copying key and cert"
_real_key="$_ssl_path/${_cert_name_prefix}key.pem"
_real_key="$_ssl_path/key.pem"
if ! cat "$_ckey" >"$_real_key"; then
_err "Error: write key file to: $_real_key"
return 1
fi
_real_fullchain="$_ssl_path/${_cert_name_prefix}cert.pem"
_real_fullchain="$_ssl_path/cert.pem"
if ! cat "$_cfullchain" >"$_real_fullchain"; then
_err "Error: write cert file to: $_real_fullchain"
return 1
fi
DEFAULT_MAILCOW_RELOAD="docker restart $(docker ps -qaf name=postfix-mailcow); docker restart $(docker ps -qaf name=nginx-mailcow); docker restart $(docker ps -qaf name=dovecot-mailcow)"
DEFAULT_MAILCOW_RELOAD="docker restart \$(docker ps --quiet --filter name=nginx-mailcow --filter name=dovecot-mailcow --filter name=postfix-mailcow)"
_reload="${DEPLOY_MAILCOW_RELOAD:-$DEFAULT_MAILCOW_RELOAD}"
_info "Run reload: $_reload"

132
deploy/proxmoxve.sh Normal file
View File

@@ -0,0 +1,132 @@
#!/usr/bin/env sh
# Deploy certificates to a proxmox virtual environment node using the API.
#
# Environment variables that can be set are:
# `DEPLOY_PROXMOXVE_SERVER`: The hostname of the proxmox ve node. Defaults to
# _cdomain.
# `DEPLOY_PROXMOXVE_SERVER_PORT`: The port number the management interface is on.
# Defaults to 8006.
# `DEPLOY_PROXMOXVE_NODE_NAME`: The name of the node we'll be connecting to.
# Defaults to the host portion of the server
# domain name.
# `DEPLOY_PROXMOXVE_USER`: The user we'll connect as. Defaults to root.
# `DEPLOY_PROXMOXVE_USER_REALM`: The authentication realm the user authenticates
# with. Defaults to pam.
# `DEPLOY_PROXMOXVE_API_TOKEN_NAME`: The name of the API token created for the
# user account. Defaults to acme.
# `DEPLOY_PROXMOXVE_API_TOKEN_KEY`: The API token. Required.
proxmoxve_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug2 _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
# "Sane" defaults.
_getdeployconf DEPLOY_PROXMOXVE_SERVER
if [ -z "$DEPLOY_PROXMOXVE_SERVER" ]; then
_target_hostname="$_cdomain"
else
_target_hostname="$DEPLOY_PROXMOXVE_SERVER"
_savedeployconf DEPLOY_PROXMOXVE_SERVER "$DEPLOY_PROXMOXVE_SERVER"
fi
_debug2 DEPLOY_PROXMOXVE_SERVER "$_target_hostname"
_getdeployconf DEPLOY_PROXMOXVE_SERVER_PORT
if [ -z "$DEPLOY_PROXMOXVE_SERVER_PORT" ]; then
_target_port="8006"
else
_target_port="$DEPLOY_PROXMOXVE_SERVER_PORT"
_savedeployconf DEPLOY_PROXMOXVE_SERVER_PORT "$DEPLOY_PROXMOXVE_SERVER_PORT"
fi
_debug2 DEPLOY_PROXMOXVE_SERVER_PORT "$_target_port"
_getdeployconf DEPLOY_PROXMOXVE_NODE_NAME
if [ -z "$DEPLOY_PROXMOXVE_NODE_NAME" ]; then
_node_name=$(echo "$_target_hostname" | cut -d. -f1)
else
_node_name="$DEPLOY_PROXMOXVE_NODE_NAME"
_savedeployconf DEPLOY_PROXMOXVE_NODE_NAME "$DEPLOY_PROXMOXVE_NODE_NAME"
fi
_debug2 DEPLOY_PROXMOXVE_NODE_NAME "$_node_name"
# Complete URL.
_target_url="https://${_target_hostname}:${_target_port}/api2/json/nodes/${_node_name}/certificates/custom"
_debug TARGET_URL "$_target_url"
# More "sane" defaults.
_getdeployconf DEPLOY_PROXMOXVE_USER
if [ -z "$DEPLOY_PROXMOXVE_USER" ]; then
_proxmoxve_user="root"
else
_proxmoxve_user="$DEPLOY_PROXMOXVE_USER"
_savedeployconf DEPLOY_PROXMOXVE_USER "$DEPLOY_PROXMOXVE_USER"
fi
_debug2 DEPLOY_PROXMOXVE_USER "$_proxmoxve_user"
_getdeployconf DEPLOY_PROXMOXVE_USER_REALM
if [ -z "$DEPLOY_PROXMOXVE_USER_REALM" ]; then
_proxmoxve_user_realm="pam"
else
_proxmoxve_user_realm="$DEPLOY_PROXMOXVE_USER_REALM"
_savedeployconf DEPLOY_PROXMOXVE_USER_REALM "$DEPLOY_PROXMOXVE_USER_REALM"
fi
_debug2 DEPLOY_PROXMOXVE_USER_REALM "$_proxmoxve_user_realm"
_getdeployconf DEPLOY_PROXMOXVE_API_TOKEN_NAME
if [ -z "$DEPLOY_PROXMOXVE_API_TOKEN_NAME" ]; then
_proxmoxve_api_token_name="acme"
else
_proxmoxve_api_token_name="$DEPLOY_PROXMOXVE_API_TOKEN_NAME"
_savedeployconf DEPLOY_PROXMOXVE_API_TOKEN_NAME "$DEPLOY_PROXMOXVE_API_TOKEN_NAME"
fi
_debug2 DEPLOY_PROXMOXVE_API_TOKEN_NAME "$_proxmoxve_api_token_name"
# This is required.
_getdeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY
if [ -z "$DEPLOY_PROXMOXVE_API_TOKEN_KEY" ]; then
_err "API key not provided."
return 1
else
_proxmoxve_api_token_key="$DEPLOY_PROXMOXVE_API_TOKEN_KEY"
_savedeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY "$DEPLOY_PROXMOXVE_API_TOKEN_KEY"
fi
_debug2 DEPLOY_PROXMOXVE_API_TOKEN_KEY _proxmoxve_api_token_key
# PVE API Token header value. Used in "Authorization: PVEAPIToken".
_proxmoxve_header_api_token="${_proxmoxve_user}@${_proxmoxve_user_realm}!${_proxmoxve_api_token_name}=${_proxmoxve_api_token_key}"
_debug2 "Auth Header" _proxmoxve_header_api_token
# Ugly. I hate putting heredocs inside functions because heredocs don't
# account for whitespace correctly but it _does_ work and is several times
# cleaner than anything else I had here.
#
# This dumps the json payload to a variable that should be passable to the
# _psot function.
_json_payload=$(
cat <<HEREDOC
{
"certificates": "$(tr '\n' ':' <"$_cfullchain" | sed 's/:/\\n/g')",
"key": "$(tr '\n' ':' <"$_ckey" | sed 's/:/\\n/g')",
"node":"$_node_name",
"restart":"1",
"force":"1"
}
HEREDOC
)
_debug2 Payload "$_json_payload"
# Push certificates to server.
export _HTTPS_INSECURE=1
export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}"
_post "$_json_payload" "$_target_url" "" POST "application/json"
}

View File

@@ -53,7 +53,7 @@ qiniu_deploy() {
sslcert_access_token="$(_make_access_token "$sslcert_path")"
_debug sslcert_access_token "$sslcert_access_token"
export _H1="Authorization: QBox $sslcert_access_token"
sslcert_response=$(_post "$sslcerl_body" "$QINIU_API_BASE$sslcert_path" 0 "POST" "application/json" | _dbase64 "multiline")
sslcert_response=$(_post "$sslcerl_body" "$QINIU_API_BASE$sslcert_path" 0 "POST" "application/json" | _dbase64)
if ! _contains "$sslcert_response" "certID"; then
_err "Error in creating certificate:"
@@ -75,7 +75,7 @@ qiniu_deploy() {
update_access_token="$(_make_access_token "$update_path")"
_debug update_access_token "$update_access_token"
export _H1="Authorization: QBox $update_access_token"
update_response=$(_post "$update_body" "$QINIU_API_BASE$update_path" 0 "PUT" "application/json" | _dbase64 "multiline")
update_response=$(_post "$update_body" "$QINIU_API_BASE$update_path" 0 "PUT" "application/json" | _dbase64)
if _contains "$update_response" "error"; then
_err "Error in updating domain $domain httpsconf:"

View File

@@ -23,6 +23,7 @@
# ```sh
# export ROUTER_OS_USERNAME=certuser
# export ROUTER_OS_HOST=router.example.com
# export ROUTER_OS_PORT=22
#
# acme.sh --deploy -d ftp.example.com --deploy-hook routeros
# ```
@@ -48,6 +49,16 @@
# One optional thing to do as well is to create a script that updates
# all the required services and run that script in a single command.
#
# To adopt parameters to `scp` and/or `ssh` set the optional
# `ROUTER_OS_SSH_CMD` and `ROUTER_OS_SCP_CMD` variables accordingly,
# see ssh(1) and scp(1) for parameters to those commands.
#
# Example:
# ```ssh
# export ROUTER_OS_SSH_CMD="ssh -i /acme.sh/.ssh/router.example.com -o UserKnownHostsFile=/acme.sh/.ssh/known_hosts"
# export ROUTER_OS_SCP_CMD="scp -i /acme.sh/.ssh/router.example.com -o UserKnownHostsFile=/acme.sh/.ssh/known_hosts"
# ````
#
# returns 0 means success, otherwise error.
######## Public functions #####################
@@ -59,6 +70,7 @@ routeros_deploy() {
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_err_code=0
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
@@ -80,6 +92,27 @@ routeros_deploy() {
return 1
fi
_getdeployconf ROUTER_OS_PORT
if [ -z "$ROUTER_OS_PORT" ]; then
_debug "Using default port 22 as ROUTER_OS_PORT, please set if not correct."
ROUTER_OS_PORT=22
fi
_getdeployconf ROUTER_OS_SSH_CMD
if [ -z "$ROUTER_OS_SSH_CMD" ]; then
_debug "Use default ssh setup."
ROUTER_OS_SSH_CMD="ssh -p $ROUTER_OS_PORT"
fi
_getdeployconf ROUTER_OS_SCP_CMD
if [ -z "$ROUTER_OS_SCP_CMD" ]; then
_debug "USe default scp setup."
ROUTER_OS_SCP_CMD="scp -P $ROUTER_OS_PORT"
fi
_getdeployconf ROUTER_OS_ADDITIONAL_SERVICES
if [ -z "$ROUTER_OS_ADDITIONAL_SERVICES" ]; then
@@ -89,16 +122,26 @@ routeros_deploy() {
_savedeployconf ROUTER_OS_HOST "$ROUTER_OS_HOST"
_savedeployconf ROUTER_OS_USERNAME "$ROUTER_OS_USERNAME"
_savedeployconf ROUTER_OS_PORT "$ROUTER_OS_PORT"
_savedeployconf ROUTER_OS_SSH_CMD "$ROUTER_OS_SSH_CMD"
_savedeployconf ROUTER_OS_SCP_CMD "$ROUTER_OS_SCP_CMD"
_savedeployconf ROUTER_OS_ADDITIONAL_SERVICES "$ROUTER_OS_ADDITIONAL_SERVICES"
_info "Trying to push key '$_ckey' to router"
scp "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key"
_info "Trying to push cert '$_cfullchain' to router"
scp "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer"
DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=admin policy=ftp,read,write,password,sensitive \
source=\"## generated by routeros deploy script in acme.sh;\
\n/certificate remove [ find name=$_cdomain.cer_0 ];\
# push key to routeros
if ! _scp_certificate "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key"; then
return $_err_code
fi
# push certificate chain to routeros
if ! _scp_certificate "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer"; then
return $_err_code
fi
DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=$ROUTER_OS_USERNAME \
comment=\"generated by routeros deploy script in acme.sh\" \
source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\
\n/certificate remove [ find name=$_cdomain.cer_1 ];\
\n/certificate remove [ find name=$_cdomain.cer_2 ];\
\ndelay 1;\
\n/certificate import file-name=$_cdomain.cer passphrase=\\\"\\\";\
\n/certificate import file-name=$_cdomain.key passphrase=\\\"\\\";\
@@ -110,12 +153,51 @@ source=\"## generated by routeros deploy script in acme.sh;\
\n$ROUTER_OS_ADDITIONAL_SERVICES;\
\n\"
"
# shellcheck disable=SC2029
ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "$DEPLOY_SCRIPT_CMD"
# shellcheck disable=SC2029
ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script run \"LE Cert Deploy - $_cdomain\""
# shellcheck disable=SC2029
ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script remove \"LE Cert Deploy - $_cdomain\""
if ! _ssh_remote_cmd "$DEPLOY_SCRIPT_CMD"; then
return $_err_code
fi
if ! _ssh_remote_cmd "/system script run \"LE Cert Deploy - $_cdomain\""; then
return $_err_code
fi
if ! _ssh_remote_cmd "/system script remove \"LE Cert Deploy - $_cdomain\""; then
return $_err_code
fi
return 0
}
# inspired by deploy/ssh.sh
_ssh_remote_cmd() {
_cmd="$1"
_secure_debug "Remote commands to execute: $_cmd"
_info "Submitting sequence of commands to routeros"
# quotations in bash cmd below intended. Squash travis spellcheck error
# shellcheck disable=SC2029
$ROUTER_OS_SSH_CMD "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "$_cmd"
_err_code="$?"
if [ "$_err_code" != "0" ]; then
_err "Error code $_err_code returned from routeros"
fi
return $_err_code
}
_scp_certificate() {
_src="$1"
_dst="$2"
_secure_debug "scp '$_src' to '$_dst'"
_info "Push key '$_src' to routeros"
$ROUTER_OS_SCP_CMD "$_src" "$_dst"
_err_code="$?"
if [ "$_err_code" != "0" ]; then
_err "Error code $_err_code returned from scp"
fi
return $_err_code
}

View File

@@ -14,7 +14,7 @@
# The following examples are for QNAP NAS running QTS 4.2
# export DEPLOY_SSH_CMD="" # defaults to "ssh -T"
# export DEPLOY_SSH_USER="admin" # required
# export DEPLOY_SSH_SERVER="qnap" # defaults to domain name
# export DEPLOY_SSH_SERVER="host1 host2:8022 192.168.0.1:9022" # defaults to domain name, support multiple servers with optional port
# export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem"
# export DEPLOY_SSH_CERTFILE="/etc/stunnel/stunnel.pem"
# export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem"
@@ -23,6 +23,8 @@
# export DEPLOY_SSH_BACKUP="" # yes or no, default to yes or previously saved value
# export DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" # path on remote system. Defaults to .acme_ssh_deploy
# export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value
# export DEPLOY_SSH_USE_SCP="" yes or no, default to no
# export DEPLOY_SSH_SCP_CMD="" defaults to "scp -q"
#
######## Public functions #####################
@@ -42,72 +44,134 @@ ssh_deploy() {
_debug _cfullchain "$_cfullchain"
# USER is required to login by SSH to remote host.
_migratedeployconf Le_Deploy_ssh_user DEPLOY_SSH_USER
_getdeployconf DEPLOY_SSH_USER
_debug2 DEPLOY_SSH_USER "$DEPLOY_SSH_USER"
if [ -z "$DEPLOY_SSH_USER" ]; then
if [ -z "$Le_Deploy_ssh_user" ]; then
_err "DEPLOY_SSH_USER not defined."
return 1
fi
else
Le_Deploy_ssh_user="$DEPLOY_SSH_USER"
_savedomainconf Le_Deploy_ssh_user "$Le_Deploy_ssh_user"
_err "DEPLOY_SSH_USER not defined."
return 1
fi
_savedeployconf DEPLOY_SSH_USER "$DEPLOY_SSH_USER"
# SERVER is optional. If not provided then use _cdomain
_migratedeployconf Le_Deploy_ssh_server DEPLOY_SSH_SERVER
_getdeployconf DEPLOY_SSH_SERVER
_debug2 DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER"
if [ -n "$DEPLOY_SSH_SERVER" ]; then
Le_Deploy_ssh_server="$DEPLOY_SSH_SERVER"
_savedomainconf Le_Deploy_ssh_server "$Le_Deploy_ssh_server"
elif [ -z "$Le_Deploy_ssh_server" ]; then
Le_Deploy_ssh_server="$_cdomain"
if [ -z "$DEPLOY_SSH_SERVER" ]; then
DEPLOY_SSH_SERVER="$_cdomain"
fi
_savedeployconf DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER"
# CMD is optional. If not provided then use ssh
_migratedeployconf Le_Deploy_ssh_cmd DEPLOY_SSH_CMD
_getdeployconf DEPLOY_SSH_CMD
_debug2 DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD"
if [ -n "$DEPLOY_SSH_CMD" ]; then
Le_Deploy_ssh_cmd="$DEPLOY_SSH_CMD"
_savedomainconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd"
elif [ -z "$Le_Deploy_ssh_cmd" ]; then
Le_Deploy_ssh_cmd="ssh -T"
if [ -z "$DEPLOY_SSH_CMD" ]; then
DEPLOY_SSH_CMD="ssh -T"
fi
_savedeployconf DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD"
# BACKUP is optional. If not provided then default to previously saved value or yes.
_migratedeployconf Le_Deploy_ssh_backup DEPLOY_SSH_BACKUP
_getdeployconf DEPLOY_SSH_BACKUP
_debug2 DEPLOY_SSH_BACKUP "$DEPLOY_SSH_BACKUP"
if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then
Le_Deploy_ssh_backup="no"
elif [ -z "$Le_Deploy_ssh_backup" ] || [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
Le_Deploy_ssh_backup="yes"
if [ -z "$DEPLOY_SSH_BACKUP" ]; then
DEPLOY_SSH_BACKUP="yes"
fi
_savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup"
_savedeployconf DEPLOY_SSH_BACKUP "$DEPLOY_SSH_BACKUP"
# BACKUP_PATH is optional. If not provided then default to previously saved value or .acme_ssh_deploy
_migratedeployconf Le_Deploy_ssh_backup_path DEPLOY_SSH_BACKUP_PATH
_getdeployconf DEPLOY_SSH_BACKUP_PATH
_debug2 DEPLOY_SSH_BACKUP_PATH "$DEPLOY_SSH_BACKUP_PATH"
if [ -n "$DEPLOY_SSH_BACKUP_PATH" ]; then
Le_Deploy_ssh_backup_path="$DEPLOY_SSH_BACKUP_PATH"
elif [ -z "$Le_Deploy_ssh_backup_path" ]; then
Le_Deploy_ssh_backup_path=".acme_ssh_deploy"
if [ -z "$DEPLOY_SSH_BACKUP_PATH" ]; then
DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy"
fi
_savedomainconf Le_Deploy_ssh_backup_path "$Le_Deploy_ssh_backup_path"
_savedeployconf DEPLOY_SSH_BACKUP_PATH "$DEPLOY_SSH_BACKUP_PATH"
# MULTI_CALL is optional. If not provided then default to previously saved
# value (which may be undefined... equivalent to "no").
_migratedeployconf Le_Deploy_ssh_multi_call DEPLOY_SSH_MULTI_CALL
_getdeployconf DEPLOY_SSH_MULTI_CALL
_debug2 DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
Le_Deploy_ssh_multi_call="yes"
_savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call"
elif [ "$DEPLOY_SSH_MULTI_CALL" = "no" ]; then
Le_Deploy_ssh_multi_call=""
_cleardomainconf Le_Deploy_ssh_multi_call
if [ -z "$DEPLOY_SSH_MULTI_CALL" ]; then
DEPLOY_SSH_MULTI_CALL="no"
fi
_savedeployconf DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL"
# KEYFILE is optional.
# If provided then private key will be copied to provided filename.
_migratedeployconf Le_Deploy_ssh_keyfile DEPLOY_SSH_KEYFILE
_getdeployconf DEPLOY_SSH_KEYFILE
_debug2 DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE"
if [ -n "$DEPLOY_SSH_KEYFILE" ]; then
_savedeployconf DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE"
fi
_deploy_ssh_servers=$Le_Deploy_ssh_server
for Le_Deploy_ssh_server in $_deploy_ssh_servers; do
# CERTFILE is optional.
# If provided then certificate will be copied or appended to provided filename.
_migratedeployconf Le_Deploy_ssh_certfile DEPLOY_SSH_CERTFILE
_getdeployconf DEPLOY_SSH_CERTFILE
_debug2 DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE"
if [ -n "$DEPLOY_SSH_CERTFILE" ]; then
_savedeployconf DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE"
fi
# CAFILE is optional.
# If provided then CA intermediate certificate will be copied or appended to provided filename.
_migratedeployconf Le_Deploy_ssh_cafile DEPLOY_SSH_CAFILE
_getdeployconf DEPLOY_SSH_CAFILE
_debug2 DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE"
if [ -n "$DEPLOY_SSH_CAFILE" ]; then
_savedeployconf DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE"
fi
# FULLCHAIN is optional.
# If provided then fullchain certificate will be copied or appended to provided filename.
_migratedeployconf Le_Deploy_ssh_fullchain DEPLOY_SSH_FULLCHAIN
_getdeployconf DEPLOY_SSH_FULLCHAIN
_debug2 DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN"
if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then
_savedeployconf DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN"
fi
# REMOTE_CMD is optional.
# If provided then this command will be executed on remote host.
_migratedeployconf Le_Deploy_ssh_remote_cmd DEPLOY_SSH_REMOTE_CMD
_getdeployconf DEPLOY_SSH_REMOTE_CMD
_debug2 DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD"
if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then
_savedeployconf DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD"
fi
# USE_SCP is optional. If not provided then default to previously saved
# value (which may be undefined... equivalent to "no").
_getdeployconf DEPLOY_SSH_USE_SCP
_debug2 DEPLOY_SSH_USE_SCP "$DEPLOY_SSH_USE_SCP"
if [ -z "$DEPLOY_SSH_USE_SCP" ]; then
DEPLOY_SSH_USE_SCP="no"
fi
_savedeployconf DEPLOY_SSH_USE_SCP "$DEPLOY_SSH_USE_SCP"
# SCP_CMD is optional. If not provided then use scp
_getdeployconf DEPLOY_SSH_SCP_CMD
_debug2 DEPLOY_SSH_SCP_CMD "$DEPLOY_SSH_SCP_CMD"
if [ -z "$DEPLOY_SSH_SCP_CMD" ]; then
DEPLOY_SSH_SCP_CMD="scp -q"
fi
_savedeployconf DEPLOY_SSH_SCP_CMD "$DEPLOY_SSH_SCP_CMD"
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then
DEPLOY_SSH_MULTI_CALL="yes"
_info "Using scp as alternate method for copying files. Multicall Mode is implicit"
elif [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
_info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host"
else
_info "Required commands batched and sent in single call to remote host"
fi
_deploy_ssh_servers="$DEPLOY_SSH_SERVER"
for DEPLOY_SSH_SERVER in $_deploy_ssh_servers; do
_ssh_deploy
done
}
@@ -117,16 +181,25 @@ _ssh_deploy() {
_cmdstr=""
_backupprefix=""
_backupdir=""
_local_cert_file=""
_local_ca_file=""
_local_full_file=""
_info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server"
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
_info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host"
else
_info "Required commands batched and sent in single call to remote host"
fi
case $DEPLOY_SSH_SERVER in
*:*)
_host=${DEPLOY_SSH_SERVER%:*}
_port=${DEPLOY_SSH_SERVER##*:}
;;
*)
_host=$DEPLOY_SSH_SERVER
_port=
;;
esac
if [ "$Le_Deploy_ssh_backup" = "yes" ]; then
_backupprefix="$Le_Deploy_ssh_backup_path/$_cdomain-backup"
_info "Deploy certificates to remote server $DEPLOY_SSH_USER@$_host:$_port"
if [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
_backupprefix="$DEPLOY_SSH_BACKUP_PATH/$_cdomain-backup"
_backupdir="$_backupprefix-$(_utc_date | tr ' ' '-')"
# run cleanup on the backup directory, erase all older
# than 180 days (15552000 seconds).
@@ -138,7 +211,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
_cmdstr="mkdir -p $_backupdir; $_cmdstr"
_info "Backup of old certificate files will be placed in remote directory $_backupdir"
_info "Backup directories erased after 180 days."
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
@@ -146,129 +219,184 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
fi
fi
# KEYFILE is optional.
# If provided then private key will be copied to provided filename.
_getdeployconf DEPLOY_SSH_KEYFILE
_debug2 DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE"
if [ -n "$DEPLOY_SSH_KEYFILE" ]; then
Le_Deploy_ssh_keyfile="$DEPLOY_SSH_KEYFILE"
_savedomainconf Le_Deploy_ssh_keyfile "$Le_Deploy_ssh_keyfile"
fi
if [ -n "$Le_Deploy_ssh_keyfile" ]; then
if [ "$Le_Deploy_ssh_backup" = "yes" ]; then
if [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
# backup file we are about to overwrite.
_cmdstr="$_cmdstr cp $Le_Deploy_ssh_keyfile $_backupdir >/dev/null;"
_cmdstr="$_cmdstr cp $DEPLOY_SSH_KEYFILE $_backupdir >/dev/null;"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi
# copy new certificate into file.
_cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;"
_info "will copy private key to remote file $Le_Deploy_ssh_keyfile"
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
# copy new key into file.
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then
# scp the file
if ! _scp_remote_cmd "$_ckey" "$DEPLOY_SSH_KEYFILE"; then
return $_err_code
fi
_cmdstr=""
else
# ssh echo to the file
_cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $DEPLOY_SSH_KEYFILE;"
_info "will copy private key to remote file $DEPLOY_SSH_KEYFILE"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi
fi
# CERTFILE is optional.
# If provided then certificate will be copied or appended to provided filename.
_getdeployconf DEPLOY_SSH_CERTFILE
_debug2 DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE"
if [ -n "$DEPLOY_SSH_CERTFILE" ]; then
Le_Deploy_ssh_certfile="$DEPLOY_SSH_CERTFILE"
_savedomainconf Le_Deploy_ssh_certfile "$Le_Deploy_ssh_certfile"
fi
if [ -n "$Le_Deploy_ssh_certfile" ]; then
_pipe=">"
if [ "$Le_Deploy_ssh_certfile" = "$Le_Deploy_ssh_keyfile" ]; then
if [ "$DEPLOY_SSH_CERTFILE" = "$DEPLOY_SSH_KEYFILE" ]; then
# if filename is same as previous file then append.
_pipe=">>"
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
# backup file we are about to overwrite.
_cmdstr="$_cmdstr cp $Le_Deploy_ssh_certfile $_backupdir >/dev/null;"
_cmdstr="$_cmdstr cp $DEPLOY_SSH_CERTFILE $_backupdir >/dev/null;"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi
# copy new certificate into file.
_cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;"
_info "will copy certificate to remote file $Le_Deploy_ssh_certfile"
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then
# scp the file
_local_cert_file=$(_mktemp)
if [ "$DEPLOY_SSH_CERTFILE" = "$DEPLOY_SSH_KEYFILE" ]; then
cat "$_ckey" >>"$_local_cert_file"
fi
cat "$_ccert" >>"$_local_cert_file"
if ! _scp_remote_cmd "$_local_cert_file" "$DEPLOY_SSH_CERTFILE"; then
return $_err_code
fi
_cmdstr=""
else
# ssh echo to the file
_cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $DEPLOY_SSH_CERTFILE;"
_info "will copy certificate to remote file $DEPLOY_SSH_CERTFILE"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi
fi
# CAFILE is optional.
# If provided then CA intermediate certificate will be copied or appended to provided filename.
_getdeployconf DEPLOY_SSH_CAFILE
_debug2 DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE"
if [ -n "$DEPLOY_SSH_CAFILE" ]; then
Le_Deploy_ssh_cafile="$DEPLOY_SSH_CAFILE"
_savedomainconf Le_Deploy_ssh_cafile "$Le_Deploy_ssh_cafile"
fi
if [ -n "$Le_Deploy_ssh_cafile" ]; then
_pipe=">"
if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] ||
[ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then
if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_KEYFILE" ] ||
[ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_CERTFILE" ]; then
# if filename is same as previous file then append.
_pipe=">>"
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
# backup file we are about to overwrite.
_cmdstr="$_cmdstr cp $Le_Deploy_ssh_cafile $_backupdir >/dev/null;"
_cmdstr="$_cmdstr cp $DEPLOY_SSH_CAFILE $_backupdir >/dev/null;"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi
# copy new certificate into file.
_cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;"
_info "will copy CA file to remote file $Le_Deploy_ssh_cafile"
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then
# scp the file
_local_ca_file=$(_mktemp)
if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_KEYFILE" ]; then
cat "$_ckey" >>"$_local_ca_file"
fi
if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_CERTFILE" ]; then
cat "$_ccert" >>"$_local_ca_file"
fi
cat "$_cca" >>"$_local_ca_file"
if ! _scp_remote_cmd "$_local_ca_file" "$DEPLOY_SSH_CAFILE"; then
return $_err_code
fi
_cmdstr=""
else
# ssh echo to the file
_cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $DEPLOY_SSH_CAFILE;"
_info "will copy CA file to remote file $DEPLOY_SSH_CAFILE"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi
fi
# FULLCHAIN is optional.
# If provided then fullchain certificate will be copied or appended to provided filename.
_getdeployconf DEPLOY_SSH_FULLCHAIN
_debug2 DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN"
if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then
Le_Deploy_ssh_fullchain="$DEPLOY_SSH_FULLCHAIN"
_savedomainconf Le_Deploy_ssh_fullchain "$Le_Deploy_ssh_fullchain"
fi
if [ -n "$Le_Deploy_ssh_fullchain" ]; then
_pipe=">"
if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] ||
[ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ] ||
[ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then
if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_KEYFILE" ] ||
[ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CERTFILE" ] ||
[ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CAFILE" ]; then
# if filename is same as previous file then append.
_pipe=">>"
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
# backup file we are about to overwrite.
_cmdstr="$_cmdstr cp $Le_Deploy_ssh_fullchain $_backupdir >/dev/null;"
_cmdstr="$_cmdstr cp $DEPLOY_SSH_FULLCHAIN $_backupdir >/dev/null;"
if [ "$DEPLOY_SSH_FULLCHAIN" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi
# copy new certificate into file.
_cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;"
_info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain"
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then
# scp the file
_local_full_file=$(_mktemp)
if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_KEYFILE" ]; then
cat "$_ckey" >>"$_local_full_file"
fi
if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CERTFILE" ]; then
cat "$_ccert" >>"$_local_full_file"
fi
if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CAFILE" ]; then
cat "$_cca" >>"$_local_full_file"
fi
cat "$_cfullchain" >>"$_local_full_file"
if ! _scp_remote_cmd "$_local_full_file" "$DEPLOY_SSH_FULLCHAIN"; then
return $_err_code
fi
_cmdstr=""
else
# ssh echo to the file
_cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $DEPLOY_SSH_FULLCHAIN;"
_info "will copy fullchain to remote file $DEPLOY_SSH_FULLCHAIN"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi
fi
# REMOTE_CMD is optional.
# If provided then this command will be executed on remote host.
_getdeployconf DEPLOY_SSH_REMOTE_CMD
_debug2 DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD"
if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then
Le_Deploy_ssh_remote_cmd="$DEPLOY_SSH_REMOTE_CMD"
_savedomainconf Le_Deploy_ssh_remote_cmd "$Le_Deploy_ssh_remote_cmd"
# cleanup local files if any
if [ -f "$_local_cert_file" ]; then
rm -f "$_local_cert_file"
fi
if [ -n "$Le_Deploy_ssh_remote_cmd" ]; then
_cmdstr="$_cmdstr $Le_Deploy_ssh_remote_cmd;"
_info "Will execute remote command $Le_Deploy_ssh_remote_cmd"
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
if [ -f "$_local_ca_file" ]; then
rm -f "$_local_ca_file"
fi
if [ -f "$_local_full_file" ]; then
rm -f "$_local_full_file"
fi
if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then
_cmdstr="$_cmdstr $DEPLOY_SSH_REMOTE_CMD;"
_info "Will execute remote command $DEPLOY_SSH_REMOTE_CMD"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
@@ -282,17 +410,25 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
return $_err_code
fi
fi
# cleanup in case all is ok
return 0
}
#cmd
_ssh_remote_cmd() {
_cmd="$1"
_ssh_cmd="$DEPLOY_SSH_CMD"
if [ -n "$_port" ]; then
_ssh_cmd="$_ssh_cmd -p $_port"
fi
_secure_debug "Remote commands to execute: $_cmd"
_info "Submitting sequence of commands to remote server by ssh"
_info "Submitting sequence of commands to remote server by $_ssh_cmd"
# quotations in bash cmd below intended. Squash travis spellcheck error
# shellcheck disable=SC2029
$Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmd'"
$_ssh_cmd "$DEPLOY_SSH_USER@$_host" sh -c "'$_cmd'"
_err_code="$?"
if [ "$_err_code" != "0" ]; then
@@ -301,3 +437,26 @@ _ssh_remote_cmd() {
return $_err_code
}
# cmd scp
_scp_remote_cmd() {
_src=$1
_dest=$2
_scp_cmd="$DEPLOY_SSH_SCP_CMD"
if [ -n "$_port" ]; then
_scp_cmd="$_scp_cmd -P $_port"
fi
_secure_debug "Remote copy source $_src to destination $_dest"
_info "Submitting secure copy by $_scp_cmd"
$_scp_cmd "$_src" "$DEPLOY_SSH_USER"@"$_host":"$_dest"
_err_code="$?"
if [ "$_err_code" != "0" ]; then
_err "Error code $_err_code returned from scp"
fi
return $_err_code
}

View File

@@ -94,7 +94,12 @@ synology_dsm_deploy() {
otp_code=""
if [ -n "$SYNO_TOTP_SECRET" ]; then
otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)"
if _exists oathtool; then
otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)"
else
_err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET"
return 1
fi
fi
if [ -n "$SYNO_DID" ]; then
@@ -103,7 +108,7 @@ synology_dsm_deploy() {
_debug3 H1 "${_H1}"
fi
response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$otp_code" "$_base_url/webapi/auth.cgi?enable_syno_token=yes")
response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$otp_code&device_name=certrenewal&device_id=$SYNO_DID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes")
token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p')
_debug3 response "$response"
_debug token "$token"

View File

@@ -38,7 +38,7 @@ truenas_deploy() {
_getdeployconf DEPLOY_TRUENAS_APIKEY
if [ -z "$DEPLOY_TRUENAS_APIKEY" ]; then
_err "TrueNAS Api Key is not found, please define DEPLOY_TRUENAS_APIKEY."
_err "TrueNAS API key not found, please set the DEPLOY_TRUENAS_APIKEY environment variable."
return 1
fi
_secure_debug2 DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY"
@@ -62,15 +62,14 @@ truenas_deploy() {
_info "Testing Connection TrueNAS"
_response=$(_get "$_api_url/system/state")
_info "TrueNAS System State: $_response."
_info "TrueNAS system state: $_response."
if [ -z "$_response" ]; then
_err "Unable to authenticate to $_api_url."
_err 'Check your Connection and set DEPLOY_TRUENAS_HOSTNAME="192.168.178.x".'
_err 'or'
_err 'set DEPLOY_TRUENAS_HOSTNAME="<truenas_dnsname>".'
_err 'Check your Connection and set DEPLOY_TRUENAS_SCHEME="https".'
_err "Check your Api Key."
_err 'Check your connection settings are correct, e.g.'
_err 'DEPLOY_TRUENAS_HOSTNAME="192.168.x.y" or DEPLOY_TRUENAS_HOSTNAME="truenas.example.com".'
_err 'DEPLOY_TRUENAS_SCHEME="https" or DEPLOY_TRUENAS_SCHEME="http".'
_err "Verify your TrueNAS API key is valid and set correctly, e.g. DEPLOY_TRUENAS_APIKEY=xxxx...."
return 1
fi
@@ -78,7 +77,7 @@ truenas_deploy() {
_savedeployconf DEPLOY_TRUENAS_HOSTNAME "$DEPLOY_TRUENAS_HOSTNAME"
_savedeployconf DEPLOY_TRUENAS_SCHEME "$DEPLOY_TRUENAS_SCHEME"
_info "Getting active certificate from TrueNAS"
_info "Getting current active certificate from TrueNAS"
_response=$(_get "$_api_url/system/general")
_active_cert_id=$(echo "$_response" | grep -B2 '"name":' | grep 'id' | tr -d -- '"id: ,')
_active_cert_name=$(echo "$_response" | grep '"name":' | sed -n 's/.*: "\(.\{1,\}\)",$/\1/p')
@@ -88,14 +87,14 @@ truenas_deploy() {
_debug Active_UI_http_redirect "$_param_httpsredirect"
if [ "$DEPLOY_TRUENAS_SCHEME" = "http" ] && [ "$_param_httpsredirect" = "true" ]; then
_info "http Redirect active"
_info "HTTP->HTTPS redirection is enabled"
_info "Setting DEPLOY_TRUENAS_SCHEME to 'https'"
DEPLOY_TRUENAS_SCHEME="https"
_api_url="$DEPLOY_TRUENAS_SCHEME://$DEPLOY_TRUENAS_HOSTNAME/api/v2.0"
_savedeployconf DEPLOY_TRUENAS_SCHEME "$DEPLOY_TRUENAS_SCHEME"
fi
_info "Upload new certifikate to TrueNAS"
_info "Uploading new certificate to TrueNAS"
_certname="Letsencrypt_$(_utc_date | tr ' ' '_' | tr -d -- ':')"
_debug3 _certname "$_certname"
@@ -104,30 +103,30 @@ truenas_deploy() {
_debug3 _add_cert_result "$_add_cert_result"
_info "Getting Certificate list to get new Cert ID"
_info "Fetching list of installed certificates"
_cert_list=$(_get "$_api_url/system/general/ui_certificate_choices")
_cert_id=$(echo "$_cert_list" | grep "$_certname" | sed -n 's/.*"\([0-9]\{1,\}\)".*$/\1/p')
_debug3 _cert_id "$_cert_id"
_info "Activate Certificate ID: $_cert_id"
_info "Current activate certificate ID: $_cert_id"
_activateData="{\"ui_certificate\": \"${_cert_id}\"}"
_activate_result="$(_post "$_activateData" "$_api_url/system/general" "" "PUT" "application/json")"
_debug3 _activate_result "$_activate_result"
_info "Check if WebDAV certificate is the same as the WEB UI"
_info "Checking if WebDAV certificate is the same as the TrueNAS web UI"
_webdav_list=$(_get "$_api_url/webdav")
_webdav_cert_id=$(echo "$_webdav_list" | grep '"certssl":' | tr -d -- '"certsl: ,')
if [ "$_webdav_cert_id" = "$_active_cert_id" ]; then
_info "Update the WebDAV Certificate"
_info "Updating the WebDAV certificate"
_debug _webdav_cert_id "$_webdav_cert_id"
_webdav_data="{\"certssl\": \"${_cert_id}\"}"
_activate_webdav_cert="$(_post "$_webdav_data" "$_api_url/webdav" "" "PUT" "application/json")"
_webdav_new_cert_id=$(echo "$_activate_webdav_cert" | _json_decode | sed -n 's/.*: \([0-9]\{1,\}\) }$/\1/p')
_webdav_new_cert_id=$(echo "$_activate_webdav_cert" | _json_decode | grep '"certssl":' | sed -n 's/.*: \([0-9]\{1,\}\),\{0,1\}$/\1/p')
if [ "$_webdav_new_cert_id" -eq "$_cert_id" ]; then
_info "WebDAV Certificate update successfully"
_info "WebDAV certificate updated successfully"
else
_err "Unable to set WebDAV certificate"
_debug3 _activate_webdav_cert "$_activate_webdav_cert"
@@ -136,21 +135,21 @@ truenas_deploy() {
fi
_debug3 _webdav_new_cert_id "$_webdav_new_cert_id"
else
_info "WebDAV certificate not set or not the same as Web UI"
_info "WebDAV certificate is not configured or is not the same as TrueNAS web UI"
fi
_info "Check if FTP certificate is the same as the WEB UI"
_info "Checking if FTP certificate is the same as the TrueNAS web UI"
_ftp_list=$(_get "$_api_url/ftp")
_ftp_cert_id=$(echo "$_ftp_list" | grep '"ssltls_certificate":' | tr -d -- '"certislfa:_ ,')
if [ "$_ftp_cert_id" = "$_active_cert_id" ]; then
_info "Update the FTP Certificate"
_info "Updating the FTP certificate"
_debug _ftp_cert_id "$_ftp_cert_id"
_ftp_data="{\"ssltls_certificate\": \"${_cert_id}\"}"
_activate_ftp_cert="$(_post "$_ftp_data" "$_api_url/ftp" "" "PUT" "application/json")"
_ftp_new_cert_id=$(echo "$_activate_ftp_cert" | _json_decode | sed -n 's/.*: \([0-9]\{1,\}\) }$/\1/p')
_ftp_new_cert_id=$(echo "$_activate_ftp_cert" | _json_decode | grep '"ssltls_certificate":' | sed -n 's/.*: \([0-9]\{1,\}\),\{0,1\}$/\1/p')
if [ "$_ftp_new_cert_id" -eq "$_cert_id" ]; then
_info "FTP Certificate update successfully"
_info "FTP certificate updated successfully"
else
_err "Unable to set FTP certificate"
_debug3 _activate_ftp_cert "$_activate_ftp_cert"
@@ -159,22 +158,66 @@ truenas_deploy() {
fi
_debug3 _activate_ftp_cert "$_activate_ftp_cert"
else
_info "FTP certificate not set or not the same as Web UI"
_info "FTP certificate is not configured or is not the same as TrueNAS web UI"
fi
_info "Delete old Certificate"
_info "Checking if S3 certificate is the same as the TrueNAS web UI"
_s3_list=$(_get "$_api_url/s3")
_s3_cert_id=$(echo "$_s3_list" | grep '"certificate":' | tr -d -- '"certifa:_ ,')
if [ "$_s3_cert_id" = "$_active_cert_id" ]; then
_info "Updating the S3 certificate"
_debug _s3_cert_id "$_s3_cert_id"
_s3_data="{\"certificate\": \"${_cert_id}\"}"
_activate_s3_cert="$(_post "$_s3_data" "$_api_url/s3" "" "PUT" "application/json")"
_s3_new_cert_id=$(echo "$_activate_s3_cert" | _json_decode | grep '"certificate":' | sed -n 's/.*: \([0-9]\{1,\}\),\{0,1\}$/\1/p')
if [ "$_s3_new_cert_id" -eq "$_cert_id" ]; then
_info "S3 certificate updated successfully"
else
_err "Unable to set S3 certificate"
_debug3 _activate_s3_cert "$_activate_s3_cert"
_debug3 _s3_new_cert_id "$_s3_new_cert_id"
return 1
fi
_debug3 _activate_s3_cert "$_activate_s3_cert"
else
_info "S3 certificate is not configured or is not the same as TrueNAS web UI"
fi
_info "Checking if any chart release Apps is using the same certificate as TrueNAS web UI. Tool 'jq' is required"
if _exists jq; then
_info "Query all chart release"
_release_list=$(_get "$_api_url/chart/release")
_related_name_list=$(printf "%s" "$_release_list" | jq -r "[.[] | {name,certId: .config.ingress?.main.tls[]?.scaleCert} | select(.certId==$_active_cert_id) | .name ] | unique")
_release_length=$(printf "%s" "$_related_name_list" | jq -r "length")
_info "Found $_release_length related chart release in list: $_related_name_list"
for i in $(seq 0 $((_release_length - 1))); do
_release_name=$(echo "$_related_name_list" | jq -r ".[$i]")
_info "Updating certificate from $_active_cert_id to $_cert_id for chart release: $_release_name"
#Read the chart release configuration
_chart_config=$(printf "%s" "$_release_list" | jq -r ".[] | select(.name==\"$_release_name\")")
#Replace the old certificate id with the new one in path .config.ingress.main.tls[].scaleCert. Then update .config.ingress
_updated_chart_config=$(printf "%s" "$_chart_config" | jq "(.config.ingress?.main.tls[]? | select(.scaleCert==$_active_cert_id) | .scaleCert ) |= $_cert_id | .config.ingress ")
_update_chart_result="$(_post "{\"values\" : { \"ingress\" : $_updated_chart_config } }" "$_api_url/chart/release/id/$_release_name" "" "PUT" "application/json")"
_debug3 _update_chart_result "$_update_chart_result"
done
else
_info "Tool 'jq' does not exists, skip chart release checking"
fi
_info "Deleting old certificate"
_delete_result="$(_post "" "$_api_url/certificate/id/$_active_cert_id" "" "DELETE" "application/json")"
_debug3 _delete_result "$_delete_result"
_info "Reload WebUI from TrueNAS"
_info "Reloading TrueNAS web UI"
_restart_UI=$(_get "$_api_url/system/general/ui_restart")
_debug2 _restart_UI "$_restart_UI"
if [ -n "$_add_cert_result" ] && [ -n "$_activate_result" ]; then
return 0
else
_err "Certupdate was not succesfull, please use --debug"
_err "Certificate update was not succesful, please try again with --debug"
return 1
fi
}

View File

@@ -7,13 +7,16 @@
#
# VAULT_PREFIX - this contains the prefix path in vault
# VAULT_ADDR - vault requires this to find your vault server
# VAULT_SAVE_TOKEN - set to anything if you want to save the token
# VAULT_RENEW_TOKEN - set to anything if you want to renew the token to default TTL before deploying
# VAULT_KV_V2 - set to anything if you are using v2 of the kv engine
#
# additionally, you need to ensure that VAULT_TOKEN is avialable
# to access the vault server
#returns 0 means success, otherwise error.
######## Public functions #####################
######## Public functions #####################
#domain keyfile certfile cafile fullchain
vault_deploy() {
@@ -45,6 +48,26 @@ vault_deploy() {
fi
_savedeployconf VAULT_ADDR "$VAULT_ADDR"
_getdeployconf VAULT_SAVE_TOKEN
_savedeployconf VAULT_SAVE_TOKEN "$VAULT_SAVE_TOKEN"
_getdeployconf VAULT_RENEW_TOKEN
_savedeployconf VAULT_RENEW_TOKEN "$VAULT_RENEW_TOKEN"
_getdeployconf VAULT_KV_V2
_savedeployconf VAULT_KV_V2 "$VAULT_KV_V2"
_getdeployconf VAULT_TOKEN
if [ -z "$VAULT_TOKEN" ]; then
_err "VAULT_TOKEN needs to be defined"
return 1
fi
if [ -n "$VAULT_SAVE_TOKEN" ]; then
_savedeployconf VAULT_TOKEN "$VAULT_TOKEN"
fi
_migratedeployconf FABIO VAULT_FABIO_MODE
# JSON does not allow multiline strings.
# So replacing new-lines with "\n" here
_ckey=$(sed -z 's/\n/\\n/g' <"$2")
@@ -52,26 +75,56 @@ vault_deploy() {
_cca=$(sed -z 's/\n/\\n/g' <"$4")
_cfullchain=$(sed -z 's/\n/\\n/g' <"$5")
URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain"
export _H1="X-Vault-Token: $VAULT_TOKEN"
if [ -n "$FABIO" ]; then
if [ -n "$VAULT_RENEW_TOKEN" ]; then
URL="$VAULT_ADDR/v1/auth/token/renew-self"
_info "Renew the Vault token to default TTL"
if ! _post "" "$URL" >/dev/null; then
_err "Failed to renew the Vault token"
return 1
fi
fi
URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain"
if [ -n "$VAULT_FABIO_MODE" ]; then
_info "Writing certificate and key to $URL in Fabio mode"
if [ -n "$VAULT_KV_V2" ]; then
_post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL"
_post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL" >/dev/null || return 1
else
_post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL"
_post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" >/dev/null || return 1
fi
else
if [ -n "$VAULT_KV_V2" ]; then
_post "{\"data\": {\"value\": \"$_ccert\"}}" "$URL/cert.pem"
_post "{\"data\": {\"value\": \"$_ckey\"}}" "$URL/cert.key"
_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/chain.pem"
_post "{\"data\": {\"value\": \"$_cfullchain\"}}" "$URL/fullchain.pem"
_info "Writing certificate to $URL/cert.pem"
_post "{\"data\": {\"value\": \"$_ccert\"}}" "$URL/cert.pem" >/dev/null || return 1
_info "Writing key to $URL/cert.key"
_post "{\"data\": {\"value\": \"$_ckey\"}}" "$URL/cert.key" >/dev/null || return 1
_info "Writing CA certificate to $URL/ca.pem"
_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/ca.pem" >/dev/null || return 1
_info "Writing full-chain certificate to $URL/fullchain.pem"
_post "{\"data\": {\"value\": \"$_cfullchain\"}}" "$URL/fullchain.pem" >/dev/null || return 1
else
_post "{\"value\": \"$_ccert\"}" "$URL/cert.pem"
_post "{\"value\": \"$_ckey\"}" "$URL/cert.key"
_post "{\"value\": \"$_cca\"}" "$URL/chain.pem"
_post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem"
_info "Writing certificate to $URL/cert.pem"
_post "{\"value\": \"$_ccert\"}" "$URL/cert.pem" >/dev/null || return 1
_info "Writing key to $URL/cert.key"
_post "{\"value\": \"$_ckey\"}" "$URL/cert.key" >/dev/null || return 1
_info "Writing CA certificate to $URL/ca.pem"
_post "{\"value\": \"$_cca\"}" "$URL/ca.pem" >/dev/null || return 1
_info "Writing full-chain certificate to $URL/fullchain.pem"
_post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" >/dev/null || return 1
fi
# To make it compatible with the wrong ca path `chain.pem` which was used in former versions
if _contains "$(_get "$URL/chain.pem")" "-----BEGIN CERTIFICATE-----"; then
_err "The CA certificate has moved from chain.pem to ca.pem, if you don't depend on chain.pem anymore, you can delete it to avoid this warning"
_info "Updating CA certificate to $URL/chain.pem for backward compatibility"
if [ -n "$VAULT_KV_V2" ]; then
_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/chain.pem" >/dev/null || return 1
else
_post "{\"value\": \"$_cca\"}" "$URL/chain.pem" >/dev/null || return 1
fi
fi
fi

View File

@@ -8,6 +8,8 @@
#
# VAULT_PREFIX - this contains the prefix path in vault
# VAULT_ADDR - vault requires this to find your vault server
# VAULT_SAVE_TOKEN - set to anything if you want to save the token
# VAULT_RENEW_TOKEN - set to anything if you want to renew the token to default TTL before deploying
#
# additionally, you need to ensure that VAULT_TOKEN is avialable or
# `vault auth` has applied the appropriate authorization for the vault binary
@@ -33,15 +35,36 @@ vault_cli_deploy() {
_debug _cfullchain "$_cfullchain"
# validate required env vars
_getdeployconf VAULT_PREFIX
if [ -z "$VAULT_PREFIX" ]; then
_err "VAULT_PREFIX needs to be defined (contains prefix path in vault)"
return 1
fi
_savedeployconf VAULT_PREFIX "$VAULT_PREFIX"
_getdeployconf VAULT_ADDR
if [ -z "$VAULT_ADDR" ]; then
_err "VAULT_ADDR needs to be defined (contains vault connection address)"
return 1
fi
_savedeployconf VAULT_ADDR "$VAULT_ADDR"
_getdeployconf VAULT_SAVE_TOKEN
_savedeployconf VAULT_SAVE_TOKEN "$VAULT_SAVE_TOKEN"
_getdeployconf VAULT_RENEW_TOKEN
_savedeployconf VAULT_RENEW_TOKEN "$VAULT_RENEW_TOKEN"
_getdeployconf VAULT_TOKEN
if [ -z "$VAULT_TOKEN" ]; then
_err "VAULT_TOKEN needs to be defined"
return 1
fi
if [ -n "$VAULT_SAVE_TOKEN" ]; then
_savedeployconf VAULT_TOKEN "$VAULT_TOKEN"
fi
_migratedeployconf FABIO VAULT_FABIO_MODE
VAULT_CMD=$(command -v vault)
if [ ! $? ]; then
@@ -49,13 +72,33 @@ vault_cli_deploy() {
return 1
fi
if [ -n "$FABIO" ]; then
if [ -n "$VAULT_RENEW_TOKEN" ]; then
_info "Renew the Vault token to default TTL"
if ! $VAULT_CMD token renew; then
_err "Failed to renew the Vault token"
return 1
fi
fi
if [ -n "$VAULT_FABIO_MODE" ]; then
_info "Writing certificate and key to ${VAULT_PREFIX}/${_cdomain} in Fabio mode"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1
else
_info "Writing certificate to ${VAULT_PREFIX}/${_cdomain}/cert.pem"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1
_info "Writing key to ${VAULT_PREFIX}/${_cdomain}/cert.key"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1
_info "Writing CA certificate to ${VAULT_PREFIX}/${_cdomain}/ca.pem"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/ca.pem" value=@"$_cca" || return 1
_info "Writing full-chain certificate to ${VAULT_PREFIX}/${_cdomain}/fullchain.pem"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1
# To make it compatible with the wrong ca path `chain.pem` which was used in former versions
if $VAULT_CMD kv get "${VAULT_PREFIX}/${_cdomain}/chain.pem" >/dev/null; then
_err "The CA certificate has moved from chain.pem to ca.pem, if you don't depend on chain.pem anymore, you can delete it to avoid this warning"
_info "Updating CA certificate to ${VAULT_PREFIX}/${_cdomain}/chain.pem for backward compatibility"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1
fi
fi
}

View File

@@ -42,7 +42,7 @@ dns_1984hosting_add() {
_debug "Add TXT record $fulldomain with value '$txtvalue'"
value="$(printf '%s' "$txtvalue" | _url_encode)"
url="https://management.1984hosting.com/domains/entry/"
url="https://1984.hosting/domains/entry/"
postdata="entry=new"
postdata="$postdata&type=TXT"
@@ -95,7 +95,7 @@ dns_1984hosting_rm() {
_debug _domain "$_domain"
_debug "Delete $fulldomain TXT record"
url="https://management.1984hosting.com/domains"
url="https://1984.hosting/domains"
if ! _get_zone_id "$url" "$_domain"; then
_err "invalid zone" "$_domain"
return 1
@@ -138,7 +138,7 @@ _1984hosting_login() {
_debug "Login to 1984Hosting as user $One984HOSTING_Username"
username=$(printf '%s' "$One984HOSTING_Username" | _url_encode)
password=$(printf '%s' "$One984HOSTING_Password" | _url_encode)
url="https://management.1984hosting.com/accounts/checkuserauth/"
url="https://1984.hosting/accounts/checkuserauth/"
response="$(_post "username=$username&password=$password&otpkey=" $url)"
response="$(echo "$response" | _normalizeJson)"
@@ -175,7 +175,7 @@ _check_cookies() {
return 1
fi
_authget "https://management.1984hosting.com/accounts/loginstatus/"
_authget "https://1984.hosting/accounts/loginstatus/"
if _contains "$response" '"ok": true'; then
_debug "Cached cookies still valid"
return 0
@@ -204,7 +204,7 @@ _get_root() {
return 1
fi
_authget "https://management.1984hosting.com/domains/soacheck/?zone=$h&nameserver=ns0.1984.is."
_authget "https://1984.hosting/domains/soacheck/?zone=$h&nameserver=ns0.1984.is."
if _contains "$_response" "serial" && ! _contains "$_response" "null"; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h"
@@ -251,11 +251,11 @@ _htmlget() {
# add extra headers to request
_authpost() {
url="https://management.1984hosting.com/domains"
url="https://1984.hosting/domains"
_get_zone_id "$url" "$_domain"
csrf_header="$(echo "$One984HOSTING_CSRFTOKEN_COOKIE" | _egrep_o "=[^=][0-9a-zA-Z]*" | tr -d "=")"
export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE"
export _H2="Referer: https://management.1984hosting.com/domains/$_zone_id"
export _H2="Referer: https://1984.hosting/domains/$_zone_id"
export _H3="X-CSRFToken: $csrf_header"
_response=$(_post "$1" "$2")
}

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env sh
## Acmeproxy DNS provider to be used with acmeproxy (http://github.com/mdbraber/acmeproxy)
## Acmeproxy DNS provider to be used with acmeproxy (https://github.com/mdbraber/acmeproxy)
## API integration by Maarten den Braber
##
## Report any bugs via https://github.com/mdbraber/acme.sh

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env sh
#Arvan_Token="Apikey xxxx"
# Arvan_Token="Apikey xxxx"
ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains"
#Author: Vahid Fardi
#Report Bugs here: https://github.com/Neilpang/acme.sh
ARVAN_API_URL="https://napi.arvancloud.ir/cdn/4.0/domains"
# Author: Vahid Fardi
# Report Bugs here: https://github.com/Neilpang/acme.sh
#
######## Public functions #####################
@@ -18,7 +18,7 @@ dns_arvan_add() {
if [ -z "$Arvan_Token" ]; then
_err "You didn't specify \"Arvan_Token\" token yet."
_err "You can get yours from here https://npanel.arvancloud.com/profile/api-keys"
_err "You can get yours from here https://npanel.arvancloud.ir/profile/api-keys"
return 1
fi
#save the api token to the account conf file.
@@ -40,7 +40,7 @@ dns_arvan_add() {
_info "response id is $response"
_info "Added, OK"
return 0
elif _contains "$response" "Record Data is Duplicated"; then
elif _contains "$response" "Record Data is duplicate"; then
_info "Already exists, OK"
return 0
else
@@ -141,6 +141,7 @@ _arvan_rest() {
response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")"
elif [ "$mtd" = "POST" ]; then
export _H2="Content-Type: application/json"
export _H3="Accept: application/json"
_debug data "$data"
response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")"
else

View File

@@ -152,34 +152,23 @@ dns_aws_rm() {
_get_root() {
domain=$1
i=2
i=1
p=1
if aws_rest GET "2013-04-01/hostedzone"; then
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug2 "Checking domain: $h"
if [ -z "$h" ]; then
if _contains "$response" "<IsTruncated>true</IsTruncated>" && _contains "$response" "<NextMarker>"; then
_debug "IsTruncated"
_nextMarker="$(echo "$response" | _egrep_o "<NextMarker>.*</NextMarker>" | cut -d '>' -f 2 | cut -d '<' -f 1)"
_debug "NextMarker" "$_nextMarker"
if aws_rest GET "2013-04-01/hostedzone" "marker=$_nextMarker"; then
_debug "Truncated request OK"
i=2
p=1
continue
else
_err "Truncated request error."
fi
fi
#not valid
_err "Invalid domain"
return 1
fi
# iterate over names (a.b.c.d -> b.c.d -> c.d -> d)
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug "Checking domain: $h"
if [ -z "$h" ]; then
_error "invalid domain"
return 1
fi
# iterate over paginated result for list_hosted_zones
aws_rest GET "2013-04-01/hostedzone"
while true; do
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>")"
hostedzone="$(echo "$response" | tr -d '\n' | sed 's/<HostedZone>/#&/g' | tr '#' '\n' | _egrep_o "<HostedZone><Id>[^<]*<.Id><Name>$h.<.Name>.*<PrivateZone>false<.PrivateZone>.*<.HostedZone>")"
_debug hostedzone "$hostedzone"
if [ "$hostedzone" ]; then
_domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "<Id>.*<.Id>" | head -n 1 | _egrep_o ">.*<" | tr -d "<>")
@@ -192,10 +181,19 @@ _get_root() {
return 1
fi
fi
p=$i
i=$(_math "$i" + 1)
if _contains "$response" "<IsTruncated>true</IsTruncated>" && _contains "$response" "<NextMarker>"; then
_debug "IsTruncated"
_nextMarker="$(echo "$response" | _egrep_o "<NextMarker>.*</NextMarker>" | cut -d '>' -f 2 | cut -d '<' -f 1)"
_debug "NextMarker" "$_nextMarker"
else
break
fi
_debug "Checking domain: $h - Next Page "
aws_rest GET "2013-04-01/hostedzone" "marker=$_nextMarker"
done
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}

248
dnsapi/dns_bunny.sh Normal file
View File

@@ -0,0 +1,248 @@
#!/usr/bin/env sh
## Will be called by acme.sh to add the TXT record via the Bunny DNS API.
## returns 0 means success, otherwise error.
## Author: nosilver4u <nosilver4u at ewww.io>
## GitHub: https://github.com/nosilver4u/acme.sh
##
## Environment Variables Required:
##
## BUNNY_API_KEY="75310dc4-ca77-9ac3-9a19-f6355db573b49ce92ae1-2655-3ebd-61ac-3a3ae34834cc"
##
##################### Public functions #####################
## Create the text record for validation.
## Usage: fulldomain txtvalue
## EG: "_acme-challenge.www.other.domain.com" "XKrxpRBosdq0HG9i01zxXp5CPBs"
dns_bunny_add() {
fulldomain="$(echo "$1" | _lower_case)"
txtvalue=$2
BUNNY_API_KEY="${BUNNY_API_KEY:-$(_readaccountconf_mutable BUNNY_API_KEY)}"
# Check if API Key is set
if [ -z "$BUNNY_API_KEY" ]; then
BUNNY_API_KEY=""
_err "You did not specify Bunny.net API key."
_err "Please export BUNNY_API_KEY and try again."
return 1
fi
_info "Using Bunny.net dns validation - add record"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
## save the env vars (key and domain split location) for later automated use
_saveaccountconf_mutable BUNNY_API_KEY "$BUNNY_API_KEY"
## split the domain for Bunny API
if ! _get_base_domain "$fulldomain"; then
_err "domain not found in your account for addition"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug _domain_id "$_domain_id"
## Set the header with our post type and auth key
export _H1="Accept: application/json"
export _H2="AccessKey: $BUNNY_API_KEY"
export _H3="Content-Type: application/json"
PURL="https://api.bunny.net/dnszone/$_domain_id/records"
PBODY='{"Id":'$_domain_id',"Type":3,"Name":"'$_sub_domain'","Value":"'$txtvalue'","ttl":120}'
_debug PURL "$PURL"
_debug PBODY "$PBODY"
## the create request - POST
## args: BODY, URL, [need64, httpmethod]
response="$(_post "$PBODY" "$PURL" "" "PUT")"
## check response
if [ "$?" != "0" ]; then
_err "error in response: $response"
return 1
fi
_debug2 response "$response"
## finished correctly
return 0
}
## Remove the txt record after validation.
## Usage: fulldomain txtvalue
## EG: "_acme-challenge.www.other.domain.com" "XKrxpRBosdq0HG9i01zxXp5CPBs"
dns_bunny_rm() {
fulldomain="$(echo "$1" | _lower_case)"
txtvalue=$2
BUNNY_API_KEY="${BUNNY_API_KEY:-$(_readaccountconf_mutable BUNNY_API_KEY)}"
# Check if API Key Exists
if [ -z "$BUNNY_API_KEY" ]; then
BUNNY_API_KEY=""
_err "You did not specify Bunny.net API key."
_err "Please export BUNNY_API_KEY and try again."
return 1
fi
_info "Using Bunny.net dns validation - remove record"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
## split the domain for Bunny API
if ! _get_base_domain "$fulldomain"; then
_err "Domain not found in your account for TXT record removal"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug _domain_id "$_domain_id"
## Set the header with our post type and key auth key
export _H1="Accept: application/json"
export _H2="AccessKey: $BUNNY_API_KEY"
## get URL for the list of DNS records
GURL="https://api.bunny.net/dnszone/$_domain_id"
## 1) Get the domain/zone records
## the fetch request - GET
## args: URL, [onlyheader, timeout]
domain_list="$(_get "$GURL")"
## check response
if [ "$?" != "0" ]; then
_err "error in domain_list response: $domain_list"
return 1
fi
_debug2 domain_list "$domain_list"
## 2) search through records
## check for what we are looking for: "Type":3,"Value":"$txtvalue","Name":"$_sub_domain"
record="$(echo "$domain_list" | _egrep_o "\"Id\"\s*\:\s*\"*[0-9]+\"*,\s*\"Type\"[^}]*\"Value\"\s*\:\s*\"$txtvalue\"[^}]*\"Name\"\s*\:\s*\"$_sub_domain\"")"
if [ -n "$record" ]; then
## We found records
rec_ids="$(echo "$record" | _egrep_o "Id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")"
_debug rec_ids "$rec_ids"
if [ -n "$rec_ids" ]; then
echo "$rec_ids" | while IFS= read -r rec_id; do
## delete the record
## delete URL for removing the one we dont want
DURL="https://api.bunny.net/dnszone/$_domain_id/records/$rec_id"
## the removal request - DELETE
## args: BODY, URL, [need64, httpmethod]
response="$(_post "" "$DURL" "" "DELETE")"
## check response (sort of)
if [ "$?" != "0" ]; then
_err "error in remove response: $response"
return 1
fi
_debug2 response "$response"
done
fi
fi
## finished correctly
return 0
}
##################### Private functions below #####################
## Split the domain provided into the "base domain" and the "start prefix".
## This function searches for the longest subdomain in your account
## for the full domain given and splits it into the base domain (zone)
## and the prefix/record to be added/removed
## USAGE: fulldomain
## EG: "_acme-challenge.two.three.four.domain.com"
## returns
## _sub_domain="_acme-challenge.two"
## _domain="three.four.domain.com" *IF* zone "three.four.domain.com" exists
## _domain_id=234
## if only "domain.com" exists it will return
## _sub_domain="_acme-challenge.two.three.four"
## _domain="domain.com"
## _domain_id=234
_get_base_domain() {
# args
fulldomain="$(echo "$1" | _lower_case)"
_debug fulldomain "$fulldomain"
# domain max legal length = 253
MAX_DOM=255
page=1
## get a list of domains for the account to check thru
## Set the headers
export _H1="Accept: application/json"
export _H2="AccessKey: $BUNNY_API_KEY"
_debug BUNNY_API_KEY "$BUNNY_API_KEY"
## get URL for the list of domains
## may get: "links":{"pages":{"last":".../v2/domains/DOM/records?page=2","next":".../v2/domains/DOM/records?page=2"}}
DOMURL="https://api.bunny.net/dnszone"
## while we dont have a matching domain we keep going
while [ -z "$found" ]; do
## get the domain list (current page)
domain_list="$(_get "$DOMURL")"
## check response
if [ "$?" != "0" ]; then
_err "error in domain_list response: $domain_list"
return 1
fi
_debug2 domain_list "$domain_list"
i=1
while [ $i -gt 0 ]; do
## get next longest domain
_domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM")
## check we got something back from our cut (or are we at the end)
if [ -z "$_domain" ]; then
break
fi
## we got part of a domain back - grep it out
found="$(echo "$domain_list" | _egrep_o "\"Id\"\s*:\s*\"*[0-9]+\"*,\s*\"Domain\"\s*\:\s*\"$_domain\"")"
## check if it exists
if [ -n "$found" ]; then
## exists - exit loop returning the parts
sub_point=$(_math $i - 1)
_sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point")
_domain_id="$(echo "$found" | _egrep_o "Id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")"
_debug _domain_id "$_domain_id"
_debug _domain "$_domain"
_debug _sub_domain "$_sub_domain"
found=""
return 0
fi
## increment cut point $i
i=$(_math $i + 1)
done
if [ -z "$found" ]; then
page=$(_math $page + 1)
nextpage="https://api.bunny.net/dnszone?page=$page"
## Find the next page if we don't have a match.
hasnextpage="$(echo "$domain_list" | _egrep_o "\"HasMoreItems\"\s*:\s*true")"
if [ -z "$hasnextpage" ]; then
_err "No record and no nextpage in Bunny.net domain search."
found=""
return 1
fi
_debug2 nextpage "$nextpage"
DOMURL="$nextpage"
fi
done
## We went through the entire domain zone list and didn't find one that matched.
## If we ever get here, something is broken in the code...
_err "Domain not found in Bunny.net account, but we should never get here!"
found=""
return 1
}

View File

@@ -25,9 +25,16 @@ dns_cf_add() {
CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}"
if [ "$CF_Token" ]; then
_saveaccountconf_mutable CF_Token "$CF_Token"
_saveaccountconf_mutable CF_Account_ID "$CF_Account_ID"
_saveaccountconf_mutable CF_Zone_ID "$CF_Zone_ID"
if [ "$CF_Zone_ID" ]; then
_savedomainconf CF_Token "$CF_Token"
_savedomainconf CF_Account_ID "$CF_Account_ID"
_savedomainconf CF_Zone_ID "$CF_Zone_ID"
else
_saveaccountconf_mutable CF_Token "$CF_Token"
_saveaccountconf_mutable CF_Account_ID "$CF_Account_ID"
_clearaccountconf_mutable CF_Zone_ID
_clearaccountconf CF_Zone_ID
fi
else
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
CF_Key=""
@@ -45,6 +52,14 @@ dns_cf_add() {
#save the api key and email to the account conf file.
_saveaccountconf_mutable CF_Key "$CF_Key"
_saveaccountconf_mutable CF_Email "$CF_Email"
_clearaccountconf_mutable CF_Token
_clearaccountconf_mutable CF_Account_ID
_clearaccountconf_mutable CF_Zone_ID
_clearaccountconf CF_Token
_clearaccountconf CF_Account_ID
_clearaccountconf CF_Zone_ID
fi
_debug "First detect the root zone"

View File

@@ -78,7 +78,7 @@ dns_cloudns_rm() {
return 1
fi
for i in $(echo "$response" | tr '{' "\n" | grep "$record"); do
for i in $(echo "$response" | tr '{' "\n" | grep -- "$record"); do
record_id=$(echo "$i" | tr ',' "\n" | grep -E '^"id"' | sed -re 's/^\"id\"\:\"([0-9]+)\"$/\1/g')
if [ -n "$record_id" ]; then

View File

@@ -13,6 +13,7 @@
# cPanel_Hostname=hostname
#
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Used to add txt record
dns_cpanel_add() {
fulldomain=$1
@@ -120,7 +121,7 @@ _myget() {
_get_root() {
_myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones'
_domains=$(echo "$_result" | sed 's/.*\(zones.*\[\).*/\1/' | cut -d':' -f2 | sed 's/"//g' | sed 's/{//g')
_domains=$(echo "$_result" | _egrep_o '"[a-z0-9\.\-]*":\["; cPanel first' | cut -d':' -f1 | sed 's/"//g' | sed 's/{//g')
_debug "_result is: $_result"
_debug "_domains is: $_domains"
if [ -z "$_domains" ]; then
@@ -138,15 +139,15 @@ _get_root() {
}
_successful_update() {
if (echo "$_result" | grep -q 'newserial'); then return 0; fi
return 1
if (echo "$_result" | _egrep_o 'data":\[[^]]*]' | grep -q '"newserial":null'); then return 1; fi
return 0
}
_findentry() {
_debug "In _findentry"
#returns id of dns entry, if it exists
_myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&domain=$_domain"
_id=$(echo "$_result" | sed "s/.*\(line.*$fulldomain.*$txtvalue\).*/\1/" | cut -d ':' -f 2 | cut -d ',' -f 1)
_id=$(echo "$_result" | sed -e "s/},{/},\n{/g" | grep "$fulldomain" | grep "$txtvalue" | _egrep_o 'line":[0-9]+' | cut -d ':' -f 2)
_debug "_result is: $_result"
_debug "fulldomain. is $fulldomain."
_debug "txtvalue is $txtvalue"

159
dnsapi/dns_curanet.sh Normal file
View File

@@ -0,0 +1,159 @@
#!/usr/bin/env sh
#Script to use with curanet.dk, scannet.dk, wannafind.dk, dandomain.dk DNS management.
#Requires api credentials with scope: dns
#Author: Peter L. Hansen <peter@r12.dk>
#Version 1.0
CURANET_REST_URL="https://api.curanet.dk/dns/v1/Domains"
CURANET_AUTH_URL="https://apiauth.dk.team.blue/auth/realms/Curanet/protocol/openid-connect/token"
CURANET_ACCESS_TOKEN=""
######## Public functions #####################
#Usage: dns_curanet_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_curanet_add() {
fulldomain=$1
txtvalue=$2
_info "Using curanet"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
CURANET_AUTHCLIENTID="${CURANET_AUTHCLIENTID:-$(_readaccountconf_mutable CURANET_AUTHCLIENTID)}"
CURANET_AUTHSECRET="${CURANET_AUTHSECRET:-$(_readaccountconf_mutable CURANET_AUTHSECRET)}"
if [ -z "$CURANET_AUTHCLIENTID" ] || [ -z "$CURANET_AUTHSECRET" ]; then
CURANET_AUTHCLIENTID=""
CURANET_AUTHSECRET=""
_err "You don't specify curanet api client and secret."
_err "Please create your auth info and try again."
return 1
fi
#save the credentials to the account conf file.
_saveaccountconf_mutable CURANET_AUTHCLIENTID "$CURANET_AUTHCLIENTID"
_saveaccountconf_mutable CURANET_AUTHSECRET "$CURANET_AUTHSECRET"
if ! _get_token; then
_err "Unable to get token"
return 1
fi
if ! _get_root "$fulldomain"; then
_err "Invalid domain"
return 1
fi
export _H1="Content-Type: application/json-patch+json"
export _H2="Accept: application/json"
export _H3="Authorization: Bearer $CURANET_ACCESS_TOKEN"
data="{\"name\": \"$fulldomain\",\"type\": \"TXT\",\"ttl\": 60,\"priority\": 0,\"data\": \"$txtvalue\"}"
response="$(_post "$data" "$CURANET_REST_URL/${_domain}/Records" "" "")"
if _contains "$response" "$txtvalue"; then
_debug "TXT record added OK"
else
_err "Unable to add TXT record"
return 1
fi
return 0
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_curanet_rm() {
fulldomain=$1
txtvalue=$2
_info "Using curanet"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
CURANET_AUTHCLIENTID="${CURANET_AUTHCLIENTID:-$(_readaccountconf_mutable CURANET_AUTHCLIENTID)}"
CURANET_AUTHSECRET="${CURANET_AUTHSECRET:-$(_readaccountconf_mutable CURANET_AUTHSECRET)}"
if ! _get_token; then
_err "Unable to get token"
return 1
fi
if ! _get_root "$fulldomain"; then
_err "Invalid domain"
return 1
fi
_debug "Getting current record list to identify TXT to delete"
export _H1="Content-Type: application/json"
export _H2="Accept: application/json"
export _H3="Authorization: Bearer $CURANET_ACCESS_TOKEN"
response="$(_get "$CURANET_REST_URL/${_domain}/Records" "" "")"
if ! _contains "$response" "$txtvalue"; then
_err "Unable to delete record (does not contain $txtvalue )"
return 1
fi
recordid=$(echo "$response" | _egrep_o "{\"id\":[0-9]+,\"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":60,\"priority\":0,\"data\":\"..$txtvalue" | _egrep_o "id\":[0-9]+" | cut -c 5-)
if [ -z "$recordid" ]; then
_err "Unable to get recordid"
_debug "regex {\"id\":[0-9]+,\"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":60,\"priority\":0,\"data\":\"..$txtvalue"
_debug "response $response"
return 1
fi
_debug "Deleting recordID $recordid"
response="$(_post "" "$CURANET_REST_URL/${_domain}/Records/$recordid" "" "DELETE")"
return 0
}
#################### Private functions below ##################################
_get_token() {
response="$(_post "grant_type=client_credentials&client_id=$CURANET_AUTHCLIENTID&client_secret=$CURANET_AUTHSECRET&scope=dns" "$CURANET_AUTH_URL" "" "")"
if ! _contains "$response" "access_token"; then
_err "Unable get access token"
return 1
fi
CURANET_ACCESS_TOKEN=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]+" | cut -c 17-)
if [ -z "$CURANET_ACCESS_TOKEN" ]; then
_err "Unable to get token"
return 1
fi
return 0
}
#_acme-challenge.www.domain.com
#returns
# _domain=domain.com
# _domain_id=sdjkglgdfewsdfg
_get_root() {
domain=$1
i=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
export _H1="Content-Type: application/json"
export _H2="Accept: application/json"
export _H3="Authorization: Bearer $CURANET_ACCESS_TOKEN"
response="$(_get "$CURANET_REST_URL/$h/Records" "" "")"
if [ ! "$(echo "$response" | _egrep_o "Entity not found")" ]; then
_domain=$h
return 0
fi
i=$(_math "$i" + 1)
done
return 1
}

View File

@@ -1,185 +0,0 @@
#!/usr/bin/env sh
# CloudXNS Domain api
#
#CX_Key="1234"
#
#CX_Secret="sADDsdasdgdsf"
CX_Api="https://www.cloudxns.net/api2"
#REST_API
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_cx_add() {
fulldomain=$1
txtvalue=$2
CX_Key="${CX_Key:-$(_readaccountconf_mutable CX_Key)}"
CX_Secret="${CX_Secret:-$(_readaccountconf_mutable CX_Secret)}"
if [ -z "$CX_Key" ] || [ -z "$CX_Secret" ]; then
CX_Key=""
CX_Secret=""
_err "You don't specify cloudxns.net api key or secret yet."
_err "Please create you key and try again."
return 1
fi
REST_API="$CX_Api"
#save the api key and email to the account conf file.
_saveaccountconf_mutable CX_Key "$CX_Key"
_saveaccountconf_mutable CX_Secret "$CX_Secret"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
add_record "$_domain" "$_sub_domain" "$txtvalue"
}
#fulldomain txtvalue
dns_cx_rm() {
fulldomain=$1
txtvalue=$2
CX_Key="${CX_Key:-$(_readaccountconf_mutable CX_Key)}"
CX_Secret="${CX_Secret:-$(_readaccountconf_mutable CX_Secret)}"
REST_API="$CX_Api"
if _get_root "$fulldomain"; then
record_id=""
existing_records "$_domain" "$_sub_domain" "$txtvalue"
if [ "$record_id" ]; then
_rest DELETE "record/$record_id/$_domain_id" "{}"
_info "Deleted record ${fulldomain}"
fi
fi
}
#usage: root sub
#return if the sub record already exists.
#echos the existing records count.
# '0' means doesn't exist
existing_records() {
_debug "Getting txt records"
root=$1
sub=$2
if ! _rest GET "record/$_domain_id?:domain_id?host_id=0&offset=0&row_num=100"; then
return 1
fi
seg=$(printf "%s\n" "$response" | _egrep_o '"record_id":[^{]*host":"'"$_sub_domain"'"[^}]*\}')
_debug seg "$seg"
if [ -z "$seg" ]; then
return 0
fi
if printf "%s" "$response" | grep '"type":"TXT"' >/dev/null; then
record_id=$(printf "%s\n" "$seg" | _egrep_o '"record_id":"[^"]*"' | cut -d : -f 2 | tr -d \" | _head_n 1)
_debug record_id "$record_id"
return 0
fi
}
#add the txt record.
#usage: root sub txtvalue
add_record() {
root=$1
sub=$2
txtvalue=$3
fulldomain="$sub.$root"
_info "Adding record"
if ! _rest POST "record" "{\"domain_id\": $_domain_id, \"host\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"type\":\"TXT\",\"ttl\":600, \"line_id\":1}"; then
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
i=2
p=1
if ! _rest GET "domain"; then
return 1
fi
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
if _contains "$response" "$h."; then
seg=$(printf "%s\n" "$response" | _egrep_o '"id":[^{]*"'"$h"'."[^}]*}')
_debug seg "$seg"
_domain_id=$(printf "%s\n" "$seg" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")
_debug _domain_id "$_domain_id"
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_debug _sub_domain "$_sub_domain"
_domain="$h"
_debug _domain "$_domain"
return 0
fi
return 1
fi
p="$i"
i=$(_math "$i" + 1)
done
return 1
}
#Usage: method URI data
_rest() {
m=$1
ep="$2"
_debug ep "$ep"
url="$REST_API/$ep"
_debug url "$url"
cdate=$(date -u "+%Y-%m-%d %H:%M:%S UTC")
_debug cdate "$cdate"
data="$3"
_debug data "$data"
sec="$CX_Key$url$data$cdate$CX_Secret"
_debug sec "$sec"
hmac=$(printf "%s" "$sec" | _digest md5 hex)
_debug hmac "$hmac"
export _H1="API-KEY: $CX_Key"
export _H2="API-REQUEST-DATE: $cdate"
export _H3="API-HMAC: $hmac"
export _H4="Content-Type: application/json"
if [ "$data" ]; then
response="$(_post "$data" "$url" "" "$m")"
else
response="$(_get "$url")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
_contains "$response" '"code":1'
}

View File

@@ -44,7 +44,7 @@ dns_cyon_rm() {
_cyon_load_credentials() {
# Convert loaded password to/from base64 as needed.
if [ "${CY_Password_B64}" ]; then
CY_Password="$(printf "%s" "${CY_Password_B64}" | _dbase64 "multiline")"
CY_Password="$(printf "%s" "${CY_Password_B64}" | _dbase64)"
elif [ "${CY_Password}" ]; then
CY_Password_B64="$(printf "%s" "${CY_Password}" | _base64)"
fi

View File

@@ -192,6 +192,7 @@ _get_base_domain() {
## get URL for the list of domains
## may get: "links":{"pages":{"last":".../v2/domains/DOM/records?page=2","next":".../v2/domains/DOM/records?page=2"}}
DOMURL="https://api.digitalocean.com/v2/domains"
found=""
## while we dont have a matching domain we keep going
while [ -z "$found" ]; do
@@ -205,9 +206,7 @@ _get_base_domain() {
fi
_debug2 domain_list "$domain_list"
## for each shortening of our $fulldomain, check if it exists in the $domain_list
## can never start on 1 (aka whole $fulldomain) as $fulldomain starts with "_acme-challenge"
i=2
i=1
while [ $i -gt 0 ]; do
## get next longest domain
_domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM")

248
dnsapi/dns_dnsservices.sh Executable file
View File

@@ -0,0 +1,248 @@
#!/usr/bin/env sh
#This file name is "dns_dnsservices.sh"
#Script for Danish DNS registra and DNS hosting provider https://dns.services
#Author: Bjarke Bruun <bbruun@gmail.com>
#Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/4152
# Global variable to connect to the DNS.Services API
DNSServices_API=https://dns.services/api
######## Public functions #####################
#Usage: dns_dnsservices_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_dnsservices_add() {
fulldomain="$1"
txtvalue="$2"
_info "Using dns.services to create ACME DNS challenge"
_debug2 add_fulldomain "$fulldomain"
_debug2 add_txtvalue "$txtvalue"
# Read username/password from environment or .acme.sh/accounts.conf
DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}"
DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}"
if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then
DnsServices_Username=""
DnsServices_Password=""
_err "You didn't specify dns.services api username and password yet."
_err "Set environment variables DnsServices_Username and DnsServices_Password"
return 1
fi
# Setup GET/POST/DELETE headers
_setup_headers
#save the credentials to the account conf file.
_saveaccountconf_mutable DnsServices_Username "$DnsServices_Username"
_saveaccountconf_mutable DnsServices_Password "$DnsServices_Password"
if ! _contains "$DnsServices_Username" "@"; then
_err "It seems that the username variable DnsServices_Username has not been set/left blank"
_err "or is not a valid email. Please correct and try again."
return 1
fi
if ! _get_root "${fulldomain}"; then
_err "Invalid domain ${fulldomain}"
return 1
fi
if ! createRecord "$fulldomain" "${txtvalue}"; then
_err "Error creating TXT record in domain $fulldomain in $rootZoneName"
return 1
fi
_debug2 challenge-created "Created $fulldomain"
return 0
}
#Usage: fulldomain txtvalue
#Description: Remove the txt record after validation.
dns_dnsservices_rm() {
fulldomain="$1"
txtvalue="$2"
_info "Using dns.services to remove DNS record $fulldomain TXT $txtvalue"
_debug rm_fulldomain "$fulldomain"
_debug rm_txtvalue "$txtvalue"
# Read username/password from environment or .acme.sh/accounts.conf
DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}"
DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}"
if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then
DnsServices_Username=""
DnsServices_Password=""
_err "You didn't specify dns.services api username and password yet."
_err "Set environment variables DnsServices_Username and DnsServices_Password"
return 1
fi
# Setup GET/POST/DELETE headers
_setup_headers
if ! _get_root "${fulldomain}"; then
_err "Invalid domain ${fulldomain}"
return 1
fi
_debug2 rm_rootDomainInfo "found root domain $rootZoneName for $fulldomain"
if ! deleteRecord "${fulldomain}" "${txtvalue}"; then
_err "Error removing record: $fulldomain TXT ${txtvalue}"
return 1
fi
return 0
}
#################### Private functions below ##################################
_setup_headers() {
# Set up API Headers for _get() and _post()
# The <function>_add or <function>_rm must have been called before to work
if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then
_err "Could not setup BASIC authentication headers, they are missing"
return 1
fi
DnsServiceCredentials="$(printf "%s" "$DnsServices_Username:$DnsServices_Password" | _base64)"
export _H1="Authorization: Basic $DnsServiceCredentials"
export _H2="Content-Type: application/json"
# Just return if headers are set
return 0
}
_get_root() {
domain="$1"
_debug2 _get_root "Get the root domain of ${domain} for DNS API"
# Setup _get() and _post() headers
#_setup_headers
result=$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/dns")
result2="$(printf "%s\n" "$result" | tr '[' '\n' | grep '"name"')"
result3="$(printf "%s\n" "$result2" | tr '}' '\n' | grep '"name"' | sed "s,^\,,,g" | sed "s,$,},g")"
useResult=""
_debug2 _get_root "Got the following root domain(s) $result"
_debug2 _get_root "- JSON: $result"
if [ "$(printf "%s\n" "$result" | tr '}' '\n' | grep -c '"name"')" -gt "1" ]; then
checkMultiZones="true"
_debug2 _get_root "- multiple zones found"
else
checkMultiZones="false"
_debug2 _get_root "- single zone found"
fi
# Find/isolate the root zone to work with in createRecord() and deleteRecord()
rootZone=""
if [ "$checkMultiZones" = "true" ]; then
#rootZone=$(for x in $(printf "%s" "${result3}" | tr ',' '\n' | sed -n 's/.*"name":"\(.*\)",.*/\1/p'); do if [ "$(echo "$domain" | grep "$x")" != "" ]; then echo "$x"; fi; done)
rootZone=$(for x in $(printf "%s\n" "${result3}" | tr ',' '\n' | grep name | cut -d'"' -f4); do if [ "$(echo "$domain" | grep "$x")" != "" ]; then echo "$x"; fi; done)
if [ "$rootZone" != "" ]; then
_debug2 _rootZone "- root zone for $domain is $rootZone"
else
_err "Could not find root zone for $domain, is it correctly typed?"
return 1
fi
else
rootZone=$(echo "$result" | tr '}' '\n' | _egrep_o '"name":"[^"]*' | cut -d'"' -f4)
_debug2 _get_root "- only found 1 domain in API: $rootZone"
fi
if [ -z "$rootZone" ]; then
_err "Could not find root domain for $domain - is it correctly typed?"
return 1
fi
# Make sure we use the correct API zone data
useResult="$(printf "%s\n" "${result3}" tr ',' '\n' | grep "$rootZone")"
_debug2 _useResult "useResult=$useResult"
# Setup variables used by other functions to communicate with DNS.Services API
#zoneInfo=$(printf "%s\n" "$useResult" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g')
zoneInfo=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep '"name"' | cut -d'"' -f4)
rootZoneName="$rootZone"
subDomainName="$(printf "%s\n" "$domain" | sed "s,\.$rootZone,,g")"
subDomainNameClean="$(printf "%s\n" "$domain" | sed "s,_acme-challenge.,,g")"
rootZoneDomainID=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep domain_id | cut -d'"' -f4)
rootZoneServiceID=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep service_id | cut -d'"' -f4)
_debug2 _zoneInfo "Zone info from API : $zoneInfo"
_debug2 _get_root "Root zone name : $rootZoneName"
_debug2 _get_root "Root zone domain ID : $rootZoneDomainID"
_debug2 _get_root "Root zone service ID: $rootZoneServiceID"
_debug2 _get_root "Sub domain : $subDomainName"
_debug _get_root "Found valid root domain $rootZone for $subDomainNameClean"
return 0
}
createRecord() {
fulldomain="$1"
txtvalue="$2"
# Get root domain information - needed for DNS.Services API communication
if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
_get_root "$fulldomain"
fi
if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
_err "Something happend - could not get the API zone information"
return 1
fi
_debug2 createRecord "CNAME TXT value is: $txtvalue"
# Prepare data to send to API
data="{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"${txtvalue}\", \"ttl\":\"10\"}"
_debug2 createRecord "data to API: $data"
result=$(_post "$data" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records" "" "POST")
_debug2 createRecord "result from API: $result"
if [ "$(echo "$result" | _egrep_o "\"success\":true")" = "" ]; then
_err "Failed to create TXT record $fulldomain with content $txtvalue in zone $rootZoneName"
_err "$result"
return 1
fi
_info "Record \"$fulldomain TXT $txtvalue\" has been created"
return 0
}
deleteRecord() {
fulldomain="$1"
txtvalue="$2"
_log deleteRecord "Deleting $fulldomain TXT $txtvalue record"
if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
_get_root "$fulldomain"
fi
result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")"
#recordInfo="$(echo "$result" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}")"
#recordID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"id":")([^"]*)"(.*)$,\2,g')"
recordID="$(printf "%s\n" "$result" | tr '}' '\n' | grep -- "$txtvalue" | tr ',' '\n' | grep '"id"' | cut -d'"' -f4)"
_debug2 _recordID "recordID used for deletion of record: $recordID"
if [ -z "$recordID" ]; then
_info "Record $fulldomain TXT $txtvalue not found or already deleted"
return 0
else
_debug2 deleteRecord "Found recordID=$recordID"
fi
_debug2 deleteRecord "DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID"
_log "curl DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID"
result="$(_H1="$_H1" _H2="$_H2" _post "" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" "" "DELETE")"
_debug2 deleteRecord "API Delete result \"$result\""
_log "curl API Delete result \"$result\""
# Return OK regardless
return 0
}

View File

@@ -94,8 +94,8 @@ _get_domain() {
_your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')"
for l in $_your_hosts; do
#echo "host: $l"
if test "${_full_domain#*$l}" != "$_full_domain"; then
_record="${_full_domain%.$l}"
if test "${_full_domain#*"$l"}" != "$_full_domain"; then
_record=${_full_domain%."$l"}
_host=$l
_debug "The host is $_host and the record $_record"
return 0
@@ -143,7 +143,7 @@ _dns_dynv6_add_http() {
return 1
fi
_get_zone_name "$_zone_id"
record="${fulldomain%%.$_zone_name}"
record=${fulldomain%%."$_zone_name"}
_set_record TXT "$record" "$txtvalue"
if _contains "$response" "$txtvalue"; then
_info "Successfully added record"
@@ -161,7 +161,7 @@ _dns_dynv6_rm_http() {
return 1
fi
_get_zone_name "$_zone_id"
record="${fulldomain%%.$_zone_name}"
record=${fulldomain%%."$_zone_name"}
_get_record_id "$_zone_id" "$record" "$txtvalue"
_del_record "$_zone_id" "$_record_id"
if [ -z "$response" ]; then

View File

@@ -176,6 +176,7 @@ _EDGEDNS_credentials() {
_debug "GettingEdge DNS credentials"
_log "$(printf "ACME DNSAPI Edge DNS version %s" ${ACME_EDGEDNS_VERSION})"
args_missing=0
AKAMAI_ACCESS_TOKEN="${AKAMAI_ACCESS_TOKEN:-$(_readaccountconf_mutable AKAMAI_ACCESS_TOKEN)}"
if [ -z "$AKAMAI_ACCESS_TOKEN" ]; then
AKAMAI_ACCESS_TOKEN=""
AKAMAI_CLIENT_TOKEN=""
@@ -184,6 +185,7 @@ _EDGEDNS_credentials() {
_err "AKAMAI_ACCESS_TOKEN is missing"
args_missing=1
fi
AKAMAI_CLIENT_TOKEN="${AKAMAI_CLIENT_TOKEN:-$(_readaccountconf_mutable AKAMAI_CLIENT_TOKEN)}"
if [ -z "$AKAMAI_CLIENT_TOKEN" ]; then
AKAMAI_ACCESS_TOKEN=""
AKAMAI_CLIENT_TOKEN=""
@@ -192,6 +194,7 @@ _EDGEDNS_credentials() {
_err "AKAMAI_CLIENT_TOKEN is missing"
args_missing=1
fi
AKAMAI_HOST="${AKAMAI_HOST:-$(_readaccountconf_mutable AKAMAI_HOST)}"
if [ -z "$AKAMAI_HOST" ]; then
AKAMAI_ACCESS_TOKEN=""
AKAMAI_CLIENT_TOKEN=""
@@ -200,6 +203,7 @@ _EDGEDNS_credentials() {
_err "AKAMAI_HOST is missing"
args_missing=1
fi
AKAMAI_CLIENT_SECRET="${AKAMAI_CLIENT_SECRET:-$(_readaccountconf_mutable AKAMAI_CLIENT_SECRET)}"
if [ -z "$AKAMAI_CLIENT_SECRET" ]; then
AKAMAI_ACCESS_TOKEN=""
AKAMAI_CLIENT_TOKEN=""
@@ -414,7 +418,7 @@ _edgedns_make_data_to_sign() {
_secure_debug2 "hdr" "$hdr"
_edgedns_make_content_hash
path="$(echo "$_request_url_path" | tr -d "\n\r" | sed 's/https\?:\/\///')"
path="${path#*$AKAMAI_HOST}"
path=${path#*"$AKAMAI_HOST"}
_debug "hier path" "$path"
# dont expose headers to sign so use MT string
_mdata="$(printf "%s\thttps\t%s\t%s\t%s\t%s\t%s" "$_request_method" "$AKAMAI_HOST" "$path" "" "$_hash" "$hdr")"

146
dnsapi/dns_fornex.sh Normal file
View File

@@ -0,0 +1,146 @@
#!/usr/bin/env sh
#Author: Timur Umarov <inbox@tumarov.com>
FORNEX_API_URL="https://fornex.com/api/dns/v0.1"
######## Public functions #####################
#Usage: dns_fornex_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_fornex_add() {
fulldomain=$1
txtvalue=$2
if ! _Fornex_API; then
return 1
fi
if ! _get_root "$fulldomain"; then
_err "Unable to determine root domain"
return 1
else
_debug _domain "$_domain"
fi
_info "Adding record"
if _rest POST "$_domain/entry_set/add/" "host=$fulldomain&type=TXT&value=$txtvalue&apikey=$FORNEX_API_KEY"; then
_debug _response "$response"
if _contains "$response" '"ok": true' || _contains "$response" 'Такая запись уже существует.'; then
_info "Added, OK"
return 0
fi
fi
_err "Add txt record error."
return 1
}
#Usage: dns_fornex_rm _acme-challenge.www.domain.com
dns_fornex_rm() {
fulldomain=$1
txtvalue=$2
if ! _Fornex_API; then
return 1
fi
if ! _get_root "$fulldomain"; then
_err "Unable to determine root domain"
return 1
else
_debug _domain "$_domain"
fi
_debug "Getting txt records"
_rest GET "$_domain/entry_set.json?apikey=$FORNEX_API_KEY"
if ! _contains "$response" "$txtvalue"; then
_err "Txt record not found"
return 1
fi
_record_id="$(echo "$response" | _egrep_o "{[^{]*\"value\"*:*\"$txtvalue\"[^}]*}" | sed -n -e 's#.*"id": \([0-9]*\).*#\1#p')"
_debug "_record_id" "$_record_id"
if [ -z "$_record_id" ]; then
_err "can not find _record_id"
return 1
fi
if ! _rest POST "$_domain/entry_set/$_record_id/delete/" "apikey=$FORNEX_API_KEY"; 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
_get_root() {
domain=$1
i=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 ! _rest GET "domain_list.json?q=$h&apikey=$FORNEX_API_KEY"; then
return 1
fi
if _contains "$response" "\"$h\"" >/dev/null; then
_domain=$h
return 0
else
_debug "$h not found"
fi
i=$(_math "$i" + 1)
done
return 1
}
_Fornex_API() {
FORNEX_API_KEY="${FORNEX_API_KEY:-$(_readaccountconf_mutable FORNEX_API_KEY)}"
if [ -z "$FORNEX_API_KEY" ]; then
FORNEX_API_KEY=""
_err "You didn't specify the Fornex API key yet."
_err "Please create your key and try again."
return 1
fi
_saveaccountconf_mutable FORNEX_API_KEY "$FORNEX_API_KEY"
}
#method method action data
_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
export _H1="Accept: application/json"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$FORNEX_API_URL/$ep" "" "$m")"
else
response="$(_get "$FORNEX_API_URL/$ep" | _normalizeJson)"
fi
_ret="$?"
if [ "$_ret" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env sh
# Gandi LiveDNS v5 API
# http://doc.livedns.gandi.net/
# https://doc.livedns.gandi.net/
# currently under beta
#
# Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable

View File

@@ -39,7 +39,7 @@ dns_gcloud_rm() {
_dns_gcloud_start_tr || return $?
_dns_gcloud_get_rrdatas || return $?
echo "$rrdatas" | _dns_gcloud_remove_rrs || return $?
echo "$rrdatas" | grep -F -v "\"$txtvalue\"" | _dns_gcloud_add_rrs || return $?
echo "$rrdatas" | grep -F -v -- "\"$txtvalue\"" | _dns_gcloud_add_rrs || return $?
_dns_gcloud_execute_tr || return $?
_info "$fulldomain record added"
@@ -98,7 +98,7 @@ _dns_gcloud_remove_rrs() {
--ttl="$ttl" \
--type=TXT \
--zone="$managedZone" \
--transaction-file="$tr"; then
--transaction-file="$tr" --; then
_debug tr "$(cat "$tr")"
rm -r "$trd"
_err "_dns_gcloud_remove_rrs: failed to remove RRs"
@@ -113,7 +113,7 @@ _dns_gcloud_add_rrs() {
--ttl="$ttl" \
--type=TXT \
--zone="$managedZone" \
--transaction-file="$tr"; then
--transaction-file="$tr" --; then
_debug tr "$(cat "$tr")"
rm -r "$trd"
_err "_dns_gcloud_add_rrs: failed to add RRs"

187
dnsapi/dns_gcore.sh Executable file
View File

@@ -0,0 +1,187 @@
#!/usr/bin/env sh
#
#GCORE_Key='773$7b7adaf2a2b32bfb1b83787b4ff32a67eb178e3ada1af733e47b1411f2461f7f4fa7ed7138e2772a46124377bad7384b3bb8d87748f87b3f23db4b8bbe41b2bb'
#
GCORE_Api="https://api.gcorelabs.com/dns/v2"
GCORE_Doc="https://apidocs.gcore.com/dns"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_gcore_add() {
fulldomain=$1
txtvalue=$2
GCORE_Key="${GCORE_Key:-$(_readaccountconf_mutable GCORE_Key)}"
if [ -z "$GCORE_Key" ]; then
GCORE_Key=""
_err "You didn't specify a Gcore api key yet."
_err "You can get yours from here $GCORE_Doc"
return 1
fi
#save the api key to the account conf file.
_saveaccountconf_mutable GCORE_Key "$GCORE_Key"
_debug "First detect the zone name"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _zone_name "$_zone_name"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_gcore_rest GET "zones/$_zone_name/$fulldomain/TXT"
payload=""
if echo "$response" | grep "record is not found" >/dev/null; then
_info "Record doesn't exists"
payload="{\"resource_records\":[{\"content\":[\"$txtvalue\"],\"enabled\":true}],\"ttl\":120}"
elif echo "$response" | grep "$txtvalue" >/dev/null; then
_info "Already exists, OK"
return 0
elif echo "$response" | tr -d " " | grep \"name\":\""$fulldomain"\",\"type\":\"TXT\" >/dev/null; then
_info "Record with mismatch txtvalue, try update it"
payload=$(echo "$response" | tr -d " " | sed 's/"updated_at":[0-9]\+,//g' | sed 's/"meta":{}}]}/"meta":{}},{"content":['\""$txtvalue"\"'],"enabled":true}]}/')
fi
# 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 _gcore_rest PUT "zones/$_zone_name/$fulldomain/TXT" "$payload"; then
if _contains "$response" "$txtvalue"; then
_info "Added, OK"
return 0
elif _contains "$response" "rrset is already exists"; then
_info "Already exists, OK"
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
return 1
}
#fulldomain txtvalue
dns_gcore_rm() {
fulldomain=$1
txtvalue=$2
GCORE_Key="${GCORE_Key:-$(_readaccountconf_mutable GCORE_Key)}"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _zone_name "$_zone_name"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_gcore_rest GET "zones/$_zone_name/$fulldomain/TXT"
if echo "$response" | grep "record is not found" >/dev/null; then
_info "No such txt recrod"
return 0
fi
if ! echo "$response" | tr -d " " | grep \"name\":\""$fulldomain"\",\"type\":\"TXT\" >/dev/null; then
_err "Error: $response"
return 1
fi
if ! echo "$response" | tr -d " " | grep \""$txtvalue"\" >/dev/null; then
_info "No such txt recrod"
return 0
fi
count="$(echo "$response" | grep -o "content" | wc -l)"
if [ "$count" = "1" ]; then
if ! _gcore_rest DELETE "zones/$_zone_name/$fulldomain/TXT"; then
_err "Delete record error. $response"
return 1
fi
return 0
fi
payload="$(echo "$response" | tr -d " " | sed 's/"updated_at":[0-9]\+,//g' | sed 's/{"id":[0-9]\+,"content":\["'"$txtvalue"'"\],"enabled":true,"meta":{}}//' | sed 's/\[,/\[/' | sed 's/,,/,/' | sed 's/,\]/\]/')"
if ! _gcore_rest PUT "zones/$_zone_name/$fulldomain/TXT" "$payload"; then
_err "Delete record error. $response"
fi
}
#################### Private functions below ##################################
#_acme-challenge.sub.domain.com
#returns
# _sub_domain=_acme-challenge.sub or _acme-challenge
# _domain=domain.com
# _zone_name=domain.com or sub.domain.com
_get_root() {
domain=$1
i=1
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
if ! _gcore_rest GET "zones/$h"; then
return 1
fi
if _contains "$response" "\"name\":\"$h\""; then
_zone_name=$h
if [ "$_zone_name" ]; 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
}
_gcore_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
key_trimmed=$(echo "$GCORE_Key" | tr -d '"')
export _H1="Content-Type: application/json"
export _H2="Authorization: APIKey $key_trimmed"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$GCORE_Api/$ep" "" "$m")"
else
response="$(_get "$GCORE_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

View File

@@ -1,10 +1,12 @@
#!/usr/bin/env sh
#Godaddy domain api
# Get API key and secret from https://developer.godaddy.com/
#
#GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
# GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
# GD_Secret="asdfsdfsfsdfsdfdfsdf"
#
#GD_Secret="asdfsdfsfsdfsdfdfsdf"
# Ex.: acme.sh --issue --staging --dns dns_gd -d "*.s.example.com" -d "s.example.com"
GD_Api="https://api.godaddy.com/v1"
@@ -20,8 +22,8 @@ dns_gd_add() {
if [ -z "$GD_Key" ] || [ -z "$GD_Secret" ]; then
GD_Key=""
GD_Secret=""
_err "You don't specify godaddy api key and secret yet."
_err "Please create you key and try again."
_err "You didn't specify godaddy api key and secret yet."
_err "Please create your key and try again."
return 1
fi
@@ -44,14 +46,15 @@ dns_gd_add() {
fi
if _contains "$response" "$txtvalue"; then
_info "The record is existing, skip"
_info "This record already exists, skipping"
return 0
fi
_add_data="{\"data\":\"$txtvalue\"}"
for t in $(echo "$response" | tr '{' "\n" | grep "\"name\":\"$_sub_domain\"" | tr ',' "\n" | grep '"data"' | cut -d : -f 2); do
_debug2 t "$t"
if [ "$t" ]; then
# ignore empty (previously removed) records, to prevent useless _acme-challenge TXT entries
if [ "$t" ] && [ "$t" != '""' ]; then
_add_data="$_add_data,{\"data\":$t}"
fi
done
@@ -59,13 +62,25 @@ dns_gd_add() {
_info "Adding record"
if _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"; then
_info "Added, sleeping 10 seconds"
_sleep 10
#todo: check if the record takes effect
return 0
_debug "Checking updated records of '${fulldomain}'"
if ! _gd_rest GET "domains/$_domain/records/TXT/$_sub_domain"; then
_err "Validating TXT record for '${fulldomain}' with rest error [$?]." "$response"
return 1
fi
if ! _contains "$response" "$txtvalue"; then
_err "TXT record '${txtvalue}' for '${fulldomain}', value wasn't set!"
return 1
fi
else
_err "Add txt record error, value '${txtvalue}' for '${fulldomain}' was not set."
return 1
fi
_err "Add txt record error."
return 1
_sleep 10
_info "Added TXT record '${txtvalue}' for '${fulldomain}'."
return 0
}
#fulldomain
@@ -107,11 +122,20 @@ dns_gd_rm() {
fi
done
if [ -z "$_add_data" ]; then
_add_data="{\"data\":\"\"}"
# delete empty record
_debug "Delete last record for '${fulldomain}'"
if ! _gd_rest DELETE "domains/$_domain/records/TXT/$_sub_domain"; then
_err "Cannot delete empty TXT record for '$fulldomain'"
return 1
fi
else
# remove specific TXT value, keeping other entries
_debug2 _add_data "$_add_data"
if ! _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"; then
_err "Cannot update TXT record for '$fulldomain'"
return 1
fi
fi
_debug2 _add_data "$_add_data"
_gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"
}
#################### Private functions below ##################################
@@ -156,15 +180,15 @@ _gd_rest() {
export _H1="Authorization: sso-key $GD_Key:$GD_Secret"
export _H2="Content-Type: application/json"
if [ "$data" ]; then
_debug data "$data"
if [ "$data" ] || [ "$m" = "DELETE" ]; then
_debug "data ($m): " "$data"
response="$(_post "$data" "$GD_Api/$ep" "" "$m")"
else
response="$(_get "$GD_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
_err "error on rest call ($m): $ep"
return 1
fi
_debug2 response "$response"

View File

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

232
dnsapi/dns_geoscaling.sh Executable file
View File

@@ -0,0 +1,232 @@
#!/usr/bin/env sh
########################################################################
# Geoscaling hook script for acme.sh
#
# Environment variables:
#
# - $GEOSCALING_Username (your Geoscaling username - this is usually NOT an amail address)
# - $GEOSCALING_Password (your Geoscaling password)
#-- dns_geoscaling_add() - Add TXT record --------------------------------------
# Usage: dns_geoscaling_add _acme-challenge.subdomain.domain.com "XyZ123..."
dns_geoscaling_add() {
full_domain=$1
txt_value=$2
_info "Using DNS-01 Geoscaling DNS2 hook"
GEOSCALING_Username="${GEOSCALING_Username:-$(_readaccountconf_mutable GEOSCALING_Username)}"
GEOSCALING_Password="${GEOSCALING_Password:-$(_readaccountconf_mutable GEOSCALING_Password)}"
if [ -z "$GEOSCALING_Username" ] || [ -z "$GEOSCALING_Password" ]; then
GEOSCALING_Username=
GEOSCALING_Password=
_err "No auth details provided. Please set user credentials using the \$GEOSCALING_Username and \$GEOSCALING_Password environment variables."
return 1
fi
_saveaccountconf_mutable GEOSCALING_Username "${GEOSCALING_Username}"
_saveaccountconf_mutable GEOSCALING_Password "${GEOSCALING_Password}"
# Fills in the $zone_id and $zone_name
find_zone "${full_domain}" || return 1
_debug "Zone id '${zone_id}' will be used."
# We're logged in here
# we should add ${full_domain} minus the trailing ${zone_name}
prefix=$(echo "${full_domain}" | sed "s|\\.${zone_name}\$||")
body="id=${zone_id}&name=${prefix}&type=TXT&content=${txt_value}&ttl=300&prio=0"
do_post "$body" "https://www.geoscaling.com/dns2/ajax/add_record.php"
exit_code="$?"
if [ "${exit_code}" -eq 0 ]; then
_info "TXT record added successfully."
else
_err "Couldn't add the TXT record."
fi
do_logout
return "${exit_code}"
}
#-- dns_geoscaling_rm() - Remove TXT record ------------------------------------
# Usage: dns_geoscaling_rm _acme-challenge.subdomain.domain.com "XyZ123..."
dns_geoscaling_rm() {
full_domain=$1
txt_value=$2
_info "Cleaning up after DNS-01 Geoscaling DNS2 hook"
GEOSCALING_Username="${GEOSCALING_Username:-$(_readaccountconf_mutable GEOSCALING_Username)}"
GEOSCALING_Password="${GEOSCALING_Password:-$(_readaccountconf_mutable GEOSCALING_Password)}"
if [ -z "$GEOSCALING_Username" ] || [ -z "$GEOSCALING_Password" ]; then
GEOSCALING_Username=
GEOSCALING_Password=
_err "No auth details provided. Please set user credentials using the \$GEOSCALING_Username and \$GEOSCALING_Password environment variables."
return 1
fi
_saveaccountconf_mutable GEOSCALING_Username "${GEOSCALING_Username}"
_saveaccountconf_mutable GEOSCALING_Password "${GEOSCALING_Password}"
# fills in the $zone_id
find_zone "${full_domain}" || return 1
_debug "Zone id '${zone_id}' will be used."
# Here we're logged in
# Find the record id to clean
# get the domain
response=$(do_get "https://www.geoscaling.com/dns2/index.php?module=domain&id=${zone_id}")
_debug2 "response" "$response"
table="$(echo "${response}" | tr -d '\n' | sed 's|.*<div class="box"><div class="boxtitle">Basic Records</div><div class="boxtext"><table|<table|; s|</table>.*|</table>|')"
_debug2 table "${table}"
names=$(echo "${table}" | _egrep_o 'id="[0-9]+\.name">[^<]*</td>' | sed 's|</td>||; s|.*>||')
ids=$(echo "${table}" | _egrep_o 'id="[0-9]+\.name">[^<]*</td>' | sed 's|\.name">.*||; s|id="||')
types=$(echo "${table}" | _egrep_o 'id="[0-9]+\.type">[^<]*</td>' | sed 's|</td>||; s|.*>||')
values=$(echo "${table}" | _egrep_o 'id="[0-9]+\.content">[^<]*</td>' | sed 's|</td>||; s|.*>||')
_debug2 names "${names}"
_debug2 ids "${ids}"
_debug2 types "${types}"
_debug2 values "${values}"
# look for line whose name is ${full_domain}, whose type is TXT, and whose value is ${txt_value}
line_num="$(echo "${values}" | grep -F -n -- "${txt_value}" | _head_n 1 | cut -d ':' -f 1)"
_debug2 line_num "${line_num}"
found_id=
if [ -n "$line_num" ]; then
type=$(echo "${types}" | sed -n "${line_num}p")
name=$(echo "${names}" | sed -n "${line_num}p")
id=$(echo "${ids}" | sed -n "${line_num}p")
_debug2 type "$type"
_debug2 name "$name"
_debug2 id "$id"
_debug2 full_domain "$full_domain"
if [ "${type}" = "TXT" ] && [ "${name}" = "${full_domain}" ]; then
found_id=${id}
fi
fi
if [ "${found_id}" = "" ]; then
_err "Can not find record id."
return 0
fi
# Remove the record
body="id=${zone_id}&record_id=${found_id}"
response=$(do_post "$body" "https://www.geoscaling.com/dns2/ajax/delete_record.php")
exit_code="$?"
if [ "$exit_code" -eq 0 ]; then
_info "Record removed successfully."
else
_err "Could not clean (remove) up the record. Please go to Geoscaling administration interface and clean it by hand."
fi
do_logout
return "${exit_code}"
}
########################## PRIVATE FUNCTIONS ###########################
do_get() {
_url=$1
export _H1="Cookie: $geoscaling_phpsessid_cookie"
_get "${_url}"
}
do_post() {
_body=$1
_url=$2
export _H1="Cookie: $geoscaling_phpsessid_cookie"
_post "${_body}" "${_url}"
}
do_login() {
_info "Logging in..."
username_encoded="$(printf "%s" "${GEOSCALING_Username}" | _url_encode)"
password_encoded="$(printf "%s" "${GEOSCALING_Password}" | _url_encode)"
body="username=${username_encoded}&password=${password_encoded}"
response=$(_post "$body" "https://www.geoscaling.com/dns2/index.php?module=auth")
_debug2 response "${response}"
#retcode=$(grep '^HTTP[^ ]*' "${HTTP_HEADER}" | _head_n 1 | _egrep_o '[0-9]+$')
retcode=$(grep '^HTTP[^ ]*' "${HTTP_HEADER}" | _head_n 1 | cut -d ' ' -f 2)
if [ "$retcode" != "302" ]; then
_err "Geoscaling login failed for user ${GEOSCALING_Username}. Check ${HTTP_HEADER} file"
return 1
fi
geoscaling_phpsessid_cookie="$(grep -i '^set-cookie:' "${HTTP_HEADER}" | _egrep_o 'PHPSESSID=[^;]*;' | tr -d ';')"
return 0
}
do_logout() {
_info "Logging out."
response="$(do_get "https://www.geoscaling.com/dns2/index.php?module=auth")"
_debug2 response "$response"
return 0
}
find_zone() {
domain="$1"
# do login
do_login || return 1
# get zones
response="$(do_get "https://www.geoscaling.com/dns2/index.php?module=domains")"
table="$(echo "${response}" | tr -d '\n' | sed 's|.*<div class="box"><div class="boxtitle">Your domains</div><div class="boxtext"><table|<table|; s|</table>.*|</table>|')"
_debug2 table "${table}"
zone_names="$(echo "${table}" | _egrep_o '<b>[^<]*</b>' | sed 's|<b>||;s|</b>||')"
_debug2 _matches "${zone_names}"
# Zone names and zone IDs are in same order
zone_ids=$(echo "${table}" | _egrep_o '<a href=.index\.php\?module=domain&id=[0-9]+. onclick="javascript:show_loader\(\);">' | sed 's|.*id=||;s|. .*||')
_debug2 "These are the zones on this Geoscaling account:"
_debug2 "zone_names" "${zone_names}"
_debug2 "And these are their respective IDs:"
_debug2 "zone_ids" "${zone_ids}"
if [ -z "${zone_names}" ] || [ -z "${zone_ids}" ]; then
_err "Can not get zone names or IDs."
return 1
fi
# Walk through all possible zone names
strip_counter=1
while true; do
attempted_zone=$(echo "${domain}" | cut -d . -f ${strip_counter}-)
# All possible zone names have been tried
if [ -z "${attempted_zone}" ]; then
_err "No zone for domain '${domain}' found."
return 1
fi
_debug "Looking for zone '${attempted_zone}'"
line_num="$(echo "${zone_names}" | grep -n "^${attempted_zone}\$" | _head_n 1 | cut -d : -f 1)"
_debug2 line_num "${line_num}"
if [ "$line_num" ]; then
zone_id=$(echo "${zone_ids}" | sed -n "${line_num}p")
zone_name=$(echo "${zone_names}" | sed -n "${line_num}p")
if [ -z "${zone_id}" ]; then
_err "Can not find zone id."
return 1
fi
_debug "Found relevant zone '${attempted_zone}' with id '${zone_id}' - will be used for domain '${domain}'."
return 0
fi
_debug "Zone '${attempted_zone}' doesn't exist, let's try a less specific zone."
strip_counter=$(_math "${strip_counter}" + 1)
done
}
# vim: et:ts=2:sw=2:

173
dnsapi/dns_googledomains.sh Executable file
View File

@@ -0,0 +1,173 @@
#!/usr/bin/env sh
# Author: Alex Leigh <leigh at alexleigh dot me>
# Created: 2023-03-02
#GOOGLEDOMAINS_ACCESS_TOKEN="xxxx"
#GOOGLEDOMAINS_ZONE="xxxx"
GOOGLEDOMAINS_API="https://acmedns.googleapis.com/v1/acmeChallengeSets"
######## Public functions ########
#Usage: dns_googledomains_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_googledomains_add() {
fulldomain=$1
txtvalue=$2
_info "Invoking Google Domains ACME DNS API."
if ! _dns_googledomains_setup; then
return 1
fi
zone="$(_dns_googledomains_get_zone "$fulldomain")"
if [ -z "$zone" ]; then
_err "Could not find a Google Domains-managed zone containing the requested domain."
return 1
fi
_debug zone "$zone"
_debug txtvalue "$txtvalue"
_info "Adding TXT record for $fulldomain."
if _dns_googledomains_api "$zone" ":rotateChallenges" "{\"accessToken\":\"$GOOGLEDOMAINS_ACCESS_TOKEN\",\"recordsToAdd\":[{\"fqdn\":\"$fulldomain\",\"digest\":\"$txtvalue\"}],\"keepExpiredRecords\":true}"; then
if _contains "$response" "$txtvalue"; then
_info "TXT record added."
return 0
else
_err "Error adding TXT record."
return 1
fi
fi
_err "Error adding TXT record."
return 1
}
#Usage: dns_googledomains_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_googledomains_rm() {
fulldomain=$1
txtvalue=$2
_info "Invoking Google Domains ACME DNS API."
if ! _dns_googledomains_setup; then
return 1
fi
zone="$(_dns_googledomains_get_zone "$fulldomain")"
if [ -z "$zone" ]; then
_err "Could not find a Google Domains-managed domain based on request."
return 1
fi
_debug zone "$zone"
_debug txtvalue "$txtvalue"
_info "Removing TXT record for $fulldomain."
if _dns_googledomains_api "$zone" ":rotateChallenges" "{\"accessToken\":\"$GOOGLEDOMAINS_ACCESS_TOKEN\",\"recordsToRemove\":[{\"fqdn\":\"$fulldomain\",\"digest\":\"$txtvalue\"}],\"keepExpiredRecords\":true}"; then
if _contains "$response" "$txtvalue"; then
_err "Error removing TXT record."
return 1
else
_info "TXT record removed."
return 0
fi
fi
_err "Error removing TXT record."
return 1
}
######## Private functions ########
_dns_googledomains_setup() {
if [ -n "$GOOGLEDOMAINS_SETUP_COMPLETED" ]; then
return 0
fi
GOOGLEDOMAINS_ACCESS_TOKEN="${GOOGLEDOMAINS_ACCESS_TOKEN:-$(_readaccountconf_mutable GOOGLEDOMAINS_ACCESS_TOKEN)}"
GOOGLEDOMAINS_ZONE="${GOOGLEDOMAINS_ZONE:-$(_readaccountconf_mutable GOOGLEDOMAINS_ZONE)}"
if [ -z "$GOOGLEDOMAINS_ACCESS_TOKEN" ]; then
GOOGLEDOMAINS_ACCESS_TOKEN=""
_err "Google Domains access token was not specified."
_err "Please visit Google Domains Security settings to provision an ACME DNS API access token."
return 1
fi
if [ "$GOOGLEDOMAINS_ZONE" ]; then
_savedomainconf GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN"
_savedomainconf GOOGLEDOMAINS_ZONE "$GOOGLEDOMAINS_ZONE"
else
_saveaccountconf_mutable GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN"
_clearaccountconf_mutable GOOGLEDOMAINS_ZONE
_clearaccountconf GOOGLEDOMAINS_ZONE
fi
_debug GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN"
_debug GOOGLEDOMAINS_ZONE "$GOOGLEDOMAINS_ZONE"
GOOGLEDOMAINS_SETUP_COMPLETED=1
return 0
}
_dns_googledomains_get_zone() {
domain=$1
# Use zone directly if provided
if [ "$GOOGLEDOMAINS_ZONE" ]; then
if ! _dns_googledomains_api "$GOOGLEDOMAINS_ZONE"; then
return 1
fi
echo "$GOOGLEDOMAINS_ZONE"
return 0
fi
i=2
while true; do
curr=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug curr "$curr"
if [ -z "$curr" ]; then
return 1
fi
if _dns_googledomains_api "$curr"; then
echo "$curr"
return 0
fi
i=$(_math "$i" + 1)
done
return 1
}
_dns_googledomains_api() {
zone=$1
apimethod=$2
data="$3"
if [ -z "$data" ]; then
response="$(_get "$GOOGLEDOMAINS_API/$zone$apimethod")"
else
_debug data "$data"
export _H1="Content-Type: application/json"
response="$(_post "$data" "$GOOGLEDOMAINS_API/$zone$apimethod")"
fi
_debug response "$response"
if [ "$?" != "0" ]; then
_err "Error"
return 1
fi
if _contains "$response" "\"error\": {"; then
return 1
fi
return 0
}

View File

@@ -2,7 +2,7 @@
# HUAWEICLOUD_Username
# HUAWEICLOUD_Password
# HUAWEICLOUD_ProjectID
# HUAWEICLOUD_DomainName
iam_api="https://iam.myhuaweicloud.com"
dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work
@@ -14,6 +14,8 @@ dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work
#
# Ref: https://support.huaweicloud.com/intl/zh-cn/api-dns/zh-cn_topic_0132421999.html
#
# About "DomainName" parameters see: https://support.huaweicloud.com/api-iam/iam_01_0006.html
#
dns_huaweicloud_add() {
fulldomain=$1
@@ -21,16 +23,16 @@ dns_huaweicloud_add() {
HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}"
HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_DomainName)}"
# Check information
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_ProjectID}" ]; then
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
_err "Not enough information provided to dns_huaweicloud!"
return 1
fi
unset token # Clear token
token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")"
token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_DomainName}")"
if [ -z "${token}" ]; then # Check token
_err "dns_api(dns_huaweicloud): Error getting token."
return 1
@@ -56,7 +58,7 @@ dns_huaweicloud_add() {
# Do saving work if all succeeded
_saveaccountconf_mutable HUAWEICLOUD_Username "${HUAWEICLOUD_Username}"
_saveaccountconf_mutable HUAWEICLOUD_Password "${HUAWEICLOUD_Password}"
_saveaccountconf_mutable HUAWEICLOUD_ProjectID "${HUAWEICLOUD_ProjectID}"
_saveaccountconf_mutable HUAWEICLOUD_DomainName "${HUAWEICLOUD_DomainName}"
return 0
}
@@ -72,16 +74,16 @@ dns_huaweicloud_rm() {
HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}"
HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_DomainName)}"
# Check information
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_ProjectID}" ]; then
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
_err "Not enough information provided to dns_huaweicloud!"
return 1
fi
unset token # Clear token
token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")"
token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_DomainName}")"
if [ -z "${token}" ]; then # Check token
_err "dns_api(dns_huaweicloud): Error getting token."
return 1
@@ -96,19 +98,59 @@ dns_huaweicloud_rm() {
fi
_debug "Zone ID is:" "${zoneid}"
# Remove all records
# Therotically HuaweiCloud does not allow more than one record set
# But remove them recurringly to increase robusty
while [ "${record_id}" != "0" ]; do
_debug "Removing Record"
_rm_record "${token}" "${zoneid}" "${record_id}"
record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")"
done
record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")"
_recursive_rm_record "${token}" "${fulldomain}" "${zoneid}" "${record_id}"
ret="$?"
if [ "${ret}" != "0" ]; then
_err "dns_api(dns_huaweicloud): Error removing record."
return 1
fi
return 0
}
################### Private functions below ##################################
# _recursive_rm_record
# remove all records from the record set
#
# _token=$1
# _domain=$2
# _zoneid=$3
# _record_id=$4
#
# Returns 0 on success
_recursive_rm_record() {
_token=$1
_domain=$2
_zoneid=$3
_record_id=$4
# Most likely to have problems will huaweicloud side if more than 50 attempts but still cannot fully remove the record set
# Maybe can be removed manually in the dashboard
_retry_cnt=50
# Remove all records
# Therotically HuaweiCloud does not allow more than one record set
# But remove them recurringly to increase robusty
while [ "${_record_id}" != "0" ] && [ "${_retry_cnt}" != "0" ]; do
_debug "Removing Record"
_retry_cnt=$((_retry_cnt - 1))
_rm_record "${_token}" "${_zoneid}" "${_record_id}"
_record_id="$(_get_recordset_id "${_token}" "${_domain}" "${_zoneid}")"
_debug2 "Checking record exists: record_id=${_record_id}"
done
# Check if retry count is reached
if [ "${_retry_cnt}" = "0" ]; then
_debug "Failed to remove record after 50 attempts, please try removing it manually in the dashboard"
return 1
fi
return 0
}
# _get_zoneid
#
# _token=$1
@@ -122,7 +164,7 @@ _get_zoneid() {
i=1
while true; do
h=$(printf "%s" "${_domain_string}" | cut -d . -f $i-100)
h=$(printf "%s" "${_domain_string}" | cut -d . -f "$i"-100)
if [ -z "$h" ]; then
#not valid
return 1
@@ -133,11 +175,11 @@ _get_zoneid() {
if _contains "${response}" '"id"'; then
zoneidlist=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
zonenamelist=$(echo "${response}" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
_debug2 "Return Zone ID(s):" "${zoneidlist}"
_debug2 "Return Zone Name(s):" "${zonenamelist}"
_debug2 "Returned Zone ID(s):" "${zoneidlist}"
_debug2 "Returned Zone Name(s):" "${zonenamelist}"
zoneidnum=0
zoneidcount=$(echo "${zoneidlist}" | grep -c '^')
_debug "Retund Zone ID(s) Count:" "${zoneidcount}"
_debug "Returned Zone ID(s) Count:" "${zoneidcount}"
while [ "${zoneidnum}" -lt "${zoneidcount}" ]; do
zoneidnum=$(_math "$zoneidnum" + 1)
_zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p")
@@ -204,8 +246,7 @@ _add_record() {
\"type\": \"TXT\",
\"ttl\": 1,
\"records\": [
${_exist_record},
\"\\\"${_txtvalue}\\\"\"
${_exist_record},\"\\\"${_txtvalue}\\\"\"
]
}"
fi
@@ -213,19 +254,16 @@ _add_record() {
_record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")"
_debug "Record Set ID is:" "${_record_id}"
# Remove all records
while [ "${_record_id}" != "0" ]; do
_debug "Removing Record"
_rm_record "${_token}" "${zoneid}" "${_record_id}"
_record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")"
done
# Add brand new records with all old and new records
export _H2="Content-Type: application/json"
export _H1="X-Auth-Token: ${_token}"
_debug2 "${_post_body}"
_post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null
if [ -z "${_exist_record}" ]; then
_post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null
else
_post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets/${_record_id}" false "PUT" >/dev/null
fi
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
if [ "$_code" != "202" ]; then
_err "dns_huaweicloud: http code ${_code}"
@@ -253,7 +291,7 @@ _rm_record() {
_get_token() {
_username=$1
_password=$2
_project=$3
_domain_name=$3
_debug "Getting Token"
body="{
@@ -267,14 +305,14 @@ _get_token() {
\"name\": \"${_username}\",
\"password\": \"${_password}\",
\"domain\": {
\"name\": \"${_username}\"
\"name\": \"${_domain_name}\"
}
}
}
},
\"scope\": {
\"project\": {
\"id\": \"${_project}\"
\"name\": \"ap-southeast-1\"
}
}
}

View File

@@ -76,7 +76,7 @@ dns_infomaniak_add() {
domain_id=${zone_and_id#* }
# extract first part of domain
key=${fulldomain%.$zone}
key=${fulldomain%."$zone"}
_debug "zone:$zone id:$domain_id key:$key"
@@ -149,7 +149,7 @@ dns_infomaniak_rm() {
domain_id=${zone_and_id#* }
# extract first part of domain
key=${fulldomain%.$zone}
key=${fulldomain%."$zone"}
_debug "zone:$zone id:$domain_id key:$key"

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env sh
# Supports IONOS DNS API Beta v1.0.0
# Supports IONOS DNS API v1.0.1
#
# Usage:
# Export IONOS_PREFIX and IONOS_SECRET before calling acme.sh:
@@ -26,7 +26,7 @@ dns_ionos_add() {
_body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]"
if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ -z "$response" ]; then
if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "201" ]; then
_info "TXT record has been created successfully."
return 0
fi
@@ -47,7 +47,7 @@ dns_ionos_rm() {
return 1
fi
if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ -z "$response" ]; then
if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "200" ]; then
_info "TXT record has been deleted successfully."
return 0
fi
@@ -85,7 +85,7 @@ _get_root() {
p=1
if _ionos_rest GET "$IONOS_ROUTE_ZONES"; then
response="$(echo "$response" | tr -d "\n")"
_response="$(echo "$_response" | tr -d "\n")"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
@@ -93,7 +93,7 @@ _get_root() {
return 1
fi
_zone="$(echo "$response" | _egrep_o "\"name\":\"$h\".*\}")"
_zone="$(echo "$_response" | _egrep_o "\"name\":\"$h\".*\}")"
if [ "$_zone" ]; then
_zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"')
if [ "$_zone_id" ]; then
@@ -120,9 +120,9 @@ _ionos_get_record() {
txtrecord=$3
if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then
response="$(echo "$response" | tr -d "\n")"
_response="$(echo "$_response" | tr -d "\n")"
_record="$(echo "$response" | _egrep_o "\"name\":\"$fulldomain\"[^\}]*\"type\":\"TXT\"[^\}]*\"content\":\"\\\\\"$txtrecord\\\\\"\".*\}")"
_record="$(echo "$_response" | _egrep_o "\"name\":\"$fulldomain\"[^\}]*\"type\":\"TXT\"[^\}]*\"content\":\"\\\\\"$txtrecord\\\\\"\".*\}")"
if [ "$_record" ]; then
_record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"')
@@ -142,22 +142,30 @@ _ionos_rest() {
export _H1="X-API-Key: $IONOS_API_KEY"
# clear headers
: >"$HTTP_HEADER"
if [ "$method" != "GET" ]; then
export _H2="Accept: application/json"
export _H3="Content-Type: application/json"
response="$(_post "$data" "$IONOS_API$route" "" "$method" "application/json")"
_response="$(_post "$data" "$IONOS_API$route" "" "$method" "application/json")"
else
export _H2="Accept: */*"
export _H3=
response="$(_get "$IONOS_API$route")"
_response="$(_get "$IONOS_API$route")"
fi
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
if [ "$?" != "0" ]; then
_err "Error $route: $response"
_err "Error $route: $_response"
return 1
fi
_debug2 "response" "$response"
_debug2 "_response" "$_response"
_debug2 "_code" "$_code"
return 0
}

157
dnsapi/dns_ipv64.sh Executable file
View File

@@ -0,0 +1,157 @@
#!/usr/bin/env sh
#Created by Roman Lumetsberger, to use ipv64.net's API to add/remove text records
#2022/11/29
# Pass credentials before "acme.sh --issue --dns dns_ipv64 ..."
# --
# export IPv64_Token="aaaaaaaaaaaaaaaaaaaaaaaaaa"
# --
#
IPv64_API="https://ipv64.net/api"
######## Public functions ######################
#Usage: dns_ipv64_add _acme-challenge.domain.ipv64.net "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_ipv64_add() {
fulldomain=$1
txtvalue=$2
IPv64_Token="${IPv64_Token:-$(_readaccountconf_mutable IPv64_Token)}"
if [ -z "$IPv64_Token" ]; then
_err "You must export variable: IPv64_Token"
_err "The API Key for your IPv64 account is necessary."
_err "You can look it up in your IPv64 account."
return 1
fi
# Now save the credentials.
_saveaccountconf_mutable IPv64_Token "$IPv64_Token"
if ! _get_root "$fulldomain"; then
_err "invalid domain" "$fulldomain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
# convert to lower case
_domain="$(echo "$_domain" | _lower_case)"
_sub_domain="$(echo "$_sub_domain" | _lower_case)"
# Now add the TXT record
_info "Trying to add TXT record"
if _ipv64_rest "POST" "add_record=$_domain&praefix=$_sub_domain&type=TXT&content=$txtvalue"; then
_info "TXT record has been successfully added."
return 0
else
_err "Errors happened during adding the TXT record, response=$_response"
return 1
fi
}
#Usage: fulldomain txtvalue
#Usage: dns_ipv64_rm _acme-challenge.domain.ipv64.net "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
#Remove the txt record after validation.
dns_ipv64_rm() {
fulldomain=$1
txtvalue=$2
IPv64_Token="${IPv64_Token:-$(_readaccountconf_mutable IPv64_Token)}"
if [ -z "$IPv64_Token" ]; then
_err "You must export variable: IPv64_Token"
_err "The API Key for your IPv64 account is necessary."
_err "You can look it up in your IPv64 account."
return 1
fi
if ! _get_root "$fulldomain"; then
_err "invalid domain" "$fulldomain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
# convert to lower case
_domain="$(echo "$_domain" | _lower_case)"
_sub_domain="$(echo "$_sub_domain" | _lower_case)"
# Now delete the TXT record
_info "Trying to delete TXT record"
if _ipv64_rest "DELETE" "del_record=$_domain&praefix=$_sub_domain&type=TXT&content=$txtvalue"; then
_info "TXT record has been successfully deleted."
return 0
else
_err "Errors happened during deleting the TXT record, response=$_response"
return 1
fi
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain="$1"
i=1
p=1
_ipv64_get "get_domains"
domain_data=$_response
while true; do
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
if [ -z "$h" ]; then
#not valid
return 1
fi
#if _contains "$domain_data" "\""$h"\"\:"; then
if _contains "$domain_data" "\"""$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
}
#send get request to api
# $1 has to set the api-function
_ipv64_get() {
url="$IPv64_API?$1"
export _H1="Authorization: Bearer $IPv64_Token"
_response=$(_get "$url")
_response="$(echo "$_response" | _normalizeJson)"
if _contains "$_response" "429 Too Many Requests"; then
_info "API throttled, sleeping to reset the limit"
_sleep 10
_response=$(_get "$url")
_response="$(echo "$_response" | _normalizeJson)"
fi
}
_ipv64_rest() {
url="$IPv64_API"
export _H1="Authorization: Bearer $IPv64_Token"
export _H2="Content-Type: application/x-www-form-urlencoded"
_response=$(_post "$2" "$url" "" "$1")
if _contains "$_response" "429 Too Many Requests"; then
_info "API throttled, sleeping to reset the limit"
_sleep 10
_response=$(_post "$2" "$url" "" "$1")
fi
if ! _contains "$_response" "\"info\":\"success\""; then
return 1
fi
_debug2 response "$_response"
return 0
}

View File

@@ -32,7 +32,11 @@ dns_ispconfig_rm() {
#################### Private functions below ##################################
_ISPC_credentials() {
if [ -z "${ISPC_User}" ] || [ -z "$ISPC_Password" ] || [ -z "${ISPC_Api}" ] || [ -n "${ISPC_Api_Insecure}" ]; then
ISPC_User="${ISPC_User:-$(_readaccountconf_mutable ISPC_User)}"
ISPC_Password="${ISPC_Password:-$(_readaccountconf_mutable ISPC_Password)}"
ISPC_Api="${ISPC_Api:-$(_readaccountconf_mutable ISPC_Api)}"
ISPC_Api_Insecure="${ISPC_Api_Insecure:-$(_readaccountconf_mutable ISPC_Api_Insecure)}"
if [ -z "${ISPC_User}" ] || [ -z "${ISPC_Password}" ] || [ -z "${ISPC_Api}" ] || [ -z "${ISPC_Api_Insecure}" ]; then
ISPC_User=""
ISPC_Password=""
ISPC_Api=""
@@ -40,10 +44,10 @@ _ISPC_credentials() {
_err "You haven't specified the ISPConfig Login data, URL and whether you want check the ISPC SSL cert. Please try again."
return 1
else
_saveaccountconf ISPC_User "${ISPC_User}"
_saveaccountconf ISPC_Password "${ISPC_Password}"
_saveaccountconf ISPC_Api "${ISPC_Api}"
_saveaccountconf ISPC_Api_Insecure "${ISPC_Api_Insecure}"
_saveaccountconf_mutable ISPC_User "${ISPC_User}"
_saveaccountconf_mutable ISPC_Password "${ISPC_Password}"
_saveaccountconf_mutable ISPC_Api "${ISPC_Api}"
_saveaccountconf_mutable ISPC_Api_Insecure "${ISPC_Api_Insecure}"
# Set whether curl should use secure or insecure mode
export HTTPS_INSECURE="${ISPC_Api_Insecure}"
fi

View File

@@ -5,51 +5,81 @@
# Environment variables:
#
# - $KAS_Login (Kasserver API login name)
# - $KAS_Authtype (Kasserver API auth type. Default: sha1)
# - $KAS_Authtype (Kasserver API auth type. Default: plain)
# - $KAS_Authdata (Kasserver API auth data.)
#
# Author: Martin Kammerlander, Phlegx Systems OG <martin.kammerlander@phlegx.com>
# Updated by: Marc-Oliver Lange <git@die-lang.es>
# Credits: Inspired by dns_he.sh. Thanks a lot man!
# Git repo: https://github.com/phlegx/acme.sh
# TODO: Better Error handling
# Last update: squared GmbH <github@squaredgmbh.de>
# Credits:
# - dns_he.sh. Thanks a lot man!
# - Martin Kammerlander, Phlegx Systems OG <martin.kammerlander@phlegx.com>
# - Marc-Oliver Lange <git@die-lang.es>
# - https://github.com/o1oo11oo/kasapi.sh
########################################################################
KAS_Api="https://kasapi.kasserver.com/dokumentation/formular.php"
KAS_Api_GET="$(_get "https://kasapi.kasserver.com/soap/wsdl/KasApi.wsdl")"
KAS_Api="$(echo "$KAS_Api_GET" | tr -d ' ' | grep -i "<soap:addresslocation=" | sed "s/='/\n/g" | grep -i "http" | sed "s/'\/>//g")"
_info "[KAS] -> API URL $KAS_Api"
KAS_Auth_GET="$(_get "https://kasapi.kasserver.com/soap/wsdl/KasAuth.wsdl")"
KAS_Auth="$(echo "$KAS_Auth_GET" | tr -d ' ' | grep -i "<soap:addresslocation=" | sed "s/='/\n/g" | grep -i "http" | sed "s/'\/>//g")"
_info "[KAS] -> AUTH URL $KAS_Auth"
KAS_default_ratelimit=5 # TODO - Every response delivers a ratelimit (seconds) where KASAPI is blocking a request.
######## Public functions #####################
dns_kas_add() {
_fulldomain=$1
_txtvalue=$2
_info "Using DNS-01 All-inkl/Kasserver hook"
_info "Adding $_fulldomain DNS TXT entry on All-inkl/Kasserver"
_info "Check and Save Props"
_info "[KAS] -> Using DNS-01 All-inkl/Kasserver hook"
_info "[KAS] -> Check and Save Props"
_check_and_save
_info "Checking Zone and Record_Name"
_info "[KAS] -> Adding $_fulldomain DNS TXT entry on all-inkl.com/Kasserver"
_info "[KAS] -> Retriving Credential Token"
_get_credential_token
_info "[KAS] -> Checking Zone and Record_Name"
_get_zone_and_record_name "$_fulldomain"
_info "Getting Record ID"
_info "[KAS] -> Checking for existing Record entries"
_get_record_id
_info "Creating TXT DNS record"
params="?kas_login=$KAS_Login"
params="$params&kas_auth_type=$KAS_Authtype"
params="$params&kas_auth_data=$KAS_Authdata"
params="$params&var1=record_name"
params="$params&wert1=$_record_name"
params="$params&var2=record_type"
params="$params&wert2=TXT"
params="$params&var3=record_data"
params="$params&wert3=$_txtvalue"
params="$params&var4=record_aux"
params="$params&wert4=0"
params="$params&kas_action=add_dns_settings"
params="$params&var5=zone_host"
params="$params&wert5=$_zone"
_debug2 "Wait for 10 seconds by default before calling KAS API."
_sleep 10
response="$(_get "$KAS_Api$params")"
_debug2 "response" "$response"
# If there is a record_id, delete the entry
if [ -n "$_record_id" ]; then
_info "[KAS] -> Existing records found. Now deleting old entries"
for i in $_record_id; do
_delete_RecordByID "$i"
done
else
_info "[KAS] -> No record found."
fi
if ! _contains "$response" "TRUE"; then
_err "An unkown error occurred, please check manually."
_info "[KAS] -> Creating TXT DNS record"
action="add_dns_settings"
kasReqParam="\"record_name\":\"$_record_name\""
kasReqParam="$kasReqParam,\"record_type\":\"TXT\""
kasReqParam="$kasReqParam,\"record_data\":\"$_txtvalue\""
kasReqParam="$kasReqParam,\"record_aux\":\"0\""
kasReqParam="$kasReqParam,\"zone_host\":\"$_zone\""
response="$(_callAPI "$action" "$kasReqParam")"
_debug2 "[KAS] -> Response" "$response"
if [ -z "$response" ]; then
_info "[KAS] -> Response was empty, please check manually."
return 1
elif _contains "$response" "<SOAP-ENV:Fault>"; then
faultstring="$(echo "$response" | tr -d '\n\r' | sed "s/<faultstring>/\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
case "${faultstring}" in
"record_already_exists")
_info "[KAS] -> The record already exists, which must not be a problem. Please check manually."
;;
*)
_err "[KAS] -> An error =>$faultstring<= occurred, please check manually."
return 1
;;
esac
elif ! _contains "$response" "<item><key xsi:type=\"xsd:string\">ReturnString</key><value xsi:type=\"xsd:string\">TRUE</value></item>"; then
_err "[KAS] -> An unknown error occurred, please check manually."
return 1
fi
return 0
@@ -58,45 +88,62 @@ dns_kas_add() {
dns_kas_rm() {
_fulldomain=$1
_txtvalue=$2
_info "Using DNS-01 All-inkl/Kasserver hook"
_info "Cleaning up after All-inkl/Kasserver hook"
_info "Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver"
_info "Check and Save Props"
_info "[KAS] -> Using DNS-01 All-inkl/Kasserver hook"
_info "[KAS] -> Check and Save Props"
_check_and_save
_info "Checking Zone and Record_Name"
_info "[KAS] -> Cleaning up after All-inkl/Kasserver hook"
_info "[KAS] -> Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver"
_info "[KAS] -> Retriving Credential Token"
_get_credential_token
_info "[KAS] -> Checking Zone and Record_Name"
_get_zone_and_record_name "$_fulldomain"
_info "Getting Record ID"
_info "[KAS] -> Getting Record ID"
_get_record_id
_info "[KAS] -> Removing entries with ID: $_record_id"
# If there is a record_id, delete the entry
if [ -n "$_record_id" ]; then
params="?kas_login=$KAS_Login"
params="$params&kas_auth_type=$KAS_Authtype"
params="$params&kas_auth_data=$KAS_Authdata"
params="$params&kas_action=delete_dns_settings"
for i in $_record_id; do
params2="$params&var1=record_id"
params2="$params2&wert1=$i"
_debug2 "Wait for 10 seconds by default before calling KAS API."
_sleep 10
response="$(_get "$KAS_Api$params2")"
_debug2 "response" "$response"
if ! _contains "$response" "TRUE"; then
_err "Either the txt record is not found or another error occurred, please check manually."
return 1
fi
_delete_RecordByID "$i"
done
else # Cannot delete or unkown error
_err "No record_id found that can be deleted. Please check manually."
return 1
_info "[KAS] -> No record_id found that can be deleted. Please check manually."
fi
return 0
}
########################## PRIVATE FUNCTIONS ###########################
# Delete Record ID
_delete_RecordByID() {
recId=$1
action="delete_dns_settings"
kasReqParam="\"record_id\":\"$recId\""
response="$(_callAPI "$action" "$kasReqParam")"
_debug2 "[KAS] -> Response" "$response"
if [ -z "$response" ]; then
_info "[KAS] -> Response was empty, please check manually."
return 1
elif _contains "$response" "<SOAP-ENV:Fault>"; then
faultstring="$(echo "$response" | tr -d '\n\r' | sed "s/<faultstring>/\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
case "${faultstring}" in
"record_id_not_found")
_info "[KAS] -> The record was not found, which perhaps is not a problem. Please check manually."
;;
*)
_err "[KAS] -> An error =>$faultstring<= occurred, please check manually."
return 1
;;
esac
elif ! _contains "$response" "<item><key xsi:type=\"xsd:string\">ReturnString</key><value xsi:type=\"xsd:string\">TRUE</value></item>"; then
_err "[KAS] -> An unknown error occurred, please check manually."
return 1
fi
}
# Checks for the ENV variables and saves them
_check_and_save() {
KAS_Login="${KAS_Login:-$(_readaccountconf_mutable KAS_Login)}"
@@ -107,7 +154,7 @@ _check_and_save() {
KAS_Login=
KAS_Authtype=
KAS_Authdata=
_err "No auth details provided. Please set user credentials using the \$KAS_Login, \$KAS_Authtype, and \$KAS_Authdata environment variables."
_err "[KAS] -> No auth details provided. Please set user credentials using the \$KAS_Login, \$KAS_Authtype, and \$KAS_Authdata environment variables."
return 1
fi
_saveaccountconf_mutable KAS_Login "$KAS_Login"
@@ -119,50 +166,116 @@ _check_and_save() {
# Gets back the base domain/zone and record name.
# See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide
_get_zone_and_record_name() {
params="?kas_login=$KAS_Login"
params="?kas_login=$KAS_Login"
params="$params&kas_auth_type=$KAS_Authtype"
params="$params&kas_auth_data=$KAS_Authdata"
params="$params&kas_action=get_domains"
action="get_domains"
response="$(_callAPI "$action")"
_debug2 "[KAS] -> Response" "$response"
_debug2 "Wait for 10 seconds by default before calling KAS API."
_sleep 10
response="$(_get "$KAS_Api$params")"
_debug2 "response" "$response"
_zonen="$(echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "domain_name" | tr '<' '\n' | grep "domain_name" | sed "s/domain_name>=>//g")"
_domain="$1"
_temp_domain="$(echo "$1" | sed 's/\.$//')"
_rootzone="$_domain"
for i in $_zonen; do
l1=${#_rootzone}
if [ -z "$response" ]; then
_info "[KAS] -> Response was empty, please check manually."
return 1
elif _contains "$response" "<SOAP-ENV:Fault>"; then
faultstring="$(echo "$response" | tr -d '\n\r' | sed "s/<faultstring>/\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
_err "[KAS] -> Either no domains were found or another error =>$faultstring<= occurred, please check manually."
return 1
fi
zonen="$(echo "$response" | sed 's/<item>/\n/g' | sed -r 's/(.*<key xsi:type="xsd:string">domain_name<\/key><value xsi:type="xsd:string">)(.*)(<\/value.*)/\2/' | sed '/^</d')"
domain="$1"
temp_domain="$(echo "$1" | sed 's/\.$//')"
rootzone="$domain"
for i in $zonen; do
l1=${#rootzone}
l2=${#i}
if _endswith "$_domain" "$i" && [ "$l1" -ge "$l2" ]; then
_rootzone="$i"
if _endswith "$domain" "$i" && [ "$l1" -ge "$l2" ]; then
rootzone="$i"
fi
done
_zone="${_rootzone}."
_temp_record_name="$(echo "$_temp_domain" | sed "s/$_rootzone//g")"
_record_name="$(echo "$_temp_record_name" | sed 's/\.$//')"
_debug2 "Zone:" "$_zone"
_debug2 "Domain:" "$_domain"
_debug2 "Record_Name:" "$_record_name"
_zone="${rootzone}."
temp_record_name="$(echo "$temp_domain" | sed "s/$rootzone//g")"
_record_name="$(echo "$temp_record_name" | sed 's/\.$//')"
_debug "[KAS] -> Zone:" "$_zone"
_debug "[KAS] -> Domain:" "$domain"
_debug "[KAS] -> Record_Name:" "$_record_name"
return 0
}
# Retrieve the DNS record ID
_get_record_id() {
params="?kas_login=$KAS_Login"
params="$params&kas_auth_type=$KAS_Authtype"
params="$params&kas_auth_data=$KAS_Authdata"
params="$params&kas_action=get_dns_settings"
params="$params&var1=zone_host"
params="$params&wert1=$_zone"
action="get_dns_settings"
kasReqParam="\"zone_host\":\"$_zone\""
response="$(_callAPI "$action" "$kasReqParam")"
_debug2 "[KAS] -> Response" "$response"
_debug2 "Wait for 10 seconds by default before calling KAS API."
_sleep 10
response="$(_get "$KAS_Api$params")"
_debug2 "response" "$response"
_record_id="$(echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "=>$_record_name<" | grep '>TXT<' | tr '<' '\n' | grep record_id | sed "s/record_id>=>//g")"
_debug2 _record_id "$_record_id"
if [ -z "$response" ]; then
_info "[KAS] -> Response was empty, please check manually."
return 1
elif _contains "$response" "<SOAP-ENV:Fault>"; then
faultstring="$(echo "$response" | tr -d '\n\r' | sed "s/<faultstring>/\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
_err "[KAS] -> Either no domains were found or another error =>$faultstring<= occurred, please check manually."
return 1
fi
_record_id="$(echo "$response" | tr -d '\n\r' | sed "s/<item xsi:type=\"ns2:Map\">/\n/g" | grep -i "$_record_name" | grep -i ">TXT<" | sed "s/<item><key xsi:type=\"xsd:string\">record_id<\/key><value xsi:type=\"xsd:string\">/=>/g" | grep -i "$_txtvalue" | sed "s/<\/value><\/item>/\n/g" | grep "=>" | sed "s/=>//g")"
_debug "[KAS] -> Record Id: " "$_record_id"
return 0
}
# Retrieve credential token
_get_credential_token() {
baseParamAuth="\"kas_login\":\"$KAS_Login\""
baseParamAuth="$baseParamAuth,\"kas_auth_type\":\"$KAS_Authtype\""
baseParamAuth="$baseParamAuth,\"kas_auth_data\":\"$KAS_Authdata\""
baseParamAuth="$baseParamAuth,\"session_lifetime\":600"
baseParamAuth="$baseParamAuth,\"session_update_lifetime\":\"Y\""
data='<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:xmethodsKasApiAuthentication" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:KasAuth><Params xsi:type="xsd:string">{'
data="$data$baseParamAuth}</Params></ns1:KasAuth></SOAP-ENV:Body></SOAP-ENV:Envelope>"
_debug "[KAS] -> Be friendly and wait $KAS_default_ratelimit seconds by default before calling KAS API."
_sleep $KAS_default_ratelimit
contentType="text/xml"
export _H1="SOAPAction: urn:xmethodsKasApiAuthentication#KasAuth"
response="$(_post "$data" "$KAS_Auth" "" "POST" "$contentType")"
_debug2 "[KAS] -> Response" "$response"
if [ -z "$response" ]; then
_info "[KAS] -> Response was empty, please check manually."
return 1
elif _contains "$response" "<SOAP-ENV:Fault>"; then
faultstring="$(echo "$response" | tr -d '\n\r' | sed "s/<faultstring>/\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
_err "[KAS] -> Could not retrieve login token or antoher error =>$faultstring<= occurred, please check manually."
return 1
fi
_credential_token="$(echo "$response" | tr '\n' ' ' | sed 's/.*return xsi:type="xsd:string">\(.*\)<\/return>/\1/' | sed 's/<\/ns1:KasAuthResponse\(.*\)Envelope>.*//')"
_debug "[KAS] -> Credential Token: " "$_credential_token"
return 0
}
_callAPI() {
kasaction=$1
kasReqParams=$2
baseParamAuth="\"kas_login\":\"$KAS_Login\""
baseParamAuth="$baseParamAuth,\"kas_auth_type\":\"session\""
baseParamAuth="$baseParamAuth,\"kas_auth_data\":\"$_credential_token\""
data='<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:xmethodsKasApi" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:KasApi><Params xsi:type="xsd:string">{'
data="$data$baseParamAuth,\"kas_action\":\"$kasaction\""
if [ -n "$kasReqParams" ]; then
data="$data,\"KasRequestParams\":{$kasReqParams}"
fi
data="$data}</Params></ns1:KasApi></SOAP-ENV:Body></SOAP-ENV:Envelope>"
_debug2 "[KAS] -> Request" "$data"
_debug "[KAS] -> Be friendly and wait $KAS_default_ratelimit seconds by default before calling KAS API."
_sleep $KAS_default_ratelimit
contentType="text/xml"
export _H1="SOAPAction: urn:xmethodsKasApi#KasApi"
response="$(_post "$data" "$KAS_Api" "" "POST" "$contentType")"
_debug2 "[KAS] -> Response" "$response"
echo "$response"
}

View File

@@ -2,7 +2,7 @@
############################################################
# KingHost API support #
# http://api.kinghost.net/doc/ #
# https://api.kinghost.net/doc/ #
# #
# Author: Felipe Keller Braz <felipebraz@kinghost.com.br> #
# Report Bugs here: https://github.com/kinghost/acme.sh #

147
dnsapi/dns_la.sh Normal file
View File

@@ -0,0 +1,147 @@
#!/usr/bin/env sh
#LA_Id="test123"
#LA_Key="d1j2fdo4dee3948"
LA_Api="https://api.dns.la/api"
######## Public functions #####################
#Usage: dns_la_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_la_add() {
fulldomain=$1
txtvalue=$2
LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}"
LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}"
if [ -z "$LA_Id" ] || [ -z "$LA_Key" ]; then
LA_Id=""
LA_Key=""
_err "You didn't specify a dnsla api id and key yet."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf_mutable LA_Id "$LA_Id"
_saveaccountconf_mutable LA_Key "$LA_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 _la_rest "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then
if _contains "$response" '"resultid":'; then
_info "Added, OK"
return 0
elif _contains "$response" '"code":532'; then
_info "Already exists, OK"
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
return 1
}
#fulldomain txtvalue
dns_la_rm() {
fulldomain=$1
txtvalue=$2
LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}"
LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_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"
_debug "Getting txt records"
if ! _la_rest "record.ashx?cmd=listn&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue"; then
_err "Error"
return 1
fi
if ! _contains "$response" '"recordid":'; then
_info "Don't need to remove."
return 0
fi
record_id=$(printf "%s" "$response" | grep '"recordid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n')
_debug "record_id" "$record_id"
if [ -z "$record_id" ]; then
_err "Can not get record id to remove."
return 1
fi
if ! _la_rest "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$record_id"; then
_err "Delete record error."
return 1
fi
_contains "$response" '"code":300'
}
#################### 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=1
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1
fi
if ! _la_rest "domain.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domain=$h"; then
return 1
fi
if _contains "$response" '"domainid":'; then
_domain_id=$(printf "%s" "$response" | grep '"domainid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n')
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
}
#Usage: URI
_la_rest() {
url="$LA_Api/$1"
_debug "$url"
if ! response="$(_get "$url" | tr -d ' ' | tr "}" ",")"; then
_err "Error: $url"
return 1
fi
_debug2 response "$response"
return 0
}

View File

@@ -3,10 +3,10 @@
#Author: Rolph Haspers <r.haspers@global.leaseweb.com>
#Utilize leaseweb.com API to finish dns-01 verifications.
#Requires a Leaseweb API Key (export LSW_Key="Your Key")
#See http://developer.leaseweb.com for more information.
#See https://developer.leaseweb.com for more information.
######## Public functions #####################
LSW_API="https://api.leaseweb.com/hosting/v2/domains/"
LSW_API="https://api.leaseweb.com/hosting/v2/domains"
#Usage: dns_leaseweb_add _acme-challenge.www.domain.com
dns_leaseweb_add() {

View File

@@ -32,8 +32,12 @@ dns_loopia_add() {
_info "Adding record"
_loopia_add_sub_domain "$_domain" "$_sub_domain"
_loopia_add_record "$_domain" "$_sub_domain" "$txtvalue"
if ! _loopia_add_sub_domain "$_domain" "$_sub_domain"; then
return 1
fi
if ! _loopia_add_record "$_domain" "$_sub_domain" "$txtvalue"; then
return 1
fi
}
@@ -70,12 +74,13 @@ dns_loopia_rm() {
<value><string>%s</string></value>
</param>
</params>
</methodCall>' "$LOOPIA_User" "$LOOPIA_Password" "$_domain" "$_sub_domain")
</methodCall>' "$LOOPIA_User" "$Encoded_Password" "$_domain" "$_sub_domain")
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
if ! _contains "$response" "OK"; then
_err "Error could not get txt records"
err_response=$(echo "$response" | sed 's/.*<string>\(.*\)<\/string>.*/\1/')
_err "Error could not get txt records: $err_response"
return 1
fi
}
@@ -101,6 +106,12 @@ _loopia_load_config() {
return 1
fi
if _contains "$LOOPIA_Password" "'" || _contains "$LOOPIA_Password" '"'; then
_err "Password contains quoute or double quoute and this is not supported by dns_loopia.sh"
return 1
fi
Encoded_Password=$(_xml_encode "$LOOPIA_Password")
return 0
}
@@ -133,11 +144,12 @@ _loopia_get_records() {
<value><string>%s</string></value>
</param>
</params>
</methodCall>' $LOOPIA_User $LOOPIA_Password "$domain" "$sub_domain")
</methodCall>' "$LOOPIA_User" "$Encoded_Password" "$domain" "$sub_domain")
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
if ! _contains "$response" "<array>"; then
_err "Error"
err_response=$(echo "$response" | sed 's/.*<string>\(.*\)<\/string>.*/\1/')
_err "Error: $err_response"
return 1
fi
return 0
@@ -162,7 +174,7 @@ _get_root() {
<value><string>%s</string></value>
</param>
</params>
</methodCall>' $LOOPIA_User $LOOPIA_Password)
</methodCall>' "$LOOPIA_User" "$Encoded_Password")
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
while true; do
@@ -206,32 +218,35 @@ _loopia_add_record() {
<value><string>%s</string></value>
</param>
<param>
<struct>
<member>
<name>type</name>
<value><string>TXT</string></value>
</member>
<member>
<name>priority</name>
<value><int>0</int></value>
</member>
<member>
<name>ttl</name>
<value><int>300</int></value>
</member>
<member>
<name>rdata</name>
<value><string>%s</string></value>
</member>
</struct>
<value>
<struct>
<member>
<name>type</name>
<value><string>TXT</string></value>
</member>
<member>
<name>priority</name>
<value><int>0</int></value>
</member>
<member>
<name>ttl</name>
<value><int>300</int></value>
</member>
<member>
<name>rdata</name>
<value><string>%s</string></value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>' $LOOPIA_User $LOOPIA_Password "$domain" "$sub_domain" "$txtval")
</methodCall>' "$LOOPIA_User" "$Encoded_Password" "$domain" "$sub_domain" "$txtval")
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
if ! _contains "$response" "OK"; then
_err "Error"
err_response=$(echo "$response" | sed 's/.*<string>\(.*\)<\/string>.*/\1/')
_err "Error: $err_response"
return 1
fi
return 0
@@ -255,7 +270,7 @@ _sub_domain_exists() {
<value><string>%s</string></value>
</param>
</params>
</methodCall>' $LOOPIA_User $LOOPIA_Password "$domain")
</methodCall>' "$LOOPIA_User" "$Encoded_Password" "$domain")
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
@@ -290,13 +305,22 @@ _loopia_add_sub_domain() {
<value><string>%s</string></value>
</param>
</params>
</methodCall>' $LOOPIA_User $LOOPIA_Password "$domain" "$sub_domain")
</methodCall>' "$LOOPIA_User" "$Encoded_Password" "$domain" "$sub_domain")
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
if ! _contains "$response" "OK"; then
_err "Error"
err_response=$(echo "$response" | sed 's/.*<string>\(.*\)<\/string>.*/\1/')
_err "Error: $err_response"
return 1
fi
return 0
}
_xml_encode() {
encoded_string=$1
encoded_string=$(echo "$encoded_string" | sed 's/&/\&amp;/')
encoded_string=$(echo "$encoded_string" | sed 's/</\&lt;/')
encoded_string=$(echo "$encoded_string" | sed 's/>/\&gt;/')
printf "%s" "$encoded_string"
}

View File

@@ -163,6 +163,7 @@ _retrieve_miab_env() {
_saveaccountconf_mutable MIAB_Username "$MIAB_Username"
_saveaccountconf_mutable MIAB_Password "$MIAB_Password"
_saveaccountconf_mutable MIAB_Server "$MIAB_Server"
return 0
}
#Useage: _miab_rest "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" "custom/_acme-challenge.www.domain.com/txt "POST"

View File

@@ -74,7 +74,7 @@ dns_mydevil_rm() {
validRecords="^${num}${w}${fulldomain}${w}TXT${w}${any}${txtvalue}$"
for id in $(devil dns list "$domain" | tail -n+2 | grep "${validRecords}" | cut -w -s -f 1); do
_info "Removing record $id from domain $domain"
devil dns del "$domain" "$id" || _err "Could not remove DNS record."
echo "y" | devil dns del "$domain" "$id" || _err "Could not remove DNS record."
done
}
@@ -87,7 +87,9 @@ mydevil_get_domain() {
domain=""
for domain in $(devil dns list | cut -w -s -f 1 | tail -n+2); do
_debug "Checking domain: $domain"
if _endswith "$fulldomain" "$domain"; then
_debug "Fulldomain '$fulldomain' matches '$domain'"
printf -- "%s" "$domain"
return 0
fi

View File

@@ -150,7 +150,7 @@ _get_root() {
_mydnsjp_retrieve_domain() {
_debug "Login to MyDNS.JP"
response="$(_post "masterid=$MYDNSJP_MasterID&masterpwd=$MYDNSJP_Password" "$MYDNSJP_API/?MENU=100")"
response="$(_post "MENU=100&masterid=$MYDNSJP_MasterID&masterpwd=$MYDNSJP_Password" "$MYDNSJP_API/members/")"
cookie="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2)"
# If cookies is not empty then logon successful
@@ -159,22 +159,8 @@ _mydnsjp_retrieve_domain() {
return 1
fi
_debug "Retrieve DOMAIN INFO page"
export _H1="Cookie:${cookie}"
response="$(_get "$MYDNSJP_API/?MENU=300")"
if [ "$?" != "0" ]; then
_err "Fail to retrieve DOMAIN INFO."
return 1
fi
_root_domain=$(echo "$response" | grep "DNSINFO\[domainname\]" | sed 's/^.*value="\([^"]*\)".*/\1/')
# Logout
response="$(_get "$MYDNSJP_API/?MENU=090")"
_debug _root_domain "$_root_domain"
if [ -z "$_root_domain" ]; then

View File

@@ -82,7 +82,7 @@ _get_root() {
_debug "Failed domain lookup via domains.getList api call. Trying domain lookup via domains.dns.getHosts api."
# The above "getList" api will only return hosts *owned* by the calling user. However, if the calling
# user is not the owner, but still has administrative rights, we must query the getHosts api directly.
# See this comment and the official namecheap response: http://disq.us/p/1q6v9x9
# See this comment and the official namecheap response: https://disq.us/p/1q6v9x9
if ! _get_root_by_getHosts "$fulldomain"; then
return 1
fi
@@ -259,7 +259,7 @@ _set_namecheap_TXT() {
_debug hosts "$hosts"
if [ -z "$hosts" ]; then
_error "Hosts not found"
_err "Hosts not found"
return 1
fi
@@ -313,7 +313,7 @@ _del_namecheap_TXT() {
_debug hosts "$hosts"
if [ -z "$hosts" ]; then
_error "Hosts not found"
_err "Hosts not found"
return 1
fi

View File

@@ -110,7 +110,7 @@ _get_root() {
return 1
fi
if _contains "$response" "<domain>$host"; then
if _contains "$response" ">$host</domain>"; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$host"
return 0

59
dnsapi/dns_nanelo.sh Normal file
View File

@@ -0,0 +1,59 @@
#!/usr/bin/env sh
# Official DNS API for Nanelo.com
# Provide the required API Key like this:
# NANELO_TOKEN="FmD408PdqT1E269gUK57"
NANELO_API="https://api.nanelo.com/v1/"
######## Public functions #####################
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_nanelo_add() {
fulldomain=$1
txtvalue=$2
NANELO_TOKEN="${NANELO_TOKEN:-$(_readaccountconf_mutable NANELO_TOKEN)}"
if [ -z "$NANELO_TOKEN" ]; then
NANELO_TOKEN=""
_err "You didn't configure a Nanelo API Key yet."
_err "Please set NANELO_TOKEN and try again."
_err "Login to Nanelo.com and go to Settings > API Keys to get a Key"
return 1
fi
_saveaccountconf_mutable NANELO_TOKEN "$NANELO_TOKEN"
_info "Adding TXT record to ${fulldomain}"
response="$(_get "$NANELO_API$NANELO_TOKEN/dns/addrecord?type=TXT&ttl=60&name=${fulldomain}&value=${txtvalue}")"
if _contains "${response}" 'success'; then
return 0
fi
_err "Could not create resource record, please check the logs"
_err "${response}"
return 1
}
dns_nanelo_rm() {
fulldomain=$1
txtvalue=$2
NANELO_TOKEN="${NANELO_TOKEN:-$(_readaccountconf_mutable NANELO_TOKEN)}"
if [ -z "$NANELO_TOKEN" ]; then
NANELO_TOKEN=""
_err "You didn't configure a Nanelo API Key yet."
_err "Please set NANELO_TOKEN and try again."
_err "Login to Nanelo.com and go to Settings > API Keys to get a Key"
return 1
fi
_saveaccountconf_mutable NANELO_TOKEN "$NANELO_TOKEN"
_info "Deleting resource record $fulldomain"
response="$(_get "$NANELO_API$NANELO_TOKEN/dns/deleterecord?type=TXT&ttl=60&name=${fulldomain}&value=${txtvalue}")"
if _contains "${response}" 'success'; then
return 0
fi
_err "Could not delete resource record, please check the logs"
_err "${response}"
return 1
}

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env sh
#NederHost_Key="sdfgikogfdfghjklkjhgfcdcfghjk"
#NederHost_Key="sdfgikogfdfghjklkjhgfcdcfghj"
NederHost_Api="https://api.nederhost.nl/dns/v1"
@@ -112,12 +112,8 @@ _nederhost_rest() {
export _H1="Authorization: Bearer $NederHost_Key"
export _H2="Content-Type: application/json"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$NederHost_Api/$ep" "" "$m")"
else
response="$(_get "$NederHost_Api/$ep")"
fi
_debug data "$data"
response="$(_post "$data" "$NederHost_Api/$ep" "" "$m")"
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
_debug "http response code $_code"

View File

@@ -18,15 +18,15 @@ dns_netlify_add() {
NETLIFY_ACCESS_TOKEN=""
_err "Please specify your Netlify Access Token and try again."
return 1
else
_saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN"
fi
_info "Using Netlify"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN"
if ! _get_root "$fulldomain" "$accesstoken"; then
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
@@ -62,9 +62,9 @@ dns_netlify_rm() {
_debug txtdomain "$txtdomain"
_debug txt "$txt"
_saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN"
NETLIFY_ACCESS_TOKEN="${NETLIFY_ACCESS_TOKEN:-$(_readaccountconf_mutable NETLIFY_ACCESS_TOKEN)}"
if ! _get_root "$txtdomain" "$accesstoken"; then
if ! _get_root "$txtdomain"; then
_err "invalid domain"
return 1
fi
@@ -114,7 +114,7 @@ _get_root() {
fi
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
_domain_id=$(echo "$response" | _egrep_o "\"[^\"]*\",\"name\":\"$h" | cut -d , -f 1 | tr -d \")
_domain_id=$(echo "$response" | _egrep_o "\"[^\"]*\",\"name\":\"$h\"" | cut -d , -f 1 | tr -d \")
if [ "$_domain_id" ]; then
if [ "$i" = 1 ]; then
#create the record at the domain apex (@) if only the domain name was provided as --domain-alias

View File

@@ -159,7 +159,7 @@ _oci_config() {
fi
if [ "$(printf "%s\n" "$OCI_CLI_KEY" | wc -l)" -eq 1 ]; then
OCI_CLI_KEY=$(printf "%s" "$OCI_CLI_KEY" | _dbase64 multiline)
OCI_CLI_KEY=$(printf "%s" "$OCI_CLI_KEY" | _dbase64)
fi
return 0
@@ -265,6 +265,7 @@ _signed_request() {
_response="$(_get "https://${_sig_host}${_sig_target}")"
elif [ "$_curl_method" = "PATCH" ]; then
export _H1="$_date_header"
# shellcheck disable=SC2090
export _H2="$_sig_body_sha256"
export _H3="$_sig_body_type"
export _H4="$_sig_body_length"

View File

@@ -57,16 +57,16 @@ _dns_openstack_create_recordset() {
if [ -z "$_recordset_id" ]; then
_info "Creating a new recordset"
if ! _recordset_id=$(openstack recordset create -c id -f value --type TXT --record "$txtvalue" "$_zone_id" "$fulldomain."); then
if ! _recordset_id=$(openstack recordset create -c id -f value --type TXT --record="$txtvalue" "$_zone_id" "$fulldomain."); then
_err "No recordset ID found after create"
return 1
fi
else
_info "Updating existing recordset"
# Build new list of --record <rec> args for update
_record_args="--record $txtvalue"
# Build new list of --record=<rec> args for update
_record_args="--record=$txtvalue"
for _rec in $_records; do
_record_args="$_record_args --record $_rec"
_record_args="$_record_args --record=$_rec"
done
# shellcheck disable=SC2086
if ! _recordset_id=$(openstack recordset set -c id -f value $_record_args "$_zone_id" "$fulldomain."); then
@@ -107,13 +107,13 @@ _dns_openstack_delete_recordset() {
fi
else
_info "Found existing records, updating recordset"
# Build new list of --record <rec> args for update
# Build new list of --record=<rec> args for update
_record_args=""
for _rec in $_records; do
if [ "$_rec" = "$txtvalue" ]; then
continue
fi
_record_args="$_record_args --record $_rec"
_record_args="$_record_args --record=$_rec"
done
# shellcheck disable=SC2086
if ! openstack recordset set -c id -f value $_record_args "$_zone_id" "$fulldomain." >/dev/null; then

View File

@@ -137,7 +137,7 @@ _get_root() {
domain=$1
i=2
p=1
if _opns_rest "GET" "/domain/get"; then
if _opns_rest "GET" "/domain/searchPrimaryDomain"; then
_domain_response="$response"
else
return 1
@@ -150,8 +150,7 @@ _get_root() {
return 1
fi
_debug h "$h"
id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":{\"\":{[^}]*}}(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2)
id=$(echo "$_domain_response" | _egrep_o "\"uuid\":\"[a-z0-9\-]*\",\"enabled\":\"1\",\"type\":\"primary\",\"domainname\":\"${h}\"" | cut -d ':' -f 2 | cut -d '"' -f 2)
if [ -n "$id" ]; then
_debug id "$id"
_host=$(printf "%s" "$domain" | cut -d . -f 1-$p)

View File

@@ -14,6 +14,9 @@
#'ovh-eu'
OVH_EU='https://eu.api.ovh.com/1.0'
#'ovh-us'
OVH_US='https://api.us.ovhcloud.com/1.0'
#'ovh-ca':
OVH_CA='https://ca.api.ovh.com/1.0'
@@ -29,9 +32,6 @@ SYS_EU='https://eu.api.soyoustart.com/1.0'
#'soyoustart-ca'
SYS_CA='https://ca.api.soyoustart.com/1.0'
#'runabove-ca'
RAV_CA='https://api.runabove.com/1.0'
wiki="https://github.com/acmesh-official/acme.sh/wiki/How-to-use-OVH-domain-api"
ovh_success="https://github.com/acmesh-official/acme.sh/wiki/OVH-Success"
@@ -45,6 +45,10 @@ _ovh_get_api() {
printf "%s" $OVH_EU
return
;;
ovh-us | ovhus)
printf "%s" $OVH_US
return
;;
ovh-ca | ovhca)
printf "%s" $OVH_CA
return
@@ -65,14 +69,15 @@ _ovh_get_api() {
printf "%s" $SYS_CA
return
;;
runabove-ca | runaboveca)
printf "%s" $RAV_CA
# raw API url starts with https://
https*)
printf "%s" "$1"
return
;;
*)
_err "Unknown parameter : $1"
_err "Unknown endpoint : $1"
return 1
;;
esac
@@ -92,7 +97,7 @@ _initAuth() {
if [ "$OVH_AK" != "$(_readaccountconf OVH_AK)" ]; then
_info "It seems that your ovh key is changed, let's clear consumer key first."
_clearaccountconf OVH_CK
_clearaccountconf_mutable OVH_CK
fi
_saveaccountconf_mutable OVH_AK "$OVH_AK"
_saveaccountconf_mutable OVH_AS "$OVH_AS"
@@ -118,13 +123,14 @@ _initAuth() {
#return and wait for retry.
return 1
fi
_saveaccountconf_mutable OVH_CK "$OVH_CK"
_info "Checking authentication"
if ! _ovh_rest GET "domain" || _contains "$response" "INVALID_CREDENTIAL" || _contains "$response" "NOT_CREDENTIAL"; then
_err "The consumer key is invalid: $OVH_CK"
_err "Please retry to create a new one."
_clearaccountconf OVH_CK
_clearaccountconf_mutable OVH_CK
return 1
fi
_info "Consumer key is ok."
@@ -198,6 +204,8 @@ dns_ovh_rm() {
if ! _ovh_rest DELETE "domain/zone/$_domain/record/$rid"; then
return 1
fi
_ovh_rest POST "domain/zone/$_domain/refresh"
_debug "Refresh:$response"
return 0
fi
done
@@ -233,8 +241,7 @@ _ovh_authentication() {
_secure_debug consumerKey "$consumerKey"
OVH_CK="$consumerKey"
_saveaccountconf OVH_CK "$OVH_CK"
_saveaccountconf_mutable OVH_CK "$OVH_CK"
_info "Please open this link to do authentication: $(__green "$validationUrl")"
_info "Here is a guide for you: $(__green "$wiki")"

View File

@@ -41,7 +41,7 @@ pleskxml_init_checks_done=0
NEWLINE='\
'
pleskxml_tplt_get_domains="<packet><customer><get-domain-list><filter/></get-domain-list></customer></packet>"
pleskxml_tplt_get_domains="<packet><webspace><get><filter/><dataset><gen_info/></dataset></get></webspace></packet>"
# Get a list of domains that PLESK can manage, so we can check root domain + host for acme.sh
# Also used to test credentials and URI.
# No params.
@@ -145,22 +145,25 @@ dns_pleskxml_rm() {
)"
if [ -z "$reclist" ]; then
_err "No TXT records found for root domain ${root_domain_name} (Plesk domain ID ${root_domain_id}). Exiting."
_err "No TXT records found for root domain $fulldomain (Plesk domain ID ${root_domain_id}). Exiting."
return 1
fi
_debug "Got list of DNS TXT records for root domain '$root_domain_name':"
_debug "Got list of DNS TXT records for root Plesk domain ID ${root_domain_id} of root domain $fulldomain:"
_debug "$reclist"
# Extracting the id of the TXT record for the full domain (NOT case-sensitive) and corresponding value
recid="$(
_value "$reclist" |
grep "<host>${fulldomain}.</host>" |
grep -i "<host>${fulldomain}.</host>" |
grep "<value>${txtvalue}</value>" |
sed 's/^.*<id>\([0-9]\{1,\}\)<\/id>.*$/\1/'
)"
_debug "Got id from line: $recid"
if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then
_err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'"
_err "DNS records for root domain '${fulldomain}.' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'"
_err "Cannot delete TXT record. Exiting."
return 1
fi
@@ -251,9 +254,12 @@ _call_api() {
# Detect any <status> that isn't "ok". None of the used calls should fail if the API is working correctly.
# Also detect if there simply aren't any status lines (null result?) and report that, as well.
# Remove <data></data> structure from result string, since it might contain <status> values that are related to the status of the domain and not to the API request
statuslines_count_total="$(echo "$pleskxml_prettyprint_result" | grep -c '^ *<status>[^<]*</status> *$')"
statuslines_count_okay="$(echo "$pleskxml_prettyprint_result" | grep -c '^ *<status>ok</status> *$')"
statuslines_count_total="$(echo "$pleskxml_prettyprint_result" | sed '/<data>/,/<\/data>/d' | grep -c '^ *<status>[^<]*</status> *$')"
statuslines_count_okay="$(echo "$pleskxml_prettyprint_result" | sed '/<data>/,/<\/data>/d' | grep -c '^ *<status>ok</status> *$')"
_debug "statuslines_count_total=$statuslines_count_total."
_debug "statuslines_count_okay=$statuslines_count_okay."
if [ -z "$statuslines_count_total" ]; then
@@ -375,7 +381,7 @@ _pleskxml_get_root_domain() {
# Output will be one line per known domain, containing 2 <name> tages and a single <id> tag
# We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned.
output="$(_api_response_split "$pleskxml_prettyprint_result" 'domain' '<type>domain</type>' | sed 's/<ascii-name>/<name>/g;s/<\/ascii-name>/<\/name>/g' | grep '<name>' | grep '<id>')"
output="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '<status>ok</status>' | sed 's/<ascii-name>/<name>/g;s/<\/ascii-name>/<\/name>/g' | grep '<name>' | grep '<id>')"
_debug 'Domains managed by Plesk server are (ignore the hacked output):'
_debug "$output"

115
dnsapi/dns_rage4.sh Executable file
View File

@@ -0,0 +1,115 @@
#!/usr/bin/env sh
#
#RAGE4_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
#RAGE4_USERNAME="xxxx@sss.com"
RAGE4_Api="https://rage4.com/rapi/"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_rage4_add() {
fulldomain=$1
txtvalue=$2
unquotedtxtvalue=$(echo "$txtvalue" | tr -d \")
RAGE4_USERNAME="${RAGE4_USERNAME:-$(_readaccountconf_mutable RAGE4_USERNAME)}"
RAGE4_TOKEN="${RAGE4_TOKEN:-$(_readaccountconf_mutable RAGE4_TOKEN)}"
if [ -z "$RAGE4_USERNAME" ] || [ -z "$RAGE4_TOKEN" ]; then
RAGE4_USERNAME=""
RAGE4_TOKEN=""
_err "You didn't specify a Rage4 api token and username yet."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf_mutable RAGE4_USERNAME "$RAGE4_USERNAME"
_saveaccountconf_mutable RAGE4_TOKEN "$RAGE4_TOKEN"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_rage4_rest "createrecord/?id=$_domain_id&name=$fulldomain&content=$unquotedtxtvalue&type=TXT&active=true&ttl=1"
return 0
}
#fulldomain txtvalue
dns_rage4_rm() {
fulldomain=$1
txtvalue=$2
RAGE4_USERNAME="${RAGE4_USERNAME:-$(_readaccountconf_mutable RAGE4_USERNAME)}"
RAGE4_TOKEN="${RAGE4_TOKEN:-$(_readaccountconf_mutable RAGE4_TOKEN)}"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug "Getting txt records"
_rage4_rest "getrecords/?id=${_domain_id}"
_record_id=$(echo "$response" | sed -rn 's/.*"id":([[:digit:]]+)[^\}]*'"$txtvalue"'.*/\1/p')
_rage4_rest "deleterecord/?id=${_record_id}"
return 0
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _domain=domain.com
# _domain_id=sdjkglgdfewsdfg
_get_root() {
domain=$1
if ! _rage4_rest "getdomains"; then
return 1
fi
_debug _get_root_domain "$domain"
for line in $(echo "$response" | tr '}' '\n'); do
__domain=$(echo "$line" | sed -rn 's/.*"name":"([^"]*)",.*/\1/p')
__domain_id=$(echo "$line" | sed -rn 's/.*"id":([^,]*),.*/\1/p')
if [ "$domain" != "${domain%"$__domain"*}" ]; then
_domain_id="$__domain_id"
break
fi
done
if [ -z "$_domain_id" ]; then
return 1
fi
return 0
}
_rage4_rest() {
ep="$1"
_debug "$ep"
username_trimmed=$(echo "$RAGE4_USERNAME" | tr -d '"')
token_trimmed=$(echo "$RAGE4_TOKEN" | tr -d '"')
auth=$(printf '%s:%s' "$username_trimmed" "$token_trimmed" | _base64)
export _H1="Content-Type: application/json"
export _H2="Authorization: Basic $auth"
response="$(_get "$RAGE4_Api$ep")"
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

View File

@@ -92,10 +92,10 @@ _get_root() {
domains_list=$(echo "${response}" | grep dname | sed -r "s/.*dname=\"([^\"]+)\".*/\\1/g")
for ITEM in ${domains_list}; do
IDN_ITEM="$(_idn "${ITEM}")"
IDN_ITEM=${ITEM}
case "${domain}" in
*${IDN_ITEM}*)
_domain=${IDN_ITEM}
_domain="$(_idn "${ITEM}")"
_debug _domain "${_domain}"
return 0
;;

View File

@@ -76,7 +76,7 @@ dns_selectel_rm() {
return 1
fi
_record_seg="$(echo "$response" | _egrep_o "\"content\" *: *\"$txtvalue\"[^}]*}")"
_record_seg="$(echo "$response" | _egrep_o "[^{]*\"content\" *: *\"$txtvalue\"[^}]*}")"
_debug2 "_record_seg" "$_record_seg"
if [ -z "$_record_seg" ]; then
_err "can not find _record_seg"
@@ -120,7 +120,7 @@ _get_root() {
return 1
fi
if _contains "$response" "\"name\": \"$h\","; then
if _contains "$response" "\"name\" *: *\"$h\","; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
_debug "Getting domain id for $h"

94
dnsapi/dns_selfhost.sh Normal file
View File

@@ -0,0 +1,94 @@
#!/usr/bin/env sh
#
# Author: Marvin Edeler
# Report Bugs here: https://github.com/Marvo2011/acme.sh/issues/1
# Last Edit: 17.02.2022
dns_selfhost_add() {
fulldomain=$1
txt=$2
_info "Calling acme-dns on selfhost"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txt"
SELFHOSTDNS_UPDATE_URL="https://selfhost.de/cgi-bin/api.pl"
# Get values, but don't save until we successfully validated
SELFHOSTDNS_USERNAME="${SELFHOSTDNS_USERNAME:-$(_readaccountconf_mutable SELFHOSTDNS_USERNAME)}"
SELFHOSTDNS_PASSWORD="${SELFHOSTDNS_PASSWORD:-$(_readaccountconf_mutable SELFHOSTDNS_PASSWORD)}"
# These values are domain dependent, so read them from there
SELFHOSTDNS_MAP="${SELFHOSTDNS_MAP:-$(_readdomainconf SELFHOSTDNS_MAP)}"
# Selfhost api can't dynamically add TXT record,
# so we have to store the last used RID of the domain to support a second RID for wildcard domains
# (format: 'fulldomainA:lastRid fulldomainB:lastRid ...')
SELFHOSTDNS_MAP_LAST_USED_INTERNAL=$(_readdomainconf SELFHOSTDNS_MAP_LAST_USED_INTERNAL)
if [ -z "${SELFHOSTDNS_USERNAME:-}" ] || [ -z "${SELFHOSTDNS_PASSWORD:-}" ]; then
_err "SELFHOSTDNS_USERNAME and SELFHOSTDNS_PASSWORD must be set"
return 1
fi
# get the domain entry from SELFHOSTDNS_MAP
# only match full domains (at the beginning of the string or with a leading whitespace),
# e.g. don't match mytest.example.com or sub.test.example.com for test.example.com
# if the domain is defined multiple times only the last occurance will be matched
mapEntry=$(echo "$SELFHOSTDNS_MAP" | sed -n -E "s/(^|^.*[[:space:]])($fulldomain)(:[[:digit:]]+)([:]?[[:digit:]]*)(.*)/\2\3\4/p")
_debug2 mapEntry "$mapEntry"
if test -z "$mapEntry"; then
_err "SELFHOSTDNS_MAP must contain the fulldomain incl. prefix and at least one RID"
return 1
fi
# get the RIDs from the map entry
rid1=$(echo "$mapEntry" | cut -d: -f2)
rid2=$(echo "$mapEntry" | cut -d: -f3)
# read last used rid domain
lastUsedRidForDomainEntry=$(echo "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL" | sed -n -E "s/(^|^.*[[:space:]])($fulldomain:[[:digit:]]+)(.*)/\2/p")
_debug2 lastUsedRidForDomainEntry "$lastUsedRidForDomainEntry"
lastUsedRidForDomain=$(echo "$lastUsedRidForDomainEntry" | cut -d: -f2)
rid="$rid1"
if [ "$lastUsedRidForDomain" = "$rid" ] && ! test -z "$rid2"; then
rid="$rid2"
fi
_info "Trying to add $txt on selfhost for rid: $rid"
data="?username=$SELFHOSTDNS_USERNAME&password=$SELFHOSTDNS_PASSWORD&rid=$rid&content=$txt"
response="$(_get "$SELFHOSTDNS_UPDATE_URL$data")"
if ! echo "$response" | grep "200 OK" >/dev/null; then
_err "Invalid response of acme-dns for selfhost"
return 1
fi
# write last used rid domain
newLastUsedRidForDomainEntry="$fulldomain:$rid"
if ! test -z "$lastUsedRidForDomainEntry"; then
# replace last used rid entry for domain
SELFHOSTDNS_MAP_LAST_USED_INTERNAL=$(echo "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL" | sed -n -E "s/$lastUsedRidForDomainEntry/$newLastUsedRidForDomainEntry/p")
else
# add last used rid entry for domain
if test -z "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL"; then
SELFHOSTDNS_MAP_LAST_USED_INTERNAL="$newLastUsedRidForDomainEntry"
else
SELFHOSTDNS_MAP_LAST_USED_INTERNAL="$SELFHOSTDNS_MAP_LAST_USED_INTERNAL $newLastUsedRidForDomainEntry"
fi
fi
# Now that we know the values are good, save them
_saveaccountconf_mutable SELFHOSTDNS_USERNAME "$SELFHOSTDNS_USERNAME"
_saveaccountconf_mutable SELFHOSTDNS_PASSWORD "$SELFHOSTDNS_PASSWORD"
# These values are domain dependent, so store them there
_savedomainconf SELFHOSTDNS_MAP "$SELFHOSTDNS_MAP"
_savedomainconf SELFHOSTDNS_MAP_LAST_USED_INTERNAL "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL"
}
dns_selfhost_rm() {
fulldomain=$1
txt=$2
_debug fulldomain "$fulldomain"
_debug txtvalue "$txt"
_info "Creating and removing of records is not supported by selfhost API, will not delete anything."
}

View File

@@ -53,7 +53,7 @@ dns_servercow_add() {
if printf -- "%s" "$response" | grep "{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\"" >/dev/null; then
_info "A txt record with the same name already exists."
# trim the string on the left
txtvalue_old=${response#*{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"}
txtvalue_old=${response#*{\"name\":\""$_sub_domain"\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"}
# trim the string on the right
txtvalue_old=${txtvalue_old%%\"*}

View File

@@ -5,8 +5,8 @@
#SIMPLY_AccountName="accountname"
#SIMPLY_ApiKey="apikey"
#
#SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]"
SIMPLY_Api_Default="https://api.simply.com/1"
#SIMPLY_Api="https://api.simply.com/2/"
SIMPLY_Api_Default="https://api.simply.com/2"
#This is used for determining success of REST call
SIMPLY_SUCCESS_CODE='"status":200'
@@ -237,12 +237,18 @@ _simply_rest() {
_debug2 ep "$ep"
_debug2 m "$m"
export _H1="Content-Type: application/json"
basicauth=$(printf "%s:%s" "$SIMPLY_AccountName" "$SIMPLY_ApiKey" | _base64)
if [ "$basicauth" ]; then
export _H1="Authorization: Basic $basicauth"
fi
export _H2="Content-Type: application/json"
if [ "$m" != "GET" ]; then
response="$(_post "$data" "$SIMPLY_Api/$SIMPLY_AccountName/$SIMPLY_ApiKey/$ep" "" "$m")"
response="$(_post "$data" "$SIMPLY_Api/$ep" "" "$m")"
else
response="$(_get "$SIMPLY_Api/$SIMPLY_AccountName/$SIMPLY_ApiKey/$ep")"
response="$(_get "$SIMPLY_Api/$ep")"
fi
if [ "$?" != "0" ]; then

View File

@@ -1,7 +1,6 @@
#!/usr/bin/env sh
TRANSIP_Api_Url="https://api.transip.nl/v6"
TRANSIP_Token_Read_Only="false"
TRANSIP_Token_Global_Key="false"
TRANSIP_Token_Expiration="30 minutes"
# You can't reuse a label token, so we leave this empty normally
TRANSIP_Token_Label=""
@@ -96,7 +95,11 @@ _transip_get_token() {
nonce=$(echo "TRANSIP$(_time)" | _digest sha1 hex | cut -c 1-32)
_debug nonce "$nonce"
data="{\"login\":\"${TRANSIP_Username}\",\"nonce\":\"${nonce}\",\"read_only\":\"${TRANSIP_Token_Read_Only}\",\"expiration_time\":\"${TRANSIP_Token_Expiration}\",\"label\":\"${TRANSIP_Token_Label}\",\"global_key\":\"${TRANSIP_Token_Global_Key}\"}"
# make IP whitelisting configurable
TRANSIP_Token_Global_Key="${TRANSIP_Token_Global_Key:-$(_readaccountconf_mutable TRANSIP_Token_Global_Key)}"
_saveaccountconf_mutable TRANSIP_Token_Global_Key "$TRANSIP_Token_Global_Key"
data="{\"login\":\"${TRANSIP_Username}\",\"nonce\":\"${nonce}\",\"read_only\":\"${TRANSIP_Token_Read_Only}\",\"expiration_time\":\"${TRANSIP_Token_Expiration}\",\"label\":\"${TRANSIP_Token_Label}\",\"global_key\":\"${TRANSIP_Token_Global_Key:-false}\"}"
_debug data "$data"
#_signature=$(printf "%s" "$data" | openssl dgst -sha512 -sign "$TRANSIP_Key_File" | _base64)
@@ -139,6 +142,18 @@ _transip_setup() {
_saveaccountconf_mutable TRANSIP_Username "$TRANSIP_Username"
_saveaccountconf_mutable TRANSIP_Key_File "$TRANSIP_Key_File"
# download key file if it's an URL
if _startswith "$TRANSIP_Key_File" "http"; then
_debug "download transip key file"
TRANSIP_Key_URL=$TRANSIP_Key_File
TRANSIP_Key_File="$(_mktemp)"
chmod 600 "$TRANSIP_Key_File"
if ! _get "$TRANSIP_Key_URL" >"$TRANSIP_Key_File"; then
_err "Error getting key file from : $TRANSIP_Key_URL"
return 1
fi
fi
if [ -f "$TRANSIP_Key_File" ]; then
if ! grep "BEGIN PRIVATE KEY" "$TRANSIP_Key_File" >/dev/null 2>&1; then
_err "Key file doesn't seem to be a valid key: ${TRANSIP_Key_File}"
@@ -156,6 +171,12 @@ _transip_setup() {
fi
fi
if [ -n "${TRANSIP_Key_URL}" ]; then
_debug "delete transip key file"
rm "${TRANSIP_Key_File}"
TRANSIP_Key_File=$TRANSIP_Key_URL
fi
_get_root "$fulldomain" || return 1
return 0

160
dnsapi/dns_udr.sh Normal file
View File

@@ -0,0 +1,160 @@
#!/usr/bin/env sh
# united-domains Reselling (https://www.ud-reselling.com/) DNS API
# Author: Andreas Scherer (https://github.com/andischerer)
# Created: 2021-02-01
#
# Set the environment variables as below:
#
# export UDR_USER="your_username_goes_here"
# export UDR_PASS="some_password_goes_here"
#
UDR_API="https://api.domainreselling.de/api/call.cgi"
UDR_TTL="30"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "some_long_string_of_characters_go_here_from_lets_encrypt"
dns_udr_add() {
fulldomain=$1
txtvalue=$2
UDR_USER="${UDR_USER:-$(_readaccountconf_mutable UDR_USER)}"
UDR_PASS="${UDR_PASS:-$(_readaccountconf_mutable UDR_PASS)}"
if [ -z "$UDR_USER" ] || [ -z "$UDR_PASS" ]; then
UDR_USER=""
UDR_PASS=""
_err "You didn't specify an UD-Reselling username and password yet"
return 1
fi
# save the username and password to the account conf file.
_saveaccountconf_mutable UDR_USER "$UDR_USER"
_saveaccountconf_mutable UDR_PASS "$UDR_PASS"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _dnszone "${_dnszone}"
_debug "Getting txt records"
if ! _udr_rest "QueryDNSZoneRRList" "dnszone=${_dnszone}"; then
return 1
fi
rr="${fulldomain}. ${UDR_TTL} IN TXT ${txtvalue}"
_debug resource_record "${rr}"
if _contains "$response" "$rr" >/dev/null; then
_err "Error, it would appear that this record already exists. Please review existing TXT records for this domain."
return 1
fi
_info "Adding record"
if ! _udr_rest "UpdateDNSZone" "dnszone=${_dnszone}&addrr0=${rr}"; then
_err "Adding the record did not succeed, please verify/check."
return 1
fi
_info "Added, OK"
return 0
}
dns_udr_rm() {
fulldomain=$1
txtvalue=$2
UDR_USER="${UDR_USER:-$(_readaccountconf_mutable UDR_USER)}"
UDR_PASS="${UDR_PASS:-$(_readaccountconf_mutable UDR_PASS)}"
if [ -z "$UDR_USER" ] || [ -z "$UDR_PASS" ]; then
UDR_USER=""
UDR_PASS=""
_err "You didn't specify an UD-Reselling username and password yet"
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _dnszone "${_dnszone}"
_debug "Getting txt records"
if ! _udr_rest "QueryDNSZoneRRList" "dnszone=${_dnszone}"; then
return 1
fi
rr="${fulldomain}. ${UDR_TTL} IN TXT ${txtvalue}"
_debug resource_record "${rr}"
if _contains "$response" "$rr" >/dev/null; then
if ! _udr_rest "UpdateDNSZone" "dnszone=${_dnszone}&delrr0=${rr}"; then
_err "Deleting the record did not succeed, please verify/check."
return 1
fi
_info "Removed, OK"
return 0
else
_info "Text record is not present, will not delete anything."
return 0
fi
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain=$1
i=1
if ! _udr_rest "QueryDNSZoneList" ""; then
return 1
fi
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
if _contains "${response}" "${h}." >/dev/null; then
_dnszone=$(echo "$response" | _egrep_o "${h}")
if [ "$_dnszone" ]; then
return 0
fi
return 1
fi
i=$(_math "$i" + 1)
done
return 1
}
_udr_rest() {
if [ -n "$2" ]; then
data="command=$1&$2"
else
data="command=$1"
fi
_debug data "${data}"
response="$(_post "${data}" "${UDR_API}?s_login=${UDR_USER}&s_pw=${UDR_PASS}" "" "POST")"
_code=$(echo "$response" | _egrep_o "code = ([0-9]+)" | _head_n 1 | cut -d = -f 2 | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
_description=$(echo "$response" | _egrep_o "description = .*" | _head_n 1 | cut -d = -f 2 | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
_debug response_code "$_code"
_debug response_description "$_description"
if [ ! "$_code" = "200" ]; then
_err "DNS-API-Error: $_description"
return 1
fi
return 0
}

View File

@@ -5,7 +5,8 @@
#
# ULTRA_PWD="some_password_goes_here"
ULTRA_API="https://restapi.ultradns.com/v2/"
ULTRA_API="https://api.ultradns.com/v3/"
ULTRA_AUTH_API="https://api.ultradns.com/v2/"
#Usage: add _acme-challenge.www.domain.com "some_long_string_of_characters_go_here_from_lets_encrypt"
dns_ultra_add() {
@@ -121,7 +122,7 @@ _get_root() {
return 1
fi
if _contains "${response}" "${h}." >/dev/null; then
_domain_id=$(echo "$response" | _egrep_o "${h}")
_domain_id=$(echo "$response" | _egrep_o "${h}" | head -1)
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="${h}"
@@ -142,23 +143,25 @@ _ultra_rest() {
ep="$2"
data="$3"
_debug "$ep"
_debug TOKEN "${AUTH_TOKEN}"
if [ -z "$AUTH_TOKEN" ]; then
_ultra_login
fi
_debug TOKEN "$AUTH_TOKEN"
_ultra_login
export _H1="Content-Type: application/json"
export _H2="Authorization: Bearer ${AUTH_TOKEN}"
export _H2="Authorization: Bearer $AUTH_TOKEN"
if [ "$m" != "GET" ]; then
_debug data "${data}"
response="$(_post "${data}" "${ULTRA_API}"/"${ep}" "" "${m}")"
_debug data "$data"
response="$(_post "$data" "$ULTRA_API$ep" "" "$m")"
else
response="$(_get "$ULTRA_API/$ep")"
response="$(_get "$ULTRA_API$ep")"
fi
}
_ultra_login() {
export _H1=""
export _H2=""
AUTH_TOKEN=$(_post "grant_type=password&username=${ULTRA_USR}&password=${ULTRA_PWD}" "${ULTRA_API}authorization/token" | cut -d, -f3 | cut -d\" -f4)
AUTH_TOKEN=$(_post "grant_type=password&username=${ULTRA_USR}&password=${ULTRA_PWD}" "${ULTRA_AUTH_API}authorization/token" | cut -d, -f3 | cut -d\" -f4)
export AUTH_TOKEN
}

142
dnsapi/dns_vercel.sh Normal file
View File

@@ -0,0 +1,142 @@
#!/usr/bin/env sh
# Vercel DNS API
#
# This is your API token which can be acquired on the account page.
# https://vercel.com/account/tokens
#
# VERCEL_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje"
VERCEL_API="https://api.vercel.com"
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_vercel_add() {
fulldomain=$1
txtvalue=$2
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
VERCEL_TOKEN="${VERCEL_TOKEN:-$(_readaccountconf_mutable VERCEL_TOKEN)}"
if [ -z "$VERCEL_TOKEN" ]; then
VERCEL_TOKEN=""
_err "You have not set the Vercel API token yet."
_err "Please visit https://vercel.com/account/tokens to generate it."
return 1
fi
_saveaccountconf_mutable VERCEL_TOKEN "$VERCEL_TOKEN"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_info "Adding record"
if _vercel_rest POST "v2/domains/$_domain/records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\"}"; then
if printf -- "%s" "$response" | grep "\"uid\":\"" >/dev/null; then
_info "Added"
return 0
else
_err "Unexpected response while adding text record."
return 1
fi
fi
_err "Add txt record error."
}
dns_vercel_rm() {
fulldomain=$1
txtvalue=$2
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_vercel_rest GET "v2/domains/$_domain/records"
count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$_sub_domain\",[^{]*\"type\":\"TXT\"" | wc -l | tr -d " ")
if [ "$count" = "0" ]; then
_info "Don't need to remove."
else
_record_id=$(printf "%s" "$response" | _egrep_o "\"id\":[^,]*,\"slug\":\"[^,]*\",\"name\":\"$_sub_domain\",[^{]*\"type\":\"TXT\",\"value\":\"$txtvalue\"" | cut -d: -f2 | cut -d, -f1 | tr -d '"')
if [ "$_record_id" ]; then
echo "$_record_id" | while read -r item; do
if _vercel_rest DELETE "v2/domains/$_domain/records/$item"; then
_info "removed record" "$item"
return 0
else
_err "failed to remove record" "$item"
return 1
fi
done
fi
fi
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain="$1"
ep="$2"
i=1
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
#not valid
return 1
fi
if ! _vercel_rest GET "v4/domains/$h"; then
return 1
fi
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_vercel_rest() {
m="$1"
ep="$2"
data="$3"
path="$VERCEL_API/$ep"
export _H1="Content-Type: application/json"
export _H2="Authorization: Bearer $VERCEL_TOKEN"
if [ "$m" != "GET" ]; then
_secure_debug2 data "$data"
response="$(_post "$data" "$path" "" "$m")"
else
response="$(_get "$path")"
fi
_ret="$?"
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
_debug "http response code $_code"
_secure_debug2 response "$response"
if [ "$_ret" != "0" ]; then
_err "error $ep"
return 1
fi
response="$(printf "%s" "$response" | _normalizeJson)"
return 0
}

View File

@@ -3,10 +3,10 @@
#
#VULTR_API_KEY=000011112222333344445555666677778888
VULTR_Api="https://api.vultr.com/v1"
VULTR_Api="https://api.vultr.com/v2"
######## Public functions #####################
#
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_vultr_add() {
fulldomain=$1
@@ -31,14 +31,14 @@ dns_vultr_add() {
_debug _domain "$_domain"
_debug 'Getting txt records'
_vultr_rest GET "dns/records?domain=$_domain"
_vultr_rest GET "domains/$_domain/records"
if printf "%s\n" "$response" | grep -- "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then
_err 'Error'
return 1
fi
if ! _vultr_rest POST 'dns/create_record' "domain=$_domain&name=$_sub_domain&data=\"$txtvalue\"&type=TXT"; then
if ! _vultr_rest POST "domains/$_domain/records" "{\"name\":\"$_sub_domain\",\"data\":\"$txtvalue\",\"type\":\"TXT\"}"; then
_err "$response"
return 1
fi
@@ -71,14 +71,14 @@ dns_vultr_rm() {
_debug _domain "$_domain"
_debug 'Getting txt records'
_vultr_rest GET "dns/records?domain=$_domain"
_vultr_rest GET "domains/$_domain/records"
if printf "%s\n" "$response" | grep -- "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then
_err 'Error'
return 1
fi
_record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'RECORDID' | cut -d : -f 2)"
_record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'id' | cut -d : -f 2 | tr -d '"')"
_debug _record_id "$_record_id"
if [ "$_record_id" ]; then
_info "Successfully retrieved the record id for ACME challenge."
@@ -87,7 +87,7 @@ dns_vultr_rm() {
return 0
fi
if ! _vultr_rest POST 'dns/delete_record' "domain=$_domain&RECORDID=$_record_id"; then
if ! _vultr_rest DELETE "domains/$_domain/records/$_record_id"; then
_err "$response"
return 1
fi
@@ -112,11 +112,11 @@ _get_root() {
return 1
fi
if ! _vultr_rest GET "dns/list"; then
if ! _vultr_rest GET "domains"; then
return 1
fi
if printf "%s\n" "$response" | grep '^\[.*\]' >/dev/null; then
if printf "%s\n" "$response" | grep -E '^\{.*\}' >/dev/null; then
if _contains "$response" "\"domain\":\"$_domain\""; then
_sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")"
return 0
@@ -139,10 +139,10 @@ _vultr_rest() {
data="$3"
_debug "$ep"
api_key_trimmed=$(echo $VULTR_API_KEY | tr -d '"')
api_key_trimmed=$(echo "$VULTR_API_KEY" | tr -d '"')
export _H1="Api-Key: $api_key_trimmed"
export _H2='Content-Type: application/x-www-form-urlencoded'
export _H1="Authorization: Bearer $api_key_trimmed"
export _H2='Content-Type: application/json'
if [ "$m" != "GET" ]; then
_debug data "$data"

View File

@@ -12,7 +12,7 @@ RECORD=''
# Usage: dns_world4you_add <fqdn> <value>
dns_world4you_add() {
fqdn="$1"
fqdn=$(echo "$1" | _lower_case)
value="$2"
_info "Using world4you to add record"
_debug fulldomain "$fqdn"
@@ -24,7 +24,7 @@ dns_world4you_add() {
fi
export _H1="Cookie: W4YSESSID=$sessid"
form=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht")
form=$(_get "$WORLD4YOU_API/")
_get_paketnr "$fqdn" "$form"
paketnr="$PAKETNR"
if [ -z "$paketnr" ]; then
@@ -49,33 +49,32 @@ dns_world4you_add() {
ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns" '' POST 'application/x-www-form-urlencoded')
_resethttp
if _contains "$(_head_n 3 <"$HTTP_HEADER")" '302'; then
if _contains "$(_head_n 1 <"$HTTP_HEADER")" '302'; then
res=$(_get "$WORLD4YOU_API/$paketnr/dns")
if _contains "$res" "successfully"; then
return 0
else
msg=$(echo "$res" | tr '\n' '\t' | sed 's/.*<h3 class="mb-5">[^\t]*\t *\([^\t]*\)\t.*/\1/')
if _contains "$msg" '^<\!DOCTYPE html>'; then
msg='Unknown error'
fi
_err "Unable to add record: $msg"
if _contains "$msg" '^<\!DOCTYPE html>'; then
msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "<h3[^>]*>[^<]" | sed 's/<[^>]*>//g' | sed 's/^\s*//g')
if [ "$msg" = '' ]; then
_err "Unable to add record: Unknown error"
echo "$ret" >'error-01.html'
echo "$res" >'error-02.html'
_err "View error-01.html and error-02.html for debugging"
else
_err "Unable to add record: my.world4you.com: $msg"
fi
return 1
fi
else
_err "$(_head_n 3 <"$HTTP_HEADER")"
_err "View $HTTP_HEADER for debugging"
msg=$(echo "$ret" | grep '"form-error-message"' | sed 's/^.*<div class="form-error-message">\([^<]*\)<\/div>.*$/\1/')
_err "Unable to add record: my.world4you.com: $msg"
return 1
fi
}
# Usage: dns_world4you_rm <fqdn> <value>
dns_world4you_rm() {
fqdn="$1"
fqdn=$(echo "$1" | _lower_case)
value="$2"
_info "Using world4you to remove record"
_debug fulldomain "$fqdn"
@@ -87,7 +86,7 @@ dns_world4you_rm() {
fi
export _H1="Cookie: W4YSESSID=$sessid"
form=$(_get "$WORLD4YOU_API/dashboard/paketuebersicht")
form=$(_get "$WORLD4YOU_API/")
_get_paketnr "$fqdn" "$form"
paketnr="$PAKETNR"
if [ -z "$paketnr" ]; then
@@ -114,26 +113,25 @@ dns_world4you_rm() {
ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns/record/delete" '' POST 'application/x-www-form-urlencoded')
_resethttp
if _contains "$(_head_n 3 <"$HTTP_HEADER")" '302'; then
if _contains "$(_head_n 1 <"$HTTP_HEADER")" '302'; then
res=$(_get "$WORLD4YOU_API/$paketnr/dns")
if _contains "$res" "successfully"; then
return 0
else
msg=$(echo "$res" | tr '\n' '\t' | sed 's/.*<h3 class="mb-5">[^\t]*\t *\([^\t]*\)\t.*/\1/')
if _contains "$msg" '^<\!DOCTYPE html>'; then
msg='Unknown error'
fi
_err "Unable to remove record: $msg"
if _contains "$msg" '^<\!DOCTYPE html>'; then
msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "<h3[^>]*>[^<]" | sed 's/<[^>]*>//g' | sed 's/^\s*//g')
if [ "$msg" = '' ]; then
_err "Unable to remove record: Unknown error"
echo "$ret" >'error-01.html'
echo "$res" >'error-02.html'
_err "View error-01.html and error-02.html for debugging"
else
_err "Unable to remove record: my.world4you.com: $msg"
fi
return 1
fi
else
_err "$(_head_n 3 <"$HTTP_HEADER")"
_err "View $HTTP_HEADER for debugging"
msg=$(echo "$ret" | grep "form-error-message" | sed 's/^.*<div class="form-error-message">\([^<]*\)<\/div>.*$/\1/')
_err "Unable to remove record: my.world4you.com: $msg"
return 1
fi
}
@@ -157,34 +155,47 @@ _login() {
_saveaccountconf_mutable WORLD4YOU_USERNAME "$WORLD4YOU_USERNAME"
_saveaccountconf_mutable WORLD4YOU_PASSWORD "$WORLD4YOU_PASSWORD"
_resethttp
export ACME_HTTP_NO_REDIRECTS=1
page=$(_get "$WORLD4YOU_API/login")
_resethttp
if _contains "$(_head_n 1 <"$HTTP_HEADER")" '302'; then
_info "Already logged in"
_parse_sessid
return 0
fi
_info "Logging in..."
username="$WORLD4YOU_USERNAME"
password="$WORLD4YOU_PASSWORD"
csrf_token=$(_get "$WORLD4YOU_API/login" | grep '_csrf_token' | sed 's/^.*<input[^>]*value=\"\([^"]*\)\".*$/\1/')
sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/')
csrf_token=$(echo "$page" | grep '_csrf_token' | sed 's/^.*<input[^>]*value=\"\([^"]*\)\".*$/\1/')
_parse_sessid
export _H1="Cookie: W4YSESSID=$sessid"
export _H2="X-Requested-With: XMLHttpRequest"
body="_username=$username&_password=$password&_csrf_token=$csrf_token"
ret=$(_post "$body" "$WORLD4YOU_API/login" '' POST 'application/x-www-form-urlencoded')
unset _H2
_debug ret "$ret"
if _contains "$ret" "\"success\":true"; then
_info "Successfully logged in"
sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/')
_parse_sessid
else
_err "Unable to log in: $(echo "$ret" | sed 's/^.*"message":"\([^\"]*\)".*$/\1/')"
msg=$(echo "$ret" | sed 's/^.*"message":"\([^\"]*\)".*$/\1/')
_err "Unable to log in: my.world4you.com: $msg"
return 1
fi
}
# Usage _get_paketnr <fqdn> <form>
# Usage: _get_paketnr <fqdn> <form>
_get_paketnr() {
fqdn="$1"
form="$2"
domains=$(echo "$form" | grep '^ *[A-Za-z0-9_\.-]*\.[A-Za-z0-9_-]*$' | sed 's/^ *\(.*\)$/\1/')
domains=$(echo "$form" | grep '<ul class="nav header-paket-list">' | sed 's/<li/\n<li/g' | sed 's/<[^>]*>/ /g' | sed 's/^.*>\([^>]*\)$/\1/')
domain=''
for domain in $domains; do
if _contains "$fqdn" "$domain\$"; then
@@ -199,6 +210,11 @@ _get_paketnr() {
TLD="$domain"
_debug domain "$domain"
RECORD=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#TLD} - 1))")
PAKETNR=$(echo "$form" | grep "data-textfilter=\".* $domain " | _head_n 1 | sed 's/^.* \([0-9]*\) .*$/\1/')
PAKETNR=$(echo "$domains" | grep "$domain" | sed 's/^[^,]*, *\([0-9]*\).*$/\1/')
return 0
}
# Usage: _parse_sessid
_parse_sessid() {
sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | _tail_n 1 | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/')
}

264
dnsapi/dns_yc.sh Normal file
View File

@@ -0,0 +1,264 @@
#!/usr/bin/env sh
#YC_Zone_ID="" # DNS Zone ID
#YC_Folder_ID="" # YC Folder ID
#YC_SA_ID="" # Service Account ID
#YC_SA_Key_ID="" # Service Account IAM Key ID
#YC_SA_Key_File_Path="/path/to/private.key" # Path to private.key use instead of YC_SA_Key_File_PEM_b64
#YC_SA_Key_File_PEM_b64="" # Base64 content of private.key use instead of YC_SA_Key_File_Path
YC_Api="https://dns.api.cloud.yandex.net/dns/v1"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_yc_add() {
fulldomain="$(echo "$1". | _lower_case)" # Add dot at end of domain name
txtvalue=$2
YC_SA_Key_File_PEM_b64="${YC_SA_Key_File_PEM_b64:-$(_readaccountconf_mutable YC_SA_Key_File_PEM_b64)}"
YC_SA_Key_File_Path="${YC_SA_Key_File_Path:-$(_readaccountconf_mutable YC_SA_Key_File_Path)}"
if [ "$YC_SA_Key_File_PEM_b64" ]; then
echo "$YC_SA_Key_File_PEM_b64" | _dbase64 >private.key
YC_SA_Key_File="private.key"
_savedomainconf YC_SA_Key_File_PEM_b64 "$YC_SA_Key_File_PEM_b64"
else
YC_SA_Key_File="$YC_SA_Key_File_Path"
_savedomainconf YC_SA_Key_File_Path "$YC_SA_Key_File_Path"
fi
YC_Zone_ID="${YC_Zone_ID:-$(_readaccountconf_mutable YC_Zone_ID)}"
YC_Folder_ID="${YC_Folder_ID:-$(_readaccountconf_mutable YC_Folder_ID)}"
YC_SA_ID="${YC_SA_ID:-$(_readaccountconf_mutable YC_SA_ID)}"
YC_SA_Key_ID="${YC_SA_Key_ID:-$(_readaccountconf_mutable YC_SA_Key_ID)}"
if [ "$YC_SA_ID" ] && [ "$YC_SA_Key_ID" ] && [ "$YC_SA_Key_File" ]; then
if [ -f "$YC_SA_Key_File" ]; then
if _isRSA "$YC_SA_Key_File" >/dev/null 2>&1; then
if [ "$YC_Zone_ID" ]; then
_savedomainconf YC_Zone_ID "$YC_Zone_ID"
_savedomainconf YC_SA_ID "$YC_SA_ID"
_savedomainconf YC_SA_Key_ID "$YC_SA_Key_ID"
elif [ "$YC_Folder_ID" ]; then
_savedomainconf YC_Folder_ID "$YC_Folder_ID"
_saveaccountconf_mutable YC_SA_ID "$YC_SA_ID"
_saveaccountconf_mutable YC_SA_Key_ID "$YC_SA_Key_ID"
_clearaccountconf_mutable YC_Zone_ID
_clearaccountconf YC_Zone_ID
else
_err "You didn't specify a Yandex Cloud Zone ID or Folder ID yet."
return 1
fi
else
_err "YC_SA_Key_File not a RSA file(_isRSA function return false)."
return 1
fi
else
_err "YC_SA_Key_File not found in path $YC_SA_Key_File."
return 1
fi
else
_clearaccountconf YC_Zone_ID
_clearaccountconf YC_Folder_ID
_clearaccountconf YC_SA_ID
_clearaccountconf YC_SA_Key_ID
_clearaccountconf YC_SA_Key_File_PEM_b64
_clearaccountconf YC_SA_Key_File_Path
_err "You didn't specify a YC_SA_ID or YC_SA_Key_ID or YC_SA_Key_File."
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"
if ! _yc_rest GET "zones/${_domain_id}:getRecordSet?type=TXT&name=$_sub_domain"; then
_err "Error: $response"
return 1
fi
_info "Adding record"
if _yc_rest POST "zones/$_domain_id:upsertRecordSets" "{\"merges\": [ { \"name\":\"$_sub_domain\",\"type\":\"TXT\",\"ttl\":\"120\",\"data\":[\"$txtvalue\"]}]}"; then
if _contains "$response" "\"done\": true"; then
_info "Added, OK"
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
return 1
}
#fulldomain txtvalue
dns_yc_rm() {
fulldomain="$(echo "$1". | _lower_case)" # Add dot at end of domain name
txtvalue=$2
YC_Zone_ID="${YC_Zone_ID:-$(_readaccountconf_mutable YC_Zone_ID)}"
YC_Folder_ID="${YC_Folder_ID:-$(_readaccountconf_mutable YC_Folder_ID)}"
YC_SA_ID="${YC_SA_ID:-$(_readaccountconf_mutable YC_SA_ID)}"
YC_SA_Key_ID="${YC_SA_Key_ID:-$(_readaccountconf_mutable YC_SA_Key_ID)}"
_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"
if _yc_rest GET "zones/${_domain_id}:getRecordSet?type=TXT&name=$_sub_domain"; then
exists_txtvalue=$(echo "$response" | _normalizeJson | _egrep_o "\"data\".*\][^,]*" | _egrep_o "[^:]*$")
_debug exists_txtvalue "$exists_txtvalue"
else
_err "Error: $response"
return 1
fi
if _yc_rest POST "zones/$_domain_id:updateRecordSets" "{\"deletions\": [ { \"name\":\"$_sub_domain\",\"type\":\"TXT\",\"ttl\":\"120\",\"data\":$exists_txtvalue}]}"; then
if _contains "$response" "\"done\": true"; then
_info "Delete, OK"
return 0
else
_err "Delete record error."
return 1
fi
fi
_err "Delete record error."
return 1
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
# _domain_id=sdjkglgdfewsdfg
_get_root() {
domain=$1
i=1
p=1
# Use Zone ID directly if provided
if [ "$YC_Zone_ID" ]; then
if ! _yc_rest GET "zones/$YC_Zone_ID"; then
return 1
else
if echo "$response" | tr -d " " | _egrep_o "\"id\":\"$YC_Zone_ID\"" >/dev/null; then
_domain=$(echo "$response" | _egrep_o "\"zone\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ")
if [ "$_domain" ]; then
_cutlength=$((${#domain} - ${#_domain}))
_sub_domain=$(printf "%s" "$domain" | cut -c "1-$_cutlength")
_domain_id=$YC_Zone_ID
return 0
else
return 1
fi
else
return 1
fi
fi
fi
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
if [ "$YC_Folder_ID" ]; then
if ! _yc_rest GET "zones?folderId=$YC_Folder_ID"; then
return 1
fi
else
echo "You didn't specify a Yandex Cloud Folder ID."
return 1
fi
if _contains "$response" "\"zone\": \"$h\""; then
_domain_id=$(echo "$response" | _normalizeJson | _egrep_o "[^{]*\"zone\":\"$h\"[^}]*" | _egrep_o "\"id\"[^,]*" | _egrep_o "[^:]*$" | tr -d '"')
_debug _domain_id "$_domain_id"
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
return 1
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_yc_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
if [ ! "$YC_Token" ]; then
_debug "Login"
_yc_login
else
_debug "Token already exists. Skip Login."
fi
token_trimmed=$(echo "$YC_Token" | tr -d '"')
export _H1="Content-Type: application/json"
export _H2="Authorization: Bearer $token_trimmed"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$YC_Api/$ep" "" "$m")"
else
response="$(_get "$YC_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}
_yc_login() {
header=$(echo "{\"typ\":\"JWT\",\"alg\":\"PS256\",\"kid\":\"$YC_SA_Key_ID\"}" | _normalizeJson | _base64 | _url_replace)
_debug header "$header"
_current_timestamp=$(_time)
_expire_timestamp=$(_math "$_current_timestamp" + 1200) # 20 minutes
payload=$(echo "{\"iss\":\"$YC_SA_ID\",\"aud\":\"https://iam.api.cloud.yandex.net/iam/v1/tokens\",\"iat\":$_current_timestamp,\"exp\":$_expire_timestamp}" | _normalizeJson | _base64 | _url_replace)
_debug payload "$payload"
#signature=$(printf "%s.%s" "$header" "$payload" | ${ACME_OPENSSL_BIN:-openssl} dgst -sign "$YC_SA_Key_File -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1" | _base64 | _url_replace )
_signature=$(printf "%s.%s" "$header" "$payload" | _sign "$YC_SA_Key_File" "sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1" | _url_replace)
_debug2 _signature "$_signature"
rm -rf "$YC_SA_Key_File"
_jwt=$(printf "{\"jwt\": \"%s.%s.%s\"}" "$header" "$payload" "$_signature")
_debug2 _jwt "$_jwt"
export _H1="Content-Type: application/json"
_iam_response="$(_post "$_jwt" "https://iam.api.cloud.yandex.net/iam/v1/tokens" "" "POST")"
_debug3 _iam_response "$(echo "$_iam_response" | _normalizeJson)"
YC_Token="$(echo "$_iam_response" | _normalizeJson | _egrep_o "\"iamToken\"[^,]*" | _egrep_o "[^:]*$" | tr -d '"')"
_debug3 YC_Token
return 0
}

View File

@@ -0,0 +1,44 @@
#!/usr/bin/env sh
#Support CallMeBot Whatsapp webhooks
#CALLMEBOT_YOUR_PHONE_NO=""
#CALLMEBOT_API_KEY=""
callmebotWhatsApp_send() {
_subject="$1"
_content="$2"
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
_debug "_statusCode" "$_statusCode"
CALLMEBOT_YOUR_PHONE_NO="${CALLMEBOT_YOUR_PHONE_NO:-$(_readaccountconf_mutable CALLMEBOT_YOUR_PHONE_NO)}"
if [ -z "$CALLMEBOT_YOUR_PHONE_NO" ]; then
CALLMEBOT_YOUR_PHONE_NO=""
_err "You didn't specify a Slack webhook url CALLMEBOT_YOUR_PHONE_NO yet."
return 1
fi
_saveaccountconf_mutable CALLMEBOT_YOUR_PHONE_NO "$CALLMEBOT_YOUR_PHONE_NO"
CALLMEBOT_API_KEY="${CALLMEBOT_API_KEY:-$(_readaccountconf_mutable CALLMEBOT_API_KEY)}"
if [ "$CALLMEBOT_API_KEY" ]; then
_saveaccountconf_mutable CALLMEBOT_API_KEY "$CALLMEBOT_API_KEY"
fi
_waUrl="https://api.callmebot.com/whatsapp.php"
_Phone_No="$(printf "%s" "$CALLMEBOT_YOUR_PHONE_NO" | _url_encode)"
_apikey="$(printf "%s" "$CALLMEBOT_API_KEY" | _url_encode)"
_message="$(printf "*%s*\\n%s" "$_subject" "$_content" | _url_encode)"
_finalUrl="$_waUrl?phone=$_Phone_No&apikey=$_apikey&text=$_message"
response="$(_get "$_finalUrl")"
if [ "$?" = "0" ] && _contains ".<p><b>Message queued.</b> You will receive it in a few seconds."; then
_info "wa send success."
return 0
fi
_err "wa send error."
_debug "URL" "$_finalUrl"
_debug "Response" "$response"
return 1
}

57
notify/discord.sh Normal file
View File

@@ -0,0 +1,57 @@
#!/usr/bin/env sh
#Support Discord webhooks
# Required:
#DISCORD_WEBHOOK_URL=""
# Optional:
#DISCORD_USERNAME=""
#DISCORD_AVATAR_URL=""
discord_send() {
_subject="$1"
_content="$2"
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
_debug "_statusCode" "$_statusCode"
DISCORD_WEBHOOK_URL="${DISCORD_WEBHOOK_URL:-$(_readaccountconf_mutable DISCORD_WEBHOOK_URL)}"
if [ -z "$DISCORD_WEBHOOK_URL" ]; then
DISCORD_WEBHOOK_URL=""
_err "You didn't specify a Discord webhook url DISCORD_WEBHOOK_URL yet."
return 1
fi
_saveaccountconf_mutable DISCORD_WEBHOOK_URL "$DISCORD_WEBHOOK_URL"
DISCORD_USERNAME="${DISCORD_USERNAME:-$(_readaccountconf_mutable DISCORD_USERNAME)}"
if [ "$DISCORD_USERNAME" ]; then
_saveaccountconf_mutable DISCORD_USERNAME "$DISCORD_USERNAME"
fi
DISCORD_AVATAR_URL="${DISCORD_AVATAR_URL:-$(_readaccountconf_mutable DISCORD_AVATAR_URL)}"
if [ "$DISCORD_AVATAR_URL" ]; then
_saveaccountconf_mutable DISCORD_AVATAR_URL "$DISCORD_AVATAR_URL"
fi
export _H1="Content-Type: application/json"
_content="$(printf "**%s**\n%s" "$_subject" "$_content" | _json_encode)"
_data="{\"content\": \"$_content\" "
if [ "$DISCORD_USERNAME" ]; then
_data="$_data, \"username\": \"$DISCORD_USERNAME\" "
fi
if [ "$DISCORD_AVATAR_URL" ]; then
_data="$_data, \"avatar_url\": \"$DISCORD_AVATAR_URL\" "
fi
_data="$_data}"
if _post "$_data" "$DISCORD_WEBHOOK_URL?wait=true"; then
# shellcheck disable=SC2154
if [ "$response" ]; then
_info "discord send success."
return 0
fi
fi
_err "discord send error."
_err "$response"
return 1
}

45
notify/slack_app.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/usr/bin/env sh
#Support Slack APP notifications
#SLACK_APP_CHANNEL=""
#SLACK_APP_TOKEN=""
slack_app_send() {
_subject="$1"
_content="$2"
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
_debug "_statusCode" "$_statusCode"
SLACK_APP_CHANNEL="${SLACK_APP_CHANNEL:-$(_readaccountconf_mutable SLACK_APP_CHANNEL)}"
if [ -n "$SLACK_APP_CHANNEL" ]; then
_saveaccountconf_mutable SLACK_APP_CHANNEL "$SLACK_APP_CHANNEL"
fi
SLACK_APP_TOKEN="${SLACK_APP_TOKEN:-$(_readaccountconf_mutable SLACK_APP_TOKEN)}"
if [ -n "$SLACK_APP_TOKEN" ]; then
_saveaccountconf_mutable SLACK_APP_TOKEN "$SLACK_APP_TOKEN"
fi
_content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)"
_data="{\"text\": \"$_content\", "
if [ -n "$SLACK_APP_CHANNEL" ]; then
_data="$_data\"channel\": \"$SLACK_APP_CHANNEL\", "
fi
_data="$_data\"mrkdwn\": \"true\"}"
export _H1="Authorization: Bearer $SLACK_APP_TOKEN"
SLACK_APP_API_URL="https://slack.com/api/chat.postMessage"
if _post "$_data" "$SLACK_APP_API_URL" "" "POST" "application/json; charset=utf-8"; then
# shellcheck disable=SC2154
SLACK_APP_RESULT_OK=$(echo "$response" | _egrep_o 'ok" *: *true')
if [ "$?" = "0" ] && [ "$SLACK_APP_RESULT_OK" ]; then
_info "slack send success."
return 0
fi
fi
_err "slack send error."
_err "$response"
return 1
}

View File

@@ -169,7 +169,7 @@ _clean_email_header() {
# email
_email_has_display_name() {
_email="$1"
expr "$_email" : '^.*[<>"]' >/dev/null
echo "$_email" | grep -q -E '^.*[<>"]'
}
##
@@ -249,7 +249,7 @@ _mime_encoded_word() {
_text="$1"
# (regex character ranges like [a-z] can be locale-dependent; enumerate ASCII chars to avoid that)
_ascii='] $`"'"[!#%&'()*+,./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ~^_abcdefghijklmnopqrstuvwxyz{|}~-"
if expr "$_text" : "^.*[^$_ascii]" >/dev/null; then
if echo "$_text" | grep -q -E "^.*[^$_ascii]"; then
# At least one non-ASCII char; convert entire thing to encoded word
printf "%s" "=?UTF-8?B?$(printf "%s" "$_text" | _base64)?="
else

49
notify/weixin_work.sh Normal file
View File

@@ -0,0 +1,49 @@
#!/usr/bin/env sh
#Support weixin work webhooks api
#WEIXIN_WORK_WEBHOOK="xxxx"
#optional
#WEIXIN_WORK_KEYWORD="yyyy"
#`WEIXIN_WORK_SIGNING_KEY`="SEC08ffdbd403cbc3fc8a65xxxxxxxxxxxxxxxxxxxx"
# subject content statusCode
weixin_work_send() {
_subject="$1"
_content="$2"
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
_debug "_subject" "$_subject"
_debug "_content" "$_content"
_debug "_statusCode" "$_statusCode"
WEIXIN_WORK_WEBHOOK="${WEIXIN_WORK_WEBHOOK:-$(_readaccountconf_mutable WEIXIN_WORK_WEBHOOK)}"
if [ -z "$WEIXIN_WORK_WEBHOOK" ]; then
WEIXIN_WORK_WEBHOOK=""
_err "You didn't specify a weixin_work webhooks WEIXIN_WORK_WEBHOOK yet."
_err "You can get yours from https://work.weixin.qq.com/api/doc/90000/90136/91770"
return 1
fi
_saveaccountconf_mutable WEIXIN_WORK_WEBHOOK "$WEIXIN_WORK_WEBHOOK"
WEIXIN_WORK_KEYWORD="${WEIXIN_WORK_KEYWORD:-$(_readaccountconf_mutable WEIXIN_WORK_KEYWORD)}"
if [ "$WEIXIN_WORK_KEYWORD" ]; then
_saveaccountconf_mutable WEIXIN_WORK_KEYWORD "$WEIXIN_WORK_KEYWORD"
fi
_content=$(echo "$_content" | _json_encode)
_subject=$(echo "$_subject" | _json_encode)
_data="{\"msgtype\": \"text\", \"text\": {\"content\": \"[$WEIXIN_WORK_KEYWORD]\n$_subject\n$_content\"}}"
response="$(_post "$_data" "$WEIXIN_WORK_WEBHOOK" "" "POST" "application/json")"
if [ "$?" = "0" ] && _contains "$response" "errmsg\":\"ok"; then
_info "weixin_work webhooks event fired success."
return 0
fi
_err "weixin_work webhooks event fired error."
_err "$response"
return 1
}