Compare commits

...
1920 Commits
Author SHA1 Message Date
neil 76d1377fc1 Merge pull request #6934 from acmesh-official/dev
sync
2026-04-28 22:22:24 +02:00
neil 15a0f52577 fix https://github.com/acmesh-official/acme.sh/issues/6930#issuecomment-4327834577 2026-04-28 09:09:50 +02:00
Adam Bodnar fd6ff7b173 Add dns_cpanel_uapi DNS API plugin (#6878)
* Add dns_cpanel_uapi.sh
2026-04-26 14:29:40 +02:00
neil ed6d1f3447 Merge pull request #6929 from acmesh-official/dev
sync
2026-04-24 23:30:42 +02:00
neil 0b2187ab3f add MidnightBSD 2026-04-24 22:43:25 +02:00
neil 4b8b23bb90 fix ca name 2026-04-24 21:47:27 +02:00
neil d00b2722ee Merge pull request #6889 from achmadalifn4/dev
Add BytePlus ALB deployment script
2026-04-24 21:46:10 +02:00
neil df49dd2ec9 Merge pull request #6928 from acmesh-official/dev
sync
2026-04-24 21:36:58 +02:00
Achmad Alif Nasrulloh e9b0cafac5 Fix byteplus_alb.sh 2026-04-24 11:21:43 +07:00
Antoni Company 9882d534af fix: commit overhaul (#6915)
- Removed scope exclusion for "standard commit".
  - If 'device-and-networks' is excluded (previous behaviour), a certificate for Panorama (always outside of a template) will not be committed (imported to the config but never applied to Panorama). Therefore, panos.sh was only working for certificates used in templates and applied to devices, but not for the Panorama certificate itself.
  - According to the official documentation and the XML API Browser, there is no 'policy-and-objects' that can be excluded.
  - Although it is not mandatory that the user account is solely dedicated to replace certificates and to perform no other type of operations, it is recommended. If such recommendation is applied, the only changes being committed would be in relation to certificates. Therefore, it should be safe not to exclude any scopes.
- Changed the order for "force commit" from '<commit><partial><force>' (unofficial) to '<commit><force><partial>' (official). Both work, but it is recommended to use what is part of the official documentation and/or XML API Browser.
- Removed unofficial 'policy-and-objects' from commented out code (see above).
- Replaced 'exclude' with 'excluded' from commented out code, as per the official documentation. Both work, but see above.
- Replaced 'acmekeytest' with $_panos_user in the commented out code.

Official documentation: https://docs.paloaltonetworks.com/ngfw/api/pan-os-xml-api-request-types-and-actions/commit
XML API Browser: https://<PANOS HOST>/api
2026-04-20 11:28:17 +02:00
neil 539b46adc9 fix https://github.com/acmesh-official/acme.sh/issues/6898#issuecomment-4207794240 2026-04-14 21:19:25 +08:00
ACHMAD ALIF NASRULLOH f89a9a5de3 Add new header variable _H5 in byteplus_alb.sh
Added a new header variable _H5 to the byteplus_alb.sh script.
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot 00090d24b8 Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot 73a682e561 Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot a1b94db94d Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot 5c94af86f3 Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot 3843495397 Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot a739bf3e3a Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
Achmad Alif Nasrulloh 75642a1252 Update bteplus_alb.sh 2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot 668427f285 Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot d0e123cb02 Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot 8587c3e744 Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot 934870fc77 Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot 8eea7ca307 Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot 28f1f07f49 Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot ad71a785ec Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot d5c8060a65 Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot 4178c33524 Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot 044371b00a Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOHandCopilot 86d98b0461 Update deploy/byteplus_alb.sh
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 21:04:48 +08:00
ACHMAD ALIF NASRULLOH 6efd6d5b5a Add BytePlus ALB deployment script
This script deploys SSL/TLS certificates issued by acme.sh to BytePlus Application Load Balancer (ALB), supporting automatic renewal with zero-downtime certificate rotation.
2026-04-14 21:04:48 +08:00
GNDevProd 454cec6e43 Add Gname.com dnsapi support (#6808)
* add gname dns acme.sh
2026-04-14 20:57:22 +08:00
wangzhizhou afba1455b8 add dnsapi for baidu cloud dns (#6844) 2026-04-14 20:44:30 +08:00
Mitchell van Bijleveld f3e61a8ef4 Don't mark restart http as failed if json returns false because it was not restarted (#6906) 2026-04-14 20:37:50 +08:00
neil 0894955895 fix https://github.com/acmesh-official/acme.sh/pull/6731#issuecomment-3733144962 2026-04-08 22:33:30 +08:00
breviloandOliver Behnke 5b5ef91d88 Fix off-by-one error preventing the final poll to succeed (#6865)
When the final poll (`_link_cert_retry` at 29) returns, the status
is never checked again. So even a `valid` status goes unnoticed.
It's a pre-test loop after all.

Co-authored-by: Oliver Behnke <oliver.behnke@aei.mpg.de>
2026-04-08 22:18:26 +08:00
Jordan RussellandJordan Russell 618735d11e [dnsapi] add SiteHost DNS API hook (#6891)
Co-authored-by: Jordan Russell <jordan.russell@sitehost.co.nz>
2026-04-08 22:07:30 +08:00
Lorenz Stechauner 08b2186afe dns_world4you: Adapt to latest record id changes (#6897) 2026-04-08 22:00:42 +08:00
Stefan Bottelier 3509f6404f Add bHosted.nl DNS API (#6864)
Add bHosted.nl DNS API (#6864)
2026-04-08 21:59:09 +08:00
neil 50dbdd781b fix DEFAULT_RENEW
fix https://github.com/acmesh-official/acme.sh/issues/2217#issuecomment-4155894630
2026-04-05 10:46:29 +08:00
neil 346acc3f33 Update copilot-instructions.md 2026-04-05 10:40:35 +08:00
neil a79bdb9ef3 Merge branch 'dev' of https://github.com/acmesh-official/acme.sh into dev 2026-04-04 22:24:13 +08:00
neil 563415d21f Merge pull request #6895 from acmesh-official/dev
sync
2026-04-04 21:19:05 +08:00
neil c2c5c3cdb7 Update copilot-instructions.md 2026-04-04 21:18:36 +08:00
neil 4aeb7bbab0 fix rule 2026-04-04 21:18:36 +08:00
orangepizza 12f639116c Update copilot instruction to match actual PR rule (#6873)
old version had instruction to use bash-only [[ ]] test, remove it and add rules for DNS script writing from https://github.com/acmesh-official/acme.sh/issues/343
2026-04-04 21:18:36 +08:00
Tomáš Pavlič 4cb1c6e1ea [dnsapi] add subreg.cz dns hook (#6848)
* Add DNS hook for subreg.cz
2026-04-04 21:18:36 +08:00
heximcz 9aad08ef14 Add BEST-HOSTING DNS API (#6859)
* Add BEST-HOSTING DNS API
2026-04-04 21:18:36 +08:00
neil 3b503a009c fix https://github.com/acmesh-official/acme.sh/issues/4924#issuecomment-4069887654 2026-04-04 21:18:36 +08:00
neil 13d6496653 fix https://github.com/acmesh-official/acme.sh/issues/6866#issuecomment-4080403721 2026-04-04 21:18:36 +08:00
neil 605299947e format 2026-04-04 21:18:36 +08:00
neil d050f3458b don't switch from test back to production ca 2026-04-04 21:18:36 +08:00
CZECHIA-COM d66264e741 Add dns_czechia DNS API plugin (#6764)
* Create dns_czechia.sh

This PR adds a DNS API plugin for CZECHIA.COM / RegZone (ZONER a.s.).
2026-04-04 21:18:36 +08:00
neil cf9c70a6c7 Update copilot-instructions.md 2026-04-04 21:16:40 +08:00
Florian Heigl ef49a9fd23 Update synology_dsm.sh (#6894)
quote variable name so message isn't missing the variable that needs to be fixed.
this was reported in #2727  (feedback for hook)
2026-04-03 11:38:21 +08:00
neil fe5d2e3ef7 fix rule 2026-04-03 11:33:05 +08:00
orangepizza bf486bb988 Update copilot instruction to match actual PR rule (#6873)
old version had instruction to use bash-only [[ ]] test, remove it and add rules for DNS script writing from https://github.com/acmesh-official/acme.sh/issues/343
2026-03-28 09:26:47 +08:00
Tomáš Pavlič 3c8c735362 [dnsapi] add subreg.cz dns hook (#6848)
* Add DNS hook for subreg.cz
2026-03-22 11:40:44 +08:00
heximcz c397bd6573 Add BEST-HOSTING DNS API (#6859)
* Add BEST-HOSTING DNS API
2026-03-22 11:36:29 +08:00
neil e26ce2f19c fix https://github.com/acmesh-official/acme.sh/issues/4924#issuecomment-4069887654 2026-03-21 13:02:16 +08:00
neil af5e592fe4 fix https://github.com/acmesh-official/acme.sh/issues/6866#issuecomment-4080403721 2026-03-21 10:47:11 +08:00
neil e21be4455f format 2026-03-21 10:41:58 +08:00
neil 5842e6ff4f don't switch from test back to production ca 2026-03-21 10:40:10 +08:00
CZECHIA-COM 8aea731bd4 Add dns_czechia DNS API plugin (#6764)
* Create dns_czechia.sh

This PR adds a DNS API plugin for CZECHIA.COM / RegZone (ZONER a.s.).
2026-03-16 20:17:18 +08:00
neil 5d158b1640 Merge pull request #6857 from acmesh-official/dev
sync
2026-03-13 20:19:12 +08:00
neil 3198c1af6e fix https://github.com/acmesh-official/acme.sh/issues/6856#issuecomment-4054175916 2026-03-13 20:10:22 +08:00
neil fc8a61f10f update 2026-03-13 18:41:02 +08:00
neil d08b4de794 Merge pull request #6832 from acmesh-official/dev
sync
2026-03-08 18:51:51 +08:00
neil cc677ba9f1 minor 2026-03-08 18:43:39 +08:00
Ludwig 03860a4978 dnsapi/dns_me: ignore "already exists" error for multi-domain support (#6830) 2026-03-08 18:37:29 +08:00
neil da5e818907 Merge pull request #6796 from Tra5is/add_technitium_expiry_ttl
Add Expiry TTL option for Technitium DNS API
2026-03-04 15:17:02 +08:00
Travis f0146bd90e shfmt edit 2026-03-03 05:31:51 -08:00
Tra5is 20722ea030 Merge branch 'dev' into add_technitium_expiry_ttl 2026-03-03 04:59:54 -08:00
neil fdd2e4f19a add copilot 2026-03-01 13:13:07 +08:00
neil 89c86efc56 Merge pull request #6793 from ecm75/fix_kemplm
fixed checking for existing domain on loadmaster
2026-02-23 19:37:06 +08:00
Eike-Christian Müller 8ca1c83b95 Fixed missing error return value when certificate upload fails. 2026-02-23 09:24:06 +01:00
neil 8304d3e323 Merge pull request #6800 from pgerber/ipv6-debug
Fix IPv6 URL when trying to fetch challenge ourselves for debugging
2026-02-22 22:35:25 +08:00
Peter Gerber b5bfd08e35 Fix IPv6 URL when trying to fetch challenge ourselves for debugging
Fixes the following error when debugging is enabled:

[Sat Feb 21 04:00:22 CET 2026] Here is the curl dump log:
[Sat Feb 21 04:00:22 CET 2026] * URL rejected: Port number was not a decimal number between 0 and 65535
* closing connection #-1

IPv6 addresses in URLs need to be written like this:

    http://[2001:43:5::250]
2026-02-21 04:03:41 +00:00
Travis 70f9e255d3 Add Expiry TTL option for Technitium DNS API 2026-02-18 09:29:47 -08:00
neil 12f147bf40 Merge pull request #6794 from infinitydev/pvefix
Add error check to Proxmox deploy hooks
2026-02-18 12:14:52 +08:00
infinitydev bef0fdb1ae check Proxmox Backup Server API response for errors 2026-02-17 19:28:25 +01:00
infinitydev 020a4bb5b3 check Proxmox VE API response for errors 2026-02-17 12:12:17 +00:00
emueller acaaca89ab fixed checking for existing domain on loadmaster 2026-02-17 11:03:53 +01:00
neil bdfa988b65 Merge pull request #6436 from invario/localcopy-deploy-hook
Add 'localcopy' deploy-hook
2026-02-14 11:01:40 +08:00
neil 0e93d2bee1 Merge pull request #6786 from alexandergott-afk/dev
Allow more than one DNS server for HA environments #6785
2026-02-13 11:13:50 +08:00
alexandergott-afk 83424e7ba4 Add the information from my last accepted pull that the TSIG key is optional. 2026-02-12 15:32:53 +01:00
alexandergott-afk 5bc44caf50 Allow more than one DNS server for HA environments 2026-02-12 15:27:23 +01:00
alexandergott-afk 47412d1822 Update dns_nsupdate.sh 2026-02-12 15:24:45 +01:00
neil f68a758974 Merge pull request #6775 from alexandergott-afk/master
Add some fixes for dns_nsupdate provider
2026-02-09 20:16:49 +08:00
alexandergott-afk fb4ae10e08 Merge branch 'dev' into master 2026-02-09 10:45:31 +01:00
neil 824e7b3d80 Merge pull request #6709 from invario/docker-non-root-supercronic
Docker with non-root using supercronic
2026-02-09 17:43:28 +08:00
alexandergott-afk 34052e56d7 too many spaces removed 2026-02-09 10:39:27 +01:00
alexandergott-afk 3374c22169 Merge branch 'dev' into master 2026-02-09 10:03:58 +01:00
alexandergott-afk 4807df0c3e Fix Tab 2026-02-09 10:03:26 +01:00
neil b79146281c Merge pull request #6767 from dga-nagra/panos-api-key
Fix bug + Allow panos deploy-hook to use PANOS_KEY
2026-02-07 22:15:28 +08:00
neil ab3093d58c Merge pull request #6472 from UncleVic/master
feat: #6471 add message_thread_id to telegram notifications
2026-02-07 22:11:42 +08:00
neil c21db5c5d5 Change shebang to use env for portability 2026-02-07 22:10:48 +08:00
alexandergott-afk ec0dc40ad8 Merge branch 'dev' into master 2026-02-05 10:39:19 +01:00
alexandergott-afk 7236ba2d7c Update dns_nsupdate.sh 2026-02-05 09:20:51 +01:00
alexandergott-afk b440e49164 Update dns_nsupdate.sh 2026-02-05 09:14:18 +01:00
neil 80e39eb63c Merge pull request #6687 from kapouer/ssh-noscp-permissions
Ssh noscp permissions
2026-02-04 18:49:52 +08:00
dga-nagra 61e986f23c Conditionnaly change permissions (#1) 2026-02-04 11:01:44 +01:00
David Gallay 6a60695549 Allowing panos deploy-hook to only depend on PANOS_KEY.
Previous version add bugs that were not properly using the _api_key.

It also enforced to provide PANOS_USER and PANOS_PASSWORD which can be very constraining.

PANOS_KEY now has precedence. If not provided, the script falls back to PANOS_USER and PANOS_PASSWORD.
2026-02-03 10:51:42 +01:00
neil 28c088611a Merge pull request #6440 from jf-lines/dns_infomaniak_API_v2
dns_infomaniak: upgraded to API v2. v1 is deprecated.
2026-02-01 17:15:02 +01:00
JF DAGUIN 274fd53c83 Merge branch 'dev' into dns_infomaniak_API_v2 2026-01-30 23:08:17 +01:00
JF DAGUIN a4595f334e Merge branch 'acmesh-official:master' into dns_infomaniak_API_v2 2026-01-30 23:04:36 +01:00
JF DAGUIN 477277bd2d Rewrite token scope and URL to add one
Updated comments for clarity and formatting.
2026-01-30 23:00:25 +01:00
neil d8053ed6b2 Merge pull request #6760 from OpusDNS/add-opusdns-provider
[CLOUD-31] Add acme.sh OpusDNS provider
2026-01-24 07:51:13 +01:00
neil e44809c180 Update acme.sh 2026-01-24 07:49:18 +01:00
Kilian Ries 9c245eb37a fix: start zone detection from i=1 per acme.sh convention 2026-01-23 09:20:00 +01:00
Kilian Ries 713251c65b Merge branch 'dev' into add-opusdns-provider 2026-01-22 18:34:04 +01:00
Kilian Ries 2e85e6f9bb Fix zone detection: check for dnssec_status instead of name
The error response also contains 'name' in 'zone_name' field,
causing false positives. Check for 'dnssec_status' which only
exists in valid zone responses.
2026-01-22 18:13:51 +01:00
Kilian Ries 9e584e346d Refactor: Add _opusdns_api helper, simplify code
- Added _opusdns_api() for all API requests
- Added _opusdns_init() for config initialization
- Removed duplicate code in add/rm functions
- Removed dead code (orphaned lines 173-178)
- Script now 158 lines (was 255, originally 379)
2026-01-22 18:13:09 +01:00
Kilian Ries 163eb1acb9 Simplify zone detection with API check
Instead of fetching all zones and matching, iterate through domain
parts and check each against the API until a valid zone is found.
Same approach as GoDaddy DNS plugin.

Example: _acme-challenge.test.example.com
- Try: test.example.com → 404
- Try: example.com → 200 ✓ → zone found!

Script reduced from 304 to 255 lines.
2026-01-22 18:11:01 +01:00
Kilian Ries 25a3ee48df Fix zone pagination parsing
- Fixed jq path: .pagination.has_next_page instead of .has_next_page
- Fixed grep fallback: remove rrsets before extracting zone names
  to avoid matching nested 'name' fields
- Simplified has_next_page detection with simple grep -q
- Added debug output for page zones and has_next status
2026-01-22 17:58:09 +01:00
Kilian Ries 30c9332327 Remove custom DNS propagation check
acme.sh handles DNS propagation checking internally via --dnssleep
and _check_dns_record. Custom propagation checks are unnecessary
and can conflict with acme.sh's own timing.

Removed:
- _opusdns_wait_for_propagation() function
- OPUSDNS_Polling_Interval option
- OPUSDNS_Propagation_Timeout option

Script is now consistent with other DNS API implementations
(Cloudflare, AWS, etc.) which don't have custom propagation checks.
2026-01-22 17:28:41 +01:00
Kilian Ries dc65223da1 Remove all trailing whitespace for shfmt compliance 2026-01-22 17:10:12 +01:00
Kilian Ries 01c93b9bbd Fix shellcheck and shfmt issues
- Add double quotes around variables to prevent globbing
- Fix parameter expansion quoting in ${domain%.${_zone}}
- Remove trailing whitespace for shfmt compliance
2026-01-22 17:04:43 +01:00
Kilian Ries b4ac517c7b Trigger DNS workflow for OpusDNS testing 2026-01-22 16:58:09 +01:00
Kilian Ries bfd1f9bf6c [CLOUD-31] add acme.sh opusdns provider 2026-01-22 16:43:26 +01:00
neil 0cef5edac2 fix https://github.com/acmesh-official/acme.sh/issues/6196#issuecomment-3777530678 2026-01-21 20:00:27 +01:00
neil 8c384a92bf Merge pull request #6755 from zbindenp/master
Fix dns_cyon to use correct regex
2026-01-18 14:30:53 +01:00
neil ce2d9e9746 Merge pull request #6485 from Fangliding/master
Fix ipv6 cert cannot be found
2026-01-18 14:29:33 +01:00
Patrick Zbinden 282b048557 Fix dns_cyon to use correct regex 2026-01-14 21:05:32 +01:00
neil f39d066ced Merge pull request #6754 from acmesh-official/dev
sync
2026-01-13 21:50:14 +01:00
neil e2882c536b disable notifications for myself
disable notifications for myself
2026-01-13 21:43:46 +01:00
neil 892b3ca219 fix account.conf permission
https://github.com/acmesh-official/acme.sh/issues/6708#issuecomment-3745737079
2026-01-13 21:28:14 +01:00
neil 4de00d4603 Merge pull request #6748 from acmesh-official/dev
sync
2026-01-11 21:50:00 +01:00
neil 40b29c1879 support Haiku OS 2026-01-11 21:37:02 +01:00
neil d57ab0ab7d fix haiku 2026-01-11 21:28:45 +01:00
neil d8c062defb fix haiku 2026-01-11 21:21:08 +01:00
neil 3e36b61823 fix haiku 2026-01-11 21:14:29 +01:00
neil 09009794e0 fix 2026-01-11 21:10:37 +01:00
neil 5e670e0d93 support haiku 2026-01-11 21:02:57 +01:00
neil bc646d120e Merge pull request #6746 from d-kurz/dev
dns_dynv6: Allow challenge strings that contain "id"
2026-01-10 12:54:47 +01:00
neil c58da45917 Merge pull request #6678 from fratoro/master
Update dns_cyon to use unique user-agent and all cookies
2026-01-10 12:52:24 +01:00
Denis Kurz b37867d027 remove unused code 2026-01-10 01:44:07 +01:00
Denis Kurz 880d93f7f7 fix(dynv6): allow 'id' in dns challenge
If the random dns challenge string happens to contain 'id',
the parsing method passed a broken, mingled mix of the
record's data and id field, instead of just the id. As a result,
deleting the TXT record failed. We now specifically look for
'"id":', which cannot appear as part of the challenge string.
2026-01-10 01:44:07 +01:00
Denis Kurz 5ad2bea129 fix typos 2026-01-10 01:44:07 +01:00
neil 9e51432a6f Merge pull request #6745 from acmesh-official/dev
sync
2026-01-06 08:55:01 +01:00
neil 903a53991d fix bugs 2026-01-05 22:06:43 +01:00
neil 188aa515ce Merge pull request #6724 from h-haaks/base64-encode-pfx-password
Base64 encode pfx password
2026-01-05 21:46:34 +01:00
neil 6a9776b1f0 Merge pull request #6631 from rperper/dev
QUIC.cloud DNS API support (dns_api.sh)
2026-01-05 21:42:13 +01:00
neil 2092d6061b fix https://github.com/acmesh-official/acme.sh/issues/6736#issuecomment-3707981300 2026-01-05 21:38:37 +01:00
neil 35f99c545c add debug wiki 2026-01-05 21:11:07 +01:00
neil 4b278dc1bb Merge pull request #6735 from JensSpanier/dev
Pushover: Remove asterisks
2026-01-05 20:54:00 +01:00
neil 9bf5179b55 Merge pull request #6739 from moaminsharifi/master
Add Virakcloud dns api
2026-01-05 20:51:43 +01:00
Amin Sharifi ca94221d08 Merge branch 'dev' into master 2026-01-04 18:26:04 +03:30
Amin Sharifi 70462b5ac3 run ~/shfmt -l -w -i 2 dnsapi/dns_virakcloud.sh and Remove unnecessary blank lines in dns_virakcloud.sh 2026-01-04 16:33:37 +03:30
Amin Sharifi ef035248c3 Add VirakCloud DNS API support 2026-01-04 16:29:30 +03:30
Amin Sharifi 877cbe04c9 Add VirakCloud DNS API support with add and remove TXT record functions 2026-01-04 16:18:18 +03:30
Jens Spanier 94c670a759 Remove asterisks and line breaks 2026-01-04 11:49:35 +01:00
neil 045e4dee2e use openindiana-vm@v1 2026-01-02 16:24:06 +01:00
neil 06d9ca61a3 Merge pull request #6728 from jwaterwater/feat/qiniu-force-https-config
Feat/qiniu force https config
2026-01-02 15:36:09 +01:00
neil dc6a996cc3 Merge pull request #6731 from jdevera/posix_globs_for_list
Fix `--list` regression in POSIX / Docker environments
2026-01-02 15:34:27 +01:00
Jacobo de Vera b08bb2ef69 Fix list command for POSIX sh by avoiding brace expansion 2026-01-02 12:16:46 +00:00
风扇滑翔翼 64ac537e72 Merge branch 'dev' into master 2026-01-02 14:52:10 +08:00
风扇滑翔翼 ef2089ceb1 Update directory iteration pattern in acme.sh 2026-01-02 14:48:11 +08:00
Your Name 2ad984d8ad feat(qiniu): make forceHttps configurable via environment variable
Add QINIU_FORCE_HTTPS environment variable (default: false) to allow
configuring HTTPS redirect behavior for CDN domains.
2026-01-01 13:26:02 +00:00
Bob Perper 6a37f23b14 Ran shfmt locally 2025-12-30 16:31:16 -05:00
Bob Perper cf2f9ef251 Missed additional quotes 2025-12-30 16:27:21 -05:00
Bob Perper f9ffdbe407 Initialize record_id 2025-12-30 16:23:01 -05:00
Bob Perper 778b4a38ed Missed several double quote issues 2025-12-30 16:17:03 -05:00
Bob Perper 397c0605e5 Double quote for globbing 2025-12-30 16:11:39 -05:00
Bob Perper b4f30ff026 Updated for shfmt 2025-12-30 16:07:01 -05:00
Bob Perper 0b66acf332 shfmt fixes 2025-12-30 15:54:23 -05:00
Bob Perper 185d92f1e7 shfmt fixes 2025-12-30 15:50:39 -05:00
Bob Perper e031457cfa shfmt fixes 2025-12-30 15:48:29 -05:00
Bob Perper 162cfebbbb Removed jq requirement 2025-12-30 15:36:06 -05:00
Bob Perper 66ef351f36 Merge branch 'dev' of https://github.com/rperper/acme.sh into dev 2025-12-30 15:35:23 -05:00
invario 6a98b9f81e chown /acme.sh to non-root user and set HOME to /acme.sh
Signed-off-by: invario <67800603+invario@users.noreply.github.com>
2025-12-30 12:44:46 -05:00
invario 4219f7b2f6 align logic to acme.sh installcert(), fix perms on non-key files
Signed-off-by: invario <67800603+invario@users.noreply.github.com>
2025-12-30 11:41:50 -05:00
jwaterwater e260b86414 Merge branch 'acmesh-official:master' into master 2025-12-30 21:48:28 +08:00
Hugo Haakseth 21d52b5995 Store pfx password base64 encoded 2025-12-30 10:57:12 +01:00
invarioandKevin Hoser e03f8d3ad6 fix: savedeployconf for DEPLOY_LOCALCOPY_CERTIFICATE
Co-authored-by: Kevin Hoser <45083826+hoser21@users.noreply.github.com>
2025-12-28 12:03:02 -05:00
invario 6f5a0c5d5e have entry.sh (instead of dockerfile) generate crontab file
Signed-off-by: invario <67800603+invario@users.noreply.github.com>
2025-12-28 11:40:18 -05:00
invario 57db388932 Docker with non-root using supercronic
Replaces cronie with supercronic to allow non-root users to have
cronjobs. Creates user/group acme:acme UID:1000/GID:1000 with
home directory pointing to LE_CONFIG_HOME (default: /acme.sh)
'crontab' is generated in LE_CONFIG_HOME which is used by
supercronic.

Note that `acme.sh --installcronjob` and `--uninstallcronjob`
when run as a non-root user will fail but neither of should be
used in `daemon` mode anyway.

Signed-off-by: invario <67800603+invario@users.noreply.github.com>
2025-12-28 11:39:59 -05:00
neil d795cb4850 Merge pull request #6717 from acmesh-official/ari
Ari
2025-12-27 12:29:55 +01:00
neil 1bd2922bc3 Merge pull request #6716 from acmesh-official/dev
sync
2025-12-27 11:49:21 +01:00
neil 47f24126f5 Update supported OS table in README
add openindiana
2025-12-27 11:47:16 +01:00
neil 76fdac59bc Add OpenIndiana CI workflow and badge
Introduced a new OpenIndiana job to the DNS GitHub Actions workflow for testing, including necessary environment variables and steps. Updated README to display the OpenIndiana workflow status badge.
2025-12-27 11:41:58 +01:00
neil 49a3d586a3 Add OpenIndiana CI workflow
Introduces a GitHub Actions workflow for OpenIndiana to automate testing of shell scripts.
2025-12-27 11:37:39 +01:00
neil 361e7c5ad4 use nfs for vms
use nfs for vms
2025-12-27 11:26:59 +01:00
neil 3ae9711892 Merge pull request #6715 from acmesh-official/dev
sync
2025-12-27 11:22:22 +01:00
neil fc7168e11d change default renew to 30 days
change default renew to 30 days
and fix readme
2025-12-27 11:20:22 +01:00
neil 260df0048b Merge pull request #6241 from tomo2403/multideploy-yaml
Multideploy: Deploy to multiple hooks of the same type
2025-12-27 11:04:17 +01:00
invario 11cae37405 make compatible with both yq versions
kislyuk yq (used by Debian packages) does not accept `yq e` and
also returns strings with double quotes.

mikefarah's yq-go (used by Alpine) accepts `yq e` and `yq`.

replace `yq e` with `yq` and also use `-r` switch to remove double
quoting to ensure uniform return values from both yq versions.

Signed-off-by: invario <67800603+invario@users.noreply.github.com>
2025-12-27 11:02:40 +01:00
tomo 61b59831c4 minor code style adjustments in multideploy script 2025-12-27 11:02:40 +01:00
Jacobo de Vera 96f38655b4 Use file descriptor 3 for main deployment loop
Before this, some deployment scripts would interact with STDIN and that would cause this loop to skip some elements. By using descriptor 3 we avoid clashing with the very common stdin and stdout.
2025-12-27 11:02:40 +01:00
Jacobo de Vera ab7835ec58 Fix eval bug by quoting
Before this, the eval call would try to run some commands (if they were compound commands) in the yaml file on the machine running acme.sh

Eval might not be worth it for the little benefit it brings.
2025-12-27 11:02:40 +01:00
Jacobo de Vera b8b1f1e9b4 Remove config logging when checking
Because it causes a mysterious crash and it's honestly not worth it.
2025-12-27 11:02:40 +01:00
Jacobo de Vera 6b66e734a9 Remove explicit save of the deployhook
acme.sh takes care of that
2025-12-27 11:02:40 +01:00
Jacobo de Vera 4f0a4850a6 Remove unnecessary resetting of IFS 2025-12-27 11:02:40 +01:00
Jacobo de Vera 8a78865174 Quote paths to prevent word splitting 2025-12-27 11:02:40 +01:00
Jacobo de Vera 69dd2cf78b Explain _clear_envs rationale 2025-12-27 11:02:40 +01:00
Jacobo de Vera a961e03a59 Explain the use of eval 2025-12-27 11:02:40 +01:00
Jacobo de Vera 1eee4dee9c Update dependency name from yq to yq-go 2025-12-27 11:02:40 +01:00
Jacobo de Vera 1d8788767f Make failure to check file stop the deployment
Before this, checker issues were only logged. This stops the deployment if any configuration is incorrect.
2025-12-27 11:02:40 +01:00
Jacobo de Vera 986a6138eb Fix config file checks
The config file checks were returning okay even when there were errors. The yq tool returns "null" when it cannot find what's queried, but exists with a 0 rc still.
2025-12-27 11:02:40 +01:00
Jacobo de Vera f850e8d0e4 Support spaces in service names
- Prefer using a pipe to `while read`
- But use a temp file when the loop needs to modify variables that need to be used outside the loop, as the pipe creates a subshell and modifications do not survive after the loop exits.
2025-12-27 11:02:40 +01:00
tomo d375012c5d fixed yml file env list 2025-12-27 11:02:40 +01:00
tomo 37c25aa107 removed unneeded return value 2025-12-27 11:02:40 +01:00
tomo 7b16526e7f removed dead code 2025-12-27 11:02:40 +01:00
tomo 093f36b4d6 implemented exiting with the number of failed deployments 2025-12-27 11:02:40 +01:00
tomo e5b47f6402 implemented exiting with 1 if at least one deployment fails 2025-12-27 11:02:40 +01:00
tomo a55d40be97 fixed bug with envs due to the use of a wrong function 2025-12-27 11:02:40 +01:00
tomo c1c49d5a01 simplified deploy method 2025-12-27 11:02:40 +01:00
tomo 88e4d64c1a fixed IFS problems for some hooks 2025-12-27 11:02:40 +01:00
tomo 17e0bbcbb6 fixed formatting 2025-12-27 11:02:40 +01:00
tomo 95c7546051 removed configs and implemented specification of deploy file name 2025-12-27 11:02:40 +01:00
tomo c1e17c366f Update links in multideploy.sh 2025-12-27 11:02:40 +01:00
tomo 88cde7be6d fixed missing wiki link 2025-12-27 11:02:40 +01:00
tomo c16e059535 allowed using varaibles in deploy file 2025-12-27 11:02:40 +01:00
tomo 88d4637ee3 added header doc 2025-12-27 11:02:40 +01:00
tomo 74ed0354a3 added docs and enhanced log messages 2025-12-27 11:02:40 +01:00
tomo 2cc5e66517 added docs 2025-12-27 11:02:40 +01:00
tomo ba7c368ee5 fixed IFS problems 2025-12-27 11:02:40 +01:00
tomo 768de270bf improved preprocessing and fixed bug with wrong param of services 2025-12-27 11:02:40 +01:00
tomo db1dc4de0d added debug messages 2025-12-27 11:02:40 +01:00
tomo fb0926dc81 implemented checking for different kinds of deploy file 2025-12-27 11:02:40 +01:00
tomo 34eb2a655a added yq to dockerfile 2025-12-27 11:02:40 +01:00
tomo 23e1a53ec8 implemented deploying to services 2025-12-27 11:02:40 +01:00
tomo 67d58a12e7 implemented handling envs 2025-12-27 11:02:40 +01:00
tomo 0ed5e21232 fixed formatting and private var names 2025-12-27 11:02:40 +01:00
tomo b2eb1d2bbc refactored getting services 2025-12-27 11:02:40 +01:00
tomo 3c184486c3 fixed indents 2025-12-27 11:02:40 +01:00
tomo 5a730bf00d implemented checking deploy file 2025-12-27 11:02:40 +01:00
neil cbd5dae3b4 Merge pull request #6714 from xiagw/fix-ali-cdn-timestamp
fix: update timestamp variable for ali CDN and DCDN SSL certificate queries
2025-12-27 11:00:06 +01:00
xiagw b9c877adb9 fix: update timestamp variable for CDN and DCDN SSL certificate queries 2025-12-27 14:33:03 +08:00
neil d24c7e977e Merge pull request #6697 from sergiustheblack/fix/strongswan
Fix strongswan deploy hook
2025-12-25 13:39:05 +01:00
neil 6a1ff1c0a6 Merge pull request #6710 from erfantkerfan/dev
improve: change sotoon api to v2.1 with simplification
2025-12-25 13:36:06 +01:00
jwaterwater 10126410b6 Merge branch 'dev' into master 2025-12-25 15:09:08 +08:00
jwaterwater f4a575fee1 bug fixed 2025-12-25 14:48:44 +08:00
Erfan Gholizade 383557df61 improve: change sotoon api to v2.1 with simplification 2025-12-24 17:19:17 +03:30
neil dba4be8065 Merge pull request #6696 from taoso/dev
Support list IPv6 address certificate
2025-12-23 21:42:01 +01:00
Bob Perper f1aac43f0f Retry for workflow 2025-12-23 09:10:49 -05:00
Bob Perper 94783f46ad Retry to pass workflow 2025-12-23 07:53:33 -05:00
Bob Perper 1d26d4fc91 Detect missing jq 2025-12-22 16:42:26 -05:00
Bob Perper 7fc45226da Merge branch 'acmesh-official:dev' into dev 2025-12-22 16:38:10 -05:00
neil a670c07caf Merge pull request #6692 from as-kholin/omglol_202512
Minor updates to the Omg.lol DNS API
2025-12-22 20:09:23 +01:00
neil 09cc2bdfa5 Merge pull request #6690 from flybyray/issue6688
inwx API change
2025-12-22 20:06:16 +01:00
neil cc897cab4c Merge pull request #6655 from hostup/dev
Add: Hostup DNS provider
2025-12-22 19:48:07 +01:00
neil 7ba9597928 Merge pull request #6659 from erfantkerfan/master
Added Sotoon dns api
2025-12-22 19:42:12 +01:00
neil d2d862420e Merge pull request #6705 from mq00fc/dev
Fix ali-cdn deploy hook
2025-12-22 19:41:00 +01:00
DreamSlave fd6a14de8a Update timestamp function in ali_dcdn.sh 2025-12-22 17:00:31 +08:00
DreamSlave 0eb40c6ce6 Update timestamp variable in ali_cdn.sh 2025-12-22 17:00:22 +08:00
hostup e321b3c75c Update dns_hostup.sh 2025-12-22 04:53:21 +01:00
hostup 03d8d3bc1b Update dns_hostup.sh 2025-12-22 04:29:50 +01:00
Erfan Gholizade f85de2b0d3 Added Sotoon dns api
handle the case of metadata 404 in old api domains

fix index of domain start

fix shfmt

Revert "handle the case of metadata 404 in old api domains"

This reverts commit 9fe4616664b897c9891271006e7489b10bb818ca.

fix 404 on dot ad hyphen

fix shfmt
2025-12-21 11:50:13 +03:30
Robert Rettig 5fb42b7339 remove prior additions which tried to use oathtool in tests 2025-12-20 14:53:01 +01:00
Robert Rettig 1b2630dc0d stop using oathtool 2025-12-20 13:26:38 +01:00
海涛 3fb4c313ec Support list IPv6 address certificate 2025-12-20 10:05:52 +08:00
Robert Rettig 65892453be take a fork of acmetest 2025-12-19 19:23:13 +01:00
Robert Rettig cba0ff8321 Add oathtool to ubuntu package list in plat.conf 2025-12-19 19:09:23 +01:00
Robert Rettig b6523c2301 Install oathtool in container via _setup function 2025-12-19 18:42:28 +01:00
Robert Rettig e92d0a7492 Fix: Install oathtool at runtime in test container 2025-12-19 18:20:56 +01:00
Robert Rettig 0e5aab346f Add oathtool to acmetest Docker image for 2FA support 2025-12-19 18:17:05 +01:00
Robert Rettig a5ad15be02 Add oathtool to Docker job for 2FA support 2025-12-19 18:07:46 +01:00
Robert Rettig 27ebf09c5c Improve _htmlEscape function robustness by using printf instead of echo
small commit to trigger github actions
2025-12-19 18:02:18 +01:00
Robert Rettig 1c65c04b54 update dns_inwx_info 2025-12-19 17:51:13 +01:00
Robert Rettig 987882ea37 fix delete 2025-12-19 17:49:24 +01:00
Sergey Parfenov 00aaed1b14 Fix strongswan deploy hook
Make it more resistant to deploy hooks api change by passing custom arguments first
2025-12-19 18:12:45 +03:00
Robert Rettig e3b1bccb6a Fixes to support INWX again
Fixes #6688
2025-12-18 16:00:55 +00:00
Jérémy Lal 6ca19fb003 Ensure ssh.sh sets 600 permissions on keyfile 2025-12-18 09:55:50 +01:00
as-kholin 85ff92170b Updated comment to be more clear on variable vs.
definition
2025-12-17 17:15:10 -05:00
Gary McGregor 7ac8c6c75b Merge remote-tracking branch 'upstream/dev' into omglol_202512 2025-12-17 16:56:26 -05:00
neil 6004e7f5cd Merge pull request #6675 from imiric/fix/exoscale-dns
fix: update Exoscale DNS script
2025-12-17 20:49:41 +01:00
as-kholin 4a7e5d0720 Updating Auth header to satisfy shellcheck 2025-12-16 15:00:05 -05:00
as-kholin b4042d5ccb Updated checks for empty parameters to actually trigger, and added a validation check against the omg.lol API to confirm address and apikey are good before proceeding 2025-12-16 14:51:42 -05:00
Bob Perper 6f66e294de Yet another try 2025-12-11 15:43:15 -05:00
Bob Perper 5017c12324 Trying verification again 2025-12-11 09:03:38 -05:00
fratoro 70bc5a6fba Update dns_cyon to use unique user-agent and all cookies 2025-12-09 22:57:26 +01:00
fratoro 3063973744 Update dns_cyon to use unique user-agent and all cookies 2025-12-09 16:49:12 +01:00
Bob Perper 1a2071a120 Merge branch 'acmesh-official:dev' into dev 2025-12-09 10:05:22 -05:00
Bob Perper e5dea48d3c Retry pull request with HTTPS_INSECURE=1 2025-12-09 07:40:00 -05:00
Ivan Mirić 1413aa332b fix: update Exoscale DNS script
This updates the Exoscale DNS script to work with v2 of their API.
2025-12-09 09:49:54 +01:00
neil 37cf431e80 Merge pull request #6676 from acmesh-official/dev
sync
2025-12-08 21:17:08 +01:00
neil 0c9d2dafe3 Merge pull request #6638 from pini-gh/fix-6081
dnsapi/dns_gandi_livedns.sh: save Gandi LiveDNS variables with prefix 'SAVED_'
2025-12-08 21:14:48 +01:00
neil e8708a7489 fix solaris 2025-12-08 21:13:00 +01:00
neil 79592c700f Merge pull request #6671 from ufozone/dev
Add mgw-media.de DNS API
2025-12-08 20:14:00 +01:00
Markus G. ad3783170e Fix formatting issues in dns_mgwm.sh script 2025-12-08 19:31:40 +01:00
Gilles Filippini 329dab9a67 Use '_mutable' functions for authentication variables
Fixes #6081.
2025-12-08 19:02:33 +01:00
Markus G. f142f37064 Remove DNS provider information comment
Removed comment about DNS provider information.
2025-12-08 18:49:51 +01:00
Markus G. 0d2955b48d Update documentation links in dns_mgwm.sh 2025-12-08 18:49:51 +01:00
Markus G. 95da407de8 Refactor DNS API script to use new request function 2025-12-08 18:49:51 +01:00
Markus G. 503ca1e9c2 Change MGWM_API_BASE to use IP address 2025-12-08 18:49:51 +01:00
Markus G. d8722c46d9 Consolidate API request logic in dns_mgwm.sh
Refactor DNS API functions to use a unified request handler.
2025-12-08 18:49:51 +01:00
Markus G. 546c2d47d5 Refactor DNS API for mgw-media.de
Updated DNS API script for mgw-media.de to use new base URL and improved API request structure.
2025-12-08 18:49:51 +01:00
Markus G. 2ba615555c Refactor dns_mgwm.sh for improved API interaction
Refactor MGWM API script to improve clarity and functionality. Update API endpoint and streamline credential handling.
2025-12-08 18:49:51 +01:00
Markus G. e94c6be4a1 Update MGWM API endpoint to IPv4 2025-12-08 18:49:51 +01:00
Markus G. 11eaad1fa7 Update API URLs to include .php extension 2025-12-08 18:49:51 +01:00
Markus G. daf7f7c268 Refactor dns_mgwm.sh for better API integration
Refactor DNS API script to improve credential handling and update API endpoint.
2025-12-08 18:49:51 +01:00
ufozone 4965c704d7 Initial commit for mgw-media.de 2025-12-08 18:49:51 +01:00
neil b7fe7a40ba Merge pull request #6333 from EfficientIP-Labs/dns_efficientip
Implement DNS API for Efficientip SOLIDserver
2025-12-08 18:46:59 +01:00
Bob Perper 5fcca7c7e0 Retry correct commit 2025-12-08 08:48:30 -05:00
Bob Perper b0088c82dc Merge branch 'acmesh-official:dev' into dev 2025-12-08 08:44:42 -05:00
Bob Perper 875cf056b7 Submit dns_qc.sh for review 2025-12-08 08:40:44 -05:00
neil 3b2c2b16b2 minor 2025-12-06 11:23:28 +01:00
neil 45cb36f6d9 fix https://github.com/acmesh-official/acme.sh/issues/6246#issuecomment-3610998032 2025-12-05 22:31:45 +01:00
Bob Perper ed1bd01592 Save account information differently 2025-12-05 16:29:49 -05:00
Bob Perper a1857af6de Update error message and secrets 2025-12-05 15:53:17 -05:00
neil 70e965fd55 Merge pull request #6665 from acmesh-official/dev
sync
2025-12-05 21:51:56 +01:00
neil bee01c938a add comment 2025-12-05 21:46:15 +01:00
Bob Perper 6b6d22c5ba shfmt updates 2025-12-05 13:52:59 -05:00
Bob Perper 67a389cbbf Minor change and setup secrets again 2025-12-05 10:35:52 -05:00
Bob Perper d3930639db Updated secrets and put back guards 2025-12-05 08:58:41 -05:00
Bob Perper 65292b010e Merge branch 'acmesh-official:dev' into dev 2025-12-05 08:57:01 -05:00
invario f39a6fe517 Use cat instead of cp for all files
Signed-off-by: invario <67800603+invario@users.noreply.github.com>
2025-12-04 11:06:50 -05:00
invario 2775def93a Use 'cat' instead of 'cp', removed use of temp file, keeps permissions
Signed-off-by: invario <67800603+invario@users.noreply.github.com>
2025-12-03 12:05:19 -05:00
neil 5cbae50ec1 Merge pull request #6651 from stefanriegel/master
Added dns provider for Infoblox Universal DDI
2025-12-02 20:00:09 +01:00
hostup 51b4fa0080 Update dns_hostup.sh 2025-12-01 17:19:16 +01:00
hostup 64a6ea68fa Update dns_hostup.sh 2025-12-01 15:58:36 +01:00
hostup d97b4477b2 Update dns_hostup.sh 2025-12-01 15:55:17 +01:00
hostup b8e394e76a Update dns_hostup.sh
bug fix Omnios fial
2025-12-01 15:48:48 +01:00
hostup 671d542898 chore: trigger DNS API test 2025-12-01 13:49:12 +01:00
hostup 9980ad0fef add HostUp DNS 2025-12-01 13:33:19 +01:00
Stefan 004deaeea1 Merge branch 'dev' into master 2025-11-30 19:28:39 +01:00
Stefan Riegel 36b8ca2bc0 Fix shfmt formatting: Remove trailing whitespace 2025-11-30 00:49:36 +01:00
Stefan Riegel 890ab4a7bb Refactor dns_infoblox_uddi.sh: Fix zone detection and add wildcard cert support
- Added _get_root() helper function for proper zone detection
- Fixed zone ID extraction to match dns/auth_zone/* pattern
- Added _infoblox_rest() wrapper for API calls with proper auth
- Improved error handling for authentication failures
- Added support for wildcard certificates (multiple TXT records)
- Filter by exact txtvalue when deleting records
- Follow acme.sh best practices and conventions

Tested with:
- Standard domain certificates
- Wildcard certificates (*.domain.com)
- Multiple subdomains
- Staging and production Let's Encrypt
2025-11-30 00:48:15 +01:00
Stefan Riegel 490b9e2d09 Clean up debug statements 2025-11-29 23:39:43 +01:00
Stefan Riegel ca35e8c118 Fix zone_id extraction to query correct zone 2025-11-29 23:32:28 +01:00
Stefan Riegel eeb91de6a3 Replace jq with shell-based JSON parsing 2025-11-29 23:13:52 +01:00
Stefan Riegel 657b7195d6 Fix Authorization header format 2025-11-29 23:06:26 +01:00
Stefan 054a73f297 fix DNS API 2025-11-29 22:48:06 +01:00
Stefan 5c6d8aacbe Add files via upload 2025-11-29 22:38:02 +01:00
neil ac0df6bc88 start 3.1.3 2025-11-29 16:36:14 +01:00
neil f007b46c1b Merge pull request #6644 from SunMar/patch-1
fix "dns_aws.sh: line 164: _error: command not found" #6443
2025-11-28 20:15:18 +01:00
SunMar c5566eafeb fix "dns_aws.sh: line 164: _error: command not found" #6443 2025-11-28 09:44:50 +01:00
neil 40290ad42a Merge pull request #6643 from acmesh-official/dev
sync
2025-11-27 22:15:40 +01:00
neil 705fbcd570 fix https://github.com/acmesh-official/acme.sh/issues/6124#issuecomment-3586650156 2025-11-27 22:13:28 +01:00
asavin 75ee17aeeb Remove unecessary base64 encoding 2025-11-25 14:47:40 +01:00
ZeroSSL-Andreas 9b30bd5a03 Update README.md 2025-11-25 14:41:31 +01:00
neil 94a163397b Merge pull request #6630 from spin-acompany/feat-panos-filename
Add custom certname for panos
2025-11-23 11:52:02 +01:00
Antoni Company 46a2608783 fix: Renamed filaname to certname
- Changed filename to certname to better reflect the actual issue at hand.
- Restored _cdomain variable to its original place for clarity.
2025-11-22 09:22:45 +00:00
Bob Perper 88e9681481 Additional shfmt issues 2025-11-21 16:26:24 -05:00
Bob Perper 20ef8cd369 Additional shfmt issues 2025-11-21 16:22:42 -05:00
Bob Perper ded539b11c Additional shfmt issues 2025-11-21 16:04:23 -05:00
Bob Perper 5e76ea820c Additional shfmt issues 2025-11-21 16:01:14 -05:00
Bob Perper 90d2ff8fad Better fixes for shfmt errors 2025-11-21 15:27:38 -05:00
Bob Perper 0f42b06b48 Trying again to fix shfmt error 2025-11-21 08:02:59 -05:00
Bob Perper b500ac3dbb Updated secret and dns_qc.sh 2025-11-20 15:38:56 -05:00
neil d2539c3f1a fix
https://github.com/acmesh-official/acme.sh/issues/6402
2025-11-20 21:18:50 +01:00
neil 8faebdc99c Merge pull request #6632 from acmesh-official/dev
sync
2025-11-20 20:56:44 +01:00
Bob Perper 894dfdd5d8 Merge branch 'QUIC.cloud' of github.com:rperper/acme.sh into QUIC.cloud 2025-11-20 08:02:11 -05:00
Bob Perper d0d97a40a6 Commit to force initial test 2025-11-20 08:01:36 -05:00
Bob Perper cf5fd403e8 Removed false wiki page 2025-11-20 08:01:36 -05:00
Bob Perper 72a6a5ce04 Added wiki doc 2025-11-20 08:01:36 -05:00
Bob Perper 9381835a7c QUIC.cloud support for acme.sh 2025-11-20 08:01:36 -05:00
Bob Perper 2c9ba9b3df Merge remote-tracking branch 'upstream/dev' into QUIC.cloud 2025-11-20 07:58:23 -05:00
Antoni Company 3d3053f427 feat: Add custom filename for panos 2025-11-20 10:06:37 +00:00
neil 90e6c9b87b Merge pull request #6629 from WongIong/patch-1
Adapting to Cloudflare's new response
2025-11-19 20:51:34 +01:00
Mason a9f96bf709 Reformat using shfmt 2025-11-20 00:29:44 +08:00
Mason c950b67e4b Adapting to Cloudflare's new response 2025-11-19 23:27:45 +08:00
Bob Perper 9a74c86327 Commit to force initial test 2025-11-19 09:06:55 -05:00
neil 6715320e78 fix https://github.com/acmesh-official/acme.sh/issues/6610
https://github.com/acmesh-official/acme.sh/issues/6617#issuecomment-3546341480
2025-11-19 08:51:25 +01:00
neil 77805086d0 Merge pull request #6563 from PKlapp/dns_hetznercloud
Add Hetzner Cloud DNS provider (dns_hetznercloud)
2025-11-18 21:11:39 +01:00
Bob Perper 692a21ee0d Merge branch 'acmesh-official:master' into QUIC.cloud 2025-11-18 11:25:49 -05:00
neil ff8c12ac75 Merge pull request #6620 from coderjoe/fix/readme-clarify-keylength-documentation 2025-11-17 22:08:20 +01:00
Joe Bauser 0d1f9edf3f README.md clarify keylength arg and ECC default
Reorder and reword small portions of the keylength documentation and
make the ECC cert default explicitly stated in part 2 to avoid
confusion.

Fixes #6590
2025-11-17 15:42:13 -05:00
neil 4bfc5aafd3 Merge pull request #6616 from acmesh-official/dev
add logo
2025-11-16 09:31:21 +01:00
neil a6ff1d6924 add logo 2025-11-16 09:30:41 +01:00
neil 7c7c99656a Merge pull request #6612 from acmesh-official/dev
remove ClearLinux
2025-11-15 11:28:02 +01:00
neil 66bad853ae remove ClearLinux 2025-11-15 11:27:04 +01:00
neil 52ac922014 Merge pull request #6611 from acmesh-official/dev
sync
2025-11-15 11:23:56 +01:00
neil 4a7f35dea7 remove clientauth
https://github.com/acmesh-official/acme.sh/issues/6610
2025-11-15 11:12:09 +01:00
EfficientIP-Labs ad2cb507a4 Merge branch 'dev' into dns_efficientip 2025-11-12 14:11:54 +01:00
EfficientIP-Labs dca23a98f1 Merge branch 'acmesh-official:master' into dns_efficientip 2025-11-12 10:50:42 +01:00
neil 8955732c05 Merge pull request #6504 from AnTheMaker/patch-1
[Important DNS Provider Update] Support Nanelo DNS Team- & Workspace-specific API keys
2025-11-09 22:27:44 +01:00
An | Anton Röhm 762b140808 Merge branch 'acmesh-official:master' into patch-1 2025-11-09 20:58:12 +01:00
neil 57f8221bab fix --request-v4/6
https://github.com/acmesh-official/acme.sh/pull/6582
2025-11-09 19:58:25 +01:00
neil b7a575b837 Merge pull request #6582 from Roy-Orbison/request-ip-family
Choose an IP address family for outgoing requests
2025-11-09 19:33:44 +01:00
neil 0a4500e85b Merge pull request #6604 from acmesh-official/dev
sync
2025-11-09 19:15:45 +01:00
neil 9a994e7f36 fix 2025-11-09 19:03:30 +01:00
neil 839d611f64 use ghcr.io/letsencrypt/pebble:latest 2025-11-09 18:50:09 +01:00
neil 421946a923 Merge pull request #6589 from de-es/ntfy
Add priority, tags and title to ntfy notification
2025-11-09 18:11:50 +01:00
neil 1f598a0a79 Merge pull request #6594 from rglidden/truenas_25.10_fix
truenas_ws: Fix TrueNAS deploy fails on TrueNAS 25.10 due to invalid passphrase
2025-11-09 18:10:08 +01:00
neil d5c669bcd2 Merge pull request #6600 from seagleNet/feat/notify_opsgenie
feat: Add notify plugin for opsgenie
2025-11-09 18:09:04 +01:00
neil 32c664d450 Merge pull request #6603 from pvamos/alpine22
Bump Alpine version from 3.21 to 3.22
2025-11-09 18:01:32 +01:00
neil adb46748de Merge pull request #6447 from privacyfr3ak/master
Fix keystore ownership in Unifi deployment - unifi.sh for BSD
2025-11-09 18:00:39 +01:00
privacyfr3ak 59a286b0b7 disable shellcheck 2025-11-08 16:59:10 -05:00
Péter Vámos c5f41479a9 Bump Alpine version from 3.21 to 3.22 2025-11-07 16:16:30 +01:00
neil b694019a40 Merge pull request #6597 from peterlh/master
Updated Curanet API - API Response changed
2025-11-04 22:49:21 +01:00
PrivacyFreak 72259059ef Merge branch 'acmesh-official:master' into master 2025-11-04 15:23:54 +00:00
seagleNet 0fa53d62cb feat: Add notify plugin for opsgenie 2025-11-04 09:35:47 +01:00
PKlapp 47d17c1298 Merge pull request #1 from PKlapp/dns_hetznercloud_improvements
DNS Hetzner Cloud improvements
2025-11-04 01:17:45 +01:00
Peter Lindegaard Hansen d187b982eb Update dns_curanet.sh 2025-11-03 18:14:27 +01:00
Peter Lindegaard Hansen b7c8601540 Update dns_curanet.sh 2025-11-03 16:18:15 +01:00
Richard Glidden 693b1f7a74 Fix TrueNAS deploy fails on TrueNAS 25.10 2025-11-02 23:01:51 -05:00
Philipp Klapp 5f81460504 Wait for Hetzner Cloud DNS actions to complete before returning 2025-11-02 04:07:58 +01:00
Philipp Klapp b65f432ee0 Normalize Hetzner zone names to punycode 2025-11-01 13:44:11 +01:00
Dennis Schmidt 3d21ac4525 CS
Make shfmt happy
2025-10-31 08:41:34 +00:00
Dennis Schmidt 7c5b9a5b92 Add priority, tags and title to ntfy notification
Make the ntfy.sh notifications easier to distinguish at a first glance.
2025-10-31 08:41:34 +00:00
neil 82ff65c3d4 Merge pull request #6575 from JensSpanier/dev
Add deploy hook for KeyHelp API
2025-10-30 21:42:45 +01:00
Bob Perper 68eb6defd3 Removed false wiki page 2025-10-27 12:04:08 -04:00
Bob Perper e25e30dcdd Added wiki doc 2025-10-27 12:00:01 -04:00
Roy Orbitson 48c48cb344 Choose an IP address family for outgoing requests
Useful where remote endpoints filter requests by IP address, but one's
Internet connection has a stable IP for only one address family,
e.g.: a dynamic IPv6 prefix and a static IPv4 address; or a static IPv6
prefix and CGNAT IPv4.
2025-10-27 17:32:20 +10:30
neil a1f4f9ddb7 Merge pull request #6579 from acmesh-official/dev
sync
2025-10-24 21:15:08 +02:00
Bob Perper 7ca8a9e449 QUIC.cloud support for acme.sh 2025-10-24 11:34:25 -04:00
Jens Spanier 0c7943868d Merge branch 'acmesh-official:dev' into dev 2025-10-21 11:35:19 +02:00
Jens Spanier 3cdce86339 rename to keyhelp_api 2025-10-21 11:34:46 +02:00
Alexis Savin 8cb9713493 Merge branch 'acmesh-official:master' into dns_efficientip 2025-10-18 18:25:40 +02:00
asavin ef76831d37 Addressing #pullrequestreview-3353279982 2025-10-18 14:16:51 +02:00
neil 08246f7005 Merge pull request #6567 from vmichelin/dev
fix #6555 : ovh dns api enable to remove record
2025-10-18 13:11:30 +02:00
neil c377ec69d3 Merge pull request #6571 from DuolaD/master
Fix the issue where Telegram bots would not push notifications.
2025-10-18 12:41:15 +02:00
DuolaD a2c2b7ffee Fixed the issue where Telegram bots would not push notifications. 2025-10-18 11:41:26 +08:00
An 65bd3d67b4 nanelo dns: minor log improvements 2025-10-14 15:51:28 +02:00
asavin c4671272c0 Yet another push to try the test suite 2025-10-14 13:35:15 +02:00
Vmichelin 25c564bae1 fix #6555 : ovh dns api enable to remove record 2025-10-14 10:10:19 +02:00
Philipp Klapp 3c3ec2c97c Script created for Hetzner Cloud 2025-10-13 09:05:59 +02:00
neil 15197455f2 Merge pull request #5061 from b1n23/dev
Add deployhook for CacheFly, Edgio and Netlify
2025-10-11 12:47:40 +02:00
Jens Spanier f7cc72be35 add missing double quotes 2025-10-09 13:28:04 +02:00
Jens Spanier 17da49bb78 add keyhelp deploy hook 2025-10-09 13:16:28 +02:00
neil a5754e9ec4 Merge pull request #6551 from acmesh-official/dev
sync
2025-10-06 12:32:49 +01:00
neil 2584f09083 Merge pull request #6543 from szhu25/add-to-list
Add "Profile" column to --list command
2025-10-06 12:30:49 +01:00
Steven Zhu d439933b52 add Profile column to --list output
This commit adds a new "Profile" column to the output of the `--list` command.

The column displays the value of the `Le_Certificate_Profile` variable stored in each domain's respective configuration file. If a profile is not set for a certificate, the column is left empty.

This enhances the utility of the list command by providing more at-a-glance information about each certificate's configuration, which is particularly useful for CAs that support different certificate profiles.
2025-09-28 19:20:08 -04:00
neil 094d03bf7a Merge pull request #6542 from szhu25/list-profiles
Implement discovery of CA certificate profiles
2025-09-28 15:42:50 +01:00
Steven Zhu 0f5093c0b7 Remove space 2025-09-27 17:52:44 -04:00
Steven Zhu 80748b9fe0 Quick Patch 2025-09-27 17:37:37 -04:00
Steven Zhu b244c76dd5 Add --list-profiles command to show CA profiles
This commit introduces a new command, `--list-profiles`, to allow users to discover the certificate profiles supported by a Certificate Authority.

The command queries the `meta.profiles` object within the ACME directory JSON for the selected server and formats the output for readability. If a CA does not publish profiles in its directory, the command reports that none were found.

Usage:
  acme.sh --list-profiles [--server letsencrypt]
2025-09-27 17:29:12 -04:00
neil a91ab54449 Merge pull request #6540 from acmesh-official/dev
sync
2025-09-27 22:22:55 +01:00
neil f2dbf56db1 Merge pull request #6514 from zjwangmin/dev
fix bug for #6510
2025-09-27 22:16:14 +01:00
neil e5214ea2e5 add Actalis.com CA 2025-09-27 23:12:05 +02:00
neil 11995b958a add actalis.com CA 2025-09-27 22:57:42 +02:00
neil 493ec4be52 Merge pull request #6442 from JensSpanier/dev
Support certificate profile selection
2025-09-27 21:27:55 +01:00
Jens Spanier 604e6873ba Add short name + wiki link to help 2025-09-22 12:12:17 +02:00
Jens Spanier 5954f0dde5 Change to --cert-profile 2025-09-22 12:11:50 +02:00
neil b8e91036dd Merge pull request #6524 from acmesh-official/dev
sync
2025-09-21 18:06:01 +02:00
neil f22b490a10 remove buypass 2025-09-21 18:04:59 +02:00
neil 49ed112ef5 Merge pull request #6523 from acmesh-official/dev
sync
2025-09-21 17:18:25 +02:00
neil 471e0c05f9 remove mageia 2025-09-20 10:38:43 +02:00
neil c3ec827fdd remove buypass 2025-09-19 20:54:09 +02:00
neil ca7bdd9101 Merge pull request #6424 from rglidden/truenas_ws_remote
truenas_ws: Add ability to deploy to remote TrueNAS server via WebSockets
2025-09-19 20:49:29 +02:00
Richard Glidden 070cd0f4df Use _sleep instead of sleep 2025-09-16 22:19:16 -04:00
EfficientIP-Labs 86f2584162 Merge branch 'acmesh-official:master' into dns_efficientip 2025-09-16 11:15:51 +02:00
Jens Spanier 1b00ced7ad Add --profile as option for selecting certificate profile 2025-09-16 09:20:31 +02:00
Min Wang 44c7473ef9 fix bug for #6510 2025-09-16 15:09:12 +08:00
neil 20c80f553f Merge pull request #6513 from acmesh-official/dev
sync
2025-09-15 20:13:47 +02:00
neil b4a5149ba2 Merge pull request #6503 from benyamin-codez/dnsapi-dns_opnsense-v25.7-refresh-dev
dnsapi/dns_opnsense.sh: Refresh for OPNsense v25.7 series
2025-09-15 19:35:42 +02:00
neil df350e6660 fix format 2025-09-15 19:34:54 +02:00
benyamin-codez d76f4b27b0 dnsapi/dns_opnsense.sh: Refresh for OPNsense v25.7 series
Updates the dns_opnsense.sh Bourne shell script for OPNSense v25.7 series:

1. Fixes historical error in rm_record() [used incorrect response variable]
2. Improves debug messaging in rm_record()
3. Fixes _get_root() for change in OPNsense API
    * Response is now split into pseudo-rows
    * We now iterate through pseudo-rows for matching domainname field
4. Fixes _existingchallenge() for change in OPNsense API
    * Fixes unreliable regex for uuid
    * Adds domain regex and %domain field
5. Fixes historical error in _existingchallenge() [incorrect variable syntax]

Resolves #6467

Signed-off-by: benyamin-codez <115509179+benyamin-codez@users.noreply.github.com>
2025-09-15 15:50:48 +10:00
neil a1ea2a5aa6 fix tr
https://github.com/acmesh-official/acme.sh/issues/6511#issuecomment-3282521860
2025-09-14 10:35:34 +02:00
Richard Glidden 8608e9cd3a Save and read variables 2025-09-12 22:22:30 -04:00
Jens Spanier 5f8f7ee576 Merge branch 'acmesh-official:dev' into dev 2025-09-10 09:09:43 +02:00
An d8a92a2e65 switch nanelo api to post requests 2025-09-08 21:32:15 +02:00
An | Anton Röhm 67ed930100 Merge branch 'acmesh-official:master' into patch-1 2025-09-08 21:22:55 +02:00
EfficientIP-Labs 020c52e583 Merge branch 'acmesh-official:master' into dns_efficientip 2025-09-08 09:23:17 +02:00
neil 03dd318265 Merge pull request #6505 from acmesh-official/dev
sync
2025-09-07 20:49:42 +02:00
neil fc3bfda3bd Merge pull request #6487 from aSauerwein/master
add template_stack option to push to device
2025-09-07 20:48:00 +02:00
An | Anton Röhm 7eb0ce6e90 Merge branch 'dev' into patch-1 2025-09-07 17:19:02 +02:00
An | Anton Röhm 5aa964cde9 Formatting
using shfmt to format the code
2025-09-07 17:17:51 +02:00
An | Anton Röhm 31d7264583 Fix pattern matching for best zone selection 2025-09-07 17:14:06 +02:00
An | Anton Röhm 93dc22a71f Support Nanelo DNS Team- & Workspace-specific API keys
Nanelo Team- and Workspace-specific API keys require the "domain" parameter to be set containing the DNS zone name (unlike the Domain-specific API keys).
So I've added a function to detect the root DNS zone and set the required parameter as described here: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide#3-detect-which-part-is-your-root-zone
2025-09-07 16:57:10 +02:00
neil c4d228ad8d Merge pull request #6493 from jdevera/proxmox_response_check
Show proxmox deploy scripts response only on debug
2025-09-07 10:41:24 +02:00
neil 30faf500eb fix https://github.com/acmesh-official/acme.sh/pull/6499#issuecomment-3259771356 2025-09-07 10:09:27 +02:00
neil 26d4bac85f Merge pull request #6501 from fuyufjh/patch-1
Fix sed command in telegram notifier
2025-09-07 10:06:35 +02:00
Eric Fu e0e3cdc316 Fix sed command in telegram notifier 2025-09-06 22:31:50 +08:00
neil 1deb52f86d Merge pull request #6499 from OnyxMsi/ipv6_only_socat_error
socat rejects TCP-LISTEN on ipv6 only networks
2025-09-05 22:19:21 +02:00
neil 39cb87dc4b fix for DragonflyBSD
just move "date -u -j -f" before the linux branch.
2025-09-05 22:08:55 +02:00
Guillaume PELURE 04e2549239 socat rejects TCP-LISTEN on ipv6 only networks 2025-09-02 21:13:38 +02:00
neil e06cdbf0ac Merge pull request #6495 from jdevera/patch-1
Fix diff in wiki notifications (use full clone)
2025-09-02 17:38:41 +02:00
Jacobo de Vera d366b7e4fc Fix diff in wiki notifications (use full clone)
The checkout action fetches one single commit, so attempts to find previous states of a page result in error. Adding fetch-depth:0 to the configuration fetches all commits and makes finding the previous commit that changed a page possible in the github action.
2025-09-01 19:54:36 +01:00
Jacobo de Vera 5aae3333bc Show proxmox deploy scripts response only on debug 2025-08-31 20:44:24 +01:00
Richard Glidden 6d40ac8644 chore: Fix shellcheck errors 2025-08-29 16:24:30 -04:00
Richard Glidden d7c428fc8d feat: Add ability to deploy to remote TrueNAS instances 2025-08-29 16:24:30 -04:00
neil 28f8f56fa3 Merge pull request #6365 from OPPO9008/dev
dnsla api更新
2025-08-28 13:45:15 +08:00
neil b1f6b5314c Merge pull request #5197 from aorith/dev
fix: rage4 - add error 400 and TXT cleanup
2025-08-28 13:42:03 +08:00
asauerwein fdb1e8c2e4 fix usage of H1 header
change to while loop

use global variable for loop

fix if statement to be sh compliant

shfmt
2025-08-20 18:37:25 +02:00
asauerwein 5b02e86334 add template_stack option to push to device 2025-08-20 17:47:36 +02:00
风扇滑翔翼 8713918bdb Fix ipv6 cert cannot be found 2025-08-20 13:00:56 +08:00
neil 10627e4974 Merge pull request #6473 from woutd/constellix-rate-limit
Add sleep before each REST call to Constellix to prevent rate limit
2025-08-19 10:05:37 +08:00
neil 1b89e7c2ec Merge pull request #6476 from TobiasGrave/fix_variomedia_api_2
Variomedia API: Fix DNS challenge TXT record deletion
2025-08-16 00:18:03 +08:00
Tobias Grave bcf0afb25e Variomedia API: Fix DNS deletion issues 2025-08-15 09:02:57 +02:00
wout ab22c8ca1c Convert domain to lower case, needed for Constellix REST API 2025-08-12 19:04:19 +02:00
neil 49513cb2ee Merge pull request #6284 from fornex-com/master
Optimize root domain search through api
2025-08-12 22:31:02 +08:00
wout 1b5e66f9c2 Add sleep before each REST call to Constellix to prevent rate limit 2025-08-12 11:30:16 +02:00
1f486fc9a5 Upload latest dev branch to master (#3)
* Fix for empty error objects in response breaking extraction of domain validation types

Fix for empty error objects in the response which mess up the extraction of domain validation types due to the closing brace in the error object prematurely matching the end of the search pattern.

This seems to be a recent change with ZeroSSL in particular where "error":{} is being included in responses.

There could potentially be a related issue if there is a complex error object ever returned in the validation check response where an embedded sub-object could lead to an incomplete extraction of the error message, roughly around line 5040.

Adapted from fix suggested here: https://github.com/acmesh-official/acme.sh/issues/4933#issuecomment-1870499018

* Add new dnsapi support for OpenProvider.eu using new REST API

* Cleanup duplicate debug log output based on DNS test run

* Resolve spellcheck error

* Configure 10 second timeout to ACME_DIRECTORY API call

* add support for AIX style netstat

* add

* fix for wiki

* minor

* minor

* wiki

* wiki

* dnsapi: dns_mydnsjp.sh fix author

The @epgdatacapbon was renamed to @tkmsst

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>

* dnsapi: dns_ddnss.sh remove RaidenII from authors

He made the DuckDNS script that was used for this script but he can't support the script.

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>

* dnsapi: fix authors: use @ for GitHub profiles

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>

* dnsapi: dns_vultr.sh remove empty author

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>

* dnsapi: dns_mijnhost.sh rearrange fields, use user docs instead of API docs

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>

* dnsapi: fix Structured DNS Info

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>

* Fix logged typo when running pre hook

* Run post hook when _on_before_issue errors

---------

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
Co-authored-by: Ciaran Walsh <ciaran@ciaran-walsh.com>
Co-authored-by: Lambiek12 <algemeen@lambiek12.nl>
Co-authored-by: Erwin Oegema <blablaechthema@hotmail.com>
Co-authored-by: laDanz <cdanzmann@gmail.com>
Co-authored-by: neil <github@neilpang.com>
Co-authored-by: neil <gitpc@neilpang.com>
Co-authored-by: Sergey Ponomarev <stokito@gmail.com>
Co-authored-by: David Beitey <david@davidjb.com>
Co-authored-by: Jan-willem van Kampen <Lambiek12@users.noreply.github.com>
2025-08-12 11:12:09 +03:00
Viktor Polyakov 45c4a98f1d feat: add message_thread_id to telegram notifications 2025-08-11 16:05:09 +03:00
neil 4cdbdf2125 Merge pull request #6391 from Lambiek12/dev
New dnsapi support for OpenProvider.eu using REST API
2025-08-06 19:28:09 +08:00
neil ec5ecabdec Merge pull request #5008 from cjwalsh/patch-1
Fix for empty error objects in response breaking extraction of domain validation types
2025-08-06 19:07:19 +08:00
Ciaran Walsh e391301348 Merge branch 'acmesh-official:master' into patch-1 2025-08-03 22:42:11 +01:00
Ciaran Walsh 49866b6cf4 Merge branch 'dev' into patch-1 2025-08-03 21:48:26 +01:00
invario 3252e0ce2e Add outputs for PFX and PEM
Signed-off-by: invario <67800603+invario@users.noreply.github.com>
2025-07-28 12:14:12 -04:00
Jan-willem van Kampen 09d326de3a Merge branch 'acmesh-official:dev' into dev 2025-07-25 18:49:53 +02:00
Alexis Savin eda8614754 Merge branch 'acmesh-official:master' into dns_efficientip 2025-07-18 12:13:37 +02:00
JF DAGUIN f1209ce06a Merge branch 'dev' into dns_infomaniak_API_v2 2025-07-16 20:39:47 +02:00
PrivacyFreak 06c1911a28 fix keystore ownership read for unifi.sh 2025-07-14 18:48:32 +00:00
neil 8cac773e34 Merge pull request #6444 from davidjb/fix-typo
Fix logged typo when running pre hook
2025-07-13 12:08:19 +08:00
neil 365ec1fd5e Merge pull request #6445 from davidjb/onbeforeissue-error-handling
Run post hook when `_on_before_issue()` errors
2025-07-13 12:07:45 +08:00
David Beitey 40e58ed12d Run post hook when _on_before_issue errors 2025-07-13 11:40:34 +10:00
David Beitey 0c98dc54fe Fix logged typo when running pre hook 2025-07-13 11:19:23 +10:00
Jens Spanier 3b0f624302 Support certificate profile selection 2025-07-10 10:55:05 +02:00
JF DAGUIN 5808b8d176 Merge branch 'dev' into dns_infomaniak_API_v2 2025-07-09 13:43:23 +02:00
pileus-lines c2f8b4d1f2 Update dns_infomaniak.sh
because infomaniak API v1 no longer works
2025-07-09 12:13:17 +02:00
neil 56242423b2 Merge pull request #6434 from stokito/dnsapi_fix_info
DNS API: Fix Structural  Info
2025-07-08 10:47:54 +08:00
invario 014a781426 Create localcopy deploy-hook
Deploy-hook to very simply copy files to set directories and then execute whatever reloadcmd
the admin needs afterwards. This can be useful for configurations where the "multideploy"
hook (in development) is used or when an admin wants ACME.SH to renew certs but needs to
manually configure deployment via an external script (e.g. The deploy-freenas script for TrueNAS Core/Scale

https://github.com/danb35/deploy-freenas/

Signed-off-by: invario <67800603+invario@users.noreply.github.com>
2025-07-06 20:12:10 -04:00
Sergey Ponomarev 8113711b7a dnsapi: fix Structured DNS Info
Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2025-07-06 01:43:16 +03:00
Sergey Ponomarev 85ec6343ff dnsapi: dns_mijnhost.sh rearrange fields, use user docs instead of API docs
Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2025-07-06 01:42:39 +03:00
Sergey Ponomarev daf183e2cc dnsapi: dns_vultr.sh remove empty author
Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2025-07-06 01:41:58 +03:00
Sergey Ponomarev c6819cbd6b dnsapi: fix authors: use @ for GitHub profiles
Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2025-07-06 01:40:53 +03:00
Sergey Ponomarev 01ed3c3326 dnsapi: dns_ddnss.sh remove RaidenII from authors
He made the DuckDNS script that was used for this script but he can't support the script.

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2025-07-06 01:36:40 +03:00
Sergey Ponomarev 76b68f7ccb dnsapi: dns_mydnsjp.sh fix author
The @epgdatacapbon was renamed to @tkmsst

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2025-07-06 01:34:21 +03:00
OPPO9008 2bea808251 Update dns_la.sh 2025-07-02 21:15:46 +08:00
neil 52e051bb02 Merge pull request #6417 from acmesh-official/dev
wiki
2025-06-25 22:15:26 +02:00
neil 74fdf649d3 wiki 2025-06-25 22:14:30 +02:00
neil 2402f463e1 Merge pull request #6416 from acmesh-official/dev
sync
2025-06-25 22:12:27 +02:00
neil 424d33faa0 wiki 2025-06-25 22:11:35 +02:00
neil b64c57fa36 Merge pull request #6414 from acmesh-official/dev
minor
2025-06-25 22:02:02 +02:00
neil 6966b3810d minor 2025-06-25 22:01:11 +02:00
neil 02cb4764c2 Merge pull request #6412 from acmesh-official/dev
minor
2025-06-25 21:52:41 +02:00
neil 89071f7226 minor 2025-06-25 21:51:55 +02:00
neil d6eca62e56 Merge pull request #6411 from acmesh-official/dev
fix for wiki
2025-06-25 21:47:46 +02:00
neil b025e7f0f2 fix for wiki 2025-06-25 21:46:58 +02:00
neil 0f7ecad4e8 Merge pull request #6409 from acmesh-official/dev
sync
2025-06-25 21:34:58 +02:00
neil 4a16aaacb6 add 2025-06-25 21:27:08 +02:00
asavin ca08ce4262 Fixing forgottent openssl ref 2025-06-23 08:59:33 +02:00
neil 21c758c3d3 Merge pull request #6393 from diamondo25/dev-configure-acme_directory-timeout
Configure 10 second timeout to ACME_DIRECTORY API call
2025-06-21 22:19:56 +02:00
neil c338f1a3fa Merge pull request #6404 from laDanz/master
add support for AIX style netstat
2025-06-21 21:52:10 +02:00
laDanz 242085d676 add support for AIX style netstat 2025-06-17 14:05:40 +02:00
keryfan 289d895423 Merge branch 'dev' into master 2025-06-13 17:59:18 +03:00
asavin eb22a84db4 Merge branch 'dns_efficientip' 2025-06-11 16:47:36 +02:00
Alexis Savin d66dd99621 Merge branch 'dev' into dns_efficientip 2025-06-11 16:33:09 +02:00
Erwin Oegema f2b248243c Configure 10 second timeout to ACME_DIRECTORY API call 2025-06-10 10:36:06 +02:00
Lambiek12 fcd358eb71 Resolve spellcheck error 2025-06-08 17:35:09 +02:00
Lambiek12 06d3739a8d Cleanup duplicate debug log output based on DNS test run 2025-06-08 17:29:39 +02:00
Lambiek12 bff1064dbd Add new dnsapi support for OpenProvider.eu using new REST API 2025-06-08 15:39:10 +02:00
OPPO9008 19678db933 Update dns_la.sh 2025-06-06 02:06:27 +08:00
neil 3d8b682380 Merge pull request #6380 from schlegel11/master
Cloudns provider: Fix missing api password encoding
2025-05-31 17:52:44 +02:00
neil 7b76502ee6 Merge pull request #6352 from ecm75/kemploadmaster
Add deploy script for Kemp Loadmaster
2025-05-31 17:30:50 +02:00
Marcel Schlegel 28687ad7c7 Issue 3968: Fix missing api password encoding. 2025-05-31 15:02:25 +02:00
neil d420ff0e56 Merge pull request #5043 from coderjoe/feature/deploy-to-zyxel-gs1900-switches
Add deploy/zyxel_gs1900.sh
2025-05-25 19:05:33 +02:00
asavin 5a085f2514 Addressing #discussion_r2105799190 2025-05-25 18:37:17 +02:00
Alexis Savin e79ee7fb74 Merge branch 'acmesh-official:master' into dns_efficientip 2025-05-25 18:27:39 +02:00
neil ed1adfd878 Merge pull request #6355 from ymol-spraaklab/dev
Set DNS Record TTL to 60 instead of 300 sec
2025-05-24 14:08:57 +02:00
neil 58a7b9ffa7 Merge pull request #6366 from stokito/patch-1
DNS API: fix structural info for new providers
2025-05-24 14:07:19 +02:00
neil af5d046698 Merge pull request #6367 from KincaidYang/dev
docs (dns_tencent) : update documentation links
2025-05-24 14:00:28 +02:00
YANGJINZE 9e75b707ce Merge pull request #1 from KincaidYang/KincaidYang-patch-1
docs (dns_tencent) : update documentation links
2025-05-23 18:03:56 +08:00
YANGJINZE 8241b078ce docs (dns_tencent) : update documentation links 2025-05-23 17:54:56 +08:00
OPPO9008 c8f1e41197 Update dns_la.sh 2025-05-20 20:29:44 +08:00
OPPO9008 cddf098f47 Update dns_la.sh 2025-05-20 20:28:59 +08:00
OPPO9008 500cfbc19c Update dns_la.sh 2025-05-19 21:29:33 +08:00
Sergey Ponomarev 133ae8555a dns_freemyip.sh: fix strutural info 2025-05-19 15:15:46 +03:00
Sergey Ponomarev f132010acb dns_edgecenter.sh: fix structural info 2025-05-19 15:08:54 +03:00
ymol-spraaklab 426305dc33 Merge branch 'dev' into dev 2025-05-19 10:49:48 +02:00
emueller 55282851c4 implemented all suggestions 2025-05-19 09:18:29 +02:00
OPPO9008 9e7d1b9ce7 Update dns_la.sh 2025-05-19 13:16:30 +08:00
OPPO9008 e0da5f1703 Update dns_la.sh 2025-05-19 09:49:21 +08:00
Joe Bauser 4f5a70b804 Apply suggested fixes from shfmt diffs 2025-05-17 21:25:39 -04:00
neil 42bbd1b44a Merge pull request #6359 from acmesh-official/dev
sync
2025-05-17 16:56:42 -04:00
neil fdeaf861e3 Merge pull request #6197 from xvybihal/dns_active24v2
dns_active24: rewrite for supporting new v2 API
2025-05-17 16:35:59 -04:00
neil 8e032a27c4 Merge pull request #6354 from phedoreanu/dev
dns_1984.hosting.sh: fix session cookie name
2025-05-17 15:38:54 -04:00
neil 5bfd43b718 fix pr 2025-05-17 21:28:26 +02:00
neil ce7f4cb9a8 Merge pull request #6356 from Attackwave/deploy/truenas_ws
Deploy/truenas ws
2025-05-17 15:23:03 -04:00
Attackwave 99a4cf9e07 Quickfix TrueNAS 25.04 2025-05-16 22:44:25 +02:00
ymol-spraaklab b82f6801cd Set DNS Record TTL to 60 instead of 300 sec 2025-05-16 15:40:36 +02:00
Adrian Fedoreanu 184cb0b9a8 dns_1984.hosting.sh: fix session cookie name 2025-05-15 16:01:24 +02:00
emueller bf2e99efa6 fixed quoting in kemplm.sh 2025-05-12 10:52:35 +02:00
emueller 7543d5220c fixed kemplm.sh formatting 2025-05-12 10:45:01 +02:00
emueller ca73e1f024 added deploy/kemplm.sh for deploying certs on Kemp Loadmaster 2025-05-12 10:28:35 +02:00
EfficientIP-Labs 718ff3a5f5 Merge branch 'acmesh-official:master' into dns_efficientip 2025-05-09 09:03:45 +02:00
neil c2ccc1f980 Merge pull request #6347 from acmesh-official/dev 2025-05-08 15:18:55 -04:00
keryfan f34d4bd6da Merge branch 'acmesh-official:master' into master 2025-05-08 16:26:10 +02:00
Josef Vybíhal 8a4b436314 Merge branch 'acmesh-official:master' into dns_active24v2 2025-05-05 15:48:45 +02:00
Josef Vybíhal 42aaf7c2a0 dns_active24: rewrite for supporting new v2 API 2025-05-05 15:48:02 +02:00
neil eb00852a71 remove ocsp for letsencrypt server 2025-05-01 13:28:20 +02:00
neil b0535d8b40 Merge pull request #6306 from Meo597/dns-spaceship
Add Spaceship DNS API
2025-04-27 18:38:38 +02:00
Meo597 8b4d93cc14 Spaceship: fix doc 2025-04-28 00:32:46 +08:00
Meo597 e2d0923122 Spaceship: replace ~/.acme.sh with $LE_CONFIG_HOME for configurable paths 2025-04-28 00:18:23 +08:00
Meo597 2928d84339 Spaceship: replace debug with debug2 for detailed output in complex debugging 2025-04-28 00:04:49 +08:00
neil b5e3883891 update 2025-04-26 16:47:29 +02:00
asavin a2e52dadb9 Triggering pipeline with DNS_WILDCARD 2025-04-25 09:59:40 +02:00
asavin ca4cb018d0 Triggering another action pipeline 2025-04-25 09:59:40 +02:00
asavin c2762d3b6f Triggering another action pipeline 2025-04-25 09:59:40 +02:00
asavin 947e872850 Triggering another action pipeline 2025-04-25 09:59:40 +02:00
asavin 3baa5e145f Triggering another action pipeline 2025-04-25 09:59:40 +02:00
asavin 67fd35127c Triggering another action pipeline 2025-04-25 09:59:40 +02:00
asavin c421e2ddfc Triggering another action pipeline 2025-04-25 09:59:40 +02:00
asavin 42febe97b5 Triggering another action pipeline 2025-04-25 09:59:40 +02:00
asavin 74ca0fb763 Triggering another action pipeline 2025-04-25 09:59:40 +02:00
asavin 13631ea2de Triggering another action pipeline 2025-04-25 09:59:40 +02:00
asavin a1eee5923a Disabling SC2034 2025-04-25 09:59:40 +02:00
asavin af92bbca2a Disabling SC2034 2025-04-25 09:59:40 +02:00
asavin c9287071e3 Fixing shellcheck issue 2025-04-25 09:59:40 +02:00
asavin 292026288a Fixing sh syntax 2025-04-25 09:59:40 +02:00
asavin 1f056998f3 Update for testing github action pipeline 2025-04-25 09:59:40 +02:00
asavin 4d7cb7de5f Update for testing github action pipeline 2025-04-25 09:59:40 +02:00
asavin 67855f21d4 Updating issue ID 2025-04-25 09:59:40 +02:00
asavin 8484565e95 Updating Options to meet OptionsAlt pre-requisites 2025-04-25 09:59:40 +02:00
asavin f7d8abe8ea Fixing shellcheck issues 2025-04-25 09:59:40 +02:00
asavin 8ca90297e7 Remove export ? 2025-04-25 09:59:40 +02:00
asavin e08f9080c2 Initial commit 2025-04-25 09:59:40 +02:00
Meo597 d01aefd1eb Spaceship: i starts from 1 2025-04-25 05:24:05 +08:00
Meo597 e1d447847f Spaceship: fix domain conf 2025-04-25 05:21:52 +08:00
asavin 419738fbd5 Triggering pipeline with DNS_WILDCARD 2025-04-24 16:05:20 +02:00
asavin 7f1423dd6f Triggering another action pipeline 2025-04-24 13:33:28 +02:00
asavin 9f09dcd18c Triggering another action pipeline 2025-04-24 11:13:38 +02:00
asavin 91081ade3c Triggering another action pipeline 2025-04-24 10:50:57 +02:00
asavin 4d933c23a8 Triggering another action pipeline 2025-04-24 10:43:46 +02:00
asavin f29bfd995d Triggering another action pipeline 2025-04-24 10:15:56 +02:00
Joe Bauser 24a1b93842 Add deploy/zyxel_gs1900.sh
Add support for deploying to the Zyxel GS1900 line of switches as long
as those switches are running at least firmware V2.80.

Tested on a Zyxel GS1900-8 and GS1900-24E

Resolves #5042
2025-04-23 17:52:12 -04:00
neil bed1c311e3 Merge pull request #6283 from tklk-forks/azure-managed-identities-endpoint
Azure: Use endpoint environment variable for managed identities if set
2025-04-23 21:52:07 +02:00
neil 1ce8d3ae9b start 3.1.2 2025-04-23 21:42:39 +02:00
neil 676d76696b Merge pull request #6328 from acmesh-official/dev
sync
2025-04-23 20:46:32 +02:00
neil 1d18432f8d Merge pull request #6315 from alindt/fix-vault-curl
Fix error detection in vault deploy hook
2025-04-23 20:34:29 +02:00
neil 277f13ff9d Merge pull request #6317 from ruuuch/edgecenter-dns
Add Edgecenter DNS API
2025-04-23 20:33:24 +02:00
asavin 30d5d1aea9 Triggering another action pipeline 2025-04-22 18:01:29 +02:00
asavin 7a0450a7f4 Triggering another action pipeline 2025-04-22 17:55:23 +02:00
asavin 5bb09f469f Triggering another action pipeline 2025-04-22 17:06:33 +02:00
asavin 90e9d8ff52 Triggering another action pipeline 2025-04-22 16:38:37 +02:00
asavin 59a43ce5d1 Disabling SC2034 2025-04-22 16:27:36 +02:00
asavin 5bc01aa251 Disabling SC2034 2025-04-22 15:56:49 +02:00
asavin 9eeb979c7b Fixing shellcheck issue 2025-04-22 15:49:41 +02:00
asavin eabd7592fe Fixing sh syntax 2025-04-22 15:41:22 +02:00
asavin e089a3d8a1 Update for testing github action pipeline 2025-04-22 15:31:17 +02:00
asavin 7560375502 Update for testing github action pipeline 2025-04-22 15:23:11 +02:00
asavin 1f77b89266 Updating issue ID 2025-04-22 11:40:01 +02:00
asavin 7c610124d9 Updating Options to meet OptionsAlt pre-requisites 2025-04-22 11:32:23 +02:00
asavin a0c5ef4e6f Fixing shellcheck issues 2025-04-22 11:17:14 +02:00
asavin 218934e767 Remove export ? 2025-04-18 18:06:12 +02:00
asavin c6a9825c0a Initial commit 2025-04-18 17:25:55 +02:00
rka 2d365efe56 Add Edgecenter DNS API 2025-04-18 02:48:48 +03:00
Alin Trăistaru e81635f23d check curl vault http return code 2025-04-18 00:25:10 +02:00
Meo597 827315e059 Spaceship: valid api response 2025-04-15 21:02:46 +08:00
Meo597 e55a54f3d4 Spaceship: fix get_root 2025-04-15 21:02:46 +08:00
Meo597 5e8b40faf6 Spaceship: fix rm 2025-04-15 21:02:46 +08:00
Meo597 45b9982172 Add Spaceship DNS API 2025-04-15 21:02:45 +08:00
neil 9b267bb572 Merge pull request #6299 from Gontier-Julien/dev
Bump Alpine version from 3.17 to 3.21
2025-04-12 15:20:05 +01:00
Gontier Julien 20c7bfaff2 Bump Alpine version from 3.17 to 3.21
Signed-off-by: Gontier Julien <52894530+Gontier-Julien@users.noreply.github.com>
2025-04-11 20:09:03 +02:00
techknowlogick dd29f970a2 Use endpoint environment variable for managed identities if set
Some environments in azure don't use the default metadata endpoint, and instead inject an env var that should be used.
2025-03-31 10:47:49 -04:00
keryfan b6a9a1a7ee Merge branch 'dev' into master 2025-03-31 11:03:27 +03:00
neil 1d87d9b370 Merge pull request #6287 from acmesh-official/dev
sync
2025-03-29 21:18:22 +01:00
neil 40b6db6a27 persist-credentials: false 2025-03-29 21:14:56 +01:00
neil 9ba662a53e Merge pull request #6285 from ms264556/bugfix/deploy_ruckus_checkecc
Don't deploy ECC certs to legacy Ruckus
2025-03-29 21:08:25 +01:00
neil dc228c3dbb Merge pull request #6282 from magyarsz/dev
Fix error message variable when reload cmd returns with an error
2025-03-29 21:03:22 +01:00
magyarsz dd5dd422d1 Merge branch 'dev' into dev 2025-03-28 21:19:12 +01:00
neil 73fdf4b957 Merge pull request #6286 from acmesh-official/dev
sync
2025-03-28 20:51:39 +01:00
neil a1de13657e minor, just copy necessary files 2025-03-28 20:50:08 +01:00
ms264556 93c19356d0 Don't deploy ECC certs to legacy Ruckus 2025-03-27 14:03:08 +13:00
Szabolcs Magyar 8a27c902ff Fix error message variable when reload cmd returns with an error 2025-03-25 19:29:12 +01:00
neil be35b55444 Merge pull request #623 from kevinoid/fix-well-known-perms
Avoid permissions errors for chown .well-known
2025-03-23 21:20:23 +01:00
neil a16ccf40c2 Merge pull request #6198 from lindsayzhou/fix-dns-netzner-error-regexp
fix regex of matching hetzner dns api error responses
2025-03-23 21:07:24 +01:00
Sikro 5c7b1cd5f2 add environment variable for notify/telegram.sh
Since the server in mainland China cannot connect to Telegram, add the TELEGRAM_BOT_URLBASE environment variable
Please add the proxy address you set. If this variable is not added, it will be the default value (https://api.telegram.org)
2025-03-23 21:00:34 +01:00
neil fc5e593e2d Merge pull request #6277 from beedaddy/ntfy_token
support NTFY_TOKEN
2025-03-21 20:07:34 +01:00
Martin Brodbeck f1dc79f0b5 support NTFY_TOKEN 2025-03-20 10:13:12 +01:00
neil 34ea97dcea Merge pull request #4384 from fraenki/cert_home
update documentation for --cert-home parameter
2025-03-19 11:04:06 +01:00
neil f2931163aa Merge pull request #6268 from wlallemand/haproxy-fix-secure-debug
haproxy: don't leak private keys when doing --debug
2025-03-15 11:09:55 +01:00
William Lallemand 7e320d2748 haproxy: don't leak private keys when doing --debug
It was reported in issue #6267 that the private key was leaked when
using the DEPLOY_HAPROXY_HOT_UPDATE=yes feature.

Indeed, the debugging code which sends commands to HAProxy was using
_debug even when passing the private key.

This patch fixes the issue by using _secure_debug when doing that.
2025-03-11 12:04:59 +01:00
taras-l b38d15adb3 Merge pull request #2 from fornex-com/fornex_dnsapi_fix
Update _get_root url in dnsapi/dns_fornex.sh
2025-03-11 10:21:35 +02:00
kir 29342e036f Update _get_root url in dnsapi/dns_fornex.sh 2025-03-11 08:07:38 +00:00
neil 45660902ed Merge pull request #6262 from copyliu/copyliu-routeros-dev
routeros: file-name should in quotes in newer (7.18) version
2025-03-09 19:45:30 +01:00
neil 72318cb687 Merge pull request #6263 from markkuleinio/dev
dns_he_ddns: Add empty dns_he_ddns_rm() to remove warnings
2025-03-09 19:41:59 +01:00
neil f277223a65 Merge pull request #6257 from metaforget/master
cqhttp notify-hook:Compatibility with QQ Headless Project Napcat
2025-03-09 19:40:46 +01:00
Markku Leiniö 262fa74f5e dns_he_ddns: Add empty dns_he_ddns_rm() to remove warnings 2025-03-05 19:45:01 +02:00
copyliu ebdd221c72 routeros: file-name should in quotes in newer (7.18) version 2025-03-05 11:33:41 +08:00
metaforget 2b8d162c9e Merge branch 'dev' into master 2025-03-03 13:51:08 +08:00
metaforget dc8cf0e02e cqhttp notify-hook:Compatibility with QQ Headless Project Napcat 2025-03-03 10:37:38 +08:00
neil a054f6a97b Merge pull request #6240 from Giova96/master
Add FreeMyIP DNS Api Support
2025-03-02 13:06:25 +01:00
neil 63d11c3eea Merge pull request #6245 from aafbsd/patch-1
Support FreeBSD's sed -i
2025-02-28 19:48:05 +01:00
Giovannimaria Gandossi dd2199c472 Adding support for FreeMyIP dns API 2025-02-24 17:03:22 +01:00
aafbsd 661c3bbdb0 Support FreeBSD's sed -i
FreeBSD's sed requires an extension for the backup file when -i is used. However, it may be zero-length to indicate that no backup is desired.
2025-02-24 12:33:42 +00:00
neil 5236e81068 version 3.1.1 2025-02-23 09:28:14 +01:00
neil c459b5eb9d Merge pull request #6243 from acmesh-official/dev
sync
2025-02-23 09:26:46 +01:00
neil 384f0fb89a Merge pull request #6242 from NerLOR/master
dns_world4you: Adapt to change in world4you.com
2025-02-23 09:25:10 +01:00
Lorenz Stechauner 1d628bcf9e dns_world4you: Adapt to change in world4you.com 2025-02-22 18:56:15 +01:00
neil b8644f49ec Merge pull request #6239 from scruel/patch-1
chore(synology): remove personal mail
2025-02-20 10:38:47 +01:00
Scruel Tao 091c1f7ef1 chore(synology): remove personal mail 2025-02-20 17:16:23 +08:00
neil c838c3fa73 Merge pull request #6234 from tomo2403/deployhook-docker
Allow deploying of PKCS to docker containers and other hooks
2025-02-19 21:31:09 +01:00
neil 8bb9106b42 Merge pull request #6226 from davidha/fix-saved-local-hostname
Fix bug saving SYNO_LOCAL_HOSTNAME
2025-02-19 21:29:24 +01:00
tomo a7e3b0d184 Merge branch 'dev' into deployhook-docker 2025-02-15 20:24:05 +01:00
tomo 449c542d5a fixed env warning while building 2025-02-15 17:16:07 +01:00
tomo 7f19f8cf0e implemented deploying pfx to docker container 2025-02-15 15:18:10 +01:00
tomo b2eb704394 allowed deploying of pfx cert 2025-02-15 15:16:52 +01:00
David Ha 899da0c6ea Update synology_dsm.sh
fix check logic
2025-02-09 23:43:55 +00:00
David Ha def41a7878 Fix bug saving SYNO_LOCAL_HOSTNAME
Exporting SYNO_LOCAL_HOSTNAME=1 only works on the first deploy invocation. Subsequent deploys using the saved config fails because it saves $SYNO_HOSTNAME instead of $SYNO_LOCAL_HOSTNAME.
2025-02-09 22:56:46 +00:00
neil 6dbe49089e minor 2025-01-25 21:00:34 +01:00
neil 5883e5159f Merge pull request #6202 from ARNik/dns_beget
Add Beget.com DNS API support
2025-01-18 19:46:24 +01:00
ARNik 26a5d48f63 dnsapi: Beget.com fix case-sensitive domain names 2025-01-16 21:57:41 +03:00
ARNik aa6feb4b62 dnsapi: Beget.com fix rm record 2025-01-16 20:55:56 +03:00
ARNik 2fef0ebea8 dnsapi: Beget.com subdomain preparation rework 2025-01-16 20:55:56 +03:00
ARNik 66dd51a09a dnsapi: check Beget.com API replies 2025-01-16 19:45:26 +03:00
ARNik 077868604d dnsapi: Add Beget.com DNS API 2025-01-15 09:40:31 +03:00
Lindsay Zhou 6c555cb666 fix regex of matching hetzner dns api error responses 2025-01-13 11:11:36 +08:00
neil 0ae80272fb Merge pull request #5237 from markkuleinio/add-he-ddns
Add dnsapi script for HE DDNS
2025-01-11 10:48:12 +01:00
neil 7bef7cf9e2 Merge pull request #6108 from Attackwave/Truenas-Deploy-Websocket
Truenas deploy websocket
2025-01-11 10:46:40 +01:00
neil 6fa24cad18 Merge pull request #6195 from 3VAbdAVE/dev
Fixed cloudkey gen 2 changes
2025-01-10 20:40:28 +01:00
neil 6313020ba9 Merge pull request #6194 from ghen2/hostname
Portability: use `uname -n` instead of `hostname`.
2025-01-10 20:39:45 +01:00
3VAbdAVE b2eead386d Merge remote-tracking branch 'upstream/dev' into dev 2025-01-10 09:19:29 -05:00
Geert Hendrickx b826123d98 Portability: use uname -n instead of hostname.
`hostname` is not available by default on some modern Linux distributions
(eg. Arch Linux), whereas `uname -n` is defined by POSIX, so guaranteed.
2025-01-10 12:39:30 +01:00
neil cf537070d8 Merge pull request #5128 from vlad-kms/master
Feature: Add new version API dns SELECTEL dns_selectel.sh (actual v2)
2025-01-09 22:44:16 +01:00
neil 7a00a1dced Merge pull request #6191 from HTDemony/master
Create script for deploy certificate on Proxmox Backup Server
2025-01-09 22:42:01 +01:00
Demony 80c37ebab2 Merge branch 'dev' into master 2025-01-08 21:37:21 +01:00
neil 5fb4136bcd Merge pull request #6190 from jpmens/patch-2
Correct typo in acme.sh
2025-01-08 19:23:22 +01:00
Yann DEMOULIN 6a249ca1dd Create script for deploy certificate on Proxmox Backup Server 2025-01-07 22:23:27 +01:00
Jan-Piet Mens 5610d4782f Correct typo in acme.sh 2025-01-07 13:13:27 +01:00
Markku Leiniö fef4574c3c Fix option description 2025-01-04 21:34:14 +02:00
neil 65239c7c25 Merge pull request #6184 from JazzMalar/master
Update dns_cyon plugin
2025-01-04 10:43:54 +01:00
Markus Schenk 1b123054b3 also updated the other validation functions 2025-01-03 13:08:18 +01:00
Markus Schenk b29d17f522 changed char class for compatibility with openbsd 2025-01-03 13:04:04 +01:00
Markus Schenk 04aefbf28d moved the env change check to its own function 2025-01-03 00:31:27 +01:00
Attackwave f8fcf02448 Merge branch 'acmesh-official:master' into Truenas-Deploy-Websocket 2025-01-02 19:44:24 +01:00
Markus Schenk 0e4fd5269b run tests 2025-01-02 00:49:20 +01:00
Markus Schenk 6328496bfb run tests 2025-01-02 00:41:59 +01:00
Markus Schenk 524b40b75f adhere to shell formatting 2025-01-02 00:36:28 +01:00
Markus Schenk 0241552c0d update dns_cyon for updated field names and add validation 2025-01-02 00:26:47 +01:00
neil fd3f6687ce Merge pull request #6099 from catap/openbsd
Fix syntax for OpenBSD sh
2025-01-01 15:14:25 +01:00
neil 93d63749e6 Merge pull request #6178 from peterv99/dev
Add mijn.host DNS API Support
2025-01-01 15:10:45 +01:00
neil 41bf5450d9 Merge pull request #6181 from M0NsTeRRR/master
fix: remove control characters
2025-01-01 11:24:21 +01:00
Ludovic Ortega d37553e7b8 fix: remove control characters
Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>
2024-12-31 18:04:39 +01:00
neil 101d7138c2 Merge pull request #6176 from stokito/dnsapi_struct_info_missing
dnsapi: Add structured info for lima-city and west.cn
2024-12-31 11:24:02 +01:00
Sergey Ponomarev 11de3aed51 dnsapi: structured info minor fixes
Extend dns_myapi.sh info with samples.
omglol: Split Address option by a dot to avoid incorrect parsing with a dot from omg.lol

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2024-12-31 11:45:29 +02:00
3VAbdAVE 4bb41cf886 Fixed bad variable. 2024-12-29 12:52:09 -05:00
peterv99 1ae7dd9b11 Updated info block 2024-12-29 09:30:48 +01:00
Sergey Ponomarev a3250fac6d dnsapi: Add structured info for lima-city and west.cn
Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2024-12-28 22:31:24 +02:00
neil fabe6317ef Merge pull request #6174 from stokito/dns_api_fix
DNS API: fix structural info for new providers
2024-12-28 20:05:44 +01:00
3VAbdAVE 23a4af9a52 Merge branch 'acmesh-official:master' into master 2024-12-28 13:19:17 -05:00
peterv99 9526dbadad mijn.host API unreliable, upped retry times to 15 2024-12-28 17:26:52 +01:00
Sergey Ponomarev 6ad469c637 dnsapi: Fix structured info
Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2024-12-28 17:42:58 +02:00
peterv99 b30cdf0873 Merge branch 'dev' of github.com:peterv99/acme.sh into dev 2024-12-28 13:35:53 +01:00
peterv99 234bc93ddb Removed superfluous debug message 2024-12-28 12:42:50 +01:00
peterv99 42862852b8 Corrected sleep message 2024-12-28 12:41:26 +01:00
peterv99 7a6101c417 Corrected sleep time message 2024-12-28 10:22:28 +01:00
peterv99 588123ed11 Updated backoff algorithm 2024-12-27 23:56:13 +01:00
peterv99 ac9852f9df Added fix for specific API error that mijn.host sometimes throws. 2024-12-27 16:47:02 +01:00
peterv99 d093476da5 Refactored REST calls to add generic retries,
as mijn.host API times out at times.
2024-12-27 12:55:12 +01:00
peterv99 9ad794f2cc Name change, function name change to mijnhost 2024-12-27 08:56:16 +01:00
peterv99 b0f566a80d Name change to be in line with other API scripts
Added time-out to _get calls at 120s to fix API timeouts
2024-12-26 23:36:55 +01:00
Vladimir Alexeev d3f3a70350 keep content:
# dns_selectel_info='Selectel.com
# Domains: Selectel.ru
# Site: Selectel.com
# Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_selectel
# Options:
# Variables that must be defined before running
2024-12-26 08:45:03 +10:00
Vladimir Alexeev 3f262fe872 keep content:
# dns_selectel_info='Selectel.com
# Domains: Selectel.ru
# Site: Selectel.com
# Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_selectel
# Options:
# Variables that must be defined before running
2024-12-26 08:12:36 +10:00
peterv99 150c708726 Better debug messages for root domain detection 2024-12-25 14:11:52 +01:00
peterv99 7512dbffbb Fixed yet another error in dns_rm 2024-12-25 09:50:27 +01:00
peterv99 3cfa882fe1 Fixed error in dns_mijn_host_rm 2024-12-25 08:52:09 +01:00
peterv99 35f3b7088d Updated PUT request to hold only fqdn domain name values# 2024-12-25 00:00:19 +01:00
peterv99 07220a324d Removed all jq references 2024-12-24 23:21:50 +01:00
peterv99 c7cecd5b4f Removed "." from _sub_domain to create a valid domain. 2024-12-24 17:30:50 +01:00
peterv99 ab1a2045d9 Made string removal in root domain detection posix compliant 2024-12-24 17:10:30 +01:00
peterv99 5e9a067e87 Fixed root domain detection and processing. 2024-12-24 16:55:26 +01:00
Peter Vos 4cc460be64 Added dns challenge for mijn.host 2024-12-24 13:33:15 +01:00
Vladimir Alexeev 112bfccfd5 fix _get_root() make it start from 1. because we need to support --domain-alias (only version api actual v2) 2024-12-24 16:00:01 +10:00
Владимир Алексеев b29cb08956 Merge branch 'acmesh-official:master' into master 2024-12-23 14:51:57 +10:00
Vladimir Alexeev e42ad9be24 fix
don't use debug3, use debug2
  add # shellcheck disable=SC2034
2024-12-23 14:50:28 +10:00
neil 02da1700e0 fix format 2024-12-22 14:19:58 +01:00
neil a9f97e1fe2 fix format 2024-12-22 14:17:33 +01:00
neil d75077c6f9 fix format 2024-12-22 13:36:43 +01:00
neil b81939f02d Merge pull request #6168 from adn77/master
Fix keystore ownership in Unifi deployment - unifi.sh
2024-12-22 13:26:26 +01:00
Alex 0e1d90dd0c Properly guess system.properties location 2024-12-20 10:36:45 +01:00
Alex 03e9c612b9 Correct file ownership according to keystore directory 2024-12-20 10:34:51 +01:00
neil ee661e5d71 fix format 2024-12-10 21:02:54 +01:00
neil 5ddffc9172 fix format 2024-12-10 21:01:37 +01:00
neil f981c782bb Merge pull request #6160 from acmesh-official/dev
sync
2024-12-10 21:00:22 +01:00
neil 40dd085ef8 Merge pull request #6159 from acmesh-official/dev
fix format
2024-12-10 20:59:27 +01:00
neil 3fbdb7a007 fix format 2024-12-10 20:58:02 +01:00
neil d5b5bcef56 support ARI, not finished yet
https://github.com/acmesh-official/acme.sh/issues/4944
2024-12-10 20:54:20 +01:00
neil 2997a15ba8 Merge pull request #6136 from lukavia/dev
Add support for ZoneEdit.com
2024-12-09 09:22:54 +01:00
neil b4c02eca16 Merge pull request #6114 from NerLOR/master
dns_world4you: Adapt to change in world4you.com DeleteDnsRecordForm
2024-12-07 23:01:16 +01:00
neil 223dc87cef usage 2024-12-07 22:50:12 +01:00
neil 3ccdae0634 Merge pull request #4832 from kchiem/dev
deploy hook for Ruckus ZoneDirector / Unleashed
2024-12-07 22:24:04 +01:00
Anton Avramov 11af6f49c6 Add support for ZoneEdit.com 2024-12-05 22:12:04 -05:00
Kevin Locke 22dfedf6ae Avoid permissions errors for chown .well-known
When acme.sh is run as a non-root user different from the owner of the
webroot directory it is unable to change the owner of the files in
.well-known to that user, causing permissions errors.  Avoid this by
making the files world-readable.

These files should pose no disclosure risk since they are sent in
cleartext during the HTTP Identifier Validation Challenge[1] and may
already be exposed by directory enumeration, depending on server
settings.  AFAIK they should be safe to expose as world-readable in all
cases.

1.  https://ietf-wg-acme.github.io/acme/#rfc.section.7.2

Fixes Neilpang/acme.sh#32
Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
2024-11-30 16:34:52 -07:00
Lorenz Stechauner 157d3f9dc9 dns_word4you: Fix for OpenBSD 2024-11-30 20:25:55 +01:00
3VAbdAVE f3b2ab5e60 Fix gen1 cloudkey's symlinked keystore 2024-11-30 10:32:24 -05:00
neil fca53a0c2c Merge pull request #6117 from qupfer/technitum
add dns_api for Technitum dns server
2024-11-28 12:22:52 +01:00
Henning Reich 6d302889fa small cleanup 2024-11-27 10:11:50 +01:00
Henning Reich a94ac63e74 add issue link 2024-11-27 09:20:57 +01:00
Henning Reich 19e73f8889 add account to rm function 2024-11-26 12:29:07 +01:00
Henning Reich aacc26179e remove comments 2024-11-26 12:17:11 +01:00
Henning Reich 36f060dcf6 add author 2024-11-26 11:42:05 +01:00
Henning Reich cb12c8dfd5 working example 2024-11-26 11:21:17 +01:00
Lorenz Stechauner 9cd1d1a9dc dns_world4you: Adapt to change in world4you.com DeleteDnsRecordForm 2024-11-26 09:20:18 +01:00
Attackwave ebaf4c9c01 Update truenas_ws.sh (Output new certificate name) 2024-11-25 21:23:59 +01:00
Attackwave 44240339d9 Update truenas_ws.sh (Interpreter changed from bash to sh) 2024-11-25 21:13:43 +01:00
Attackwave 9110375173 Update truenas_ws.sh (fixed shfmt) 2024-11-25 20:50:40 +01:00
qupfer c3557bbe3f 1 2024-11-25 20:26:23 +01:00
Henning Reich cd924099e4 add template 2024-11-25 17:46:59 +00:00
Attackwave f2a311bb81 Update truenas_ws.sh (added return instead exit) 2024-11-25 14:44:52 +01:00
Attackwave d7855e8fe5 Update truenas_ws.sh (shfmt and shellcheck) 2024-11-24 14:59:51 +01:00
Attackwave 1e52efa867 Merge branch 'acmesh-official:master' into Truenas-Deploy-Websocket 2024-11-24 14:39:58 +01:00
neil 5d6f1bd2d7 Merge pull request #6110 from acmesh-official/dev
sync
2024-11-23 11:00:10 +01:00
neil 48ccaa8b91 Merge pull request #6106 from CreatorHRS/dev
fix: new version of fornex dns based on api version 2.3.1
2024-11-23 10:51:21 +01:00
mikhailkhr 54ac0048c4 fix: missing quotes 2024-11-20 12:43:58 +03:00
mikhailkhr 276e089419 fix: new version of fornex dns based on api version 2.3.1 2024-11-20 12:38:06 +03:00
Kirill A. Korinsky 3b8608761b Fix syntax for OpenBSD sh 2024-11-17 20:58:06 +01:00
Attackwave 413a91646c Create truenas_ws.sh 2024-11-16 19:15:39 +01:00
kchiem 4299c6a802 Merge pull request #5 from ms264556/dev
Remove awk usage & refuse host redirects
2024-11-15 00:32:43 -08:00
ms264556 4232923641 Remove awk usage and refuse redirect to new host 2024-11-15 12:39:41 +13:00
neil 75b4bb306b Merge pull request #6096 from acmesh-official/dev
sync
2024-11-14 20:44:30 +01:00
neil 4e0686f73c fix for omnios-r151052 2024-11-14 20:35:15 +01:00
neil 709f1e76d3 fix for omnios-r151052 2024-11-14 20:17:03 +01:00
neil 0c2d7b9c06 fix for latest omnios-r151052 2024-11-14 20:03:32 +01:00
kchiem 412e14a41c Merge pull request #4 from ms264556/dev
fix acme.sh PR shfmt failure
2024-11-13 12:04:16 -08:00
neil 532b425dd9 Merge pull request #5276 from stbeldarborge/master
Add existing bearer token support to Azure DNS API
2024-11-13 20:21:39 +01:00
ms264556 2bb5fbdee5 Remove HTTPS_INSECURE 2024-11-14 07:21:19 +13:00
ms264556 38c41b72d6 fix acme.sh PR shfmt failure 2024-11-14 07:16:38 +13:00
neil 30e89c3cdc Merge pull request #6094 from sergiustheblack/feature/swanctl
StrongSwan deploy hook: swanctl support
2024-11-13 09:01:54 +01:00
kchiem b665014707 Merge pull request #3 from ms264556/dev
Fix info logging
2024-11-12 21:11:22 -08:00
ms264556 e98e7a232f Fix info logging 2024-11-13 17:27:36 +13:00
kchiem 5f7ad72d45 Merge pull request #2 from ms264556/dev
fix insecure password debug and _info typo
2024-11-12 18:19:03 -08:00
Sergey Parfenov 9c25365b12 Add swanctl support 2024-11-13 04:07:28 +03:00
ms264556 0cc74b7cfe fix insecure password debug and _info typo 2024-11-13 12:50:51 +13:00
neil 8a972ea213 Merge pull request #6089 from M0NsTeRRR/master
fix(truenas): broken script since 23.10 scale release
2024-11-12 22:32:36 +01:00
Ludovic Ortega 2229bcc98b fix: echo flag 2024-11-12 22:15:44 +01:00
Ludovic Ortega 1bfd4672e1 fix: remove double square brackets 2024-11-12 22:10:34 +01:00
neil 15e9e8575a Merge pull request #5172 from vmmello/issue_4956
Fixes issue 4956: 'Linode DNS Pagination Bug'
2024-11-12 21:32:13 +01:00
kchiem d7bafa6dfa Merge pull request #1 from ms264556/dev
Rewrite deploy/ruckus.sh to use _get() and _post()
2024-11-12 00:38:37 -08:00
neil 35632f2109 Merge pull request #6093 from acmesh-official/dev
sync
2024-11-11 22:43:23 +01:00
Ludovic Ortega 08807b498e fix: bad copy/paste
Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>
2024-11-10 13:30:18 +01:00
Ludovic Ortega e8a453c567 fix: lint
Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>
2024-11-10 13:21:09 +01:00
ms264556 717802611a remove dead code 2024-11-10 22:43:57 +13:00
ms264556 b6a77e0231 Ruckus - use _get() and _post() 2024-11-10 22:12:38 +13:00
Ludovic Ortega 21b966c8e6 fix: don't check for subversion that can lead to error
Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>
2024-11-10 02:56:40 +01:00
Ludovic Ortega 64a1e88982 feat: add support for docker apps
Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>
2024-11-10 02:41:38 +01:00
Ludovic Ortega 34c8b882c6 fix: helm chart seems available only on truenas scale
Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>
2024-11-10 00:34:26 +01:00
Ludovic Ortega fa420d70cc fix: verify truenas os version 2024-11-10 00:13:53 +01:00
Ludovic Ortega 2c67934191 fix(truenas): builtin service deprecation 2024-11-09 23:29:52 +01:00
neil 821adcf178 Merge pull request #6087 from stokito/dnsapi-info
Dns API: fix structural info
2024-11-09 19:24:18 +01:00
Sergey Ponomarev 8bf9482bc0 dnsapi ionos_cloud: Use structured info
Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2024-11-09 18:31:52 +02:00
Sergey Ponomarev fe8ad3548b dnsapi alviy: Use structured info
Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2024-11-09 18:22:01 +02:00
Sergey Ponomarev 4f17bc0d86 dnsapi timeweb: Use structured info
Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2024-11-09 18:20:58 +02:00
Sergey Ponomarev 1a43c81840 dnsapi omg.lol: fix info
Description "Based on the omg.lol API" is useless for users so removed.
The link to api moved to comment bellow.
Domains: omg.lol is unnecessary because the DNS provider name is anyway omg.lol.
Site: changed to point to the https://omg.lol site.
Issues: put a link to the support issue.

Remove the useless "Please Read this guide first" comment.
Fix typos.

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2024-11-09 18:10:25 +02:00
Vinicius Mello d3cf3f7a5c fix pagination bug for domains with a big zone file
the same pagination bug that happens for accounts with a large number of
domains also happens for DNS zones with a large number of records. The
previous code assumes that all records are returned in a single page.

Changed the code to do an exact match search so that it returns only the few
required records and never paginates replies.
2024-11-08 00:59:21 -03:00
Vinicius Mello 4f96a2a667 remove unnecessary variable 'export' on variable _H4 2024-11-07 17:36:25 -03:00
Vinicius Mello 7b63ebfcaa fix random failures due to unnecessary headers on requests
was unintendedly replaying the save _H4 header on all requests, what was
causing random failures on responses from the API.
2024-11-07 12:33:56 -03:00
Vinicius Mello 724f3aa301 rename variable, undo accidental revert from dev 2024-11-06 16:20:55 -03:00
vmmello 1ff326c89c dns_linode_v4.sh: trigger action 2024-11-05 14:57:28 -03:00
vmmello 2663f500cf dns_linode_v4.sh: trigger action 2024-11-05 11:43:04 -03:00
vmmello 43ed998ed6 dns_linode_v4.sh: trigger action execution (dummy change) 2024-11-05 11:26:37 -03:00
vmmello a3032ab945 dns_linode_v4.sh: remove uneeeded extra space (shfmt error) 2024-11-05 11:10:55 -03:00
vmmello af9425ed8f Merge branch 'dev' into issue_4956 2024-11-05 11:07:20 -03:00
neil d058ac6174 Merge pull request #5328 from sahsanu/dev
Fix dns_pdns.sh to use saved account conf
2024-11-03 13:22:29 +01:00
neil a4e7806d21 fix https://github.com/acmesh-official/acme.sh/issues/5208 2024-11-03 13:09:52 +01:00
Vinicius Mello 03906cc055 trigger github action 2024-10-28 12:07:33 -03:00
Vinicius Mello 10833dcf39 trigger github action 2024-10-28 11:50:28 -03:00
neil a00323412b Merge pull request #5374 from ryoon/posix-shell-portability
Fix POSIX shell portability
2024-10-25 08:55:38 +02:00
Ryo ONODERA 838a20ea95 Fix POSIX shell portability
POSIX standard says test command has '=" as for checking identical.
'==' is bash dialect.
Replace '==' with '='.

See:
https://pubs.opengroup.org/onlinepubs/009604399/utilities/test.html
2024-10-24 22:52:28 +09:00
Владимир Алексеев e8ed8cbfcd Merge branch 'dev' into master 2024-10-22 05:25:27 +10:00
neil 5c78a5e4fe Merge pull request #5331 from lifeboy/revert-TXT-add-update
Revert txt add update
2024-10-16 17:29:14 +02:00
Roland Giesler 30ed4af38d Revert TXT add update
The change was needed for Power-Mailinabox and broke Mail-in-a-box, so a new API for Power-Mailinabox has been added
2024-10-16 11:49:29 +02:00
sahsanu 6a9304dd1c Change _saveaccountconf to _saveaccountconf_mutable 2024-10-16 09:03:18 +02:00
sahsanu 1782eeb785 Fix dns_pdns.sh to use saved account conf 2024-10-14 16:18:44 +02:00
sahsanu 1aabb7d6de Fix dns_pdns.sh to use saved account conf 2024-10-14 15:59:54 +02:00
neil d4b8f9700b Merge pull request #5326 from acmesh-official/dev
sync
2024-10-13 18:02:13 +02:00
neil 2ebecf1aa0 fix format 2024-10-13 17:59:25 +02:00
neil 7031df4948 fix format 2024-10-13 17:58:19 +02:00
neil e0381dd757 fix format 2024-10-13 17:55:22 +02:00
neil 9b2eae24d2 fix format 2024-10-13 17:49:29 +02:00
neil 7362e8de4d fix format 2024-10-13 17:41:22 +02:00
neil 87beb0a5f2 fix name 2024-10-13 17:26:14 +02:00
neil fc69cea4f7 Merge pull request #5323 from allddd/update_porkbun_url
Update Porkbun API URL
2024-10-12 20:46:07 +02:00
allddd ad4780a1ac update api url 2024-10-12 01:07:35 +02:00
Eldar Borge 72f487d2e3 Merge branch 'acmesh-official:master' into master 2024-10-11 09:11:00 +02:00
stbeldarborge 0c10bd7dd7 shfmt 2024-10-10 12:35:05 +02:00
stbeldarborge b0418cb394 trigger 2024-10-10 12:23:07 +02:00
stbeldarborge a30c81dadc bearetoken 2024-10-10 12:00:11 +02:00
stbeldarborge 40df6e87db newline 2024-10-10 11:54:42 +02:00
stbeldarborge 0dff1dce8f accoutn conf 2024-10-10 11:50:57 +02:00
stbeldarborge ffd3b3e6b5 revert 2024-10-10 11:36:37 +02:00
stbeldarborge 1305b0d8dd revert 2024-10-10 11:29:34 +02:00
stbeldarborge 5fc41a3ea2 read account conf 2024-10-10 11:24:24 +02:00
stbeldarborge fc87fc7cab debug 2024-10-10 11:18:03 +02:00
stbeldarborge 8887a0a6d3 new name 2024-10-10 11:09:25 +02:00
stbeldarborge ba7764aeaf saveaccountconf 2024-10-10 10:59:29 +02:00
stbeldarborge 28afe6f29f comment 2024-10-10 10:30:54 +02:00
neil 138ab6dbbd Merge pull request #5315 from fazelukario/patch-1
Fix markdown issue in telegram notify hook
2024-10-07 08:48:02 +02:00
fazelukario 26c2fc21c8 Moving to MarkdownV2 as the old Markdown is obsolete
- Implemented MarkdownV2 with escape of all necessary characters.
- Ref: https://core.telegram.org/bots/api#markdownv2-style
2024-10-07 05:16:11 +03:00
fazelukario fef74c3bca feat Cross-Platform Compatibility Guide 2024-10-07 03:46:35 +03:00
fazelukario c390f1bfee Escape markdown for subject 2024-10-07 03:34:49 +03:00
neil f6698d4a84 Merge pull request #5301 from as-kholin/dns_omglol
Adding omg.lol DNS API
2024-10-06 11:52:33 +02:00
Gary McGregor 4193196c8b Merge remote-tracking branch 'upstream/dev' into dns_omglol 2024-10-04 23:39:55 -05:00
neil da06dc3728 Merge pull request #5313 from abulgatz/patch-1
Updated MS links, added wiki link, updated error messages, updated API limit comment
2024-10-03 09:33:19 +02:00
Adam Bulgatz a0b8be5941 Updated MS links, added wiki link, updated error messages, updated API limit comment
Updated all Microsoft links from old `docs` subdomain to new `learn` subdomain, and fixed a couple that weren't working.

Added missing $wiki variable to print the wiki link in error messages.

Updated spelling and formatting in error messages

Updated a comment and added a TODO as Microsoft has increased the number of allowed Public DNS zones per subscription from 100 to 250, while the function in this script can only handle the old limit of 100.
2024-10-03 01:24:07 -05:00
Gary McGregor fe971680ea With variable name updates, correct missed update for the name for saved variables 2024-09-30 07:42:09 -05:00
Gary McGregor 254eb8f304 Updated variable names per @NeilPang 2024-09-30 06:47:26 -05:00
Gary McGregor c9d15901d1 Merge remote-tracking branch 'upstream/master' into dns_omglol 2024-09-30 06:46:30 -05:00
Gary McGregor 59b3f5fb19 Merge remote-tracking branch 'upstream/dev' into dns_omglol 2024-09-29 23:09:22 -05:00
Gary McGregor dbe9dd47ce Correcting over-correct on debugging levels 2024-09-29 23:08:39 -05:00
neil 8e35f8c3aa Merge pull request #5309 from jschauma/master
on OpenBSD, add libiconv
2024-09-29 21:34:28 +02:00
Gary McGregor 80970a0ac6 Merge remote-tracking branch 'upstream/dev' into dns_omglol 2024-09-29 13:35:23 -05:00
Gary McGregor 432f6ac4d7 Updated input parameters per feedback from @Neilpang. Also updated debugging statements to be consistently applied. 2024-09-29 13:34:34 -05:00
neil eaf11009d1 Merge pull request #5310 from acmesh-official/dev
sync
2024-09-29 12:46:32 +02:00
neil df93fb773f Merge pull request #5297 from PMExtra/feature/ali_dcdn
Add ali_dcdn deploy hook (Alibaba Cloud DCDN)
2024-09-29 12:23:31 +02:00
Gary McGregor f6887a4dac Merge remote-tracking branch 'upstream/dev' into dns_omglol 2024-09-28 22:50:47 -05:00
Jan Schaumann 1c58c4c409 on OpenBSD, add libiconv
acme.sh dnsapi/dns_edgedns.sh invokes iconv(1) which is not provided by
OpenBSD in the base system. Adding the libiconv package provides this tool.

This should also help address acmesh-official/acme.sh#4350, albeit indirectly:
it looks like that PR cannot be merged because the OpenBSD test fails despite
the PR not actually changing anything having to do with iconv. That is, I
suspect that the test for OpenBSD failed (or would have failed, had it been
run?) prior to that PR being issued.

(This was previously submitted as
https://github.com/acmesh-official/acmetest/pull/28 )
2024-09-28 14:18:22 -04:00
neil a972901438 Merge pull request #5305 from mpgirro/oci-image-source
Add OpenContainers Annotations as Labels to Docker Image
2024-09-27 08:45:10 +02:00
Maximilian Irro 25703296a6 Add OpenContainer Image Format Annotations as Labels to Docker Image 2024-09-26 21:50:06 +02:00
PM Extra 7ebe97b931 Merge pull request #1 from ShirasawaSama/patch-1
fix: fix ali_dcdn function naming typo
2024-09-25 14:30:10 +08:00
Shirasawa 76719d1bf5 fix: fix ali_dcdn function naming typo 2024-09-25 00:27:04 +08:00
Gary McGregor cb113437f6 Updating per comment re: Exit vs Return on initial validation 2024-09-24 07:23:39 -05:00
Gary McGregor e6b3e42d61 Adding omg.lol DNS API 2024-09-23 22:21:37 -05:00
neil c20b0169a9 upgrade version 2024-09-23 18:15:10 +02:00
PMExtra 89342bcb75 add ali_dcdn deploy hook 2024-09-23 15:11:52 +08:00
neil e036eea362 Merge pull request #5158 from henrikalves/dode
update dns_doapi
2024-09-21 17:29:26 +02:00
neil 2044d633e9 Merge pull request #5183 from WinSCaP/patch-1
Update dns_openprovider.sh for OpenProvider
2024-09-21 17:24:53 +02:00
neil 8cb684e6bd fix https://github.com/acmesh-official/acme.sh/issues/5067 2024-09-21 17:11:17 +02:00
neil 997bd3392f fix https://github.com/acmesh-official/acme.sh/issues/5293 2024-09-21 13:21:32 +02:00
neil ad44c87746 Merge pull request #5296 from nikolaypronchev/master
Fix Timeweb Cloud DNS API pagination
2024-09-21 13:03:21 +02:00
Nikolay Pronchev 45ea2f82ba explicitly reset *_return variables 2024-09-20 15:14:30 +00:00
Nikolay Pronchev df6aa99ec2 fix Timeweb Cloud DNS API pagination 2024-09-20 14:00:44 +00:00
stbeldarborge 1029dd3504 fix format 2024-09-20 15:44:50 +02:00
neil 114eb6288d Merge pull request #5294 from PMExtra/refactor/ali_api
refactor: Alibaba Cloud API
2024-09-20 09:33:44 +02:00
PMExtra 2ea37e6a0d refactor(ali): check the result of prepare_ali_credentials 2024-09-20 14:55:33 +08:00
PMExtra ea2330b49f refactor(ali): move the loading script into ali_cdn_deploy 2024-09-20 14:54:07 +08:00
PMExtra 610bb2b85c refactor(ali): set API endpoint for each action 2024-09-19 16:30:04 +08:00
PMExtra fca6e9b932 refactor: Alibaba Cloud API 2024-09-19 15:49:42 +08:00
neil fc7f86104e Merge pull request #5290 from acmesh-official/dev
sync
2024-09-18 08:58:43 +02:00
neil d057a9bb6d update version 2024-09-18 08:57:32 +02:00
neil 167aba6f26 Merge pull request #5285 from markt-de/fix_nsupdate
URGENT: fix dns_nsupdate when NSUPDATE_OPT is empty
2024-09-17 17:52:09 +02:00
Frank Wall 9ecd84080b resolve shellcheck offenses
With nsupdate the rule seems to be: filenames need to be wrapped
in double quotes, while all other options must not use double quotes.
Hence there is no way to resolve the shellcheck offense, because
the key requires quotes, but the other options must not use quotes.
2024-09-17 15:27:46 +02:00
Frank Wall 22d260f4e6 fix dns_nsupdate when NSUPDATE_OPT is empty, refs #5224 2024-09-16 16:49:28 +02:00
neil ea94477cd4 Merge pull request #5229 from tomo2403/master
Update bark.sh
2024-09-15 17:51:52 +02:00
tomo 522c953860 Update dockerhub.yml 2024-09-15 17:08:09 +02:00
neil f86ee84457 fix format 2024-09-15 14:31:15 +02:00
neil 2d282597ca fix format 2024-09-15 14:30:12 +02:00
neil 8635d89cc8 Merge pull request #5029 from scruel/patch-2
Prevent leaving blank lines in config file after cleared keys.
2024-09-15 13:58:09 +02:00
neil dc341ef9c1 Merge pull request #5149 from Weishaupt/patch-1
Fix missing XML Escape in Password of INWX DNS API
2024-09-15 13:46:38 +02:00
neil beb31ab2fa Merge pull request #5246 from 3VAbdAVE/dev
Updating unifi deploy hook - remove keytool requirement
2024-09-15 13:43:18 +02:00
neil e0214a2c2a Merge pull request #5218 from IIIPr0t0typ3III/dev
2 Bugfixes of `dns_dynv6.sh`: 1. domains containing 'id' are now working as intended and 2. hostnames are now cast to lowercase on the fly
2024-09-15 13:39:27 +02:00
neil 5275daa66c Merge pull request #5231 from mickaelmonsieur/master
Update dns_ispconfig.sh
2024-09-15 13:35:38 +02:00
neil fb27261568 Merge pull request #5284 from acmesh-official/dev
sync
2024-09-15 11:09:49 +02:00
neil 5a20ce81e3 Merge pull request #5117 from alviy/master
New Alviy provider
2024-09-13 14:29:48 +02:00
neil 1454b85671 Merge pull request #5223 from Linkje/update-teams-notification-workflow
Update teams notification workflow
2024-09-13 14:25:16 +02:00
neil fc4dba4468 Merge pull request #5187 from rwese/improve-dns_anx-performance
improve performance and memory usage for dns_anx
2024-09-13 14:22:01 +02:00
neil adff28dade Merge pull request #5224 from gmanic/master
Add optional cmd line parameter NSUPDATE_OPT to dns_nsupdate api
2024-09-13 14:13:40 +02:00
neil c345ecae63 Merge pull request #5141 from nikolaypronchev/master
Add Timeweb Cloud DNS API
2024-09-13 14:03:46 +02:00
neil e6461380c6 Merge pull request #5205 from PMExtra/feature/ali_cdn
feat(deploy_ali_cdn): support Alibaba Cloud CDN deployment
2024-09-13 13:58:52 +02:00
neil deb2a3e415 Merge pull request #5263 from i18nsite/patch-1
Update dns_huaweicloud.sh
2024-09-13 13:57:07 +02:00
neil c71dcd7611 Merge pull request #5214 from WhiteAls/yandex360
Support for the Yandex 360 for Business DNS API
2024-09-13 13:55:01 +02:00
neil c1e05664ed Merge pull request #5268 from lifeboy/patch-1
Fix MIAB dns create TXT record format
2024-09-09 15:15:23 +02:00
Nikolay Pronchev 0f1e5f4fa4 Merge branch 'acmesh-official:master' into master 2024-09-06 19:28:44 +03:00
stbeldarborge 8860915fb9 remove dns 2024-09-03 21:36:54 +02:00
stbeldarborge f0d486d1ff add bearer token to removal 2024-09-03 20:59:17 +02:00
WhiteAls 0fa20da990 Little optimisations and fixes.
- Removed or moved `_normalizeJson` processing to occur only when needed.
- Corrected usage of `_red` to `__red`.
- Simplified JSON parsing by using more concise `cut` commands.
- Simplify token refresh logic.
2024-09-03 17:11:43 +00:00
stbeldarborge b27767e8f4 logic 2024-09-02 16:04:34 +02:00
stbeldarborge 0b2edd28df bearer check 2024-09-02 16:02:36 +02:00
stbeldarborge dd634382d7 debug 2024-09-02 15:57:48 +02:00
stbeldarborge c7fb155733 debug 2024-09-02 15:56:12 +02:00
stbeldarborge 1eaa2cc619 debug 2024-09-02 15:53:33 +02:00
stbeldarborge 92a47aaac5 logic 2024-09-02 15:41:55 +02:00
stbeldarborge fcffe8beb9 feat: add bearer token support 2024-09-02 15:40:45 +02:00
Lifeboy 02fb40c507 Syntax corrections, previous change broke script 2024-09-02 14:56:00 +02:00
Lifeboy dc6ea97877 Syntax corrections, previous change broke script 2024-09-02 14:54:22 +02:00
Lifeboy 031d53b04f Syntax corrections suggested by testing script 2024-09-02 12:14:22 +02:00
Lifeboy 3006c90fb8 Syntax corrections suggested by testing script 2024-09-02 12:04:56 +02:00
Lifeboy 9cec2688ed Syntax corrections suggested by testing script 2024-09-02 11:58:27 +02:00
Lifeboy 65c3dc21f4 Added comments 2024-09-02 11:50:33 +02:00
i18n.site cefa7d940a Update DNS.yml
DNS.yml can be triggered manually
2024-08-28 11:31:29 +08:00
Lifeboy fab292d2de correct a typo 2024-08-27 17:06:36 +02:00
i18n.site 00bbe68f78 Update dns_huaweicloud.sh
fix https://github.com/acmesh-official/acme.sh/issues/5261
2024-08-23 16:00:08 +08:00
Lifeboy fa3591f4f2 TXT record ADD test successfully 2024-08-22 14:39:09 +02:00
Nikolay Pronchev 10cfc6838d add Timeweb Cloud DNS API 2024-08-22 09:12:21 +03:00
Lifeboy 42e78f9a3e changes not yet tested 2024-08-21 15:42:49 +02:00
Roland Giesler 0122eabd44 Update dns_miab.sh
Corrected typo
2024-08-21 15:10:37 +02:00
Roland Giesler 435bb3f1d3 Update dns_miab.sh
The MIAB API requires that the txtvlaue to a TXT record includes the "value=" and "ttl=" components as part of the TXT record when adding a new record.
2024-08-21 12:13:04 +02:00
neil 1d59d43286 Merge pull request #5255 from acmesh-official/dev
sync
2024-08-20 11:59:56 +08:00
neil fe30bf7d09 Merge pull request #5252 from williamdes/patch-1
Add ACCOUNT_THUMBPRINT to update account
2024-08-19 22:16:44 +08:00
neil 5f68ad4e19 fix 2024-08-19 22:15:50 +08:00
William Desportes 3fc39aad33 Add ACCOUNT_THUMBPRINT to update account
Ref: #590
2024-08-19 13:30:11 +00:00
3VAbdAVE a94653ba77 Merge branch 'dev' of https://github.com/3VAbdAVE/acme.sh into dev 2024-08-15 11:25:36 -04:00
3VAbdAVE d8637b2c0f fixes #3359
Ubiquiti removed keytool (and java) from recent releases of Unifi OS. This moves from keytool to openssl's native pkcs12.

Tested on Unifi Dream Machine which runs Unifi OS and a built-in Unifi controller.

Also added backup of existing files prior to change in case anything goes wrong, and update system configuration with compatible ciphers.
2024-08-15 11:25:23 -04:00
3VAbdAVE f1b6016157 Merge branch 'acmesh-official:dev' into dev 2024-08-15 11:18:31 -04:00
3VAbdAVE de99d6d9fc fixed shfmt 2024-08-15 11:09:40 -04:00
neil bb8386ab85 Merge pull request #5245 from nathanejohnson/master
RouterOS - make deploy more resilient
2024-08-15 19:57:44 +08:00
3VAbdAVE ca6226359b removed old comment 2024-08-11 22:49:20 -04:00
3VAbdAVE adfafe5c54 reverted bad merge 2024-08-11 22:48:44 -04:00
3VAbdAVE a8d8fefceb Merge branch 'acmesh-official:dev' into dev 2024-08-11 22:47:00 -04:00
3VAbdAVE 3bb5943b20 Merge branch 'dev' of https://github.com/3VAbdAVE/acme.sh into dev 2024-08-11 22:44:13 -04:00
3VAbdAVE 57da04b5ec Updated Unifi deploy hook to use openssl's pkcs12 instead of Java Keytool after Ubiquiti removed it, update system configuration for stronger ciphers, and back up existing certificates prior to change. 2024-08-11 22:39:47 -04:00
Nathan Johnson e711d168df RouterOS - make deploy more resilient
In the case where importing the cert and key removes the files from disk
the existing deploy will fail when it tries to remove those files.  This
still attempts to remove the files but catches the error and moves on instead
of bombing like before.

Similarly, if the deploy had failed before, subsequent deploys would fail
because the script already existed, so it would not be able to create
the script.  This first attempts to remove the script if it exists, and then
creates the script.
2024-08-09 16:38:09 -05:00
Markku Leiniö 833632eee3 Add shellcheck disable=SC2034 for the info variable 2024-08-04 19:15:11 +03:00
Markku Leiniö abc76299c0 Fix documentation link 2024-08-04 18:58:59 +03:00
Markku Leiniö c96fcf319a Remove dns_he_ddns_rm(), not used 2024-08-04 18:25:20 +03:00
Markku Leiniö 5214a7c3ec Add dnsapi script for HE DDNS 2024-08-04 18:19:21 +03:00
WhiteAls 1700f064b3 Fix: Support for IDN 2024-08-03 18:59:29 +00:00
3VAbdAVE de902166a8 Replaced keytool with openssl pkcs12. Added backup of original certificates. 2024-08-01 08:15:16 -07:00
WhiteAls 2f08bd1965 Refactor: Improve Yandex360 DNS API integration:
- Make YANDEX360_ORG_ID optional and auto-retrieve if not provided.
- Refactor _get_root function to search across multiple organizations.
2024-08-01 03:28:32 +00:00
WhiteAls 13c68cd799 Refactor: Rename _check_yandex360_variables to _check_variables and improve error handling 2024-08-01 03:04:23 +00:00
WhiteAls c7d78f4594 Fix: Corrected the entry point for Yandex 360 API 2024-08-01 02:44:22 +00:00
WhiteAls 2f1ca949f0 Fix: Make record_id extraction independent of JSON key order 2024-08-01 02:33:09 +00:00
WhiteAls a6488ff9ac Optimizing debug output 2024-08-01 02:18:48 +00:00
Mickael cb5eae888d Update dns_ispconfig.sh
Add permissions to:
- Client functions
- DNS zone functions
2024-07-31 16:22:12 +02:00
tomo b6f7710621 Update bark.sh
Bark API v2 is now fully implemented. BARK_SOUND is now also optional, as intended by the API.
2024-07-27 14:28:07 +02:00
tomo 3e36f05a8c Update dockerhub.yml 2024-07-27 14:23:07 +02:00
gmanic bcb7e5f2c8 Update dns_nsupdate.sh
Corrected required variable double quote
2024-07-24 20:28:39 +00:00
Joris van den Dries 3cefcd8204 change reference to static value 2024-07-24 15:02:48 +02:00
Joris van den Dries 4cd1871816 Removed obsolete documentation 2024-07-24 12:23:17 +02:00
Joris van den Dries 7aaa9583fa Update teams notify script to support new notification setup using workflows instead of connectors being fased out.
Color support has been dropped since this has no support inside adaptive-card
2024-07-24 12:05:57 +02:00
Felix Schmidt dd582c0306 Changed the direct call of tr to cast to lower case to the function
`_lower_case` which is already provided.
2024-07-23 12:59:42 +02:00
neil 5cded5b53e Merge pull request #5217 from oittaa/patch-2
_checkSudo: [ -z "__INTERACTIVE" ] should be [ -z "$__INTERACTIVE" ]
2024-07-23 09:05:37 +08:00
IIIPr0t0typ3III 0a64567822 Merge branch 'acmesh-official:dev' into dev 2024-07-22 15:47:54 +02:00
WhiteAls 7ca861805d Fixed incorrect links in informational messages 2024-07-20 19:03:38 +03:00
oittaa 6b6faa8129 _checkSudo: [ -z "__INTERACTIVE" ] should be [ -z "$__INTERACTIVE" ]
Fixes #5216
2024-07-20 13:31:53 +02:00
WhiteAls f84577bcda Support for the Yandex 360 for Business DNS API 2024-07-20 05:41:54 +03:00
WhiteAls 37f9fd3498 The old Yandex DNS API was discontinued #4555 2024-07-20 05:38:51 +03:00
neil 11aef82993 Merge pull request #5139 from scruel/scruel-patch-1
feat: guide user to run script as root to create temp admin user
2024-07-19 11:16:44 +08:00
neil 9861e2d724 Merge pull request #5212 from allddd/dns_porkbun_grep_fix
dns_porkbun: remove stray backslashes
2024-07-19 10:33:49 +08:00
allddd 7ae0d0caa3 dns_porkbun: remove stray backslashes 2024-07-18 21:57:22 +02:00
b1n23 2f5ea120cb deployhook KeyHelp: fix bug 2024-07-16 00:25:53 +08:00
neil 93d2c9a3f0 Merge pull request #5207 from scruel/patch-5
fix(deploy): respect api path with synology Auth API
2024-07-14 17:33:26 +08:00
Scruel Tao 60569fdd83 fix(deploy): respect api path with synology Auth API
fix #5184
2024-07-14 15:04:43 +08:00
neil 0f61e9c15e Merge pull request #5206 from acmesh-official/dev
sync
2024-07-14 14:06:00 +08:00
neil d81fc155cb add timeout for _getRepoHash
https://github.com/acmesh-official/acme.sh/issues/5200
2024-07-14 13:50:35 +08:00
neil 60f7750d77 Merge pull request #4896 from vladh/master
Improve grammar
2024-07-14 13:23:32 +08:00
Vlad-Stefan Harbuz 9bdfd8f4fe Improve grammar 2024-07-12 13:04:42 +01:00
PMExtra 945b7de76f feat(deploy_ali_cdn): improve upper-case 2024-07-11 18:41:39 +08:00
PMExtra 3c35eadbc4 feat(deploy_ali_cdn): support Alibaba Cloud CDN deployment 2024-07-11 18:29:20 +08:00
Felix Schmidt ab86e056a2 Changed A-Z and a-z to [:upper:] and [:lower:] from last commit to comply with requested standards.
This does not change any functionality in this special case but the
request for [:upper:] and [:lower:] makes a lot of sense in general.
2024-07-07 13:02:47 +02:00
Felix Schmidt a2bc79ddd5 Fixed a bug where trying to add entries where the fulldomain contains upper case characters would not be accepted (dynv6 API rejects those).
Now the fulldomain will be cast to lowercase first which should not make
any difference since DNS is case insensitive.
2024-07-07 12:34:44 +02:00
Владимир Алексеев 51151293d7 Remove date -d on macOS 2024-07-06 21:01:25 +10:00
IIIPr0t0typ3III 5789e80d74 Fixed a bug where the zone_id was corrupted for domains containing the string 'id' dns_dynv6.sh
This will now search for `"id:"` instead of `id` and therefore will only find the id field and not any other field containing the sub-string 'id'
2024-07-05 18:43:11 +02:00
Manuel Sanchez Pinar 2beb2f5659 fix: rage4 - add error 400 and TXT cleanup
The following error happens if the header is set
    to 'Content-Type: application/json':

        {"statusCode":400,"message":"One or more errors occurred!",
        "errors":{"serializerErrors":["The input does not contain
        any JSON tokens. Expected the input to start with a valid
        JSON token, when isFinalBlock is true. LineNumber:
        0 | BytePositionInLine: 0."]}}

    Fix TXT removal
2024-07-05 09:23:14 +02:00
neil 65868ab8a7 remove centos 2024-07-03 18:27:47 +08:00
René Weselowski 89586530a5 improve performance and memory usage for dns_anx
when fetching all zones the memory usage can exceede limits and also
cause timeouts.

with this change the zone will be searched via the longest to shortest
match using the get endpoint.
2024-06-26 15:06:19 +02:00
neil 0d93145834 Merge pull request #5133 from mdmower/ext-key-usage
feat: Support manually defining extended key usage in CSR
2024-06-25 05:13:46 +02:00
WinSCaP 617f4acfd6 Update dns_openprovider.sh for OpenProvider
Removed the NS type, as settings nameservers via API is no longer supported.  The API implementation is not changed to the new REST API.
2024-06-22 11:37:10 +02:00
neil fe4113d623 add PROJECT_API for
https://github.com/acmesh-official/acme.sh/issues/5170
2024-06-17 15:30:10 +02:00
neil 9a0e15cced Merge pull request #5159 from themarek/dev
improve compatibility with FreeBSD
2024-06-17 14:57:28 +02:00
Marek Wester e0c63d58b2 improve compatibility with FreeBSD
it is related to this bug report: opnsense/plugins#3525

FreeBSD's sed doesn't have the -z option, so empty certificates are delivered to vault when running the script on FreeBSD.
2024-06-15 23:19:04 +02:00
neil f7f8ea9b97 Merge pull request #5110 from ionos-cloud/add_ionos_cloud_script
Feature: DNS API for IONOS cloud
2024-06-15 14:50:32 +02:00
neil 58cad98cd8 Merge pull request #5041 from j-c-m/ksh_openbsd_porkbun_fix
Quote echo $data in _porkbun_rest (dns_porkbun)
2024-06-15 14:45:19 +02:00
Vinicius Mello 2f8fb360aa fix CI reported problems for shellcheck and shfmt
fix minor problems reported by shellcheck and shfmt
2024-06-12 15:03:02 -03:00
Vinicius Mello 05ec3922f1 minor wording fix
minor fix for text coherence
2024-06-11 17:17:37 -03:00
Vinicius Mello 1c9423ef31 fix pagination bug querying Linode API v4
fixes issue #4956

previous code only worked for the first 10 domains on the account (as Linode
API returned a paginated response, with only 10 records).

This change makes an exact search query for each subdomain, completely removing any
need for walking through paginated responses. What makes it work for large
accounts with any number of domains.
2024-06-11 12:50:45 -03:00
zak905 74ffbb2172 fix forgotten parenthensis 2024-06-10 19:53:05 +02:00
zak905 cc9c85cc1a use lower_case util function instead of raw bash command 2024-06-09 21:02:54 +02:00
b1n23 3f40380c69 deployhook Directadmin: Support for selecting the scheme of DirectAdmin , HTTP or HTTPS 2024-06-03 16:57:51 +08:00
b1n23 1116b73a08 deployhook KeyHelp: Support enabling the Enforce HTTPS option 2024-06-03 16:47:43 +08:00
neil a8f252e45d Merge pull request #5057 from phedoreanu/dev
dns_1984.hosting - update _get_root check
2024-05-28 09:27:30 +02:00
Henrik Alves b821836dc4 update dns_doapi 2024-05-27 12:45:01 +02:00
Владимир Алексеев a42fef0905 Merge branch 'dev' into master 2024-05-20 07:05:06 +10:00
neil f7e09af5c9 Merge pull request #4738 from stokito/dns_api_info
Structured DNS provider API info
2024-05-19 09:12:14 +02:00
neil 304cb56337 Merge pull request #4929 from jeromecst/master
Add notification support for ntfy.sh
2024-05-19 09:05:51 +02:00
Sergey Ponomarev 6b7b5caf54 DNS provider API: structured description
Instead of using comments declare info in a special variable.
Then the variable can be used to print the DNS API provider usage.
The usage can be parsed on UI and show all needed inputs for options.

The info is stored in plain string that it's both human-readable and easy to parse:

    dns_example_info='API name
     An extended description.
     Multiline.
    Domains: list of alternative domains to find
    Site: the dns provider website e.g. example.com
    Docs: Link to ACME.sh wiki for the provider
    Options:
     VARIABLE1 Title for the option1.
     VARIABLE2 Title for the option2. Default "default value".
     VARIABLE3 Title for the option3. Description to show on UI. Optional.
    Issues: Link to a support ticket on https://github.com/acmesh-official/acme.sh
    Author: First Lastname <authoremail@example.com>, Another Author <https://github.com/example>;
    '

Here:
VARIABLE1 will be required.
VARIABLE2 will be required too but will be populated with a "default value".
VARIABLE3 is optional and can be empty.

A DNS provider may have alternative options like CloudFlare may use API KEY or API Token.
You can use a second section OptionsAlt: section.

Some providers may have alternative names or domains e.g. Aliyun and AlibabaCloud.
Add them to Domains: section.

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
2024-05-18 12:06:41 +03:00
Marvin Dickhaus fd461fe015 Fix missing XML Escaping in Password String
Fixes #5060
2024-05-16 22:44:47 +02:00
zak905 2797d2c535 fix add and rm method names 2024-05-14 19:50:44 +02:00
zak905 f440656572 create new script for ionos cloud and rollback changes to dns_ionos.sh 2024-05-14 18:35:25 +02:00
3VAbdAVE b1d019146a UBNT removed keytool from UnifiOS, modify to use openssl PKCS12. Also backup certificates before overwrite, and force unifi to start with unifi-core if both are installed. 2024-05-13 07:50:46 -04:00
Scruel Tao 1dbc58d4e0 chore: optimize more msgs 2024-05-08 14:01:43 +08:00
Scruel Tao 47ccb28482 chore: typo 2024-05-08 04:46:51 +08:00
Scruel Tao 744dea00ca feat: guide user to run script as root to create temp admin user
Message text and comment optimized
2024-05-08 02:56:21 +08:00
zak905 373c2b379c remove debug print statements and usage of custom fork of acmetest 2024-05-06 14:53:51 +02:00
Владимир Алексеев 95b51cf9e6 Merge branch 'acmesh-official:master' into master 2024-05-05 09:42:54 +10:00
Vladimir Alexeev a375e924b4 translation of comments into English 2024-05-05 07:42:22 +10:00
Matt Mower 957bbab440 feat: Support manually defining extended key usage in CSR
- New CLI param: --extended-key-usage <string>
- When --extended-key-usage is defined:
  1. Set [v3_req]extendedKeyUsage to the provided value.
  2. Store the value in domain conf Le_ExtKeyUse for reuse.
2024-05-04 11:58:29 -07:00
neil bd48c99383 fix ca names 2024-05-04 16:27:31 +02:00
Vladimir Alexeev d989617825 set default SL_Ver to v1 2024-05-04 20:42:38 +10:00
Vladimir Alexeev 177d9b7cb0 set default SL_Ver to v1 2024-05-04 20:38:42 +10:00
Vladimir Alexeev 7a1305c1bb fix del record for v1, delete one entry at a time 2024-05-04 19:12:42 +10:00
zak905 52d1d421a3 escape brackets in regexp and format using shfmt 2024-05-03 17:04:49 +02:00
zak905 c3cc13595d use posix compliant lower case shell command 2024-05-02 18:48:39 +02:00
zak905 adc8031e34 fix shell linter and formating 2024-04-30 17:04:24 +02:00
zak905 0974c74a89 transform record name to lower case when searching for TXT record 2024-04-30 16:59:02 +02:00
zak905 c64aae6f39 more debugging - add function argument printing 2024-04-30 16:59:02 +02:00
zak905 b7b1714637 add some debug statements 2024-04-30 16:59:02 +02:00
zak905 d8525493a1 attempt to use custom fork of acmetest 2024-04-30 16:59:02 +02:00
zak905 30d0945855 fix regexp for findind acme challenge record from API response 2024-04-30 16:59:02 +02:00
zak905 ffde1f8343 linting based on ShellCheck results 2024-04-30 16:59:02 +02:00
zak905 96c35b41ed fix TXT record lookup and removal 2024-04-30 16:59:02 +02:00
zak905 dc2979926f fix zone search 2024-04-30 16:59:02 +02:00
zak905 ff357dd3fb fix syntax error 2024-04-30 16:59:02 +02:00
zak905 f35e15204d implement dns_ionos_rm function 2024-04-30 16:59:02 +02:00
zak905 3ae4ba3300 dns_ionos.sh: implement dns_ionos_add for ionos cloud 2024-04-30 16:59:02 +02:00
Vladimir Alexeev 8bb29f53d1 test DNS for v1 (legacy) 003 2024-04-30 16:15:45 +10:00
Vladimir Alexeev 2e3c1ef4ac test DNS for v1 (legacy) 003 2024-04-30 13:49:53 +10:00
Vladimir Alexeev ada7e12b5a test DNS for v1 (legacy) 003 2024-04-30 11:03:53 +10:00
Vladimir Alexeev b8949ba3dd test DNS for v1 (legacy) 002 2024-04-30 10:01:50 +10:00
Vladimir Alexeev 73fe47ba79 test DNS for v1 (legacy) 001 2024-04-30 09:57:49 +10:00
Vladimir Alexeev 577920de86 test DNS for v2 (actual) 001 2024-04-30 08:36:36 +10:00
neil 0d8a314bcf Merge pull request #5123 from acmesh-official/dev
sync
2024-04-29 20:15:14 +02:00
neil e7cfde1904 Merge pull request #5049 from hknet/patch-2
fixed handling of key and secret
2024-04-29 20:14:01 +02:00
Vladimir Alexeev 517baa3235 test DNS for v2 (actual) 2024-04-29 22:54:31 +10:00
alviy aa41df4e7d run test 2024-04-27 13:49:37 +03:00
alviy d73953af3d spellcheck 2024-04-27 12:28:06 +03:00
alviy 54eec82311 spellcheck 2024-04-27 11:45:14 +03:00
alviy dab244ad25 shfmt 2024-04-27 11:29:30 +03:00
alviy dbe7cb8dbb remove rev command 2024-04-27 09:55:38 +03:00
alviy e814cccc44 Update dns_alviy.sh 2024-04-27 00:06:22 +03:00
alviy 1078fdc157 fix Shellcheck 2024-04-26 23:25:38 +03:00
alviy 4bf4259dda Update _get_root logic 2024-04-26 23:05:42 +03:00
alviy 03b53cbb60 run DNS test 2024-04-26 20:38:01 +03:00
alviy 7ef1340e2a Update dns_alviy.sh 2024-04-25 23:16:11 +03:00
alviy c0b87adee5 shfmt 2024-04-25 22:51:32 +03:00
alviy 4a8c2251e0 4th+ level domain 2024-04-25 22:47:53 +03:00
alviy d1df5f3021 test DNS 2024-04-25 22:36:11 +03:00
alviy e1acea52f8 run DNS test 2024-04-25 22:27:04 +03:00
alviy 2e9f159225 shfmt 2024-04-25 22:15:16 +03:00
alviy 2fcda9a73a Quotes recomendations 2024-04-25 22:07:29 +03:00
alviy 78ba205f4d DNS test init 2024-04-25 19:37:49 +03:00
alviy f44dec2c8d add new provider - Alviy.com 2024-04-25 18:43:35 +03:00
neil 8c07af6fc7 Merge pull request #5113 from scruel/dev
fix(deploy_dsm): ensure grep get the error code
2024-04-25 09:19:08 +02:00
Scruel Tao cd01104de9 fix(deploy_dsm): ensure grep get the error code
Added grep -o option to ensure the script won't get other digits as the error code result
2024-04-25 13:39:05 +08:00
neil 28f438a6bd Merge pull request #5111 from scruel/scruel-patch-1 2024-04-24 23:16:49 +02:00
Scruel Tao 9ff89b570f fix(deploy_dsm): missing gerp -P option on busybox
Fixes:  #5105
2024-04-25 04:02:49 +08:00
neil bc90376489 Merge pull request #5102 from acmesh-official/dev
sync
2024-04-21 12:11:04 +02:00
neil 43b5ea801f convert to pkcs12 when renewal
fix https://github.com/acmesh-official/acme.sh/issues/3474#issuecomment-2058126129
2024-04-21 11:21:45 +02:00
neil 9863e7ea6e Merge pull request #5023 from scruel/patch-dsm-deploy
Patch Synology DSM deploy: support DSM 6.x & user-friendly refactor.
2024-04-21 09:45:41 +02:00
b1n23 bfba44fbad format adjustment 2024-04-07 12:36:19 +00:00
b1n23 c466f063c8 add newline at end of file 2024-04-01 21:59:12 +08:00
neil ebaa39b03f Merge pull request #5075 from acmesh-official/dev
sync
2024-04-01 11:46:18 +02:00
neil fa3d7ad14b Merge pull request #5069 from annieoxe/decode-eab_hmac_key
Fix: Decode eab_hmac_key as single-line
2024-03-31 23:02:42 +02:00
neil c51104f956 fix format 2024-03-31 20:33:57 +02:00
neil 84795ff4d9 Merge pull request #4757 from laraveluser/master
Add support for Lima-City
2024-03-31 20:20:29 +02:00
neil cc5c722e29 Merge pull request #5072 from aSauerwein/master
feature: add template option for panos deploy hook
2024-03-31 20:15:18 +02:00
asauerwein 4fcddd1893 add template option 2024-03-31 09:16:21 +02:00
b1n23 295af01687 Add deployhook for KeyHelp 2024-03-28 23:07:14 +08:00
laraveluser c8604255e4 Merge branch 'acmesh-official:master' into master 2024-03-27 21:47:09 +01:00
annieoxi 492826a7f2 Fix: Decode eab_hmac_key as single-line
This commit resolves the issue #5068.
2024-03-26 12:35:54 +01:00
b1n23 e7284df1df Add deployhook for DirectAdmin 2024-03-21 21:44:33 +08:00
b1n23 3b46060caa deployhook Netlify: Support multiple Site ID 2024-03-20 23:06:09 +08:00
b1n23 696182cfa4 deployhook Edgio: Support multiple Environment ID 2024-03-20 23:05:43 +08:00
b1n23 d1a1d1da8f Add deployhook for CacheFly 2024-03-20 21:00:50 +08:00
b1n23 c508984f56 Add deployhook for Edgio 2024-03-20 21:00:50 +08:00
b1n23 54eba51b35 Add deployhook for Netlify 2024-03-20 21:00:50 +08:00
Adrian Fedoreanu 5e64781d65 update _get_root check 2024-03-19 19:41:33 +01:00
neil 2d4b900e33 Merge pull request #5032 from scruel/patch-3
fix(config_migrate): always remove domain old key & replace old value by new value
2024-03-18 21:43:03 +01:00
neil d2481f5790 Merge pull request #5048 from hknet/patch-1
dns-record TTL set to 300
2024-03-18 21:25:35 +01:00
neil 49f6104f03 Merge pull request #4979 from derytim/aws_dns_imdsv2
Aws dns imdsv2
2024-03-18 21:16:16 +01:00
neil 2728d2aa6e fix format 2024-03-18 21:09:49 +01:00
neil 0588fc6b7c Merge pull request #4581 from wlallemand/haproxy-hot-update
haproxy deploy hook updates existing certificate over stats socket
2024-03-18 21:07:12 +01:00
Tim Dery e3cd52cab4 Merge branch 'dev' into aws_dns_imdsv2 2024-03-13 11:06:52 -07:00
Tim Dery b2c6b9a320 attempt _use_metadata fix from j-c-m 2024-03-11 10:33:14 -07:00
Harald Kapper 39fa40ab12 fixed secret+key storage-usage
fixed the key and secret handling via acme account.conf
2024-03-11 03:27:17 +01:00
Harald Kapper 0bf87bf4af dns-record TTL set to 300
reduce TTL for the TXT record from 3600 to 300 to have an easier way to replicate changes for the dns-verification in case multiple submissions for a specific record/domain are done within an hour.
2024-03-11 00:44:53 +01:00
Jesse Miller 92d37f6eaf Quote echo $data in _porkbun_rest
Quote echo $data in _porkbun_rest to avoid
brace expansion under ksh (OpenBSD).
2024-03-06 15:56:42 -07:00
laraveluser d3b022fe17 Update dns_limacity.sh 2024-03-03 10:32:21 +01:00
Scruel Tao 79640f6b7d replace wired space symbol 2024-02-28 20:02:24 +08:00
Scruel Tao 2cbdf274b1 feat(config_migrate): always remove domain old key & replace old value by new value 2024-02-28 18:30:06 +08:00
Scruel Tao 6af5293315 doc: adjust 2024-02-28 02:00:07 +08:00
Scruel Tao bd3a2b1bb5 Prevent leaving blank lines in config file after cleared keys. 2024-02-27 12:40:52 +08:00
Scruel Tao ff090d2f74 fix lint 2024-02-26 23:45:19 +08:00
Scruel Tao 68e3a12a91 feat: improve robustness of the usage of DSM tool synogroup 2024-02-26 23:38:44 +08:00
Scruel Tao 50eda6b678 fix: lint 2024-02-26 21:07:15 +08:00
Scruel Tao 192ec598a3 feat: add SYNO_LOCAL_HOSTNAME to prevent remote deploy via temp admin method 2024-02-26 21:03:26 +08:00
Scruel Tao 5b449999a5 refactor: unify variable naming convention again (revert some changes) 2024-02-26 20:55:49 +08:00
Scruel Tao afed62f6de fix: should save SYNO_UseTempAdmin only after login success. 2024-02-26 07:05:00 +08:00
Scruel Tao 59d1e16f9c feat: bypass enforce temp admin 2FA 2024-02-26 06:23:47 +08:00
Scruel Tao dbe0d477d6 feat: more user-friendly logic & error messages. 2024-02-26 06:23:46 +08:00
Scruel Tao 7248560169 feat: support DSM 6.x 2024-02-26 06:23:45 +08:00
Scruel Tao f840f7d75b refactor: unify variable naming convention 2024-02-26 06:23:42 +08:00
neil 6e14a073ff Merge pull request #5021 from acmesh-official/dev
sync
2024-02-25 19:25:26 +01:00
Scruel Tao cf3839ecec doc(deploy): update usage doc 2024-02-22 12:38:51 +08:00
Ciaran Walsh b0ca4435fd Fix for empty error objects in response breaking extraction of domain validation types
Fix for empty error objects in the response which mess up the extraction of domain validation types due to the closing brace in the error object prematurely matching the end of the search pattern.

This seems to be a recent change with ZeroSSL in particular where "error":{} is being included in responses.

There could potentially be a related issue if there is a complex error object ever returned in the validation check response where an embedded sub-object could lead to an incomplete extraction of the error message, roughly around line 5040.

Adapted from fix suggested here: https://github.com/acmesh-official/acme.sh/issues/4933#issuecomment-1870499018
2024-02-21 00:21:09 +00:00
neil aa8cf76fb1 Merge pull request #4706 from scruel/syno-patch
Add SYNO_USE_TEMP_ADMIN variable & Fix broken logic
2024-02-13 09:57:51 +08:00
neil 10b4bb598a fix https://github.com/acmesh-official/acme.sh/issues/4995#issuecomment-1937486243 2024-02-12 13:16:08 +08:00
neil de14d59bb3 Merge pull request #4987 from acmesh-official/dev
sync
2024-02-04 12:39:06 +08:00
neil d76272f0ea fix message 2024-02-04 12:35:07 +08:00
neil e04093efe2 remove socket err temp file 2024-02-04 12:31:34 +08:00
neil bd6bbba948 remove socaterr temp file 2024-02-04 12:27:06 +08:00
neil 37e4f35c93 fix format 2024-02-04 12:21:50 +08:00
neil 0084cb7403 fix format 2024-02-04 12:18:58 +08:00
neil 99e5c159a7 check socat "Permission denied" 2024-02-04 12:17:03 +08:00
neil 802121d54a show dns message on any branch 2024-02-04 11:42:28 +08:00
neil 160b2e95c9 Merge pull request #4986 from acmesh-official/dev
sync
2024-02-04 00:11:26 +08:00
neil 7ec692cdef fix socat for netbsd:
listens to ipv4 by default.
2024-02-03 23:59:48 +08:00
neil 3dca67112d fix netbsd 2024-02-03 18:39:58 +08:00
neil f8dac5905c check the status of Order object and the Authorization object. 2024-02-03 18:07:50 +08:00
Tim Dery 48e4e41e05 add cr to force a new gh actions run 2024-01-31 17:32:56 -08:00
Tim Dery 22374b81de delete a cr to force a workflow run 2024-01-31 16:02:45 -08:00
Tim Dery b9157e29cb spacing cleanup 2024-01-31 15:52:59 -08:00
Tim Dery bd247c35f2 remove comments 2024-01-31 15:48:44 -08:00
Tim Dery 7da9a45c61 combined functions for cleaner code 2024-01-31 15:39:08 -08:00
Tim Dery 122dfa12ac add imdsv2 support to dns_aws 2024-01-30 15:51:55 -08:00
neil 1905830b20 Merge pull request #4948 from rparenton/gandi-livedns-new-api
Fix #4836 (Switch to new Gandi LiveDNS API)
2024-01-14 13:04:51 +01:00
Robert bfb41ce123 Fix acmesh-official#4836 (Switch to new Gandi LiveDNS API)
1. Updated LiveDNS API URL for the new API to allow Personal Access Tokens to work
2. Updated authorization header syntax to allow deprecated API Keys to work with the new API
3. Removed white space in JSON response parsing to match responses returned by the server
2024-01-13 13:39:09 -06:00
neil 85e3ecfe0b fix omnios 2024-01-13 20:28:21 +01:00
laraveluser 9e073c954d Update dns_limacity.sh 2024-01-12 20:39:44 +01:00
neil b79c3f5cc4 fix pkg_add 2024-01-12 20:36:49 +01:00
laraveluser ad5acb80fe Update dns_limacity.sh 2024-01-12 20:33:01 +01:00
laraveluser 7b7c834b08 Update dns_limacity.sh 2024-01-12 19:48:14 +01:00
laraveluser 42827be7c3 Update dns_limacity.sh 2024-01-12 18:39:28 +01:00
laraveluser 7022d27b8e Update dns_limacity.sh 2024-01-12 17:58:54 +01:00
laraveluser ab911f1ce9 Update dns_limacity.sh 2024-01-12 17:54:23 +01:00
laraveluser a6a1de50c8 Merge branch 'acmesh-official:master' into master 2024-01-12 01:07:07 +01:00
laraveluser 97723fbbc9 Update dns_limacity.sh 2024-01-08 01:45:34 +01:00
neil 2e58cf1168 Merge pull request #4940 from dario-pilori/fix-routeros-7
Fix RouterOS deploy hook for 7
2024-01-04 23:15:36 +01:00
Dario Pilori 3ca97d7258 Remove whitespace in script name in routeros.sh deploy hook 2024-01-04 18:28:05 +01:00
neil 9786dccdee Merge pull request #4161 from seidler2547/seidler2547-remove-do
remove dns_do as it does not work anymore
2024-01-02 20:34:15 +01:00
Jérôme a3612f53dd change shebang to sh 2023-12-26 01:52:16 +01:00
Jérôme 112257c49e Add notification support for ntfy.sh 2023-12-26 01:45:38 +01:00
neil d8e2b96bce Merge pull request #4925 from LordDarkneo/patch-1
Logout update for DSM Deploy script (2727 issue)
2023-12-24 16:01:25 +01:00
LordDarkneo 6992659ba9 Update synology_dsm.sh 2023-12-22 14:36:52 -05:00
LordDarkneo 05696d443a Update synology_dsm.sh
#2727 issue when logging out on older version - using variables to unlog only for CERT user
2023-12-22 14:34:35 -05:00
LordDarkneo f59a925897 Update synology_dsm.sh
Issue for lougout
2023-12-22 09:09:29 -05:00
neil afacdfcb95 Merge pull request #4918 from acmesh-official/dev
sync
2023-12-17 22:26:04 +01:00
neil 8cb1b6b5d5 update 2023-12-05 20:19:40 +01:00
neil f7d9d53ad2 Merge pull request #4899 from acmesh-official/dev
sync
2023-12-05 20:16:27 +01:00
neil f4315e2c6f fix _date2time 2023-12-05 19:33:10 +01:00
neil f0ac566c93 add Omnios 2023-12-04 23:51:06 +01:00
neil 50f6a459cf update solaris 2023-12-04 09:41:39 +01:00
neil 179c80ae6d Merge pull request #4861 from mrbaiwei/master
support West.cn Domain
2023-12-04 09:35:18 +01:00
neil 6e72f161a6 Merge pull request #4872 from sandercox/patch-1
Update dns_gcloud.sh rm logs record added
2023-12-03 14:52:58 +01:00
neil f71d8d7348 minor 2023-12-03 14:44:23 +01:00
neil a12a3640a7 update 2023-12-03 14:40:32 +01:00
neil 3b7bc5a56a update dragonflybsd-vm@v1 2023-12-02 22:50:59 +01:00
William Lallemand e09d45c844 haproxy; don't use '*' in the filename for wildcard domain
By default acme.sh uses the '*' character in the filename for wildcard.
That can be confusing within HAProxy since the * character in front of a
filename in the stat socket is used to specified an uncommitted
transaction.

This patch replace the '*' by a '_' in the filename.
This is only done when using the default filename, the name can still be
forced with an asterisk.
2023-12-01 15:35:31 +01:00
William Lallemand 36fc321096 haproxy: use the master CLI for hot update
DEPLOY_HAPROXY_MASTER_CLI allows to use the HAProxy master CLI instead
of a stats socket for DEPLOY_HAPROXY_HOT_UPDATE="yes"

The syntax of the master CLI is slightly different, a prefix with the
process number need to be added before any command.

This patch uses ${_cmdpfx} in front of every socat commands which is
filled when the master CLI is used.
2023-11-30 15:22:51 +01:00
William Lallemand 98a7a01dbb haproxy: deploy script can add a new certificate over the stats socket
DEPLOY_HAPROXY_HOT_UPDATE="yes" now allows to add a new certificate
within HAProxy instead of updating an existing one.

In order to work, the ${DEPLOY_HAPROXY_PEM_PATH} value must be used as a
parameter to the "crt" keyword in the haproxy configuration.

The patch uses the following commands over HAProxy stats socket:
- show ssl cert
- new ssl cert
- set ssl cert
- commit ssl cert
- add ssl crt-list
2023-11-30 14:00:44 +01:00
William Lallemand 0f7be90500 haproxy: deploy script can update existing certificate over stats socket
Since version 2.2, HAProxy is able to update dynamically certificates,
without a reload.

This patch uses socat to push the certificate into HAProxy in order to
achieve hot update. With this method, reloading is not required.
This should be used only to update an existing certificate in haproxy.

2 new variables are available:

- DEPLOY_HAPROXY_HOT_UPDATE="yes" update over the stats socket instead
  of reloading

- DEPLOY_HAPROXY_STATS_SOCKET="UNIX:/run/haproxy/admin.sock" set the path on
  the stats socket.
2023-11-30 14:00:44 +01:00
William Lallemand 7aaf4432d4 haproxy: sanitize the PEM in the deploy script
Sanitize the PEM of the haproxy deploy script by removing the '\n', this
way it could be injected directly over the CLI.
2023-11-30 14:00:41 +01:00
neil 884a8995b4 Merge pull request #4853 from Max13/deploy/proxmoxve
Fix typo in proxmoxve deploy hook
2023-11-22 09:19:51 +01:00
neil bb42595275 Merge pull request #4866 from phedoreanu/dev
dns_1984.hosting.sh: update login and account status URLs
2023-11-21 22:23:06 +01:00
neil a4bd89c938 fix 2023-11-21 09:00:22 +01:00
neil f364d4fbef fix 2023-11-21 08:45:54 +01:00
neil f899d0d8ed update 2023-11-20 23:39:25 +01:00
Sander Cox 074cf00a7c Update dns_gcloud.sh rm logs record added
The logs show record was added twice but the second time was actual the rm command thus the removal of the record!
2023-11-14 11:28:24 +01:00
Adrian Fedoreanu 15d10eeebc dns_1984.hosting.sh: update login and account status URLs 2023-11-10 08:22:28 +01:00
mrbaiwei bea71f3411 Update dns_west_cn.sh
Signed-off-by: mrbaiwei <mrbaiwei@gmail.com>
2023-11-07 07:20:25 +08:00
mrbaiwei eb99803b53 Update west.cn domain api
Signed-off-by: mrbaiwei <mrbaiwei@gmail.com>
2023-11-06 13:18:36 +08:00
mrbaiwei a60d0c4108 Update dns_west_cn.sh
Signed-off-by: mrbaiwei <mrbaiwei@gmail.com>
2023-11-06 11:25:09 +08:00
neil 1cc3a13c49 fix comments 2023-11-04 10:04:26 +01:00
mrbaiwei feffbba6de Update dns_west.sh
Signed-off-by: mrbaiwei <mrbaiwei@gmail.com>
2023-11-04 14:16:11 +08:00
mrbaiwei 6ea09444ec Update dns_west.sh
Signed-off-by: mrbaiwei <mrbaiwei@gmail.com>
2023-11-04 00:04:05 +08:00
neil f1f486dacf Merge pull request #4843 from trulyliu/dev
Fix https://github.com/acmesh-official/acme.sh/issues/4460
2023-11-03 15:57:49 +01:00
neil fec4af3194 Merge pull request #4855 from studycom-mrobinson/aws-similar-names
Acme2 similar names
2023-11-03 15:56:37 +01:00
mrbaiwei 5342c7c82b support West.cn Domain
Signed-off-by: mrbaiwei <mrbaiwei@gmail.com>
2023-11-03 18:14:26 +08:00
Matthew Robinson 8454ffa331 Fix issue with similar domain names causing an error in selecting the proper root domain to add challenge records in 2023-11-02 08:30:44 -07:00
Gavin Leo 199977be6a Fix https://github.com/acmesh-official/acme.sh/issues/4460
Update gcore API url.
2023-11-02 09:27:14 +08:00
Adnan RIHAN 00dbc3881f Fixed variables 2023-11-01 20:02:16 +01:00
neil d93a5b2d20 Merge pull request #4841 from podguzovvasily/patch-1
Update haproxy.sh
2023-10-29 18:11:51 +01:00
podguzovvasily 8ca5ca6594 Update haproxy.sh
resolved issue with HAProxy https://github.com/acmesh-official/acme.sh/issues/4788
according https://serversforhackers.com/c/letsencrypt-with-haproxy
2023-10-24 16:58:47 +03:00
neil fe890c62f4 fix https://github.com/acmesh-official/acme.sh/issues/4835 2023-10-22 23:07:00 +08:00
Keith Chiem ed72b090af deploy hook for Ruckus ZoneDirector / Unleashed 2023-10-18 20:32:39 -07:00
neil e15513bfdd fix format 2023-10-06 20:05:39 +08:00
neil dbe569c0d9 Merge pull request #4622 from defragatwork/mattermost
Add support for Mattermost notifications (Bot account)
2023-10-06 20:01:50 +08:00
neil f2e1b589b5 start 3.0.8 2023-10-06 20:01:28 +08:00
neil 377a37e4c9 Merge pull request #4820 from acmesh-official/dev
sync
2023-10-05 13:25:27 +08:00
neil 6e163208b4 Merge pull request #4809 from winromulus/dev
fix: Synology DSM API path regex
2023-09-26 09:23:43 +08:00
Romeo Dumitrescu 87a7bde618 fix: Synology DSM API path regex
Fix the regex for looking up the API path value from the Synology API query.
2023-09-25 18:43:01 +03:00
neil 37b0498699 Merge pull request #4805 from acmesh-official/dev
sync
2023-09-24 17:03:38 +08:00
neil 59f976dc48 fix https://github.com/acmesh-official/acme.sh/issues/4798 2023-09-20 18:07:16 +08:00
neil 8565a853a8 Merge pull request #4787 from TobiasGrave/fix_variomedia_api
Fix Variomedia API
2023-09-15 09:07:24 +08:00
Tobias Grave dfd49e46ad Fix root zone determination for Variomedia API 2023-09-14 09:25:45 +02:00
neil 73bbaced62 Merge pull request #4782 from KincaidYang/KincaidYang-patch-4
Add TencentCloud API
2023-09-13 21:13:33 +08:00
neil 0c8870cb7f Merge pull request #944 from MarcelWaldvogel/random-cron
Random cron
2023-09-13 21:07:51 +08:00
neil 1a90f66f73 Merge pull request #4794 from zbbfufu/feature/gandi-replace-apikey-by-personal-token
dns_gandi: implements token in addition to the (deprecated) API key
2023-09-13 18:02:12 +08:00
Julien Furgerot 558e706bde fix ci errors (shellcheck & shfmt) 2023-09-12 15:54:44 +02:00
Julien Furgerot 1a08be0a3f dns_gandi: implements personal access token in addition to the (deprecated) API key 2023-09-12 09:48:09 +02:00
Scruel Tao 29b2960805 Optimze comment & remove tail space 2023-09-07 15:01:37 +08:00
Scruel Tao f7f3a0bf0d Merge branch 'dev' into syno-patch 2023-09-07 14:57:53 +08:00
Tobias Grave ae4c186f55 Fix Variomedia API 2023-09-07 08:40:46 +02:00
KincaidYang af534a73fc 移除部分敏感debug信息 2023-09-06 13:09:52 +08:00
KincaidYang 772bbdc862 Replace some functions 2023-09-06 12:57:19 +08:00
neil 86521ec443 Merge pull request #4754 from LJea/master
Improved api compatibility with devices
2023-09-04 15:55:04 +08:00
KincaidYang e3c4c9265d Replace some functions. 2023-09-03 21:21:05 +08:00
KincaidYang b3f8612e61 Following Neilpang's suggestions and project standards, replace some functions. 2023-09-03 01:31:57 +08:00
LJea 27b1dd04c4 improve the compatibility
Fixed an issue where some embedded devices could not obtain nanoseconds resulting in abnormal parameter coding
2023-09-03 01:02:16 +09:00
neil 46a876445f Merge pull request #3959 from Eagle3386/master
Add ArtFiles.de DNS API plugin
2023-09-02 22:39:00 +08:00
neil 9bb58e47a7 Merge pull request #4728 from Eagle3386/dev-1
Fix Auth API access for DSM 6
2023-09-02 22:06:22 +08:00
neil b8447fcab8 Merge pull request #4780 from acmesh-official/dev
sync
2023-09-02 19:08:54 +08:00
KincaidYang 3abcfd8fa9 Add dns_tencent.sh
Adapt to Tencent Cloud (DNSPod) API 3.0
2023-09-02 18:47:59 +08:00
neil f4ff2d5d2e Merge pull request #4779 from KincaidYang/master 2023-09-02 18:43:53 +08:00
KincaidYang 09b41aa667 fix for nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation
In #4776, I mistakenly added libnghttp2 to NetBSD, now for correction.
2023-09-02 18:38:51 +08:00
KincaidYang 87dc4fe388 fix for curl bugs nghttp2_option_set_no_rfc9113_leading_and_trailing_…
In #4776, I mistakenly added libnghttp2 to NetBsd, and now it has been corrected and added to OpenBsd
2023-09-02 18:23:14 +08:00
neil eed8a7f078 add more debug code https://github.com/acmesh-official/acme.sh/issues/4768 2023-09-02 17:27:21 +08:00
neil c18364c755 change default log level to 2 2023-09-02 17:18:12 +08:00
neil 04946e992e change the default debug level to 2. 2023-09-02 17:15:17 +08:00
neil 5533782152 Merge pull request #4777 from acmesh-official/dev
sync
2023-09-02 17:09:45 +08:00
neil 3f42487f0a Merge pull request #4749 from Nirzak/Nirzak-patch-1
Fixed grep pattern regex for nginx conf path
2023-09-02 15:45:30 +08:00
neil 8bdcd22486 fix https://github.com/acmesh-official/acme.sh/issues/4746 2023-09-02 15:45:07 +08:00
neil b32d22731b remove 2023-09-02 15:45:06 +08:00
neil b788cc24d1 Merge pull request #4764 from sebastianas/inwx
inwx: Be case insensitive while searching for the cookie.
2023-09-02 15:36:43 +08:00
neil 94948f6d34 Merge pull request #4776 from KincaidYang/master
fix for curl bugs nghttp2_option_set_no_rfc9113_leading_and_trailing_…
2023-09-02 15:27:15 +08:00
KincaidYang e5b76ed4c4 Delete dnsapi/dns_tencent.sh 2023-09-02 15:13:37 +08:00
KincaidYang 29a2920a2c Add dns_tencent.sh
Adapt to Tencent Cloud (DNSPod) API 3.0
2023-09-02 14:49:43 +08:00
KincaidYang 089d35708b fix for curl bugs nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation
see
https://bugs.launchpad.net/ubuntu/+source/curl/+bug/2018342
https://github.com/acmesh-official/acme.sh/commit/b6f62ac446ab9ff78f4a90c4330dc314678545c9
https://github.com/acmesh-official/acme.sh/issues/4775
2023-09-02 14:31:17 +08:00
Sebastian Andrzej Siewior 9b0b5bce9f inwx: Be case insensitive while searching for the cookie.
At least since 2023-08-25 the cookie is set via `set-cookie' instead the
expecting `Set-Cookie' string. A month earlier it was working.

Ignore the case while matching the cookie.

Fixes: #4763
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
2023-08-28 21:33:54 +02:00
laraveluser ef20a0128f Add support for Lima-City 2023-08-25 17:22:20 +02:00
neil 3039e4eb6d Merge pull request #4755 from glocknerc/master-1
Master 1
2023-08-24 09:19:57 +08:00
glocknerc 9143cd1485 Change grep to be case-insensitive when looking for Set-Cookie header since INWX change casing to lowercase 2023-08-23 14:07:07 +02:00
Nirjas Jakilim 13d31ecb7f fixed regex for nginx conf path
Fixed the regex for nginx path configuration to fix grep: unrecognized option error
2023-08-21 12:28:50 +06:00
neil a936b2f1f6 Merge pull request #4745 from vitoyucepi/help_punctuation
Remove punctuation symbol
2023-08-21 09:08:48 +08:00
Vito 8d00f489cd Remove excessive full stop from help 2023-08-20 17:11:14 +00:00
Martin Arndt b793dbf977 Fix device ID property name for DSM 6 2023-08-11 17:55:45 +02:00
Martin Arndt d52b38777a Fix Auth API access for DSM 6 2023-08-09 19:52:37 +02:00
neil 56cf93dff2 Merge pull request #4575 from sg1888/panos-ecc-fix
Added functionality for Palo Alto Firewall deployments (PANOS)
2023-07-30 21:45:50 +08:00
neil 67d84cadad Merge pull request #4708 from sg1888/verbiage
Fixed help verbiage to reflect capabilities of --ecc flag
2023-07-30 21:30:49 +08:00
neil b384a24c0e Merge pull request #4710 from zearan/patch-1
Fix the API calls that get the list of domains that PLESK can manage
2023-07-30 21:19:23 +08:00
Martin Arndt 66a68edbe6 Merge branch 'acmesh-official:master' into master 2023-07-30 14:56:31 +02:00
neil dcf3d7234e Merge pull request #4712 from samuel-jimenez/dev
Add DNSExit.com API support
2023-07-30 11:32:03 +08:00
neil 0da839cce3 Merge pull request #4720 from acmesh-official/dev
sync
2023-07-30 11:22:51 +08:00
neil b6f62ac446 fix for curl bugs nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation
see https://bugs.launchpad.net/ubuntu/+source/curl/+bug/2018342
2023-07-30 10:58:22 +08:00
neil 15ee036db1 fix for solaris 2023-07-29 23:30:44 +08:00
neil 6db8ae451a fix for solaris 2023-07-29 23:17:20 +08:00
neil a7f3d413ef fix for solaris 2023-07-29 22:32:30 +08:00
Malte Rabenseifner 3b7be478aa Fix stuff from tests
ShellCheck tests have brought up a couple of issues, that I was not aware of needed to be taken care. This should fix the tests.
2023-07-29 11:27:33 +02:00
neil 7f39cdc856 fix format 2023-07-29 16:45:49 +08:00
Martin Arndt 80006f4730 Added bug report url 2023-07-29 10:26:59 +02:00
neil a51025fe8f fix https://github.com/acmesh-official/acme.sh/issues/3645 2023-07-29 15:32:50 +08:00
neil c42ed9c693 Merge pull request #4714 from hknet/master
Update dns_kappernet.sh
2023-07-28 10:41:56 +08:00
Harald Kapper c48c8d07de Update dns_kappernet.sh
dns update waiting time is reduced now (new backend at kapper.net)
2023-07-27 21:49:23 +02:00
samuel 4d4b6edbc2 Add DNSExit.com API support 2023-07-26 10:40:44 -05:00
Malte Rabenseifner 2014ca9feb Fix the API calls that get the list of domains that PLESK can manage 2023-07-26 15:36:11 +02:00
sg1888 a9f631f404 Added help verbiage for --ecc flag 2023-07-21 16:49:20 +00:00
Scruel Tao ba468bb5e4 Fix for shfmt check 2023-07-20 13:38:36 +08:00
Scruel Tao cf86d57a9f Fix for shfmt check 2023-07-20 13:34:57 +08:00
Scruel Tao 9e958f4e32 Fix shellcheck 2023-07-20 13:09:21 +08:00
Scruel Tao c7f6f20c9d Add SYNO_USE_TEMP_ADMIN variable & Fix broken logic
1. Fix the broken logic in (Sorry for including fix commit in same PR, I'm feeling quite tired and would like to go to sleep right away...)
2. Provides new method to obtain credential info for authentication, it will create a temp admin user if SYNO_USE_TEMP_ADMIN is set, instead of requiring the user's own credentials which will be saved in disk.

I do really don't like to have plaintext credentials be saved in disk, and I noticed that you've spent a lot of time fighting with 2FA related stuffs, so why not just get rid of the whole old way. :)
2023-07-20 02:48:29 +08:00
sg1888 1984f44ffe Shell formatting 2023-07-18 20:18:12 +00:00
sg1888 02de281e40 Removed unused variable 2023-07-18 20:15:46 +00:00
sg1888 ae035deb92 Fixed shell check errors 2023-07-18 20:10:31 +00:00
sg1888 edd1b60c3d Removed ability to specify API key to facilitate future multiple host functionality. 2023-07-18 19:43:47 +00:00
neil 55a3709bd1 Merge pull request #4700 from szhu25/patch-1
Fix SES region variable
2023-07-17 09:56:58 +08:00
Martin Arndt d1fc01a407 RI 2023-07-15 19:31:12 +02:00
Martin Arndt 65293f81d9 Merge branch 'master' into dev 2023-07-15 19:29:50 +02:00
Martin Arndt 0afb0f7958 Merge branch 'acmesh-official:dev' into dev 2023-07-15 19:19:31 +02:00
Steven Zhu dd958872a8 Fix SES region variable
The last version do not save the SES region into the config file, breaking the notification hook.
2023-07-14 12:47:44 -04:00
sg1888 62a2ce1d35 Merge remote-tracking branch 'upstream/dev' into panos-ecc-fix 2023-07-12 00:22:03 +00:00
sg1888 b556908cab Modified ECC file test 2023-07-12 00:03:21 +00:00
sg1888 e69a19db5c Incorporated partial commit to address issue #4198 2023-07-11 23:56:41 +00:00
sg1888 d86414febb Excluded scopes for api key test 2023-07-11 23:41:24 +00:00
sg1888 832318fab1 Merge remote-tracking branch 'upstream/master' into panos-ecc-fix 2023-07-11 20:25:43 +00:00
neil 80ad62ff56 Merge pull request #3208 from cusae/dev
Add BookMyName API support
2023-07-10 09:21:50 +08:00
Arnaud Launay ee50f254df Add BookMyName API support 2023-07-09 20:08:10 +02:00
Arnaud Launay cc0be6cd90 Merge branch 'acmesh-official:dev' into dev 2023-07-09 20:00:52 +02:00
neil a7455d7edd fix https://github.com/acmesh-official/acme.sh/issues/4562#issuecomment-1598731384 2023-07-08 14:11:51 +08:00
neil b7c370fff7 Merge pull request #4691 from acmesh-official/4442
4442
2023-07-08 13:49:18 +08:00
neil 8fd3a64e35 fix https://github.com/acmesh-official/acme.sh/issues/4442 2023-07-08 12:51:56 +08:00
neil 3761fb4377 fix bug https://github.com/acmesh-official/acme.sh/issues/4442 2023-07-08 12:37:01 +08:00
neil 0472f5da6a Revert "fix format"
This reverts commit 09041fb81d.

Revert "fix https://github.com/acmesh-official/acme.sh/issues/4680"

This reverts commit 299a157409.
2023-07-08 11:43:44 +08:00
neil 09041fb81d fix format 2023-07-08 11:19:09 +08:00
neil 299a157409 fix https://github.com/acmesh-official/acme.sh/issues/4680
zerossl returns retry-after header within "200 OK" code.
so we don't check the "503" code anymore.
2023-07-08 11:17:19 +08:00
neil 53ede7b0d8 Merge pull request #4646 from Eagle3386/patch-1
Remove external OTP dependency from deploy hook Synology_DSM.sh
2023-07-08 10:54:56 +08:00
neil cd13aee3e7 Merge pull request #4687 from szhu25/ses-notifyhook
Notify hook: AWS SES
2023-07-08 10:33:27 +08:00
Martin Arndt 8b3acb719e Fix TXT record removal 2023-07-05 13:04:08 +02:00
Martin Arndt 2961a90e7f Make ShellCheck & ShellFormat happy 2023-07-05 11:14:49 +02:00
Martin Arndt db8a2d0c65 Fix & improve DNS API for ArtFiles.de 2023-07-05 11:05:06 +02:00
Steven Zhu a6b5f0c9d4 Fix variable naming to make the access key and secret key consistent with Route53. 2023-07-04 22:31:30 -04:00
Steven Zhu 8d136c6a25 Add newline at end of file to satisfy shfmt's "extra line" error 2023-07-04 22:15:53 -04:00
Steven Zhu 4d94270cde Add newline at end of file to satisfy shfmt's "No newline at end of file" error 2023-07-04 22:14:17 -04:00
Steven Zhu e0d96bcb39 Add initial AWS SES support
Copied most of the v4 api stuff from DNS_AWS hook (Thanks!)

New tokens added:
AWS_SES_ACCESS_KEY_ID
AWS_SES_SECRET_ACCESS_KEY
AWS_SES_REGION
AWS_SES_TO
AWS_SES_FROM
AWS_SES_FROM_NAME (Optional)
2023-07-04 21:54:49 -04:00
Martin Arndt 0d7b831661 Fix variable initialization 2023-07-04 16:58:14 +02:00
Martin Arndt 0c9e4f67a8 Update synology_dsm.sh
Split "[ && ]" into "[ ] && [ ]" to make ShellCheck happy
2023-07-04 15:55:44 +02:00
Martin Arndt da2c386b60 Merge branch 'acmesh-official:dev' into dev 2023-07-04 15:51:15 +02:00
Martin Arndt 4770364d42 Merge branch 'acmesh-official:master' into master 2023-07-04 15:50:01 +02:00
Martin Arndt db3f131dfc Re-add deprecated SYNO_TOTP_SECRET part for legacy compatibility
As requested in acmesh-official/acme.sh/pull/4646 by Neil Pang
2023-07-04 15:47:19 +02:00
Martin Arndt d7f58c64f8 Merge branch 'acmesh-official:master' into patch-1 2023-07-04 14:57:19 +02:00
neil 41b6aebe7c Merge pull request #4574 from systemcrash/patch-1
Spelling / grammar
2023-06-30 11:10:23 +08:00
neil 7d50332246 Merge pull request #4412 from phedoreanu/bugfix/1984_hosting_csrftoken
dns_1984.hosting.sh: fix login with valid csrftoken
2023-06-11 21:26:17 +08:00
Adrian Fedoreanu 0d0478245f dns_1984hosting.sh: fix login with valid csrftoken and sessionid 2023-06-11 15:22:45 +02:00
neil f680ede980 start 3.0.7 2023-06-10 01:16:57 +08:00
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
Martin Arndt d108072bfb Add ArtFiles.de DNS API plugin 2023-05-30 09:24:17 +02:00
Martin Arndt 8cc7c5349a Merge branch 'acmesh-official:master' into master 2023-05-29 20:23:38 +02:00
Martin Arndt fb33ea2a0b Fix single quote escaping 2023-05-29 20:21:16 +02:00
Martin Arndt 63fca33b04 Fix retrieval of domain zone 2023-05-29 20:12:52 +02:00
Martin Arndt 0548ad2fc6 Fix debug output of session ID 2023-05-28 22:33:15 +02:00
Martin Arndt 623d615cd7 Remove external OTP dependency from synology_dsm.sh
Also adapt to DSM 7's API improvements.
2023-05-28 21:42:53 +02:00
sg1888 126df9647b Modified keytest to perform a partial empty commit 2023-05-24 18:51:57 +00:00
sg1888 2e2e7cd054 Added ability to force commit to firewall. Username is now also mandatory 2023-05-17 20:06:06 +00:00
sg1888 0ebc9f7a44 Fixed typo 2023-05-15 01:46:21 +00:00
sg1888 a8fba65cbd Cleaned up verbiage. Added ability to store / update user variable. Added ability to use user/pass OR key 2023-05-15 01:43:54 +00:00
gmanic 0b0476e196 Update dns_nsupdate.sh 2023-05-14 21:01:51 +00:00
gmanic f99d6dac08 Push for actions 2023-05-14 20:58:48 +00:00
gmanic cd2b7cd943 Correct Typo, add -n test
Added a test for non-zero-string, corrected type ZONE instead of OPT
2023-05-14 20:20:22 +00:00
gmanic af759f2330 Enable additional command line parameters for nsupdate
For being able to use e.g. "-v" to use TCP communication with the NSUPDATE_SERVER -> NSUPDATE_OPT has been added.
NSUPDATE_OPT will be plainly added to the command line of nsupdate.
NSUPDATE_OPT will also be saved to conf respectively read from conf
2023-05-14 20:02:43 +00: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
Alexander Pushkarev bb5f3cc326 Add support for Mattermost notifications. 2023-05-01 23:00:01 +03:00
sg1888 7623025b90 Fixes for POSIX sh shell 2023-04-24 18:45:50 +00:00
sg1888 56c98e9295 Merge remote-tracking branch 'upstream/master' into panos-ecc-fix 2023-04-24 17:02:48 +00: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
sg1888 df753e2619 Added functionality to save and reuse API key 2023-04-12 22:00:53 +00: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
sg1888 cbb7082afd Fixed bug with wildcard certs and ecc keys 2023-03-31 00:33:44 +00:00
Paul Dee 6ee72e119c Spelling / grammar 2023-03-31 01:13:41 +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 Manandidawnlight 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
Frank Wall 778ee02803 update documentation for --cert-home
Although the main use-case may be the --install command, this command
also proves to be useful for the --signcsr and --issue commands.
2022-11-07 23:43:37 +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
seidler2547 b3529dc748 remove dns_do as it does not work anymore
The API that it uses was shut down in May 2022
2022-06-27 19:42:16 +00: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
Martin Arndt 13c7182948 Fix usage docs in file's header comment 2022-06-18 17:32:56 +02: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
Martin Arndt edc76795d4 Merge branch 'acmesh-official:master' into master 2022-06-16 09:51:19 +02: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
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
Marvo2011 a092a2fa43 Merge pull request #3 from AlvinSchiller/dev
Save domain dependent values in domain.conf
2022-05-03 09:17:22 +02: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
Marvo2011 d6c68f1a84 Rename delete function, add info 2022-03-28 13:03:02 +02: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
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
Martin Arndt ed56d52af3 Changed GitHub issues URL 2022-02-27 15:12:05 +01:00
Martin Arndt fb457968ec Fix formatting according to Shellcheck 3/3 2022-02-27 14:38:24 +01:00
Martin Arndt 0bea2e2b94 Fix formatting according to Shellcheck 2/2 2022-02-27 14:37:22 +01:00
Martin Arndt 72d02f442e Fix formatting according to Shellcheck 2022-02-27 14:35:21 +01:00
Martin Arndt bcf63b5d27 Add ArtFiles.de DNS API plugin 2022-02-27 14:17:34 +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
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
Marcel Waldvogel 92dbe6cdf8 Simplify and clarify SunOS crontab differences 2020-10-12 14:20:40 +02:00
Marcel Waldvogel 0781e8cf12 Use random hour for cron job
The hour for the cron job isn't really random (as is the minute),
but assuming acme.sh installation times are not correlated, neither
will be the resulting cron start times.
2020-10-12 13:52:57 +02:00
Arnaud Launay b71a088da7 Revert "no private functions"
This reverts commit d76fb566a2.
2020-10-10 11:46:32 +02:00
Arnaud Launay d76fb566a2 no private functions 2020-10-10 11:02:47 +02:00
Arnaud Launay 24a40af103 Merge remote-tracking branch 'upstream/dev' into dev 2020-10-09 17:32:30 +02:00
neil 4a60292f82 update freebsd 2020-10-09 17:22:17 +02:00
Arnaud Launay 7eea866869 BMN -> BookMyName 2020-10-05 15:57:52 +02:00
Arnaud Launay 4ab5456a98 keep shfmt happy 2020-10-05 15:49:00 +02:00
Arnaud Launay 8881a9f40e Add BookMyName API support 2020-10-05 15:46:18 +02:00
250 changed files with 22554 additions and 4016 deletions

No files matched your search

+190
View File
@@ -0,0 +1,190 @@
# GitHub Copilot Shell Scripting (sh) Review Instructions for acme.sh
## Overall Goal
Your role is to act as a rigorous yet helpful senior engineer, reviewing Shell script code (`.sh` files) for the [acme.sh](https://github.com/acmesh-official/acme.sh) project. Ensure the code exhibits the highest levels of robustness, security, and portability.
The review must focus on risks unique to Shell scripting, such as proper quoting, robust error handling, and the secure execution of external commands.
## Required Output Format
Organize the feedback into a single, structured report, using the three-level marking system:
1. **Critical Issues (Must Fix Before Merge)**
2. **Suggestions (Improvements to Consider)**
3. **Good Practices (Points to Commend)**
---
## Shell Compatibility
- **POSIX sh only** -- all scripts must target `sh`, not `bash`. No bash-isms allowed.
- **Shebang**: always use `#!/usr/bin/env sh` (not `#!/bin/sh`, not `#!/usr/bin/env bash`).
- **Use `return`, never `exit`** -- scripts are sourced, not executed as subprocesses. `exit` would kill the parent shell.
- **Cross-platform**: code must work on Linux, macOS, FreeBSD, Solaris, and BusyBox environments.
---
## Robustness and Error Handling
- **(Critical)** Enforce the use of the following combination at the start of the script for safety and robustness:
- `set -e`: Exit immediately if a command exits with a non-zero status.
- `set -u`: Treat unset variables as an error and exit.
- `set -o pipefail`: Ensure the whole pipeline fails if any command in the pipe fails.
- **Always check return values** of function calls. If an error occurs, there must be a way to stop execution.
- **Return 1** after `_err` messages:
```sh
if [ -z "$VARIABLE" ]; then
_err "VARIABLE is required"
return 1
fi
```
- Check for the use of `mktemp` when creating temporary files to prevent race conditions and security risks.
---
## Security and Quoting
- **(Critical)** Check that all variable expansions (like `$VAR` and `$(COMMAND)`) are properly enclosed in **double quotes** (i.e., `"$VAR"` and `"$(COMMAND)"`) to prevent **Word Splitting** and **Globbing**.
- **(Critical)** Find and flag any hardcoded passwords, keys, tokens, or authentication details.
- Verify that all user input, command-line arguments (`$1`, `$2`, etc.), or environment variables are rigorously validated and sanitized before use.
- Avoid `eval` -- warn against and suggest alternatives, as it can lead to arbitrary code execution.
---
## Use Built-in Helper Functions
Never use raw shell commands when acme.sh provides a wrapper function. This is the most critical rule for portability.
| Instead of | Use |
|---|---|
| `tr '[:upper:]' '[:lower:]'` | `_lower_case()` |
| `tr '[:lower:]' '[:upper:]'` | `_upper_case()` |
| `head -n 1` | `_head_n 1` |
| `openssl dgst` / `openssl` | `_digest()` / `_hmac()` |
| `date` | `_utc_date()` with `sed`/`tr` |
| `curl` / `wget` | `_get()` or `_post()` |
| `sleep` | `_sleep` |
| `base64` / `openssl base64` | `_base64()` |
| `$(( ))` arithmetic | `_math()` |
| `grep -E` / `grep -Po` | `_egrep_o()` |
| `printf` | `echo` |
| `idn` command | `_idn()` / `_is_idn()` |
| `mktemp` | `_mktemp()` |
| `[:space:]` | ` ` |
| `[:alnum:]` | `A-Za-z0-9` |
| `[:alpha:]` | `A-Za-z` |
| `[:digit:]` | `0-9` |
| `awk` | `cut` / `sed` / `while read` loops |
When fixing a pattern issue, fix **all instances** in the file, not just the one highlighted.
---
## Forbidden External Tools
Do not use these commands -- they are not portable across all target platforms:
- `jq` (parse JSON with built-in string manipulation)
- `grep -A` (removed throughout the project)
- `grep -Po` (Perl regex not available everywhere)
- `rev`, `xargs`, `iconv`
- If you must depend on an external tool, check with `_exists` first:
```sh
if ! _exists jq; then
_err "jq is required"
return 1
fi
```
- Warn against patterns like `for i in $(cat file)` or `for i in $(ls)` and recommend the more robust `while IFS= read -r line` pattern for safely processing file contents or filenames that might contain spaces.
---
## Configuration Management
Use the correct save/read functions depending on hook type:
- **DNS hooks**: `_readaccountconf_mutable` to read API keys, `_saveaccountconf_mutable` to save them. Do not use `_saveaccountconf` or `_readaccountconf`.
- **Deploy hooks**: `_savedeployconf` / `_getdeployconf`
- **Notification hooks**: use account conf functions.
- Save operations should only happen in the correct lifecycle function (e.g., `_issue()`).
- Use environment variables for all configurable values -- do not introduce hardcoded config files.
- Do not clear account conf without a clear reason.
---
## DNS API Conventions
- Read the [DNS API Dev Guide](https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide) before writing a DNS plugin.
- Each file under `dnsapi/` must contain a `{filename}_add` function for adding DNS TXT records.
- The `_get_root()` loop counter `i` must start from `1` (not `2`) to support DNS alias mode.
- The `dns_*_rm()` function must remove records **by TXT value**, not by replacing/updating. See [#1261](https://github.com/acmesh-official/acme.sh/issues/1261).
- Preserve the `dns_*_info` metadata variable block in each DNS script header.
---
## Variable Naming
- Use CamelCase with provider prefix: `KINGHOST_Username` (not `KINGHOST_username`).
- Variable names should use uppercase letters and underscores (e.g., `MY_VARIABLE`), or follow established project conventions.
- Avoid confusingly similar names. Prefer one variable with comma-separated values over multiple variables (e.g., `CZ_Zones` with comma support instead of separate `CZ_Zone` and `CZ_Zones`).
- Do not define variables with the same name in different scopes.
- Variables inside functions should be declared using the `local` keyword to avoid unintentionally modifying global state.
---
## Code Style
- Use `shfmt` for formatting -- CI enforces it.
- Reduce indentation where possible.
- Single space, not double spaces.
- No trailing semicolons after `return` statements.
- Add a newline at the end of every file.
- Use `$(command)` over backticks `` `command` `` for command substitution.
---
## Simplicity
- Prefer hardcoded sensible defaults over unnecessary configuration variables (e.g., use `3600` for TTL instead of a `DESEC_TTL` variable).
- Reject over-engineered solutions. If it can be done in one line, do it in one line.
- Follow existing patterns in the codebase -- new hooks should look like existing hooks.
- Respect user choices: do not `chmod` files that already exist; the user's permissions take priority.
---
## Documentation Requirements
Before a PR can be merged, the following documentation must be provided:
- **Wiki page**: add or update the relevant page:
- DNS APIs: [dnsapi](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) or [dnsapi2](https://github.com/acmesh-official/acme.sh/wiki/dnsapi2)
- Deploy hooks: [deployhooks](https://github.com/acmesh-official/acme.sh/wiki/deployhooks)
- Notification hooks: [notify](https://github.com/acmesh-official/acme.sh/wiki/notify)
- Options: [Options-and-Params](https://github.com/acmesh-official/acme.sh/wiki/Options-and-Params)
- **In-code usage**: add usage examples in the help text of `acme.sh` itself.
- **README**: add website URLs for new DNS providers.
---
## CI and Merge Hygiene
- All CI checks must pass before merge.
- Rebase to the latest `dev` branch frequently -- do not use merge commits.
- Enable GitHub Actions on your fork to catch errors early.
- Run the [DNS API Test](https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test) workflow for DNS plugins.
- For Docker changes, ensure the Dockerfile includes any required dependencies.
---
## Debug Logging
- Use `_debug2` (not `_debug3` or other levels) unless there is a specific reason for a different level.
---
## Things to Avoid in Reviews
- Do not comment on purely stylistic issues like spacing or indentation, which should be handled by tools like ShellCheck or `shfmt`.
- Do not be overly verbose unless a significant issue is found. Keep feedback concise and actionable.
+723 -254
View File
@@ -1,254 +1,723 @@
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:
workflow_dispatch:
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@v6
- 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@v6
- 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@v6
- 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: ubuntu-latest
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@v6
- 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@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
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
sync: nfs
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
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
OpenBSD:
runs-on: ubuntu-latest
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@v6
- 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@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
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 libiconv
usesh: true
sync: nfs
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
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
NetBSD:
runs-on: ubuntu-latest
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@v6
- 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@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
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: |
/usr/sbin/pkg_add curl socat
usesh: true
sync: nfs
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
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
DragonFlyBSD:
runs-on: ubuntu-latest
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@v6
- 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@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
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 libnghttp2
pkg install -y curl socat
usesh: true
sync: nfs
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
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
MidnightBSD:
runs-on: ubuntu-latest
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 }}
TokenName1: ${{ secrets.TokenName1}}
TokenName2: ${{ secrets.TokenName2}}
TokenName3: ${{ secrets.TokenName3}}
TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}}
steps:
- uses: actions/checkout@v6
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/midnightbsd-vm@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
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: mport install socat curl || true
usesh: true
sync: nfs
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
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
Solaris:
runs-on: ubuntu-latest
needs: MidnightBSD
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@v6
- 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@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
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}}'
sync: nfs
prepare: |
pkgutil -U
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: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
Omnios:
runs-on: ubuntu-latest
needs: Solaris
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 Omnios 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@v6
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/omnios-vm@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
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}}'
sync: nfs
prepare: pkg install socat
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
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
OpenIndiana:
runs-on: ubuntu-latest
needs: Omnios
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 OpenIndiana 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@v6
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/openindiana-vm@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
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}}'
sync: nfs
prepare: pkg install socat
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
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
Haiku:
runs-on: ubuntu-latest
needs: OpenIndiana
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 OpenIndiana 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@v6
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/haiku-vm@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
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}}'
sync: rsync
copyback: false
prepare: |
mkdir -p /boot/home/.cache
pkgman install -y cronie
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
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
+77
View File
@@ -0,0 +1,77 @@
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)
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC DV SSL CA 2"
# CA: "ZeroSSL RSA DV SSL CA 2"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: ubuntu-latest
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@v6
- uses: anyvm-org/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@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
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 libnghttp2
pkg install -y curl socat
usesh: true
sync: nfs
run: |
cd ../acmetest \
&& ./letest.sh
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
+29 -11
View File
@@ -14,6 +14,11 @@ on:
- '*.sh'
- '.github/workflows/FreeBSD.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
FreeBSD:
@@ -24,13 +29,19 @@ jobs:
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
TEST_PREFERRED_CHAIN: (STAGING)
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING)
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_ECDSA: "ZeroSSL ECC DV SSL CA 2"
# CA: "ZeroSSL RSA DV SSL CA 2"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: macos-10.15
runs-on: ubuntu-latest
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@v6
- uses: anyvm-org/cf-tunnel@v0
id: tunnel
with:
protocol: http
@@ -48,16 +60,22 @@ 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@v1
with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
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
sync: nfs
run: |
cd ../acmetest \
&& ./letest.sh
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
+84
View File
@@ -0,0 +1,84 @@
name: Haiku
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/Haiku.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/Haiku.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
Haiku:
strategy:
fail-fast: false
matrix:
include:
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING)
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING)
ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC DV SSL CA 2"
# CA: "ZeroSSL RSA DV SSL CA 2"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: ubuntu-latest
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@v6
- uses: anyvm-org/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/haiku-vm@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: |
"8080": "80"
prepare: |
mkdir -p /boot/home/.cache
pkgman install -y cronie
sync: rsync
copyback: false
run: |
cd ../acmetest \
&& ./letest.sh
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
+18 -4
View File
@@ -15,22 +15,36 @@ on:
- '.github/workflows/Linux.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
Linux:
strategy:
matrix:
os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:7", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3"]
os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "gentoo/stage3"]
runs-on: ubuntu-latest
env:
TEST_LOCAL: 1
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
TEST_PREFERRED_CHAIN: (STAGING)
TEST_ACME_Server: "LetsEncrypt.org_test"
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v6
- uses: anyvm-org/cf-tunnel@v0
id: tunnel
with:
protocol: http
port: 80
- 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 \
&& git clone --depth=1 https://github.com/acmesh-official/acmetest.git \
&& cp -r acme.sh acmetest/
- name: Run acmetest
run: |
+17 -5
View File
@@ -14,6 +14,11 @@ on:
- '*.sh'
- '.github/workflows/MacOS.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
MacOS:
@@ -24,10 +29,10 @@ jobs:
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
TEST_PREFERRED_CHAIN: (STAGING)
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA"
# CA_ECDSA: "ZeroSSL ECC DV SSL CA 2"
# CA: "ZeroSSL RSA DV SSL CA 2"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: macos-latest
@@ -39,13 +44,20 @@ jobs:
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v6
- name: Install tools
run: brew install socat
- uses: anyvm-org/cf-tunnel@v0
id: tunnel
with:
protocol: http
port: 80
- 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 \
&& git clone --depth=1 https://github.com/acmesh-official/acmetest.git \
&& cp -r acme.sh acmetest/
- name: Run acmetest
run: |
+74
View File
@@ -0,0 +1,74 @@
name: MidnightBSD
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/MidnightBSD.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/MidnightBSD.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
MidnightBSD:
strategy:
matrix:
include:
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING)
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC DV SSL CA 2"
# CA: "ZeroSSL RSA DV SSL CA 2"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: ubuntu-latest
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@v6
- uses: anyvm-org/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/midnightbsd-vm@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: |
"8080": "80"
prepare: mport install socat curl wget || true
usesh: true
sync: nfs
run: |
cd ../acmetest \
&& ./letest.sh
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
+76
View File
@@ -0,0 +1,76 @@
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)
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC DV SSL CA 2"
# CA: "ZeroSSL RSA DV SSL CA 2"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: ubuntu-latest
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@v6
- uses: anyvm-org/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@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: |
"8080": "80"
prepare: |
/usr/sbin/pkg_add curl socat
usesh: true
sync: nfs
run: |
cd ../acmetest \
&& ./letest.sh
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
+80
View File
@@ -0,0 +1,80 @@
name: Omnios
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/Omnios.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/Omnios.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
Omnios:
strategy:
matrix:
include:
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING)
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING)
ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC DV SSL CA 2"
# CA: "ZeroSSL RSA DV SSL CA 2"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: ubuntu-latest
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@v6
- uses: anyvm-org/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/omnios-vm@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: |
"8080": "80"
prepare: pkg install socat wget
sync: nfs
run: |
cd ../acmetest \
&& ./letest.sh
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
+81
View File
@@ -0,0 +1,81 @@
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)
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING)
ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC DV SSL CA 2"
# CA: "ZeroSSL RSA DV SSL CA 2"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: ubuntu-latest
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@v6
- uses: anyvm-org/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@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
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 libnghttp2
usesh: true
sync: nfs
run: |
cd ../acmetest \
&& ./letest.sh
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
+80
View File
@@ -0,0 +1,80 @@
name: OpenIndiana
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/OpenIndiana.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/OpenIndiana.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
OpenIndiana:
strategy:
matrix:
include:
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING)
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING)
ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC DV SSL CA 2"
# CA: "ZeroSSL RSA DV SSL CA 2"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: ubuntu-latest
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@v6
- uses: anyvm-org/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/openindiana-vm@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: |
"8080": "80"
prepare: pkg install socat curl
sync: nfs
run: |
cd ../acmetest \
&& ./letest.sh
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
+18 -8
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,23 +33,23 @@ jobs:
TEST_CA: "Pebble Intermediate CA"
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v6
- 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: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker compose up -d
- 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@v6
- 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 ghcr.io/letsencrypt/pebble:latest -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
+82 -61
View File
@@ -1,61 +1,82 @@
name: Solaris
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/Solaris.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/Solaris.yml'
jobs:
Solaris:
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-10.15
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@v2
- uses: vmactions/cf-tunnel@v0.0.3
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 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/solaris-vm@v0.0.5
with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
nat: |
"8080": "80"
prepare: pkgutil -y -i socat curl
run: |
cd ../acmetest \
&& ./letest.sh
name: Solaris
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/Solaris.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/Solaris.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
Solaris:
strategy:
matrix:
include:
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING)
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING)
ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC DV SSL CA 2"
# CA: "ZeroSSL RSA DV SSL CA 2"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: ubuntu-latest
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@v6
- uses: anyvm-org/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/solaris-vm@v1
with:
debug-on-error: ${{ vars.DEBUG_ON_ERROR }}
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: |
"8080": "80"
prepare: |
pkgutil -U
pkgutil -y -i socat curl wget
sync: nfs
run: |
cd ../acmetest \
&& ./letest.sh
- name: DebugOnError
if: ${{ failure() }}
run: |
echo "See how to debug in VM:"
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
+25 -8
View File
@@ -14,6 +14,11 @@ on:
- '*.sh'
- '.github/workflows/Ubuntu.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
Ubuntu:
@@ -24,10 +29,16 @@ jobs:
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
TEST_PREFERRED_CHAIN: (STAGING)
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING)
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_ECDSA: "ZeroSSL ECC DV SSL CA 2"
CA: "ZeroSSL RSA DV SSL CA 2"
CA_EMAIL: "githubtest@acme.sh"
TEST_PREFERRED_CHAIN: ""
- TEST_ACME_Server: "https://localhost:9000/acme/acme/directory"
@@ -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@v6
- 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: |
+18 -6
View File
@@ -15,6 +15,11 @@ on:
- '.github/workflows/Windows.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
Windows:
strategy:
@@ -24,10 +29,10 @@ jobs:
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
TEST_PREFERRED_CHAIN: (STAGING)
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA"
# CA_ECDSA: "ZeroSSL ECC DV SSL CA 2"
# CA: "ZeroSSL RSA DV SSL CA 2"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: windows-latest
@@ -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@v6
- 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
@@ -62,9 +67,16 @@ jobs:
shell: cmd
run: |
echo "PATH=%PATH%"
- uses: anyvm-org/cf-tunnel@v0
id: tunnel
with:
protocol: http
port: 80
- name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- 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
+25 -8
View File
@@ -11,7 +11,13 @@ on:
- "Dockerfile"
- '.github/workflows/dockerhub.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
DOCKER_IMAGE: neilpang/acme.sh
jobs:
CheckToken:
runs-on: ubuntu-latest
@@ -24,9 +30,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,18 +43,23 @@ jobs:
if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
steps:
- name: checkout code
uses: actions/checkout@v2
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v2
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v6
with:
images: ${DOCKER_IMAGE}
- 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
- name: build and push the image
run: |
DOCKER_IMAGE=neilpang/acme.sh
if [[ $GITHUB_REF == refs/tags/* ]]; then
DOCKER_IMAGE_TAG=${GITHUB_REF#refs/tags/}
fi
@@ -62,8 +73,14 @@ jobs:
fi
fi
DOCKER_LABELS=()
while read -r label; do
DOCKER_LABELS+=(--label "${label}")
done <<<"${DOCKER_METADATA_OUTPUT_LABELS}"
docker buildx build \
--tag ${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG} \
"${DOCKER_LABELS[@]}" \
--output "type=image,push=true" \
--build-arg AUTO_UPGRADE=${AUTO_UPGRADE} \
--platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386,linux/ppc64le,linux/s390x .
+19
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."
})
+34
View File
@@ -0,0 +1,34 @@
name: Check dns api
on:
pull_request_target:
types:
- opened
paths:
- 'dnsapi/*.sh'
jobs:
welcome:
runs-on: ubuntu-latest
if: github.actor != 'neilpang'
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**
READ ME !!!!!
Read me !!!!!!
First thing: don't send PR to the master branch, please send to the dev branch instead.
Please read the [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide).
You MUST pass the [DNS-API-Test](../wiki/DNS-API-Test).
Then reply on this message, otherwise, your code will not be reviewed or merged.
Please also make sure to add/update the usage here: https://github.com/acmesh-official/acme.sh/wiki/dnsapi2
注意: 必须通过了 [DNS-API-Test](../wiki/DNS-API-Test) 才会被 review. 无论是修改, 还是新加的 dns api, 都必须确保通过这个测试.
`
})
+31
View File
@@ -0,0 +1,31 @@
name: Check notify api
on:
pull_request_target:
types:
- opened
branches:
- 'dev'
paths:
- 'notify/*.sh'
jobs:
welcome:
runs-on: ubuntu-latest
if: github.actor != 'neilpang'
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've 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 ✨
`
})
+8 -3
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@v6
- 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@v6
- 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
+66
View File
@@ -0,0 +1,66 @@
name: Notify via Issue on Wiki Edit
on:
gollum:
jobs:
notify:
runs-on: ubuntu-latest
if: github.actor != 'neilpang'
steps:
- name: Checkout wiki repository
uses: actions/checkout@v6
with:
repository: ${{ github.repository }}.wiki
path: wiki
fetch-depth: 0
- name: Generate wiki change message
run: |
actor="${{ github.actor }}"
sender_url=$(jq -r '.sender.html_url' "$GITHUB_EVENT_PATH")
page_name=$(jq -r '.pages[0].page_name' "$GITHUB_EVENT_PATH")
page_sha=$(jq -r '.pages[0].sha' "$GITHUB_EVENT_PATH")
page_url=$(jq -r '.pages[0].html_url' "$GITHUB_EVENT_PATH")
page_action=$(jq -r '.pages[0].action' "$GITHUB_EVENT_PATH")
page_summary=$(jq -r '.pages[0].summary' "$GITHUB_EVENT_PATH")
now="$(date '+%Y-%m-%d %H:%M:%S')"
cd wiki
prev_sha=$(git rev-list $page_sha^ -- "$page_name.md" | head -n 1)
if [ -n "$prev_sha" ]; then
git diff $prev_sha $page_sha -- "$page_name.md" > ../wiki.diff || echo "(No diff found)" > ../wiki.diff
else
echo "(no diff)" > ../wiki.diff
fi
cd ..
{
echo "Wiki edited"
echo -n "User: "
echo "@$actor [$actor]($sender_url)"
echo "Time: $now"
echo "Page: [$page_name]($page_url) (Action: $page_action)"
echo "Comment: $page_summary"
echo "[Click here to Revert](${page_url}/_history)"
echo ""
echo "----"
echo "### diff:"
echo '```diff'
cat wiki.diff
echo '```'
} > wiki-change-msg.txt
- name: Create issue to notify Neilpang
uses: peter-evans/create-issue-from-file@v5
with:
title: "Wiki edited"
content-filepath: ./wiki-change-msg.txt
assignees: Neilpang
env:
TZ: Asia/Shanghai
+30 -11
View File
@@ -1,4 +1,4 @@
FROM alpine:3.15
FROM alpine:3.23
RUN apk --no-cache add -f \
openssl \
@@ -12,20 +12,33 @@ RUN apk --no-cache add -f \
oath-toolkit-oathtool \
tar \
libidn \
jq
jq \
yq-go \
supercronic
ENV LE_CONFIG_HOME /acme.sh
ENV LE_WORKING_DIR=/acmebin
ENV LE_CONFIG_HOME=/acme.sh
ENV HOME=/acme.sh
ARG AUTO_UPGRADE=1
ENV AUTO_UPGRADE $AUTO_UPGRADE
ENV AUTO_UPGRADE=$AUTO_UPGRADE
#Install
COPY ./ /install_acme.sh/
COPY ./acme.sh /install_acme.sh/acme.sh
COPY ./deploy /install_acme.sh/deploy
COPY ./dnsapi /install_acme.sh/dnsapi
COPY ./notify /install_acme.sh/notify
RUN addgroup -g 1000 acme && adduser -h $LE_CONFIG_HOME -s /bin/sh -G acme -D -H -u 1000 acme
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 $LE_WORKING_DIR/acme.sh /usr/local/bin/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 chown -R acme:acme $LE_CONFIG_HOME
RUN for verb in help \
version \
@@ -59,17 +72,23 @@ RUN for verb in help \
set-default-ca \
set-default-chain \
; do \
printf -- "%b" "#!/usr/bin/env sh\n/root/.acme.sh/acme.sh --${verb} --config-home /acme.sh \"\$@\"" >/usr/local/bin/--${verb} && chmod +x /usr/local/bin/--${verb} \
printf -- "%b" "#!/usr/bin/env sh\n$LE_WORKING_DIR/acme.sh --${verb} --config-home $LE_CONFIG_HOME \"\$@\"" >/usr/local/bin/--${verb} && chmod +x /usr/local/bin/--${verb} \
; done
RUN printf "%b" '#!'"/usr/bin/env sh\n \
if [ \"\$1\" = \"daemon\" ]; then \n \
trap \"echo stop && killall crond && exit 0\" SIGTERM SIGINT \n \
crond && sleep infinity &\n \
wait \n \
if [ ! -f \"\$LE_CONFIG_HOME/crontab\" ]; then \n \
echo \"\$LE_CONFIG_HOME/crontab not found, generating one\" \n \
time=\$(date -u \"+%s\") \n \
random_minute=\$((\$time % 60)) \n \
random_hour=\$((\$time / 60 % 24)) \n \
echo \"\$random_minute \$random_hour * * * \\\"\$LE_WORKING_DIR\\\"/acme.sh --cron --home \\\"\$LE_WORKING_DIR\\\" --config-home \\\"\$LE_CONFIG_HOME\\\"\" > \"\$LE_CONFIG_HOME\"/crontab \n \
fi \n \
echo \"Running Supercronic using crontab at \$LE_CONFIG_HOME/crontab\" \n \
exec -- /usr/bin/supercronic \"\$LE_CONFIG_HOME/crontab\" \n \
else \n \
exec -- \"\$@\"\n \
fi" >/entry.sh && chmod +x /entry.sh
fi\n" >/entry.sh && chmod +x /entry.sh && chmod -R o+rwx $LE_WORKING_DIR && chmod -R o+rwx $LE_CONFIG_HOME
VOLUME /acme.sh
+262 -187
View File
@@ -1,64 +1,89 @@
# An ACME Shell script: acme.sh
<p align="center">
<a href="https://zerossl.com/?fromacme.sh">
<img src="https://github.com/user-attachments/assets/7531085e-399b-4ac2-82a2-90d14a0b7f05" alt="zerossl.com">
</a>
</p>
[![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)
[![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)
<h1 align="center">🔐 acme.sh</h1>
<h3 align="center">An ACME Protocol Client Written Purely in Shell</h3>
![Shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg)
![PebbleStrict](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg)
![DockerHub](https://github.com/acmesh-official/acme.sh/workflows/Build%20DockerHub/badge.svg)
<p align="center">
<a href="https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml"><img src="https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml/badge.svg" alt="FreeBSD"></a>
<a href="https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml"><img src="https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml/badge.svg" alt="OpenBSD"></a>
<a href="https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml"><img src="https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml/badge.svg" alt="NetBSD"></a>
<a href="https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml"><img src="https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml/badge.svg" alt="MacOS"></a>
<a href="https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml"><img src="https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg" alt="Ubuntu"></a>
<a href="https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml"><img src="https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml/badge.svg" alt="Windows"></a>
<a href="https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml"><img src="https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml/badge.svg" alt="Solaris"></a>
<a href="https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml"><img src="https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml/badge.svg" alt="DragonFlyBSD"></a>
<a href="https://github.com/acmesh-official/acme.sh/actions/workflows/MidnightBSD.yml"><img src="https://github.com/acmesh-official/acme.sh/actions/workflows/MidnightBSD.yml/badge.svg" alt="MidnightBSD"></a>
<a href="https://github.com/acmesh-official/acme.sh/actions/workflows/Omnios.yml"><img src="https://github.com/acmesh-official/acme.sh/actions/workflows/Omnios.yml/badge.svg" alt="Omnios"></a>
<a href="https://github.com/acmesh-official/acme.sh/actions/workflows/OpenIndiana.yml"><img src="https://github.com/acmesh-official/acme.sh/actions/workflows/OpenIndiana.yml/badge.svg" alt="OpenIndiana"></a>
<a href="https://github.com/acmesh-official/acme.sh/actions/workflows/Haiku.yml"><img src="https://github.com/acmesh-official/acme.sh/actions/workflows/Haiku.yml/badge.svg" alt="Haiku"></a>
</p>
<p align="center">
<img src="https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg" alt="Shellcheck">
<img src="https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg" alt="PebbleStrict">
<img src="https://github.com/acmesh-official/acme.sh/workflows/Build%20DockerHub/badge.svg" alt="DockerHub">
</p>
<p align="center">
<a href="https://opencollective.com/acmesh"><img src="https://opencollective.com/acmesh/all/badge.svg?label=financial+contributors" alt="Financial Contributors on Open Collective"></a>
<a href="https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/acme-sh/Lobby.svg" alt="Join the chat at Gitter"></a>
<a href="https://hub.docker.com/r/neilpang/acme.sh" title="Click to view the image on Docker Hub"><img src="https://img.shields.io/docker/stars/neilpang/acme.sh.svg" alt="Docker stars"></a>
<a href="https://hub.docker.com/r/neilpang/acme.sh" title="Click to view the image on Docker Hub"><img src="https://img.shields.io/docker/pulls/neilpang/acme.sh.svg" alt="Docker pulls"></a>
</p>
<a href="https://opencollective.com/acmesh" alt="Financial Contributors on Open Collective"><img src="https://opencollective.com/acmesh/all/badge.svg?label=financial+contributors" /></a>
[![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Docker stars](https://img.shields.io/docker/stars/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub")
[![Docker pulls](https://img.shields.io/docker/pulls/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub")
---
## ✨ Features
- 🐚 An ACME protocol client written **purely in Shell** (Unix shell) language
- 📜 Full ACME protocol implementation
- 🔑 Support **ECDSA** certificates
- 🌐 Support **SAN** and **wildcard** certificates
- ⚡ Simple, powerful and very easy to use — only **3 minutes** to learn!
- 🔧 Compatible with **Bash**, **dash** and **sh**
- 🚫 No dependencies on Python
- 🔄 One script to issue, renew and install your certificates automatically
- 👤 **DOES NOT** require `root/sudoer` access
- 🐳 Docker ready
- 🌍 IPv6 ready
- 📧 Cron job notifications for renewal or error
- An ACME protocol client written purely in Shell (Unix shell) language.
- Full ACME protocol implementation.
- Support ECDSA certs
- Support SAN and wildcard certs
- Simple, powerful and very easy to use. You only need 3 minutes to learn it.
- Bash, dash and sh compatible.
- Purely written in Shell with no dependencies on python.
- Just one script to issue, renew and install your certificates automatically.
- DOES NOT require `root/sudoer` access.
- Docker ready
- IPv6 ready
- Cron job notifications for renewal or error etc.
> 💡 It's probably the **easiest & smartest** shell script to automatically issue & renew free certificates.
It's probably the `easiest & smartest` shell script to automatically issue & renew the free certificates.
<p align="center">
<a href="https://github.com/acmesh-official/acme.sh/wiki"><strong>📚 Wiki</strong></a> •
<a href="https://github.com/acmesh-official/acme.sh/wiki/Run-acme.sh-in-docker"><strong>🐳 Docker Guide</strong></a> •
<a href="https://twitter.com/neilpangxa"><strong>🐦 Twitter</strong></a>
</p>
Wiki: https://github.com/acmesh-official/acme.sh/wiki
---
For Docker Fans: [acme.sh :two_hearts: Docker ](https://github.com/acmesh-official/acme.sh/wiki/Run-acme.sh-in-docker)
## 🌏 [中文说明](https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E)
Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
---
# [中文说明](https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E)
# Who:
## 🏆 Who Uses acme.sh?
- [FreeBSD.org](https://blog.crashed.org/letsencrypt-in-freebsd-org/)
- [ruby-china.org](https://ruby-china.org/topics/31983)
- [Proxmox](https://pve.proxmox.com/wiki/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)
# Tested OS
---
## 🖥️ Tested OS
| NO | Status| Platform|
|----|-------|---------|
@@ -68,67 +93,81 @@ 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|[![MidnightBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/MidnightBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/MidnightBSD.yml)|MidnightBSD
|11|[![Omnios](https://github.com/acmesh-official/acme.sh/actions/workflows/Omnios.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Omnios.yml)|Omnios
|12|[![OpenIndiana](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenIndiana.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenIndiana.yml)|OpenIndiana
|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)| Debian
|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)|openSUSE
|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)|Alpine Linux (with curl)
|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)|Archlinux
|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)|fedora
|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)|Kali Linux
|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)|Oracle Linux
|20|[![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
|21|[![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
|22|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111
|23|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT)
|24|[![](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)
|25|[![Haiku](https://github.com/acmesh-official/acme.sh/actions/workflows/Haiku.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Haiku.yml)|Haiku OS
Check our [testing project](https://github.com/acmesh-official/acmetest):
> 🧪 Check our [testing project](https://github.com/acmesh-official/acmetest)
>
> 🖥️ The testing VMs are supported by [vmactions.org](https://vmactions.org)
https://github.com/acmesh-official/acmetest
---
# Supported CA
## 🏛️ Supported CA
- [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA)(default)
- 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
| CA | Status |
|---|---|
| [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA) | ⭐ **Default** |
| Letsencrypt.org CA | ✅ Supported |
| [SSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/SSL.com-CA) | ✅ Supported |
| [Google.com Public CA](https://github.com/acmesh-official/acme.sh/wiki/Google-Public-CA) | ✅ Supported |
| [Actalis.com CA](https://github.com/acmesh-official/acme.sh/wiki/Actalis.com-CA) | ✅ Supported |
| [Pebble strict Mode](https://github.com/letsencrypt/pebble) | ✅ Supported |
| Any [RFC8555](https://tools.ietf.org/html/rfc8555)-compliant CA | ✅ Supported |
# Supported modes
---
- Webroot mode
- Standalone mode
- Standalone tls-alpn mode
- Apache mode
- Nginx mode
- DNS mode
- [DNS alias mode](https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode)
- [Stateless mode](https://github.com/acmesh-official/acme.sh/wiki/Stateless-Mode)
## ⚙️ Supported Modes
| Mode | Description |
|------|-------------|
| 📁 Webroot mode | Use existing webroot directory |
| 🖥️ Standalone mode | Built-in webserver on port 80 |
| 🔐 Standalone tls-alpn mode | Built-in webserver on port 443 |
| 🪶 Apache mode | Use Apache for verification |
| ⚡ Nginx mode | Use Nginx for verification |
| 🌐 DNS mode | Use DNS TXT records |
| 🔗 [DNS alias mode](https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode) | Use DNS alias for verification |
| 📡 [Stateless mode](https://github.com/acmesh-official/acme.sh/wiki/Stateless-Mode) | Stateless verification |
# 1. How to install
---
### 1. Install online
## 📖 Usage Guide
Check this project: https://github.com/acmesh-official/get.acme.sh
### 1️⃣ How to Install
#### 📥 Install Online
> Check this project: https://github.com/acmesh-official/get.acme.sh
```bash
curl https://get.acme.sh | sh -s email=my@example.com
```
Or:
**Or:**
```bash
wget -O - https://get.acme.sh | sh -s email=my@example.com
```
### 2. Or, Install from git
#### 📦 Install from Git
Clone this project and launch installation:
@@ -138,11 +177,11 @@ cd ./acme.sh
./acme.sh --install -m my@example.com
```
You `don't have to be root` then, although `it is recommended`.
> 💡 You `don't have to be root` then, although `it is recommended`.
Advanced Installation: https://github.com/acmesh-official/acme.sh/wiki/How-to-install
📚 **Advanced Installation:** https://github.com/acmesh-official/acme.sh/wiki/How-to-install
The installer will perform 3 actions:
**The installer will perform 3 actions:**
1. Create and copy `acme.sh` to your home dir (`$HOME`): `~/.acme.sh/`.
All certs will be placed in this folder too.
@@ -155,17 +194,19 @@ Cron entry example:
0 0 * * * "/home/user/.acme.sh"/acme.sh --cron --home "/home/user/.acme.sh" > /dev/null
```
After the installation, you must close the current terminal and reopen it to make the alias take effect.
> ⚠️ After the installation, you must close the current terminal and reopen it to make the alias take effect.
Ok, you are ready to issue certs now.
✅ **You are ready to issue certs now!**
Show help message:
**Show help message:**
```sh
root@v1:~# acme.sh -h
acme.sh -h
```
# 2. Just issue a cert
---
### 2️⃣ Issue a Certificate
**Example 1:** Single domain.
@@ -200,17 +241,21 @@ You must point and bind all the domains to the same webroot dir: `/home/wwwroot/
The certs will be placed in `~/.acme.sh/example.com/`
The certs will be renewed automatically every **60** days.
> 🔄 The certs will be renewed automatically every **30** days.
More examples: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
> 🔐 The certs will default to **ECC** certificates.
📚 **More examples:** https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
# 3. Install the cert to Apache/Nginx etc.
---
### 3️⃣ Install the Certificate to Apache/Nginx
After the cert is generated, you probably want to install/copy the cert to your Apache/Nginx or other servers.
You **MUST** use this command to copy the certs to the target files, **DO NOT** use the certs files in **~/.acme.sh/** folder, they are for internal use only, the folder structure may change in the future.
**Apache** example:
> ⚠️ **IMPORTANT:** You **MUST** use this command to copy the certs to the target files. **DO NOT** use the certs files in `~/.acme.sh/` folder — they are for internal use only, the folder structure may change in the future.
#### 🪶 Apache Example:
```bash
acme.sh --install-cert -d example.com \
--cert-file /path/to/certfile/in/apache/cert.pem \
@@ -219,7 +264,7 @@ acme.sh --install-cert -d example.com \
--reloadcmd "service apache2 force-reload"
```
**Nginx** example:
#### ⚡ Nginx Example:
```bash
acme.sh --install-cert -d example.com \
--key-file /path/to/keyfile/in/nginx/key.pem \
@@ -233,91 +278,89 @@ The ownership and permission info of existing files are preserved. You can pre-c
Install/copy the cert/key to the production Apache or Nginx path.
The cert will be renewed every **60** days by default (which is configurable). Once the cert is renewed, the Apache/Nginx service will be reloaded automatically by the command: `service apache2 force-reload` or `service nginx force-reload`.
> 🔄 The cert will be renewed every **30** days by default (configurable). Once renewed, the Apache/Nginx service will be reloaded automatically.
> ⚠️ **IMPORTANT:** The `reloadcmd` is very important. The cert can be automatically renewed, but without a correct `reloadcmd`, the cert may not be flushed to your server (like nginx or apache), then your website will not be able to show the renewed cert.
**Please take care: The reloadcmd is very important. The cert can be automatically renewed, but, without a correct 'reloadcmd' the cert may not be flushed to your server(like nginx or apache), then your website will not be able to show renewed cert in 60 days.**
---
# 4. Use Standalone server to issue cert
### 4️⃣ Use Standalone Server to Issue Certificate
**(requires you to be root/sudoer or have permission to listen on port 80 (TCP))**
> 🔐 Requires root/sudoer or permission to listen on port **80** (TCP)
Port `80` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again.
> ⚠️ Port `80` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again.
```bash
acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com
```
More examples: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
📚 **More examples:** https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
# 5. Use Standalone ssl server to issue cert
---
**(requires you to be root/sudoer or have permission to listen on port 443 (TCP))**
### 5️⃣ Use Standalone TLS Server to Issue Certificate
Port `443` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again.
> 🔐 Requires root/sudoer or permission to listen on port **443** (TCP)
> ⚠️ Port `443` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again.
```bash
acme.sh --issue --alpn -d example.com -d www.example.com -d cp.example.com
```
More examples: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
📚 **More examples:** https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
---
# 6. Use Apache mode
### 6️⃣ Use Apache Mode
**(requires you to be root/sudoer, since it is required to interact with Apache server)**
> 🔐 Requires root/sudoer to interact with Apache server
If you are running a web server, it is recommended to use the `Webroot mode`.
Particularly, if you are running an Apache server, you can use Apache mode instead. This mode doesn't write any files to your web root folder.
Just set string "apache" as the second argument and it will force use of apache plugin automatically.
```sh
acme.sh --issue --apache -d example.com -d www.example.com -d cp.example.com
```
**This apache mode is only to issue the cert, it will not change your apache config files.
You will need to configure your website config files to use the cert by yourself.
We don't want to mess with your apache server, don't worry.**
> 💡 **Note:** This Apache mode is only to issue the cert, it will **not** change your Apache config files. You will need to configure your website config files to use the cert by yourself. We don't want to mess with your Apache server, don't worry!
More examples: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
📚 **More examples:** https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
# 7. Use Nginx mode
---
**(requires you to be root/sudoer, since it is required to interact with Nginx server)**
### 7️⃣ Use Nginx Mode
> 🔐 Requires root/sudoer to interact with Nginx server
If you are running a web server, it is recommended to use the `Webroot mode`.
Particularly, if you are running an nginx server, you can use nginx mode instead. This mode doesn't write any files to your web root folder.
Particularly, if you are running an Nginx server, you can use Nginx mode instead. This mode doesn't write any files to your web root folder.
Just set string "nginx" as the second argument.
It will configure nginx server automatically to verify the domain and then restore the nginx config to the original version.
So, the config is not changed.
It will configure Nginx server automatically to verify the domain and then restore the Nginx config to the original version. So, the config is not changed.
```sh
acme.sh --issue --nginx -d example.com -d www.example.com -d cp.example.com
```
**This nginx mode is only to issue the cert, it will not change your nginx config files.
You will need to configure your website config files to use the cert by yourself.
We don't want to mess with your nginx server, don't worry.**
> 💡 **Note:** This Nginx mode is only to issue the cert, it will **not** change your Nginx config files. You will need to configure your website config files to use the cert by yourself. We don't want to mess with your Nginx server, don't worry!
More examples: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
📚 **More examples:** https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
# 8. Automatic DNS API integration
---
### 8️⃣ Automatic DNS API Integration
If your DNS provider supports API access, we can use that API to automatically issue the certs.
You don't have to do anything manually!
> ✨ **You don't have to do anything manually!**
### Currently acme.sh supports most of the dns providers:
📚 **Currently acme.sh supports most DNS providers:** https://github.com/acmesh-official/acme.sh/wiki/dnsapi
https://github.com/acmesh-official/acme.sh/wiki/dnsapi
---
# 9. Use DNS manual mode:
### 9️⃣ Use DNS Manual Mode
See: https://github.com/acmesh-official/acme.sh/wiki/dns-manual-mode first.
@@ -347,72 +390,74 @@ Then just rerun with `renew` argument:
acme.sh --renew -d example.com
```
Ok, it's done.
✅ **Done!**
**Take care, this is dns manual mode, it can not be renewed automatically. you will have to add a new txt record to your domain by your hand when you renew your cert.**
> ⚠️ **WARNING:** This is DNS manual mode — it **cannot** be renewed automatically. You will have to add a new TXT record to your domain manually when you renew your cert. **Please use DNS API mode instead.**
**Please use dns api mode instead.**
---
# 10. Issue ECC certificates
### 🔟 Issue Certificates of Different Key Types (ECC or RSA)
`Let's Encrypt` can now issue **ECDSA** certificates.
Just set the `keylength` to a valid, supported value.
And we support them too!
**Valid values for the `keylength` parameter:**
Just set the `keylength` parameter with a prefix `ec-`.
| Key Length | Description |
|------------|-------------|
| `ec-256` | prime256v1, "ECDSA P-256" ⭐ **Default** |
| `ec-384` | secp384r1, "ECDSA P-384" |
| `ec-521` | secp521r1, "ECDSA P-521" ⚠️ Not supported by Let's Encrypt yet |
| `2048` | RSA 2048-bit |
| `3072` | RSA 3072-bit |
| `4096` | RSA 4096-bit |
For example:
**Examples:**
### Single domain ECC certificate
#### Single domain with ECDSA P-384 certificate
```bash
acme.sh --issue -w /home/wwwroot/example.com -d example.com --keylength ec-256
acme.sh --issue -w /home/wwwroot/example.com -d example.com --keylength ec-384
```
### SAN multi domain ECC certificate
#### SAN multi domain with RSA4096 certificate
```bash
acme.sh --issue -w /home/wwwroot/example.com -d example.com -d www.example.com --keylength ec-256
acme.sh --issue -w /home/wwwroot/example.com -d example.com -d www.example.com --keylength 4096
```
Please look at the `keylength` parameter above.
---
Valid values are:
### 1️⃣1️⃣ Issue Wildcard Certificates
1. **ec-256 (prime256v1, "ECDSA P-256")**
2. **ec-384 (secp384r1, "ECDSA P-384")**
3. **ec-521 (secp521r1, "ECDSA P-521", which is not supported by Let's Encrypt yet.)**
# 11. Issue Wildcard certificates
It's simple, just give a wildcard domain as the `-d` parameter.
It's simple! Just give a wildcard domain as the `-d` parameter:
```sh
acme.sh --issue -d example.com -d '*.example.com' --dns dns_cf
acme.sh --issue -d example.com -d '*.example.com' --dns dns_cf
```
# 12. How to renew the certs
---
No, you don't need to renew the certs manually. All the certs will be renewed automatically every **60** days.
### 1️⃣2️⃣ How to Renew Certificates
However, you can also force to renew a cert:
> 🔄 No need to renew manually! All certs will be renewed automatically every **30** days.
However, you can force a renewal:
```sh
acme.sh --renew -d example.com --force
```
or, for ECC cert:
**For ECC cert:**
```sh
acme.sh --renew -d example.com --force --ecc
```
---
# 13. How to stop cert renewal
### 1️⃣3️⃣ How to Stop Certificate Renewal
To stop renewal of a cert, you can execute the following to remove the cert from the renewal list:
@@ -422,73 +467,78 @@ acme.sh --remove -d example.com [--ecc]
The cert/key file is not removed from the disk.
You can remove the respective directory (e.g. `~/.acme.sh/example.com`) by yourself.
> 💡 You can remove the respective directory (e.g. `~/.acme.sh/example.com`) manually.
---
# 14. How to upgrade `acme.sh`
### 1️⃣4️⃣ How to Upgrade acme.sh
acme.sh is in constant development, so it's strongly recommended to use the latest code.
> 🚀 acme.sh is in constant development — it's strongly recommended to use the latest code.
You can update acme.sh to the latest code:
**Update to latest:**
```sh
acme.sh --upgrade
```
You can also enable auto upgrade:
**Enable auto upgrade:**
```sh
acme.sh --upgrade --auto-upgrade
```
Then **acme.sh** will be kept up to date automatically.
Disable auto upgrade:
**Disable auto upgrade:**
```sh
acme.sh --upgrade --auto-upgrade 0
```
---
# 15. Issue a cert from an existing CSR
### 1️⃣5️⃣ Issue a Certificate from an Existing CSR
https://github.com/acmesh-official/acme.sh/wiki/Issue-a-cert-from-existing-CSR
📚 https://github.com/acmesh-official/acme.sh/wiki/Issue-a-cert-from-existing-CSR
---
# 16. Send notifications in cronjob
### 1️⃣6️⃣ Send Notifications in Cronjob
https://github.com/acmesh-official/acme.sh/wiki/notify
📚 https://github.com/acmesh-official/acme.sh/wiki/notify
---
# 17. Under the Hood
### 1️⃣7️⃣ Under the Hood
Speak ACME language using shell, directly to "Let's Encrypt".
> 🔧 Speak ACME language using shell, directly to "Let's Encrypt".
TODO:
---
### 1️⃣8️⃣ Acknowledgments
# 18. Acknowledgments
| Project | Link |
|---------|------|
| 🙏 Acme-tiny | https://github.com/diafygi/acme-tiny |
| 📜 ACME protocol | https://github.com/ietf-wg-acme/acme |
1. Acme-tiny: https://github.com/diafygi/acme-tiny
2. ACME protocol: https://github.com/ietf-wg-acme/acme
---
## 👥 Contributors
## Contributors
### Code Contributors
### 💻 Code Contributors
This project exists thanks to all the people who contribute.
<a href="https://github.com/acmesh-official/acme.sh/graphs/contributors"><img src="https://opencollective.com/acmesh/contributors.svg?width=890&button=false" /></a>
### Financial Contributors
### 💰 Financial Contributors
Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/acmesh/contribute)]
#### Individuals
#### 👤 Individuals
<a href="https://opencollective.com/acmesh"><img src="https://opencollective.com/acmesh/individuals.svg?width=890"></a>
#### Organizations
#### 🏢 Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/acmesh/contribute)]
@@ -503,18 +553,43 @@ 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>
# 19. License & Others
---
License is GPLv3
### 1️⃣9️⃣ License & Others
Please Star and Fork me.
📄 **License:** GPLv3
[Issues](https://github.com/acmesh-official/acme.sh/issues) and [pull requests](https://github.com/acmesh-official/acme.sh/pulls) are welcome.
⭐ Please **Star** and **Fork** this project!
🐛 [Issues](https://github.com/acmesh-official/acme.sh/issues) and 🔀 [Pull Requests](https://github.com/acmesh-official/acme.sh/pulls) are welcome.
# 20. Donate
Your donation makes **acme.sh** better:
---
1. PayPal/Alipay(支付宝)/Wechat(微信): [https://donate.acme.sh/](https://donate.acme.sh/)
### 2️⃣0️⃣ Donate
[Donate List](https://github.com/acmesh-official/acme.sh/wiki/Donate-list)
> 💝 Your donation makes **acme.sh** better!
| Method | Link |
|--------|------|
| PayPal / Alipay(支付宝) / Wechat(微信) | [https://donate.acme.sh/](https://donate.acme.sh/) |
📜 [Donate List](https://github.com/acmesh-official/acme.sh/wiki/Donate-list)
---
### 2️⃣1️⃣ About This Repository
> [!NOTE]
> This repository is officially maintained by <strong>ZeroSSL</strong> as part of our commitment to providing secure and reliable SSL/TLS solutions. We welcome contributions and feedback from the community!
> For more information about our services, including free and paid SSL/TLS certificates, visit https://zerossl.com.
>
> All donations made through this repository go directly to the original independent maintainer (Neil Pang), not to ZeroSSL.
<p align="center">
<a href="https://zerossl.com">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://zerossl.com/assets/images/zerossl_logo_white.svg">
<source media="(prefers-color-scheme: light)" srcset="https://zerossl.com/assets/images/zerossl_logo.svg">
<img src="https://zerossl.com/assets/images/zerossl_logo.svg" alt="ZeroSSL" width="256">
</picture>
</a>
</p>
+1138 -656
View File
File diff suppressed because it is too large. Load diff
+88
View File
@@ -0,0 +1,88 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034,SC2154
# Script to create certificate to Alibaba Cloud CDN
#
# Docs: https://github.com/acmesh-official/acme.sh/wiki/deployhooks#33-deploy-your-certificate-to-cdn-or-dcdn-of-alibaba-cloud-aliyun
#
# This deployment required following variables
# export Ali_Key="ALIACCESSKEY"
# export Ali_Secret="ALISECRETKEY"
# The credentials are shared with all the Alibaba Cloud deploy hooks and dnsapi
#
# To specify the CDN domain that is different from the certificate CN, usually used for multi-domain or wildcard certificates
# export DEPLOY_ALI_CDN_DOMAIN="cdn.example.com"
# If you have multiple CDN domains using the same certificate, just
# export DEPLOY_ALI_CDN_DOMAIN="cdn1.example.com cdn2.example.com"
#
# For DCDN, see ali_dcdn deploy hook
Ali_CDN_API="https://cdn.aliyuncs.com/"
ali_cdn_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
# Load dnsapi/dns_ali.sh to reduce the duplicated codes
# https://github.com/acmesh-official/acme.sh/pull/5205#issuecomment-2357867276
dnsapi_ali="$(_findHook "$_cdomain" "$_SUB_FOLDER_DNSAPI" dns_ali)"
# shellcheck source=/dev/null
if ! . "$dnsapi_ali"; then
_err "Error loading file $dnsapi_ali. Please check your API file and try again."
return 1
fi
_prepare_ali_credentials || return 1
_getdeployconf DEPLOY_ALI_CDN_DOMAIN
if [ "$DEPLOY_ALI_CDN_DOMAIN" ]; then
_savedeployconf DEPLOY_ALI_CDN_DOMAIN "$DEPLOY_ALI_CDN_DOMAIN"
else
DEPLOY_ALI_CDN_DOMAIN="$_cdomain"
fi
# read cert and key files and urlencode both
_cert=$(_url_encode upper-hex <"$_cfullchain")
_key=$(_url_encode upper-hex <"$_ckey")
_debug2 _cert "$_cert"
_debug2 _key "$_key"
## update domain ssl config
for domain in $DEPLOY_ALI_CDN_DOMAIN; do
_set_cdn_domain_ssl_certificate_query "$domain" "$_cert" "$_key"
if _ali_rest "Set CDN domain SSL certificate for $domain" "" POST; then
_info "Domain $domain certificate has been deployed successfully"
fi
done
return 0
}
# domain pub pri
_set_cdn_domain_ssl_certificate_query() {
endpoint=$Ali_CDN_API
query=''
query=$query'AccessKeyId='$Ali_Key
query=$query'&Action=SetCdnDomainSSLCertificate'
query=$query'&CertType=upload'
query=$query'&DomainName='$1
query=$query'&Format=json'
query=$query'&SSLPri='$3
query=$query'&SSLProtocol=on'
query=$query'&SSLPub='$2
query=$query'&SignatureMethod=HMAC-SHA1'
query=$query"&SignatureNonce=$(_ali_nonce)"
query=$query'&SignatureVersion=1.0'
query=$query'&Timestamp='$(_ali_timestamp)
query=$query'&Version=2018-05-10'
}
+88
View File
@@ -0,0 +1,88 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034,SC2154
# Script to create certificate to Alibaba Cloud DCDN
#
# Docs: https://github.com/acmesh-official/acme.sh/wiki/deployhooks#33-deploy-your-certificate-to-cdn-or-dcdn-of-alibaba-cloud-aliyun
#
# This deployment required following variables
# export Ali_Key="ALIACCESSKEY"
# export Ali_Secret="ALISECRETKEY"
# The credentials are shared with all the Alibaba Cloud deploy hooks and dnsapi
#
# To specify the DCDN domain that is different from the certificate CN, usually used for multi-domain or wildcard certificates
# export DEPLOY_ALI_DCDN_DOMAIN="dcdn.example.com"
# If you have multiple CDN domains using the same certificate, just
# export DEPLOY_ALI_DCDN_DOMAIN="dcdn1.example.com dcdn2.example.com"
#
# For regular CDN, see ali_cdn deploy hook
Ali_DCDN_API="https://dcdn.aliyuncs.com/"
ali_dcdn_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
# Load dnsapi/dns_ali.sh to reduce the duplicated codes
# https://github.com/acmesh-official/acme.sh/pull/5205#issuecomment-2357867276
dnsapi_ali="$(_findHook "$_cdomain" "$_SUB_FOLDER_DNSAPI" dns_ali)"
# shellcheck source=/dev/null
if ! . "$dnsapi_ali"; then
_err "Error loading file $dnsapi_ali. Please check your API file and try again."
return 1
fi
_prepare_ali_credentials || return 1
_getdeployconf DEPLOY_ALI_DCDN_DOMAIN
if [ "$DEPLOY_ALI_DCDN_DOMAIN" ]; then
_savedeployconf DEPLOY_ALI_DCDN_DOMAIN "$DEPLOY_ALI_DCDN_DOMAIN"
else
DEPLOY_ALI_DCDN_DOMAIN="$_cdomain"
fi
# read cert and key files and urlencode both
_cert=$(_url_encode upper-hex <"$_cfullchain")
_key=$(_url_encode upper-hex <"$_ckey")
_debug2 _cert "$_cert"
_debug2 _key "$_key"
## update domain ssl config
for domain in $DEPLOY_ALI_DCDN_DOMAIN; do
_set_dcdn_domain_ssl_certificate_query "$domain" "$_cert" "$_key"
if _ali_rest "Set DCDN domain SSL certificate for $domain" "" POST; then
_info "Domain $domain certificate has been deployed successfully"
fi
done
return 0
}
# domain pub pri
_set_dcdn_domain_ssl_certificate_query() {
endpoint=$Ali_DCDN_API
query=''
query=$query'AccessKeyId='$Ali_Key
query=$query'&Action=SetDcdnDomainSSLCertificate'
query=$query'&CertType=upload'
query=$query'&DomainName='$1
query=$query'&Format=json'
query=$query'&SSLPri='$3
query=$query'&SSLProtocol=on'
query=$query'&SSLPub='$2
query=$query'&SignatureMethod=HMAC-SHA1'
query=$query"&SignatureNonce=$(_ali_nonce)"
query=$query'&SignatureVersion=1.0'
query=$query'&Timestamp='$(_ali_timestamp)
query=$query'&Version=2018-01-15'
}
+394
View File
@@ -0,0 +1,394 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034,SC2154
#
# acme.sh deploy hook: BytePlus Application Load Balancer (ALB)
# https://github.com/acmesh-official/acme.sh/wiki/deployhooks
#
# Deploys SSL/TLS certificates issued by acme.sh to BytePlus ALB.
# Supports automatic renewal with zero-downtime certificate rotation
# for certificates that have already been uploaded and have a saved
# BytePlus CertificateId.
#
# ┌─────────────────────────────────────────────────────────────────────┐
# │ FIRST TIME (new domain) │
# │ 1. acme.sh --issue -d example.com -w /var/www/html/ │
# │ 2. Upload/import the certificate to BytePlus ALB manually │
# │ 3. Save/configure the existing CertificateId for this hook │
# │ 4. Manually assign cert to ALB Listener (one-time only) │
# │ │
# │ RENEWAL (fully automatic after CertificateId is configured) │
# │ acme.sh cron triggers renew → deploy hook runs automatically │
# │ → ReplaceCertificate (UpdateMode=new) — single API call │
# │ → All attached listeners updated, old cert auto-deleted │
# └─────────────────────────────────────────────────────────────────────┘
#
# Required environment variables:
# export BYTEPLUS_ACCESS_KEY="AKAPxxxxxxxxxx"
# export BYTEPLUS_SECRET_KEY="your-secret-key"
#
# Optional environment variables:
# export BYTEPLUS_REGION="ap-southeast-3" # default: ap-southeast-3
# export BYTEPLUS_HOST="alb.ap-southeast-3.byteplusapi.com" # custom API host
# export BYTEPLUS_PROJECT_NAME="live" # default: "default" project
# export BYTEPLUS_CERT_NAME="" # default: acme-{domain}-{YYYYMMDD-HHMM}
# export BYTEPLUS_CERT_DESCRIPTION="" # default: empty
# export BYTEPLUS_DELETE_OLD_CERT="true" # default: true — auto-delete after replace
#
# API notes:
# - All BytePlus ALB APIs use GET with query string parameters
# - Request signing: HMAC-SHA256 with signed headers host;x-date
# - PublicKey/PrivateKey are URL-encoded (RFC 3986) in query string
# - ReplaceCertificate with UpdateMode=new uploads + replaces in 1 call
#
# Dependencies: curl, openssl, awk (standard on most Linux)
#
# Docs:
# Signing — https://docs.byteplus.com/en/docs/byteplus-platform/reference-how-to-calculate-a-signature
# ALB API — https://docs.byteplus.com/en/docs/byteplus-alb
# ══════════════════════════════════════════════════════════════════════════════
# Constants
# ══════════════════════════════════════════════════════════════════════════════
# SHA-256 hash of empty string (used for GET requests with no body)
_BYTEPLUS_EMPTY_HASH="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
# ══════════════════════════════════════════════════════════════════════════════
# Main deploy function — called by acme.sh
# ══════════════════════════════════════════════════════════════════════════════
byteplus_alb_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
# ── 1. Load & validate credentials ──────────────────────────────────────────
# Preserve environment values before _getdeployconf (which may reset them)
_env_project_name="${BYTEPLUS_PROJECT_NAME:-}"
_env_delete_old="${BYTEPLUS_DELETE_OLD_CERT:-}"
_getdeployconf BYTEPLUS_ACCESS_KEY
_getdeployconf BYTEPLUS_SECRET_KEY
_getdeployconf BYTEPLUS_REGION
_getdeployconf BYTEPLUS_HOST
_getdeployconf BYTEPLUS_PROJECT_NAME
_getdeployconf BYTEPLUS_DELETE_OLD_CERT
_getdeployconf BYTEPLUS_CERT_NAME
# Restore from environment if _getdeployconf cleared them
if [ -z "$BYTEPLUS_PROJECT_NAME" ] && [ -n "$_env_project_name" ]; then
_debug "Restoring BYTEPLUS_PROJECT_NAME from environment"
BYTEPLUS_PROJECT_NAME="$_env_project_name"
fi
if [ -z "$BYTEPLUS_DELETE_OLD_CERT" ] && [ -n "$_env_delete_old" ]; then
BYTEPLUS_DELETE_OLD_CERT="$_env_delete_old"
fi
# Validate required credentials
if [ -z "$BYTEPLUS_ACCESS_KEY" ]; then
_err "BYTEPLUS_ACCESS_KEY is not set."
_err "Please run: export BYTEPLUS_ACCESS_KEY=\"your-access-key\""
return 1
fi
if [ -z "$BYTEPLUS_SECRET_KEY" ]; then
_err "BYTEPLUS_SECRET_KEY is not set."
_err "Please run: export BYTEPLUS_SECRET_KEY=\"your-secret-key\""
return 1
fi
# Save credentials for future runs
_savedeployconf BYTEPLUS_ACCESS_KEY "$BYTEPLUS_ACCESS_KEY"
_savedeployconf BYTEPLUS_SECRET_KEY "$BYTEPLUS_SECRET_KEY"
# Region (default: ap-southeast-3)
BYTEPLUS_REGION="${BYTEPLUS_REGION:-ap-southeast-3}"
_savedeployconf BYTEPLUS_REGION "$BYTEPLUS_REGION"
# Project name
if [ -n "$BYTEPLUS_PROJECT_NAME" ]; then
_savedeployconf BYTEPLUS_PROJECT_NAME "$BYTEPLUS_PROJECT_NAME"
_info "Using project: $BYTEPLUS_PROJECT_NAME"
else
_info "WARNING: BYTEPLUS_PROJECT_NAME is not set. Cert will go to 'default' project."
fi
# Delete old cert toggle (default: true)
BYTEPLUS_DELETE_OLD_CERT="${BYTEPLUS_DELETE_OLD_CERT:-true}"
_savedeployconf BYTEPLUS_DELETE_OLD_CERT "$BYTEPLUS_DELETE_OLD_CERT"
# API host — custom override or auto-build from region
if [ -n "$BYTEPLUS_HOST" ]; then
_BYTEPLUS_HOST="$BYTEPLUS_HOST"
_savedeployconf BYTEPLUS_HOST "$BYTEPLUS_HOST"
else
_BYTEPLUS_HOST="alb.${BYTEPLUS_REGION}.byteplusapi.com"
fi
_info "Using API host: $_BYTEPLUS_HOST"
_BYTEPLUS_SERVICE="alb"
# ── 2. Build certificate name ────────────────────────────────────────────────
_date_tag=$(date -u +%Y%m%d-%H%M)
# Replace wildcard * and dots for a valid cert name
_safe_domain=$(echo "$_cdomain" | sed 's/\*\.//g' | sed 's/\./-/g')
# Safe identifier version for deployconf keys: map all non [A-Za-z0-9_] to _
_conf_key=$(echo "$_cdomain" | sed 's/^\*\.//' | sed 's/[^A-Za-z0-9_]/_/g')
if [ -z "$BYTEPLUS_CERT_NAME" ]; then
BYTEPLUS_CERT_NAME="acme-${_safe_domain}-${_date_tag}"
fi
# Enforce BytePlus naming rules: start with letter, max 128 chars
BYTEPLUS_CERT_NAME=$(echo "$BYTEPLUS_CERT_NAME" | sed 's/[^A-Za-z0-9._-]/-/g')
case "$BYTEPLUS_CERT_NAME" in
[A-Za-z]*) ;;
*)
BYTEPLUS_CERT_NAME="a$BYTEPLUS_CERT_NAME"
;;
esac
BYTEPLUS_CERT_NAME=$(echo "$BYTEPLUS_CERT_NAME" | cut -c1-128)
_info "Certificate name: $BYTEPLUS_CERT_NAME"
# ── 3. Read cert and key ─────────────────────────────────────────────────────
# BytePlus requires NO blank lines between PEM blocks in the certificate chain
_public_key=$(sed '/^[[:space:]]*$/d' "$_cfullchain" | tr -d '\r')
_private_key=$(sed '/^[[:space:]]*$/d' "$_ckey" | tr -d '\r')
if [ -z "$_public_key" ] || [ -z "$_private_key" ]; then
_err "Failed to read certificate or key file."
return 1
fi
# ── 4. Deploy: first-time upload or renewal replace ─────────────────────────
_getdeployconf "BYTEPLUS_CERT_ID_${_conf_key}"
_old_cert_id=$(eval echo "\$BYTEPLUS_CERT_ID_${_conf_key}")
if [ -z "$_old_cert_id" ]; then
_byteplus_first_time_deploy
else
_byteplus_renewal_deploy
fi
# Check if deploy step set _new_cert_id
if [ -z "$_new_cert_id" ]; then
return 1
fi
# ── 5. Save new CertificateId for next renewal ───────────────────────────────
_savedeployconf "BYTEPLUS_CERT_ID_${_conf_key}" "$_new_cert_id"
_info "Saved CertificateId '$_new_cert_id' for domain '$_cdomain'."
return 0
}
# ══════════════════════════════════════════════════════════════════════════════
# Deploy: First time — UploadCertificate
# ══════════════════════════════════════════════════════════════════════════════
_byteplus_first_time_deploy() {
_info "No previous CertificateId found."
_err "Refusing to upload certificate material because this hook passes PublicKey/PrivateKey as request parameters."
_err "Uploading a private key in the request URL can leak it via logs, proxies, and process listings."
_err "Please upload the certificate to BytePlus manually for the initial deployment, set BYTEPLUS_CERT_ID_${_conf_key} to that CertificateId, and rerun."
_err "This hook stores CertificateId values per domain using deployconf, so the variable name must include the current domain-specific suffix."
_err "This hook must be updated to send PublicKey and PrivateKey in a POST body before automatic first-time upload can be enabled safely."
return 1
}
# ══════════════════════════════════════════════════════════════════════════════
# Deploy: Renewal — ReplaceCertificate (UpdateMode=new)
# ══════════════════════════════════════════════════════════════════════════════
_byteplus_renewal_deploy() {
_info "Replacing old certificate '$_old_cert_id' (UpdateMode=new)..."
_err "Refusing to replace certificate material because this hook passes PublicKey/PrivateKey as request parameters."
_err "Uploading a private key in the request URL can leak it via logs, proxies, and process listings."
_err "Please replace the certificate in BytePlus manually for renewal until this hook is updated to send PublicKey and PrivateKey in a POST body safely."
return 1
}
# ══════════════════════════════════════════════════════════════════════════════
# Delete old certificate (with retry)
# ══════════════════════════════════════════════════════════════════════════════
_byteplus_delete_old_cert() {
_del_cert_id="$1"
_info "Waiting 5s for cert status to settle..."
_sleep 5
_info "Deleting old certificate '$_del_cert_id'..."
_del_response=$(_byteplus_alb_api "DeleteCertificate" "CertificateId=${_del_cert_id}")
if echo "$_del_response" | grep -q '"Error"'; then
_info "Delete failed, retrying in 10s..."
_sleep 10
_del_response=$(_byteplus_alb_api "DeleteCertificate" "CertificateId=${_del_cert_id}")
if echo "$_del_response" | grep -q '"Error"'; then
_info "Warning: Could not delete old certificate '$_del_cert_id'."
_info "Error: $(_byteplus_extract_error "$_del_response")"
_info "Please remove it manually from BytePlus Console."
else
_info "Old certificate '$_del_cert_id' deleted (retry succeeded)."
fi
else
_info "Old certificate '$_del_cert_id' deleted."
fi
}
# ══════════════════════════════════════════════════════════════════════════════
# JSON response helpers
# ══════════════════════════════════════════════════════════════════════════════
# Extract CertificateId from API response JSON
_byteplus_extract_cert_id() {
echo "$1" | _egrep_o '"CertificateId"\s*:\s*"[^"]*"' | head -1 | _egrep_o '"[^"]*"$' | tr -d '"'
}
# Extract error message from API response JSON
_byteplus_extract_error() {
_code=$(echo "$1" | _egrep_o '"Code"\s*:\s*"[^"]*"' | head -1 | _egrep_o '"[^"]*"$' | tr -d '"')
_msg=$(echo "$1" | _egrep_o '"Message"\s*:\s*"[^"]*"' | head -1 | _egrep_o '"[^"]*"$' | tr -d '"')
if [ -n "$_code" ]; then
printf '%s — %s' "$_code" "$_msg"
else
printf '%s' "$1"
fi
}
# ══════════════════════════════════════════════════════════════════════════════
# BytePlus ALB API caller
# ══════════════════════════════════════════════════════════════════════════════
# Usage: _byteplus_alb_api ACTION [param1=val1] [param2=val2] ...
# All parameters sent via GET query string. Signing: HMAC-SHA256, host;x-date.
_byteplus_alb_api() {
_action="$1"
shift
# Build query string — all params go in URL
_query_params="Action=${_action}&Version=2020-04-01"
for _param in "$@"; do
_pname="${_param%%=*}"
_pval="${_param#*=}"
_query_params="${_query_params}&${_pname}=$(_byteplus_urlencode "$_pval")"
done
# Timestamps
_x_date=$(date -u +%Y%m%dT%H%M%SZ)
_date_only=$(date -u +%Y%m%d)
# Sort query params for canonical request
_sorted_query=$(echo "$_query_params" | tr '&' '\n' | LC_ALL=C sort | tr '\n' '&' | sed 's/&$//')
# Canonical headers — only host and x-date
_canonical_headers="host:${_BYTEPLUS_HOST}
x-date:${_x_date}
"
_signed_headers="host;x-date"
# Canonical request
_canonical_request="GET
/
${_sorted_query}
${_canonical_headers}
${_signed_headers}
${_BYTEPLUS_EMPTY_HASH}"
# Do not log _canonical_request because the query string may contain
# URL-encoded certificate or private key material.
# Hash of canonical request
# _digest is provided by acme.sh and works across OpenSSL versions.
_cr_hash=$(printf '%s' "$_canonical_request" | _digest sha256 hex)
# Credential scope
_credential_scope="${_date_only}/${BYTEPLUS_REGION}/${_BYTEPLUS_SERVICE}/request"
# String to sign
_string_to_sign="HMAC-SHA256
${_x_date}
${_credential_scope}
${_cr_hash}"
_debug2 _string_to_sign "$_string_to_sign"
# Signing key derivation (HMAC chain)
# _hmac <algo> <hex-key> reads data from stdin and returns a hex digest.
# acme.sh's _hmac abstracts away OpenSSL version differences, so this works
# on both modern (-mac HMAC -macopt hexkey:) and older (-hmac) OpenSSL builds.
#
# The first step seeds the chain from the raw secret key, so we convert it
# to hex first with _hex_dump (also an acme.sh built-in).
_secret_hex=$(printf '%s' "$BYTEPLUS_SECRET_KEY" | _hex_dump | tr -d ' \n')
_k_date=$(printf '%s' "$_date_only" | _hmac sha256 "$_secret_hex" hex)
_k_region=$(printf '%s' "$BYTEPLUS_REGION" | _hmac sha256 "$_k_date" hex)
_k_service=$(printf '%s' "$_BYTEPLUS_SERVICE" | _hmac sha256 "$_k_region" hex)
_k_signing=$(printf '%s' "request" | _hmac sha256 "$_k_service" hex)
# Final signature
_signature=$(printf '%s' "$_string_to_sign" | _hmac sha256 "$_k_signing" hex)
# Authorization header
_auth="HMAC-SHA256 Credential=${BYTEPLUS_ACCESS_KEY}/${_credential_scope}, SignedHeaders=${_signed_headers}, Signature=${_signature}"
_secure_debug2 _auth "$_auth"
# Send request parameters in the POST body instead of the URL query string.
# This avoids exposing sensitive or large values in debug-logged URLs and
# reduces the risk of exceeding URL length limits.
_url="https://${_BYTEPLUS_HOST}/"
_body="$_sorted_query"
_saved_H1="${_H1:-}"
_saved_H2="${_H2:-}"
_saved_H3="${_H3:-}"
_saved_H4="${_H4:-}"
_saved_H5="${_H5:-}"
_H1="Authorization: ${_auth}"
_H2="X-Date: ${_x_date}"
_H3="Host: ${_BYTEPLUS_HOST}"
_H4="Content-Type: application/x-www-form-urlencoded"
_H5=""
_response="$(_post "$_body" "$_url" "" "POST")"
_request_ret="$?"
_H1="$_saved_H1"
_H2="$_saved_H2"
_H3="$_saved_H3"
_H4="$_saved_H4"
_H5="$_saved_H5"
if [ "$_request_ret" != "0" ]; then
_err "byteplus_alb_api request failed for [$_action]"
return 1
fi
_debug2 "_byteplus_alb_api response [$_action]" "$_response"
printf '%s' "$_response"
}
# ══════════════════════════════════════════════════════════════════════════════
# URL encode (RFC 3986)
# ══════════════════════════════════════════════════════════════════════════════
_byteplus_urlencode() {
printf '%s' "$1" | _url_encode
}
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env sh
# Script to deploy certificate to CacheFly
# https://api.cachefly.com/api/2.5/docs#tag/Certificates/paths/~1certificates/post
# This deployment required following variables
# export CACHEFLY_TOKEN="Your CacheFly API Token"
# returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
CACHEFLY_API_BASE="https://api.cachefly.com/api/2.5"
cachefly_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
if [ -z "$CACHEFLY_TOKEN" ]; then
_err "CACHEFLY_TOKEN is not defined."
return 1
else
_savedomainconf CACHEFLY_TOKEN "$CACHEFLY_TOKEN"
fi
_info "Deploying certificate to CacheFly..."
## upload certificate
string_fullchain=$(sed 's/$/\\n/' "$_cfullchain" | tr -d '\n')
string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n')
_request_body="{\"certificate\":\"$string_fullchain\",\"certificateKey\":\"$string_key\"}"
_debug _request_body "$_request_body"
_debug CACHEFLY_TOKEN "$CACHEFLY_TOKEN"
export _H1="Authorization: Bearer $CACHEFLY_TOKEN"
_response=$(_post "$_request_body" "$CACHEFLY_API_BASE/certificates" "" "POST" "application/json")
if _contains "$_response" "message"; then
_err "Error in deploying $_cdomain certificate to CacheFly."
_err "$_response"
return 1
fi
_debug response "$_response"
_info "Domain $_cdomain certificate successfully deployed to CacheFly."
return 0
}
+168 -19
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\"")"
}
+86
View File
@@ -0,0 +1,86 @@
#!/usr/bin/env sh
# Script to deploy certificate to DirectAdmin
# https://docs.directadmin.com/directadmin/customizing-workflow/api-all-about.html#creating-a-login-key
# https://docs.directadmin.com/changelog/version-1.24.4.html#cmd-api-catch-all-pop-passwords-frontpage-protected-dirs-ssl-certs
# This deployment required following variables
# export DirectAdmin_SCHEME="https" # Optional, https or http, defaults to https
# export DirectAdmin_ENDPOINT="example.com:2222"
# export DirectAdmin_USERNAME="Your DirectAdmin Username"
# export DirectAdmin_KEY="Your DirectAdmin Login Key or Password"
# export DirectAdmin_MAIN_DOMAIN="Your DirectAdmin Main Domain, NOT Subdomain"
# returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
directadmin_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
if [ -z "$DirectAdmin_ENDPOINT" ]; then
_err "DirectAdmin_ENDPOINT is not defined."
return 1
else
_savedomainconf DirectAdmin_ENDPOINT "$DirectAdmin_ENDPOINT"
fi
if [ -z "$DirectAdmin_USERNAME" ]; then
_err "DirectAdmin_USERNAME is not defined."
return 1
else
_savedomainconf DirectAdmin_USERNAME "$DirectAdmin_USERNAME"
fi
if [ -z "$DirectAdmin_KEY" ]; then
_err "DirectAdmin_KEY is not defined."
return 1
else
_savedomainconf DirectAdmin_KEY "$DirectAdmin_KEY"
fi
if [ -z "$DirectAdmin_MAIN_DOMAIN" ]; then
_err "DirectAdmin_MAIN_DOMAIN is not defined."
return 1
else
_savedomainconf DirectAdmin_MAIN_DOMAIN "$DirectAdmin_MAIN_DOMAIN"
fi
# Optional SCHEME
_getdeployconf DirectAdmin_SCHEME
# set default values for DirectAdmin_SCHEME
[ -n "${DirectAdmin_SCHEME}" ] || DirectAdmin_SCHEME="https"
_info "Deploying certificate to DirectAdmin..."
# upload certificate
string_cfullchain=$(sed 's/$/\\n/' "$_cfullchain" | tr -d '\n')
string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n')
_request_body="{\"domain\":\"$DirectAdmin_MAIN_DOMAIN\",\"action\":\"save\",\"type\":\"paste\",\"certificate\":\"$string_key\n$string_cfullchain\n\"}"
_debug _request_body "$_request_body"
_debug DirectAdmin_ENDPOINT "$DirectAdmin_ENDPOINT"
_debug DirectAdmin_USERNAME "$DirectAdmin_USERNAME"
_debug DirectAdmin_KEY "$DirectAdmin_KEY"
_debug DirectAdmin_MAIN_DOMAIN "$DirectAdmin_MAIN_DOMAIN"
_response=$(_post "$_request_body" "$DirectAdmin_SCHEME://$DirectAdmin_USERNAME:$DirectAdmin_KEY@$DirectAdmin_ENDPOINT/CMD_API_SSL" "" "POST" "application/json")
if _contains "$_response" "error=1"; then
_err "Error in deploying $_cdomain certificate to DirectAdmin Domain $DirectAdmin_MAIN_DOMAIN."
_err "$_response"
return 1
fi
_info "$_response"
_info "Domain $_cdomain certificate successfully deployed to DirectAdmin Domain $DirectAdmin_MAIN_DOMAIN."
return 0
}
+32 -8
View File
@@ -18,6 +18,7 @@ docker_deploy() {
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_cpfx="$6"
_debug _cdomain "$_cdomain"
_getdeployconf DEPLOY_DOCKER_CONTAINER_LABEL
_debug2 DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL"
@@ -88,6 +89,12 @@ docker_deploy() {
_savedeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"
fi
_getdeployconf DEPLOY_DOCKER_CONTAINER_PFX_FILE
_debug2 DEPLOY_DOCKER_CONTAINER_PFX_FILE "$DEPLOY_DOCKER_CONTAINER_PFX_FILE"
if [ "$DEPLOY_DOCKER_CONTAINER_PFX_FILE" ]; then
_savedeployconf DEPLOY_DOCKER_CONTAINER_PFX_FILE "$DEPLOY_DOCKER_CONTAINER_PFX_FILE"
fi
_getdeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD
_debug2 DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then
@@ -125,6 +132,12 @@ docker_deploy() {
fi
fi
if [ "$DEPLOY_DOCKER_CONTAINER_PFX_FILE" ]; then
if ! _docker_cp "$_cid" "$_cpfx" "$DEPLOY_DOCKER_CONTAINER_PFX_FILE"; then
return 1
fi
fi
if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then
_info "Reloading: $DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
if ! _docker_exec "$_cid" "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"; then
@@ -273,16 +286,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
}
+86
View File
@@ -0,0 +1,86 @@
#!/usr/bin/env sh
# Here is a script to deploy cert to edgio using its API
# https://docs.edg.io/guides/v7/develop/rest_api/authentication
# https://docs.edg.io/rest_api/#tag/tls-certs/operation/postConfigV01TlsCerts
# This deployment required following variables
# export EDGIO_CLIENT_ID="Your Edgio Client ID"
# export EDGIO_CLIENT_SECRET="Your Edgio Client Secret"
# export EDGIO_ENVIRONMENT_ID="Your Edgio Environment ID"
# If have more than one Environment ID
# export EDGIO_ENVIRONMENT_ID="ENVIRONMENT_ID_1 ENVIRONMENT_ID_2"
# returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
edgio_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
if [ -z "$EDGIO_CLIENT_ID" ]; then
_err "EDGIO_CLIENT_ID is not defined."
return 1
else
_savedomainconf EDGIO_CLIENT_ID "$EDGIO_CLIENT_ID"
fi
if [ -z "$EDGIO_CLIENT_SECRET" ]; then
_err "EDGIO_CLIENT_SECRET is not defined."
return 1
else
_savedomainconf EDGIO_CLIENT_SECRET "$EDGIO_CLIENT_SECRET"
fi
if [ -z "$EDGIO_ENVIRONMENT_ID" ]; then
_err "EDGIO_ENVIRONMENT_ID is not defined."
return 1
else
_savedomainconf EDGIO_ENVIRONMENT_ID "$EDGIO_ENVIRONMENT_ID"
fi
_info "Getting access token"
_data="client_id=$EDGIO_CLIENT_ID&client_secret=$EDGIO_CLIENT_SECRET&grant_type=client_credentials&scope=app.config"
_debug Get_access_token_data "$_data"
_response=$(_post "$_data" "https://id.edgio.app/connect/token" "" "POST" "application/x-www-form-urlencoded")
_debug Get_access_token_response "$_response"
_access_token=$(echo "$_response" | _json_decode | _egrep_o '"access_token":"[^"]*' | cut -d : -f 2 | tr -d '"')
_debug _access_token "$_access_token"
if [ -z "$_access_token" ]; then
_err "Error in getting access token"
return 1
fi
_info "Uploading certificate"
string_ccert=$(sed 's/$/\\n/' "$_ccert" | tr -d '\n')
string_cca=$(sed 's/$/\\n/' "$_cca" | tr -d '\n')
string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n')
for ENVIRONMENT_ID in $EDGIO_ENVIRONMENT_ID; do
_data="{\"environment_id\":\"$ENVIRONMENT_ID\",\"primary_cert\":\"$string_ccert\",\"intermediate_cert\":\"$string_cca\",\"private_key\":\"$string_key\"}"
_debug Upload_certificate_data "$_data"
_H1="Authorization: Bearer $_access_token"
_response=$(_post "$_data" "https://edgioapis.com/config/v0.1/tls-certs" "" "POST" "application/json")
if _contains "$_response" "message"; then
_err "Error in deploying $_cdomain certificate to Edgio ENVIRONMENT_ID $ENVIRONMENT_ID."
_err "$_response"
return 1
fi
_debug Upload_certificate_response "$_response"
_info "Domain $_cdomain certificate successfully deployed to Edgio ENVIRONMENT_ID $ENVIRONMENT_ID."
done
return 0
}
-1
View File
@@ -109,6 +109,5 @@ exim4_deploy() {
fi
return 1
fi
return 0
}
+8 -7
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
+1 -1
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
+132 -9
View File
@@ -36,6 +36,19 @@
# Note: This functionality requires HAProxy was compiled against
# a version of OpenSSL that supports this.
#
# export DEPLOY_HAPROXY_HOT_UPDATE="yes"
# export DEPLOY_HAPROXY_STATS_SOCKET="UNIX:/run/haproxy/admin.sock"
#
# OPTIONAL: Deploy the certificate over the HAProxy stats socket without
# needing to reload HAProxy. Default is "no".
#
# Require the socat binary. DEPLOY_HAPROXY_STATS_SOCKET variable uses the socat
# address format.
#
# export DEPLOY_HAPROXY_MASTER_CLI="UNIX:/run/haproxy-master.sock"
#
# OPTIONAL: To use the master CLI with DEPLOY_HAPROXY_HOT_UPDATE="yes" instead
# of a stats socket, use this variable.
######## Public functions #####################
@@ -46,6 +59,7 @@ haproxy_deploy() {
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_cmdpfx=""
# Some defaults
DEPLOY_HAPROXY_PEM_PATH_DEFAULT="/etc/haproxy"
@@ -53,6 +67,8 @@ haproxy_deploy() {
DEPLOY_HAPROXY_BUNDLE_DEFAULT="no"
DEPLOY_HAPROXY_ISSUER_DEFAULT="no"
DEPLOY_HAPROXY_RELOAD_DEFAULT="true"
DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT="no"
DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT="UNIX:/run/haproxy/admin.sock"
_debug _cdomain "${_cdomain}"
_debug _ckey "${_ckey}"
@@ -86,6 +102,11 @@ haproxy_deploy() {
_savedomainconf Le_Deploy_haproxy_pem_name "${Le_Deploy_haproxy_pem_name}"
elif [ -z "${Le_Deploy_haproxy_pem_name}" ]; then
Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}"
# We better not have '*' as the first character
if [ "${Le_Deploy_haproxy_pem_name%%"${Le_Deploy_haproxy_pem_name#?}"}" = '*' ]; then
# removes the first characters and add a _ instead
Le_Deploy_haproxy_pem_name="_${Le_Deploy_haproxy_pem_name#?}"
fi
fi
# BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}"
@@ -118,6 +139,36 @@ haproxy_deploy() {
Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD_DEFAULT}"
fi
# HOT_UPDATE is optional. If not provided then assume "${DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT}"
_getdeployconf DEPLOY_HAPROXY_HOT_UPDATE
_debug2 DEPLOY_HAPROXY_HOT_UPDATE "${DEPLOY_HAPROXY_HOT_UPDATE}"
if [ -n "${DEPLOY_HAPROXY_HOT_UPDATE}" ]; then
Le_Deploy_haproxy_hot_update="${DEPLOY_HAPROXY_HOT_UPDATE}"
_savedomainconf Le_Deploy_haproxy_hot_update "${Le_Deploy_haproxy_hot_update}"
elif [ -z "${Le_Deploy_haproxy_hot_update}" ]; then
Le_Deploy_haproxy_hot_update="${DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT}"
fi
# STATS_SOCKET is optional. If not provided then assume "${DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT}"
_getdeployconf DEPLOY_HAPROXY_STATS_SOCKET
_debug2 DEPLOY_HAPROXY_STATS_SOCKET "${DEPLOY_HAPROXY_STATS_SOCKET}"
if [ -n "${DEPLOY_HAPROXY_STATS_SOCKET}" ]; then
Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_STATS_SOCKET}"
_savedomainconf Le_Deploy_haproxy_stats_socket "${Le_Deploy_haproxy_stats_socket}"
elif [ -z "${Le_Deploy_haproxy_stats_socket}" ]; then
Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT}"
fi
# MASTER_CLI is optional. No defaults are used. When the master CLI is used,
# all commands are sent with a prefix.
_getdeployconf DEPLOY_HAPROXY_MASTER_CLI
_debug2 DEPLOY_HAPROXY_MASTER_CLI "${DEPLOY_HAPROXY_MASTER_CLI}"
if [ -n "${DEPLOY_HAPROXY_MASTER_CLI}" ]; then
Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_MASTER_CLI}"
_savedomainconf Le_Deploy_haproxy_stats_socket "${Le_Deploy_haproxy_stats_socket}"
_cmdpfx="@1 " # command prefix used for master CLI only.
fi
# Set the suffix depending if we are creating a bundle or not
if [ "${Le_Deploy_haproxy_bundle}" = "yes" ]; then
_info "Bundle creation requested"
@@ -142,12 +193,13 @@ haproxy_deploy() {
_issuer="${_pem}.issuer"
_ocsp="${_pem}.ocsp"
_reload="${Le_Deploy_haproxy_reload}"
_statssock="${Le_Deploy_haproxy_stats_socket}"
_info "Deploying PEM file"
# Create a temporary PEM file
_temppem="$(_mktemp)"
_debug _temppem "${_temppem}"
cat "${_ckey}" "${_ccert}" "${_cca}" >"${_temppem}"
cat "${_ccert}" "${_cca}" "${_ckey}" | grep . >"${_temppem}"
_ret="$?"
# Check that we could create the temporary file
@@ -265,15 +317,86 @@ haproxy_deploy() {
fi
fi
# Reload HAProxy
_debug _reload "${_reload}"
eval "${_reload}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_err "Error code ${_ret} during reload"
return ${_ret}
if [ "${Le_Deploy_haproxy_hot_update}" = "yes" ]; then
# set the socket name for messages
if [ -n "${_cmdpfx}" ]; then
_socketname="master CLI"
else
_socketname="stats socket"
fi
# Update certificate over HAProxy stats socket or master CLI.
if _exists socat; then
# look for the certificate on the stats socket, to chose between updating or creating one
_socat_cert_cmd="echo '${_cmdpfx}show ssl cert' | socat '${_statssock}' - | grep -q '^${_pem}$'"
_debug _socat_cert_cmd "${_socat_cert_cmd}"
eval "${_socat_cert_cmd}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_newcert="1"
_info "Creating new certificate '${_pem}' over HAProxy ${_socketname}."
# certificate wasn't found, it's a new one. We should check if the crt-list exists and creates/inserts the certificate.
_socat_crtlist_show_cmd="echo '${_cmdpfx}show ssl crt-list' | socat '${_statssock}' - | grep -q '^${Le_Deploy_haproxy_pem_path}$'"
_debug _socat_crtlist_show_cmd "${_socat_crtlist_show_cmd}"
eval "${_socat_crtlist_show_cmd}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_err "Couldn't find '${Le_Deploy_haproxy_pem_path}' in haproxy 'show ssl crt-list'"
return "${_ret}"
fi
# create a new certificate
_socat_new_cmd="echo '${_cmdpfx}new ssl cert ${_pem}' | socat '${_statssock}' - | grep -q 'New empty'"
_debug _socat_new_cmd "${_socat_new_cmd}"
eval "${_socat_new_cmd}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_err "Couldn't create '${_pem}' in haproxy"
return "${_ret}"
fi
else
_info "Update existing certificate '${_pem}' over HAProxy ${_socketname}."
fi
_socat_cert_set_cmd="echo -e '${_cmdpfx}set ssl cert ${_pem} <<\n$(cat "${_pem}")\n' | socat '${_statssock}' - | grep -q 'Transaction created'"
_secure_debug _socat_cert_set_cmd "${_socat_cert_set_cmd}"
eval "${_socat_cert_set_cmd}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_err "Can't update '${_pem}' in haproxy"
return "${_ret}"
fi
_socat_cert_commit_cmd="echo '${_cmdpfx}commit ssl cert ${_pem}' | socat '${_statssock}' - | grep -q '^Success!$'"
_debug _socat_cert_commit_cmd "${_socat_cert_commit_cmd}"
eval "${_socat_cert_commit_cmd}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_err "Can't commit '${_pem}' in haproxy"
return ${_ret}
fi
if [ "${_newcert}" = "1" ]; then
# if this is a new certificate, it needs to be inserted into the crt-list`
_socat_cert_add_cmd="echo '${_cmdpfx}add ssl crt-list ${Le_Deploy_haproxy_pem_path} ${_pem}' | socat '${_statssock}' - | grep -q 'Success!'"
_debug _socat_cert_add_cmd "${_socat_cert_add_cmd}"
eval "${_socat_cert_add_cmd}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_err "Can't update '${_pem}' in haproxy"
return "${_ret}"
fi
fi
else
_err "'socat' is not available, couldn't update over ${_socketname}"
fi
else
_info "Reload successful"
# Reload HAProxy
_debug _reload "${_reload}"
eval "${_reload}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_err "Error code ${_ret} during reload"
return ${_ret}
else
_info "Reload successful"
fi
fi
return 0
+99
View File
@@ -0,0 +1,99 @@
#!/usr/bin/env sh
#Here is a script to deploy cert to a Kemp Loadmaster.
#returns 0 means success, otherwise error.
#DEPLOY_KEMP_TOKEN="token"
#DEPLOY_KEMP_URL="https://kemplm.example.com"
######## Public functions #####################
#domain keyfile certfile cafile fullchain
kemplm_deploy() {
_domain="$1"
_key_file="$2"
_cert_file="$3"
_ca_file="$4"
_fullchain_file="$5"
_debug _domain "$_domain"
_debug _key_file "$_key_file"
_debug _cert_file "$_cert_file"
_debug _ca_file "$_ca_file"
_debug _fullchain_file "$_fullchain_file"
if ! _exists jq; then
_err "jq not found"
return 1
fi
# Rename wildcard certs, kemp accepts only alphanumeric names so we delete '*.' from filename
_kemp_domain=$(echo "${_domain}" | sed 's/\*\.//')
_debug _kemp_domain "$_kemp_domain"
# Read config from saved values or env
_getdeployconf DEPLOY_KEMP_TOKEN
_getdeployconf DEPLOY_KEMP_URL
_debug DEPLOY_KEMP_URL "$DEPLOY_KEMP_URL"
_secure_debug DEPLOY_KEMP_TOKEN "$DEPLOY_KEMP_TOKEN"
if [ -z "$DEPLOY_KEMP_TOKEN" ]; then
_err "Kemp Loadmaster token is not found, please define DEPLOY_KEMP_TOKEN."
return 1
fi
if [ -z "$DEPLOY_KEMP_URL" ]; then
_err "Kemp Loadmaster URL is not found, please define DEPLOY_KEMP_URL."
return 1
fi
# Save current values
_savedeployconf DEPLOY_KEMP_TOKEN "$DEPLOY_KEMP_TOKEN"
_savedeployconf DEPLOY_KEMP_URL "$DEPLOY_KEMP_URL"
# Check if certificate is already installed
_info "Check if certificate is already present"
_list_request="{\"cmd\": \"listcert\", \"apikey\": \"${DEPLOY_KEMP_TOKEN}\"}"
_debug3 _list_request "${_list_request}"
_kemp_cert_count=$(HTTPS_INSECURE=1 _post "${_list_request}" "${DEPLOY_KEMP_URL}/accessv2" | jq -r '.cert[] | .name' | grep -c "^${_kemp_domain}$")
_debug2 _kemp_cert_count "${_kemp_cert_count}"
_kemp_replace_cert=1
if [ "${_kemp_cert_count}" -eq 0 ]; then
_kemp_replace_cert=0
_info "Certificate does not exist on Kemp Loadmaster"
else
_info "Certificate already exists on Kemp Loadmaster"
fi
_debug _kemp_replace_cert "${_kemp_replace_cert}"
# Upload new certificate to Kemp Loadmaster
_kemp_upload_cert=$(_mktemp)
cat "${_fullchain_file}" "${_key_file}" | base64 | tr -d '\n' >"${_kemp_upload_cert}"
_info "Uploading certificate to Kemp Loadmaster"
_add_data=$(cat "${_kemp_upload_cert}")
_add_request="{\"cmd\": \"addcert\", \"apikey\": \"${DEPLOY_KEMP_TOKEN}\", \"replace\": ${_kemp_replace_cert}, \"cert\": \"${_kemp_domain}\", \"data\": \"${_add_data}\"}"
_debug3 _add_request "${_add_request}"
_kemp_post_result=$(HTTPS_INSECURE=1 _post "${_add_request}" "${DEPLOY_KEMP_URL}/accessv2")
_retval=$?
_debug2 _kemp_post_result "${_kemp_post_result}"
if [ "${_retval}" -eq 0 ]; then
_kemp_post_status=$(echo "${_kemp_post_result}" | jq -r '.status')
_kemp_post_message=$(echo "${_kemp_post_result}" | jq -r '.message')
if [ "${_kemp_post_status}" = "ok" ]; then
_info "Upload successful"
else
_err "Upload failed: ${_kemp_post_message}"
_retval=1
fi
else
_err "Upload failed"
_retval=1
fi
rm "${_kemp_upload_cert}"
return $_retval
}
+131
View File
@@ -0,0 +1,131 @@
#!/usr/bin/env sh
# Script to deploy certificate to KeyHelp
# This deployment required following variables
# export DEPLOY_KEYHELP_BASEURL="https://keyhelp.example.com"
# export DEPLOY_KEYHELP_USERNAME="Your KeyHelp Username"
# export DEPLOY_KEYHELP_PASSWORD="Your KeyHelp Password"
# export DEPLOY_KEYHELP_DOMAIN_ID="Depoly certificate to this Domain ID"
# Open the 'Edit domain' page, and you will see id=xxx at the end of the URL. This is the Domain ID.
# https://DEPLOY_KEYHELP_BASEURL/index.php?page=domains&action=edit&id=xxx
# If have more than one domain name
# export DEPLOY_KEYHELP_DOMAIN_ID="111 222 333"
keyhelp_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
if [ -z "$DEPLOY_KEYHELP_BASEURL" ]; then
_err "DEPLOY_KEYHELP_BASEURL is not defined."
return 1
else
_savedomainconf DEPLOY_KEYHELP_BASEURL "$DEPLOY_KEYHELP_BASEURL"
fi
if [ -z "$DEPLOY_KEYHELP_USERNAME" ]; then
_err "DEPLOY_KEYHELP_USERNAME is not defined."
return 1
else
_savedomainconf DEPLOY_KEYHELP_USERNAME "$DEPLOY_KEYHELP_USERNAME"
fi
if [ -z "$DEPLOY_KEYHELP_PASSWORD" ]; then
_err "DEPLOY_KEYHELP_PASSWORD is not defined."
return 1
else
_savedomainconf DEPLOY_KEYHELP_PASSWORD "$DEPLOY_KEYHELP_PASSWORD"
fi
if [ -z "$DEPLOY_KEYHELP_DOMAIN_ID" ]; then
_err "DEPLOY_KEYHELP_DOMAIN_ID is not defined."
return 1
else
_savedomainconf DEPLOY_KEYHELP_DOMAIN_ID "$DEPLOY_KEYHELP_DOMAIN_ID"
fi
# Optional DEPLOY_KEYHELP_ENFORCE_HTTPS
_getdeployconf DEPLOY_KEYHELP_ENFORCE_HTTPS
# set default values for DEPLOY_KEYHELP_ENFORCE_HTTPS
[ -n "${DEPLOY_KEYHELP_ENFORCE_HTTPS}" ] || DEPLOY_KEYHELP_ENFORCE_HTTPS="1"
_info "Logging in to keyhelp panel"
username_encoded="$(printf "%s" "${DEPLOY_KEYHELP_USERNAME}" | _url_encode)"
password_encoded="$(printf "%s" "${DEPLOY_KEYHELP_PASSWORD}" | _url_encode)"
_H1="Content-Type: application/x-www-form-urlencoded"
_response=$(_get "$DEPLOY_KEYHELP_BASEURL/index.php?submit=1&username=$username_encoded&password=$password_encoded" "TRUE")
_cookie="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2)"
# If cookies is not empty then logon successful
if [ -z "$_cookie" ]; then
_err "Fail to get cookie."
return 1
fi
_debug "cookie" "$_cookie"
_info "Uploading certificate"
_date=$(date +"%Y%m%d")
encoded_key="$(_url_encode <"$_ckey")"
encoded_ccert="$(_url_encode <"$_ccert")"
encoded_cca="$(_url_encode <"$_cca")"
certificate_name="$_cdomain-$_date"
_request_body="submit=1&certificate_name=$certificate_name&add_type=upload&text_private_key=$encoded_key&text_certificate=$encoded_ccert&text_ca_certificate=$encoded_cca"
_H1="Cookie: $_cookie"
_response=$(_post "$_request_body" "$DEPLOY_KEYHELP_BASEURL/index.php?page=ssl_certificates&action=add" "" "POST")
_message=$(echo "$_response" | grep -A 2 'message-body' | sed -n '/<div class="message-body ">/,/<\/div>/{//!p;}' | sed 's/<[^>]*>//g' | sed 's/^ *//;s/ *$//')
_info "_message" "$_message"
if [ -z "$_message" ]; then
_err "Fail to upload certificate."
return 1
fi
for DOMAIN_ID in $DEPLOY_KEYHELP_DOMAIN_ID; do
_info "Apply certificate to domain id $DOMAIN_ID"
_response=$(_get "$DEPLOY_KEYHELP_BASEURL/index.php?page=domains&action=edit&id=$DOMAIN_ID")
cert_value=$(echo "$_response" | grep "$certificate_name" | sed -n 's/.*value="\([^"]*\).*/\1/p')
target_type=$(echo "$_response" | grep 'target_type' | grep 'checked' | sed -n 's/.*value="\([^"]*\).*/\1/p')
if [ "$target_type" = "directory" ]; then
path=$(echo "$_response" | awk '/name="path"/{getline; print}' | sed -n 's/.*value="\([^"]*\).*/\1/p')
fi
echo "$_response" | grep "is_prefer_https" | grep "checked" >/dev/null
if [ $? -eq 0 ]; then
is_prefer_https=1
else
is_prefer_https=0
fi
echo "$_response" | grep "hsts_enabled" | grep "checked" >/dev/null
if [ $? -eq 0 ]; then
hsts_enabled=1
else
hsts_enabled=0
fi
_debug "cert_value" "$cert_value"
if [ -z "$cert_value" ]; then
_err "Fail to get certificate id."
return 1
fi
_request_body="submit=1&id=$DOMAIN_ID&target_type=$target_type&path=$path&is_prefer_https=$is_prefer_https&hsts_enabled=$hsts_enabled&certificate_type=custom&certificate_id=$cert_value&enforce_https=$DEPLOY_KEYHELP_ENFORCE_HTTPS"
_response=$(_post "$_request_body" "$DEPLOY_KEYHELP_BASEURL/index.php?page=domains&action=edit" "" "POST")
_message=$(echo "$_response" | grep -A 2 'message-body' | sed -n '/<div class="message-body ">/,/<\/div>/{//!p;}' | sed 's/<[^>]*>//g' | sed 's/^ *//;s/ *$//')
_info "_message" "$_message"
if [ -z "$_message" ]; then
_err "Fail to apply certificate."
return 1
fi
done
_info "Domain $_cdomain certificate successfully deployed to KeyHelp Domain ID $DEPLOY_KEYHELP_DOMAIN_ID."
return 0
}
+86
View File
@@ -0,0 +1,86 @@
#!/usr/bin/env sh
keyhelp_api_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
# Read config from saved values or env
_getdeployconf DEPLOY_KEYHELP_HOST
_getdeployconf DEPLOY_KEYHELP_API_KEY
_debug DEPLOY_KEYHELP_HOST "$DEPLOY_KEYHELP_HOST"
_secure_debug DEPLOY_KEYHELP_API_KEY "$DEPLOY_KEYHELP_API_KEY"
if [ -z "$DEPLOY_KEYHELP_HOST" ]; then
_err "KeyHelp host not found, please define DEPLOY_KEYHELP_HOST."
return 1
fi
if [ -z "$DEPLOY_KEYHELP_API_KEY" ]; then
_err "KeyHelp api key not found, please define DEPLOY_KEYHELP_API_KEY."
return 1
fi
# Save current values
_savedeployconf DEPLOY_KEYHELP_HOST "$DEPLOY_KEYHELP_HOST"
_savedeployconf DEPLOY_KEYHELP_API_KEY "$DEPLOY_KEYHELP_API_KEY"
_request_key="$(tr '\n' ':' <"$_ckey" | sed 's/:/\\n/g')"
_request_cert="$(tr '\n' ':' <"$_ccert" | sed 's/:/\\n/g')"
_request_ca="$(tr '\n' ':' <"$_cca" | sed 's/:/\\n/g')"
_request_body="{
\"name\": \"$_cdomain\",
\"components\": {
\"private_key\": \"$_request_key\",
\"certificate\": \"$_request_cert\",
\"ca_certificate\": \"$_request_ca\"
}
}"
_hosts="$(echo "$DEPLOY_KEYHELP_HOST" | tr "," " ")"
_keys="$(echo "$DEPLOY_KEYHELP_API_KEY" | tr "," " ")"
_i=1
for _host in $_hosts; do
_key="$(_getfield "$_keys" "$_i" " ")"
_i="$(_math "$_i" + 1)"
export _H1="X-API-Key: $_key"
_put_url="$_host/api/v2/certificates/name/$_cdomain"
if _post "$_request_body" "$_put_url" "" "PUT" "application/json" >/dev/null; then
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
else
_err "Cannot make PUT request to $_put_url"
return 1
fi
if [ "$_code" = "404" ]; then
_info "$_cdomain not found, creating new entry at $_host"
_post_url="$_host/api/v2/certificates"
if _post "$_request_body" "$_post_url" "" "POST" "application/json" >/dev/null; then
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
else
_err "Cannot make POST request to $_post_url"
return 1
fi
fi
if _startswith "$_code" "2"; then
_info "$_cdomain set at $_host"
else
_err "HTTP status code is $_code"
return 1
fi
done
return 0
}
+157
View File
@@ -0,0 +1,157 @@
#!/usr/bin/env sh
# Deploy-hook to very simply copy files to set directories and then
# execute whatever reloadcmd the admin needs afterwards. This can be
# useful for configurations where the "multideploy" hook (in development)
# is used or when an admin wants ACME.SH to renew certs but needs to
# manually configure deployment via an external script
# (e.g. The deploy-freenas script for TrueNAS Core/Scale
# https://github.com/danb35/deploy-freenas/ )
#
# If the same file is configured for the certificate key
# and the certificate and/or full chain, a combined PEM file will
# be output instead.
#
# Environment variables to be utilized are as follows:
#
# DEPLOY_LOCALCOPY_CERTKEY - /path/to/target/cert.key
# DEPLOY_LOCALCOPY_CERTIFICATE - /path/to/target/cert.cer
# DEPLOY_LOCALCOPY_FULLCHAIN - /path/to/target/fullchain.cer
# DEPLOY_LOCALCOPY_CA - /path/to/target/ca.cer
# DEPLOY_LOCALCOPY_PFX - /path/to/target/cert.pfx
# DEPLOY_LOCALCOPY_RELOADCMD - "echo 'this is my cmd'"
######## Public functions #####################
#domain keyfile certfile cafile fullchain
localcopy_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_cpfx="$6"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
_debug _cpfx "$_cpfx"
_getdeployconf DEPLOY_LOCALCOPY_CERTIFICATE
_getdeployconf DEPLOY_LOCALCOPY_CERTKEY
_getdeployconf DEPLOY_LOCALCOPY_FULLCHAIN
_getdeployconf DEPLOY_LOCALCOPY_CA
_getdeployconf DEPLOY_LOCALCOPY_RELOADCMD
_getdeployconf DEPLOY_LOCALCOPY_PFX
_combined_target=""
_combined_srccert=""
# Create PEM file
if [ "$DEPLOY_LOCALCOPY_CERTKEY" ] &&
{ [ "$DEPLOY_LOCALCOPY_CERTKEY" = "$DEPLOY_LOCALCOPY_FULLCHAIN" ] ||
[ "$DEPLOY_LOCALCOPY_CERTKEY" = "$DEPLOY_LOCALCOPY_CERTIFICATE" ]; }; then
_combined_target="$DEPLOY_LOCALCOPY_CERTKEY"
_savedeployconf DEPLOY_LOCALCOPY_CERTKEY "$DEPLOY_LOCALCOPY_CERTKEY"
if [ "$DEPLOY_LOCALCOPY_CERTKEY" = "$DEPLOY_LOCALCOPY_CERTIFICATE" ]; then
_combined_srccert="$_ccert"
_savedeployconf DEPLOY_LOCALCOPY_CERTIFICATE "$DEPLOY_LOCALCOPY_CERTIFICATE"
DEPLOY_LOCALCOPY_CERTIFICATE=""
fi
if [ "$DEPLOY_LOCALCOPY_CERTKEY" = "$DEPLOY_LOCALCOPY_FULLCHAIN" ]; then
_combined_srccert="$_cfullchain"
_savedeployconf DEPLOY_LOCALCOPY_FULLCHAIN "$DEPLOY_LOCALCOPY_FULLCHAIN"
DEPLOY_LOCALCOPY_FULLCHAIN=""
fi
DEPLOY_LOCALCOPY_CERTKEY=""
_info "Creating combined PEM"
_debug "Creating combined PEM at $_combined_target"
if ! [ -f "$_combined_target" ]; then
touch "$_combined_target" || return 1
chmod 600 "$_combined_target"
fi
if ! cat "$_combined_srccert" "$_ckey" >"$_combined_target"; then
_err "Failed to create PEM file"
return 1
fi
fi
if [ "$DEPLOY_LOCALCOPY_CERTIFICATE" ]; then
_info "Copying certificate"
_debug "Copying $_ccert to $DEPLOY_LOCALCOPY_CERTIFICATE"
if ! cat "$_ccert" >"$DEPLOY_LOCALCOPY_CERTIFICATE"; then
_err "Failed to copy certificate, aborting."
return 1
fi
_savedeployconf DEPLOY_LOCALCOPY_CERTIFICATE "$DEPLOY_LOCALCOPY_CERTIFICATE"
fi
if [ "$DEPLOY_LOCALCOPY_CERTKEY" ]; then
_info "Copying certificate key"
_debug "Copying $_ckey to $DEPLOY_LOCALCOPY_CERTKEY"
if ! [ -f "$DEPLOY_LOCALCOPY_CERTKEY" ]; then
touch "$DEPLOY_LOCALCOPY_CERTKEY" || return 1
chmod 600 "$DEPLOY_LOCALCOPY_CERTKEY"
fi
if ! cat "$_ckey" >"$DEPLOY_LOCALCOPY_CERTKEY"; then
_err "Failed to copy certificate key, aborting."
return 1
fi
_savedeployconf DEPLOY_LOCALCOPY_CERTKEY "$DEPLOY_LOCALCOPY_CERTKEY"
fi
if [ "$DEPLOY_LOCALCOPY_FULLCHAIN" ]; then
_info "Copying fullchain"
_debug "Copying $_cfullchain to $DEPLOY_LOCALCOPY_FULLCHAIN"
if ! cat "$_cfullchain" >"$DEPLOY_LOCALCOPY_FULLCHAIN"; then
_err "Failed to copy fullchain, aborting."
return 1
fi
_savedeployconf DEPLOY_LOCALCOPY_FULLCHAIN "$DEPLOY_LOCALCOPY_FULLCHAIN"
fi
if [ "$DEPLOY_LOCALCOPY_CA" ]; then
_info "Copying CA"
_debug "Copying $_cca to $DEPLOY_LOCALCOPY_CA"
if ! cat "$_cca" >"$DEPLOY_LOCALCOPY_CA"; then
_err "Failed to copy CA, aborting."
return 1
fi
_savedeployconf DEPLOY_LOCALCOPY_CA "$DEPLOY_LOCALCOPY_CA"
fi
if [ "$DEPLOY_LOCALCOPY_PFX" ]; then
_info "Copying PFX"
_debug "Copying $_cpfx to $DEPLOY_LOCALCOPY_PFX"
if ! [ -f "$DEPLOY_LOCALCOPY_PFX" ]; then
touch "$DEPLOY_LOCALCOPY_PFX" || return 1
chmod 600 "$DEPLOY_LOCALCOPY_PFX"
fi
if ! cat "$_cpfx" >"$DEPLOY_LOCALCOPY_PFX"; then
_err "Failed to copy PFX, aborting."
return 1
fi
_savedeployconf DEPLOY_LOCALCOPY_PFX "$DEPLOY_LOCALCOPY_PFX"
fi
_reload=$DEPLOY_LOCALCOPY_RELOADCMD
_debug "Running reloadcmd $_reload"
if [ -z "$_reload" ]; then
_info "Reloadcmd not provided, skipping."
else
_info "Reloading"
if eval "$_reload"; then
_info "Reload successful."
_savedeployconf DEPLOY_LOCALCOPY_RELOADCMD "$DEPLOY_LOCALCOPY_RELOADCMD" "base64"
else
_err "Reload failed."
return 1
fi
fi
_info "$(__green "'localcopy' deploy success")"
return 0
}
+3 -13
View File
@@ -44,30 +44,20 @@ mailcow_deploy() {
return 1
fi
# ECC or RSA
length=$(_readdomainconf Le_Keylength)
if _isEccKey "$length"; 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 --quiet --filter name=nginx-mailcow --filter 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"
+276
View File
@@ -0,0 +1,276 @@
#!/usr/bin/env sh
################################################################################
# ACME.sh 3rd party deploy plugin for multiple (same) services
################################################################################
# Authors: tomo2403 (creator), https://github.com/tomo2403
# Updated: 2025-03-01
# Issues: https://github.com/acmesh-official/acme.sh/issues and mention @tomo2403
################################################################################
# Usage (shown values are the examples):
# 1. Set optional environment variables
# - export MULTIDEPLOY_FILENAME="multideploy.yaml" - "multideploy.yml" will be automatically used if not set"
#
# 2. Run command:
# acme.sh --deploy --deploy-hook multideploy -d example.com
################################################################################
# Dependencies:
# - yq
################################################################################
# Return value:
# 0 means success, otherwise error.
################################################################################
MULTIDEPLOY_VERSION="1.0"
# Description: This function handles the deployment of certificates to multiple services.
# It processes the provided certificate files and deploys them according to the
# configuration specified in the multideploy file.
#
# Parameters:
# _cdomain - The domain name for which the certificate is issued.
# _ckey - The private key file for the certificate.
# _ccert - The certificate file.
# _cca - The CA (Certificate Authority) file.
# _cfullchain - The full chain certificate file.
# _cpfx - The PFX (Personal Information Exchange) file.
multideploy_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_cpfx="$6"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
_debug _cpfx "$_cpfx"
MULTIDEPLOY_FILENAME="${MULTIDEPLOY_FILENAME:-$(_getdeployconf MULTIDEPLOY_FILENAME)}"
if [ -z "$MULTIDEPLOY_FILENAME" ]; then
MULTIDEPLOY_FILENAME="multideploy.yml"
_info "MULTIDEPLOY_FILENAME is not set, so I will use 'multideploy.yml'."
else
_savedeployconf "MULTIDEPLOY_FILENAME" "$MULTIDEPLOY_FILENAME"
_debug2 "MULTIDEPLOY_FILENAME" "$MULTIDEPLOY_FILENAME"
fi
if ! file=$(_preprocess_deployfile "$MULTIDEPLOY_FILENAME"); then
_err "Failed to preprocess deploy file."
return 1
fi
_debug3 "File" "$file"
# Deploy to services
_deploy_services "$file"
_exitCode="$?"
return "$_exitCode"
}
# Description:
# This function preprocesses the deploy file by checking if 'yq' is installed,
# verifying the existence of the deploy file, and ensuring only one deploy file is present.
# Arguments:
# $@ - Posible deploy file names.
# Usage:
# _preprocess_deployfile "<deploy_file1>" "<deploy_file2>?"
_preprocess_deployfile() {
# Check if yq is installed
if ! command -v yq >/dev/null 2>&1; then
_err "yq is not installed! Please install yq and try again."
return 1
fi
_debug3 "yq is installed."
# Check if deploy file exists
for file in "$@"; do
_debug3 "Checking file" "$DOMAIN_PATH/$file"
if [ -f "$DOMAIN_PATH/$file" ]; then
_debug3 "File found"
if [ -n "$found_file" ]; then
_err "Multiple deploy files found. Please keep only one deploy file."
return 1
fi
found_file="$file"
else
_debug3 "File not found"
fi
done
if [ -z "$found_file" ]; then
_err "Deploy file not found. Go to https://github.com/acmesh-official/acme.sh/wiki/deployhooks#36-deploying-to-multiple-services-with-the-same-hooks to see how to create one."
return 1
fi
if ! _check_deployfile "$DOMAIN_PATH/$found_file"; then
_err "Deploy file is not valid: $DOMAIN_PATH/$found_file"
return 1
fi
echo "$DOMAIN_PATH/$found_file"
}
# Description:
# This function checks the deploy file for version compatibility and the existence of the specified configuration and services.
# Arguments:
# $1 - The path to the deploy configuration file.
# $2 - The name of the deploy configuration to use.
# Usage:
# _check_deployfile "<deploy_file_path>"
_check_deployfile() {
_deploy_file="$1"
_debug2 "check: Deploy file" "$_deploy_file"
# Check version
_deploy_file_version=$(yq -r '.version' "$_deploy_file")
if [ "$MULTIDEPLOY_VERSION" != "$_deploy_file_version" ]; then
_err "As of $PROJECT_NAME $VER, the deploy file needs version $MULTIDEPLOY_VERSION! Your current deploy file is of version $_deploy_file_version."
return 1
fi
_debug2 "check: Deploy file version is compatible: $_deploy_file_version"
# Extract all services from config
_services=$(yq -r '.services[].name' "$_deploy_file")
if [ -z "$_services" ]; then
_err "Config does not have any services to deploy to."
return 1
fi
_debug2 "check: Config has services."
echo "$_services" | while read -r _service; do
_debug3 " - $_service"
done
# Check if extracted services exist in services list
echo "$_services" | while read -r _service; do
_debug2 "check: Checking service: $_service"
# Check if service exists
_service_config=$(yq -r ".services[] | select(.name == \"$_service\")" "$_deploy_file")
if [ -z "$_service_config" ] || [ "$_service_config" = "null" ]; then
_err "Service '$_service' not found."
return 1
fi
_service_hook=$(echo "$_service_config" | yq -r ".hook" -)
if [ -z "$_service_hook" ] || [ "$_service_hook" = "null" ]; then
_err "Service '$_service' does not have a hook."
return 1
fi
_service_environment=$(echo "$_service_config" | yq -r ".environment" -)
if [ -z "$_service_environment" ] || [ "$_service_environment" = "null" ]; then
_err "Service '$_service' does not have an environment."
return 1
fi
done
}
# Description: This function takes a list of environment variables in YAML format,
# parses them, and exports each key-value pair as environment variables.
# Arguments:
# $1 - A string containing the list of environment variables in YAML format.
# Usage:
# _export_envs "$env_list"
_export_envs() {
_env_list="$1"
_secure_debug3 "Exporting envs" "$_env_list"
echo "$_env_list" | yq -r 'to_entries | .[] | .key + "=" + .value' | while IFS='=' read -r _key _value; do
# Using eval to expand nested variables in the configuration file
_value=$(eval 'echo "'"$_value"'"')
_savedeployconf "$_key" "$_value"
_secure_debug3 "Saved $_key" "$_value"
done
}
# Description:
# This function takes a YAML formatted string of environment variables, parses it,
# and clears each environment variable. It logs the process of clearing each variable.
#
# Note: Environment variables for a hook may be optional and differ between
# services using the same hook.
# If one service sets optional environment variables and another does not, the
# variables may persist and affect subsequent deployments.
# Clearing these variables after each service ensures that only the
# environment variables explicitly specified for each service in the deploy
# file are used.
# Arguments:
# $1 - A YAML formatted string containing environment variable key-value pairs.
# Usage:
# _clear_envs "<yaml_string>"
_clear_envs() {
_env_list="$1"
_secure_debug3 "Clearing envs" "$_env_list"
env_pairs=$(echo "$_env_list" | yq -r 'to_entries | .[] | .key + "=" + .value')
echo "$env_pairs" | while IFS='=' read -r _key _value; do
_debug3 "Deleting key" "$_key"
_cleardomainconf "SAVED_$_key"
unset -v "$_key"
done
}
# Description:
# This function deploys services listed in the deploy configuration file.
# Arguments:
# $1 - The path to the deploy configuration file.
# $2 - The list of services to deploy.
# Usage:
# _deploy_services "<deploy_file_path>" "<services_list>"
_deploy_services() {
_deploy_file="$1"
_debug3 "Deploy file" "$_deploy_file"
_tempfile=$(mktemp)
trap 'rm -f $_tempfile' EXIT
yq -r '.services[].name' "$_deploy_file" >"$_tempfile"
_debug3 "Services" "$(cat "$_tempfile")"
_failedServices=""
_failedCount=0
while read -r _service <&3; do
_debug2 "Service" "$_service"
_hook=$(yq -r ".services[] | select(.name == \"$_service\").hook" "$_deploy_file")
_envs=$(yq -r ".services[] | select(.name == \"$_service\").environment" "$_deploy_file")
_export_envs "$_envs"
if ! _deploy_service "$_service" "$_hook"; then
_failedServices="$_service, $_failedServices"
_failedCount=$((_failedCount + 1))
fi
_clear_envs "$_envs"
done 3<"$_tempfile"
_debug3 "Failed services" "$_failedServices"
_debug2 "Failed count" "$_failedCount"
if [ -n "$_failedServices" ]; then
_info "$(__red "Deployment failed") for services: $_failedServices"
else
_debug "All services deployed successfully."
fi
return "$_failedCount"
}
# Description: Deploys a service using the specified hook.
# Arguments:
# $1 - The name of the service to deploy.
# $2 - The hook to use for deployment.
# Usage:
# _deploy_service <service_name> <hook>
_deploy_service() {
_name="$1"
_hook="$2"
_debug2 "SERVICE" "$_name"
_debug2 "HOOK" "$_hook"
_info "$(__green "Deploying") to '$_name' using '$_hook'"
_deploy "$_cdomain" "$_hook"
}
+69
View File
@@ -0,0 +1,69 @@
#!/usr/bin/env sh
# Script to deploy certificate to Netlify
# https://docs.netlify.com/api/get-started/#authentication
# https://open-api.netlify.com/#tag/sniCertificate
# This deployment required following variables
# export Netlify_ACCESS_TOKEN="Your Netlify Access Token"
# export Netlify_SITE_ID="Your Netlify Site ID"
# If have more than one SITE ID
# export Netlify_SITE_ID="SITE_ID_1 SITE_ID_2"
# returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
netlify_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
if [ -z "$Netlify_ACCESS_TOKEN" ]; then
_err "Netlify_ACCESS_TOKEN is not defined."
return 1
else
_savedomainconf Netlify_ACCESS_TOKEN "$Netlify_ACCESS_TOKEN"
fi
if [ -z "$Netlify_SITE_ID" ]; then
_err "Netlify_SITE_ID is not defined."
return 1
else
_savedomainconf Netlify_SITE_ID "$Netlify_SITE_ID"
fi
_info "Deploying certificate to Netlify..."
## upload certificate
string_ccert=$(sed 's/$/\\n/' "$_ccert" | tr -d '\n')
string_cca=$(sed 's/$/\\n/' "$_cca" | tr -d '\n')
string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n')
for SITE_ID in $Netlify_SITE_ID; do
_request_body="{\"certificate\":\"$string_ccert\",\"key\":\"$string_key\",\"ca_certificates\":\"$string_cca\"}"
_debug _request_body "$_request_body"
_debug Netlify_ACCESS_TOKEN "$Netlify_ACCESS_TOKEN"
export _H1="Authorization: Bearer $Netlify_ACCESS_TOKEN"
_response=$(_post "$_request_body" "https://api.netlify.com/api/v1/sites/$SITE_ID/ssl" "" "POST" "application/json")
if _contains "$_response" "\"error\""; then
_err "Error in deploying $_cdomain certificate to Netlify SITE_ID $SITE_ID."
_err "$_response"
return 1
fi
_debug response "$_response"
_info "Domain $_cdomain certificate successfully deployed to Netlify SITE_ID $SITE_ID."
done
return 0
}
+227 -48
View File
@@ -7,13 +7,27 @@
#
# Firewall admin with superuser and IP address is required.
#
# export PANOS_USER="" # required
# export PANOS_PASS="" # required
# export PANOS_HOST="" # required
# REQUIRED:
# export PANOS_HOST=""
# export PANOS_USER="" #User *MUST* have Commit and Import Permissions in XML API for Admin Role
# export PANOS_PASS=""
#
# OPTIONAL
# export PANOS_TEMPLATE="" # Template Name of panorama managed devices
# export PANOS_TEMPLATE_STACK="" # set a Template Stack if certificate should also be pushed automatically
# export PANOS_VSYS="Shared" # name of the vsys to import the certificate
# export PANOS_CERTNAME="" # use a custom certificate name to work around Panorama's 31-character limit
#
# The script will automatically generate a new API key if
# no key is found, or if a saved key has expired or is invalid.
# This function is to parse the XML
_COMMIT_WAIT_INTERVAL=30 # query commit status every 30 seconds
_COMMIT_WAIT_ITERATIONS=20 # query commit status 20 times (20*30 = 600 seconds = 10 minutes)
# This function is to parse the XML response from the firewall
parse_response() {
type=$2
_debug "API Response: $1"
if [ "$type" = 'keygen' ]; then
status=$(echo "$1" | sed 's/^.*\(['\'']\)\([a-z]*\)'\''.*/\2/g')
if [ "$status" = "success" ]; then
@@ -23,25 +37,52 @@ parse_response() {
message="PAN-OS Key could not be set."
fi
else
status=$(echo "$1" | sed 's/^.*"\([a-z]*\)".*/\1/g')
message=$(echo "$1" | sed 's/^.*<result>\(.*\)<\/result.*/\1/g')
if [ "$type" = 'commit' ]; then
job_id=$(echo "$1" | sed 's/^.*\(<job>\)\(.*\)<\/job>.*/\2/g')
_commit_job_id=$job_id
elif [ "$type" = 'job_status' ]; then
job_status=$(echo "$1" | tr -d '\n' | sed 's/^.*<result>\([^<]*\)<\/result>.*/\1/g')
_commit_job_status=$job_status
fi
status=$(echo "$1" | tr -d '\n' | sed 's/^.*"\([a-z]*\)".*/\1/g')
message=$(echo "$1" | tr -d '\n' | sed 's/.*\(<result>\|<msg>\|<line>\)\([^<]*\).*/\2/g')
_debug "Firewall message: $message"
if [ "$type" = 'keytest' ] && [ "$status" != "success" ]; then
_debug "**** API Key has EXPIRED or is INVALID ****"
unset _panos_key
fi
fi
return 0
}
#This function is used to deploy to the firewall
deployer() {
content=""
type=$1 # Types are keygen, cert, key, commit
_debug "**** Deploying $type *****"
type=$1 # Types are keytest, keygen, cert, key, commit, job_status, push
panos_url="https://$_panos_host/api/"
export _H1="Content-Type: application/x-www-form-urlencoded"
#Test API Key by performing a lookup
if [ "$type" = 'keytest' ]; then
_debug "**** Testing saved API Key ****"
# Get Version Info to test key
content="type=version&key=$_panos_key"
## Exclude all scopes for the empty commit
#_exclude_scope="<device-and-network>excluded</device-and-network><shared-object>excluded</shared-object>"
#content="type=commit&action=partial&key=$_panos_key&cmd=<commit><partial>$_exclude_scope<admin><member>$_panos_user</member></admin></partial></commit>"
fi
# Generate API Key
if [ "$type" = 'keygen' ]; then
_H1="Content-Type: application/x-www-form-urlencoded"
_debug "**** Generating new API Key ****"
content="type=keygen&user=$_panos_user&password=$_panos_pass"
# content="$content${nl}--$delim${nl}Content-Disposition: form-data; type=\"keygen\"; user=\"$_panos_user\"; password=\"$_panos_pass\"${nl}Content-Type: application/octet-stream${nl}${nl}"
fi
# Deploy Cert or Key
if [ "$type" = 'cert' ] || [ "$type" = 'key' ]; then
#Generate DEIM
_debug "**** Deploying $type ****"
#Generate DELIM
delim="-----MultipartDelimiter$(date "+%s%N")"
nl="\015\012"
#Set Header
@@ -49,19 +90,31 @@ deployer() {
if [ "$type" = 'cert' ]; then
panos_url="${panos_url}?type=import"
content="--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\ncertificate"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n$_cdomain"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n$_panos_certname"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")"
if [ "$_panos_template" ]; then
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n$_panos_template"
fi
if [ "$_panos_vsys" ]; then
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl-vsys\"\r\n\r\n$_panos_vsys"
fi
fi
if [ "$type" = 'key' ]; then
panos_url="${panos_url}?type=import"
content="--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\nprivate-key"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n$_cdomain"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n$_panos_certname"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n123456"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_panos_certname.key")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")"
if [ "$_panos_template" ]; then
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n$_panos_template"
fi
if [ "$_panos_vsys" ]; then
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl-vsys\"\r\n\r\n$_panos_vsys"
fi
fi
#Close multipart
content="$content${nl}--$delim--${nl}${nl}"
@@ -69,20 +122,43 @@ deployer() {
content=$(printf %b "$content")
fi
# Commit changes
if [ "$type" = 'commit' ]; then
export _H1="Content-Type: application/x-www-form-urlencoded"
cmd=$(printf "%s" "<commit><partial><$_panos_user></$_panos_user></partial></commit>" | _url_encode)
content="type=commit&key=$_panos_key&cmd=$cmd"
_debug "**** Committing changes ****"
#Check for force commit - will commit ALL uncommited changes to the firewall. Use with caution!
if [ "$FORCE" ]; then
_debug "Force switch detected. Committing ALL changes to the firewall."
cmd=$(printf "%s" "<commit><force><partial><admin><member>$_panos_user</member></admin></partial></force></commit>" | _url_encode)
else
cmd=$(printf "%s" "<commit><partial><admin><member>$_panos_user</member></admin></partial></commit>" | _url_encode)
fi
content="type=commit&action=partial&key=$_panos_key&cmd=$cmd"
fi
# Query job status
if [ "$type" = 'job_status' ]; then
echo "**** Querying job $_commit_job_id status ****"
cmd=$(printf "%s" "<show><jobs><id>$_commit_job_id</id></jobs></show>" | _url_encode)
content="type=op&key=$_panos_key&cmd=$cmd"
fi
# Push changes
if [ "$type" = 'push' ]; then
echo "**** Pushing changes ****"
cmd=$(printf "%s" "<commit-all><template-stack><name>$_panos_template_stack</name><admin><member>$_panos_user</member></admin></template-stack></commit-all>" | _url_encode)
content="type=commit&action=all&key=$_panos_key&cmd=$cmd"
fi
response=$(_post "$content" "$panos_url" "" "POST")
parse_response "$response" "$type"
# Saving response to variables
response_status=$status
#DEBUG
_debug response_status "$response_status"
if [ "$response_status" = "success" ]; then
_debug "Successfully deployed $type"
return 0
elif [ "$_commit_job_status" ]; then
_debug "Commit Job Status = $_commit_job_status"
else
_err "Deploy of type $type failed. Try deploying with --debug to troubleshoot."
_debug "$message"
@@ -92,48 +168,151 @@ deployer() {
# This is the main function that will call the other functions to deploy everything.
panos_deploy() {
_cdomain="$1"
_cdomain=$(echo "$1" | sed 's/*/WILDCARD_/g') #Wildcard Safe Filename
_ckey="$2"
_cfullchain="$5"
# PANOS ENV VAR check
if [ -z "$PANOS_USER" ] || [ -z "$PANOS_PASS" ] || [ -z "$PANOS_HOST" ]; then
_debug "No ENV variables found lets check for saved variables"
_getdeployconf PANOS_USER
_getdeployconf PANOS_PASS
_getdeployconf PANOS_HOST
_panos_user=$PANOS_USER
_panos_pass=$PANOS_PASS
_panos_host=$PANOS_HOST
if [ -z "$_panos_user" ] && [ -z "$_panos_pass" ] && [ -z "$_panos_host" ]; then
_err "No host, user and pass found.. If this is the first time deploying please set PANOS_HOST, PANOS_USER and PANOS_PASS in environment variables. Delete them after you have succesfully deployed certs."
return 1
else
_debug "Using saved env variables."
fi
else
_debug "Detected ENV variables to be saved to the deploy conf."
# Encrypt and save user
_savedeployconf PANOS_USER "$PANOS_USER" 1
_savedeployconf PANOS_PASS "$PANOS_PASS" 1
_savedeployconf PANOS_HOST "$PANOS_HOST" 1
_panos_user="$PANOS_USER"
_panos_pass="$PANOS_PASS"
_panos_host="$PANOS_HOST"
# VALID FILE CHECK
if [ ! -f "$_ckey" ] || [ ! -f "$_cfullchain" ]; then
_err "Unable to find a valid key and/or cert. If this is an ECDSA/ECC cert, use the --ecc flag when deploying."
return 1
fi
_debug "Let's use username and pass to generate token."
if [ -z "$_panos_user" ] || [ -z "$_panos_pass" ] || [ -z "$_panos_host" ]; then
_err "Please pass username and password and host as env variables PANOS_USER, PANOS_PASS and PANOS_HOST"
# PANOS_HOST
if [ "$PANOS_HOST" ]; then
_debug "Detected ENV variable PANOS_HOST. Saving to file."
_savedeployconf PANOS_HOST "$PANOS_HOST" 1
else
_debug "Attempting to load variable PANOS_HOST from file."
_getdeployconf PANOS_HOST
fi
# PANOS USER
if [ "$PANOS_USER" ]; then
_debug "Detected ENV variable PANOS_USER. Saving to file."
_savedeployconf PANOS_USER "$PANOS_USER" 1
else
_debug "Attempting to load variable PANOS_USER from file."
_getdeployconf PANOS_USER
fi
# PANOS_PASS
if [ "$PANOS_PASS" ]; then
_debug "Detected ENV variable PANOS_PASS. Saving to file."
_savedeployconf PANOS_PASS "$PANOS_PASS" 1
else
_debug "Attempting to load variable PANOS_PASS from file."
_getdeployconf PANOS_PASS
fi
# PANOS_KEY
if [ "$PANOS_KEY" ]; then
_debug "Detected ENV variable PANOS_KEY. Saving to file."
_savedeployconf PANOS_KEY "$PANOS_KEY" 1
else
_debug "Attempting to load variable PANOS_KEY from file."
_getdeployconf PANOS_KEY
fi
# PANOS_TEMPLATE
if [ "$PANOS_TEMPLATE" ]; then
_debug "Detected ENV variable PANOS_TEMPLATE. Saving to file."
_savedeployconf PANOS_TEMPLATE "$PANOS_TEMPLATE" 1
else
_debug "Attempting to load variable PANOS_TEMPLATE from file."
_getdeployconf PANOS_TEMPLATE
fi
# PANOS_TEMPLATE_STACK
if [ "$PANOS_TEMPLATE_STACK" ]; then
_debug "Detected ENV variable PANOS_TEMPLATE_STACK. Saving to file."
_savedeployconf PANOS_TEMPLATE_STACK "$PANOS_TEMPLATE_STACK" 1
else
_debug "Attempting to load variable PANOS_TEMPLATE_STACK from file."
_getdeployconf PANOS_TEMPLATE_STACK
fi
# PANOS_TEMPLATE_STACK
if [ "$PANOS_VSYS" ]; then
_debug "Detected ENV variable PANOS_VSYS. Saving to file."
_savedeployconf PANOS_VSYS "$PANOS_VSYS" 1
else
_debug "Attempting to load variable PANOS_VSYS from file."
_getdeployconf PANOS_VSYS
fi
# PANOS_CERTNAME
if [ "$PANOS_CERTNAME" ]; then
_debug "Detected ENV variable PANOS_CERTNAME. Saving to file."
_savedeployconf PANOS_CERTNAME "$PANOS_CERTNAME" 1
else
_debug "Attempting to load variable PANOS_CERTNAME from file."
_getdeployconf PANOS_CERTNAME
fi
#Store variables
_panos_host=$PANOS_HOST
_panos_user=$PANOS_USER
_panos_pass=$PANOS_PASS
_panos_key=$PANOS_KEY
_panos_template=$PANOS_TEMPLATE
_panos_template_stack=$PANOS_TEMPLATE_STACK
_panos_vsys=$PANOS_VSYS
_panos_certname=$PANOS_CERTNAME
#Test API Key if found. If the key is invalid, the variable _panos_key will be unset.
if [ "$_panos_host" ] && [ "$_panos_key" ]; then
_debug "**** Testing API KEY ****"
deployer keytest
fi
# Check for valid variables
if [ -z "$_panos_host" ]; then
_err "No host found. If this is your first time deploying, please set PANOS_HOST in ENV variables. You can delete it after you have successfully deployed the certs."
return 1
else
_debug "Getting PANOS KEY"
deployer keygen
# Use certificate name based on the first domain on the certificate if no custom certificate name is set
if [ -z "$_panos_certname" ]; then
_panos_certname="$_cdomain"
_savedeployconf PANOS_CERTNAME "$_panos_certname" 1
fi
# Generate a new API key if no valid API key is found
if [ -z "$_panos_key" ]; then
_err "Missing apikey."
if [ -z "$_panos_user" ]; then
_err "No user found. If this is your first time deploying, please set PANOS_USER in ENV variables. You can delete it after you have successfully deployed the certs."
return 1
elif [ -z "$_panos_pass" ]; then
_err "No password found. If this is your first time deploying, please set PANOS_PASS in ENV variables. You can delete it after you have successfully deployed the certs."
return 1
fi
_debug "**** Generating new PANOS API KEY ****"
deployer keygen
_savedeployconf PANOS_KEY "$_panos_key" 1
fi
# Confirm that a valid key was generated
if [ -z "$_panos_key" ]; then
_err "Unable to generate an API key. The user and pass may be invalid or not authorized to generate a new key. Please check the PANOS_USER and PANOS_PASS credentials and try again"
return 1
else
deployer cert
deployer key
deployer commit
if [ "$_panos_template_stack" ]; then
# try to get job status for 20 times in 30 sec interval
i=0
while [ "$i" -lt $_COMMIT_WAIT_ITERATIONS ]; do
deployer job_status
if [ "$_commit_job_status" = "OK" ]; then
echo "Commit finished!"
break
fi
sleep $_COMMIT_WAIT_INTERVAL
i=$((i + 1))
done
deployer push
fi
fi
fi
}
+132
View File
@@ -0,0 +1,132 @@
#!/usr/bin/env sh
# Deploy certificates to a proxmox backup server using the API.
#
# Environment variables that can be set are:
# `DEPLOY_PROXMOXBS_SERVER`: The hostname of the proxmox backup server. Defaults to
# _cdomain.
# `DEPLOY_PROXMOXBS_SERVER_PORT`: The port number the management interface is on.
# Defaults to 8007.
# `DEPLOY_PROXMOXBS_USER`: The user we'll connect as. Defaults to root.
# `DEPLOY_PROXMOXBS_USER_REALM`: The authentication realm the user authenticates
# with. Defaults to pam.
# `DEPLOY_PROXMOXBS_API_TOKEN_NAME`: The name of the API token created for the
# user account. Defaults to acme.
# `DEPLOY_PROXMOXBS_API_TOKEN_KEY`: The API token. Required.
proxmoxbs_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_PROXMOXBS_SERVER
if [ -z "$DEPLOY_PROXMOXBS_SERVER" ]; then
_target_hostname="$_cdomain"
else
_target_hostname="$DEPLOY_PROXMOXBS_SERVER"
_savedeployconf DEPLOY_PROXMOXBS_SERVER "$DEPLOY_PROXMOXBS_SERVER"
fi
_debug2 DEPLOY_PROXMOXBS_SERVER "$_target_hostname"
_getdeployconf DEPLOY_PROXMOXBS_SERVER_PORT
if [ -z "$DEPLOY_PROXMOXBS_SERVER_PORT" ]; then
_target_port="8007"
else
_target_port="$DEPLOY_PROXMOXBS_SERVER_PORT"
_savedeployconf DEPLOY_PROXMOXBS_SERVER_PORT "$DEPLOY_PROXMOXBS_SERVER_PORT"
fi
_debug2 DEPLOY_PROXMOXBS_SERVER_PORT "$_target_port"
# Complete URL.
_target_url="https://${_target_hostname}:${_target_port}/api2/json/nodes/localhost/certificates/custom"
_debug TARGET_URL "$_target_url"
# More "sane" defaults.
_getdeployconf DEPLOY_PROXMOXBS_USER
if [ -z "$DEPLOY_PROXMOXBS_USER" ]; then
_proxmoxbs_user="root"
else
_proxmoxbs_user="$DEPLOY_PROXMOXBS_USER"
_savedeployconf DEPLOY_PROXMOXBS_USER "$DEPLOY_PROXMOXBS_USER"
fi
_debug2 DEPLOY_PROXMOXBS_USER "$_proxmoxbs_user"
_getdeployconf DEPLOY_PROXMOXBS_USER_REALM
if [ -z "$DEPLOY_PROXMOXBS_USER_REALM" ]; then
_proxmoxbs_user_realm="pam"
else
_proxmoxbs_user_realm="$DEPLOY_PROXMOXBS_USER_REALM"
_savedeployconf DEPLOY_PROXMOXBS_USER_REALM "$DEPLOY_PROXMOXBS_USER_REALM"
fi
_debug2 DEPLOY_PROXMOXBS_USER_REALM "$_proxmoxbs_user_realm"
_getdeployconf DEPLOY_PROXMOXBS_API_TOKEN_NAME
if [ -z "$DEPLOY_PROXMOXBS_API_TOKEN_NAME" ]; then
_proxmoxbs_api_token_name="acme"
else
_proxmoxbs_api_token_name="$DEPLOY_PROXMOXBS_API_TOKEN_NAME"
_savedeployconf DEPLOY_PROXMOXBS_API_TOKEN_NAME "$DEPLOY_PROXMOXBS_API_TOKEN_NAME"
fi
_debug2 DEPLOY_PROXMOXBS_API_TOKEN_NAME "$_proxmoxbs_api_token_name"
# This is required.
_getdeployconf DEPLOY_PROXMOXBS_API_TOKEN_KEY
if [ -z "$DEPLOY_PROXMOXBS_API_TOKEN_KEY" ]; then
_err "API key not provided."
return 1
else
_proxmoxbs_api_token_key="$DEPLOY_PROXMOXBS_API_TOKEN_KEY"
_savedeployconf DEPLOY_PROXMOXBS_API_TOKEN_KEY "$DEPLOY_PROXMOXBS_API_TOKEN_KEY"
fi
_debug2 DEPLOY_PROXMOXBS_API_TOKEN_KEY "$_proxmoxbs_api_token_key"
# PBS API Token header value. Used in "Authorization: PBSAPIToken".
_proxmoxbs_header_api_token="${_proxmoxbs_user}@${_proxmoxbs_user_realm}!${_proxmoxbs_api_token_name}:${_proxmoxbs_api_token_key}"
_debug2 "Auth Header" "$_proxmoxbs_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":"localhost",
"restart":true,
"force":true
}
HEREDOC
)
_debug2 Payload "$_json_payload"
_info "Push certificates to server"
export HTTPS_INSECURE=1
export _H1="Authorization: PBSAPIToken=${_proxmoxbs_header_api_token}"
response=$(_post "$_json_payload" "$_target_url" "" POST "application/json")
response="$(echo "$response" | _json_decode | _normalizeJson)"
message=$(echo "$response" | _egrep_o '"message":"[^"]*' | cut -d : -f 2 | tr -d '"')
_retval=$?
if [ "${_retval}" -eq 0 ] && [ -z "$message" ]; then
_debug3 response "$response"
_info "Certificate successfully deployed"
return 0
else
_err "Certificate deployment failed: $message"
_debug "Response" "$response"
return 1
fi
}
+144
View File
@@ -0,0 +1,144 @@
#!/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"
_info "Push certificates to server"
export HTTPS_INSECURE=1
export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}"
response=$(_post "$_json_payload" "$_target_url" "" POST "application/json")
response="$(echo "$response" | _json_decode | _normalizeJson)"
message=$(echo "$response" | _egrep_o '"message":"[^"]*' | cut -d : -f 2 | tr -d '"')
_retval=$?
if [ "${_retval}" -eq 0 ] && [ -z "$message" ]; then
_debug3 response "$response"
_info "Certificate successfully deployed"
return 0
else
_err "Certificate deployment failed: $message"
_debug "Response" "$response"
return 1
fi
}
+11 -3
View File
@@ -8,6 +8,8 @@
# export QINIU_CDN_DOMAIN="cdn.example.com"
# If you have more than one domain, just
# export QINIU_CDN_DOMAIN="cdn1.example.com cdn2.example.com"
# Optional: force HTTPS redirect (default: false)
# export QINIU_FORCE_HTTPS="true"
QINIU_API_BASE="https://api.qiniu.com"
@@ -44,6 +46,12 @@ qiniu_deploy() {
QINIU_CDN_DOMAIN="$_cdomain"
fi
if [ -z "$QINIU_FORCE_HTTPS" ]; then
QINIU_FORCE_HTTPS="false"
else
_savedomainconf QINIU_FORCE_HTTPS "$QINIU_FORCE_HTTPS"
fi
## upload certificate
string_fullchain=$(sed 's/$/\\n/' "$_cfullchain" | tr -d '\n')
string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n')
@@ -53,7 +61,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:"
@@ -69,13 +77,13 @@ qiniu_deploy() {
_debug certId "$_certId"
## update domain ssl config
update_body="{\"certid\":$_certId,\"forceHttps\":false}"
update_body="{\"certid\":$_certId,\"forceHttps\":$QINIU_FORCE_HTTPS}"
for domain in $QINIU_CDN_DOMAIN; do
update_path="/domain/$domain/httpsconf"
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:"
+8 -7
View File
@@ -137,17 +137,18 @@ routeros_deploy() {
return $_err_code
fi
DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=$ROUTER_OS_USERNAME \
DEPLOY_SCRIPT_CMD=":do {/system script remove \"LECertDeploy-$_cdomain\" } on-error={ }; \
/system script add name=\"LECertDeploy-$_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=\\\"\\\";\
\n/certificate import file-name=\\\"$_cdomain.cer\\\" passphrase=\\\"\\\";\
\n/certificate import file-name=\\\"$_cdomain.key\\\" passphrase=\\\"\\\";\
\ndelay 1;\
\n/file remove $_cdomain.cer;\
\n/file remove $_cdomain.key;\
\n:do {/file remove $_cdomain.cer; } on-error={ }\
\n:do {/file remove $_cdomain.key; } on-error={ }\
\ndelay 2;\
\n/ip service set www-ssl certificate=$_cdomain.cer_0;\
\n$ROUTER_OS_ADDITIONAL_SERVICES;\
@@ -158,11 +159,11 @@ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\
return $_err_code
fi
if ! _ssh_remote_cmd "/system script run \"LE Cert Deploy - $_cdomain\""; then
if ! _ssh_remote_cmd "/system script run \"LECertDeploy-$_cdomain\""; then
return $_err_code
fi
if ! _ssh_remote_cmd "/system script remove \"LE Cert Deploy - $_cdomain\""; then
if ! _ssh_remote_cmd "/system script remove \"LECertDeploy-$_cdomain\""; then
return $_err_code
fi
+200
View File
@@ -0,0 +1,200 @@
#!/usr/bin/env sh
# Here is a script to deploy cert to Ruckus ZoneDirector / Unleashed.
#
# Public domain, 2024, Tony Rielly <https://github.com/ms264556>
#
# ```sh
# acme.sh --deploy -d ruckus.example.com --deploy-hook ruckus
# ```
#
# Then you need to set the environment variables for the
# deploy script to work.
#
# ```sh
# export RUCKUS_HOST=myruckus.example.com
# export RUCKUS_USER=myruckususername
# export RUCKUS_PASS=myruckuspassword
#
# acme.sh --deploy -d myruckus.example.com --deploy-hook ruckus
# ```
#
# returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
ruckus_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_err_code=0
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
_getdeployconf RUCKUS_HOST
_getdeployconf RUCKUS_USER
_getdeployconf RUCKUS_PASS
if [ -z "$RUCKUS_HOST" ]; then
_debug "Using _cdomain as RUCKUS_HOST, please set if not correct."
RUCKUS_HOST="$_cdomain"
fi
if [ -z "$RUCKUS_USER" ]; then
_err "Need to set the env variable RUCKUS_USER"
return 1
fi
if [ -z "$RUCKUS_PASS" ]; then
_err "Need to set the env variable RUCKUS_PASS"
return 1
fi
_savedeployconf RUCKUS_HOST "$RUCKUS_HOST"
_savedeployconf RUCKUS_USER "$RUCKUS_USER"
_savedeployconf RUCKUS_PASS "$RUCKUS_PASS"
_debug RUCKUS_HOST "$RUCKUS_HOST"
_debug RUCKUS_USER "$RUCKUS_USER"
_secure_debug RUCKUS_PASS "$RUCKUS_PASS"
export ACME_HTTP_NO_REDIRECTS=1
_info "Discovering the login URL"
_get "https://$RUCKUS_HOST" >/dev/null
_login_url="$(_response_header 'Location')"
if [ -n "$_login_url" ]; then
_login_path=$(echo "$_login_url" | sed 's|https\?://[^/]\+||')
if [ -z "$_login_path" ]; then
# redirect was to a different host
_err "Connection failed: redirected to a different host. Configure Unleashed with a Preferred Master or Management Interface."
return 1
fi
fi
if [ -z "${_login_url}" ]; then
_err "Connection failed: couldn't find login page."
return 1
fi
_base_url=$(dirname "$_login_url")
_login_page=$(basename "$_login_url")
if [ "$_login_page" = "index.html" ]; then
_err "Connection temporarily unavailable: Unleashed Rebuilding."
return 1
fi
if [ "$_login_page" = "wizard.jsp" ]; then
_err "Connection failed: Setup Wizard not complete."
return 1
fi
_info "Login"
_username_encoded="$(printf "%s" "$RUCKUS_USER" | _url_encode)"
_password_encoded="$(printf "%s" "$RUCKUS_PASS" | _url_encode)"
_login_query="$(printf "%s" "username=${_username_encoded}&password=${_password_encoded}&ok=Log+In")"
_post "$_login_query" "$_login_url" >/dev/null
_login_code="$(_response_code)"
if [ "$_login_code" = "200" ]; then
_err "Login failed: incorrect credentials."
return 1
fi
_info "Collect Session Cookie"
_H1="Cookie: $(_response_cookie)"
export _H1
_info "Collect CSRF Token"
_H2="X-CSRF-Token: $(_response_header 'HTTP_X_CSRF_TOKEN')"
export _H2
if _isRSA "$_ckey" >/dev/null 2>&1; then
_debug "Using RSA certificate."
else
_info "Verifying ECC certificate support."
_ul_version="$(_get_unleashed_version)"
if [ -z "$_ul_version" ]; then
_err "Your controller doesn't support ECC certificates. Please deploy an RSA certificate."
return 1
fi
_ul_version_major="$(echo "$_ul_version" | cut -d . -f 1)"
_ul_version_minor="$(echo "$_ul_version" | cut -d . -f 2)"
if [ "$_ul_version_major" -lt "200" ]; then
_err "ZoneDirector doesn't support ECC certificates. Please deploy an RSA certificate."
return 1
elif [ "$_ul_version_minor" -lt "13" ]; then
_err "Unleashed $_ul_version_major.$_ul_version_minor doesn't support ECC certificates. Please deploy an RSA certificate or upgrade to Unleashed 200.13+."
return 1
fi
_debug "ECC certificates OK for Unleashed $_ul_version_major.$_ul_version_minor."
fi
_info "Uploading certificate"
_post_upload "uploadcert" "$_cfullchain"
_info "Uploading private key"
_post_upload "uploadprivatekey" "$_ckey"
_info "Replacing certificate"
_replace_cert_ajax='<ajax-request action="docmd" comp="system" updater="rid.0.5" xcmd="replace-cert" checkAbility="6" timeout="-1"><xcmd cmd="replace-cert" cn="'$RUCKUS_HOST'"/></ajax-request>'
_post "$_replace_cert_ajax" "$_base_url/_cmdstat.jsp" >/dev/null
_info "Rebooting"
_cert_reboot_ajax='<ajax-request action="docmd" comp="worker" updater="rid.0.5" xcmd="cert-reboot" checkAbility="6"><xcmd cmd="cert-reboot" action="undefined"/></ajax-request>'
_post "$_cert_reboot_ajax" "$_base_url/_cmdstat.jsp" >/dev/null
return 0
}
_response_code() {
_egrep_o <"$HTTP_HEADER" "^HTTP[^ ]* .*$" | cut -d " " -f 2-100 | tr -d "\f\n" | _egrep_o "^[0-9]*"
}
_response_header() {
grep <"$HTTP_HEADER" -i "^$1:" | cut -d ':' -f 2- | tr -d "\r\n\t "
}
_response_cookie() {
_response_header 'Set-Cookie' | sed 's/;.*//'
}
_get_unleashed_version() {
_post '<ajax-request action="getstat" comp="system"><sysinfo/></ajax-request>' "$_base_url/_cmdstat.jsp" | _egrep_o "version-num=\"[^\"]*\"" | cut -d '"' -f 2
}
_post_upload() {
_post_action="$1"
_post_file="$2"
_post_boundary="----FormBoundary$(date "+%s%N")"
_post_data="$({
printf -- "--%s\r\n" "$_post_boundary"
printf -- "Content-Disposition: form-data; name=\"u\"; filename=\"%s\"\r\n" "$_post_action"
printf -- "Content-Type: application/octet-stream\r\n\r\n"
printf -- "%s\r\n" "$(cat "$_post_file")"
printf -- "--%s\r\n" "$_post_boundary"
printf -- "Content-Disposition: form-data; name=\"action\"\r\n\r\n"
printf -- "%s\r\n" "$_post_action"
printf -- "--%s\r\n" "$_post_boundary"
printf -- "Content-Disposition: form-data; name=\"callback\"\r\n\r\n"
printf -- "%s\r\n" "uploader_$_post_action"
printf -- "--%s--\r\n\r\n" "$_post_boundary"
})"
_post "$_post_data" "$_base_url/_upload.jsp?request_type=xhr" "" "" "multipart/form-data; boundary=$_post_boundary" >/dev/null
}
+286 -125
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,186 @@ 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
# If file doesn't exist, create it and change its permissions.
_cmdstr="$_cmdstr test ! -f $DEPLOY_SSH_KEYFILE && touch $DEPLOY_SSH_KEYFILE && chmod 600 $DEPLOY_SSH_KEYFILE;"
# 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 +412,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 +439,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
}
+77 -34
View File
@@ -10,46 +10,89 @@
#domain keyfile certfile cafile fullchain
strongswan_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_cdomain="${1}"
_ckey="${2}"
_ccert="${3}"
_cca="${4}"
_cfullchain="${5}"
_info "Using strongswan"
if [ -x /usr/sbin/ipsec ]; then
_ipsec=/usr/sbin/ipsec
elif [ -x /usr/sbin/strongswan ]; then
_ipsec=/usr/sbin/strongswan
elif [ -x /usr/local/sbin/ipsec ]; then
_ipsec=/usr/local/sbin/ipsec
else
if _exists ipsec; then
_ipsec=ipsec
elif _exists strongswan; then
_ipsec=strongswan
fi
if _exists swanctl; then
_swanctl=swanctl
fi
# For legacy stroke mode
if [ -n "${_ipsec}" ]; then
_info "${_ipsec} command detected"
_confdir=$(${_ipsec} --confdir)
if [ -z "${_confdir}" ]; then
_err "no strongswan --confdir is detected"
return 1
fi
_info _confdir "${_confdir}"
__deploy_cert "stroke" "${_confdir}" "$@"
${_ipsec} reload
fi
# For modern vici mode
if [ -n "${_swanctl}" ]; then
_info "${_swanctl} command detected"
for _dir in /usr/local/etc/swanctl /etc/swanctl /etc/strongswan/swanctl; do
if [ -d ${_dir} ]; then
_confdir=${_dir}
_info _confdir "${_confdir}"
break
fi
done
if [ -z "${_confdir}" ]; then
_err "no swanctl config dir is found"
return 1
fi
__deploy_cert "vici" "${_confdir}" "$@"
${_swanctl} --load-creds
fi
if [ -z "${_swanctl}" ] && [ -z "${_ipsec}" ]; then
_err "no strongswan or ipsec command is detected"
_err "no swanctl is detected"
return 1
fi
}
_info _ipsec "$_ipsec"
#################### Private functions below ##################################
_confdir=$($_ipsec --confdir)
if [ $? -ne 0 ] || [ -z "$_confdir" ]; then
_err "no strongswan --confdir is detected"
__deploy_cert() {
_swan_mode="${1}"
_confdir="${2}"
_cdomain="${3}"
_ckey="${4}"
_ccert="${5}"
_cca="${6}"
_cfullchain="${7}"
_debug _cdomain "${_cdomain}"
_debug _ckey "${_ckey}"
_debug _ccert "${_ccert}"
_debug _cca "${_cca}"
_debug _cfullchain "${_cfullchain}"
_debug _swan_mode "${_swan_mode}"
_debug _confdir "${_confdir}"
if [ "${_swan_mode}" = "vici" ]; then
_dir_private="private"
_dir_cert="x509"
_dir_ca="x509ca"
elif [ "${_swan_mode}" = "stroke" ]; then
_dir_private="ipsec.d/private"
_dir_cert="ipsec.d/certs"
_dir_ca="ipsec.d/cacerts"
else
_err "unknown StrongSwan mode ${_swan_mode}"
return 1
fi
_info _confdir "$_confdir"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
cat "$_ckey" >"${_confdir}/ipsec.d/private/$(basename "$_ckey")"
cat "$_ccert" >"${_confdir}/ipsec.d/certs/$(basename "$_ccert")"
cat "$_cca" >"${_confdir}/ipsec.d/cacerts/$(basename "$_cca")"
cat "$_cfullchain" >"${_confdir}/ipsec.d/cacerts/$(basename "$_cfullchain")"
$_ipsec reload
cat "${_ckey}" >"${_confdir}/${_dir_private}/$(basename "${_ckey}")"
cat "${_ccert}" >"${_confdir}/${_dir_cert}/$(basename "${_ccert}")"
cat "${_cca}" >"${_confdir}/${_dir_ca}/$(basename "${_cca}")"
if [ "${_swan_mode}" = "stroke" ]; then
cat "${_cfullchain}" >"${_confdir}/${_dir_ca}/$(basename "${_cfullchain}")"
fi
}
+362 -100
View File
@@ -1,34 +1,53 @@
#!/usr/bin/env sh
#!/bin/bash
# Here is a script to deploy cert to Synology DSM
#
# It requires following environment variables:
#
# SYNO_Username - Synology Username to login (must be an administrator)
# SYNO_Password - Synology Password to login
# SYNO_Certificate - Certificate description to target for replacement
#
# The following environmental variables may be set if you don't like their
# default values:
#
# SYNO_Scheme - defaults to http
# SYNO_Hostname - defaults to localhost
# SYNO_Port - defaults to 5000
# SYNO_DID - device ID to skip OTP - defaults to empty
# SYNO_TOTP_SECRET - TOTP secret to generate OTP - defaults to empty
#
################################################################################
# ACME.sh 3rd party deploy plugin for Synology DSM
################################################################################
# Authors: Brian Hartvigsen (creator), https://github.com/tresni
# Martin Arndt (contributor), https://troublezone.net/
# Updated: 2023-07-03
# Issues: https://github.com/acmesh-official/acme.sh/issues/2727
################################################################################
# Usage (shown values are the examples):
# 1. Set required environment variables:
# - use automatically created temp admin user to authenticate
# export SYNO_USE_TEMP_ADMIN=1
# - or provide your own admin user credential to authenticate
# 1. export SYNO_USERNAME="adminUser"
# 2. export SYNO_PASSWORD="adminPassword"
# 2. Set optional environment variables
# - common optional variables
# - export SYNO_SCHEME="http" - defaults to "http"
# - export SYNO_HOSTNAME="localhost" - defaults to "localhost"
# - export SYNO_PORT="5000" - defaults to "5000"
# - export SYNO_CREATE=1 - to allow creating the cert if it doesn't exist
# - export SYNO_CERTIFICATE="" - to replace a specific cert by its
# description
# - temp admin optional variables
# - export SYNO_LOCAL_HOSTNAME=1 - if set to 1, force to treat hostname is
# targeting current local machine (since
# this method only locally supported)
# - exsiting admin 2FA-OTP optional variables
# - export SYNO_OTP_CODE="XXXXXX" - if set, script won't require to
# interactive input the OTP code
# - export SYNO_DEVICE_NAME="CertRenewal" - if set, script won't require to
# interactive input the device name
# - export SYNO_DEVICE_ID="" - (deprecated, auth with OTP code instead)
# required for omitting 2FA-OTP
# 3. Run command:
# acme.sh --deploy --deploy-hook synology_dsm -d example.com
################################################################################
# Dependencies:
# -------------
# - jq and curl
# - oathtool (When using 2 Factor Authentication and SYNO_TOTP_SECRET is set)
#
#returns 0 means success, otherwise error.
######## Public functions #####################
# - curl
# - synouser & synogroup & synosetkeyvalue (Required for SYNO_USE_TEMP_ADMIN=1)
################################################################################
# Return value:
# 0 means success, otherwise error.
################################################################################
########## Public functions ####################################################
#domain keyfile certfile cafile fullchain
synology_dsm_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
@@ -36,148 +55,391 @@ synology_dsm_deploy() {
_debug _cdomain "$_cdomain"
# Get Username and Password, but don't save until we successfully authenticate
_getdeployconf SYNO_Username
_getdeployconf SYNO_Password
_getdeployconf SYNO_Create
_getdeployconf SYNO_DID
_getdeployconf SYNO_TOTP_SECRET
if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then
_err "SYNO_Username & SYNO_Password must be set"
# Get username and password, but don't save until we authenticated successfully
_migratedeployconf SYNO_Username SYNO_USERNAME
_migratedeployconf SYNO_Password SYNO_PASSWORD
_migratedeployconf SYNO_Device_ID SYNO_DEVICE_ID
_migratedeployconf SYNO_Device_Name SYNO_DEVICE_NAME
_getdeployconf SYNO_USERNAME
_getdeployconf SYNO_PASSWORD
_getdeployconf SYNO_DEVICE_ID
_getdeployconf SYNO_DEVICE_NAME
# Prepare to use temp admin if SYNO_USE_TEMP_ADMIN is set
_getdeployconf SYNO_USE_TEMP_ADMIN
_check2cleardeployconfexp SYNO_USE_TEMP_ADMIN
_debug2 SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN"
if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then
if ! _exists synouser || ! _exists synogroup || ! _exists synosetkeyvalue; then
_err "Missing required tools to creat temp admin user, please set SYNO_USERNAME and SYNO_PASSWORD instead."
_err "Notice: temp admin user authorization method only supports local deployment on DSM."
return 1
fi
if synouser --help 2>&1 | grep -q 'Permission denied'; then
_err "For creating temp admin user, the deploy script must be run as root."
return 1
fi
[ -n "$SYNO_USERNAME" ] || _savedeployconf SYNO_USERNAME ""
[ -n "$SYNO_PASSWORD" ] || _savedeployconf SYNO_PASSWORD ""
_debug "Setting temp admin user credential..."
SYNO_USERNAME=sc-acmesh-tmp
SYNO_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16)
# Set 2FA-OTP settings to empty consider they won't be needed.
SYNO_DEVICE_ID=
SYNO_DEVICE_NAME=
SYNO_OTP_CODE=
else
_debug2 SYNO_USERNAME "$SYNO_USERNAME"
_secure_debug2 SYNO_PASSWORD "$SYNO_PASSWORD"
_debug2 SYNO_DEVICE_NAME "$SYNO_DEVICE_NAME"
_secure_debug2 SYNO_DEVICE_ID "$SYNO_DEVICE_ID"
fi
if [ -z "$SYNO_USERNAME" ] || [ -z "$SYNO_PASSWORD" ]; then
_err "You must set either SYNO_USE_TEMP_ADMIN, or set both SYNO_USERNAME and SYNO_PASSWORD."
return 1
fi
_debug2 SYNO_Username "$SYNO_Username"
_secure_debug2 SYNO_Password "$SYNO_Password"
# Optional scheme, hostname, and port for Synology DSM
_getdeployconf SYNO_Scheme
_getdeployconf SYNO_Hostname
_getdeployconf SYNO_Port
# Optional scheme, hostname and port for Synology DSM
_migratedeployconf SYNO_Scheme SYNO_SCHEME
_migratedeployconf SYNO_Hostname SYNO_HOSTNAME
_migratedeployconf SYNO_Port SYNO_PORT
_getdeployconf SYNO_SCHEME
_getdeployconf SYNO_HOSTNAME
_getdeployconf SYNO_PORT
# default vaules for scheme, hostname, and port
# defaulting to localhost and http because it's localhost...
[ -n "${SYNO_Scheme}" ] || SYNO_Scheme="http"
[ -n "${SYNO_Hostname}" ] || SYNO_Hostname="localhost"
[ -n "${SYNO_Port}" ] || SYNO_Port="5000"
# Default values for scheme, hostname and port
# Defaulting to localhost and http, because it's localhost…
[ -n "$SYNO_SCHEME" ] || SYNO_SCHEME=http
[ -n "$SYNO_HOSTNAME" ] || SYNO_HOSTNAME=localhost
[ -n "$SYNO_PORT" ] || SYNO_PORT=5000
_savedeployconf SYNO_SCHEME "$SYNO_SCHEME"
_savedeployconf SYNO_HOSTNAME "$SYNO_HOSTNAME"
_savedeployconf SYNO_PORT "$SYNO_PORT"
_debug2 SYNO_SCHEME "$SYNO_SCHEME"
_debug2 SYNO_HOSTNAME "$SYNO_HOSTNAME"
_debug2 SYNO_PORT "$SYNO_PORT"
_savedeployconf SYNO_Scheme "$SYNO_Scheme"
_savedeployconf SYNO_Hostname "$SYNO_Hostname"
_savedeployconf SYNO_Port "$SYNO_Port"
_debug2 SYNO_Scheme "$SYNO_Scheme"
_debug2 SYNO_Hostname "$SYNO_Hostname"
_debug2 SYNO_Port "$SYNO_Port"
# Get the certificate description, but don't save it until we verfiy it's real
_getdeployconf SYNO_Certificate
_debug SYNO_Certificate "${SYNO_Certificate:-}"
# Get the certificate description, but don't save it until we verify it's real
_migratedeployconf SYNO_Certificate SYNO_CERTIFICATE "base64"
_getdeployconf SYNO_CERTIFICATE
_check2cleardeployconfexp SYNO_CERTIFICATE
_debug SYNO_CERTIFICATE "${SYNO_CERTIFICATE:-}"
# shellcheck disable=SC1003 # We are not trying to escape a single quote
if printf "%s" "$SYNO_Certificate" | grep '\\'; then
if printf "%s" "$SYNO_CERTIFICATE" | grep '\\'; then
_err "Do not use a backslash (\) in your certificate description"
return 1
fi
_base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port"
_debug "Getting API version..."
_base_url="$SYNO_SCHEME://$SYNO_HOSTNAME:$SYNO_PORT"
_debug _base_url "$_base_url"
_debug "Getting API version"
response=$(_get "$_base_url/webapi/query.cgi?api=SYNO.API.Info&version=1&method=query&query=SYNO.API.Auth")
api_path=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"path" *: *"\([^"]*\)".*/\1/p')
api_version=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"maxVersion" *: *\([0-9]*\).*/\1/p')
_debug3 response "$response"
_debug3 api_path "$api_path"
_debug3 api_version "$api_version"
# Login, get the token from JSON and session id from cookie
_info "Logging into $SYNO_Hostname:$SYNO_Port"
encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)"
encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)"
# Login, get the session ID and SynoToken from JSON
_info "Logging into $SYNO_HOSTNAME:$SYNO_PORT..."
encoded_username="$(printf "%s" "$SYNO_USERNAME" | _url_encode)"
encoded_password="$(printf "%s" "$SYNO_PASSWORD" | _url_encode)"
# ## START ## - DEPRECATED, for backward compatibility
_getdeployconf SYNO_TOTP_SECRET
otp_code=""
if [ -n "$SYNO_TOTP_SECRET" ]; then
if _exists oathtool; then
otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)"
else
_info "WARNING: Usage of SYNO_TOTP_SECRET is deprecated!"
_info " See synology_dsm.sh script or ACME.sh Wiki page for details:"
_info " https://github.com/acmesh-official/acme.sh/wiki/Synology-NAS-Guide"
if ! _exists oathtool; then
_err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET"
return 1
fi
DEPRECATED_otp_code="$(oathtool --base32 --totp "$SYNO_TOTP_SECRET" 2>/dev/null)"
if [ -z "$SYNO_DEVICE_ID" ]; then
_getdeployconf SYNO_DID
[ -n "$SYNO_DID" ] || SYNO_DEVICE_ID="$SYNO_DID"
fi
if [ -n "$SYNO_DEVICE_ID" ]; then
_H1="Cookie: did=$SYNO_DEVICE_ID"
export _H1
_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=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DEVICE_ID" "$_base_url/webapi/$api_path?enable_syno_token=yes")
_debug3 response "$response"
# ## END ## - DEPRECATED, for backward compatibility
# If SYNO_DEVICE_ID or SYNO_OTP_CODE is set, we treat current account enabled 2FA-OTP.
# Notice that if SYNO_USE_TEMP_ADMIN=1, both variables will be unset
else
if [ -n "$SYNO_DEVICE_ID" ] || [ -n "$SYNO_OTP_CODE" ]; then
response='{"error":{"code":403}}'
# Assume the current account disabled 2FA-OTP, try to log in right away.
else
if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then
_getdeployconf SYNO_LOCAL_HOSTNAME
_debug SYNO_LOCAL_HOSTNAME "${SYNO_LOCAL_HOSTNAME:-}"
if [ "$SYNO_HOSTNAME" != "localhost" ] && [ "$SYNO_HOSTNAME" != "127.0.0.1" ]; then
if [ "$SYNO_LOCAL_HOSTNAME" != "1" ]; then
_err "SYNO_USE_TEMP_ADMIN=1 only support local deployment, though if you are sure that the hostname $SYNO_HOSTNAME is targeting to your **current local machine**, execute 'export SYNO_LOCAL_HOSTNAME=1' then rerun."
return 1
fi
fi
_debug "Creating temp admin user in Synology DSM..."
if synogroup --help | grep -q '\-\-memberadd '; then
_temp_admin_create "$SYNO_USERNAME" "$SYNO_PASSWORD"
synogroup --memberadd administrators "$SYNO_USERNAME" >/dev/null
elif synogroup --help | grep -q '\-\-member '; then
# For supporting DSM 6.x which only has `--member` parameter.
cur_admins=$(synogroup --get administrators | awk -F '[][]' '/Group Members/,0{if(NF>1)printf "%s ", $2}')
if [ -n "$cur_admins" ]; then
_temp_admin_create "$SYNO_USERNAME" "$SYNO_PASSWORD"
_secure_debug3 admin_users "$cur_admins$SYNO_USERNAME"
# shellcheck disable=SC2086
synogroup --member administrators $cur_admins $SYNO_USERNAME >/dev/null
else
_err "The tool synogroup may be broken, please set SYNO_USERNAME and SYNO_PASSWORD instead."
return 1
fi
else
_err "Unsupported synogroup tool detected, please set SYNO_USERNAME and SYNO_PASSWORD instead."
return 1
fi
# havig a workaround to temporary disable enforce 2FA-OTP, will restore
# it soon (after a single request), though if any accident occurs like
# unexpected interruption, this setting can be easily reverted manually.
otp_enforce_option=$(synogetkeyvalue /etc/synoinfo.conf otp_enforce_option)
if [ -n "$otp_enforce_option" ] && [ "${otp_enforce_option:-"none"}" != "none" ]; then
synosetkeyvalue /etc/synoinfo.conf otp_enforce_option none
_info "Enforcing 2FA-OTP has been disabled to complete temp admin authentication."
_info "Notice: it will be restored soon, if not, you can restore it manually via Control Panel."
_info "previous_otp_enforce_option" "$otp_enforce_option"
else
otp_enforce_option=""
fi
fi
response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes")
if [ -n "$SYNO_USE_TEMP_ADMIN" ] && [ -n "$otp_enforce_option" ]; then
synosetkeyvalue /etc/synoinfo.conf otp_enforce_option "$otp_enforce_option"
_info "Restored previous enforce 2FA-OTP option."
fi
_debug3 response "$response"
fi
fi
if [ -n "$SYNO_DID" ]; then
_H1="Cookie: did=$SYNO_DID"
export _H1
_debug3 H1 "${_H1}"
error_code=$(echo "$response" | grep '"error":' | grep -o '"code":[0-9]*' | grep -o '[0-9]*')
_debug2 error_code "$error_code"
# Account has 2FA-OTP enabled, since error 403 reported.
# https://global.download.synology.com/download/Document/Software/DeveloperGuide/Os/DSM/All/enu/DSM_Login_Web_API_Guide_enu.pdf
if [ "$error_code" == "403" ]; then
if [ -z "$SYNO_DEVICE_NAME" ]; then
printf "Enter device name or leave empty for default (CertRenewal): "
read -r SYNO_DEVICE_NAME
[ -n "$SYNO_DEVICE_NAME" ] || SYNO_DEVICE_NAME="CertRenewal"
fi
if [ -n "$SYNO_DEVICE_ID" ]; then
# Omit OTP code with SYNO_DEVICE_ID.
response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_DEVICE_NAME&device_id=$SYNO_DEVICE_ID")
_secure_debug3 response "$response"
else
# Require the OTP code if still unset.
if [ -z "$SYNO_OTP_CODE" ]; then
printf "Enter OTP code for user '%s': " "$SYNO_USERNAME"
read -r SYNO_OTP_CODE
fi
_secure_debug SYNO_OTP_CODE "${SYNO_OTP_CODE:-}"
if [ -z "$SYNO_OTP_CODE" ]; then
response='{"error":{"code":404}}'
else
response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_DEVICE_NAME&otp_code=$SYNO_OTP_CODE")
_secure_debug3 response "$response"
id_property='device_id'
[ "${api_version}" -gt '6' ] || id_property='did'
SYNO_DEVICE_ID=$(echo "$response" | grep "$id_property" | sed -n 's/.*"'$id_property'" *: *"\([^"]*\).*/\1/p')
_secure_debug2 SYNO_DEVICE_ID "$SYNO_DEVICE_ID"
fi
fi
error_code=$(echo "$response" | grep '"error":' | grep -o '"code":[0-9]*' | grep -o '[0-9]*')
_debug2 error_code "$error_code"
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")
token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p')
_debug3 response "$response"
_debug token "$token"
if [ -z "$token" ]; then
_err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme."
_err "Check your username and password."
_err "If two-factor authentication is enabled for the user, set SYNO_TOTP_SECRET."
if [ -n "$error_code" ]; then
if [ "$error_code" == "403" ] && [ -n "$SYNO_DEVICE_ID" ]; then
_cleardeployconf SYNO_DEVICE_ID
_err "Failed to authenticate with SYNO_DEVICE_ID (may expired or invalid), please try again in a new terminal window."
elif [ "$error_code" == "404" ]; then
_err "Failed to authenticate with provided 2FA-OTP code, please try again in a new terminal window."
elif [ "$error_code" == "406" ]; then
if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then
_err "Failed with unexcepted error, please report this by providing full log with '--debug 3'."
else
_err "Enforce auth with 2FA-OTP enabled, please configure the user to enable 2FA-OTP to continue."
fi
elif [ "$error_code" == "400" ]; then
_err "Failed to authenticate, no such account or incorrect password."
elif [ "$error_code" == "401" ]; then
_err "Failed to authenticate with a non-existent account."
elif [ "$error_code" == "408" ] || [ "$error_code" == "409" ] || [ "$error_code" == "410" ]; then
_err "Failed to authenticate, the account password has expired or must be changed."
else
_err "Failed to authenticate with error: $error_code."
fi
_temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME"
return 1
fi
sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p')
token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p')
_debug "Session ID" "$sid"
_debug SynoToken "$token"
if [ -z "$sid" ] || [ -z "$token" ]; then
# Still can't get necessary info even got no errors, may Synology have API updated?
_err "Unable to authenticate to $_base_url, you may report this by providing full log with '--debug 3'."
_temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME"
return 1
fi
_H1="X-SYNO-TOKEN: $token"
export _H1
_debug2 H1 "${_H1}"
# Now that we know the username and password are good, save them
_savedeployconf SYNO_Username "$SYNO_Username"
_savedeployconf SYNO_Password "$SYNO_Password"
_savedeployconf SYNO_DID "$SYNO_DID"
_savedeployconf SYNO_TOTP_SECRET "$SYNO_TOTP_SECRET"
# Now that we know the username and password are good, save them if not in temp admin mode.
if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then
_cleardeployconf SYNO_USERNAME
_cleardeployconf SYNO_PASSWORD
_cleardeployconf SYNO_DEVICE_ID
_cleardeployconf SYNO_DEVICE_NAME
_savedeployconf SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN"
_savedeployconf SYNO_LOCAL_HOSTNAME "$SYNO_LOCAL_HOSTNAME"
else
_savedeployconf SYNO_USERNAME "$SYNO_USERNAME"
_savedeployconf SYNO_PASSWORD "$SYNO_PASSWORD"
_savedeployconf SYNO_DEVICE_ID "$SYNO_DEVICE_ID"
_savedeployconf SYNO_DEVICE_NAME "$SYNO_DEVICE_NAME"
fi
_info "Getting certificates in Synology DSM"
_info "Getting certificates in Synology DSM..."
response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi")
_debug3 response "$response"
escaped_certificate="$(printf "%s" "$SYNO_Certificate" | sed 's/\([].*^$[]\)/\\\1/g;s/"/\\\\"/g')"
escaped_certificate="$(printf "%s" "$SYNO_CERTIFICATE" | sed 's/\([].*^$[]\)/\\\1/g;s/"/\\\\"/g')"
_debug escaped_certificate "$escaped_certificate"
id=$(echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\"id\":\"\([^\"]*\).*/\1/p")
_debug2 id "$id"
if [ -z "$id" ] && [ -z "${SYNO_Create:-}" ]; then
_err "Unable to find certificate: $SYNO_Certificate and \$SYNO_Create is not set"
error_code=$(echo "$response" | grep '"error":' | grep -o '"code":[0-9]*' | grep -o '[0-9]*')
_debug2 error_code "$error_code"
if [ -n "$error_code" ]; then
if [ "$error_code" -eq 105 ]; then
_err "Current user is not administrator and does not have sufficient permission for deploying."
else
_err "Failed to fetch certificate info: $error_code, please try again or contact Synology to learn more."
fi
_temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME"
return 1
fi
# we've verified this certificate description is a thing, so save it
_savedeployconf SYNO_Certificate "$SYNO_Certificate" "base64"
_migratedeployconf SYNO_Create SYNO_CREATE
_getdeployconf SYNO_CREATE
_debug2 SYNO_CREATE "$SYNO_CREATE"
_info "Generate form POST request"
if [ -z "$id" ] && [ -z "$SYNO_CREATE" ]; then
_err "Unable to find certificate: $SYNO_CERTIFICATE and \$SYNO_CREATE is not set."
_temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME"
return 1
fi
# We've verified this certificate description is a thing, so save it
_savedeployconf SYNO_CERTIFICATE "$SYNO_CERTIFICATE" "base64"
_info "Generating form POST request..."
nl="\0015\0012"
delim="--------------------------$(_utc_date | tr -d -- '-: ')"
content="--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")\0012"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"cert\"; filename=\"$(basename "$_ccert")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ccert")\0012"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"inter_cert\"; filename=\"$(basename "$_cca")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cca")\0012"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"id\"${nl}${nl}$id"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_Certificate}"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_CERTIFICATE}"
if echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then
_debug2 default "this is the default certificate"
_debug2 default "This is the default certificate"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"as_default\"${nl}${nl}true"
else
_debug2 default "this is NOT the default certificate"
_debug2 default "This is NOT the default certificate"
fi
content="$content${nl}--$delim--${nl}"
content="$(printf "%b_" "$content")"
content="${content%_}" # protect trailing \n
_info "Upload certificate to the Synology DSM"
_info "Upload certificate to the Synology DSM."
response=$(_post "$content" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token&_sid=$sid" "" "POST" "multipart/form-data; boundary=${delim}")
_debug3 response "$response"
if ! echo "$response" | grep '"error":' >/dev/null; then
if echo "$response" | grep '"restart_httpd":true' >/dev/null; then
_info "http services were restarted"
_info "Restart HTTP services succeeded."
else
_info "http services were NOT restarted"
_info "Restart HTTP services not necessary."
fi
_temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME"
_logout
return 0
else
_err "Unable to update certificate, error code $response"
_temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME"
_err "Unable to update certificate, got error response: $response."
_logout
return 1
fi
}
#################### Private functions below ##################################
_logout() {
# Logout CERT user only to not occupy a permanent session, e.g. in DSM's "Connected Users" widget (based on previous variables)
response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=logout&_sid=$sid")
_debug3 response "$response"
}
_temp_admin_create() {
_username="$1"
_password="$2"
synouser --del "$_username" >/dev/null 2>/dev/null
synouser --add "$_username" "$_password" "" 0 "" 0 >/dev/null
}
_temp_admin_cleanup() {
_flag=$1
_username=$2
if [ -n "${_flag}" ]; then
_debug "Cleanuping temp admin info..."
synouser --del "$_username" >/dev/null
fi
}
#_cleardeployconf key
_cleardeployconf() {
_cleardomainconf "SAVED_$1"
}
# key
_check2cleardeployconfexp() {
_key="$1"
_clear_key="CLEAR_$_key"
# Clear saved settings if explicitly requested
if [ -n "$(eval echo \$"$_clear_key")" ]; then
_debug2 "$_key: value cleared from config, exported value will be ignored."
_cleardeployconf "$_key"
eval "$_key"=
export "$_key"=
eval SAVED_"$_key"=
export SAVED_"$_key"=
fi
}
+112 -42
View File
@@ -9,7 +9,7 @@
#
# Following environment variables must be set:
#
# export DEPLOY_TRUENAS_APIKEY="<API_KEY_GENERATED_IN_THE_WEB_UI"
# export DEPLOY_TRUENAS_APIKEY="<API_KEY_GENERATED_IN_THE_WEB_UI>"
#
# The following environmental variables may be set if you don't like their
# default values:
@@ -64,6 +64,20 @@ truenas_deploy() {
_response=$(_get "$_api_url/system/state")
_info "TrueNAS system state: $_response."
_info "Getting TrueNAS version"
_response=$(_get "$_api_url/system/version")
if echo "$_response" | grep -q "SCALE"; then
_truenas_os=$(echo "$_response" | cut -d '-' -f 2)
_truenas_version=$(echo "$_response" | cut -d '-' -f 3 | tr -d '"' | cut -d '.' -f 1,2)
else
_truenas_os="unknown"
_truenas_version="unknown"
fi
_info "Detected TrueNAS system os: $_truenas_os"
_info "Detected TrueNAS system version: $_truenas_version"
if [ -z "$_response" ]; then
_err "Unable to authenticate to $_api_url."
_err 'Check your connection settings are correct, e.g.'
@@ -115,27 +129,106 @@ truenas_deploy() {
_debug3 _activate_result "$_activate_result"
_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: ,')
_truenas_version_23_10="23.10"
_truenas_version_24_10="24.10"
if [ "$_webdav_cert_id" = "$_active_cert_id" ]; then
_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 | grep '"certssl":' | sed -n 's/.*: \([0-9]\{1,\}\),\{0,1\}$/\1/p')
if [ "$_webdav_new_cert_id" -eq "$_cert_id" ]; then
_info "WebDAV certificate updated successfully"
else
_err "Unable to set WebDAV certificate"
_debug3 _activate_webdav_cert "$_activate_webdav_cert"
_check_version=$(printf "%s\n%s" "$_truenas_version_23_10" "$_truenas_version" | sort -V | head -n 1)
if [ "$_truenas_os" != "SCALE" ] || [ "$_check_version" != "$_truenas_version_23_10" ]; then
_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 "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 | grep '"certssl":' | sed -n 's/.*: \([0-9]\{1,\}\),\{0,1\}$/\1/p')
if [ "$_webdav_new_cert_id" -eq "$_cert_id" ]; then
_info "WebDAV certificate updated successfully"
else
_err "Unable to set WebDAV certificate"
_debug3 _activate_webdav_cert "$_activate_webdav_cert"
_debug3 _webdav_new_cert_id "$_webdav_new_cert_id"
return 1
fi
_debug3 _webdav_new_cert_id "$_webdav_new_cert_id"
return 1
else
_info "WebDAV certificate is not configured or is not the same as TrueNAS web UI"
fi
_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
fi
if [ "$_truenas_os" = "SCALE" ]; then
_check_version=$(printf "%s\n%s" "$_truenas_version_24_10" "$_truenas_version" | sort -V | head -n 1)
if [ "$_check_version" != "$_truenas_version_24_10" ]; then
_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
else
_info "Checking if any app is using the same certificate as TrueNAS web UI. Tool 'jq' is required"
if _exists jq; then
_info "Query all apps"
_app_list=$(_get "$_api_url/app")
_app_id_list=$(printf "%s" "$_app_list" | jq -r '.[].name')
_app_length=$(echo "$_app_id_list" | wc -l)
_info "Found $_app_length apps"
_info "Checking for each app if an update is needed"
for i in $(seq 1 "$_app_length"); do
_app_id=$(echo "$_app_id_list" | sed -n "${i}p")
_app_config="$(_post "\"$_app_id\"" "$_api_url/app/config" "" "POST" "application/json")"
# Check if the app use the same certificate TrueNAS web UI
_app_active_cert_config=$(echo "$_app_config" | tr -d '\000-\037' | _json_decode | jq -r ".ix_certificates[\"$_active_cert_id\"]")
if [ "$_app_active_cert_config" != "null" ]; then
_info "Updating certificate from $_active_cert_id to $_cert_id for app: $_app_id"
#Replace the old certificate id with the new one in path
_update_app_result="$(_post "{\"values\" : { \"network\": { \"certificate_id\": $_cert_id } } }" "$_api_url/app/id/$_app_id" "" "PUT" "application/json")"
_debug3 _update_app_result "$_update_app_result"
fi
done
else
_info "Tool 'jq' does not exists, skip app checking"
fi
fi
_debug3 _webdav_new_cert_id "$_webdav_new_cert_id"
else
_info "WebDAV certificate is not configured or is not the same as TrueNAS web UI"
fi
_info "Checking if FTP certificate is the same as the TrueNAS web UI"
@@ -161,29 +254,6 @@ truenas_deploy() {
_info "FTP certificate is not configured or is not the same as TrueNAS web UI"
fi
_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 "Deleting old certificate"
_delete_result="$(_post "" "$_api_url/certificate/id/$_active_cert_id" "" "DELETE" "application/json")"
+343
View File
@@ -0,0 +1,343 @@
#!/usr/bin/env sh
# TrueNAS deploy script for SCALE/CORE using websocket
# It is recommend to use a wildcard certificate
#
# Websocket Documentation: https://www.truenas.com/docs/api/scale_websocket_api.html
#
# Tested with TrueNAS Scale - Electric Eel 24.10
# Changes certificate in the following services:
# - Web UI
# - FTP
# - iX Apps
#
# The following environment variables must be set:
# ------------------------------------------------
#
# # API KEY
# # Use the folowing URL to create a new API token: <TRUENAS_HOSTNAME OR IP>/ui/apikeys
# export DEPLOY_TRUENAS_APIKEY="<API_KEY_GENERATED_IN_THE_WEB_UI"
#
### Private functions
# Call websocket method
# Usage:
# _ws_response=$(_ws_call "math.dummycalc" "'{"x": 4, "y": 5}'")
# _info "$_ws_response"
#
# Output:
# {"z": 9}
#
# Arguments:
# $@ - midclt arguments for call
#
# Returns:
# JSON/JOBID
_ws_call() {
_debug "_ws_call arg1" "$1"
_debug "_ws_call arg2" "$2"
_debug "_ws_call arg3" "$3"
if [ $# -eq 3 ]; then
_ws_response=$(midclt --uri "$_ws_uri" -K "$DEPLOY_TRUENAS_APIKEY" call "$1" "$2" "$3")
fi
if [ $# -eq 2 ]; then
_ws_response=$(midclt --uri "$_ws_uri" -K "$DEPLOY_TRUENAS_APIKEY" call "$1" "$2")
fi
if [ $# -eq 1 ]; then
_ws_response=$(midclt --uri "$_ws_uri" -K "$DEPLOY_TRUENAS_APIKEY" call "$1")
fi
_debug "_ws_response" "$_ws_response"
printf "%s" "$_ws_response"
return 0
}
# Upload certificate with webclient api
_ws_upload_cert() {
/usr/bin/env python - <<EOF
import sys
from truenas_api_client import Client
with Client(uri="$_ws_uri") as c:
### Login with API key
print("I:Trying to upload new certificate...")
ret = c.call("auth.login_with_api_key", "${DEPLOY_TRUENAS_APIKEY}")
if ret:
### upload certificate
with open('$1', 'r') as file:
fullchain = file.read()
with open('$2', 'r') as file:
privatekey = file.read()
ret = c.call("certificate.create", {"name": "$3", "create_type": "CERTIFICATE_CREATE_IMPORTED", "certificate": fullchain, "privatekey": privatekey}, job=True)
print("R:" + str(ret["id"]))
sys.exit(0)
else:
print("R:0")
print("E:_ws_upload_cert error!")
sys.exit(7)
EOF
return $?
}
# Check argument is a number
# Usage:
#
# Output:
# n/a
#
# Arguments:
# $1 - Anything
#
# Returns:
# 0: true
# 1: false
_ws_check_jobid() {
case "$1" in
[0-9]*)
return 0
;;
esac
return 1
}
# Wait for job to finish and return result as JSON
# Usage:
# _ws_result=$(_ws_get_job_result "$_ws_jobid")
# _new_certid=$(printf "%s" "$_ws_result" | jq -r '."id"')
#
# Output:
# JSON result of the job
#
# Arguments:
# $1 - JobID
#
# Returns:
# n/a
_ws_get_job_result() {
while true; do
_sleep 2
_ws_response=$(_ws_call "core.get_jobs" "[[\"id\", \"=\", $1]]")
if [ "$(printf "%s" "$_ws_response" | jq -r '.[]."state"')" != "RUNNING" ]; then
_ws_result="$(printf "%s" "$_ws_response" | jq '.[]."result"')"
_debug "_ws_result" "$_ws_result"
printf "%s" "$_ws_result"
_ws_error="$(printf "%s" "$_ws_response" | jq '.[]."error"')"
if [ "$_ws_error" != "null" ]; then
_err "Job $1 failed:"
_err "$_ws_error"
return 7
fi
break
fi
done
return 0
}
########################
### Public functions ###
########################
# truenas_ws_deploy
#
# Deploy new certificate to TrueNAS services
#
# Arguments
# 1: Domain
# 2: Key-File
# 3: Certificate-File
# 4: CA-File
# 5: FullChain-File
# Returns:
# 0: Success
# 1: Missing API Key
# 2: TrueNAS not ready
# 3: Not a JobID
# 4: FTP cert error
# 5: WebUI cert error
# 6: Job error
# 7: WS call error
#
truenas_ws_deploy() {
_domain="$1"
_file_key="$2"
_file_cert="$3"
_file_ca="$4"
_file_fullchain="$5"
_debug _domain "$_domain"
_debug _file_key "$_file_key"
_debug _file_cert "$_file_cert"
_debug _file_ca "$_file_ca"
_debug _file_fullchain "$_file_fullchain"
########## Environment check
_info "Checking environment variables..."
_getdeployconf DEPLOY_TRUENAS_APIKEY
_getdeployconf DEPLOY_TRUENAS_HOSTNAME
_getdeployconf DEPLOY_TRUENAS_PROTOCOL
# Check API Key
if [ -z "$DEPLOY_TRUENAS_APIKEY" ]; then
_err "TrueNAS API key not found, please set the DEPLOY_TRUENAS_APIKEY environment variable."
return 1
fi
# Check Hostname, default to localhost if not set
if [ -z "$DEPLOY_TRUENAS_HOSTNAME" ]; then
_info "TrueNAS hostname not set. Using 'localhost'."
DEPLOY_TRUENAS_HOSTNAME="localhost"
fi
# Check protocol, default to ws if not set
if [ -z "$DEPLOY_TRUENAS_PROTOCOL" ]; then
_info "TrueNAS protocol not set. Using 'ws'."
DEPLOY_TRUENAS_PROTOCOL="ws"
fi
_ws_uri="$DEPLOY_TRUENAS_PROTOCOL://$DEPLOY_TRUENAS_HOSTNAME/websocket"
_debug2 DEPLOY_TRUENAS_HOSTNAME "$DEPLOY_TRUENAS_HOSTNAME"
_debug2 DEPLOY_TRUENAS_PROTOCOL "$DEPLOY_TRUENAS_PROTOCOL"
_debug _ws_uri "$_ws_uri"
_secure_debug2 DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY"
_info "Environment variables: OK"
########## Health check
_info "Checking TrueNAS health..."
_ws_response=$(_ws_call "system.ready" | tr '[:lower:]' '[:upper:]')
_ws_ret=$?
if [ $_ws_ret -gt 0 ]; then
_err "Error calling system.ready:"
_err "$_ws_response"
return $_ws_ret
fi
if [ "$_ws_response" != "TRUE" ]; then
_err "TrueNAS is not ready."
_err "Please check environment variables DEPLOY_TRUENAS_APIKEY, DEPLOY_TRUENAS_HOSTNAME and DEPLOY_TRUENAS_PROTOCOL."
_err "Verify API key."
return 2
fi
_savedeployconf DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY"
_savedeployconf DEPLOY_TRUENAS_HOSTNAME "$DEPLOY_TRUENAS_HOSTNAME"
_savedeployconf DEPLOY_TRUENAS_PROTOCOL "$DEPLOY_TRUENAS_PROTOCOL"
_info "TrueNAS health: OK"
########## System info
_info "Gather system info..."
_ws_response=$(_ws_call "system.info")
_truenas_version=$(printf "%s" "$_ws_response" | jq -r '."version"')
_info "TrueNAS version: $_truenas_version"
########## Gather current certificate
_info "Gather current WebUI certificate..."
_ws_response="$(_ws_call "system.general.config")"
_ui_certificate_id=$(printf "%s" "$_ws_response" | jq -r '."ui_certificate"."id"')
_ui_certificate_name=$(printf "%s" "$_ws_response" | jq -r '."ui_certificate"."name"')
_info "Current WebUI certificate ID: $_ui_certificate_id"
_info "Current WebUI certificate name: $_ui_certificate_name"
########## Upload new certificate
_info "Upload new certificate..."
_certname="acme_$(_utc_date | tr -d '\-\:' | tr ' ' '_')"
_info "New WebUI certificate name: $_certname"
_debug _certname "$_certname"
_ws_out=$(_ws_upload_cert "$_file_fullchain" "$_file_key" "$_certname")
echo "$_ws_out" | while IFS= read -r LINE; do
case "$LINE" in
I:*)
_info "${LINE#I:}"
;;
D:*)
_debug "${LINE#D:}"
;;
E*)
_err "${LINE#E:}"
;;
*) ;;
esac
done
_new_certid=$(echo "$_ws_out" | grep 'R:' | cut -d ':' -f 2)
_info "New certificate ID: $_new_certid"
########## FTP
_info "Replace FTP certificate..."
_ws_response=$(_ws_call "ftp.update" "{\"ssltls_certificate\": $_new_certid}")
_ftp_certid=$(printf "%s" "$_ws_response" | jq -r '."ssltls_certificate"')
if [ "$_ftp_certid" != "$_new_certid" ]; then
_err "Cannot set FTP certificate."
_debug "_ws_response" "$_ws_response"
return 4
fi
########## ix Apps (SCALE only)
_info "Replace app certificates..."
_ws_response=$(_ws_call "app.query")
for _app_name in $(printf "%s" "$_ws_response" | jq -r '.[]."name"'); do
_info "Checking app $_app_name..."
_ws_response=$(_ws_call "app.config" "$_app_name")
if [ "$(printf "%s" "$_ws_response" | jq -r '."network" | has("certificate_id")')" = "true" ]; then
_info "App has certificate option, setup new certificate..."
_info "App will be redeployed after updating the certificate."
_ws_jobid=$(_ws_call "app.update" "$_app_name" "{\"values\": {\"network\": {\"certificate_id\": $_new_certid}}}")
_debug "_ws_jobid" "$_ws_jobid"
if ! _ws_check_jobid "$_ws_jobid"; then
_err "No JobID returned from websocket method."
return 3
fi
_ws_result=$(_ws_get_job_result "$_ws_jobid")
_ws_ret=$?
if [ $_ws_ret -gt 0 ]; then
return $_ws_ret
fi
_debug "_ws_result" "$_ws_result"
_info "App certificate replaced."
else
_info "App has no certificate option, skipping..."
fi
done
########## WebUI
_info "Replace WebUI certificate..."
_ws_response=$(_ws_call "system.general.update" "{\"ui_certificate\": $_new_certid}")
_changed_certid=$(printf "%s" "$_ws_response" | jq -r '."ui_certificate"."id"')
if [ "$_changed_certid" != "$_new_certid" ]; then
_err "WebUI certificate change error.."
return 5
else
_info "WebUI certificate replaced."
fi
_info "Restarting WebUI..."
_ws_response=$(_ws_call "system.general.ui_restart")
_info "Waiting for UI restart..."
_sleep 15
########## Certificates
_info "Deleting old certificate..."
_ws_jobid=$(_ws_call "certificate.delete" "$_ui_certificate_id")
if ! _ws_check_jobid "$_ws_jobid"; then
_err "No JobID returned from websocket method."
return 3
fi
_ws_result=$(_ws_get_job_result "$_ws_jobid")
_ws_ret=$?
if [ $_ws_ret -gt 0 ]; then
return $_ws_ret
fi
_info "Have a nice day...bye!"
}
+120 -27
View File
@@ -5,6 +5,15 @@
# - self-hosted Unifi Controller
# - Unifi Cloud Key (Gen1/2/2+)
# - Unifi Cloud Key running UnifiOS (v2.0.0+, Gen2/2+ only)
# - Unifi Dream Machine
# This has not been tested on other "all-in-one" devices such as
# UDM Pro or Unifi Express.
#
# OS Version v2.0.0+
# Network Application version 7.0.0+
# OS version ~3.1 removed java and keytool from the UnifiOS.
# Using PKCS12 format keystore appears to work fine.
#
# Please report bugs to https://github.com/acmesh-official/acme.sh/issues/3359
#returns 0 means success, otherwise error.
@@ -21,7 +30,9 @@
# Keystore password (built into Unifi Controller, not a user-set password):
#DEPLOY_UNIFI_KEYPASS="aircontrolenterprise"
# Command to restart Unifi Controller:
#DEPLOY_UNIFI_RELOAD="service unifi restart"
# DEPLOY_UNIFI_RELOAD="systemctl restart unifi"
# System Properties file location for controller
#DEPLOY_UNIFI_SYSTEM_PROPERTIES="/usr/lib/unifi/data/system.properties"
#
# Settings for Unifi Cloud Key Gen1 (nginx admin pages):
# Directory where cloudkey.crt and cloudkey.key live:
@@ -34,7 +45,7 @@
# Directory where unifi-core.crt and unifi-core.key live:
#DEPLOY_UNIFI_CORE_CONFIG="/data/unifi-core/config/"
# Command to restart unifi-core:
#DEPLOY_UNIFI_RELOAD="systemctl restart unifi-core"
# DEPLOY_UNIFI_OS_RELOAD="systemctl restart unifi-core"
#
# At least one of DEPLOY_UNIFI_KEYSTORE, DEPLOY_UNIFI_CLOUDKEY_CERTDIR,
# or DEPLOY_UNIFI_CORE_CONFIG must exist to receive the deployed certs.
@@ -60,12 +71,16 @@ unifi_deploy() {
_getdeployconf DEPLOY_UNIFI_CLOUDKEY_CERTDIR
_getdeployconf DEPLOY_UNIFI_CORE_CONFIG
_getdeployconf DEPLOY_UNIFI_RELOAD
_getdeployconf DEPLOY_UNIFI_SYSTEM_PROPERTIES
_getdeployconf DEPLOY_UNIFI_OS_RELOAD
_debug2 DEPLOY_UNIFI_KEYSTORE "$DEPLOY_UNIFI_KEYSTORE"
_debug2 DEPLOY_UNIFI_KEYPASS "$DEPLOY_UNIFI_KEYPASS"
_debug2 DEPLOY_UNIFI_CLOUDKEY_CERTDIR "$DEPLOY_UNIFI_CLOUDKEY_CERTDIR"
_debug2 DEPLOY_UNIFI_CORE_CONFIG "$DEPLOY_UNIFI_CORE_CONFIG"
_debug2 DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD"
_debug2 DEPLOY_UNIFI_OS_RELOAD "$DEPLOY_UNIFI_OS_RELOAD"
_debug2 DEPLOY_UNIFI_SYSTEM_PROPERTIES "$DEPLOY_UNIFI_SYSTEM_PROPERTIES"
# Space-separated list of environments detected and installed:
_services_updated=""
@@ -74,14 +89,16 @@ unifi_deploy() {
_reload_cmd=""
# Unifi Controller environment (self hosted or any Cloud Key) --
# auto-detect by file /usr/lib/unifi/data/keystore:
# auto-detect by file /usr/lib/unifi/data/keystore
_unifi_keystore="${DEPLOY_UNIFI_KEYSTORE:-/usr/lib/unifi/data/keystore}"
if [ -f "$_unifi_keystore" ]; then
_info "Installing certificate for Unifi Controller (Java keystore)"
_debug _unifi_keystore "$_unifi_keystore"
if ! _exists keytool; then
_err "keytool not found"
return 1
_do_keytool=0
_info "Installing certificate for Unifi Controller (PKCS12 keystore)."
else
_do_keytool=1
_info "Installing certificate for Unifi Controller (Java keystore)"
fi
if [ ! -w "$_unifi_keystore" ]; then
_err "The file $_unifi_keystore is not writable, please change the permission."
@@ -92,6 +109,7 @@ unifi_deploy() {
_debug "Generate import pkcs12"
_import_pkcs12="$(_mktemp)"
_debug "_toPkcs $_import_pkcs12 $_ckey $_ccert $_cca $_unifi_keypass unifi root"
_toPkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca" "$_unifi_keypass" unifi root
# shellcheck disable=SC2181
if [ "$?" != "0" ]; then
@@ -99,22 +117,79 @@ unifi_deploy() {
return 1
fi
_debug "Import into keystore: $_unifi_keystore"
if keytool -importkeystore \
-deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \
-srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \
-alias unifi -noprompt; then
_debug "Import keystore success!"
rm "$_import_pkcs12"
# Save the existing keystore in case something goes wrong.
mv -f "${_unifi_keystore}" "${_unifi_keystore}"_original
_info "Previous keystore saved to ${_unifi_keystore}_original."
if [ "$_do_keytool" -eq 1 ]; then
_debug "Import into keystore: $_unifi_keystore"
if keytool -importkeystore \
-deststorepass "$_unifi_keypass" -destkeypass "$_unifi_keypass" -destkeystore "$_unifi_keystore" \
-srckeystore "$_import_pkcs12" -srcstoretype PKCS12 -srcstorepass "$_unifi_keypass" \
-alias unifi -noprompt; then
_debug "Import keystore success!"
else
_err "Error importing into Unifi Java keystore."
_err "Please re-run with --debug and report a bug."
_info "Restoring original keystore."
mv -f "${_unifi_keystore}"_original "${_unifi_keystore}"
rm "$_import_pkcs12"
return 1
fi
else
_err "Error importing into Unifi Java keystore."
_err "Please re-run with --debug and report a bug."
rm "$_import_pkcs12"
return 1
_debug "Copying new keystore to $_unifi_keystore"
cp -f "$_import_pkcs12" "$_unifi_keystore"
fi
if systemctl -q is-active unifi; then
_reload_cmd="${_reload_cmd:+$_reload_cmd && }service unifi restart"
# correct file ownership according to the directory, the keystore is placed in
_unifi_keystore_dir=$(dirname "${_unifi_keystore}")
# shellcheck disable=SC2012
_unifi_keystore_dir_owner=$(ls -ld "${_unifi_keystore_dir}" | awk '{print $3}')
# shellcheck disable=SC2012
_unifi_keystore_owner=$(ls -l "${_unifi_keystore}" | awk '{print $3}')
if ! [ "${_unifi_keystore_owner}" = "${_unifi_keystore_dir_owner}" ]; then
_debug "Changing keystore owner to ${_unifi_keystore_dir_owner}"
chown "$_unifi_keystore_dir_owner" "${_unifi_keystore}" >/dev/null 2>&1 # fail quietly if we're not running as root
fi
# Update unifi service for certificate cipher compatibility
_unifi_system_properties="${DEPLOY_UNIFI_SYSTEM_PROPERTIES:-/usr/lib/unifi/data/system.properties}"
if ${ACME_OPENSSL_BIN:-openssl} pkcs12 \
-in "$_import_pkcs12" \
-password pass:aircontrolenterprise \
-nokeys | ${ACME_OPENSSL_BIN:-openssl} x509 -text \
-noout | grep -i "signature" | grep -iq ecdsa >/dev/null 2>&1; then
if [ -f "$(dirname "${DEPLOY_UNIFI_KEYSTORE}")/system.properties" ]; then
_unifi_system_properties="$(dirname "${DEPLOY_UNIFI_KEYSTORE}")/system.properties"
else
_unifi_system_properties="/usr/lib/unifi/data/system.properties"
fi
if [ -f "${_unifi_system_properties}" ]; then
cp -f "${_unifi_system_properties}" "${_unifi_system_properties}"_original
_info "Updating system configuration for cipher compatibility."
_info "Saved original system config to ${_unifi_system_properties}_original"
sed -i '/unifi\.https\.ciphers/d' "${_unifi_system_properties}"
echo "unifi.https.ciphers=ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES128-GCM-SHA256" >>"${_unifi_system_properties}"
sed -i '/unifi\.https\.sslEnabledProtocols/d' "${_unifi_system_properties}"
echo "unifi.https.sslEnabledProtocols=TLSv1.3,TLSv1.2" >>"${_unifi_system_properties}"
_info "System configuration updated."
fi
fi
rm "$_import_pkcs12"
# Restarting unifi-core will bring up unifi, doing it out of order results in
# a certificate error, and breaks wifiman.
# Restart if we aren't doing Unifi OS (e.g. unifi-core service), otherwise stop for later restart.
_unifi_reload="${DEPLOY_UNIFI_RELOAD:-systemctl restart unifi}"
if [ ! -f "${DEPLOY_UNIFI_CORE_CONFIG:-/data/unifi-core/config}/unifi-core.key" ]; then
_reload_cmd="${_reload_cmd:+$_reload_cmd && }$_unifi_reload"
else
_info "Stopping Unifi Controller for later restart."
_unifi_stop=$(echo "${_unifi_reload}" | sed -e 's/restart/stop/')
$_unifi_stop
_reload_cmd="${_reload_cmd:+$_reload_cmd && }$_unifi_reload"
_info "Unifi Controller stopped."
fi
_services_updated="${_services_updated} unifi"
_info "Install Unifi Controller certificate success!"
@@ -134,13 +209,24 @@ unifi_deploy() {
return 1
fi
# Cloud Key expects to load the keystore from /etc/ssl/private/unifi.keystore.jks.
# Normally /usr/lib/unifi/data/keystore is a symlink there (so the keystore was
# updated above), but if not, we don't know how to handle this installation:
if ! cmp -s "$_unifi_keystore" "${_cloudkey_certdir}/unifi.keystore.jks"; then
_err "Unsupported Cloud Key configuration: keystore not found at '${_cloudkey_certdir}/unifi.keystore.jks'"
return 1
# It appears that unifi won't start if this is a symlink, so we'll copy it instead.
# if ! cmp -s "$_unifi_keystore" "${_cloudkey_certdir}/unifi.keystore.jks"; then
# _err "Unsupported Cloud Key configuration: keystore not found at '${_cloudkey_certdir}/unifi.keystore.jks'"
# return 1
# fi
_info "Updating ${_cloudkey_certdir}/unifi.keystore.jks"
if [ -e "${_cloudkey_certdir}/unifi.keystore.jks" ]; then
if [ -L "${_cloudkey_certdir}/unifi.keystore.jks" ]; then
rm -f "${_cloudkey_certdir}/unifi.keystore.jks"
else
mv "${_cloudkey_certdir}/unifi.keystore.jks" "${_cloudkey_certdir}/unifi.keystore.jks_original"
fi
fi
cp "${_unifi_keystore}" "${_cloudkey_certdir}/unifi.keystore.jks"
cat "$_cfullchain" >"${_cloudkey_certdir}/cloudkey.crt"
cat "$_ckey" >"${_cloudkey_certdir}/cloudkey.key"
(cd "$_cloudkey_certdir" && tar -cf cert.tar cloudkey.crt cloudkey.key unifi.keystore.jks)
@@ -165,12 +251,17 @@ unifi_deploy() {
return 1
fi
# Save the existing certs in case something goes wrong.
cp -f "${_unifi_core_config}"/unifi-core.crt "${_unifi_core_config}"/unifi-core_original.crt
cp -f "${_unifi_core_config}"/unifi-core.key "${_unifi_core_config}"/unifi-core_original.key
_info "Previous certificate and key saved to ${_unifi_core_config}/unifi-core_original.crt.key."
cat "$_cfullchain" >"${_unifi_core_config}/unifi-core.crt"
cat "$_ckey" >"${_unifi_core_config}/unifi-core.key"
if systemctl -q is-active unifi-core; then
_reload_cmd="${_reload_cmd:+$_reload_cmd && }systemctl restart unifi-core"
fi
_unifi_os_reload="${DEPLOY_UNIFI_OS_RELOAD:-systemctl restart unifi-core}"
_reload_cmd="${_reload_cmd:+$_reload_cmd && }$_unifi_os_reload"
_info "Install UnifiOS certificate success!"
_services_updated="${_services_updated} unifi-core"
elif [ "$DEPLOY_UNIFI_CORE_CONFIG" ]; then
@@ -209,6 +300,8 @@ unifi_deploy() {
_savedeployconf DEPLOY_UNIFI_CLOUDKEY_CERTDIR "$DEPLOY_UNIFI_CLOUDKEY_CERTDIR"
_savedeployconf DEPLOY_UNIFI_CORE_CONFIG "$DEPLOY_UNIFI_CORE_CONFIG"
_savedeployconf DEPLOY_UNIFI_RELOAD "$DEPLOY_UNIFI_RELOAD"
_savedeployconf DEPLOY_UNIFI_OS_RELOAD "$DEPLOY_UNIFI_OS_RELOAD"
_savedeployconf DEPLOY_UNIFI_SYSTEM_PROPERTIES "$DEPLOY_UNIFI_SYSTEM_PROPERTIES"
return 0
}
+145 -22
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,34 +48,154 @@ 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")
_ccert=$(sed -z 's/\n/\\n/g' <"$3")
_cca=$(sed -z 's/\n/\\n/g' <"$4")
_cfullchain=$(sed -z 's/\n/\\n/g' <"$5")
_ckey=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$2")
_ccert=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$3")
_cca=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$4")
_cfullchain=$(sed -e ':a' -e N -e '$ ! ba' -e '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_KV_V2" ]; then
_post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL"
else
_post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL"
if [ -n "$VAULT_RENEW_TOKEN" ]; then
URL="$VAULT_ADDR/v1/auth/token/renew-self"
_info "Renew the Vault token to default TTL"
_response=$(_post "" "$URL")
if [ "$?" != "0" ]; then
_err "Failed to renew the Vault token"
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"
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"
if echo "$_response" | grep -q '"errors":\['; then
_err "Failed to renew the Vault token: $_response"
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
_response=$(_post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL")
if [ "$?" != "0" ]; then return 1; fi
if echo "$_response" | grep -q '"errors":\['; then
_err "Vault error: $_response"
return 1
fi
else
_response=$(_post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL")
if [ "$?" != "0" ]; then return 1; fi
if echo "$_response" | grep -q '"errors":\['; then
_err "Vault error: $_response"
return 1
fi
fi
else
if [ -n "$VAULT_KV_V2" ]; then
_info "Writing certificate to $URL/cert.pem"
_response=$(_post "{\"data\": {\"value\": \"$_ccert\"}}" "$URL/cert.pem")
if [ "$?" != "0" ]; then return 1; fi
if echo "$_response" | grep -q '"errors":\['; then
_err "Vault error writing cert.pem: $_response"
return 1
fi
_info "Writing key to $URL/cert.key"
_response=$(_post "{\"data\": {\"value\": \"$_ckey\"}}" "$URL/cert.key")
if [ "$?" != "0" ]; then return 1; fi
if echo "$_response" | grep -q '"errors":\['; then
_err "Vault error writing cert.key: $_response"
return 1
fi
_info "Writing CA certificate to $URL/ca.pem"
_response=$(_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/ca.pem")
if [ "$?" != "0" ]; then return 1; fi
if echo "$_response" | grep -q '"errors":\['; then
_err "Vault error writing ca.pem: $_response"
return 1
fi
_info "Writing full-chain certificate to $URL/fullchain.pem"
_response=$(_post "{\"data\": {\"value\": \"$_cfullchain\"}}" "$URL/fullchain.pem")
if [ "$?" != "0" ]; then return 1; fi
if echo "$_response" | grep -q '"errors":\['; then
_err "Vault error writing fullchain.pem: $_response"
return 1
fi
else
_info "Writing certificate to $URL/cert.pem"
_response=$(_post "{\"value\": \"$_ccert\"}" "$URL/cert.pem")
if [ "$?" != "0" ]; then return 1; fi
if echo "$_response" | grep -q '"errors":\['; then
_err "Vault error writing cert.pem: $_response"
return 1
fi
_info "Writing key to $URL/cert.key"
_response=$(_post "{\"value\": \"$_ckey\"}" "$URL/cert.key")
if [ "$?" != "0" ]; then return 1; fi
if echo "$_response" | grep -q '"errors":\['; then
_err "Vault error writing cert.key: $_response"
return 1
fi
_info "Writing CA certificate to $URL/ca.pem"
_response=$(_post "{\"value\": \"$_cca\"}" "$URL/ca.pem")
if [ "$?" != "0" ]; then return 1; fi
if echo "$_response" | grep -q '"errors":\['; then
_err "Vault error writing ca.pem: $_response"
return 1
fi
_info "Writing full-chain certificate to $URL/fullchain.pem"
_response=$(_post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem")
if [ "$?" != "0" ]; then return 1; fi
if echo "$_response" | grep -q '"errors":\['; then
_err "Vault error writing fullchain.pem: $_response"
return 1
fi
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
_response=$(_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/chain.pem")
if [ "$?" != "0" ]; then return 1; fi
if echo "$_response" | grep -q '"errors":\['; then
_err "Vault error writing chain.pem: $_response"
return 1
fi
else
_response=$(_post "{\"value\": \"$_cca\"}" "$URL/chain.pem")
if [ "$?" != "0" ]; then return 1; fi
if echo "$_response" | grep -q '"errors":\['; then
_err "Vault error writing chain.pem: $_response"
return 1
fi
fi
fi
fi
}
+45 -2
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
}
+1 -1
View File
@@ -106,5 +106,5 @@ vsftpd_deploy() {
fi
return 1
fi
return 0
}
+500
View File
@@ -0,0 +1,500 @@
#!/usr/bin/env sh
# Deploy certificates to Zyxel GS1900 series switches
#
# This script uses the https web administration interface in order
# to upload updated certificates to Zyxel GS1900 series switches.
# Only a few models have been tested but untested switches from the
# same model line may work as well. If you test and confirm a switch
# as working please submit a pull request updating this compatibility
# list!
#
# Known Issues:
# 1. This is a consumer grade switch and is a bit underpowered
# the longer the RSA key size the slower your switch web UI
# will be. RSA 2048 will work, RSA 4096 will work but you may
# experience performance problems.
# 2. You must use RSA certificates. The switch will reject EC-256
# and EC-384 certificates in firmware 2.80
# See: https://community.zyxel.com/en/discussion/21506/bug-cannot-import-ssl-cert-on-gs1900-8-and-gs1900-24e-firmware-v2-80/
#
# Current GS1900 Switch Compatibility:
# GS1900-8 - Working as of firmware V2.80
# GS1900-8HP - Untested
# GS1900-10HP - Untested
# GS1900-16 - Untested
# GS1900-24 - Untested
# GS1900-24E - Working as of firmware V2.80
# GS1900-24EP - Untested
# GS1900-24HP - Untested
# GS1900-48 - Untested
# GS1900-48HP - Untested
#
# Prerequisite Setup Steps:
# 1. Install at least firmware V2.80 on your switch
# 2. Enable HTTPS web management on your switch
#
# Usage:
# 1. Ensure the switch has firmware V2.80 or later.
# 2. Ensure the switch has HTTPS management enabled.
# 3. Set the appropriate environment variables for your environment.
#
# DEPLOY_ZYXEL_SWITCH - The switch hostname. (Default: _cdomain)
# DEPLOY_ZYXEL_SWITCH_USER - The webadmin user. (Default: admin)
# DEPLOY_ZYXEL_SWITCH_PASSWORD - The webadmin password for the switch.
# DEPLOY_ZYXEL_SWITCH_REBOOT - If "1" reboot after update. (Default: "0")
#
# 4. Run the deployment plugin:
# acme.sh --deploy --deploy-hook zyxel_gs1900 -d example.com
#
# returns 0 means success, otherwise error.
#domain keyfile certfile cafile fullchain
zyxel_gs1900_deploy() {
_zyxel_gs1900_minimum_firmware_version="v2.80"
_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"
_getdeployconf DEPLOY_ZYXEL_SWITCH
_getdeployconf DEPLOY_ZYXEL_SWITCH_USER
_getdeployconf DEPLOY_ZYXEL_SWITCH_PASSWORD
_getdeployconf DEPLOY_ZYXEL_SWITCH_REBOOT
if [ -z "$DEPLOY_ZYXEL_SWITCH" ]; then
DEPLOY_ZYXEL_SWITCH="$_cdomain"
fi
if [ -z "$DEPLOY_ZYXEL_SWITCH_USER" ]; then
DEPLOY_ZYXEL_SWITCH_USER="admin"
fi
if [ -z "$DEPLOY_ZYXEL_SWITCH_PASSWORD" ]; then
DEPLOY_ZYXEL_SWITCH_PASSWORD="1234"
fi
if [ -z "$DEPLOY_ZYXEL_SWITCH_REBOOT" ]; then
DEPLOY_ZYXEL_SWITCH_REBOOT="0"
fi
_savedeployconf DEPLOY_ZYXEL_SWITCH "$DEPLOY_ZYXEL_SWITCH"
_savedeployconf DEPLOY_ZYXEL_SWITCH_USER "$DEPLOY_ZYXEL_SWITCH_USER"
_savedeployconf DEPLOY_ZYXEL_SWITCH_PASSWORD "$DEPLOY_ZYXEL_SWITCH_PASSWORD"
_savedeployconf DEPLOY_ZYXEL_SWITCH_REBOOT "$DEPLOY_ZYXEL_SWITCH_REBOOT"
_debug DEPLOY_ZYXEL_SWITCH "$DEPLOY_ZYXEL_SWITCH"
_debug DEPLOY_ZYXEL_SWITCH_USER "$DEPLOY_ZYXEL_SWITCH_USER"
_secure_debug DEPLOY_ZYXEL_SWITCH_PASSWORD "$DEPLOY_ZYXEL_SWITCH_PASSWORD"
_debug DEPLOY_ZYXEL_SWITCH_REBOOT "$DEPLOY_ZYXEL_SWITCH_REBOOT"
_zyxel_switch_base_uri="https://${DEPLOY_ZYXEL_SWITCH}"
_info "Beginning to deploy to a Zyxel GS1900 series switch at ${_zyxel_switch_base_uri}."
_zyxel_gs1900_deployment_precheck || return $?
_zyxel_gs1900_should_update
if [ "$?" != "0" ]; then
_info "The switch already has our certificate installed. No update required."
return 0
else
_info "The switch does not yet have our certificate installed."
fi
_info "Logging into the switch web interface."
_zyxel_gs1900_login || return $?
_info "Validating the switch is compatible with this deployment process."
_zyxel_gs1900_validate_device_compatibility || return $?
_info "Uploading the certificate."
_zyxel_gs1900_upload_certificate || return $?
if [ "$DEPLOY_ZYXEL_SWITCH_REBOOT" = "1" ]; then
_info "Rebooting the switch."
_zyxel_gs1900_trigger_reboot || return $?
fi
return 0
}
_zyxel_gs1900_deployment_precheck() {
# Initialize the keylength if it isn't already
if [ -z "$Le_Keylength" ]; then
Le_Keylength=""
fi
if _isEccKey "$Le_Keylength"; then
_info "Warning: Zyxel GS1900 switches are not currently known to work with ECC keys!"
_info "You can continue, but your switch may reject your key."
elif [ -n "$Le_Keylength" ] && [ "$Le_Keylength" -gt "2048" ]; then
_info "Warning: Your RSA key length is greater than 2048!"
_info "You can continue, but you may experience performance issues in the web administration interface."
fi
# Check the server for some common failure modes prior to authentication and certificate upload in order to avoid
# sending a certificate when we may not want to.
test_login_response=$(_post "username=test&password=test&login=true;" "${_zyxel_switch_base_uri}/cgi-bin/dispatcher.cgi?cmd=0.html" '' "POST" "application/x-www-form-urlencoded" 2>&1)
test_login_page_exitcode="$?"
_debug3 "Test Login Response: ${test_login_response}"
if [ "$test_login_page_exitcode" -ne "0" ]; then
if { [ "${ACME_USE_WGET:-0}" = "0" ] && [ "$test_login_page_exitcode" = "60" ]; } || { [ "${ACME_USE_WGET:-0}" = "1" ] && [ "$test_login_page_exitcode" = "5" ]; }; then
_err "The SSL certificate at $_zyxel_switch_base_uri could not be validated."
_err "Please double check your hostname, port, and that you are actually connecting to your switch."
_err "If the problem persists then please ensure that the certificate is not self-signed, has not"
_err "expired, and matches the switch hostname. If you expect validation to fail then you can disable"
_err "certificate validation by running with --insecure."
return 1
elif [ "${ACME_USE_WGET:-0}" = "0" ] && [ "$test_login_page_exitcode" = "56" ]; then
_debug3 "Intentionally ignore curl exit code 56 in our precheck"
else
_err "Failed to submit the initial login attempt to $_zyxel_switch_base_uri."
return 1
fi
fi
}
_zyxel_gs1900_login() {
# Login to the switch and set the appropriate auth cookie in _H1
username_encoded=$(printf "%s" "$DEPLOY_ZYXEL_SWITCH_USER" | _url_encode)
password_encoded=$(_zyxel_gs1900_password_obfuscate "$DEPLOY_ZYXEL_SWITCH_PASSWORD" | _url_encode)
login_response=$(_post "username=${username_encoded}&password=${password_encoded}&login=true;" "${_zyxel_switch_base_uri}/cgi-bin/dispatcher.cgi?cmd=0.html" '' "POST" "application/x-www-form-urlencoded" | tr -d '\n')
auth_response=$(_post "authId=${login_response}&login_chk=true" "${_zyxel_switch_base_uri}/cgi-bin/dispatcher.cgi?cmd=0.html" '' "POST" "application/x-www-form-urlencoded" | tr -d '\n')
if [ "$auth_response" != "OK" ]; then
_err "Login failed due to invalid credentials."
_err "Please double check the configured username and password and try again."
return 1
fi
sessionid=$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'HTTPS_XSSID=[^;]*;' | tr -d ';')
_secure_debug2 "sessionid" "$sessionid"
export _H1="Cookie: $sessionid"
_secure_debug2 "_H1" "$_H1"
return 0
}
_zyxel_gs1900_validate_device_compatibility() {
# Check the switches model and firmware version and throw errors
# if this script isn't compatible.
device_info_html=$(_get "${_zyxel_switch_base_uri}/cgi-bin/dispatcher.cgi?cmd=12" | tr -d '\n')
model_name=$(_zyxel_gs1900_get_model "$device_info_html")
_debug2 "model_name" "$model_name"
if [ -z "$model_name" ]; then
_err "Could not find the switch model name."
_err "Please re-run with --debug and report a bug."
return $?
fi
if ! expr "$model_name" : "GS1900-" >/dev/null; then
_err "Switch is an unsupported model: $model_name"
return 1
fi
firmware_version=$(_zyxel_gs1900_get_firmware_version "$device_info_html")
_debug2 "firmware_version" "$firmware_version"
if [ -z "$firmware_version" ]; then
_err "Could not find the switch firmware version."
_err "Please re-run with --debug and report a bug."
return $?
fi
_debug2 "_zyxel_gs1900_minimum_firmware_version" "$_zyxel_gs1900_minimum_firmware_version"
minimum_major_version=$(_zyxel_gs1900_parse_major_version "$_zyxel_gs1900_minimum_firmware_version")
_debug2 "minimum_major_version" "$minimum_major_version"
minimum_minor_version=$(_zyxel_gs1900_parse_minor_version "$_zyxel_gs1900_minimum_firmware_version")
_debug2 "minimum_minor_version" "$minimum_minor_version"
_debug2 "firmware_version" "$firmware_version"
firmware_major_version=$(_zyxel_gs1900_parse_major_version "$firmware_version")
_debug2 "firmware_major_version" "$firmware_major_version"
firmware_minor_version=$(_zyxel_gs1900_parse_minor_version "$firmware_version")
_debug2 "firmware_minor_version" "$firmware_minor_version"
_ret=0
if [ "$firmware_major_version" -lt "$minimum_major_version" ]; then
_ret=1
elif [ "$firmware_major_version" -eq "$minimum_major_version" ] && [ "$firmware_minor_version" -lt "$minimum_minor_version" ]; then
_ret=1
fi
if [ "$_ret" != "0" ]; then
_err "Unsupported firmware version $firmware_version. Please upgrade to at least version $_zyxel_gs1900_minimum_firmware_version."
fi
return $?
}
_zyxel_gs1900_should_update() {
# Get the remote certificate serial number
_remote_cert=$(${ACME_OPENSSL_BIN:-openssl} s_client -showcerts -connect "${DEPLOY_ZYXEL_SWITCH}:443" 2>/dev/null </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p')
_debug3 "_remote_cert" "$_remote_cert"
_remote_cert_serial=$(printf "%s" "${_remote_cert}" | ${ACME_OPENSSL_BIN:-openssl} x509 -noout -serial)
_debug2 "_remote_cert_serial" "$_remote_cert_serial"
# Get our certificate serial number
_our_cert_serial=$(${ACME_OPENSSL_BIN:-openssl} x509 -noout -serial <"${_ccert}")
_debug2 "_our_cert_serial" "$_our_cert_serial"
[ "${_remote_cert_serial}" != "${_our_cert_serial}" ]
}
_zyxel_gs1900_upload_certificate() {
# Generate a PKCS12 certificate with a temporary password since the web interface
# requires a password be present. Then upload that certificate.
temp_cert_password=$(head /dev/urandom | tr -dc 'A-Za-z0-9' | head -c 64)
_secure_debug2 "temp_cert_password" "$temp_cert_password"
temp_pkcs12="$(_mktemp)"
_debug2 "temp_pkcs12" "$temp_pkcs12"
_toPkcs "$temp_pkcs12" "$_ckey" "$_ccert" "$_cca" "$temp_cert_password"
if [ "$?" != "0" ]; then
_err "Failed to generate a pkcs12 certificate."
_err "Please re-run with --debug and report a bug."
# ensure the temporary certificate file is cleaned up
[ -f "${temp_pkcs12}" ] && rm -f "${temp_pkcs12}"
return $?
fi
# Load the upload page
upload_page_html=$(_get "${_zyxel_switch_base_uri}/cgi-bin/dispatcher.cgi?cmd=5914" | tr -d '\n')
# Get the first instance of XSSID from the upload page
form_xss_value=$(printf "%s" "$upload_page_html" | _egrep_o 'name="XSSID"\s*value="[^"]+"' | sed 's/^.*="\([^"]\{1,\}\)"$/\1/g' | head -n 1)
_secure_debug2 "form_xss_value" "$form_xss_value"
_info "Generating the certificate upload request"
upload_post_request="$(_mktemp)"
upload_post_boundary="---------------------------$(date +%Y%m%d%H%M%S)"
{
printf -- "--%s\r\n" "${upload_post_boundary}"
printf "Content-Disposition: form-data; name=\"XSSID\"\r\n\r\n%s\r\n" "${form_xss_value}"
printf -- "--%s\r\n" "${upload_post_boundary}"
printf "Content-Disposition: form-data; name=\"http_file\"; filename=\"temp_pkcs12.pfx\"\r\n"
printf "Content-Type: application/pkcs12\r\n\r\n"
cat "${temp_pkcs12}"
printf "\r\n"
printf -- "--%s\r\n" "${upload_post_boundary}"
printf "Content-Disposition: form-data; name=\"pwd\"\r\n\r\n%s\r\n" "${temp_cert_password}"
printf -- "--%s\r\n" "${upload_post_boundary}"
printf "Content-Disposition: form-data; name=\"cmd\"\r\n\r\n%s\r\n" "31"
printf -- "--%s\r\n" "${upload_post_boundary}"
printf "Content-Disposition: form-data; name=\"sysSubmit\"\r\n\r\n%s\r\n" "Import"
printf -- "--%s--\r\n" "${upload_post_boundary}"
} >"${upload_post_request}"
_info "Upload certificate to the switch"
# Unfortunately we cannot rely upon the switch response across switch models
# to return a consistent body return - so we cannot inspect the result of this
# upload to determine success.
upload_response=$(_zyxel_upload_pkcs12 "${upload_post_request}" "${upload_post_boundary}" 2>&1)
_debug3 "Upload response: ${upload_response}"
rm "${upload_post_request}"
# Pause for a few seconds to give the switch a chance to process the certificate
# For some reason I've found this to be necessary on my GS1900-24E
_debug2 "Waiting 4 seconds for the switch to process the newly uploaded certificate."
sleep "4"
# Check to see whether or not our update was successful
_ret=0
_zyxel_gs1900_should_update
if [ "$?" != "0" ]; then
_info "The certificate was updated successfully"
else
_ret=1
_err "The certificate upload does not appear to have worked."
_err "The remote certificate does not match the certificate we tried to upload."
_err "Please re-run with --debug 2 and review for unexpected errors. If none can be found please submit a bug."
fi
# ensure the temporary files are cleaned up
[ -f "${temp_pkcs12}" ] && rm -f "${temp_pkcs12}"
return $_ret
}
# make the certificate upload request using either
# --data binary with @ for file access in CURL
# or using --post-file for wget to ensure we upload
# the pkcs12 without getting tripped up on null bytes
#
# Usage _zyxel_upload_pkcs12 [body file name] [post boundary marker]
_zyxel_upload_pkcs12() {
bodyfilename="$1"
multipartformmarker="$2"
_post_url="${_zyxel_switch_base_uri}/cgi-bin/httpuploadcert.cgi"
httpmethod="POST"
_postContentType="multipart/form-data; boundary=${multipartformmarker}"
if [ -z "$httpmethod" ]; then
httpmethod="POST"
fi
_debug $httpmethod
_debug "_post_url" "$_post_url"
_debug2 "bodyfilename" "$bodyfilename"
_debug2 "_postContentType" "$_postContentType"
_inithttp
if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then
_CURL="$_ACME_CURL"
if [ "$HTTPS_INSECURE" ]; then
_CURL="$_CURL --insecure "
fi
if [ "$httpmethod" = "HEAD" ]; then
_CURL="$_CURL -I "
fi
_debug "_CURL" "$_CURL"
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data-binary "@${bodyfilename}" "$_post_url")"
_ret="$?"
if [ "$_ret" != "0" ]; then
_err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret"
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
_err "Here is the curl dump log:"
_err "$(cat "$_CURL_DUMP")"
fi
fi
elif [ "$_ACME_WGET" ]; then
_WGET="$_ACME_WGET"
if [ "$HTTPS_INSECURE" ]; then
_WGET="$_WGET --no-check-certificate "
fi
_debug "_WGET" "$_WGET"
response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-file="${bodyfilename}" "$_post_url" 2>"$HTTP_HEADER")"
_ret="$?"
if [ "$_ret" = "8" ]; then
_ret=0
_debug "wget returned 8 as the server returned a 'Bad Request' response. Let's process the response later."
fi
if [ "$_ret" != "0" ]; then
_err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret"
fi
if _contains "$_WGET" " -d "; then
# Demultiplex wget debug output
cat "$HTTP_HEADER" >&2
_sed_i '/^[^ ][^ ]/d; /^ *$/d' "$HTTP_HEADER"
fi
# remove leading whitespaces from header to match curl format
_sed_i 's/^ //g' "$HTTP_HEADER"
else
_ret="$?"
_err "Neither curl nor wget have been found, cannot make $httpmethod request."
fi
_debug "_ret" "$_ret"
printf "%s" "$response"
return $_ret
}
_zyxel_gs1900_trigger_reboot() {
# Trigger a reboot via the management reboot page in the web ui
reboot_page_html=$(_get "${_zyxel_switch_base_uri}/cgi-bin/dispatcher.cgi?cmd=5888" | tr -d '\n')
reboot_xss_value=$(printf "%s" "$reboot_page_html" | _egrep_o 'name="XSSID"\s*value="[^"]+"' | sed 's/^.*="\([^"]\{1,\}\)"$/\1/g')
_secure_debug2 "reboot_xss_value" "$reboot_xss_value"
reboot_response_html=$(_post "XSSID=${reboot_xss_value}&cmd=5889&sysSubmit=Reboot" "${_zyxel_switch_base_uri}/cgi-bin/dispatcher.cgi" '' "POST" "application/x-www-form-urlencoded")
reboot_message=$(printf "%s" "$reboot_response_html" | tr -d '\t\r\n\v\f' | _egrep_o "Rebooting now...")
if [ -z "$reboot_message" ]; then
_err "Failed to trigger switch reboot!"
return 1
fi
return 0
}
# password
_zyxel_gs1900_password_obfuscate() {
# Return the password obfuscated via the same method used by the
# switch's web UI login process
echo "$1" | awk '{
encoded = "";
password = $1;
allowed = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
len = length($1);
pwi = length($1);
for (i=1; i <= (321 - pwi); i++)
{
if (0 == i % 5 && pwi > 0)
{
encoded = (encoded)(substr(password, pwi--, 1));
}
else if (i == 123)
{
if (len < 10)
{
encoded = (encoded)(0);
}
else
{
encoded = (encoded)(int(len / 10));
}
}
else if (i == 289)
{
encoded = (encoded)(len % 10)
}
else
{
encoded = (encoded)(substr(allowed, int(rand() * length(allowed)), 1))
}
}
printf("%s", encoded);
}'
}
# html label
_zyxel_html_table_lookup() {
# Look up a value in the html representing the status page of the switch
# when provided with the html of the page and the label (i.e. "Model Name:")
html="$1"
label=$(printf "%s" "$2" | tr -d ' ')
lookup_result=$(printf "%s" "$html" | tr -d "\t\r\n\v\f" | sed 's/<tr>/\n<tr>/g' | sed 's/<td[^>]*>/<td>/g' | tr -d ' ' | grep -i "$label" | sed "s/<tr><td>$label<\/td><td>\([^<]\{1,\}\)<\/td><\/tr>/\1/i")
printf "%s" "$lookup_result"
return 0
}
# html
_zyxel_gs1900_get_model() {
html="$1"
model_name=$(_zyxel_html_table_lookup "$html" "Model Name:")
printf "%s" "$model_name"
}
# html
_zyxel_gs1900_get_firmware_version() {
html="$1"
firmware_version=$(_zyxel_html_table_lookup "$html" "Firmware Version:" | _egrep_o "V[^.]+.[^(]+")
printf "%s" "$firmware_version"
}
# version_number
_zyxel_gs1900_parse_major_version() {
printf "%s" "$1" | sed 's/^V\([0-9]\{1,\}\).\{1,\}$/\1/gi'
}
# version_number
_zyxel_gs1900_parse_minor_version() {
printf "%s" "$1" | sed 's/^.\{1,\}\.\([0-9]\{1,\}\)$/\1/gi'
}
+91 -84
View File
@@ -1,46 +1,42 @@
#!/usr/bin/env sh
#This file name is "dns_1984hosting.sh"
#So, here must be a method dns_1984hosting_add()
#Which will be called by acme.sh to add the txt record to your api system.
#returns 0 means success, otherwise error.
# shellcheck disable=SC2034
dns_1984hosting_info='1984.hosting
Domains: 1984.is
Site: 1984.hosting
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_1984hosting
Options:
One984HOSTING_Username Username
One984HOSTING_Password Password
Issues: github.com/acmesh-official/acme.sh/issues/2851
Author: Adrian Fedoreanu
'
#Author: Adrian Fedoreanu
#Report Bugs here: https://github.com/acmesh-official/acme.sh
# or here... https://github.com/acmesh-official/acme.sh/issues/2851
#
######## Public functions #####################
######## Public functions #####################
# Export 1984HOSTING username and password in following variables
#
# One984HOSTING_Username=username
# One984HOSTING_Password=password
#
# sessionid cookie is saved in ~/.acme.sh/account.conf
# username/password need to be set only when changed.
#Usage: dns_1984hosting_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Usage: dns_1984hosting_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Add a text record.
dns_1984hosting_add() {
fulldomain=$1
txtvalue=$2
_info "Add TXT record using 1984Hosting"
_info "Add TXT record using 1984Hosting."
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
if ! _1984hosting_login; then
_err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file"
_err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file."
return 1
fi
_debug "First detect the root zone"
_debug "First detect the root zone."
if ! _get_root "$fulldomain"; then
_err "invalid domain" "$fulldomain"
_err "Invalid domain '$fulldomain'."
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Add TXT record $fulldomain with value '$txtvalue'"
_debug "Add TXT record $fulldomain with value '$txtvalue'."
value="$(printf '%s' "$txtvalue" | _url_encode)"
url="https://1984.hosting/domains/entry/"
@@ -53,102 +49,108 @@ dns_1984hosting_add() {
_debug2 postdata "$postdata"
_authpost "$postdata" "$url"
response="$(echo "$_response" | _normalizeJson)"
_debug2 response "$response"
if _contains "$response" '"haserrors": true'; then
_err "1984Hosting failed to add TXT record for $_sub_domain bad RC from _post"
if _contains "$_response" '"haserrors": true'; then
_err "1984Hosting failed to add TXT record for $_sub_domain bad RC from _post."
return 1
elif _contains "$response" "html>"; then
_err "1984Hosting failed to add TXT record for $_sub_domain. Check $HTTP_HEADER file"
elif _contains "$_response" "html>"; then
_err "1984Hosting failed to add TXT record for $_sub_domain. Check $HTTP_HEADER file."
return 1
elif _contains "$response" '"auth": false'; then
_err "1984Hosting failed to add TXT record for $_sub_domain. Invalid or expired cookie"
elif _contains "$_response" '"auth": false'; then
_err "1984Hosting failed to add TXT record for $_sub_domain. Invalid or expired cookie."
return 1
fi
_info "Added acme challenge TXT record for $fulldomain at 1984Hosting"
_info "Added acme challenge TXT record for $fulldomain at 1984Hosting."
return 0
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
# Usage: fulldomain txtvalue
# Remove the txt record after validation.
dns_1984hosting_rm() {
fulldomain=$1
txtvalue=$2
_info "Delete TXT record using 1984Hosting"
_info "Delete TXT record using 1984Hosting."
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
if ! _1984hosting_login; then
_err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file"
_err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file."
return 1
fi
_debug "First detect the root zone"
_debug "First detect the root zone."
if ! _get_root "$fulldomain"; then
_err "invalid domain" "$fulldomain"
_err "Invalid domain '$fulldomain'."
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Delete $fulldomain TXT record"
_debug "Delete $fulldomain TXT record."
url="https://1984.hosting/domains"
if ! _get_zone_id "$url" "$_domain"; then
_err "invalid zone" "$_domain"
_err "Invalid zone '$_domain'."
return 1
fi
_htmlget "$url/$_zone_id" "$txtvalue"
_debug2 _response "$_response"
entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')"
_debug2 entry_id "$entry_id"
if [ -z "$entry_id" ]; then
_err "Error getting TXT entry_id for $1"
_err "Error getting TXT entry_id for $1."
return 1
fi
_authpost "entry=$entry_id" "$url/delentry/"
response="$(echo "$_response" | _normalizeJson)"
_debug2 response "$response"
if ! _contains "$response" '"ok": true'; then
_err "1984Hosting failed to delete TXT record for $entry_id bad RC from _post"
if ! _contains "$_response" '"ok": true'; then
_err "1984Hosting failed to delete TXT record for $entry_id bad RC from _post."
return 1
fi
_info "Deleted acme challenge TXT record for $fulldomain at 1984Hosting"
_info "Deleted acme challenge TXT record for $fulldomain at 1984Hosting."
return 0
}
#################### Private functions below ##################################
# usage: _1984hosting_login username password
# returns 0 success
_1984hosting_login() {
if ! _check_credentials; then return 1; fi
if _check_cookies; then
_debug "Already logged in"
_debug "Already logged in."
return 0
fi
_debug "Login to 1984Hosting as user $One984HOSTING_Username"
_debug "Login to 1984Hosting as user $One984HOSTING_Username."
username=$(printf '%s' "$One984HOSTING_Username" | _url_encode)
password=$(printf '%s' "$One984HOSTING_Password" | _url_encode)
url="https://1984.hosting/accounts/checkuserauth/"
url="https://1984.hosting/api/auth/"
_get "https://1984.hosting/accounts/login/" | grep "csrfmiddlewaretoken"
csrftoken="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'csrftoken=[^;]*;' | tr -d ';')"
sessionid="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'cookie1984nammnamm=[^;]*;' | tr -d ';')"
if [ -z "$csrftoken" ] || [ -z "$sessionid" ]; then
_err "One or more cookies are empty: '$csrftoken', '$sessionid'."
return 1
fi
export _H1="Cookie: $csrftoken; $sessionid"
export _H2="Referer: https://1984.hosting/accounts/login/"
csrf_header=$(echo "$csrftoken" | sed 's/csrftoken=//' | _head_n 1)
export _H3="X-CSRFToken: $csrf_header"
response="$(_post "username=$username&password=$password&otpkey=" $url)"
response="$(echo "$response" | _normalizeJson)"
_debug2 response "$response"
if _contains "$response" '"loggedin": true'; then
One984HOSTING_SESSIONID_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'sessionid=[^;]*;' | tr -d ';')"
One984HOSTING_SESSIONID_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'cookie1984nammnamm=[^;]*;' | tr -d ';')"
One984HOSTING_CSRFTOKEN_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'csrftoken=[^;]*;' | tr -d ';')"
export One984HOSTING_SESSIONID_COOKIE
export One984HOSTING_CSRFTOKEN_COOKIE
_saveaccountconf_mutable One984HOSTING_Username "$One984HOSTING_Username"
_saveaccountconf_mutable One984HOSTING_Password "$One984HOSTING_Password"
_saveaccountconf_mutable One984HOSTING_SESSIONID_COOKIE "$One984HOSTING_SESSIONID_COOKIE"
_saveaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE "$One984HOSTING_CSRFTOKEN_COOKIE"
return 0
@@ -157,9 +159,13 @@ _1984hosting_login() {
}
_check_credentials() {
One984HOSTING_Username="${One984HOSTING_Username:-$(_readaccountconf_mutable One984HOSTING_Username)}"
One984HOSTING_Password="${One984HOSTING_Password:-$(_readaccountconf_mutable One984HOSTING_Password)}"
if [ -z "$One984HOSTING_Username" ] || [ -z "$One984HOSTING_Password" ]; then
One984HOSTING_Username=""
One984HOSTING_Password=""
_clearaccountconf_mutable One984HOSTING_Username
_clearaccountconf_mutable One984HOSTING_Password
_err "You haven't specified 1984Hosting username or password yet."
_err "Please export as One984HOSTING_Username / One984HOSTING_Password and try again."
return 1
@@ -171,42 +177,43 @@ _check_cookies() {
One984HOSTING_SESSIONID_COOKIE="${One984HOSTING_SESSIONID_COOKIE:-$(_readaccountconf_mutable One984HOSTING_SESSIONID_COOKIE)}"
One984HOSTING_CSRFTOKEN_COOKIE="${One984HOSTING_CSRFTOKEN_COOKIE:-$(_readaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE)}"
if [ -z "$One984HOSTING_SESSIONID_COOKIE" ] || [ -z "$One984HOSTING_CSRFTOKEN_COOKIE" ]; then
_debug "No cached cookie(s) found"
_debug "No cached cookie(s) found."
return 1
fi
_authget "https://1984.hosting/accounts/loginstatus/"
if _contains "$response" '"ok": true'; then
_debug "Cached cookies still valid"
_authget "https://1984.hosting/api/auth/"
if _contains "$_response" '"ok": true'; then
_debug "Cached cookies still valid."
return 0
fi
_debug "Cached cookies no longer valid"
_debug "Cached cookies no longer valid. Clearing cookies."
One984HOSTING_SESSIONID_COOKIE=""
One984HOSTING_CSRFTOKEN_COOKIE=""
_saveaccountconf_mutable One984HOSTING_SESSIONID_COOKIE "$One984HOSTING_SESSIONID_COOKIE"
_saveaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE "$One984HOSTING_CSRFTOKEN_COOKIE"
_clearaccountconf_mutable One984HOSTING_SESSIONID_COOKIE
_clearaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE
return 1
}
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
# _acme-challenge.www.domain.com
# Returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain="$1"
i=1
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
# not valid
if [ -z "$h" ]; then
#not valid
return 1
fi
_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)
_authget "https://1984.hosting/domains/zonestatus/$h/?cached=no"
if _contains "$_response" '"ok": true'; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain="$h"
return 0
fi
@@ -216,46 +223,46 @@ _get_root() {
return 1
}
#usage: _get_zone_id url domain.com
#returns zone id for domain.com
# Usage: _get_zone_id url domain.com
# Returns zone id for domain.com
_get_zone_id() {
url=$1
domain=$2
_htmlget "$url" "$domain"
_debug2 _response "$_response"
_zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+' | _head_n 1)"
_debug2 _zone_id "$_zone_id"
if [ -z "$_zone_id" ]; then
_err "Error getting _zone_id for $2"
_err "Error getting _zone_id for $2."
return 1
fi
return 0
}
# add extra headers to request
# Add extra headers to request
_authget() {
export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE"
export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE; $One984HOSTING_SESSIONID_COOKIE"
_response=$(_get "$1" | _normalizeJson)
_debug2 _response "$_response"
}
# truncate huge HTML response
# echo: Argument list too long
# Truncate huge HTML response
_htmlget() {
export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE"
export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE; $One984HOSTING_SESSIONID_COOKIE"
_response=$(_get "$1" | grep "$2")
if _contains "$_response" "@$2"; then
_response=$(echo "$_response" | grep -v "[@]" | _head_n 1)
fi
_debug2 _response "$_response"
}
# add extra headers to request
# Add extra headers to request
_authpost() {
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 _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE; $One984HOSTING_SESSIONID_COOKIE"
export _H2="Referer: https://1984.hosting/domains/$_zone_id"
export _H3="X-CSRFToken: $csrf_header"
_response=$(_post "$1" "$2")
_response="$(_post "$1" "$2" | _normalizeJson)"
_debug2 _response "$_response"
}
+14 -14
View File
@@ -1,18 +1,18 @@
#!/usr/bin/env sh
#
#Author: Wolfgang Ebner
#Author: Sven Neubuaer
#Report Bugs here: https://github.com/dampfklon/acme.sh
#
# Usage:
# export ACMEDNS_BASE_URL="https://auth.acme-dns.io"
#
# You can optionally define an already existing account:
#
# export ACMEDNS_USERNAME="<username>"
# export ACMEDNS_PASSWORD="<password>"
# export ACMEDNS_SUBDOMAIN="<subdomain>"
#
# shellcheck disable=SC2034
dns_acmedns_info='acme-dns Server API
The acme-dns is a limited DNS server with RESTful API to handle ACME DNS challenges.
Site: github.com/joohoi/acme-dns
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_acmedns
Options:
ACMEDNS_USERNAME Username. Optional.
ACMEDNS_PASSWORD Password. Optional.
ACMEDNS_SUBDOMAIN Subdomain. Optional.
ACMEDNS_BASE_URL API endpoint. Default: "https://auth.acme-dns.io".
Issues: github.com/dampfklon/acme.sh
Author: Wolfgang Ebner, Sven Neubuaer
'
######## Public functions #####################
#Usage: dns_acmedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
Regular → Executable
+13 -5
View File
@@ -1,9 +1,17 @@
#!/usr/bin/env sh
## Acmeproxy DNS provider to be used with acmeproxy (http://github.com/mdbraber/acmeproxy)
## API integration by Maarten den Braber
##
## Report any bugs via https://github.com/mdbraber/acme.sh
# shellcheck disable=SC2034
dns_acmeproxy_info='AcmeProxy Server API
AcmeProxy can be used to as a single host in your network to request certificates through a DNS API.
Clients can connect with the one AcmeProxy host so you do not need to store DNS API credentials on every single host.
Site: github.com/mdbraber/acmeproxy
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_acmeproxy
Options:
ACMEPROXY_ENDPOINT API Endpoint
ACMEPROXY_USERNAME Username
ACMEPROXY_PASSWORD Password
Issues: github.com/acmesh-official/acme.sh/issues/2251
Author: Maarten den Braber
'
dns_acmeproxy_add() {
fulldomain="${1}"
+122 -57
View File
@@ -1,10 +1,17 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_active24_info='Active24.cz
Site: Active24.cz
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_active24
Options:
Active24_ApiKey API Key. Called "Identifier" in the Active24 Admin
Active24_ApiSecret API Secret. Called "Secret key" in the Active24 Admin
Issues: github.com/acmesh-official/acme.sh/issues/2059
'
#ACTIVE24_Token="sdfsdfsdfljlbjkljlkjsdfoiwje"
ACTIVE24_Api="https://api.active24.com"
######## Public functions #####################
Active24_Api="https://rest.active24.cz"
# export Active24_ApiKey=ak48l3h7-ak5d-qn4t-p8gc-b6fs8c3l
# export Active24_ApiSecret=ajvkeo3y82ndsu2smvxy3o36496dcascksldncsq
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Used to add txt record
@@ -15,8 +22,8 @@ dns_active24_add() {
_active24_init
_info "Adding txt record"
if _active24_rest POST "dns/$_domain/txt/v1" "{\"name\":\"$_sub_domain\",\"text\":\"$txtvalue\",\"ttl\":0}"; then
if _contains "$response" "errors"; then
if _active24_rest POST "/v2/service/$_service_id/dns/record" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":300}"; then
if _contains "$response" "error"; then
_err "Add txt record error."
return 1
else
@@ -24,6 +31,7 @@ dns_active24_add() {
return 0
fi
fi
_err "Add txt record error."
return 1
}
@@ -37,19 +45,25 @@ dns_active24_rm() {
_active24_init
_debug "Getting txt records"
_active24_rest GET "dns/$_domain/records/v1"
# The API needs to send data in body in order the filter to work
# TODO: web can also add content $txtvalue to filter and then get the id from response
_active24_rest GET "/v2/service/$_service_id/dns/record" "{\"page\":1,\"descending\":true,\"sortBy\":\"name\",\"rowsPerPage\":100,\"totalRecords\":0,\"filters\":{\"type\":[\"TXT\"],\"name\":\"${_sub_domain}\"}}"
#_active24_rest GET "/v2/service/$_service_id/dns/record?rowsPerPage=100"
if _contains "$response" "errors"; then
if _contains "$response" "error"; then
_err "Error"
return 1
fi
hash_ids=$(echo "$response" | _egrep_o "[^{]+${txtvalue}[^}]+" | _egrep_o "hashId\":\"[^\"]+" | cut -c10-)
# Note: it might never be more than one record actually, NEEDS more INVESTIGATION
record_ids=$(printf "%s" "$response" | _egrep_o "[^{]+${txtvalue}[^}]+" | _egrep_o '"id" *: *[^,]+' | cut -d ':' -f 2)
_debug2 record_ids "$record_ids"
for hash_id in $hash_ids; do
_debug "Removing hash_id" "$hash_id"
if _active24_rest DELETE "dns/$_domain/$hash_id/v1" ""; then
if _contains "$response" "errors"; then
for redord_id in $record_ids; do
_debug "Removing record_id" "$redord_id"
_debug "txtvalue" "$txtvalue"
if _active24_rest DELETE "/v2/service/$_service_id/dns/record/$redord_id" ""; then
if _contains "$response" "error"; then
_err "Unable to remove txt record."
return 1
else
@@ -63,23 +77,17 @@ dns_active24_rm() {
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
if ! _active24_rest GET "dns/domains/v1"; then
if ! _active24_rest GET "/v1/user/self/service"; then
return 1
fi
i=2
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug "h" "$h"
if [ -z "$h" ]; then
#not valid
@@ -87,7 +95,7 @@ _get_root() {
fi
if _contains "$response" "\"$h\"" >/dev/null; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain=$h
return 0
fi
@@ -97,21 +105,98 @@ _get_root() {
return 1
}
_active24_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
_active24_init() {
Active24_ApiKey="${Active24_ApiKey:-$(_readaccountconf_mutable Active24_ApiKey)}"
Active24_ApiSecret="${Active24_ApiSecret:-$(_readaccountconf_mutable Active24_ApiSecret)}"
#Active24_ServiceId="${Active24_ServiceId:-$(_readaccountconf_mutable Active24_ServiceId)}"
export _H1="Authorization: Bearer $ACTIVE24_Token"
if [ "$m" != "GET" ]; then
_debug "data" "$data"
response="$(_post "$data" "$ACTIVE24_Api/$ep" "" "$m" "application/json")"
else
response="$(_get "$ACTIVE24_Api/$ep")"
if [ -z "$Active24_ApiKey" ] || [ -z "$Active24_ApiSecret" ]; then
Active24_ApiKey=""
Active24_ApiSecret=""
_err "You don't specify Active24 api key and ApiSecret yet."
_err "Please create your key and try again."
return 1
fi
#save the credentials to the account conf file.
_saveaccountconf_mutable Active24_ApiKey "$Active24_ApiKey"
_saveaccountconf_mutable Active24_ApiSecret "$Active24_ApiSecret"
_debug "A24 API CHECK"
if ! _active24_rest GET "/v2/check"; then
_err "A24 API check failed with: $response"
return 1
fi
if ! echo "$response" | tr -d " " | grep \"verified\":true >/dev/null; then
_err "A24 API check failed with: $response"
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_active24_get_service_id "$_domain"
_debug _service_id "$_service_id"
}
_active24_get_service_id() {
_d=$1
if ! _active24_rest GET "/v1/user/self/zone/${_d}"; then
return 1
else
response=$(echo "$response" | _json_decode)
_service_id=$(echo "$response" | _egrep_o '"id" *: *[^,]+' | cut -d ':' -f 2)
fi
}
_active24_rest() {
m=$1
ep_qs=$2 # with query string
# ep=$2
ep=$(printf "%s" "$ep_qs" | cut -d '?' -f1) # no query string
data="$3"
_debug "A24 $ep"
_debug "A24 $Active24_ApiKey"
_debug "A24 $Active24_ApiSecret"
timestamp=$(_time)
datez=$(date -u +"%Y%m%dT%H%M%SZ")
canonicalRequest="${m} ${ep} ${timestamp}"
signature=$(printf "%s" "$canonicalRequest" | _hmac sha1 "$(printf "%s" "$Active24_ApiSecret" | _hex_dump | tr -d " ")" hex)
authorization64="$(printf "%s:%s" "$Active24_ApiKey" "$signature" | _base64)"
export _H1="Date: ${datez}"
export _H2="Accept: application/json"
export _H3="Content-Type: application/json"
export _H4="Authorization: Basic ${authorization64}"
_debug2 H1 "$_H1"
_debug2 H2 "$_H2"
_debug2 H3 "$_H3"
_debug2 H4 "$_H4"
# _sleep 1
if [ "$m" != "GET" ]; then
_debug2 "${m} $Active24_Api${ep_qs}"
_debug "data" "$data"
response="$(_post "$data" "$Active24_Api${ep_qs}" "" "$m" "application/json")"
else
if [ -z "$data" ]; then
_debug2 "GET $Active24_Api${ep_qs}"
response="$(_get "$Active24_Api${ep_qs}")"
else
_debug2 "GET $Active24_Api${ep_qs} with data: ${data}"
response="$(_post "$data" "$Active24_Api${ep_qs}" "" "$m" "application/json")"
fi
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
@@ -119,23 +204,3 @@ _active24_rest() {
_debug2 response "$response"
return 0
}
_active24_init() {
ACTIVE24_Token="${ACTIVE24_Token:-$(_readaccountconf_mutable ACTIVE24_Token)}"
if [ -z "$ACTIVE24_Token" ]; then
ACTIVE24_Token=""
_err "You didn't specify a Active24 api token yet."
_err "Please create the token and try again."
return 1
fi
_saveaccountconf_mutable ACTIVE24_Token "$ACTIVE24_Token"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
}
+11 -10
View File
@@ -1,12 +1,13 @@
#!/usr/bin/env sh
#
#AD_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje"
#This is the Alwaysdata api wrapper for acme.sh
#
#Author: Paul Koppen
#Report Bugs here: https://github.com/wpk-/acme.sh
# shellcheck disable=SC2034
dns_ad_info='AlwaysData.com
Site: AlwaysData.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ad
Options:
AD_API_KEY API Key
Issues: github.com/acmesh-official/acme.sh/pull/503
Author: Paul Koppen
'
AD_API_URL="https://$AD_API_KEY:@api.alwaysdata.com/v1"
@@ -94,7 +95,7 @@ _get_root() {
if _ad_rest GET "domain/"; then
response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
@@ -105,7 +106,7 @@ _get_root() {
if [ "$hostedzone" ]; then
_domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain=$h
return 0
fi
+88 -70
View File
@@ -1,27 +1,27 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_ali_info='AlibabaCloud.com
Domains: Aliyun.com
Site: AlibabaCloud.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ali
Options:
Ali_Key API Key
Ali_Secret API Secret
'
Ali_API="https://alidns.aliyuncs.com/"
# NOTICE:
# This file is referenced by Alibaba Cloud Services deploy hooks
# https://github.com/acmesh-official/acme.sh/pull/5205#issuecomment-2357867276
# Be careful when modifying this file, especially when making breaking changes for common functions
#Ali_Key="LTqIA87hOKdjevsf5"
#Ali_Secret="0p5EYueFNq501xnCPzKNbx6K51qPH2"
Ali_DNS_API="https://alidns.aliyuncs.com/"
#Usage: dns_ali_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_ali_add() {
fulldomain=$1
txtvalue=$2
Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}"
Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}"
if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then
Ali_Key=""
Ali_Secret=""
_err "You don't specify aliyun api key and secret yet."
return 1
fi
#save the api key and secret to the account conf file.
_saveaccountconf_mutable Ali_Key "$Ali_Key"
_saveaccountconf_mutable Ali_Secret "$Ali_Secret"
_prepare_ali_credentials || return 1
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
@@ -46,14 +46,75 @@ dns_ali_rm() {
_clean
}
#################### Private functions below ##################################
#################### Alibaba Cloud common functions below ####################
_prepare_ali_credentials() {
Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}"
Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}"
if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then
Ali_Key=""
Ali_Secret=""
_err "You don't specify aliyun api key and secret yet."
return 1
fi
#save the api key and secret to the account conf file.
_saveaccountconf_mutable Ali_Key "$Ali_Key"
_saveaccountconf_mutable Ali_Secret "$Ali_Secret"
}
# act ign mtd
_ali_rest() {
act="$1"
ign="$2"
mtd="${3:-GET}"
signature=$(printf "%s" "$mtd&%2F&$(printf "%s" "$query" | _url_encode upper-hex)" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64)
signature=$(printf "%s" "$signature" | _url_encode upper-hex)
url="$endpoint?Signature=$signature"
if [ "$mtd" = "GET" ]; then
url="$url&$query"
response="$(_get "$url")"
else
response="$(_post "$query" "$url" "" "$mtd" "application/x-www-form-urlencoded")"
fi
_ret="$?"
_debug2 response "$response"
if [ "$_ret" != "0" ]; then
_err "Error <$act>"
return 1
fi
if [ -z "$ign" ]; then
message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")"
if [ "$message" ]; then
_err "$message"
return 1
fi
fi
}
_ali_nonce() {
if [ "$ACME_OPENSSL_BIN" ]; then
"$ACME_OPENSSL_BIN" rand -hex 16 2>/dev/null && return 0
fi
printf "%s" "$(date +%s)$$$(date +%N)" | _digest sha256 hex | cut -c 1-32
}
_ali_timestamp() {
date -u +"%Y-%m-%dT%H%%3A%M%%3A%SZ"
}
#################### Private functions below ####################
_get_root() {
domain=$1
i=2
i=1
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
if [ -z "$h" ]; then
#not valid
return 1
@@ -65,7 +126,7 @@ _get_root() {
fi
if _contains "$response" "PageNumber"; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_debug _sub_domain "$_sub_domain"
_domain="$h"
_debug _domain "$_domain"
@@ -77,52 +138,10 @@ _get_root() {
return 1
}
_ali_rest() {
signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64)
signature=$(_ali_urlencode "$signature")
url="$Ali_API?$query&Signature=$signature"
if ! response="$(_get "$url")"; then
_err "Error <$1>"
return 1
fi
_debug2 response "$response"
if [ -z "$2" ]; then
message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")"
if [ "$message" ]; then
_err "$message"
return 1
fi
fi
}
_ali_urlencode() {
_str="$1"
_str_len=${#_str}
_u_i=1
while [ "$_u_i" -le "$_str_len" ]; do
_str_c="$(printf "%s" "$_str" | cut -c "$_u_i")"
case $_str_c in [a-zA-Z0-9.~_-])
printf "%s" "$_str_c"
;;
*)
printf "%%%02X" "'$_str_c"
;;
esac
_u_i="$(_math "$_u_i" + 1)"
done
}
_ali_nonce() {
#_head_n 1 </dev/urandom | _digest "sha256" hex | cut -c 1-31
#Not so good...
date +"%s%N"
}
_check_exist_query() {
_qdomain="$1"
_qsubdomain="$2"
endpoint=$Ali_DNS_API
query=''
query=$query'AccessKeyId='$Ali_Key
query=$query'&Action=DescribeDomainRecords'
@@ -132,12 +151,13 @@ _check_exist_query() {
query=$query'&SignatureMethod=HMAC-SHA1'
query=$query"&SignatureNonce=$(_ali_nonce)"
query=$query'&SignatureVersion=1.0'
query=$query'&Timestamp='$(_timestamp)
query=$query'&Timestamp='$(_ali_timestamp)
query=$query'&TypeKeyWord=TXT'
query=$query'&Version=2015-01-09'
}
_add_record_query() {
endpoint=$Ali_DNS_API
query=''
query=$query'AccessKeyId='$Ali_Key
query=$query'&Action=AddDomainRecord'
@@ -147,13 +167,14 @@ _add_record_query() {
query=$query'&SignatureMethod=HMAC-SHA1'
query=$query"&SignatureNonce=$(_ali_nonce)"
query=$query'&SignatureVersion=1.0'
query=$query'&Timestamp='$(_timestamp)
query=$query'&Timestamp='$(_ali_timestamp)
query=$query'&Type=TXT'
query=$query'&Value='$3
query=$query'&Version=2015-01-09'
}
_delete_record_query() {
endpoint=$Ali_DNS_API
query=''
query=$query'AccessKeyId='$Ali_Key
query=$query'&Action=DeleteDomainRecord'
@@ -162,11 +183,12 @@ _delete_record_query() {
query=$query'&SignatureMethod=HMAC-SHA1'
query=$query"&SignatureNonce=$(_ali_nonce)"
query=$query'&SignatureVersion=1.0'
query=$query'&Timestamp='$(_timestamp)
query=$query'&Timestamp='$(_ali_timestamp)
query=$query'&Version=2015-01-09'
}
_describe_records_query() {
endpoint=$Ali_DNS_API
query=''
query=$query'AccessKeyId='$Ali_Key
query=$query'&Action=DescribeDomainRecords'
@@ -175,7 +197,7 @@ _describe_records_query() {
query=$query'&SignatureMethod=HMAC-SHA1'
query=$query"&SignatureNonce=$(_ali_nonce)"
query=$query'&SignatureVersion=1.0'
query=$query'&Timestamp='$(_timestamp)
query=$query'&Timestamp='$(_ali_timestamp)
query=$query'&Version=2015-01-09'
}
@@ -197,7 +219,3 @@ _clean() {
fi
}
_timestamp() {
date -u +"%Y-%m-%dT%H%%3A%M%%3A%SZ"
}
+185
View File
@@ -0,0 +1,185 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_alviy_info='Alviy.com
Site: Alviy.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_alviy
Options:
Alviy_token API token. Get it from the https://cloud.alviy.com/token
Issues: github.com/acmesh-official/acme.sh/issues/5115
'
Alviy_Api="https://cloud.alviy.com/api/v1"
######## Public functions #####################
#Usage: dns_alviy_add _acme-challenge.www.domain.com "content"
dns_alviy_add() {
fulldomain=$1
txtvalue=$2
Alviy_token="${Alviy_token:-$(_readaccountconf_mutable Alviy_token)}"
if [ -z "$Alviy_token" ]; then
Alviy_token=""
_err "Please specify Alviy token."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf_mutable Alviy_token "$Alviy_token"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting existing records"
if _alviy_txt_exists "$_domain" "$fulldomain" "$txtvalue"; then
_info "This record already exists, skipping"
return 0
fi
_add_data="{\"content\":\"$txtvalue\",\"type\":\"TXT\"}"
_debug2 _add_data "$_add_data"
_info "Adding record"
if _alviy_rest POST "zone/$_domain/domain/$fulldomain/" "$_add_data"; then
_debug "Checking updated records of '${fulldomain}'"
if ! _alviy_txt_exists "$_domain" "$fulldomain" "$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
_sleep 10
_info "Added TXT record '${txtvalue}' for '${fulldomain}'."
return 0
}
#fulldomain
dns_alviy_rm() {
fulldomain=$1
txtvalue=$2
Alviy_token="${Alviy_token:-$(_readaccountconf_mutable Alviy_token)}"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
if ! _alviy_txt_exists "$_domain" "$fulldomain" "$txtvalue"; then
_info "The record does not exist, skip"
return 0
fi
_add_data=""
uuid=$(echo "$response" | tr "{" "\n" | grep "$txtvalue" | tr "," "\n" | grep uuid | cut -d \" -f4)
# delete record
_debug "Delete TXT record for '${fulldomain}'"
if ! _alviy_rest DELETE "zone/$_domain/record/$uuid" "{\"confirm\":1}"; then
_err "Cannot delete empty TXT record for '$fulldomain'"
return 1
fi
_info "The record '$fulldomain'='$txtvalue' deleted"
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain=$1
i=3
a="init"
while [ -n "$a" ]; do
a=$(printf "%s" "$domain" | cut -d . -f $i-)
i=$((i + 1))
done
n=$((i - 3))
h=$(printf "%s" "$domain" | cut -d . -f $n-)
if [ -z "$h" ]; then
#not valid
_alviy_rest GET "zone/$domain/"
_debug "can't get host from $domain"
return 1
fi
if ! _alviy_rest GET "zone/$h/"; then
return 1
fi
if _contains "$response" '"code":"NOT_FOUND"'; then
_debug "$h not found"
else
s=$((n - 1))
_sub_domain=$(printf "%s" "$domain" | cut -d . -f -$s)
_domain="$h"
return 0
fi
return 1
}
_alviy_txt_exists() {
zone=$1
domain=$2
content_data=$3
_debug "Getting existing records"
if ! _alviy_rest GET "zone/$zone/domain/$domain/TXT/"; then
_info "The record does not exist"
return 1
fi
if ! _contains "$response" "$3"; then
_info "The record has other value"
return 1
fi
# GOOD code return - TRUE function
return 0
}
_alviy_rest() {
method=$1
path="$2"
content_data="$3"
_debug "$path"
export _H1="Authorization: Bearer $Alviy_token"
export _H2="Content-Type: application/json"
if [ "$content_data" ] || [ "$method" = "DELETE" ]; then
_debug "data ($method): " "$content_data"
response="$(_post "$content_data" "$Alviy_Api/$path" "" "$method")"
else
response="$(_get "$Alviy_Api/$path")"
fi
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
if [ "$_code" = "401" ]; then
_err "It seems that your api key or secret is not correct."
return 1
fi
if [ "$_code" != "200" ]; then
_err "API call error ($method): $path Response code $_code"
fi
if [ "$?" != "0" ]; then
_err "error on rest call ($method): $path. Response:"
_err "$response"
return 1
fi
_debug2 response "$response"
return 0
}
+11 -9
View File
@@ -1,9 +1,12 @@
#!/usr/bin/env sh
# Anexia CloudDNS acme.sh hook
# Author: MA
#ANX_Token="xxxx"
# shellcheck disable=SC2034
dns_anx_info='Anexia.com CloudDNS
Site: Anexia.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_anx
Options:
ANX_Token API Token
Issues: github.com/acmesh-official/acme.sh/issues/3238
'
ANX_API='https://engine.anexia-it.com/api/clouddns/v1'
@@ -127,18 +130,17 @@ _get_root() {
i=1
p=1
_anx_rest GET "zone.json"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
_anx_rest GET "zone.json/${h}"
if _contains "$response" "\"name\":\"$h\""; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain=$h
return 0
fi
+177
View File
@@ -0,0 +1,177 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_artfiles_info='ArtFiles.de
Site: ArtFiles.de
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_artfiles
Options:
AF_API_USERNAME API Username
AF_API_PASSWORD API Password
Issues: github.com/acmesh-official/acme.sh/issues/4718
Author: Martin Arndt <https://troublezone.net/>
'
########## API configuration ###################################################
AF_API_SUCCESS='status":"OK'
AF_URL_DCP='https://dcp.c.artfiles.de/api/'
AF_URL_DNS=${AF_URL_DCP}'dns/{*}_dns.html?domain='
AF_URL_DOMAINS=${AF_URL_DCP}'domain/get_domains.html'
########## Public functions ####################################################
# Adds a new TXT record for given ACME challenge value & domain.
# Usage: dns_artfiles_add _acme-challenge.www.example.com "ACME challenge value"
dns_artfiles_add() {
domain="$1"
txtValue="$2"
_info 'Using ArtFiles.de DNS addition API…'
_debug 'Domain' "$domain"
_debug 'txtValue' "$txtValue"
_set_credentials
_saveaccountconf_mutable 'AF_API_USERNAME' "$AF_API_USERNAME"
_saveaccountconf_mutable 'AF_API_PASSWORD' "$AF_API_PASSWORD"
_set_headers
_get_zone "$domain"
_dns 'GET'
if ! _contains "$response" 'TXT'; then
_err 'Retrieving TXT records failed.'
return 1
fi
_clean_records
_dns 'SET' "$(printf -- '%s\n_acme-challenge "%s"' "$response" "$txtValue")"
if ! _contains "$response" "$AF_API_SUCCESS"; then
_err 'Adding ACME challenge value failed.'
return 1
fi
}
# Removes the existing TXT record for given ACME challenge value & domain.
# Usage: dns_artfiles_rm _acme-challenge.www.example.com "ACME challenge value"
dns_artfiles_rm() {
domain="$1"
txtValue="$2"
_info 'Using ArtFiles.de DNS removal API…'
_debug 'Domain' "$domain"
_debug 'txtValue' "$txtValue"
_set_credentials
_set_headers
_get_zone "$domain"
if ! _dns 'GET'; then
return 1
fi
if ! _contains "$response" "$txtValue"; then
_err 'Retrieved TXT records are missing given ACME challenge value.'
return 1
fi
_clean_records
response="$(printf -- '%s' "$response" | sed '/_acme-challenge "'"$txtValue"'"/d')"
_dns 'SET' "$response"
if ! _contains "$response" "$AF_API_SUCCESS"; then
_err 'Removing ACME challenge value failed.'
return 1
fi
}
########## Private functions ###################################################
# Cleans awful TXT records response of ArtFiles's API & pretty prints it.
# Usage: _clean_records
_clean_records() {
_info 'Cleaning TXT records…'
# Extract TXT part, strip trailing quote sign (ACME.sh API guidelines forbid
# usage of SED's GNU extensions, hence couldn't omit it via regex), strip '\'
# from '\"' & turn '\n' into real LF characters.
# Yup, awful API to use - but that's all we got to get this working, so… ;)
_debug2 'Raw ' "$response"
response="$(printf -- '%s' "$response" | sed 's/^.*TXT":"\([^}]*\).*$/\1/;s/,".*$//;s/.$//;s/\\"/"/g;s/\\n/\n/g')"
_debug2 'Clean' "$response"
}
# Executes an HTTP GET or POST request for getting or setting DNS records,
# containing given payload upon POST.
# Usage: _dns [GET | SET] [payload]
_dns() {
_info 'Executing HTTP request…'
action="$1"
payload="$(printf -- '%s' "$2" | _url_encode)"
url="$(printf -- '%s%s' "$AF_URL_DNS" "$domain" | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/')"
if [ "$action" = 'SET' ]; then
_debug2 'Payload' "$payload"
response="$(_post '' "$url&TXT=$payload" '' 'POST' 'application/x-www-form-urlencoded')"
else
response="$(_get "$url" '' 10)"
fi
if ! _contains "$response" "$AF_API_SUCCESS"; then
_err "DNS API error: $response"
return 1
fi
_debug 'Response' "$response"
return 0
}
# Gets the root domain zone for given domain.
# Usage: _get_zone _acme-challenge.www.example.com
_get_zone() {
fqdn="$1"
domains="$(_get "$AF_URL_DOMAINS" '' 10)"
_info 'Getting domain zone…'
_debug2 'FQDN' "$fqdn"
_debug2 'Domains' "$domains"
while _contains "$fqdn" "."; do
if _contains "$domains" "$fqdn"; then
domain="$fqdn"
_info "Found root domain zone: $domain"
break
else
fqdn="${fqdn#*.}"
_debug2 'FQDN' "$fqdn"
fi
done
if [ "$domain" = "$fqdn" ]; then
return 0
fi
_err 'Couldn'\''t find root domain zone.'
return 1
}
# Sets the credentials for accessing ArtFiles's API
# Usage: _set_credentials
_set_credentials() {
_info 'Setting credentials…'
AF_API_USERNAME="${AF_API_USERNAME:-$(_readaccountconf_mutable AF_API_USERNAME)}"
AF_API_PASSWORD="${AF_API_PASSWORD:-$(_readaccountconf_mutable AF_API_PASSWORD)}"
if [ -z "$AF_API_USERNAME" ] || [ -z "$AF_API_PASSWORD" ]; then
_err 'Missing ArtFiles.de username and/or password.'
_err 'Please ensure both are set via export command & try again.'
return 1
fi
}
# Adds the HTTP Authorization & Content-Type headers to a follow-up request.
# Usage: _set_headers
_set_headers() {
_info 'Setting headers…'
encoded="$(printf -- '%s:%s' "$AF_API_USERNAME" "$AF_API_PASSWORD" | _base64)"
export _H1="Authorization: Basic $encoded"
export _H2='Content-Type: application/json'
}
+15 -9
View File
@@ -1,11 +1,16 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_arvan_info='ArvanCloud.ir
Site: ArvanCloud.ir
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_arvan
Options:
Arvan_Token API Token
Issues: github.com/acmesh-official/acme.sh/issues/2796
Author: Vahid Fardi
'
#Arvan_Token="Apikey xxxx"
ARVAN_API_URL="https://napi.arvancloud.ir/cdn/4.0/domains"
ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains"
#Author: Vahid Fardi
#Report Bugs here: https://github.com/Neilpang/acme.sh
#
######## Public functions #####################
#Usage: dns_arvan_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
@@ -18,7 +23,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 +45,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
@@ -102,7 +107,7 @@ _get_root() {
i=2
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
@@ -115,7 +120,7 @@ _get_root() {
if _contains "$response" "\"domain\":\"$h\""; then
_domain_id=$(echo "$response" | cut -d : -f 3 | cut -d , -f 1 | tr -d \")
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain=$h
return 0
fi
@@ -141,6 +146,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
+13 -7
View File
@@ -1,9 +1,15 @@
#!/usr/bin/env sh
#
#AURORA_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
#AURORA_Secret="sdfsdfsdfljlbjkljlkjsdfoiwje"
# shellcheck disable=SC2034
dns_aurora_info='versio.nl AuroraDNS
Domains: pcextreme.nl
Site: versio.nl
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_aurora
Options:
AURORA_Key API Key
AURORA_Secret API Secret
Issues: github.com/acmesh-official/acme.sh/issues/3459
Author: Jasper Zonneveld
'
AURORA_Api="https://api.auroradns.eu"
@@ -111,7 +117,7 @@ _get_root() {
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
@@ -126,7 +132,7 @@ _get_root() {
_domain_id=$(echo "$response" | _normalizeJson | tr -d "{}" | tr "," "\n" | grep "\"id\": *\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ")
_debug _domain_id "$_domain_id"
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain=$h
return 0
fi
+13 -14
View File
@@ -1,16 +1,15 @@
#!/usr/bin/env sh
# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*-
# This is the InternetX autoDNS xml api wrapper for acme.sh
# Author: auerswald@gmail.com
# Created: 2018-01-14
#
# export AUTODNS_USER="username"
# export AUTODNS_PASSWORD="password"
# export AUTODNS_CONTEXT="context"
#
# Usage:
# acme.sh --issue --dns dns_autodns -d example.com
# shellcheck disable=SC2034
dns_autodns_info='InternetX autoDNS
InternetX autoDNS XML API
Site: InternetX.com/autodns/
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_autodns
Options:
AUTODNS_USER Username
AUTODNS_PASSWORD Password
AUTODNS_CONTEXT Context
Author: <auerswald@gmail.com>
'
AUTODNS_API="https://gateway.autodns.com"
@@ -111,7 +110,7 @@ _get_autodns_zone() {
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug h "$h"
if [ -z "$h" ]; then
@@ -129,7 +128,7 @@ _get_autodns_zone() {
if _contains "$autodns_response" "<summary>1</summary>" >/dev/null; then
_zone="$(echo "$autodns_response" | _egrep_o '<name>[^<]*</name>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
_system_ns="$(echo "$autodns_response" | _egrep_o '<system_ns>[^<]*</system_ns>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
return 0
fi
+59 -44
View File
@@ -1,13 +1,15 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_aws_info='Amazon AWS Route53 domain API
Site: docs.aws.amazon.com/route53/
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_aws
Options:
AWS_ACCESS_KEY_ID API Key ID
AWS_SECRET_ACCESS_KEY API Secret
'
#
#AWS_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
#AWS_SECRET_ACCESS_KEY="xxxxxxx"
#This is the Amazon Route53 api wrapper for acme.sh
#All `_sleep` commands are included to avoid Route53 throttling, see
#https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html#limits-api-requests
# All `_sleep` commands are included to avoid Route53 throttling, see
# https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html#limits-api-requests
AWS_HOST="route53.amazonaws.com"
AWS_URL="https://$AWS_HOST"
@@ -145,46 +147,34 @@ dns_aws_rm() {
fi
_sleep 1
return 1
}
#################### Private functions below ##################################
_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 | sed 's/\./\\./g')
_debug "Checking domain: $h"
if [ -z "$h" ]; then
_err "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 "<>")
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain=$h
return 0
fi
@@ -192,10 +182,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
}
@@ -209,24 +208,40 @@ _use_container_role() {
}
_use_instance_role() {
_url="http://169.254.169.254/latest/meta-data/iam/security-credentials/"
_debug "_url" "$_url"
if ! _get "$_url" true 1 | _head_n 1 | grep -Fq 200; then
_instance_role_name_url="http://169.254.169.254/latest/meta-data/iam/security-credentials/"
if _get "$_instance_role_name_url" true 1 | _head_n 1 | grep -Fq 401; then
_debug "Using IMDSv2"
_token_url="http://169.254.169.254/latest/api/token"
export _H1="X-aws-ec2-metadata-token-ttl-seconds: 21600"
_token="$(_post "" "$_token_url" "" "PUT")"
_secure_debug3 "_token" "$_token"
if [ -z "$_token" ]; then
_debug "Unable to fetch IMDSv2 token from instance metadata"
return 1
fi
export _H1="X-aws-ec2-metadata-token: $_token"
fi
if ! _get "$_instance_role_name_url" true 1 | _head_n 1 | grep -Fq 200; then
_debug "Unable to fetch IAM role from instance metadata"
return 1
fi
_aws_role=$(_get "$_url" "" 1)
_debug "_aws_role" "$_aws_role"
_use_metadata "$_url$_aws_role"
_instance_role_name=$(_get "$_instance_role_name_url" "" 1)
_debug "_instance_role_name" "$_instance_role_name"
_use_metadata "$_instance_role_name_url$_instance_role_name" "$_token"
}
_use_metadata() {
export _H1="X-aws-ec2-metadata-token: $2"
_aws_creds="$(
_get "$1" "" 1 |
_normalizeJson |
tr '{,}' '\n' |
while read -r _line; do
_key="$(echo "${_line%%:*}" | tr -d '"')"
_key="$(echo "${_line%%:*}" | tr -d '\"')"
_value="${_line#*:}"
_debug3 "_key" "$_key"
_secure_debug3 "_value" "$_value"
+11 -7
View File
@@ -1,9 +1,13 @@
#!/usr/bin/env sh
#
#AZION_Email=""
#AZION_Password=""
#
# shellcheck disable=SC2034
dns_azion_info='Azion.om
Site: Azion.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_azion
Options:
AZION_Email Email
AZION_Password Password
Issues: github.com/acmesh-official/acme.sh/issues/3555
'
AZION_Api="https://api.azionapi.net"
@@ -96,7 +100,7 @@ _get_root() {
fi
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug h "$h"
if [ -z "$h" ]; then
# not valid
@@ -107,7 +111,7 @@ _get_root() {
_domain_id=$(echo "$response" | tr '{' "\n" | grep "\"domain\":\"$h\"" | _egrep_o "\"id\":[0-9]*" | _head_n 1 | 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)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain=$h
return 0
fi
+120 -70
View File
@@ -1,13 +1,25 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_azure_info='Azure
Site: Azure.microsoft.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_azure
Options:
AZUREDNS_SUBSCRIPTIONID Subscription ID
AZUREDNS_TENANTID Tenant ID
AZUREDNS_APPID App ID. App ID of the service principal
AZUREDNS_CLIENTSECRET Client Secret. Secret from creating the service principal
AZUREDNS_MANAGEDIDENTITY Use Managed Identity. Use Managed Identity assigned to a resource instead of a service principal. "true"/"false"
AZUREDNS_BEARERTOKEN Bearer Token. Used instead of service principal credentials or managed identity. Optional.
'
WIKI="https://github.com/acmesh-official/acme.sh/wiki/How-to-use-Azure-DNS"
wiki=https://github.com/acmesh-official/acme.sh/wiki/How-to-use-Azure-DNS
######## Public functions #####################
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Used to add txt record
#
# Ref: https://docs.microsoft.com/en-us/rest/api/dns/recordsets/createorupdate
# Ref: https://learn.microsoft.com/en-us/rest/api/dns/record-sets/create-or-update?view=rest-dns-2018-05-01&tabs=HTTP
#
dns_azure_add() {
@@ -20,6 +32,7 @@ dns_azure_add() {
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
AZUREDNS_BEARERTOKEN=""
_err "You didn't specify the Azure Subscription ID"
return 1
fi
@@ -34,37 +47,45 @@ dns_azure_add() {
_saveaccountconf_mutable AZUREDNS_TENANTID ""
_saveaccountconf_mutable AZUREDNS_APPID ""
_saveaccountconf_mutable AZUREDNS_CLIENTSECRET ""
_saveaccountconf_mutable AZUREDNS_BEARERTOKEN ""
else
_info "You didn't ask to use Azure managed identity, checking service principal credentials"
_info "You didn't ask to use Azure managed identity, checking service principal credentials or provided bearer token"
AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}"
AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}"
AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}"
AZUREDNS_BEARERTOKEN="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}"
if [ -z "$AZUREDNS_BEARERTOKEN" ]; then
if [ -z "$AZUREDNS_TENANTID" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
AZUREDNS_BEARERTOKEN=""
_err "You didn't specify the Azure Tenant ID "
return 1
fi
if [ -z "$AZUREDNS_TENANTID" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
_err "You didn't specify the Azure Tenant ID "
return 1
fi
if [ -z "$AZUREDNS_APPID" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
AZUREDNS_BEARERTOKEN=""
_err "You didn't specify the Azure App ID"
return 1
fi
if [ -z "$AZUREDNS_APPID" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
_err "You didn't specify the Azure App ID"
return 1
fi
if [ -z "$AZUREDNS_CLIENTSECRET" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
_err "You didn't specify the Azure Client Secret"
return 1
if [ -z "$AZUREDNS_CLIENTSECRET" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
AZUREDNS_BEARERTOKEN=""
_err "You didn't specify the Azure Client Secret"
return 1
fi
else
_info "Using provided bearer token"
fi
#save account details to account conf file, don't opt in for azure manages identity check.
@@ -72,9 +93,14 @@ dns_azure_add() {
_saveaccountconf_mutable AZUREDNS_TENANTID "$AZUREDNS_TENANTID"
_saveaccountconf_mutable AZUREDNS_APPID "$AZUREDNS_APPID"
_saveaccountconf_mutable AZUREDNS_CLIENTSECRET "$AZUREDNS_CLIENTSECRET"
_saveaccountconf_mutable AZUREDNS_BEARERTOKEN "$AZUREDNS_BEARERTOKEN"
fi
accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET")
if [ -z "$AZUREDNS_BEARERTOKEN" ]; then
accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET")
else
accesstoken=$(echo "$AZUREDNS_BEARERTOKEN" | sed "s/Bearer //g")
fi
if ! _get_root "$fulldomain" "$AZUREDNS_SUBSCRIPTIONID" "$accesstoken"; then
_err "invalid domain"
@@ -124,7 +150,7 @@ dns_azure_add() {
# Usage: fulldomain txtvalue
# Used to remove the txt record after validation
#
# Ref: https://docs.microsoft.com/en-us/rest/api/dns/recordsets/delete
# Ref: https://learn.microsoft.com/en-us/rest/api/dns/record-sets/delete?view=rest-dns-2018-05-01&tabs=HTTP
#
dns_azure_rm() {
fulldomain=$1
@@ -136,6 +162,7 @@ dns_azure_rm() {
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
AZUREDNS_BEARERTOKEN=""
_err "You didn't specify the Azure Subscription ID "
return 1
fi
@@ -144,40 +171,51 @@ dns_azure_rm() {
if [ "$AZUREDNS_MANAGEDIDENTITY" = true ]; then
_info "Using Azure managed identity"
else
_info "You didn't ask to use Azure managed identity, checking service principal credentials"
_info "You didn't ask to use Azure managed identity, checking service principal credentials or provided bearer token"
AZUREDNS_TENANTID="${AZUREDNS_TENANTID:-$(_readaccountconf_mutable AZUREDNS_TENANTID)}"
AZUREDNS_APPID="${AZUREDNS_APPID:-$(_readaccountconf_mutable AZUREDNS_APPID)}"
AZUREDNS_CLIENTSECRET="${AZUREDNS_CLIENTSECRET:-$(_readaccountconf_mutable AZUREDNS_CLIENTSECRET)}"
AZUREDNS_BEARERTOKEN="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}"
if [ -z "$AZUREDNS_BEARERTOKEN" ]; then
if [ -z "$AZUREDNS_TENANTID" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
AZUREDNS_BEARERTOKEN=""
_err "You didn't specify the Azure Tenant ID "
return 1
fi
if [ -z "$AZUREDNS_TENANTID" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
_err "You didn't specify the Azure Tenant ID "
return 1
fi
if [ -z "$AZUREDNS_APPID" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
AZUREDNS_BEARERTOKEN=""
_err "You didn't specify the Azure App ID"
return 1
fi
if [ -z "$AZUREDNS_APPID" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
_err "You didn't specify the Azure App ID"
return 1
fi
if [ -z "$AZUREDNS_CLIENTSECRET" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
_err "You didn't specify the Azure Client Secret"
return 1
if [ -z "$AZUREDNS_CLIENTSECRET" ]; then
AZUREDNS_SUBSCRIPTIONID=""
AZUREDNS_TENANTID=""
AZUREDNS_APPID=""
AZUREDNS_CLIENTSECRET=""
AZUREDNS_BEARERTOKEN=""
_err "You didn't specify the Azure Client Secret"
return 1
fi
else
_info "Using provided bearer token"
fi
fi
accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET")
if [ -z "$AZUREDNS_BEARERTOKEN" ]; then
accesstoken=$(_azure_getaccess_token "$AZUREDNS_MANAGEDIDENTITY" "$AZUREDNS_TENANTID" "$AZUREDNS_APPID" "$AZUREDNS_CLIENTSECRET")
else
accesstoken=$(echo "$AZUREDNS_BEARERTOKEN" | sed "s/Bearer //g")
fi
if ! _get_root "$fulldomain" "$AZUREDNS_SUBSCRIPTIONID" "$accesstoken"; then
_err "invalid domain"
@@ -256,10 +294,10 @@ _azure_rest() {
if [ "$_code" = "401" ]; then
# we have an invalid access token set to expired
_saveaccountconf_mutable AZUREDNS_TOKENVALIDTO "0"
_err "access denied make sure your Azure settings are correct. See $WIKI"
_err "Access denied. Invalid access token. Make sure your Azure settings are correct. See: $wiki"
return 1
fi
# See https://docs.microsoft.com/en-us/azure/architecture/best-practices/retry-service-specific#general-rest-and-retry-guidelines for retryable HTTP codes
# See https://learn.microsoft.com/en-us/azure/architecture/best-practices/retry-service-specific#general-rest-and-retry-guidelines for retryable HTTP codes
if [ "$_ret" != "0" ] || [ -z "$_code" ] || [ "$_code" = "408" ] || [ "$_code" = "500" ] || [ "$_code" = "503" ] || [ "$_code" = "504" ]; then
_request_retry_times="$(_math "$_request_retry_times" + 1)"
_info "REST call error $_code retrying $ep in $_request_retry_times s"
@@ -277,14 +315,14 @@ _azure_rest() {
return 0
}
## Ref: https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-service-to-service#request-an-access-token
## Ref: https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow#request-an-access-token
_azure_getaccess_token() {
managedIdentity=$1
tenantID=$2
clientID=$3
clientSecret=$4
accesstoken="${AZUREDNS_BEARERTOKEN:-$(_readaccountconf_mutable AZUREDNS_BEARERTOKEN)}"
accesstoken="${AZUREDNS_ACCESSTOKEN:-$(_readaccountconf_mutable AZUREDNS_ACCESSTOKEN)}"
expires_on="${AZUREDNS_TOKENVALIDTO:-$(_readaccountconf_mutable AZUREDNS_TOKENVALIDTO)}"
# can we reuse the bearer token?
@@ -301,9 +339,18 @@ _azure_getaccess_token() {
_debug "getting new bearer token"
if [ "$managedIdentity" = true ]; then
# https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http
export _H1="Metadata: true"
response="$(_get http://169.254.169.254/metadata/identity/oauth2/token\?api-version=2018-02-01\&resource=https://management.azure.com/)"
# https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http
if [ -n "$IDENTITY_ENDPOINT" ]; then
# Some Azure environments may set IDENTITY_ENDPOINT (formerly MSI_ENDPOINT) to have an alternative metadata endpoint
url="$IDENTITY_ENDPOINT?api-version=2019-08-01&resource=https://management.azure.com/"
headers="X-IDENTITY-HEADER: $IDENTITY_HEADER"
else
url="http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
headers="Metadata: true"
fi
export _H1="$headers"
response="$(_get "$url")"
response="$(echo "$response" | _normalizeJson)"
accesstoken=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
expires_on=$(echo "$response" | _egrep_o "\"expires_on\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
@@ -321,14 +368,14 @@ _azure_getaccess_token() {
fi
if [ -z "$accesstoken" ]; then
_err "no acccess token received. Check your Azure settings see $WIKI"
_err "No acccess token received. Check your Azure settings. See: $wiki"
return 1
fi
if [ "$_ret" != "0" ]; then
_err "error $response"
return 1
fi
_saveaccountconf_mutable AZUREDNS_BEARERTOKEN "$accesstoken"
_saveaccountconf_mutable AZUREDNS_ACCESSTOKEN "$accesstoken"
_saveaccountconf_mutable AZUREDNS_TOKENVALIDTO "$expires_on"
printf "%s" "$accesstoken"
return 0
@@ -341,15 +388,18 @@ _get_root() {
i=1
p=1
## Ref: https://docs.microsoft.com/en-us/rest/api/dns/zones/list
## returns up to 100 zones in one response therefore handling more results is not not implemented
## (ZoneListResult with continuation token for the next page of results)
## Per https://docs.microsoft.com/en-us/azure/azure-subscription-service-limits#dns-limits you are limited to 100 Zone/subscriptions anyways
## Ref: https://learn.microsoft.com/en-us/rest/api/dns/zones/list?view=rest-dns-2018-05-01&tabs=HTTP
## returns up to 100 zones in one response. Handling more results is not implemented
## (ZoneListResult with continuation token for the next page of results)
##
## TODO: handle more than 100 results, as per:
## https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/azure-subscription-service-limits#azure-dns-limits
## The new limit is 250 Public DNS zones per subscription, while the old limit was only 100
##
_azure_rest GET "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Network/dnszones?\$top=500&api-version=2017-09-01" "" "$accesstoken"
# Find matching domain name in Json response
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug2 "Checking domain: $h"
if [ -z "$h" ]; then
#not valid
@@ -364,7 +414,7 @@ _get_root() {
#create the record at the domain apex (@) if only the domain name was provided as --domain-alias
_sub_domain="@"
else
_sub_domain=$(echo "$domain" | cut -d . -f 1-$p)
_sub_domain=$(echo "$domain" | cut -d . -f 1-"$p")
fi
_domain=$h
return 0
+548
View File
@@ -0,0 +1,548 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
# Global variables for returning results (avoid stdout pollution from logging)
_BAIDU_FIND_RESULT=""
_BAIDU_BCE_AUTH_RESULT=""
: "${BAIDU_LOG_LEVEL:=2}"
_baidu_log_ts() {
date
}
_baidu_log_ge() {
_want="$1"
[ "${BAIDU_LOG_LEVEL:-0}" -ge "$_want" ]
}
_baidu_log() {
_lvl="$1"
_tag="$2"
_msg="$3"
if [ "$_lvl" = "0" ] || _baidu_log_ge "$_lvl"; then
printf -- "[%s] %s %s\n" "$(_baidu_log_ts)" "$_tag" "$_msg"
fi
}
_baidu_err() {
_baidu_log 0 "baidu_bcd.err" "$1"
return 1
}
_baidu_info() {
_baidu_log 1 "baidu_bcd.info" "$1"
return 0
}
_baidu_debug() {
_baidu_log 2 "$1" "$2"
return 0
}
dns_baidu_info='Baidu Cloud BCD DNS
Site: cloud.baidu.com
Docs: https://cloud.baidu.com/doc/BCD/
Signature: https://cloud.baidu.com/doc/Reference/s/njwvz1yfu
Options:
Baidu_AK AccessKeyId
Baidu_SK SecretAccessKey
OptionsAlt:
Baidu_BCD_Host API host, default: bcd.baidubce.com
Baidu_BCD_Version API version number, default: 1
Baidu_BCD_Expire Signature expiration seconds, default: 3600
Baidu_View Resolve view, default: DEFAULT
Baidu_TTL Resolve ttl seconds, default: 300
Baidu_RM_Max Max records to delete in one run, default: 20
'
BAIDU_BCD_DEFAULT_HOST="bcd.baidubce.com"
# --- Public API ---
dns_baidu_add() {
fulldomain=$(_idn "$1")
txtvalue=$2
if ! _baidu_prepare_record "$fulldomain"; then
_baidu_err "baidu_prepare_record failed for add: $fulldomain"
return 1
fi
if ! _baidu_find_record_ids "$_zone_name" "$_record_domain" "TXT" "$txtvalue"; then
_baidu_err "baidu_find_record_ids failed for add: $_record_domain.$_zone_name"
return 1
fi
_existing_ids="$_BAIDU_FIND_RESULT"
if [ "$_existing_ids" ]; then
_baidu_info "txt exists, skip add: $_record_domain.$_zone_name"
return 0
fi
_ttl="${Baidu_TTL:-300}"
_ttl="$(_baidu_trim_ws "$_ttl")"
case "$_ttl" in
"" | *[!0-9]*)
_ttl="300"
;;
esac
_view="$(_baidu_trim_ws "${Baidu_View:-DEFAULT}")"
txtvalue="$(_baidu_trim_ws "$txtvalue")"
_record_domain="$(_baidu_trim_ws "$_record_domain")"
_zone_name="$(_baidu_trim_ws "$_zone_name")"
_body="$(_baidu_payload_add_txt "$_zone_name" "$_record_domain" "$txtvalue" "$_ttl" "$_view")"
if ! _baidu_bcd_post "/domain/resolve/add" "$_body"; then
_baidu_err "baidu_bcd_post failed: add record"
return 1
fi
if _baidu_is_api_error "$response"; then
_baidu_err "$response"
return 1
fi
return 0
}
dns_baidu_rm() {
fulldomain=$(_idn "$1")
txtvalue=$2
if ! _baidu_prepare_record "$fulldomain"; then
_baidu_err "baidu_prepare_record failed for delete: $fulldomain"
return 1
fi
if ! _baidu_find_record_ids "$_zone_name" "$_record_domain" "TXT" "$txtvalue"; then
_baidu_err "baidu_find_record_ids failed for delete: $_record_domain.$_zone_name"
return 1
fi
_ids="$_BAIDU_FIND_RESULT"
if [ -z "$_ids" ]; then
_baidu_info "no matching txt to delete: $_record_domain.$_zone_name"
return 0
fi
_rm_max="${Baidu_RM_Max:-20}"
_rm_max="$(_baidu_trim_ws "$_rm_max")"
case "$_rm_max" in
"" | *[!0-9]*)
_rm_max="20"
;;
esac
_rm_cnt="$(printf "%s\n" "$_ids" | sed '/^$/d' | wc -l | tr -d ' ')"
if [ "$_rm_cnt" ] && [ "$_rm_cnt" -gt "$_rm_max" ]; then
_baidu_err "Refusing to delete $_rm_cnt records (limit: $_rm_max)"
return 1
fi
for _rid in $_ids; do
_body="$(_baidu_payload_delete "$_zone_name" "$_rid")"
if ! _baidu_bcd_post "/domain/resolve/delete" "$_body"; then
_baidu_err "baidu_bcd_post failed: delete recordId=$_rid"
return 1
fi
if _baidu_is_api_error "$response"; then
_baidu_err "$response"
return 1
fi
done
if ! _baidu_find_record_ids "$_zone_name" "$_record_domain" "TXT" "$txtvalue"; then
_baidu_err "baidu_find_record_ids failed for delete verify: $_record_domain.$_zone_name"
return 1
fi
_left_ids="$_BAIDU_FIND_RESULT"
if [ -z "$_left_ids" ]; then
return 0
fi
if [ -n "$_left_ids" ]; then
_baidu_err "delete verification failed: $_record_domain.$_zone_name still has TXT records"
return 1
fi
return 0
}
# --- Config / Record Context ---
_baidu_load_credentials() {
Baidu_AK="${Baidu_AK:-$(_readaccountconf_mutable Baidu_AK)}"
Baidu_SK="${Baidu_SK:-$(_readaccountconf_mutable Baidu_SK)}"
Baidu_AK="$(_baidu_trim_ws "$Baidu_AK")"
Baidu_SK="$(_baidu_trim_ws "$Baidu_SK")"
if [ -z "$Baidu_AK" ] || [ -z "$Baidu_SK" ]; then
_baidu_err "Baidu_AK and Baidu_SK are required"
return 1
fi
_saveaccountconf_mutable Baidu_AK "$Baidu_AK"
_saveaccountconf_mutable Baidu_SK "$Baidu_SK"
BAIDU_BCD_HOST="${Baidu_BCD_Host:-$BAIDU_BCD_DEFAULT_HOST}"
BAIDU_BCD_VERSION="${Baidu_BCD_Version:-1}"
return 0
}
_baidu_prepare_record() {
_fulldomain="$1"
if ! _baidu_load_credentials; then
_baidu_err "baidu_load_credentials failed"
return 1
fi
if ! _baidu_get_root "$_fulldomain"; then
_baidu_err "Could not find zone for $_fulldomain"
return 1
fi
_record_domain="$_sub_domain"
_zone_name="$_domain"
return 0
}
# --- Zone / Records ---
_baidu_get_root() {
domain=$1
i=1
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
if [ -z "$h" ]; then
_baidu_err "invalid domain: $domain"
return 1
fi
if ! _baidu_bcd_post "/domain/resolve/list" "$(_baidu_payload_list "$h" 1 1)"; then
_baidu_err "baidu_bcd_post failed: list zones"
return 1
fi
if ! _baidu_is_api_error "$response" && (_contains "$response" "\"totalCount\"" || _contains "$response" "\"result\""); then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain=$h
if [ "$_sub_domain" = "$_domain" ]; then
_sub_domain="@"
fi
_baidu_info "zone matched: $_domain (host: $_sub_domain)"
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
}
_baidu_find_record_ids() {
_zone_name="$1"
_record_domain="$2"
_rdtype="$3"
_rdata="$4"
# Reset global result variable
_BAIDU_FIND_RESULT=""
_zone_name_e="$(_baidu_json_escape "$_zone_name")"
_record_domain_e="$(_baidu_json_escape "$_record_domain")"
_rdtype_e="$(_baidu_json_escape "$_rdtype")"
_rdata_e="$(_baidu_json_escape "$_rdata")"
_page=1
_page_size=100
_ids=""
_max_page=""
while true; do
if ! _baidu_bcd_post "/domain/resolve/list" "$(_baidu_payload_list "$_zone_name" "$_page" "$_page_size")"; then
_baidu_err "baidu_bcd_post failed: list records"
return 1
fi
if _baidu_is_api_error "$response"; then
_baidu_err "baidu_bcd error: $(_baidu_json_get_str "$response" "code") $(_baidu_json_get_str "$response" "message")"
return 1
fi
_normalized="$(
printf "%s" "$response" | _normalizeJson
)"
if [ -z "$_max_page" ]; then
_total="$(_baidu_parse_totalcount "$_normalized")"
_max_page="$(_baidu_calc_max_page "$_total" "$_page_size")"
fi
_records=$(printf "%s" "$_normalized" | sed 's/},{/}\n{/g')
while IFS= read -r _line; do
_id="$(_baidu_match_record_id "$_line" "$_record_domain_e" "$_rdtype_e" "$_rdata_e")"
if [ "$_id" ]; then
_ids="$_ids $_id"
fi
done <<EOF
$_records
EOF
if [ "$_page" -ge "$_max_page" ]; then
break
fi
_page=$(_math "$_page" + 1)
done
# Store result in global variable instead of stdout
_BAIDU_FIND_RESULT="$_ids"
}
# --- HTTP ---
_baidu_bcd_post() {
_api_path="$1"
_payload="$2"
# BCD API requires JSON payload. Some call sites build fragments; normalize defensively.
_payload="$(_baidu_normalize_payload "$_payload")"
_ts="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
_expire="${Baidu_BCD_Expire:-3600}"
_content_type="application/json; charset=utf-8"
_payload_hash="$(printf "%s" "$_payload" | _digest sha256 hex)"
_uri="/v${BAIDU_BCD_VERSION}${_api_path}"
if ! _baidu_bce_auth "POST" "$_uri" "" "$BAIDU_BCD_HOST" "$_ts" "$_expire" "$_content_type" "$_payload_hash"; then
_baidu_err "baidu_bcd auth failed"
return 1
fi
_auth="$_BAIDU_BCE_AUTH_RESULT"
if [ -z "$_auth" ]; then
_baidu_err "baidu_bcd auth failed"
return 1
fi
_H1="Authorization: $_auth"
_H2="x-bce-date: $_ts"
_H3="x-bce-content-sha256: $_payload_hash"
_H4="Host: $BAIDU_BCD_HOST"
_H5=""
_url="https://${BAIDU_BCD_HOST}${_uri}"
_signed_headers_dbg="$(printf "%s" "$_auth" | cut -d / -f 5)"
_baidu_info "POST ${_uri}"
_baidu_info "signedHeaders: $_signed_headers_dbg"
_baidu_info "payload_sha256: $_payload_hash"
_baidu_debug "baidu_bcd.http.payload" "$(_baidu_dbg_trim "$(_baidu_redact_txt "$_payload")")"
response="$(_post "$_payload" "$_url" "" "POST" "$_content_type")"
_ret="$?"
_baidu_info "ret: $_ret"
_req_id="$(_baidu_json_get_str "$response" "requestId")"
_code="$(_baidu_json_get_str "$response" "code")"
_msg="$(_baidu_json_get_str "$response" "message")"
_baidu_info "response: requestId=${_req_id:-"-"} code=${_code:-"-"} message=$(_baidu_dbg_trim "${_msg:-"-"}")"
if [ "$_ret" != "0" ]; then
_baidu_err "baidu_bcd_post failed: $_uri"
return 1
fi
return 0
}
# --- Auth / Signing ---
_baidu_bce_auth() {
# Signing algorithm (bce-auth-v1):
# - SigningKey = HMAC-SHA256-HEX(sk, authStringPrefix)
# - Signature = HMAC-SHA256-HEX(SigningKey, CanonicalRequest)
# Reference: https://cloud.baidu.com/doc/Reference/s/njwvz1yfu
_method="$1"
_uri="$2"
_query="$3"
_host="$4"
_ts="$5"
_expire="$6"
_ct="$7"
_payload_hash="$8"
_BAIDU_BCE_AUTH_RESULT=""
_auth_prefix="bce-auth-v1/${Baidu_AK}/${_ts}/${_expire}"
_signed_headers="content-type;host;x-bce-content-sha256;x-bce-date"
_canonical_uri="$(_baidu_bce_encode_path "$_uri")"
_canonical_query=""
_host_v="$(_baidu_trim_ws "$_host")"
_date_v="$(_baidu_trim_ws "$_ts")"
_ct_v="$(_baidu_trim_ws "$_ct")"
_host_e="$(printf "%s" "$_host_v" | _url_encode upper-hex)"
_date_e="$(printf "%s" "$_date_v" | _url_encode upper-hex)"
_ct_e="$(printf "%s" "$_ct_v" | _url_encode upper-hex)"
_hash_e="$(printf "%s" "$_payload_hash" | _url_encode upper-hex)"
_canonical_headers="content-type:${_ct_e}
host:${_host_e}
x-bce-content-sha256:${_hash_e}
x-bce-date:${_date_e}"
_canonical_request="${_method}
${_canonical_uri}
${_canonical_query}
${_canonical_headers}"
_sk_hex="$(printf "%s" "$Baidu_SK" | _hex_dump | tr -d " ")"
_signing_key="$(_baidu_hmac_sha256_hexkey "$_sk_hex" "$_auth_prefix")"
_signing_key_hex="$(printf "%s" "$_signing_key" | _hex_dump | tr -d " ")"
_signature="$(_baidu_hmac_sha256_hexkey "$_signing_key_hex" "$_canonical_request")"
_baidu_debug "baidu_bcd.auth" "bce_auth"
_baidu_debug "baidu_bcd.auth.auth_prefix" "bce-auth-v1/[ak]/${_ts}/${_expire}/$_signed_headers/[signature]"
_baidu_debug "baidu_bcd.auth.canonical_request_l" "$(printf "%s" "$_canonical_request" | sed -n 'l')"
_baidu_debug "baidu_bcd.auth.signature" "$(printf "%s" "$_signature" | cut -c 1-16)..."
_BAIDU_BCE_AUTH_RESULT="${_auth_prefix}/${_signed_headers}/${_signature}"
return 0
}
_baidu_bce_encode_path() {
_p="$1"
_out=""
if [ "${_p#"/"}" != "$_p" ]; then
_out="/"
fi
_rest="${_p#/}"
while [ -n "$_rest" ]; do
_seg="${_rest%%/*}"
if [ "$_seg" ]; then
if [ -z "$_out" ] || [ "$_out" = "/" ]; then
_out="${_out}$(printf "%s" "$_seg" | _url_encode upper-hex)"
else
_out="${_out}/$(printf "%s" "$_seg" | _url_encode upper-hex)"
fi
fi
if [ "${_rest#*/}" = "$_rest" ]; then
break
fi
_rest="${_rest#*/}"
done
if [ -z "$_out" ]; then
_out="/"
fi
printf "%s" "$_out"
}
# --- Utils ---
_baidu_trim() {
printf "%s" "$1" | sed 's/^ *//;s/ *$//'
}
_baidu_trim_ws() {
printf "%s" "$1" | tr '\r\n\t' ' ' | tr -s ' ' | sed 's/^ *//;s/ *$//'
}
_baidu_dbg_trim() {
printf "%s" "$1" | tr '\r\n' ' ' | cut -c 1-800
}
_baidu_is_api_error() {
_contains "$1" "\"code\"" && _contains "$1" "\"message\""
}
_baidu_normalize_payload() {
_p="$(_baidu_trim "$(printf "%s" "$1" | tr -d '\r')")"
if [ -z "$_p" ]; then
printf "%s" ""
return 0
fi
case "$_p" in
\{* | \[*)
printf "%s" "$_p"
;;
*)
printf "%s" "{$_p}"
;;
esac
}
_baidu_redact_txt() {
printf "%s" "$1" | sed 's/"rdata" *: *"[^"]*"/"rdata":"[redacted]"/g'
}
_baidu_json_get_str() {
_json="$1"
_key="$2"
printf "%s" "$_json" | _normalizeJson | sed -n "s/.*\"${_key}\" *: *\"\\([^\"]*\\)\".*/\\1/p" | _head_n 1
}
_baidu_json_escape() {
_s="$1"
_s="$(printf "%s" "$_s" | tr -d '\r\n')"
printf "%s" "$_s" |
sed 's/\\/\\\\/g; s/ /\\t/g' |
_baidu_json_encode
}
_baidu_json_encode() {
_j_str="$(sed 's/"/\\"/g' | sed "s/\r/\\r/g")"
printf "%s" "$_j_str" | _hex_dump | _lower_case | sed 's/0a/5c 6e/g' | tr -d ' ' | _h2b | tr -d "\r\n"
}
_baidu_payload_list() {
_domain="$(_baidu_json_escape "$1")"
_pageNo="$2"
_pageSize="$3"
printf "%s" "{\"domain\":\"${_domain}\",\"pageNo\":${_pageNo},\"pageSize\":${_pageSize}}"
}
_baidu_payload_add_txt() {
_zoneName="$(_baidu_json_escape "$1")"
_domain="$(_baidu_json_escape "$2")"
_rdata="$(_baidu_json_escape "$3")"
_ttl="$4"
_view="$(_baidu_json_escape "$5")"
printf "%s" "{\"domain\":\"${_domain}\",\"view\":\"${_view}\",\"rdType\":\"TXT\",\"ttl\":${_ttl},\"rdata\":\"${_rdata}\",\"zoneName\":\"${_zoneName}\"}"
}
_baidu_payload_delete() {
_zoneName="$(_baidu_json_escape "$1")"
_recordId="$2"
printf "%s" "{\"zoneName\":\"${_zoneName}\",\"recordId\":${_recordId}}"
}
_baidu_parse_totalcount() {
_json="$1"
printf "%s" "$_json" | _egrep_o "\"totalCount\": *[0-9]*" | _head_n 1 | cut -d : -f 2 | tr -d " "
}
_baidu_calc_max_page() {
_total="$1"
_page_size="$2"
if [ -z "$_total" ]; then
printf "%s" "1"
return 0
fi
_max=$(((_total + _page_size - 1) / _page_size))
if [ "$_max" -lt 1 ]; then
_max=1
fi
printf "%s" "$_max"
}
_baidu_match_record_id() {
_line="$1"
_domain_e="$2"
_rdtype_e="$3"
_rdata_e="$4"
if ! _contains "$_line" "\"recordId\"" || (! _contains "$_line" "\"domain\":\"$_domain_e\"" && ! _contains "$_line" "\"domain\":\"${_domain_e}.\""); then
return 0
fi
if ! _contains "$_line" "\"rdtype\":\"$_rdtype_e\"" && ! _contains "$_line" "\"rdType\":\"$_rdtype_e\""; then
return 0
fi
if [ "$_rdata_e" ] && ! _contains "$_line" "\"rdata\":\"$_rdata_e\""; then
return 0
fi
printf "%s" "$_line" | _egrep_o "\"recordId\": *[0-9]*" | _head_n 1 | cut -d : -f 2 | tr -d " "
}
_baidu_hmac_sha256_hexkey() {
_key_hex="$1"
_msg="$2"
printf "%s" "$_msg" | _hmac sha256 "$_key_hex" hex
}
+281
View File
@@ -0,0 +1,281 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_beget_info='Beget.com
Site: Beget.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_beget
Options:
BEGET_User API user
BEGET_Password API password
Issues: github.com/acmesh-official/acme.sh/issues/6200
Author: ARNik <arnik@arnik.ru>
'
Beget_Api="https://api.beget.com/api"
#################### Public functions ####################
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Used to add txt record
dns_beget_add() {
fulldomain=$1
txtvalue=$2
_debug "dns_beget_add() $fulldomain $txtvalue"
fulldomain=$(echo "$fulldomain" | _lower_case)
Beget_Username="${Beget_Username:-$(_readaccountconf_mutable Beget_Username)}"
Beget_Password="${Beget_Password:-$(_readaccountconf_mutable Beget_Password)}"
if [ -z "$Beget_Username" ] || [ -z "$Beget_Password" ]; then
Beget_Username=""
Beget_Password=""
_err "You must export variables: Beget_Username, and Beget_Password"
return 1
fi
#save the credentials to the account conf file.
_saveaccountconf_mutable Beget_Username "$Beget_Username"
_saveaccountconf_mutable Beget_Password "$Beget_Password"
_info "Prepare subdomain."
if ! _prepare_subdomain "$fulldomain"; then
_err "Can't prepare subdomain."
return 1
fi
_info "Get domain records"
data="{\"fqdn\":\"$fulldomain\"}"
res=$(_api_call "$Beget_Api/dns/getData" "$data")
if ! _is_api_reply_ok "$res"; then
_err "Can't get domain records."
return 1
fi
_info "Add new TXT record"
data="{\"fqdn\":\"$fulldomain\",\"records\":{"
data=${data}$(_parce_records "$res" "A")
data=${data}$(_parce_records "$res" "AAAA")
data=${data}$(_parce_records "$res" "CAA")
data=${data}$(_parce_records "$res" "MX")
data=${data}$(_parce_records "$res" "SRV")
data=${data}$(_parce_records "$res" "TXT")
data=$(echo "$data" | sed 's/,$//')
data=${data}'}}'
str=$(_txt_to_dns_json "$txtvalue")
data=$(_add_record "$data" "TXT" "$str")
res=$(_api_call "$Beget_Api/dns/changeRecords" "$data")
if ! _is_api_reply_ok "$res"; then
_err "Can't change domain records."
return 1
fi
return 0
}
# Usage: fulldomain txtvalue
# Used to remove the txt record after validation
dns_beget_rm() {
fulldomain=$1
txtvalue=$2
_debug "dns_beget_rm() $fulldomain $txtvalue"
fulldomain=$(echo "$fulldomain" | _lower_case)
Beget_Username="${Beget_Username:-$(_readaccountconf_mutable Beget_Username)}"
Beget_Password="${Beget_Password:-$(_readaccountconf_mutable Beget_Password)}"
_info "Get current domain records"
data="{\"fqdn\":\"$fulldomain\"}"
res=$(_api_call "$Beget_Api/dns/getData" "$data")
if ! _is_api_reply_ok "$res"; then
_err "Can't get domain records."
return 1
fi
_info "Remove TXT record"
data="{\"fqdn\":\"$fulldomain\",\"records\":{"
data=${data}$(_parce_records "$res" "A")
data=${data}$(_parce_records "$res" "AAAA")
data=${data}$(_parce_records "$res" "CAA")
data=${data}$(_parce_records "$res" "MX")
data=${data}$(_parce_records "$res" "SRV")
data=${data}$(_parce_records "$res" "TXT")
data=$(echo "$data" | sed 's/,$//')
data=${data}'}}'
str=$(_txt_to_dns_json "$txtvalue")
data=$(_rm_record "$data" "$str")
res=$(_api_call "$Beget_Api/dns/changeRecords" "$data")
if ! _is_api_reply_ok "$res"; then
_err "Can't change domain records."
return 1
fi
return 0
}
#################### Private functions below ####################
# Create subdomain if needed
# Usage: _prepare_subdomain [fulldomain]
_prepare_subdomain() {
fulldomain=$1
_info "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"
if [ -z "$_sub_domain" ]; then
_debug "$fulldomain is a root domain."
return 0
fi
_info "Get subdomain list"
res=$(_api_call "$Beget_Api/domain/getSubdomainList")
if ! _is_api_reply_ok "$res"; then
_err "Can't get subdomain list."
return 1
fi
if _contains "$res" "\"fqdn\":\"$fulldomain\""; then
_debug "Subdomain $fulldomain already exist."
return 0
fi
_info "Subdomain $fulldomain does not exist. Let's create one."
data="{\"subdomain\":\"$_sub_domain\",\"domain_id\":$_domain_id}"
res=$(_api_call "$Beget_Api/domain/addSubdomainVirtual" "$data")
if ! _is_api_reply_ok "$res"; then
_err "Can't create subdomain."
return 1
fi
_debug "Cleanup subdomen records"
data="{\"fqdn\":\"$fulldomain\",\"records\":{}}"
res=$(_api_call "$Beget_Api/dns/changeRecords" "$data")
if ! _is_api_reply_ok "$res"; then
_debug "Can't cleanup $fulldomain records."
fi
data="{\"fqdn\":\"www.$fulldomain\",\"records\":{}}"
res=$(_api_call "$Beget_Api/dns/changeRecords" "$data")
if ! _is_api_reply_ok "$res"; then
_debug "Can't cleanup www.$fulldomain records."
fi
return 0
}
# Usage: _get_root _acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
# _domain_id=32436365
_get_root() {
fulldomain=$1
i=1
p=1
_debug "Get domain list"
res=$(_api_call "$Beget_Api/domain/getList")
if ! _is_api_reply_ok "$res"; then
_err "Can't get domain list."
return 1
fi
while true; do
h=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-100)
_debug h "$h"
if [ -z "$h" ]; then
return 1
fi
if _contains "$res" "$h"; then
_domain_id=$(echo "$res" | _egrep_o "\"id\":[0-9]*,\"fqdn\":\"$h\"" | cut -d , -f1 | cut -d : -f2)
if [ "$_domain_id" ]; then
if [ "$h" != "$fulldomain" ]; then
_sub_domain=$(echo "$fulldomain" | cut -d . -f 1-"$p")
else
_sub_domain=""
fi
_domain=$h
return 0
fi
return 1
fi
p="$i"
i=$(_math "$i" + 1)
done
return 1
}
# Parce DNS records from json string
# Usage: _parce_records [j_str] [record_name]
_parce_records() {
j_str=$1
record_name=$2
res="\"$record_name\":["
res=${res}$(echo "$j_str" | _egrep_o "\"$record_name\":\[.*" | cut -d '[' -f2 | cut -d ']' -f1)
res=${res}"],"
echo "$res"
}
# Usage: _add_record [data] [record_name] [record_data]
_add_record() {
data=$1
record_name=$2
record_data=$3
echo "$data" | sed "s/\"$record_name\":\[/\"$record_name\":\[$record_data,/" | sed "s/,\]/\]/"
}
# Usage: _rm_record [data] [record_data]
_rm_record() {
data=$1
record_data=$2
echo "$data" | sed "s/$record_data//g" | sed "s/,\+/,/g" |
sed "s/{,/{/g" | sed "s/,}/}/g" |
sed "s/\[,/\[/g" | sed "s/,\]/\]/g"
}
_txt_to_dns_json() {
echo "{\"ttl\":600,\"txtdata\":\"$1\"}"
}
# Usage: _api_call [api_url] [input_data]
_api_call() {
api_url="$1"
input_data="$2"
_debug "_api_call $api_url"
_debug "Request: $input_data"
# res=$(curl -s -L -D ./http.header \
# "$api_url" \
# --data-urlencode login=$Beget_Username \
# --data-urlencode passwd=$Beget_Password \
# --data-urlencode input_format=json \
# --data-urlencode output_format=json \
# --data-urlencode "input_data=$input_data")
url="$api_url?login=$Beget_Username&passwd=$Beget_Password&input_format=json&output_format=json"
if [ -n "$input_data" ]; then
url=${url}"&input_data="
url=${url}$(echo "$input_data" | _url_encode)
fi
res=$(_get "$url")
_debug "Reply: $res"
echo "$res"
}
# Usage: _is_api_reply_ok [api_reply]
_is_api_reply_ok() {
_contains "$1" '^{"status":"success","answer":{"status":"success","result":.*}}$'
}
+202
View File
@@ -0,0 +1,202 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_bh_info='Best-Hosting.cz
Site: best-hosting.cz
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_bh
Options:
BH_API_USER API User identifier.
BH_API_KEY API Secret key.
Issues: github.com/acmesh-official/acme.sh/issues/6854
Author: @heximcz
'
BH_Api="https://best-hosting.cz/api/v1"
######## Public functions #####################
# Usage: dns_bh_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_bh_add() {
fulldomain=$1
txtvalue=$2
# --- 1. Credentials ---
BH_API_USER="${BH_API_USER:-$(_readaccountconf_mutable BH_API_USER)}"
BH_API_KEY="${BH_API_KEY:-$(_readaccountconf_mutable BH_API_KEY)}"
if [ -z "$BH_API_USER" ] || [ -z "$BH_API_KEY" ]; then
BH_API_USER=""
BH_API_KEY=""
_err "You must specify BH_API_USER and BH_API_KEY."
return 1
fi
_saveaccountconf_mutable BH_API_USER "$BH_API_USER"
_saveaccountconf_mutable BH_API_KEY "$BH_API_KEY"
# --- 2. Add TXT record ---
_info "Adding TXT record for $fulldomain"
json_payload="{\"fulldomain\":\"$fulldomain\",\"txtvalue\":\"$txtvalue\"}"
if ! _bh_rest POST "dns" "$json_payload"; then
_err "Failed to add DNS record."
return 1
fi
_norm_add=$(printf "%s" "$response" | tr -d '[:space:]')
if ! _contains "$_norm_add" '"status":"success"'; then
_err "API error: $response"
return 1
fi
record_id=$(printf "%s" "$_norm_add" | _egrep_o '"id":[0-9]+' | cut -d':' -f2)
_debug record_id "$record_id"
if [ -z "$record_id" ]; then
_err "Could not parse record ID from response."
return 1
fi
# Sanitize key — replace dots and hyphens with underscores
_conf_key=$(printf "%s" "BH_record_ids_${fulldomain}" | tr '.-' '_')
# Wildcard support: store space-separated list of IDs
# First call stores "111", second call stores "111 222"
_existing_ids=$(_readdomainconf "$_conf_key")
if [ -z "$_existing_ids" ]; then
_savedomainconf "$_conf_key" "$record_id"
else
_savedomainconf "$_conf_key" "$_existing_ids $record_id"
fi
_info "DNS TXT record added successfully."
return 0
}
# Usage: dns_bh_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_bh_rm() {
fulldomain=$1
txtvalue=$2
# --- 1. Credentials ---
BH_API_USER="${BH_API_USER:-$(_readaccountconf_mutable BH_API_USER)}"
BH_API_KEY="${BH_API_KEY:-$(_readaccountconf_mutable BH_API_KEY)}"
if [ -z "$BH_API_USER" ] || [ -z "$BH_API_KEY" ]; then
BH_API_USER=""
BH_API_KEY=""
_err "You must specify BH_API_USER and BH_API_KEY."
return 1
fi
# Sanitize key — same as in add
_conf_key=$(printf "%s" "BH_record_ids_${fulldomain}" | tr '.-' '_')
# --- 2. Load stored record ID(s) ---
_existing_ids=$(_readdomainconf "$_conf_key")
_debug _existing_ids "$_existing_ids"
if [ -z "$_existing_ids" ]; then
_err "Could not find record ID for $fulldomain."
return 1
fi
record_id=""
_remaining_ids=""
# Find the record ID that matches both the name and txtvalue
for _id in $_existing_ids; do
if ! _bh_rest GET "dns/$_id"; then
_debug "Failed to query record id $_id, skipping."
# Keep it in the list so a later run can try again
if [ -z "$_remaining_ids" ]; then
_remaining_ids="$_id"
else
_remaining_ids="$_remaining_ids $_id"
fi
continue
fi
_match_name=0
_match_content=0
_norm_response=$(printf "%s" "$response" | tr -d '[:space:]')
case "$_norm_response" in
*"\"name\":\"$fulldomain\""*)
_match_name=1
;;
esac
case "$_norm_response" in
*"\"content\":\"$txtvalue\""*)
_match_content=1
;;
esac
if [ "$_match_name" -eq 1 ] && [ "$_match_content" -eq 1 ]; then
record_id="$_id"
_debug "Matched record id" "$record_id"
# Do not add this ID to _remaining_ids; it will be deleted
continue
fi
# Not a match — keep ID for potential future cleanups
if [ -z "$_remaining_ids" ]; then
_remaining_ids="$_id"
else
_remaining_ids="$_remaining_ids $_id"
fi
done
if [ -z "$record_id" ]; then
_err "Could not find matching TXT record for $fulldomain with the given value."
return 1
fi
# --- 3. Delete record ---
_info "Removing TXT record for $fulldomain"
if ! _bh_rest DELETE "dns/$record_id"; then
_err "Failed to remove DNS record."
return 1
fi
# Update stored list — remove used ID
if [ -z "$_remaining_ids" ]; then
_cleardomainconf "$_conf_key"
else
_savedomainconf "$_conf_key" "$_remaining_ids"
fi
_info "DNS TXT record removed successfully."
return 0
}
#################### Private functions #####################
_bh_rest() {
m="$1"
ep="$2"
data="$3"
_debug "$ep"
_credentials="$(printf "%s:%s" "$BH_API_USER" "$BH_API_KEY" | _base64)"
export _H1="Authorization: Basic $_credentials"
export _H2="Content-Type: application/json"
export _H3="Accept: application/json"
if [ "$m" = "GET" ]; then
response="$(_get "$BH_Api/$ep")"
else
_debug data "$data"
response="$(_post "$data" "$BH_Api/$ep" "" "$m")"
fi
if [ "$?" != "0" ]; then
_err "Error calling $m $BH_Api/$ep"
return 1
fi
_debug2 response "$response"
return 0
}
+373
View File
@@ -0,0 +1,373 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_bhosted_info='bHosted.nl DNS API
Site: bHosted.nl
Docs: https://github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_bhosted
Options:
BHOSTED_Username API username
BHOSTED_Password API password (MD5 hash like bHosted web services example)
BHOSTED_TTL TTL for TXT record (default: 300)
BHOSTED_SLD Optional override (useful for multi-part TLDs like co.uk)
BHOSTED_TLD Optional override (useful for multi-part TLDs like co.uk)
Notes:
- Plugin uses addrecord + delrecord for DNS-01 challenge
- Record ID is retrieved from addrecord XML response and cached for cleanup
'
BHOSTED_API_ROOT="https://webservices.bhosted.com/dns"
############ Public functions #####################
# Usage: dns_bhosted_add _acme-challenge.www.example.com "txt-value"
dns_bhosted_add() {
fulldomain="$1"
txtvalue="$2"
_debug "fulldomain" "$fulldomain"
_debug "txtvalue" "$txtvalue"
_bhosted_load_credentials || return 1
_bhosted_get_root "$fulldomain" || return 1
_info "Adding TXT record: ${_bhosted_name}.${_domain}"
BHOSTED_TTL="${BHOSTED_TTL:-$(_readaccountconf_mutable BHOSTED_TTL)}"
BHOSTED_TTL="${BHOSTED_TTL:-300}"
_saveaccountconf_mutable BHOSTED_TTL "$BHOSTED_TTL"
_bhosted_api_add_txt "$_bhosted_sld" "$_bhosted_tld" "$_bhosted_name" "$txtvalue" "$BHOSTED_TTL" || return 1
# Extract and cache record id in-memory for cleanup in this run
_rec_id="$(_bhosted_extract_id "$response")"
if [ -n "$_rec_id" ]; then
_hash="$(_bhosted_cache_hash "$fulldomain" "$txtvalue")"
_debug "_hash" "$_hash"
_debug "_rec_id" "$_rec_id"
_bhosted_mem_set_id "$_hash" "$_rec_id"
else
_err "TXT record added but no record id found in response."
_err "Cleanup may fail unless bHosted addrecord returns <id>...</id>."
_debug2 "add response" "$response"
return 1
fi
return 0
}
# Usage: dns_bhosted_rm _acme-challenge.www.example.com "txt-value"
dns_bhosted_rm() {
fulldomain="$1"
txtvalue="$2"
_debug "fulldomain" "$fulldomain"
_debug "txtvalue" "$txtvalue"
_bhosted_load_credentials || return 1
_bhosted_get_root "$fulldomain" || return 1
_hash="$(_bhosted_cache_hash "$fulldomain" "$txtvalue")"
_rec_id="$(_bhosted_mem_get_id "$_hash")"
if [ -z "$_rec_id" ]; then
_err "No cached bHosted record id found for cleanup."
_err "Please delete TXT manually in bHosted DNS for: ${_bhosted_name}.${_domain}"
return 1
fi
_info "Removing TXT record id=${_rec_id}: ${_bhosted_name}.${_domain}"
_bhosted_api_del_record "$_bhosted_sld" "$_bhosted_tld" "$_rec_id" || return 1
return 0
}
######## Private functions #####################
_bhosted_load_credentials() {
BHOSTED_Username="${BHOSTED_Username:-$(_readaccountconf_mutable BHOSTED_Username)}"
BHOSTED_Password="${BHOSTED_Password:-$(_readaccountconf_mutable BHOSTED_Password)}"
if [ -z "$BHOSTED_Username" ] || [ -z "$BHOSTED_Password" ]; then
BHOSTED_Username=""
BHOSTED_Password=""
_err "You didn't specify bHosted credentials."
_err "Please export BHOSTED_Username and BHOSTED_Password (MD5 hash)."
return 1
fi
_saveaccountconf_mutable BHOSTED_Username "$BHOSTED_Username"
_saveaccountconf_mutable BHOSTED_Password "$BHOSTED_Password"
return 0
}
# Determine root zone and host part
# Supports simple domains automatically (example.com, example.nl)
# For multi-part TLDs (example.co.uk), set:
# BHOSTED_SLD=example
# BHOSTED_TLD=co.uk
_bhosted_get_root() {
domain="$1"
BHOSTED_SLD="${BHOSTED_SLD:-$(_readdomainconf BHOSTED_SLD)}"
BHOSTED_TLD="${BHOSTED_TLD:-$(_readdomainconf BHOSTED_TLD)}"
if [ -n "$BHOSTED_SLD" ] && [ -n "$BHOSTED_TLD" ]; then
_savedomainconf BHOSTED_SLD "$BHOSTED_SLD"
_savedomainconf BHOSTED_TLD "$BHOSTED_TLD"
_domain="${BHOSTED_SLD}.${BHOSTED_TLD}"
case "$domain" in
*."$_domain") ;;
"$_domain") ;;
*)
_err "BHOSTED_SLD/BHOSTED_TLD do not match requested domain: $domain"
return 1
;;
esac
_bhosted_sld="$BHOSTED_SLD"
_bhosted_tld="$BHOSTED_TLD"
_bhosted_name="${domain%."$_domain"}"
if [ "$_bhosted_name" = "$domain" ]; then
_bhosted_name=""
fi
[ -n "$_bhosted_name" ] || _bhosted_name="@"
_debug "_domain" "$_domain"
_debug "_bhosted_sld" "$_bhosted_sld"
_debug "_bhosted_tld" "$_bhosted_tld"
_debug "_bhosted_name" "$_bhosted_name"
return 0
fi
# Auto-parse: assume last label = tld, label before = sld
# Works for .nl / .com / .org etc.
_bhosted_tld="$(printf "%s" "$domain" | awk -F. '{print $NF}')"
_bhosted_sld="$(printf "%s" "$domain" | awk -F. '{print $(NF-1)}')"
if [ -z "$_bhosted_sld" ] || [ -z "$_bhosted_tld" ]; then
_err "Could not parse SLD/TLD from domain: $domain"
return 1
fi
_domain="${_bhosted_sld}.${_bhosted_tld}"
_bhosted_name="${domain%."$_domain"}"
if [ "$_bhosted_name" = "$domain" ]; then
_bhosted_name=""
fi
[ -n "$_bhosted_name" ] || _bhosted_name="@"
_debug "_domain" "$_domain"
_debug "_bhosted_sld" "$_bhosted_sld"
_debug "_bhosted_tld" "$_bhosted_tld"
_debug "_bhosted_name" "$_bhosted_name"
return 0
}
_bhosted_api_add_txt() {
_sld="$1"
_tld="$2"
_name="$3"
_content="$4"
_ttl="$5"
_u_user="$(printf "%s" "$BHOSTED_Username" | _url_encode)"
_u_pass="$(printf "%s" "$BHOSTED_Password" | _url_encode)"
_u_sld="$(printf "%s" "$_sld" | _url_encode)"
_u_tld="$(printf "%s" "$_tld" | _url_encode)"
_u_name="$(printf "%s" "$_name" | _url_encode)"
_u_content="$(printf "%s" "$_content" | _url_encode)"
_u_ttl="$(printf "%s" "$_ttl" | _url_encode)"
_data="user=${_u_user}&password=${_u_pass}&tld=${_u_tld}&sld=${_u_sld}&type=TXT&name=${_u_name}&content=${_u_content}&ttl=${_u_ttl}"
_debug "bHosted add endpoint" "${BHOSTED_API_ROOT}/addrecord"
response="$(_post "$_data" "${BHOSTED_API_ROOT}/addrecord")"
_ret="$?"
_debug2 "bHosted add response" "$response"
if [ "$_ret" != "0" ]; then
_err "bHosted addrecord request failed"
return 1
fi
if _bhosted_response_has_error "$response"; then
_err "bHosted addrecord returned an error"
_debug2 "response" "$response"
return 1
fi
return 0
}
_bhosted_api_del_record() {
_sld="$1"
_tld="$2"
_id="$3"
_u_user="$(printf "%s" "$BHOSTED_Username" | _url_encode)"
_u_pass="$(printf "%s" "$BHOSTED_Password" | _url_encode)"
_u_sld="$(printf "%s" "$_sld" | _url_encode)"
_u_tld="$(printf "%s" "$_tld" | _url_encode)"
_u_id="$(printf "%s" "$_id" | _url_encode)"
_url="${BHOSTED_API_ROOT}/delrecord"
_data="user=${_u_user}&password=${_u_pass}&tld=${_u_tld}&sld=${_u_sld}&id=${_u_id}"
_debug "bHosted delete endpoint" "$_url"
response="$(_post "$_data" "$_url")"
_ret="$?"
_debug2 "bHosted delete response" "$response"
if [ "$_ret" != "0" ]; then
_err "bHosted delrecord request failed"
return 1
fi
if _bhosted_response_has_error "$response"; then
_err "bHosted delrecord returned an error"
_debug2 "response" "$response"
return 1
fi
return 0
}
# Extract XML tag value from response, e.g. <id>12345</id>
_bhosted_xml_value() {
_tag="$1"
_resp="$2"
# Flatten response to simplify parsing
_flat="$(printf "%s" "$_resp" | tr -d '\r\n\t')"
printf "%s" "$_flat" | sed -n "s:.*<${_tag}>\\([^<]*\\)</${_tag}>.*:\\1:p" | _head_n 1
}
# Return code convention:
# return 0 => response HAS error
# return 1 => response has NO error (success)
_bhosted_response_has_error() {
_resp="$1"
# Empty response = error
if [ -z "$_resp" ]; then
_debug "Empty API response"
return 0
fi
# Prefer explicit bHosted XML response fields
if _contains "$_resp" "<response>"; then
_errors="$(_bhosted_xml_value "errors" "$_resp")"
_done="$(_bhosted_xml_value "done" "$_resp")"
_subcommand="$(_bhosted_xml_value "subcommand" "$_resp")"
_id="$(_bhosted_xml_value "id" "$_resp")"
_debug "bHosted XML subcommand" "$_subcommand"
_debug "bHosted XML id" "$_id"
_debug "bHosted XML errors" "$_errors"
_debug "bHosted XML done" "$_done"
# Success according to provided format
if [ "$_errors" = "0" ] && [ "$_done" = "true" ]; then
return 1
fi
_debug "bHosted XML indicates failure"
return 0
fi
# Fallback for unexpected/non-XML responses
_resp_lc="$(_lower_case "$_resp")"
if _contains "$_resp_lc" "error"; then
_debug "Detected 'error' in response"
return 0
fi
if _contains "$_resp_lc" "fout"; then
_debug "Detected 'fout' in response"
return 0
fi
if _contains "$_resp_lc" "invalid"; then
_debug "Detected 'invalid' in response"
return 0
fi
if _contains "$_resp_lc" "failed"; then
_debug "Detected 'failed' in response"
return 0
fi
if _contains "$_resp_lc" "denied"; then
_debug "Detected 'denied' in response"
return 0
fi
# If no explicit error markers found, assume success
return 1
}
# Extract record id from response
# Supports bHosted XML first, then generic fallbacks
_bhosted_extract_id() {
_resp="$1"
# bHosted XML: <id>12345</id>
_id="$(_bhosted_xml_value "id" "$_resp" | tr -cd '0-9')"
if [ -n "$_id" ]; then
printf "%s" "$_id"
return 0
fi
# JSON: "id":12345
_id="$(printf "%s" "$_resp" | _egrep_o '"id"[[:space:]]*:[[:space:]]*[0-9]+' | _head_n 1 | tr -cd '0-9')"
if [ -n "$_id" ]; then
printf "%s" "$_id"
return 0
fi
# key=value: id=12345
_id="$(printf "%s" "$_resp" | _egrep_o '(^|[[:space:][:punct:]])id[[:space:]]*=[[:space:]]*[0-9]+' | _head_n 1 | tr -cd '0-9')"
if [ -n "$_id" ]; then
printf "%s" "$_id"
return 0
fi
# "record id 12345" / "recordid 12345"
_id="$(printf "%s" "$_resp" | _egrep_o '(record[[:space:]]*id|recordid)[^0-9]*[0-9]+' | _head_n 1 | tr -cd '0-9')"
if [ -n "$_id" ]; then
printf "%s" "$_id"
return 0
fi
return 1
}
# Create a unique config key for cached record ids
_bhosted_cache_hash() {
_fd="$1"
_tv="$2"
# md5 hex of fulldomain|txtvalue
printf "%s|%s" "$_fd" "$_tv" | _digest md5 hex
}
_bhosted_cache_key() {
_hash="$1"
printf "%s" "BHOSTED_TXT_ID_${_hash}"
}
_bhosted_mem_set_id() {
_hash="$1"
_id="$2"
_key="$(_bhosted_cache_key "$_hash")"
_savedomainconf "$_key" "$_id"
}
_bhosted_mem_get_id() {
_hash="$1"
_key="$(_bhosted_cache_key "$_hash")"
_readdomainconf "$_key"
}
+88
View File
@@ -0,0 +1,88 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_bookmyname_info='BookMyName.com
Site: BookMyName.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_bookmyname
Options:
BOOKMYNAME_USERNAME Username
BOOKMYNAME_PASSWORD Password
Issues: github.com/acmesh-official/acme.sh/issues/3209
Author: @Neilpang
'
######## Public functions #####################
# BookMyName urls:
# https://BOOKMYNAME_USERNAME:BOOKMYNAME_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=add&value="XXXXXXXX"'
# https://BOOKMYNAME_USERNAME:BOOKMYNAME_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=remove&value="XXXXXXXX"'
# Output:
#good: update done, cid 123456, domain id 456789, type txt, ip XXXXXXXX
#good: remove done 1, cid 123456, domain id 456789, ttl 300, type txt, ip XXXXXXXX
# Be careful, BMN DNS servers can be slow to pick up changes; using dnssleep is thus advised.
# Usage:
# export BOOKMYNAME_USERNAME="ABCDE-FREE"
# export BOOKMYNAME_PASSWORD="MyPassword"
# /usr/local/ssl/acme.sh/acme.sh --dns dns_bookmyname --dnssleep 600 --issue -d domain.tld
#Usage: dns_bookmyname_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_bookmyname_add() {
fulldomain=$1
txtvalue=$2
_info "Using bookmyname"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
BOOKMYNAME_USERNAME="${BOOKMYNAME_USERNAME:-$(_readaccountconf_mutable BOOKMYNAME_USERNAME)}"
BOOKMYNAME_PASSWORD="${BOOKMYNAME_PASSWORD:-$(_readaccountconf_mutable BOOKMYNAME_PASSWORD)}"
if [ -z "$BOOKMYNAME_USERNAME" ] || [ -z "$BOOKMYNAME_PASSWORD" ]; then
BOOKMYNAME_USERNAME=""
BOOKMYNAME_PASSWORD=""
_err "You didn't specify BookMyName username and password yet."
_err "Please specify them and try again."
return 1
fi
#save the credentials to the account conf file.
_saveaccountconf_mutable BOOKMYNAME_USERNAME "$BOOKMYNAME_USERNAME"
_saveaccountconf_mutable BOOKMYNAME_PASSWORD "$BOOKMYNAME_PASSWORD"
uri="https://${BOOKMYNAME_USERNAME}:${BOOKMYNAME_PASSWORD}@www.bookmyname.com/dyndns/"
data="?hostname=${fulldomain}&type=TXT&ttl=300&do=add&value=${txtvalue}"
result="$(_get "${uri}${data}")"
_debug "Result: $result"
if ! _startswith "$result" 'good: update done, cid '; then
_err "Can't add $fulldomain"
return 1
fi
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_bookmyname_rm() {
fulldomain=$1
txtvalue=$2
_info "Using bookmyname"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
BOOKMYNAME_USERNAME="${BOOKMYNAME_USERNAME:-$(_readaccountconf_mutable BOOKMYNAME_USERNAME)}"
BOOKMYNAME_PASSWORD="${BOOKMYNAME_PASSWORD:-$(_readaccountconf_mutable BOOKMYNAME_PASSWORD)}"
uri="https://${BOOKMYNAME_USERNAME}:${BOOKMYNAME_PASSWORD}@www.bookmyname.com/dyndns/"
data="?hostname=${fulldomain}&type=TXT&ttl=300&do=remove&value=${txtvalue}"
result="$(_get "${uri}${data}")"
_debug "Result: $result"
if ! _startswith "$result" 'good: remove done 1, cid '; then
_info "Can't remove $fulldomain"
fi
}
#################### Private functions below ##################################
+245
View File
@@ -0,0 +1,245 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_bunny_info='Bunny.net
Site: Bunny.net/dns/
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_bunny
Options:
BUNNY_API_KEY API Key
Issues: github.com/acmesh-official/acme.sh/issues/4296
Author: <nosilver4u@ewww.io>
'
##################### 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
}
+27 -13
View File
@@ -1,13 +1,16 @@
#!/usr/bin/env sh
#
#CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
#CF_Email="xxxx@sss.com"
#CF_Token="xxxx"
#CF_Account_ID="xxxx"
#CF_Zone_ID="xxxx"
# shellcheck disable=SC2034
dns_cf_info='CloudFlare
Site: CloudFlare.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cf
Options:
CF_Key API Key
CF_Email Your account email
OptionsAlt:
CF_Token API Token
CF_Account_ID Account ID
CF_Zone_ID Zone ID. Optional.
'
CF_Api="https://api.cloudflare.com/client/v4"
@@ -32,7 +35,8 @@ dns_cf_add() {
else
_saveaccountconf_mutable CF_Token "$CF_Token"
_saveaccountconf_mutable CF_Account_ID "$CF_Account_ID"
_saveaccountconf_mutable CF_Zone_ID "$CF_Zone_ID"
_clearaccountconf_mutable CF_Zone_ID
_clearaccountconf CF_Zone_ID
fi
else
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
@@ -51,6 +55,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"
@@ -80,7 +92,9 @@ dns_cf_add() {
if _contains "$response" "$txtvalue"; then
_info "Added, OK"
return 0
elif _contains "$response" "The record already exists"; then
elif _contains "$response" "The record already exists" ||
_contains "$response" "An identical record already exists." ||
_contains "$response" '"code":81058'; then
_info "Already exists, OK"
return 0
else
@@ -174,7 +188,7 @@ _get_root() {
fi
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
@@ -194,7 +208,7 @@ _get_root() {
if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_count":1'; then
_domain_id=$(echo "$response" | _egrep_o "\[.\"id\": *\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \" | tr -d " ")
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain=$h
return 0
fi
+11 -6
View File
@@ -1,10 +1,15 @@
#!/usr/bin/env sh
# Author: Radek Sprta <sprta@vshosting.cz>
#CLOUDDNS_EMAIL=XXXXX
#CLOUDDNS_PASSWORD="YYYYYYYYY"
#CLOUDDNS_CLIENT_ID=XXXXX
# shellcheck disable=SC2034
dns_clouddns_info='vshosting.cz CloudDNS
Site: github.com/vshosting/clouddns
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_clouddns
Options:
CLOUDDNS_EMAIL Email
CLOUDDNS_PASSWORD Password
CLOUDDNS_CLIENT_ID Client ID
Issues: github.com/acmesh-official/acme.sh/issues/2699
Author: Radek Sprta <sprta@vshosting.cz>
'
CLOUDDNS_API='https://admin.vshosting.cloud/clouddns'
CLOUDDNS_LOGIN_API='https://admin.vshosting.cloud/api/public/auth/login'
+15 -11
View File
@@ -1,12 +1,15 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_cloudns_info='ClouDNS.net
Site: ClouDNS.net
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cloudns
Options:
CLOUDNS_AUTH_ID Regular auth ID
CLOUDNS_SUB_AUTH_ID Sub auth ID
CLOUDNS_AUTH_PASSWORD Auth Password
Author: Boyan Peychev <boyan@cloudns.net>
'
# Author: Boyan Peychev <boyan at cloudns dot net>
# Repository: https://github.com/ClouDNS/acme.sh/
# Editor: I Komang Suryadana
#CLOUDNS_AUTH_ID=XXXXX
#CLOUDNS_SUB_AUTH_ID=XXXXX
#CLOUDNS_AUTH_PASSWORD="YYYYYYYYY"
CLOUDNS_API="https://api.cloudns.net"
DOMAIN_TYPE=
DOMAIN_MASTER=
@@ -78,7 +81,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
@@ -161,7 +164,7 @@ _dns_cloudns_get_zone_info() {
_dns_cloudns_get_zone_name() {
i=2
while true; do
zoneForCheck=$(printf "%s" "$1" | cut -d . -f $i-100)
zoneForCheck=$(printf "%s" "$1" | cut -d . -f "$i"-100)
if [ -z "$zoneForCheck" ]; then
return 1
@@ -194,10 +197,11 @@ _dns_cloudns_http_api_call() {
auth_user="auth-id=$CLOUDNS_AUTH_ID"
fi
encoded_password=$(echo "$CLOUDNS_AUTH_PASSWORD" | tr -d "\n\r" | _url_encode)
if [ -z "$2" ]; then
data="$auth_user&auth-password=$CLOUDNS_AUTH_PASSWORD"
data="$auth_user&auth-password=$encoded_password"
else
data="$auth_user&auth-password=$CLOUDNS_AUTH_PASSWORD&$2"
data="$auth_user&auth-password=$encoded_password&$2"
fi
response="$(_get "$CLOUDNS_API/$method?$data")"
+12 -5
View File
@@ -1,7 +1,14 @@
#!/usr/bin/env sh
# DNS API for acme.sh for Core-Networks (https://beta.api.core-networks.de/doc/).
# created by 5ll and francis
# shellcheck disable=SC2034
dns_cn_info='Core-Networks.de
Site: beta.api.Core-Networks.de/doc/
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cn
Options:
CN_User User
CN_Password Password
Issues: github.com/acmesh-official/acme.sh/issues/2142
Author: 5ll, francis
'
CN_API="https://beta.api.core-networks.de"
@@ -124,7 +131,7 @@ _cn_get_root() {
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug h "$h"
_debug _H1 "${_H1}"
@@ -142,7 +149,7 @@ _cn_get_root() {
fi
if _contains "$_cn_zonelist" "\"name\":\"$h\"" >/dev/null; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain=$h
return 0
else
+13 -2
View File
@@ -1,4 +1,15 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_conoha_info='ConoHa.jp
Domains: ConoHa.io
Site: ConoHa.jp
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_conoha
Options:
CONOHA_Username Username
CONOHA_Password Password
CONOHA_TenantId TenantId
CONOHA_IdentityServiceApi Identity Service API. E.g. "https://identity.xxxx.conoha.io/v2.0"
'
CONOHA_DNS_EP_PREFIX_REGEXP="https://dns-service\."
@@ -226,7 +237,7 @@ _get_root() {
i=2
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100).
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100).
_debug h "$h"
if [ -z "$h" ]; then
#not valid
@@ -240,7 +251,7 @@ _get_root() {
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
_domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \")
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain=$h
return 0
fi
+16 -7
View File
@@ -1,10 +1,16 @@
#!/usr/bin/env sh
# Author: Wout Decre <wout@canodus.be>
# shellcheck disable=SC2034
dns_constellix_info='Constellix.com
Site: Constellix.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_constellix
Options:
CONSTELLIX_Key API Key
CONSTELLIX_Secret API Secret
Issues: github.com/acmesh-official/acme.sh/issues/2724
Author: Wout Decre <wout@canodus.be>
'
CONSTELLIX_Api="https://api.dns.constellix.com/v1"
#CONSTELLIX_Key="XXX"
#CONSTELLIX_Secret="XXX"
######## Public functions #####################
@@ -111,12 +117,12 @@ dns_constellix_rm() {
#################### Private functions below ##################################
_get_root() {
domain=$1
domain=$(echo "$1" | _lower_case)
i=2
p=1
_debug "Detecting root zone"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
if [ -z "$h" ]; then
return 1
fi
@@ -128,7 +134,7 @@ _get_root() {
if _contains "$response" "\"name\":\"$h\""; then
_domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]*" | cut -d ':' -f 2)
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-$p)
_sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-"$p")
_domain="$h"
_debug _domain_id "$_domain_id"
@@ -150,6 +156,9 @@ _constellix_rest() {
data="$3"
_debug "$ep"
# Prevent rate limit
_sleep 2
rdate=$(date +"%s")"000"
hmac=$(printf "%s" "$rdate" | _hmac sha1 "$(printf "%s" "$CONSTELLIX_Secret" | _hex_dump | tr -d ' ')" | _base64)
+18 -17
View File
@@ -1,18 +1,19 @@
#!/usr/bin/env sh
#
#Author: Bjarne Saltbaek
#Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/3732
#
#
# shellcheck disable=SC2034
dns_cpanel_info='cPanel Server API
Manage DNS via cPanel Dashboard.
Site: cPanel.net
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_cpanel
Options:
cPanel_Username Username
cPanel_Apitoken API Token
cPanel_Hostname Server URL. E.g. "https://hostname:port"
Issues: github.com/acmesh-official/acme.sh/issues/3732
Author: Bjarne Saltbaek
'
######## Public functions #####################
#
# Export CPANEL username,api token and hostname in the following variables
#
# cPanel_Username=username
# cPanel_Apitoken=apitoken
# 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"
+269
View File
@@ -0,0 +1,269 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_cpanel_uapi_info='cPanel UAPI
Manage DNS via cPanel UAPI. Works with API tokens and Two-Factor Authentication.
Site: cpanel.net
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_cpanel_uapi
Options:
cPanel_Username Username
cPanel_Apitoken API Token
cPanel_Hostname Server URL. E.g. "https://hostname:port"
cPanel_TTL optional TXT record TTL in seconds. Default: 120
Issues: github.com/acmesh-official/acme.sh/issues/6877
Author: Adam Bodnar
'
######## Public functions #####################
# Used to add txt record
dns_cpanel_uapi_add() {
fulldomain=$1
txtvalue=$2
_info "Adding TXT record via cPanel UAPI"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
if ! _cpanel_uapi_get_root; then
_err "No matching root domain for $fulldomain found"
return 1
fi
# Build the record name relative to the zone
_escaped_domain=$(echo "$_domain" | sed 's/\./\\./g')
_record_name=$(echo "$fulldomain" | sed "s/\.${_escaped_domain}$//")
_debug "Record name: $_record_name in zone $_domain"
# Get the current SOA serial (required by mass_edit_zone)
if ! _cpanel_uapi_get_serial "$_domain"; then
_err "Failed to get zone serial for $_domain"
return 1
fi
_debug "Zone serial: $_serial"
# Use configurable TTL, default 120 seconds
_ttl="${cPanel_TTL:-$(_readaccountconf_mutable cPanel_TTL)}"
case "$_ttl" in
"")
_ttl=120
;;
*[!0-9]*)
_debug "Invalid cPanel_TTL provided, falling back to default 120"
_ttl=120
;;
esac
# Build JSON and URL-encode it for the add parameter
_add_json=$(printf '{"dname":"%s","ttl":%s,"record_type":"TXT","data":["%s"]}' "$_record_name" "$_ttl" "$txtvalue")
_debug "add_json: $_add_json"
_add_json_encoded=$(printf '%s' "$_add_json" | _url_encode)
_debug "add_json (encoded): $_add_json_encoded"
if ! _cpanel_uapi_request "execute/DNS/mass_edit_zone?zone=${_domain}&serial=${_serial}&add=${_add_json_encoded}"; then
_err "Request to add TXT record failed for zone $_domain"
return 1
fi
_debug "_result: $_result"
if _contains "$_result" '"status":1'; then
_info "TXT record added successfully"
return 0
fi
_err "Failed to add TXT record."
_err "Response: $_result"
return 1
}
# Used to remove the txt record after validation
dns_cpanel_uapi_rm() {
fulldomain=$1
txtvalue=$2
_info "Removing TXT record via cPanel UAPI"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
if ! _cpanel_uapi_get_root; then
_err "No matching root domain for $fulldomain found"
return 1
fi
if ! _cpanel_uapi_findentry; then
_info "Entry doesn't exist, nothing to delete"
return 0
fi
_debug "Deleting record with line_index=$_line_index"
if ! _cpanel_uapi_get_serial "$_domain"; then
_err "Failed to get zone serial for $_domain"
return 1
fi
if ! _cpanel_uapi_request "execute/DNS/mass_edit_zone?zone=${_domain}&serial=${_serial}&remove=${_line_index}"; then
_err "Request to remove TXT record failed for zone $_domain"
return 1
fi
_debug "_result: $_result"
if _contains "$_result" '"status":1'; then
_info "TXT record removed successfully"
return 0
fi
_err "Failed to remove TXT record."
_err "Response: $_result"
return 1
}
#################### Private functions below ##################################
_cpanel_uapi_checkcredentials() {
cPanel_Username="${cPanel_Username:-$(_readaccountconf_mutable cPanel_Username)}"
cPanel_Apitoken="${cPanel_Apitoken:-$(_readaccountconf_mutable cPanel_Apitoken)}"
cPanel_Hostname="${cPanel_Hostname:-$(_readaccountconf_mutable cPanel_Hostname)}"
if [ -z "$cPanel_Username" ] || [ -z "$cPanel_Apitoken" ] || [ -z "$cPanel_Hostname" ]; then
cPanel_Username=""
cPanel_Apitoken=""
cPanel_Hostname=""
_err "You haven't specified cPanel_Username, cPanel_Apitoken, and cPanel_Hostname."
return 1
fi
# Remove trailing slash from hostname if present
cPanel_Hostname=$(echo "$cPanel_Hostname" | sed 's|/$||')
_saveaccountconf_mutable cPanel_Username "$cPanel_Username"
_saveaccountconf_mutable cPanel_Apitoken "$cPanel_Apitoken"
_saveaccountconf_mutable cPanel_Hostname "$cPanel_Hostname"
if [ -n "$cPanel_TTL" ]; then
case "$cPanel_TTL" in
*[!0-9]*)
_info "Ignoring invalid cPanel_TTL: $cPanel_TTL"
cPanel_TTL=""
;;
*)
_saveaccountconf_mutable cPanel_TTL "$cPanel_TTL"
;;
esac
fi
return 0
}
_cpanel_uapi_request() {
export _H1="Authorization: cpanel $cPanel_Username:$cPanel_Apitoken"
_result=$(_get "$cPanel_Hostname/$1")
return $?
}
_cpanel_uapi_get_root() {
if ! _cpanel_uapi_checkcredentials; then return 1; fi
if ! _cpanel_uapi_request "execute/DomainInfo/list_domains"; then
_err "Request to cPanel API failed while listing domains"
return 1
fi
_debug "DomainInfo response length: ${#_result}"
if ! _contains "$_result" '"status":1'; then
_err "cPanel UAPI request failed. Is the API token correct?"
_debug "Response: $_result"
return 1
fi
# Extract main_domain
_main_domain=$(echo "$_result" | _egrep_o '"main_domain":"[^"]*"' | _head_n 1 | sed 's/.*"main_domain":"//;s/"//')
_debug "main_domain: $_main_domain"
# Extract addon_domains (array of strings)
_addon_domains=$(echo "$_result" | _egrep_o '"addon_domains":\[[^]]*\]' | sed 's/.*"addon_domains":\[//;s/\]$//' | _egrep_o '"[a-zA-Z0-9._-]+"' | sed 's/"//g')
_debug "addon_domains: $_addon_domains"
# Build list of all domains to check
_all_domains="$_main_domain $_addon_domains"
_debug "All domains: $_all_domains"
# Find the matching root domain (prefer longest match)
_best_match=""
_best_len=0
for _check_domain in $_all_domains; do
if [ -z "$_check_domain" ]; then continue; fi
if _endswith "$fulldomain" "$_check_domain"; then
_len=${#_check_domain}
if [ "$_len" -gt "$_best_len" ]; then
_best_match="$_check_domain"
_best_len="$_len"
fi
fi
done
if [ -n "$_best_match" ]; then
_domain="$_best_match"
_debug "Root domain: $_domain"
return 0
fi
return 1
}
_cpanel_uapi_get_serial() {
_zone="$1"
if ! _cpanel_uapi_request "execute/DNS/parse_zone?zone=${_zone}"; then
_err "Request to parse zone failed for $_zone"
return 1
fi
# Split JSON records onto separate lines using a POSIX-portable sed literal newline
# (\\n in sed replacement is a GNU/BusyBox extension; a backslash-newline works everywhere)
_soa_line=$(echo "$_result" | sed 's/},{/},\
{/g' | grep '"record_type":"SOA"' | _head_n 1)
_debug "SOA line: $_soa_line"
if [ -z "$_soa_line" ]; then
_err "SOA record not found for zone $_zone"
_debug "parse_zone response: $_result"
return 1
fi
# Extract the third element from data_b64 array (serial is index 2, 0-based)
# data_b64 format: ["ns","admin","SERIAL","refresh","retry","expire","minimum"]
_serial_b64=$(echo "$_soa_line" | _egrep_o '"data_b64":\[[^]]*\]' | sed 's/"data_b64":\[//;s/\]//' | sed 's/"//g' | cut -d',' -f3)
_debug "serial_b64: $_serial_b64"
if [ -z "$_serial_b64" ]; then
_err "Could not extract serial from SOA record"
return 1
fi
_serial=$(printf '%s' "$_serial_b64" | _dbase64)
_debug "Decoded serial: $_serial"
if [ -z "$_serial" ]; then
_err "Failed to decode serial"
return 1
fi
return 0
}
_cpanel_uapi_findentry() {
_debug "Finding TXT entry for $fulldomain with value $txtvalue"
if ! _cpanel_uapi_request "execute/DNS/parse_zone?zone=${_domain}"; then
_err "Request to parse zone failed for $_domain"
return 1
fi
_debug "parse_zone result length: ${#_result}"
# Base64-encode the txtvalue to match against data_b64 in the response
_b64_txtvalue=$(printf '%s' "$txtvalue" | _base64)
_debug "b64_txtvalue: $_b64_txtvalue"
# Split records onto separate lines, find matching TXT record by base64 value
_line_index=$(echo "$_result" | sed 's/},{/},\
{/g' | grep '"record_type":"TXT"' | grep -F "$_b64_txtvalue" | _egrep_o '"line_index":[0-9]+' | _head_n 1 | cut -d: -f2)
_debug "line_index: $_line_index"
if [ -n "$_line_index" ]; then
_debug "Entry found with line_index=$_line_index"
return 0
fi
return 1
}
+14 -8
View File
@@ -1,15 +1,21 @@
#!/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
# shellcheck disable=SC2034
dns_curanet_info='Curanet.dk
Domains: scannet.dk wannafind.dk dandomain.dk
Site: Curanet.dk
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_curanet
Options:
CURANET_AUTHCLIENTID Auth ClientID. Requires scope dns
CURANET_AUTHSECRET Auth Secret
Issues: github.com/acmesh-official/acme.sh/issues/3933
Author: Peter L. Hansen <peter@r12.dk>
'
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 #####################
######## Public functions ####################
#Usage: dns_curanet_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_curanet_add() {
@@ -136,7 +142,7 @@ _get_root() {
i=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
@@ -148,7 +154,7 @@ _get_root() {
export _H3="Authorization: Bearer $CURANET_ACCESS_TOKEN"
response="$(_get "$CURANET_REST_URL/$h/Records" "" "")"
if [ ! "$(echo "$response" | _egrep_o "Entity not found")" ]; then
if [ ! "$(echo "$response" | _egrep_o "Entity not found|Bad Request")" ]; then
_domain=$h
return 0
fi
+56 -27
View File
@@ -1,21 +1,15 @@
#!/usr/bin/env sh
########
# Custom cyon.ch DNS API for use with [acme.sh](https://github.com/acmesh-official/acme.sh)
#
# Usage: acme.sh --issue --dns dns_cyon -d www.domain.com
#
# Dependencies:
# -------------
# - oathtool (When using 2 Factor Authentication)
#
# Issues:
# -------
# Any issues / questions / suggestions can be posted here:
# https://github.com/noplanman/cyon-api/issues
#
# Author: Armando Lüscher <armando@noplanman.ch>
########
# shellcheck disable=SC2034
dns_cyon_info='cyon.ch
Site: cyon.ch
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cyon
Options:
CY_Username Username
CY_Password API Token
CY_OTP_Secret OTP token. Only required if using 2FA
Issues: github.com/noplanman/cyon-api/issues
Author: Armando Lüscher <armando@noplanman.ch>
'
dns_cyon_add() {
_cyon_load_credentials &&
@@ -44,7 +38,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
@@ -107,6 +101,8 @@ _cyon_load_parameters() {
# This header is required for curl calls.
_H1="X-Requested-With: XMLHttpRequest"
export _H1
_H3="User-Agent: cyon-dns-acmesh/1.0"
export _H3
}
_cyon_print_header() {
@@ -131,7 +127,11 @@ _cyon_print_header() {
}
_cyon_get_cookie_header() {
printf "Cookie: %s" "$(grep "cyon=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'cyon=[^;]*;' | tr -d ';')"
# Extract all cookies from the response headers (case-insensitive)
_cookies="$(grep -i "^set-cookie:" "$HTTP_HEADER" | sed 's/^[Ss]et-[Cc]ookie: //' | sed 's/;.*//' | tr '\n' '; ' | sed 's/; $//')"
if [ -n "$_cookies" ]; then
printf "Cookie: %s" "$_cookies"
fi
}
_cyon_login() {
@@ -161,7 +161,12 @@ _cyon_login() {
_get "https://my.cyon.ch/" >/dev/null
# todo: instead of just checking if the env variable is defined, check if we actually need to do a 2FA auth request.
# Update cookie after loading main page (only if new cookies are set)
_new_cookies="$(_cyon_get_cookie_header)"
if [ -n "$_new_cookies" ]; then
_H2="$_new_cookies"
export _H2
fi
# 2FA authentication with OTP?
if [ -n "${CY_OTP_Secret}" ]; then
@@ -190,6 +195,13 @@ _cyon_login() {
fi
_info " success"
# Update cookie after 2FA (only if new cookies are set)
_new_cookies="$(_cyon_get_cookie_header)"
if [ -n "$_new_cookies" ]; then
_H2="$_new_cookies"
export _H2
fi
fi
_info ""
@@ -211,7 +223,17 @@ _cyon_change_domain_env() {
domain_env="$(printf "%s" "${fulldomain}" | sed -E -e 's/.*\.(.*\..*)$/\1/')"
_debug "Changing domain environment to ${domain_env}"
gloo_item_key="$(_get "https://my.cyon.ch/domain/" | tr '\n' ' ' | sed -E -e "s/.*data-domain=\"${domain_env}\"[^<]*data-itemkey=\"([^\"]*).*/\1/")"
domain_page_response="$(_get "https://my.cyon.ch/domain/")"
_debug domain_page_response "${domain_page_response}"
# Check if we got an error response (JSON) instead of HTML
if printf "%s" "${domain_page_response}" | grep -q '"iserror":true'; then
_err " $(printf "%s" "${domain_page_response}" | _cyon_get_response_message)"
_err ""
return 1
fi
gloo_item_key="$(printf "%s" "${domain_page_response}" | tr '\n' ' ' | sed -E -e "s/.*data-domain=\"${domain_env}\"[^<]*data-itemkey=\"([^\"]*).*/\1/")"
_debug gloo_item_key "${gloo_item_key}"
domain_env_url="https://my.cyon.ch/user/environment/setdomain/d/${domain_env}/gik/${gloo_item_key}"
@@ -221,10 +243,8 @@ _cyon_change_domain_env() {
if ! _cyon_check_if_2fa_missed "${domain_env_response}"; then return 1; fi
domain_env_success="$(printf "%s" "${domain_env_response}" | _egrep_o '"authenticated":\w*' | cut -d : -f 2)"
# Bail if domain environment change fails.
if [ "${domain_env_success}" != "true" ]; then
if [ "$(printf "%s" "${domain_env_response}" | _cyon_get_environment_change_status)" != "true" ]; then
_err " $(printf "%s" "${domain_env_response}" | _cyon_get_response_message)"
_err ""
return 1
@@ -238,7 +258,7 @@ _cyon_add_txt() {
_info " - Adding DNS TXT entry..."
add_txt_url="https://my.cyon.ch/domain/dnseditor/add-record-async"
add_txt_data="zone=${fulldomain_idn}.&ttl=900&type=TXT&value=${txtvalue}"
add_txt_data="name=${fulldomain_idn}.&ttl=900&type=TXT&dnscontent=${txtvalue}"
add_txt_response="$(_post "$add_txt_data" "$add_txt_url")"
_debug add_txt_response "${add_txt_response}"
@@ -247,9 +267,10 @@ _cyon_add_txt() {
add_txt_message="$(printf "%s" "${add_txt_response}" | _cyon_get_response_message)"
add_txt_status="$(printf "%s" "${add_txt_response}" | _cyon_get_response_status)"
add_txt_validation="$(printf "%s" "${add_txt_response}" | _cyon_get_validation_status)"
# Bail if adding TXT entry fails.
if [ "${add_txt_status}" != "true" ]; then
if [ "${add_txt_status}" != "true" ] || [ "${add_txt_validation}" != "true" ]; then
_err " ${add_txt_message}"
_err ""
return 1
@@ -311,13 +332,21 @@ _cyon_get_response_message() {
}
_cyon_get_response_status() {
_egrep_o '"status":\w*' | cut -d : -f 2
_egrep_o '"status":[a-zA-Z0-9]*' | cut -d : -f 2
}
_cyon_get_validation_status() {
_egrep_o '"valid":[a-zA-Z0-9]*' | cut -d : -f 2
}
_cyon_get_response_success() {
_egrep_o '"onSuccess":"[^"]*"' | cut -d : -f 2 | tr -d '"'
}
_cyon_get_environment_change_status() {
_egrep_o '"authenticated":[a-zA-Z0-9]*' | cut -d : -f 2
}
_cyon_check_if_2fa_missed() {
# Did we miss the 2FA?
if test "${1#*multi_factor_form}" != "${1}"; then
+201
View File
@@ -0,0 +1,201 @@
#!/usr/bin/env sh
# dns_czechia.sh - CZECHIA.COM/ZONER DNS API for acme.sh (DNS-01)
#
# Documentation: https://api.czechia.com/swagger/index.html
#shellcheck disable=SC2034
dns_czechia_info='[
{"name":"CZ_AuthorizationToken","usage":"Your API token from CZECHIA.COM/Zoner administration.","required":"1"},
{"name":"CZ_Zones","usage":"Managed zones separated by comma or space (e.g. \"example.com\").","required":"1"},
{"name":"CZ_API_BASE","usage":"Defaults to https://api.czechia.com","required":"0"}
]'
dns_czechia_add() {
fulldomain="$1"
txtvalue="$2"
_debug "dns_czechia_add fulldomain='$fulldomain'"
if [ -z "$fulldomain" ] || [ -z "$txtvalue" ]; then
_err "dns_czechia_add: missing fulldomain or txtvalue"
return 1
fi
_czechia_load_conf || return 1
_current_zone=$(_czechia_pick_zone "$fulldomain")
if [ -z "$_current_zone" ]; then
_err "No matching zone found for $fulldomain. Please check CZ_Zones."
return 1
fi
_cz=$(printf "%s" "$_current_zone" | _lower_case | sed 's/[[:space:]]//g; s/\.$//')
_tk=$(printf "%s" "$CZ_AuthorizationToken" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
if [ -z "$_cz" ] || [ -z "$_tk" ]; then
_err "Missing zone or CZ_AuthorizationToken."
return 1
fi
_url="$CZ_API_BASE/api/DNS/$_cz/TXT"
_fd=$(printf "%s" "$fulldomain" | _lower_case | sed 's/\.$//')
if [ "$_fd" = "$_cz" ]; then
_h="@"
else
# Remove the literal ".<zone>" suffix from _fd, if present
_h=${_fd%."$_cz"}
[ "$_h" = "$_fd" ] && _h="@"
fi
[ -z "$_h" ] && _h="@"
_info "Adding TXT record for $_h in zone $_cz"
_h_esc=$(printf "%s" "$_h" | sed 's/\\/\\\\/g; s/"/\\"/g')
_txt_esc=$(printf "%s" "$txtvalue" | sed 's/\\/\\\\/g; s/"/\\"/g')
_body="{\"hostName\":\"$_h_esc\",\"text\":\"$_txt_esc\",\"ttl\":300,\"publishZone\":1}"
_debug "URL: $_url"
_debug "Body: $_body"
export _H1="Content-Type: application/json"
export _H2="AuthorizationToken: $_tk"
_res="$(_post "$_body" "$_url" "" "POST")"
_post_exit="$?"
_debug2 "Response: $_res"
if [ "$_post_exit" -ne 0 ]; then
_err "API request failed. exit code $_post_exit"
return 1
fi
if _contains "$_res" "already exists"; then
_info "Record already exists, skipping."
return 0
fi
_nres="$(_normalizeJson "$_res")"
if [ "$?" -ne 0 ] || [ -z "$_nres" ]; then
_nres="$_res"
fi
if _contains "$_nres" "\"status\":4" || _contains "$_nres" "\"status\":5" || _contains "$_nres" "\"errors\""; then
_err "API error: $_res"
return 1
fi
return 0
}
dns_czechia_rm() {
fulldomain="$1"
txtvalue="$2"
_debug "dns_czechia_rm fulldomain='$fulldomain'"
if [ -z "$fulldomain" ] || [ -z "$txtvalue" ]; then
_err "dns_czechia_rm: missing fulldomain or txtvalue"
return 1
fi
_czechia_load_conf || return 1
_current_zone=$(_czechia_pick_zone "$fulldomain")
if [ -z "$_current_zone" ]; then
_err "No matching zone found for $fulldomain. Please check CZ_Zones configuration."
return 1
fi
_cz=$(printf "%s" "$_current_zone" | _lower_case | sed 's/[[:space:]]//g; s/\.$//')
_tk=$(printf "%s" "$CZ_AuthorizationToken" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
if [ -z "$_cz" ] || [ -z "$_tk" ]; then
_err "Missing zone or CZ_AuthorizationToken."
return 1
fi
_url="$CZ_API_BASE/api/DNS/$_cz/TXT"
_fd=$(printf "%s" "$fulldomain" | _lower_case | sed 's/\.$//')
if [ "$_fd" = "$_cz" ]; then
_h="@"
else
_h=$(printf "%s" "$_fd" | sed "s/\.$_cz$//")
[ "$_h" = "$_fd" ] && _h="@"
fi
[ -z "$_h" ] && _h="@"
_h_esc=$(printf "%s" "$_h" | sed 's/\\/\\\\/g; s/"/\\"/g')
_txt_esc=$(printf "%s" "$txtvalue" | sed 's/\\/\\\\/g; s/"/\\"/g')
_body="{\"hostName\":\"$_h_esc\",\"text\":\"$_txt_esc\",\"ttl\":300,\"publishZone\":1}"
_debug "URL: $_url"
_debug "Body: $_body"
export _H1="Content-Type: application/json"
export _H2="AuthorizationToken: $_tk"
_res="$(_post "$_body" "$_url" "" "DELETE")"
_post_exit="$?"
_debug2 "Response: $_res"
if [ "$_post_exit" -ne 0 ]; then
_err "CZECHIA DNS API DELETE request failed for $_fd: exit code $_post_exit, response: $_res"
return 1
fi
_res_normalized=$(printf '%s' "$_res" | _normalizeJson)
if _contains "$_res_normalized" '"isError":true'; then
_err "CZECHIA DNS API reported an error while deleting TXT for $_fd: $_res"
return 1
fi
return 0
}
_czechia_load_conf() {
CZ_AuthorizationToken="${CZ_AuthorizationToken:-$(_readaccountconf_mutable CZ_AuthorizationToken)}"
if [ -z "$CZ_AuthorizationToken" ]; then
_err "Missing CZ_AuthorizationToken"
return 1
fi
CZ_Zones="${CZ_Zones:-$(_readaccountconf_mutable CZ_Zones)}"
if [ -z "$CZ_Zones" ]; then
_err "Missing CZ_Zones"
return 1
fi
CZ_API_BASE="${CZ_API_BASE:-$(_readaccountconf_mutable CZ_API_BASE)}"
[ -z "$CZ_API_BASE" ] && CZ_API_BASE="https://api.czechia.com"
_saveaccountconf_mutable CZ_AuthorizationToken "$CZ_AuthorizationToken"
_saveaccountconf_mutable CZ_Zones "$CZ_Zones"
_saveaccountconf_mutable CZ_API_BASE "$CZ_API_BASE"
return 0
}
_czechia_pick_zone() {
_fd=$(printf "%s" "$1" | _lower_case | sed 's/\.$//')
_best_zone=""
_zones_space=$(printf "%s" "$CZ_Zones" | sed 's/,/ /g')
for _z in $_zones_space; do
_clean_z=$(printf "%s" "$_z" | _lower_case | sed 's/[[:space:]]//g; s/\.$//')
[ -z "$_clean_z" ] && continue
case "$_fd" in
"$_clean_z" | *."$_clean_z")
if [ ${#_clean_z} -gt ${#_best_zone} ]; then
_best_zone="$_clean_z"
fi
;;
esac
done
printf "%s" "$_best_zone"
}
+12 -29
View File
@@ -1,31 +1,14 @@
#!/usr/bin/env sh
# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*-
# vim: et ts=2 sw=2
#
# DirectAdmin 1.41.0 API
# The DirectAdmin interface has it's own Let's encrypt functionality, but this
# script can be used to generate certificates for names which are not hosted on
# DirectAdmin
#
# User must provide login data and URL to DirectAdmin incl. port.
# You can create login key, by using the Login Keys function
# ( https://da.example.com:8443/CMD_LOGIN_KEYS ), which only has access to
# - CMD_API_DNS_CONTROL
# - CMD_API_SHOW_DOMAINS
#
# See also https://www.directadmin.com/api.php and
# https://www.directadmin.com/features.php?id=1298
#
# Report bugs to https://github.com/TigerP/acme.sh/issues
#
# Values to export:
# export DA_Api="https://remoteUser:remotePassword@da.example.com:8443"
# export DA_Api_Insecure=1
#
# Set DA_Api_Insecure to 1 for insecure and 0 for secure -> difference is
# whether ssl cert is checked for validity (0) or whether it is just accepted
# (1)
#
# shellcheck disable=SC2034
dns_da_info='DirectAdmin Server API
Site: DirectAdmin.com/api.php
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_da
Options:
DA_Api API Server URL. E.g. "https://remoteUser:remotePassword@da.domain.tld:8443"
DA_Api_Insecure Insecure TLS. 0: check for cert validity, 1: always accept
Issues: github.com/TigerP/acme.sh/issues
'
######## Public functions #####################
# Usage: dns_myapi_add _acme-challenge.www.example.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
@@ -78,7 +61,7 @@ _get_root() {
# response will contain "list[]=example.com&list[]=example.org"
_da_api CMD_API_SHOW_DOMAINS "" "${domain}"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug h "$h"
if [ -z "$h" ]; then
# not valid
@@ -86,7 +69,7 @@ _get_root() {
return 1
fi
if _contains "$response" "$h" >/dev/null; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain=$h
return 0
fi
+9 -12
View File
@@ -1,16 +1,13 @@
#!/usr/bin/env sh
#Created by RaidenII, to use DuckDNS's API to add/remove text records
#modified by helbgd @ 03/13/2018 to support ddnss.de
#modified by mod242 @ 04/24/2018 to support different ddnss domains
#Please note: the Wildcard Feature must be turned on for the Host record
#and the checkbox for TXT needs to be enabled
# Pass credentials before "acme.sh --issue --dns dns_ddnss ..."
# --
# export DDNSS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
# --
#
# shellcheck disable=SC2034
dns_ddnss_info='DDNSS.de
Site: DDNSS.de
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ddnss
Options:
DDNSS_Token API Token
Issues: github.com/acmesh-official/acme.sh/issues/2230
Author: @helbgd, @mod242
'
DDNSS_DNS_API="https://ddnss.de/upd.php"
+11 -9
View File
@@ -1,11 +1,13 @@
#!/usr/bin/env sh
#
# deSEC.io Domain API
#
# Author: Zheng Qian
#
# deSEC API doc
# https://desec.readthedocs.io/en/latest/
# shellcheck disable=SC2034
dns_desec_info='deSEC.io
Site: desec.readthedocs.io/en/latest/
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_desec
Options:
DDNSS_Token API Token
Issues: github.com/acmesh-official/acme.sh/issues/2180
Author: Zheng Qian
'
REST_API="https://desec.io/api/v1/domains"
@@ -174,7 +176,7 @@ _get_root() {
i=2
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
@@ -186,7 +188,7 @@ _get_root() {
fi
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain=$h
return 0
fi
+11 -14
View File
@@ -1,18 +1,15 @@
#!/usr/bin/env sh
########################################################################
# https://dyndnsfree.de hook script for acme.sh
#
# Environment variables:
#
# - $DF_user (your dyndnsfree.de username)
# - $DF_password (your dyndnsfree.de password)
#
# Author: Thilo Gass <thilo.gass@gmail.com>
# Git repo: https://github.com/ThiloGa/acme.sh
#-- dns_df_add() - Add TXT record --------------------------------------
# Usage: dns_df_add _acme-challenge.subdomain.domain.com "XyZ123..."
# shellcheck disable=SC2034
dns_df_info='DynDnsFree.de
Domains: dynup.de
Site: DynDnsFree.de
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_df
Options:
DF_user Username
DF_password Password
Issues: github.com/acmesh-official/acme.sh/issues/2897
Author: Thilo Gass <thilo.gass@gmail.com>
'
dyndnsfree_api="https://dynup.de/acme.php"
+13 -18
View File
@@ -1,16 +1,12 @@
#!/usr/bin/env sh
## Will be called by acme.sh to add the txt record to your api system.
## returns 0 means success, otherwise error.
## Author: thewer <github at thewer.com>
## GitHub: https://github.com/gitwer/acme.sh
##
## Environment Variables Required:
##
## DO_API_KEY="75310dc4ca779ac39a19f6355db573b49ce92ae126553ebd61ac3a3ae34834cc"
##
# shellcheck disable=SC2034
dns_dgon_info='DigitalOcean.com
Site: DigitalOcean.com/help/api/
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dgon
Options:
DO_API_KEY API Key
Author: <github@thewer.com>
'
##################### Public functions #####################
@@ -192,6 +188,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,10 +202,8 @@ _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
while [ $i -gt 0 ]; do
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)
@@ -220,14 +215,14 @@ _get_base_domain() {
## check if it exists
if [ -n "$found" ]; then
## exists - exit loop returning the parts
sub_point=$(_math $i - 1)
sub_point=$(_math "$i" - 1)
_sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point")
_debug _domain "$_domain"
_debug _sub_domain "$_sub_domain"
return 0
fi
## increment cut point $i
i=$(_math $i + 1)
i=$(_math "$i" + 1)
done
if [ -z "$found" ]; then
+188
View File
@@ -0,0 +1,188 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_dnsexit_info='DNSExit.com
Site: DNSExit.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_dnsexit
Options:
DNSEXIT_API_KEY API Key
DNSEXIT_AUTH_USER Username
DNSEXIT_AUTH_PASS Password
Issues: github.com/acmesh-official/acme.sh/issues/4719
Author: Samuel Jimenez
'
DNSEXIT_API_URL="https://api.dnsexit.com/dns/"
DNSEXIT_HOSTS_URL="https://update.dnsexit.com/ipupdate/hosts.jsp"
######## Public functions #####################
#Usage: dns_dnsexit_add _acme-challenge.*.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_dnsexit_add() {
fulldomain=$1
txtvalue=$2
_info "Using DNSExit.com"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_debug 'Load account auth'
if ! get_account_info; then
return 1
fi
_debug 'First detect the root zone'
if ! _get_root "$fulldomain"; then
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
if ! _dnsexit_rest "{\"domain\":\"$_domain\",\"add\":{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":0,\"overwrite\":false}}"; then
_err "$response"
return 1
fi
_debug2 _response "$response"
return 0
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_dnsexit_rm() {
fulldomain=$1
txtvalue=$2
_info "Using DNSExit.com"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_debug 'Load account auth'
if ! get_account_info; then
return 1
fi
_debug 'First detect the root zone'
if ! _get_root "$fulldomain"; then
_err "$response"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
if ! _dnsexit_rest "{\"domain\":\"$_domain\",\"delete\":{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\"}}"; then
_err "$response"
return 1
fi
_debug2 _response "$response"
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
_domain=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug h "$_domain"
if [ -z "$_domain" ]; then
return 1
fi
_debug login "$DNSEXIT_AUTH_USER"
_debug password "$DNSEXIT_AUTH_PASS"
_debug domain "$_domain"
_dnsexit_http "login=$DNSEXIT_AUTH_USER&password=$DNSEXIT_AUTH_PASS&domain=$_domain"
if _contains "$response" "0=$_domain"; then
_sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")"
return 0
else
_debug "Go to next level of $_domain"
fi
i=$(_math "$i" + 1)
done
return 1
}
_dnsexit_rest() {
m=POST
ep=""
data="$1"
_debug _dnsexit_rest "$ep"
_debug data "$data"
api_key_trimmed=$(echo "$DNSEXIT_API_KEY" | tr -d '"')
export _H1="apikey: $api_key_trimmed"
export _H2='Content-Type: application/json'
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$DNSEXIT_API_URL/$ep" "" "$m")"
else
response="$(_get "$DNSEXIT_API_URL/$ep")"
fi
if [ "$?" != "0" ]; then
_err "Error $ep"
return 1
fi
_debug2 response "$response"
return 0
}
_dnsexit_http() {
m=GET
param="$1"
_debug param "$param"
_debug get "$DNSEXIT_HOSTS_URL?$param"
response="$(_get "$DNSEXIT_HOSTS_URL?$param")"
_debug response "$response"
if [ "$?" != "0" ]; then
_err "Error $param"
return 1
fi
_debug2 response "$response"
return 0
}
get_account_info() {
DNSEXIT_API_KEY="${DNSEXIT_API_KEY:-$(_readaccountconf_mutable DNSEXIT_API_KEY)}"
if test -z "$DNSEXIT_API_KEY"; then
DNSEXIT_API_KEY=''
_err 'DNSEXIT_API_KEY was not exported'
return 1
fi
_saveaccountconf_mutable DNSEXIT_API_KEY "$DNSEXIT_API_KEY"
DNSEXIT_AUTH_USER="${DNSEXIT_AUTH_USER:-$(_readaccountconf_mutable DNSEXIT_AUTH_USER)}"
if test -z "$DNSEXIT_AUTH_USER"; then
DNSEXIT_AUTH_USER=""
_err 'DNSEXIT_AUTH_USER was not exported'
return 1
fi
_saveaccountconf_mutable DNSEXIT_AUTH_USER "$DNSEXIT_AUTH_USER"
DNSEXIT_AUTH_PASS="${DNSEXIT_AUTH_PASS:-$(_readaccountconf_mutable DNSEXIT_AUTH_PASS)}"
if test -z "$DNSEXIT_AUTH_PASS"; then
DNSEXIT_AUTH_PASS=""
_err 'DNSEXIT_AUTH_PASS was not exported'
return 1
fi
_saveaccountconf_mutable DNSEXIT_AUTH_PASS "$DNSEXIT_AUTH_PASS"
return 0
}
+10 -11
View File
@@ -1,15 +1,14 @@
#!/usr/bin/env sh
# dnsHome.de API for acme.sh
#
# This Script adds the necessary TXT record to a Subdomain
#
# Author dnsHome.de (https://github.com/dnsHome-de)
#
# Report Bugs to https://github.com/acmesh-official/acme.sh/issues/3819
#
# export DNSHOME_Subdomain=""
# export DNSHOME_SubdomainPassword=""
# shellcheck disable=SC2034
dns_dnshome_info='dnsHome.de
Site: dnsHome.de
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_dnshome
Options:
DNSHOME_Subdomain Subdomain
DNSHOME_SubdomainPassword Subdomain Password
Issues: github.com/acmesh-official/acme.sh/issues/3819
Author: @dnsHome-de
'
# Usage: add subdomain.ddnsdomain.tld "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Used to add txt record
+10 -10
View File
@@ -1,12 +1,12 @@
#!/usr/bin/env sh
# DNSimple domain api
# https://github.com/pho3nixf1re/acme.sh/issues
#
# This is your oauth token which can be acquired on the account page. Please
# note that this must be an _account_ token and not a _user_ token.
# https://dnsimple.com/a/<your account id>/account/access_tokens
# DNSimple_OAUTH_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje"
# shellcheck disable=SC2034
dns_dnsimple_info='DNSimple.com
Site: DNSimple.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dnsimple
Options:
DNSimple_OAUTH_TOKEN OAuth Token
Issues: github.com/pho3nixf1re/acme.sh/issues
'
DNSimple_API="https://api.dnsimple.com/v2"
@@ -92,7 +92,7 @@ _get_root() {
i=2
previous=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
if [ -z "$h" ]; then
# not valid
return 1
@@ -105,7 +105,7 @@ _get_root() {
if _contains "$response" 'not found'; then
_debug "$h not found"
else
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$previous)
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$previous")
_domain="$h"
_debug _domain "$_domain"
Loaded 100 of 250 files, more files were not shown because too many files have changed in this diff. Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.