mirror of
https://github.com/acmesh-official/acme.sh
synced 2025-11-28 20:51:08 +08:00
Compare commits
383 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16dc21afff | ||
|
|
3a1c6d84f0 | ||
|
|
e684abdacd | ||
|
|
e275cb1efd | ||
|
|
60315e5b91 | ||
|
|
43b1a4bf5a | ||
|
|
cdb238e41c | ||
|
|
3871e44d9c | ||
|
|
5a51454d13 | ||
|
|
d102943a32 | ||
|
|
a0b27ddbd8 | ||
|
|
b950b04e89 | ||
|
|
c9a55f395b | ||
|
|
424da01878 | ||
|
|
3c933158c8 | ||
|
|
7221d488e5 | ||
|
|
1c16931e26 | ||
|
|
0a4b70dbd2 | ||
|
|
666c716bda | ||
|
|
be477d7ae3 | ||
|
|
6c8a623b88 | ||
|
|
ff8de34415 | ||
|
|
f8ca6d9833 | ||
|
|
dbab519004 | ||
|
|
e888c96591 | ||
|
|
59519f0493 | ||
|
|
e02f07d356 | ||
|
|
2c90d220b8 | ||
|
|
9feeba8d4b | ||
|
|
45090fc897 | ||
|
|
d761bdc1b1 | ||
|
|
287a8c76b5 | ||
|
|
a7dd86de71 | ||
|
|
c541a2e5de | ||
|
|
41dbf1ddac | ||
|
|
70ed6b96d1 | ||
|
|
ef26075a1c | ||
|
|
91c87446be | ||
|
|
dd207e1f02 | ||
|
|
e947870da9 | ||
|
|
f0b5f592dc | ||
|
|
773a2a6cfe | ||
|
|
c2a7e384ba | ||
|
|
4a8b35ef5f | ||
|
|
5cd0db32df | ||
|
|
ef01de6149 | ||
|
|
4e9749f655 | ||
|
|
abb7a1fd47 | ||
|
|
60bcee8c1d | ||
|
|
8ded524236 | ||
|
|
0a47f48191 | ||
|
|
8601267b90 | ||
|
|
6767e0c52d | ||
|
|
5141d1775d | ||
|
|
374af996d9 | ||
|
|
dcc9624c15 | ||
|
|
b3df1a2bf8 | ||
|
|
3fc3c02a4f | ||
|
|
874ddf9a32 | ||
|
|
69aeb70cc3 | ||
|
|
47e60cefe3 | ||
|
|
4ea7f3cda5 | ||
|
|
03288b521a | ||
|
|
4b0a7a6e1f | ||
|
|
383287adcd | ||
|
|
5c00afc6fe | ||
|
|
025e0e8093 | ||
|
|
35fb1f8585 | ||
|
|
9fb14eef0e | ||
|
|
5d6d0c6176 | ||
|
|
dd707242ef | ||
|
|
4f32f1285a | ||
|
|
a6ecdbae29 | ||
|
|
4904d100ff | ||
|
|
7a1f94bc20 | ||
|
|
f9320fff8f | ||
|
|
3dde83d8a0 | ||
|
|
f3e77a989c | ||
|
|
f3539b0354 | ||
|
|
4e5d4b9695 | ||
|
|
864315f6d1 | ||
|
|
713b7338ea | ||
|
|
53117b2f4c | ||
|
|
90623142e1 | ||
|
|
43503a20e5 | ||
|
|
ec53b27dfe | ||
|
|
238ecfc539 | ||
|
|
b888792940 | ||
|
|
e3d1ab52f8 | ||
|
|
f9c2874c35 | ||
|
|
2304f005e3 | ||
|
|
b95f836256 | ||
|
|
c94f9f21af | ||
|
|
fc336e3733 | ||
|
|
fc1df9f9a5 | ||
|
|
5a604bfdee | ||
|
|
281951a86b | ||
|
|
35ec3adadc | ||
|
|
b9256a1ba7 | ||
|
|
734c9a1aa5 | ||
|
|
6502a71083 | ||
|
|
f2634b44cd | ||
|
|
dcf9c467c3 | ||
|
|
3dcacc1f8d | ||
|
|
7cb81b0f35 | ||
|
|
8155ba5224 | ||
|
|
7169060425 | ||
|
|
ddb9dd4e45 | ||
|
|
2a05f24cb6 | ||
|
|
039e4c662d | ||
|
|
70351677a1 | ||
|
|
33cadfb97d | ||
|
|
5fbaeda217 | ||
|
|
b44ba0d21a | ||
|
|
b42532afe9 | ||
|
|
da6a335b87 | ||
|
|
0e8fef73bb | ||
|
|
7122a960fa | ||
|
|
d5b649a1a4 | ||
|
|
233c724b2d | ||
|
|
e1eb001872 | ||
|
|
5899d7034f | ||
|
|
23c3e9482f | ||
|
|
dd980d9dca | ||
|
|
d4ed50a915 | ||
|
|
d986c7d126 | ||
|
|
67a2a4f249 | ||
|
|
a6e87e7e08 | ||
|
|
33da8a7f62 | ||
|
|
68c533f777 | ||
|
|
671eecf203 | ||
|
|
2454ac8ef1 | ||
|
|
20f097faa4 | ||
|
|
5dba8b493d | ||
|
|
eb27013fba | ||
|
|
4f8d1c5c9d | ||
|
|
74168c3e05 | ||
|
|
cece848801 | ||
|
|
7ddbeaa078 | ||
|
|
2d4aa7ff8b | ||
|
|
79e044ac31 | ||
|
|
15ae5a5135 | ||
|
|
5684b7c329 | ||
|
|
7e96120353 | ||
|
|
cc36421fe5 | ||
|
|
683aa727d5 | ||
|
|
ea07b495ac | ||
|
|
8d211c3524 | ||
|
|
ab8df82563 | ||
|
|
8ba9c4ab97 | ||
|
|
2f70b8682e | ||
|
|
86dd4ea480 | ||
|
|
204e5f4418 | ||
|
|
044a9bb6d3 | ||
|
|
a31143328e | ||
|
|
2bb29a105c | ||
|
|
0013d98d04 | ||
|
|
916743f44b | ||
|
|
edebe65d95 | ||
|
|
c43fcd0af6 | ||
|
|
9a5c2b88dc | ||
|
|
aaee0414c8 | ||
|
|
d0c2fb9761 | ||
|
|
4f076c6924 | ||
|
|
51d4d1451a | ||
|
|
7b9d76dc65 | ||
|
|
f91aeea91c | ||
|
|
4cabf84be9 | ||
|
|
8a1f038a80 | ||
|
|
c9cab9ab74 | ||
|
|
bd78120bd5 | ||
|
|
0de3bf0ac7 | ||
|
|
2d144a8b43 | ||
|
|
1a140a5515 | ||
|
|
1ea8cfbfb0 | ||
|
|
64fda95186 | ||
|
|
7843c0c1b0 | ||
|
|
a3784854a7 | ||
|
|
8b7c000f47 | ||
|
|
5b8d7a3f29 | ||
|
|
328dbd57d4 | ||
|
|
a8c448f4cb | ||
|
|
de0419228f | ||
|
|
d8a4e47a13 | ||
|
|
bc920949cb | ||
|
|
0717f8591c | ||
|
|
3e628f2678 | ||
|
|
ddabc38e3f | ||
|
|
c0097497be | ||
|
|
2fb9c923f4 | ||
|
|
c485011ed1 | ||
|
|
0b8ae68213 | ||
|
|
0e73128f40 | ||
|
|
927c003d22 | ||
|
|
bd73823828 | ||
|
|
11582bc7d3 | ||
|
|
20ed4f96ba | ||
|
|
19790e9011 | ||
|
|
3a29e03458 | ||
|
|
e2eb685d76 | ||
|
|
86cb28fe34 | ||
|
|
bcc9679339 | ||
|
|
e5aeff50dc | ||
|
|
5f44c195e9 | ||
|
|
e4387e4aad | ||
|
|
b1b336804d | ||
|
|
9985c43817 | ||
|
|
ae71a5abf6 | ||
|
|
df199c5788 | ||
|
|
c1ba4f1b55 | ||
|
|
afc0097b12 | ||
|
|
4e9f971c91 | ||
|
|
b1cc28bbda | ||
|
|
80d30bdd30 | ||
|
|
f27566669b | ||
|
|
29f12ddaf4 | ||
|
|
ed15ff0515 | ||
|
|
a8f71f79fe | ||
|
|
68c2478e0e | ||
|
|
4d8b661d51 | ||
|
|
1b59b0b739 | ||
|
|
093cfcdf42 | ||
|
|
41801a60ad | ||
|
|
5ff0957861 | ||
|
|
6913b8beb5 | ||
|
|
c8d17bc363 | ||
|
|
2cbf1259a8 | ||
|
|
59dc513ac3 | ||
|
|
87b110bb86 | ||
|
|
1b3e1a7abe | ||
|
|
0afabc60ae | ||
|
|
2d4ea720eb | ||
|
|
9c757bbe6e | ||
|
|
eba788e8c9 | ||
|
|
444b111a62 | ||
|
|
a364ab4ea7 | ||
|
|
be7840c827 | ||
|
|
a46e51e8db | ||
|
|
789ebb8990 | ||
|
|
e3cd96bf19 | ||
|
|
7746042adc | ||
|
|
543c4423a2 | ||
|
|
3bd4d32b8d | ||
|
|
56a686d3e0 | ||
|
|
2f97c789dd | ||
|
|
04ca808e80 | ||
|
|
9b79743c5d | ||
|
|
a386826808 | ||
|
|
668894fc4d | ||
|
|
dc882e6279 | ||
|
|
d6eebf82be | ||
|
|
799f509ba9 | ||
|
|
688a234127 | ||
|
|
6ccf617d62 | ||
|
|
b3b4811b2c | ||
|
|
966e4246e5 | ||
|
|
9377c4f3ad | ||
|
|
b876128635 | ||
|
|
c0da801580 | ||
|
|
149310e1ec | ||
|
|
4e625c18dc | ||
|
|
a5d5113be3 | ||
|
|
7900c493af | ||
|
|
76fe5d8831 | ||
|
|
37031721dd | ||
|
|
3cc283cbee | ||
|
|
35cf98fff2 | ||
|
|
ca41ea2d5c | ||
|
|
daffc4e6a4 | ||
|
|
5f3cb9019b | ||
|
|
4951b58b21 | ||
|
|
7be7586971 | ||
|
|
6d64098288 | ||
|
|
4351110082 | ||
|
|
6652138d3e | ||
|
|
c8d0d475e4 | ||
|
|
39b25029fc | ||
|
|
b5cabd6d8e | ||
|
|
b169a5c707 | ||
|
|
4f816c06b0 | ||
|
|
b5f49d9563 | ||
|
|
274fd5ab8b | ||
|
|
e48d7de763 | ||
|
|
f426940bd2 | ||
|
|
6c11dd12d7 | ||
|
|
c2b14d3075 | ||
|
|
8a144ebfee | ||
|
|
5440fcdf54 | ||
|
|
66b2d496af | ||
|
|
444a0282d7 | ||
|
|
f897ab4eb8 | ||
|
|
993c187e37 | ||
|
|
3ce67b282f | ||
|
|
606e59a5d0 | ||
|
|
0f26b1eafb | ||
|
|
80e6b1fc01 | ||
|
|
58a89edad7 | ||
|
|
bfe47eb152 | ||
|
|
32adc38e94 | ||
|
|
1584971908 | ||
|
|
025bebb3e2 | ||
|
|
4047adcc35 | ||
|
|
d4cf03c9fd | ||
|
|
5ba2068fc2 | ||
|
|
6d5743c506 | ||
|
|
a551619de6 | ||
|
|
873b113cb3 | ||
|
|
2280e66d73 | ||
|
|
2133897bbe | ||
|
|
bee5cb55a1 | ||
|
|
0a0838b616 | ||
|
|
b376dfa1e6 | ||
|
|
7ac0577b34 | ||
|
|
f16e060e87 | ||
|
|
9aaae24583 | ||
|
|
915ced7b92 | ||
|
|
5a36b9075f | ||
|
|
b5a7f46ecc | ||
|
|
4381657c5e | ||
|
|
d440b2f2b2 | ||
|
|
5b42aea9e7 | ||
|
|
e1d7a6b9ac | ||
|
|
38778f8adc | ||
|
|
8b7a86bd17 | ||
|
|
619bae745b | ||
|
|
2cf72bad30 | ||
|
|
e6959f093c | ||
|
|
8d783e8e1f | ||
|
|
f03098551e | ||
|
|
c4df8090e2 | ||
|
|
fe3523f47a | ||
|
|
199d846acb | ||
|
|
b07e479840 | ||
|
|
9bf37fde02 | ||
|
|
1054325b2d | ||
|
|
ef8cb11707 | ||
|
|
c23c40df8a | ||
|
|
77d606df34 | ||
|
|
e717c9dba2 | ||
|
|
3d312e2140 | ||
|
|
18de21f723 | ||
|
|
6aebaf6f47 | ||
|
|
a092a2fa43 | ||
|
|
227eac10f1 | ||
|
|
1cbd5485e7 | ||
|
|
610c3cf681 | ||
|
|
96d45cc341 | ||
|
|
d6c68f1a84 | ||
|
|
ac0dd90c37 | ||
|
|
9470850258 | ||
|
|
2982e9943e | ||
|
|
80e13bc24a | ||
|
|
62dad721fc | ||
|
|
cc5cfc7525 | ||
|
|
795dee85ef | ||
|
|
dbd5bef038 | ||
|
|
dd2a420578 | ||
|
|
eeee30ca03 | ||
|
|
82e8792737 | ||
|
|
6b18b3df34 | ||
|
|
fcebed19b9 | ||
|
|
af5f6176b5 | ||
|
|
424cc46db0 | ||
|
|
ce47ccecc4 | ||
|
|
d940f17390 | ||
|
|
6351b5d0dc | ||
|
|
9c4ac24a66 | ||
|
|
bf66df2a29 | ||
|
|
962ce380cd | ||
|
|
9769afb944 | ||
|
|
052b45a510 | ||
|
|
84a96e862e | ||
|
|
3105235a7a | ||
|
|
342bce2168 | ||
|
|
86d8cbc4d2 | ||
|
|
6b63bd6a44 | ||
|
|
225707c877 | ||
|
|
66da6f18e3 | ||
|
|
bdf8bf391c | ||
|
|
f66d9e1a22 | ||
|
|
ccd3d96942 | ||
|
|
00b6c6a437 | ||
|
|
21ef3b0ecf |
719
.github/workflows/DNS.yml
vendored
719
.github/workflows/DNS.yml
vendored
@@ -1,254 +1,465 @@
|
||||
name: DNS
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'dnsapi/*.sh'
|
||||
- '.github/workflows/DNS.yml'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'dev'
|
||||
paths:
|
||||
- 'dnsapi/*.sh'
|
||||
- '.github/workflows/DNS.yml'
|
||||
|
||||
|
||||
jobs:
|
||||
CheckToken:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
hasToken: ${{ steps.step_one.outputs.hasToken }}
|
||||
steps:
|
||||
- name: Set the value
|
||||
id: step_one
|
||||
run: |
|
||||
if [ "${{secrets.TokenName1}}" ] ; then
|
||||
echo "::set-output name=hasToken::true"
|
||||
else
|
||||
echo "::set-output name=hasToken::false"
|
||||
fi
|
||||
- name: Check the value
|
||||
run: echo ${{ steps.step_one.outputs.hasToken }}
|
||||
|
||||
Fail:
|
||||
runs-on: ubuntu-latest
|
||||
needs: CheckToken
|
||||
if: "contains(needs.CheckToken.outputs.hasToken, 'false')"
|
||||
steps:
|
||||
- name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test"
|
||||
run: |
|
||||
echo "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test"
|
||||
if [ "${{github.repository_owner}}" != "acmesh-official" ]; then
|
||||
false
|
||||
fi
|
||||
|
||||
Docker:
|
||||
runs-on: ubuntu-latest
|
||||
needs: CheckToken
|
||||
if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
TestingDomain: ${{ secrets.TestingDomain }}
|
||||
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
|
||||
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||
CASE: le_test_dnsapi
|
||||
TEST_LOCAL: 1
|
||||
DEBUG: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- name: Set env file
|
||||
run: |
|
||||
cd ../acmetest
|
||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||
echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> docker.env
|
||||
fi
|
||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||
echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> docker.env
|
||||
fi
|
||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||
echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> docker.env
|
||||
fi
|
||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||
echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> docker.env
|
||||
fi
|
||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||
echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env
|
||||
fi
|
||||
echo "TEST_DNS_NO_WILDCARD" >> docker.env
|
||||
echo "TEST_DNS_SLEEP" >> docker.env
|
||||
- name: Run acmetest
|
||||
run: cd ../acmetest && ./rundocker.sh testall
|
||||
|
||||
MacOS:
|
||||
runs-on: macos-latest
|
||||
needs: Docker
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
TestingDomain: ${{ secrets.TestingDomain }}
|
||||
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
|
||||
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||
CASE: le_test_dnsapi
|
||||
TEST_LOCAL: 1
|
||||
DEBUG: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install tools
|
||||
run: brew install socat
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- name: Run acmetest
|
||||
run: |
|
||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
|
||||
Windows:
|
||||
runs-on: windows-latest
|
||||
needs: MacOS
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
TestingDomain: ${{ secrets.TestingDomain }}
|
||||
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
|
||||
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||
CASE: le_test_dnsapi
|
||||
TEST_LOCAL: 1
|
||||
DEBUG: 1
|
||||
steps:
|
||||
- name: Set git to use LF
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install cygwin base packages with chocolatey
|
||||
run: |
|
||||
choco config get cacheLocation
|
||||
choco install --no-progress cygwin
|
||||
shell: cmd
|
||||
- name: Install cygwin additional packages
|
||||
run: |
|
||||
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git
|
||||
shell: cmd
|
||||
- name: Set ENV
|
||||
shell: cmd
|
||||
run: |
|
||||
echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV%
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- name: Run acmetest
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
|
||||
FreeBSD:
|
||||
runs-on: macos-10.15
|
||||
needs: Windows
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
TestingDomain: ${{ secrets.TestingDomain }}
|
||||
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
|
||||
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||
CASE: le_test_dnsapi
|
||||
TEST_LOCAL: 1
|
||||
DEBUG: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/freebsd-vm@v0.1.4
|
||||
with:
|
||||
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
||||
prepare: pkg install -y socat curl
|
||||
usesh: true
|
||||
run: |
|
||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
|
||||
Solaris:
|
||||
runs-on: macos-10.15
|
||||
needs: FreeBSD
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
TestingDomain: ${{ secrets.TestingDomain }}
|
||||
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
|
||||
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||
CASE: le_test_dnsapi
|
||||
TEST_LOCAL: 1
|
||||
DEBUG: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/solaris-vm@v0.0.5
|
||||
with:
|
||||
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
||||
prepare: pkgutil -y -i socat
|
||||
run: |
|
||||
pkg set-mediator -v -I default@1.1 openssl
|
||||
export PATH=/usr/gnu/bin:$PATH
|
||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
name: DNS
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'dnsapi/*.sh'
|
||||
- '.github/workflows/DNS.yml'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'dev'
|
||||
paths:
|
||||
- 'dnsapi/*.sh'
|
||||
- '.github/workflows/DNS.yml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
CheckToken:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
hasToken: ${{ steps.step_one.outputs.hasToken }}
|
||||
steps:
|
||||
- name: Set the value
|
||||
id: step_one
|
||||
run: |
|
||||
if [ "${{secrets.TokenName1}}" ] ; then
|
||||
echo "::set-output name=hasToken::true"
|
||||
else
|
||||
echo "::set-output name=hasToken::false"
|
||||
fi
|
||||
- name: Check the value
|
||||
run: echo ${{ steps.step_one.outputs.hasToken }}
|
||||
|
||||
Fail:
|
||||
runs-on: ubuntu-latest
|
||||
needs: CheckToken
|
||||
if: "contains(needs.CheckToken.outputs.hasToken, 'false')"
|
||||
steps:
|
||||
- name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test"
|
||||
run: |
|
||||
echo "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test"
|
||||
if [ "${{github.repository_owner}}" != "acmesh-official" ]; then
|
||||
false
|
||||
fi
|
||||
|
||||
Docker:
|
||||
runs-on: ubuntu-latest
|
||||
needs: CheckToken
|
||||
if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
TestingDomain: ${{ secrets.TestingDomain }}
|
||||
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
|
||||
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||
CASE: le_test_dnsapi
|
||||
TEST_LOCAL: 1
|
||||
DEBUG: ${{ secrets.DEBUG }}
|
||||
http_proxy: ${{ secrets.http_proxy }}
|
||||
https_proxy: ${{ secrets.https_proxy }}
|
||||
TokenName1: ${{ secrets.TokenName1}}
|
||||
TokenName2: ${{ secrets.TokenName2}}
|
||||
TokenName3: ${{ secrets.TokenName3}}
|
||||
TokenName4: ${{ secrets.TokenName4}}
|
||||
TokenName5: ${{ secrets.TokenName5}}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- name: Set env file
|
||||
run: |
|
||||
cd ../acmetest
|
||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||
echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> docker.env
|
||||
fi
|
||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||
echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> docker.env
|
||||
fi
|
||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||
echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> docker.env
|
||||
fi
|
||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||
echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> docker.env
|
||||
fi
|
||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||
echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env
|
||||
fi
|
||||
|
||||
- name: Run acmetest
|
||||
run: cd ../acmetest && ./rundocker.sh testall
|
||||
|
||||
|
||||
|
||||
|
||||
MacOS:
|
||||
runs-on: macos-latest
|
||||
needs: Docker
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
TestingDomain: ${{ secrets.TestingDomain }}
|
||||
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
|
||||
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||
CASE: le_test_dnsapi
|
||||
TEST_LOCAL: 1
|
||||
DEBUG: ${{ secrets.DEBUG }}
|
||||
http_proxy: ${{ secrets.http_proxy }}
|
||||
https_proxy: ${{ secrets.https_proxy }}
|
||||
TokenName1: ${{ secrets.TokenName1}}
|
||||
TokenName2: ${{ secrets.TokenName2}}
|
||||
TokenName3: ${{ secrets.TokenName3}}
|
||||
TokenName4: ${{ secrets.TokenName4}}
|
||||
TokenName5: ${{ secrets.TokenName5}}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install tools
|
||||
run: brew install socat
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- name: Run acmetest
|
||||
run: |
|
||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
|
||||
|
||||
|
||||
|
||||
Windows:
|
||||
runs-on: windows-latest
|
||||
needs: MacOS
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
TestingDomain: ${{ secrets.TestingDomain }}
|
||||
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
|
||||
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||
CASE: le_test_dnsapi
|
||||
TEST_LOCAL: 1
|
||||
DEBUG: ${{ secrets.DEBUG }}
|
||||
http_proxy: ${{ secrets.http_proxy }}
|
||||
https_proxy: ${{ secrets.https_proxy }}
|
||||
TokenName1: ${{ secrets.TokenName1}}
|
||||
TokenName2: ${{ secrets.TokenName2}}
|
||||
TokenName3: ${{ secrets.TokenName3}}
|
||||
TokenName4: ${{ secrets.TokenName4}}
|
||||
TokenName5: ${{ secrets.TokenName5}}
|
||||
steps:
|
||||
- name: Set git to use LF
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install cygwin base packages with chocolatey
|
||||
run: |
|
||||
choco config get cacheLocation
|
||||
choco install --no-progress cygwin
|
||||
shell: cmd
|
||||
- name: Install cygwin additional packages
|
||||
run: |
|
||||
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s https://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git
|
||||
shell: cmd
|
||||
- name: Set ENV
|
||||
shell: cmd
|
||||
run: |
|
||||
echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV%
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- name: Run acmetest
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
|
||||
|
||||
|
||||
FreeBSD:
|
||||
runs-on: macos-12
|
||||
needs: Windows
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
TestingDomain: ${{ secrets.TestingDomain }}
|
||||
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
|
||||
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||
CASE: le_test_dnsapi
|
||||
TEST_LOCAL: 1
|
||||
DEBUG: ${{ secrets.DEBUG }}
|
||||
http_proxy: ${{ secrets.http_proxy }}
|
||||
https_proxy: ${{ secrets.https_proxy }}
|
||||
TokenName1: ${{ secrets.TokenName1}}
|
||||
TokenName2: ${{ secrets.TokenName2}}
|
||||
TokenName3: ${{ secrets.TokenName3}}
|
||||
TokenName4: ${{ secrets.TokenName4}}
|
||||
TokenName5: ${{ secrets.TokenName5}}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/freebsd-vm@v0
|
||||
with:
|
||||
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
||||
prepare: pkg install -y socat curl
|
||||
usesh: true
|
||||
copyback: false
|
||||
run: |
|
||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
|
||||
|
||||
|
||||
|
||||
OpenBSD:
|
||||
runs-on: macos-12
|
||||
needs: FreeBSD
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
TestingDomain: ${{ secrets.TestingDomain }}
|
||||
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
|
||||
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||
CASE: le_test_dnsapi
|
||||
TEST_LOCAL: 1
|
||||
DEBUG: ${{ secrets.DEBUG }}
|
||||
http_proxy: ${{ secrets.http_proxy }}
|
||||
https_proxy: ${{ secrets.https_proxy }}
|
||||
TokenName1: ${{ secrets.TokenName1}}
|
||||
TokenName2: ${{ secrets.TokenName2}}
|
||||
TokenName3: ${{ secrets.TokenName3}}
|
||||
TokenName4: ${{ secrets.TokenName4}}
|
||||
TokenName5: ${{ secrets.TokenName5}}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/openbsd-vm@v0
|
||||
with:
|
||||
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
||||
prepare: pkg_add socat curl
|
||||
usesh: true
|
||||
copyback: false
|
||||
run: |
|
||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
|
||||
|
||||
|
||||
|
||||
NetBSD:
|
||||
runs-on: macos-12
|
||||
needs: OpenBSD
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
TestingDomain: ${{ secrets.TestingDomain }}
|
||||
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
|
||||
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||
CASE: le_test_dnsapi
|
||||
TEST_LOCAL: 1
|
||||
DEBUG: ${{ secrets.DEBUG }}
|
||||
http_proxy: ${{ secrets.http_proxy }}
|
||||
https_proxy: ${{ secrets.https_proxy }}
|
||||
TokenName1: ${{ secrets.TokenName1}}
|
||||
TokenName2: ${{ secrets.TokenName2}}
|
||||
TokenName3: ${{ secrets.TokenName3}}
|
||||
TokenName4: ${{ secrets.TokenName4}}
|
||||
TokenName5: ${{ secrets.TokenName5}}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/netbsd-vm@v0
|
||||
with:
|
||||
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
||||
prepare: |
|
||||
pkg_add curl socat
|
||||
usesh: true
|
||||
copyback: false
|
||||
run: |
|
||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
|
||||
|
||||
|
||||
|
||||
DragonFlyBSD:
|
||||
runs-on: macos-12
|
||||
needs: NetBSD
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
TestingDomain: ${{ secrets.TestingDomain }}
|
||||
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
|
||||
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||
CASE: le_test_dnsapi
|
||||
TEST_LOCAL: 1
|
||||
DEBUG: ${{ secrets.DEBUG }}
|
||||
http_proxy: ${{ secrets.http_proxy }}
|
||||
https_proxy: ${{ secrets.https_proxy }}
|
||||
TokenName1: ${{ secrets.TokenName1}}
|
||||
TokenName2: ${{ secrets.TokenName2}}
|
||||
TokenName3: ${{ secrets.TokenName3}}
|
||||
TokenName4: ${{ secrets.TokenName4}}
|
||||
TokenName5: ${{ secrets.TokenName5}}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/dragonflybsd-vm@v0
|
||||
with:
|
||||
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
||||
prepare: |
|
||||
pkg install -y curl socat
|
||||
usesh: true
|
||||
copyback: false
|
||||
run: |
|
||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Solaris:
|
||||
runs-on: macos-12
|
||||
needs: DragonFlyBSD
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
TestingDomain: ${{ secrets.TestingDomain }}
|
||||
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
|
||||
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||
CASE: le_test_dnsapi
|
||||
TEST_LOCAL: 1
|
||||
DEBUG: ${{ secrets.DEBUG }}
|
||||
http_proxy: ${{ secrets.http_proxy }}
|
||||
https_proxy: ${{ secrets.https_proxy }}
|
||||
HTTPS_INSECURE: 1 # always set to 1 to ignore https error, since Solaris doesn't accept the expired ISRG X1 root
|
||||
TokenName1: ${{ secrets.TokenName1}}
|
||||
TokenName2: ${{ secrets.TokenName2}}
|
||||
TokenName3: ${{ secrets.TokenName3}}
|
||||
TokenName4: ${{ secrets.TokenName4}}
|
||||
TokenName5: ${{ secrets.TokenName5}}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/solaris-vm@v0
|
||||
with:
|
||||
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy HTTPS_INSECURE TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
||||
copyback: false
|
||||
prepare: pkgutil -y -i socat
|
||||
run: |
|
||||
pkg set-mediator -v -I default@1.1 openssl
|
||||
export PATH=/usr/gnu/bin:$PATH
|
||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
||||
fi
|
||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
|
||||
|
||||
|
||||
71
.github/workflows/DragonFlyBSD.yml
vendored
Normal file
71
.github/workflows/DragonFlyBSD.yml
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
name: DragonFlyBSD
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '*.sh'
|
||||
- '.github/workflows/DragonFlyBSD.yml'
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
paths:
|
||||
- '*.sh'
|
||||
- '.github/workflows/DragonFlyBSD.yml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
DragonFlyBSD:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- TEST_ACME_Server: "LetsEncrypt.org_test"
|
||||
CA_ECDSA: ""
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
#- TEST_ACME_Server: "ZeroSSL.com"
|
||||
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
|
||||
# CA: "ZeroSSL RSA Domain Secure Site CA"
|
||||
# CA_EMAIL: "githubtest@acme.sh"
|
||||
# TEST_PREFERRED_CHAIN: ""
|
||||
runs-on: macos-12
|
||||
env:
|
||||
TEST_LOCAL: 1
|
||||
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
|
||||
CA_ECDSA: ${{ matrix.CA_ECDSA }}
|
||||
CA: ${{ matrix.CA }}
|
||||
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: vmactions/cf-tunnel@v0
|
||||
id: tunnel
|
||||
with:
|
||||
protocol: http
|
||||
port: 8080
|
||||
- name: Set envs
|
||||
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/dragonflybsd-vm@v0
|
||||
with:
|
||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
|
||||
copyback: "false"
|
||||
nat: |
|
||||
"8080": "80"
|
||||
prepare: |
|
||||
pkg install -y curl socat
|
||||
usesh: true
|
||||
run: |
|
||||
cd ../acmetest \
|
||||
&& ./letest.sh
|
||||
|
||||
|
||||
27
.github/workflows/FreeBSD.yml
vendored
27
.github/workflows/FreeBSD.yml
vendored
@@ -14,6 +14,11 @@ on:
|
||||
- '*.sh'
|
||||
- '.github/workflows/FreeBSD.yml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
FreeBSD:
|
||||
@@ -25,12 +30,18 @@ jobs:
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
- TEST_ACME_Server: "LetsEncrypt.org_test"
|
||||
CA_ECDSA: ""
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
ACME_USE_WGET: 1
|
||||
#- TEST_ACME_Server: "ZeroSSL.com"
|
||||
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
|
||||
# CA: "ZeroSSL RSA Domain Secure Site CA"
|
||||
# CA_EMAIL: "githubtest@acme.sh"
|
||||
# TEST_PREFERRED_CHAIN: ""
|
||||
runs-on: macos-10.15
|
||||
runs-on: macos-12
|
||||
env:
|
||||
TEST_LOCAL: 1
|
||||
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
|
||||
@@ -38,9 +49,10 @@ jobs:
|
||||
CA: ${{ matrix.CA }}
|
||||
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: vmactions/cf-tunnel@v0.0.3
|
||||
- uses: actions/checkout@v3
|
||||
- uses: vmactions/cf-tunnel@v0
|
||||
id: tunnel
|
||||
with:
|
||||
protocol: http
|
||||
@@ -48,14 +60,15 @@ jobs:
|
||||
- name: Set envs
|
||||
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/freebsd-vm@v0.1.5
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/freebsd-vm@v0
|
||||
with:
|
||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
|
||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
|
||||
nat: |
|
||||
"8080": "80"
|
||||
prepare: pkg install -y socat curl
|
||||
prepare: pkg install -y socat curl wget
|
||||
usesh: true
|
||||
copyback: false
|
||||
run: |
|
||||
cd ../acmetest \
|
||||
&& ./letest.sh
|
||||
|
||||
11
.github/workflows/Linux.yml
vendored
11
.github/workflows/Linux.yml
vendored
@@ -15,6 +15,12 @@ on:
|
||||
- '.github/workflows/Linux.yml'
|
||||
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
Linux:
|
||||
@@ -25,12 +31,13 @@ jobs:
|
||||
env:
|
||||
TEST_LOCAL: 1
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
TEST_ACME_Server: "LetsEncrypt.org_test"
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Clone acmetest
|
||||
run: |
|
||||
cd .. \
|
||||
&& git clone https://github.com/acmesh-official/acmetest.git \
|
||||
&& git clone --depth=1 https://github.com/acmesh-official/acmetest.git \
|
||||
&& cp -r acme.sh acmetest/
|
||||
- name: Run acmetest
|
||||
run: |
|
||||
|
||||
9
.github/workflows/MacOS.yml
vendored
9
.github/workflows/MacOS.yml
vendored
@@ -14,6 +14,11 @@ on:
|
||||
- '*.sh'
|
||||
- '.github/workflows/MacOS.yml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
MacOS:
|
||||
@@ -39,13 +44,13 @@ jobs:
|
||||
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install tools
|
||||
run: brew install socat
|
||||
- name: Clone acmetest
|
||||
run: |
|
||||
cd .. \
|
||||
&& git clone https://github.com/acmesh-official/acmetest.git \
|
||||
&& git clone --depth=1 https://github.com/acmesh-official/acmetest.git \
|
||||
&& cp -r acme.sh acmetest/
|
||||
- name: Run acmetest
|
||||
run: |
|
||||
|
||||
72
.github/workflows/NetBSD.yml
vendored
Normal file
72
.github/workflows/NetBSD.yml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
name: NetBSD
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '*.sh'
|
||||
- '.github/workflows/NetBSD.yml'
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
paths:
|
||||
- '*.sh'
|
||||
- '.github/workflows/NetBSD.yml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
NetBSD:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- TEST_ACME_Server: "LetsEncrypt.org_test"
|
||||
CA_ECDSA: ""
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
#- TEST_ACME_Server: "ZeroSSL.com"
|
||||
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
|
||||
# CA: "ZeroSSL RSA Domain Secure Site CA"
|
||||
# CA_EMAIL: "githubtest@acme.sh"
|
||||
# TEST_PREFERRED_CHAIN: ""
|
||||
runs-on: macos-12
|
||||
env:
|
||||
TEST_LOCAL: 1
|
||||
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
|
||||
CA_ECDSA: ${{ matrix.CA_ECDSA }}
|
||||
CA: ${{ matrix.CA }}
|
||||
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: vmactions/cf-tunnel@v0
|
||||
id: tunnel
|
||||
with:
|
||||
protocol: http
|
||||
port: 8080
|
||||
- name: Set envs
|
||||
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/netbsd-vm@v0
|
||||
with:
|
||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
|
||||
nat: |
|
||||
"8080": "80"
|
||||
prepare: |
|
||||
export PKG_PATH="https://cdn.NetBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f '1 2' -d.)/All/"
|
||||
pkg_add curl socat
|
||||
usesh: true
|
||||
copyback: false
|
||||
run: |
|
||||
cd ../acmetest \
|
||||
&& ./letest.sh
|
||||
|
||||
|
||||
76
.github/workflows/OpenBSD.yml
vendored
Normal file
76
.github/workflows/OpenBSD.yml
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
name: OpenBSD
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '*.sh'
|
||||
- '.github/workflows/OpenBSD.yml'
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
paths:
|
||||
- '*.sh'
|
||||
- '.github/workflows/OpenBSD.yml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
OpenBSD:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- TEST_ACME_Server: "LetsEncrypt.org_test"
|
||||
CA_ECDSA: ""
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
- TEST_ACME_Server: "LetsEncrypt.org_test"
|
||||
CA_ECDSA: ""
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
ACME_USE_WGET: 1
|
||||
#- TEST_ACME_Server: "ZeroSSL.com"
|
||||
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
|
||||
# CA: "ZeroSSL RSA Domain Secure Site CA"
|
||||
# CA_EMAIL: "githubtest@acme.sh"
|
||||
# TEST_PREFERRED_CHAIN: ""
|
||||
runs-on: macos-12
|
||||
env:
|
||||
TEST_LOCAL: 1
|
||||
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
|
||||
CA_ECDSA: ${{ matrix.CA_ECDSA }}
|
||||
CA: ${{ matrix.CA }}
|
||||
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: vmactions/cf-tunnel@v0
|
||||
id: tunnel
|
||||
with:
|
||||
protocol: http
|
||||
port: 8080
|
||||
- name: Set envs
|
||||
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/openbsd-vm@v0
|
||||
with:
|
||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
|
||||
nat: |
|
||||
"8080": "80"
|
||||
prepare: pkg_add socat curl wget
|
||||
usesh: true
|
||||
copyback: false
|
||||
run: |
|
||||
cd ../acmetest \
|
||||
&& ./letest.sh
|
||||
|
||||
|
||||
24
.github/workflows/PebbleStrict.yml
vendored
24
.github/workflows/PebbleStrict.yml
vendored
@@ -13,6 +13,13 @@ on:
|
||||
- '*.sh'
|
||||
- '.github/workflows/PebbleStrict.yml'
|
||||
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
PebbleStrict:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -26,7 +33,7 @@ jobs:
|
||||
TEST_CA: "Pebble Intermediate CA"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install tools
|
||||
run: sudo apt-get install -y socat
|
||||
- name: Run Pebble
|
||||
@@ -34,15 +41,15 @@ jobs:
|
||||
- name: Set up Pebble
|
||||
run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- name: Run acmetest
|
||||
run: cd ../acmetest && ./letest.sh
|
||||
|
||||
PebbleStrict_IPCert:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
TestingDomain: 10.30.50.1
|
||||
ACME_DIRECTORY: https://localhost:14000/dir
|
||||
TestingDomain: 1.23.45.67
|
||||
TEST_ACME_Server: https://localhost:14000/dir
|
||||
HTTPS_INSECURE: 1
|
||||
Le_HTTPPort: 5002
|
||||
Le_TLSPort: 5001
|
||||
@@ -51,12 +58,15 @@ jobs:
|
||||
TEST_IPCERT: 1
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install tools
|
||||
run: sudo apt-get install -y socat
|
||||
- name: Run Pebble
|
||||
run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d
|
||||
run: |
|
||||
docker run --rm -itd --name=pebble \
|
||||
-e PEBBLE_VA_ALWAYS_VALID=1 \
|
||||
-p 14000:14000 -p 15000:15000 letsencrypt/pebble:latest pebble -config /test/config/pebble-config.json -strict
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- name: Run acmetest
|
||||
run: cd ../acmetest && ./letest.sh
|
||||
27
.github/workflows/Solaris.yml
vendored
27
.github/workflows/Solaris.yml
vendored
@@ -15,6 +15,11 @@ on:
|
||||
- '.github/workflows/Solaris.yml'
|
||||
|
||||
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
Solaris:
|
||||
strategy:
|
||||
@@ -25,12 +30,18 @@ jobs:
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
- TEST_ACME_Server: "LetsEncrypt.org_test"
|
||||
CA_ECDSA: ""
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
ACME_USE_WGET: 1
|
||||
#- TEST_ACME_Server: "ZeroSSL.com"
|
||||
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
|
||||
# CA: "ZeroSSL RSA Domain Secure Site CA"
|
||||
# CA_EMAIL: "githubtest@acme.sh"
|
||||
# TEST_PREFERRED_CHAIN: ""
|
||||
runs-on: macos-10.15
|
||||
runs-on: macos-12
|
||||
env:
|
||||
TEST_LOCAL: 1
|
||||
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
|
||||
@@ -38,9 +49,10 @@ jobs:
|
||||
CA: ${{ matrix.CA }}
|
||||
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: vmactions/cf-tunnel@v0.0.3
|
||||
- uses: actions/checkout@v3
|
||||
- uses: vmactions/cf-tunnel@v0
|
||||
id: tunnel
|
||||
with:
|
||||
protocol: http
|
||||
@@ -48,13 +60,14 @@ jobs:
|
||||
- name: Set envs
|
||||
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/solaris-vm@v0.0.5
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/solaris-vm@v0
|
||||
with:
|
||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
|
||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
|
||||
copyback: "false"
|
||||
nat: |
|
||||
"8080": "80"
|
||||
prepare: pkgutil -y -i socat curl
|
||||
prepare: pkgutil -y -i socat curl wget
|
||||
run: |
|
||||
cd ../acmetest \
|
||||
&& ./letest.sh
|
||||
|
||||
18
.github/workflows/Ubuntu.yml
vendored
18
.github/workflows/Ubuntu.yml
vendored
@@ -14,6 +14,11 @@ on:
|
||||
- '*.sh'
|
||||
- '.github/workflows/Ubuntu.yml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
Ubuntu:
|
||||
@@ -25,6 +30,12 @@ jobs:
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
- TEST_ACME_Server: "LetsEncrypt.org_test"
|
||||
CA_ECDSA: ""
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
ACME_USE_WGET: 1
|
||||
- TEST_ACME_Server: "ZeroSSL.com"
|
||||
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
|
||||
CA: "ZeroSSL RSA Domain Secure Site CA"
|
||||
@@ -57,10 +68,11 @@ jobs:
|
||||
NO_REVOKE: ${{ matrix.NO_REVOKE }}
|
||||
TEST_IPCERT: ${{ matrix.TEST_IPCERT }}
|
||||
TestingDomain: ${{ matrix.TestingDomain }}
|
||||
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install tools
|
||||
run: sudo apt-get install -y socat
|
||||
run: sudo apt-get install -y socat wget
|
||||
- name: Start StepCA
|
||||
if: ${{ matrix.TEST_ACME_Server=='https://localhost:9000/acme/acme/directory' }}
|
||||
run: |
|
||||
@@ -76,7 +88,7 @@ jobs:
|
||||
- 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: |
|
||||
|
||||
11
.github/workflows/Windows.yml
vendored
11
.github/workflows/Windows.yml
vendored
@@ -15,6 +15,11 @@ on:
|
||||
- '.github/workflows/Windows.yml'
|
||||
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
jobs:
|
||||
Windows:
|
||||
strategy:
|
||||
@@ -44,7 +49,7 @@ jobs:
|
||||
- name: Set git to use LF
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install cygwin base packages with chocolatey
|
||||
run: |
|
||||
choco config get cacheLocation
|
||||
@@ -52,7 +57,7 @@ jobs:
|
||||
shell: cmd
|
||||
- name: Install cygwin additional packages
|
||||
run: |
|
||||
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git,xxd
|
||||
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s https://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git,xxd
|
||||
shell: cmd
|
||||
- name: Set ENV
|
||||
shell: cmd
|
||||
@@ -64,7 +69,7 @@ jobs:
|
||||
echo "PATH=%PATH%"
|
||||
- name: Clone acmetest
|
||||
shell: cmd
|
||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- name: Run acmetest
|
||||
shell: cmd
|
||||
run: cd ../acmetest && bash.exe -c ./letest.sh
|
||||
|
||||
8
.github/workflows/dockerhub.yml
vendored
8
.github/workflows/dockerhub.yml
vendored
@@ -11,7 +11,11 @@ on:
|
||||
- "Dockerfile"
|
||||
- '.github/workflows/dockerhub.yml'
|
||||
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
jobs:
|
||||
CheckToken:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -37,7 +41,7 @@ jobs:
|
||||
if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
|
||||
steps:
|
||||
- name: checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
- name: Set up Docker Buildx
|
||||
|
||||
19
.github/workflows/issue.yml
vendored
Normal file
19
.github/workflows/issue.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: "Update issues"
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
comment:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: "Please upgrade to the latest code and try again first. Maybe it's already fixed. ```acme.sh --upgrade``` If it's still not working, please provide the log with `--debug 2`, otherwise, nobody can help you."
|
||||
|
||||
})
|
||||
30
.github/workflows/pr_dns.yml
vendored
Normal file
30
.github/workflows/pr_dns.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: Check dns api
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
branches:
|
||||
- 'dev'
|
||||
paths:
|
||||
- 'dnsapi/*.sh'
|
||||
|
||||
|
||||
jobs:
|
||||
welcome:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
await github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: `**Welcome**
|
||||
Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test).
|
||||
Then reply on this message, otherwise, your code will not be reviewed or merged.
|
||||
We look forward to reviewing your Pull request shortly ✨
|
||||
`
|
||||
})
|
||||
|
||||
30
.github/workflows/pr_notify.yml
vendored
Normal file
30
.github/workflows/pr_notify.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: Check dns api
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
branches:
|
||||
- 'dev'
|
||||
paths:
|
||||
- 'notify/*.sh'
|
||||
|
||||
|
||||
jobs:
|
||||
welcome:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
await github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: `**Welcome**
|
||||
Please make sure you're read our [Code-of-conduct](../wiki/Code-of-conduct) and add the usage here: [notify](../wiki/notify).
|
||||
Then reply on this message, otherwise, your code will not be reviewed or merged.
|
||||
We look forward to reviewing your Pull request shortly ✨
|
||||
`
|
||||
})
|
||||
|
||||
11
.github/workflows/shellcheck.yml
vendored
11
.github/workflows/shellcheck.yml
vendored
@@ -13,20 +13,25 @@ on:
|
||||
- '**.sh'
|
||||
- '.github/workflows/shellcheck.yml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
jobs:
|
||||
ShellCheck:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install Shellcheck
|
||||
run: sudo apt-get install -y shellcheck
|
||||
- name: DoShellcheck
|
||||
run: shellcheck -V && shellcheck -e SC2181 **/*.sh && echo "shellcheck OK"
|
||||
run: shellcheck -V && shellcheck -e SC2181 -e SC2089 **/*.sh && echo "shellcheck OK"
|
||||
|
||||
shfmt:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install shfmt
|
||||
run: curl -sSL https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 -o ~/shfmt && chmod +x ~/shfmt
|
||||
- name: shfmt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.15
|
||||
FROM alpine:3.16.3
|
||||
|
||||
RUN apk --no-cache add -f \
|
||||
openssl \
|
||||
|
||||
42
README.md
42
README.md
@@ -1,10 +1,14 @@
|
||||
# An ACME Shell script: acme.sh
|
||||
|
||||
[](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml)
|
||||
[](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml)
|
||||
[](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml)
|
||||
[](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml)
|
||||
[](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml)
|
||||
[](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml)
|
||||
[](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml)
|
||||
[](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml)
|
||||
|
||||
|
||||

|
||||

|
||||
@@ -68,21 +72,23 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
|
||||
|4|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml)|Solaris
|
||||
|5|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml)| Ubuntu
|
||||
|6|NA|pfsense
|
||||
|7|NA|OpenBSD
|
||||
|8|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian
|
||||
|9|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS
|
||||
|10|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE
|
||||
|11|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl)
|
||||
|12|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Archlinux
|
||||
|13|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora
|
||||
|14|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux
|
||||
|15|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux
|
||||
|16|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia
|
||||
|17|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux
|
||||
|18|[](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://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|[](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml)|OpenBSD
|
||||
|8|[](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml)|NetBSD
|
||||
|9|[](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml)|DragonFlyBSD
|
||||
|10|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian
|
||||
|11|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS
|
||||
|12|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE
|
||||
|13|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl)
|
||||
|14|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Archlinux
|
||||
|15|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora
|
||||
|16|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux
|
||||
|17|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux
|
||||
|18|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia
|
||||
|19|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux
|
||||
|10|[](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux
|
||||
|11|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111
|
||||
|22|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT)
|
||||
|23|[](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management)
|
||||
|
||||
|
||||
Check our [testing project](https://github.com/acmesh-official/acmetest):
|
||||
@@ -503,6 +509,12 @@ Support this project with your organization. Your logo will show up here with a
|
||||
<a href="https://opencollective.com/acmesh/organization/8/website"><img src="https://opencollective.com/acmesh/organization/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/acmesh/organization/9/website"><img src="https://opencollective.com/acmesh/organization/9/avatar.svg"></a>
|
||||
|
||||
|
||||
#### Sponsors
|
||||
|
||||
[](https://www.quantumca.com.cn/?__utm_source=acmesh-donation)
|
||||
|
||||
|
||||
# 19. License & Others
|
||||
|
||||
License is GPLv3
|
||||
|
||||
282
acme.sh
282
acme.sh
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
VER=3.0.3
|
||||
VER=3.0.5
|
||||
|
||||
PROJECT_NAME="acme.sh"
|
||||
|
||||
@@ -20,8 +20,6 @@ _SUB_FOLDER_DEPLOY="deploy"
|
||||
|
||||
_SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY"
|
||||
|
||||
CA_LETSENCRYPT_V1="https://acme-v01.api.letsencrypt.org/directory"
|
||||
|
||||
CA_LETSENCRYPT_V2="https://acme-v02.api.letsencrypt.org/directory"
|
||||
CA_LETSENCRYPT_V2_TEST="https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
|
||||
@@ -93,6 +91,7 @@ END_CERT="-----END CERTIFICATE-----"
|
||||
|
||||
CONTENT_TYPE_JSON="application/jose+json"
|
||||
RENEW_SKIP=2
|
||||
CODE_DNS_MANUAL=3
|
||||
|
||||
B64CONF_START="__ACME_BASE64__START_"
|
||||
B64CONF_END="__ACME_BASE64__END_"
|
||||
@@ -438,21 +437,13 @@ _secure_debug3() {
|
||||
}
|
||||
|
||||
_upper_case() {
|
||||
if _is_solaris; then
|
||||
tr '[:lower:]' '[:upper:]'
|
||||
else
|
||||
# shellcheck disable=SC2018,SC2019
|
||||
tr 'a-z' 'A-Z'
|
||||
fi
|
||||
# shellcheck disable=SC2018,SC2019
|
||||
tr '[a-z]' '[A-Z]'
|
||||
}
|
||||
|
||||
_lower_case() {
|
||||
if _is_solaris; then
|
||||
tr '[:upper:]' '[:lower:]'
|
||||
else
|
||||
# shellcheck disable=SC2018,SC2019
|
||||
tr 'A-Z' 'a-z'
|
||||
fi
|
||||
# shellcheck disable=SC2018,SC2019
|
||||
tr '[A-Z]' '[a-z]'
|
||||
}
|
||||
|
||||
_startswith() {
|
||||
@@ -1195,7 +1186,7 @@ _createkey() {
|
||||
_is_idn() {
|
||||
_is_idn_d="$1"
|
||||
_debug2 _is_idn_d "$_is_idn_d"
|
||||
_idn_temp=$(printf "%s" "$_is_idn_d" | tr -d '0-9' | tr -d 'a-z' | tr -d 'A-Z' | tr -d '*.,-_')
|
||||
_idn_temp=$(printf "%s" "$_is_idn_d" | tr -d '[0-9]' | tr -d '[a-z]' | tr -d '[A-Z]' | tr -d '*.,-_')
|
||||
_debug2 _idn_temp "$_idn_temp"
|
||||
[ "$_idn_temp" ]
|
||||
}
|
||||
@@ -1244,7 +1235,7 @@ _createcsr() {
|
||||
_debug2 csr "$csr"
|
||||
_debug2 csrconf "$csrconf"
|
||||
|
||||
printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]\n\n" >"$csrconf"
|
||||
printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]\nextendedKeyUsage=serverAuth,clientAuth\n" >"$csrconf"
|
||||
|
||||
if [ "$acmeValidationv1" ]; then
|
||||
domainlist="$(_idn "$domainlist")"
|
||||
@@ -2008,7 +1999,13 @@ _post() {
|
||||
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
|
||||
_sed_i "s/^ *//g" "$HTTP_HEADER"
|
||||
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 is found, can not do $httpmethod."
|
||||
@@ -2061,9 +2058,21 @@ _get() {
|
||||
fi
|
||||
_debug "_WGET" "$_WGET"
|
||||
if [ "$onlyheader" ]; then
|
||||
$_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O /dev/null "$url" 2>&1 | sed 's/^[ ]*//g'
|
||||
_wget_out = "$($_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O /dev/null "$url" 2>&1)"
|
||||
if _contains "$_WGET" " -d "; then
|
||||
# Demultiplex wget debug output
|
||||
echo "$_wget_out" >&2
|
||||
echo "$_wget_out" | sed '/^[^ ][^ ]/d; /^ *$/d; s/^ //g' -
|
||||
fi
|
||||
else
|
||||
$_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -O - "$url"
|
||||
$_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O - "$url" 2>"$HTTP_HEADER"
|
||||
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"
|
||||
fi
|
||||
ret=$?
|
||||
if [ "$ret" = "8" ]; then
|
||||
@@ -2248,12 +2257,18 @@ _setopt() {
|
||||
if [ ! -f "$__conf" ]; then
|
||||
touch "$__conf"
|
||||
fi
|
||||
if [ -n "$(tail -c 1 <"$__conf")" ]; then
|
||||
echo >>"$__conf"
|
||||
fi
|
||||
|
||||
if grep -n "^$__opt$__sep" "$__conf" >/dev/null; then
|
||||
_debug3 OK
|
||||
if _contains "$__val" "&"; then
|
||||
__val="$(echo "$__val" | sed 's/&/\\&/g')"
|
||||
fi
|
||||
if _contains "$__val" "|"; then
|
||||
__val="$(echo "$__val" | sed 's/|/\\|/g')"
|
||||
fi
|
||||
text="$(cat "$__conf")"
|
||||
printf -- "%s\n" "$text" | sed "s|^$__opt$__sep.*$|$__opt$__sep$__val$__end|" >"$__conf"
|
||||
|
||||
@@ -2261,6 +2276,9 @@ _setopt() {
|
||||
if _contains "$__val" "&"; then
|
||||
__val="$(echo "$__val" | sed 's/&/\\&/g')"
|
||||
fi
|
||||
if _contains "$__val" "|"; then
|
||||
__val="$(echo "$__val" | sed 's/|/\\|/g')"
|
||||
fi
|
||||
text="$(cat "$__conf")"
|
||||
printf -- "%s\n" "$text" | sed "s|^#$__opt$__sep.*$|$__opt$__sep$__val$__end|" >"$__conf"
|
||||
|
||||
@@ -2570,7 +2588,7 @@ __initHome() {
|
||||
_script_home="$(dirname "$_script")"
|
||||
_debug "_script_home" "$_script_home"
|
||||
if [ -d "$_script_home" ]; then
|
||||
_SCRIPT_HOME="$_script_home"
|
||||
export _SCRIPT_HOME="$_script_home"
|
||||
else
|
||||
_err "It seems the script home is not correct:$_script_home"
|
||||
fi
|
||||
@@ -2691,6 +2709,12 @@ _initAPI() {
|
||||
return 1
|
||||
}
|
||||
|
||||
_clearCA() {
|
||||
export CA_CONF=
|
||||
export ACCOUNT_KEY_PATH=
|
||||
export ACCOUNT_JSON_PATH=
|
||||
}
|
||||
|
||||
#[domain] [keylength or isEcc flag]
|
||||
_initpath() {
|
||||
domain="$1"
|
||||
@@ -4026,8 +4050,7 @@ _ns_lookup_dp() {
|
||||
_ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type"
|
||||
}
|
||||
|
||||
#domain, type
|
||||
_ns_lookup() {
|
||||
_ns_select_doh() {
|
||||
if [ -z "$DOH_USE" ]; then
|
||||
_debug "Detect dns server first."
|
||||
if _ns_is_available_cf; then
|
||||
@@ -4046,7 +4069,11 @@ _ns_lookup() {
|
||||
_err "No doh"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
#domain, type
|
||||
_ns_lookup() {
|
||||
_ns_select_doh
|
||||
if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then
|
||||
_ns_lookup_cf "$@"
|
||||
elif [ "$DOH_USE" = "$DOH_GOOGLE" ]; then
|
||||
@@ -4069,6 +4096,7 @@ __check_txt() {
|
||||
_debug "_c_txtdomain" "$_c_txtdomain"
|
||||
_debug "_c_aliasdomain" "$_c_aliasdomain"
|
||||
_debug "_c_txt" "$_c_txt"
|
||||
_ns_select_doh
|
||||
_answers="$(_ns_lookup "$_c_aliasdomain" TXT)"
|
||||
_contains "$_answers" "$_c_txt"
|
||||
|
||||
@@ -4198,7 +4226,7 @@ _match_issuer() {
|
||||
_isIPv4() {
|
||||
for seg in $(echo "$1" | tr '.' ' '); do
|
||||
_debug2 seg "$seg"
|
||||
if [ "$(echo "$seg" | tr -d [0-9])" ]; then
|
||||
if [ "$(echo "$seg" | tr -d '[0-9]')" ]; then
|
||||
#not all number
|
||||
return 1
|
||||
fi
|
||||
@@ -4399,20 +4427,43 @@ issue() {
|
||||
_debug "_saved_account_key_hash is not changed, skip register account."
|
||||
fi
|
||||
|
||||
export Le_Next_Domain_Key="$CERT_KEY_PATH.next"
|
||||
if [ -f "$CSR_PATH" ] && [ ! -f "$CERT_KEY_PATH" ]; then
|
||||
_info "Signing from existing CSR."
|
||||
else
|
||||
# When renewing from an old version, the empty Le_Keylength means 2048.
|
||||
# Note, do not use DEFAULT_DOMAIN_KEY_LENGTH as that value may change over
|
||||
# time but an empty value implies 2048 specifically.
|
||||
_key=$(_readdomainconf Le_Keylength)
|
||||
if [ -z "$_key" ]; then
|
||||
_key=2048
|
||||
fi
|
||||
_debug "Read key length:$_key"
|
||||
if [ ! -f "$CERT_KEY_PATH" ] || [ "$_key_length" != "$_key" ] || [ "$Le_ForceNewDomainKey" = "1" ]; then
|
||||
if ! createDomainKey "$_main_domain" "$_key_length"; then
|
||||
_err "Create domain key error."
|
||||
_clearup
|
||||
_on_issue_err "$_post_hook"
|
||||
if [ "$Le_ForceNewDomainKey" = "1" ] && [ -f "$Le_Next_Domain_Key" ]; then
|
||||
_info "Using pre generated key: $Le_Next_Domain_Key"
|
||||
cat "$Le_Next_Domain_Key" >"$CERT_KEY_PATH"
|
||||
echo "" >"$Le_Next_Domain_Key"
|
||||
else
|
||||
if ! createDomainKey "$_main_domain" "$_key_length"; then
|
||||
_err "Create domain key error."
|
||||
_clearup
|
||||
_on_issue_err "$_post_hook"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ "$Le_ForceNewDomainKey" ]; then
|
||||
_info "Generate next pre-generate key."
|
||||
if [ ! -e "$Le_Next_Domain_Key" ]; then
|
||||
touch "$Le_Next_Domain_Key"
|
||||
chmod 600 "$Le_Next_Domain_Key"
|
||||
fi
|
||||
if ! _createkey "$_key_length" "$Le_Next_Domain_Key"; then
|
||||
_err "Can not pre generate domain key"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! _createcsr "$_main_domain" "$_alt_domains" "$CERT_KEY_PATH" "$CSR_PATH" "$DOMAIN_SSL_CONF"; then
|
||||
_err "Create CSR error."
|
||||
_clearup
|
||||
@@ -4752,7 +4803,9 @@ $_authorizations_map"
|
||||
_err "Please add the TXT records to the domains, and re-run with --renew."
|
||||
_on_issue_err "$_post_hook"
|
||||
_clearup
|
||||
return 1
|
||||
# If asked to be in manual DNS mode, flag this exit with a separate
|
||||
# error so it can be distinguished from other failures.
|
||||
return $CODE_DNS_MANUAL
|
||||
fi
|
||||
|
||||
fi
|
||||
@@ -4861,7 +4914,9 @@ $_authorizations_map"
|
||||
_on_issue_err "$_post_hook" "$vlist"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! chmod a+r "$wellknown_path/$token"; then
|
||||
_debug "chmod failed, but we just continue."
|
||||
fi
|
||||
if [ ! "$usingApache" ]; then
|
||||
if webroot_owner=$(_stat "$_currentRoot"); then
|
||||
_debug "Changing owner/group of .well-known to $webroot_owner"
|
||||
@@ -5144,6 +5199,9 @@ $_authorizations_map"
|
||||
|
||||
[ -f "$CA_CERT_PATH" ] && _info "The intermediate CA cert is in: $(__green "$CA_CERT_PATH")"
|
||||
[ -f "$CERT_FULLCHAIN_PATH" ] && _info "And the full chain certs is there: $(__green "$CERT_FULLCHAIN_PATH")"
|
||||
if [ "$Le_ForceNewDomainKey" ] && [ -e "$Le_Next_Domain_Key" ]; then
|
||||
_info "Your pre-generated next key for future cert key change is in: $(__green "$Le_Next_Domain_Key")"
|
||||
fi
|
||||
|
||||
Le_CertCreateTime=$(_time)
|
||||
_savedomainconf "Le_CertCreateTime" "$Le_CertCreateTime"
|
||||
@@ -5195,11 +5253,25 @@ $_authorizations_map"
|
||||
_info "The domain is set to be valid to: $_valid_to"
|
||||
_info "It can not be renewed automatically"
|
||||
_info "See: $_VALIDITY_WIKI"
|
||||
else
|
||||
_now=$(_time)
|
||||
_debug2 "_now" "$_now"
|
||||
_lifetime=$(_math $Le_NextRenewTime - $_now)
|
||||
_debug2 "_lifetime" "$_lifetime"
|
||||
if [ $_lifetime -gt 86400 ]; then
|
||||
#if lifetime is logner than one day, it will renew one day before
|
||||
Le_NextRenewTime=$(_math $Le_NextRenewTime - 86400)
|
||||
Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime")
|
||||
else
|
||||
#if lifetime is less than 24 hours, it will renew one hour before
|
||||
Le_NextRenewTime=$(_math $Le_NextRenewTime - 3600)
|
||||
Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime")
|
||||
fi
|
||||
fi
|
||||
else
|
||||
Le_NextRenewTime=$(_math "$Le_CertCreateTime" + "$Le_RenewalDays" \* 24 \* 60 \* 60)
|
||||
Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime")
|
||||
Le_NextRenewTime=$(_math "$Le_NextRenewTime" - 86400)
|
||||
Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime")
|
||||
fi
|
||||
_savedomainconf "Le_NextRenewTimeStr" "$Le_NextRenewTimeStr"
|
||||
_savedomainconf "Le_NextRenewTime" "$Le_NextRenewTime"
|
||||
@@ -5237,18 +5309,20 @@ _split_cert_chain() {
|
||||
fi
|
||||
}
|
||||
|
||||
#domain [isEcc]
|
||||
#domain [isEcc] [server]
|
||||
renew() {
|
||||
Le_Domain="$1"
|
||||
if [ -z "$Le_Domain" ]; then
|
||||
_usage "Usage: $PROJECT_ENTRY --renew --domain <domain.tld> [--ecc]"
|
||||
_usage "Usage: $PROJECT_ENTRY --renew --domain <domain.tld> [--ecc] [--server server]"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_isEcc="$2"
|
||||
#the server specified from commandline
|
||||
_acme_server_back="$ACME_DIRECTORY"
|
||||
_renewServer="$3"
|
||||
_debug "_renewServer" "$_renewServer"
|
||||
|
||||
_initpath "$Le_Domain" "$_isEcc"
|
||||
|
||||
_set_level=${NOTIFY_LEVEL:-$NOTIFY_LEVEL_DEFAULT}
|
||||
_info "$(__green "Renew: '$Le_Domain'")"
|
||||
if [ ! -f "$DOMAIN_CONF" ]; then
|
||||
@@ -5262,17 +5336,6 @@ renew() {
|
||||
|
||||
. "$DOMAIN_CONF"
|
||||
_debug Le_API "$Le_API"
|
||||
if [ -z "$Le_API" ] || [ "$CA_LETSENCRYPT_V1" = "$Le_API" ]; then
|
||||
#if this is from an old version, Le_API is empty,
|
||||
#so, we force to use letsencrypt server
|
||||
Le_API="$CA_LETSENCRYPT_V2"
|
||||
fi
|
||||
|
||||
if [ "$_acme_server_back" ]; then
|
||||
export ACME_DIRECTORY="$_acme_server_back"
|
||||
else
|
||||
export ACME_DIRECTORY="$Le_API"
|
||||
fi
|
||||
|
||||
case "$Le_API" in
|
||||
"$CA_LETSENCRYPT_V2_TEST")
|
||||
@@ -5289,17 +5352,18 @@ renew() {
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$Le_API" ] && [ "$ACME_DIRECTORY" ]; then
|
||||
if [ "$Le_API" != "$ACME_DIRECTORY" ]; then
|
||||
_clearAPI
|
||||
fi
|
||||
#reload ca configs
|
||||
ACCOUNT_KEY_PATH=""
|
||||
ACCOUNT_JSON_PATH=""
|
||||
CA_CONF=""
|
||||
_debug2 "initpath again."
|
||||
_initpath "$Le_Domain" "$_isEcc"
|
||||
if [ "$_server" ]; then
|
||||
Le_API="$_server"
|
||||
fi
|
||||
_info "Renew to Le_API=$Le_API"
|
||||
|
||||
_clearAPI
|
||||
_clearCA
|
||||
export ACME_DIRECTORY="$Le_API"
|
||||
|
||||
#reload ca configs
|
||||
_debug2 "initpath again."
|
||||
_initpath "$Le_Domain" "$_isEcc"
|
||||
|
||||
if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then
|
||||
_info "Skip, Next renewal time is: $(__green "$Le_NextRenewTimeStr")"
|
||||
@@ -5323,7 +5387,10 @@ renew() {
|
||||
Le_PostHook="$(_readdomainconf Le_PostHook)"
|
||||
Le_RenewHook="$(_readdomainconf Le_RenewHook)"
|
||||
Le_Preferred_Chain="$(_readdomainconf Le_Preferred_Chain)"
|
||||
#when renew from an old version, the empty Le_Keylength means 2048
|
||||
# When renewing from an old version, the empty Le_Keylength means 2048.
|
||||
# Note, do not use DEFAULT_DOMAIN_KEY_LENGTH as that value may change over
|
||||
# time but an empty value implies 2048 specifically.
|
||||
Le_Keylength="$(_readdomainconf Le_Keylength)"
|
||||
if [ -z "$Le_Keylength" ]; then
|
||||
Le_Keylength=2048
|
||||
fi
|
||||
@@ -5354,11 +5421,16 @@ renew() {
|
||||
return "$res"
|
||||
}
|
||||
|
||||
#renewAll [stopRenewOnError]
|
||||
#renewAll [stopRenewOnError] [server]
|
||||
renewAll() {
|
||||
_initpath
|
||||
_clearCA
|
||||
_stopRenewOnError="$1"
|
||||
_debug "_stopRenewOnError" "$_stopRenewOnError"
|
||||
|
||||
_server="$2"
|
||||
_debug "_server" "$_server"
|
||||
|
||||
_ret="0"
|
||||
_success_msg=""
|
||||
_error_msg=""
|
||||
@@ -5381,7 +5453,7 @@ renewAll() {
|
||||
_isEcc=$(echo "$d" | cut -d "$ECC_SEP" -f 2)
|
||||
d=$(echo "$d" | cut -d "$ECC_SEP" -f 1)
|
||||
fi
|
||||
renew "$d" "$_isEcc"
|
||||
renew "$d" "$_isEcc" "$_server"
|
||||
)
|
||||
rc="$?"
|
||||
_debug "Return code: $rc"
|
||||
@@ -5704,7 +5776,8 @@ installcert() {
|
||||
_savedomainconf "Le_RealKeyPath" "$_real_key"
|
||||
_savedomainconf "Le_ReloadCmd" "$_reload_cmd" "base64"
|
||||
_savedomainconf "Le_RealFullChainPath" "$_real_fullchain"
|
||||
|
||||
export Le_ForceNewDomainKey="$(_readdomainconf Le_ForceNewDomainKey)"
|
||||
export Le_Next_Domain_Key
|
||||
_installcert "$_main_domain" "$_real_cert" "$_real_key" "$_real_ca" "$_real_fullchain" "$_reload_cmd"
|
||||
}
|
||||
|
||||
@@ -5742,7 +5815,9 @@ _installcert() {
|
||||
if [ -f "$_real_cert" ] && [ ! "$_ACME_IS_RENEW" ]; then
|
||||
cp "$_real_cert" "$_backup_path/cert.bak"
|
||||
fi
|
||||
cat "$CERT_PATH" >"$_real_cert" || return 1
|
||||
if [ "$CERT_PATH" != "$_real_cert" ]; then
|
||||
cat "$CERT_PATH" >"$_real_cert" || return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$_real_ca" ]; then
|
||||
@@ -5754,7 +5829,9 @@ _installcert() {
|
||||
if [ -f "$_real_ca" ] && [ ! "$_ACME_IS_RENEW" ]; then
|
||||
cp "$_real_ca" "$_backup_path/ca.bak"
|
||||
fi
|
||||
cat "$CA_CERT_PATH" >"$_real_ca" || return 1
|
||||
if [ "$CA_CERT_PATH" != "$_real_ca" ]; then
|
||||
cat "$CA_CERT_PATH" >"$_real_ca" || return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -5763,12 +5840,14 @@ _installcert() {
|
||||
if [ -f "$_real_key" ] && [ ! "$_ACME_IS_RENEW" ]; then
|
||||
cp "$_real_key" "$_backup_path/key.bak"
|
||||
fi
|
||||
if [ -f "$_real_key" ]; then
|
||||
cat "$CERT_KEY_PATH" >"$_real_key" || return 1
|
||||
else
|
||||
touch "$_real_key" || return 1
|
||||
chmod 600 "$_real_key"
|
||||
cat "$CERT_KEY_PATH" >"$_real_key" || return 1
|
||||
if [ "$CERT_KEY_PATH" != "$_real_key" ]; then
|
||||
if [ -f "$_real_key" ]; then
|
||||
cat "$CERT_KEY_PATH" >"$_real_key" || return 1
|
||||
else
|
||||
touch "$_real_key" || return 1
|
||||
chmod 600 "$_real_key"
|
||||
cat "$CERT_KEY_PATH" >"$_real_key" || return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -5777,7 +5856,9 @@ _installcert() {
|
||||
if [ -f "$_real_fullchain" ] && [ ! "$_ACME_IS_RENEW" ]; then
|
||||
cp "$_real_fullchain" "$_backup_path/fullchain.bak"
|
||||
fi
|
||||
cat "$CERT_FULLCHAIN_PATH" >"$_real_fullchain" || return 1
|
||||
if [ "$_real_fullchain" != "$CERT_FULLCHAIN_PATH" ]; then
|
||||
cat "$CERT_FULLCHAIN_PATH" >"$_real_fullchain" || return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$_reload_cmd" ]; then
|
||||
@@ -5788,6 +5869,8 @@ _installcert() {
|
||||
export CA_CERT_PATH
|
||||
export CERT_FULLCHAIN_PATH
|
||||
export Le_Domain="$_main_domain"
|
||||
export Le_ForceNewDomainKey
|
||||
export Le_Next_Domain_Key
|
||||
cd "$DOMAIN_PATH" && eval "$_reload_cmd"
|
||||
); then
|
||||
_info "$(__green "Reload success")"
|
||||
@@ -6025,6 +6108,8 @@ revoke() {
|
||||
if [ -z "$response" ]; then
|
||||
_info "Revoke success."
|
||||
rm -f "$CERT_PATH"
|
||||
cat "$CERT_KEY_PATH" >"$CERT_KEY_PATH.revoked"
|
||||
cat "$CSR_PATH" >"$CSR_PATH.revoked"
|
||||
return 0
|
||||
else
|
||||
_err "Revoke error by domain key."
|
||||
@@ -6041,6 +6126,8 @@ revoke() {
|
||||
if [ -z "$response" ]; then
|
||||
_info "Revoke success."
|
||||
rm -f "$CERT_PATH"
|
||||
cat "$CERT_KEY_PATH" >"$CERT_KEY_PATH.revoked"
|
||||
cat "$CSR_PATH" >"$CSR_PATH.revoked"
|
||||
return 0
|
||||
else
|
||||
_err "Revoke error."
|
||||
@@ -6526,7 +6613,7 @@ install() {
|
||||
if [ "$_accountemail" ]; then
|
||||
_saveaccountconf "ACCOUNT_EMAIL" "$_accountemail"
|
||||
fi
|
||||
|
||||
_saveaccountconf "UPGRADE_HASH" "$(_getUpgradeHash)"
|
||||
_info OK
|
||||
}
|
||||
|
||||
@@ -6757,37 +6844,37 @@ Commands:
|
||||
Parameters:
|
||||
-d, --domain <domain.tld> Specifies a domain, used to issue, renew or revoke etc.
|
||||
--challenge-alias <domain.tld> The challenge domain alias for DNS alias mode.
|
||||
See: $_DNS_ALIAS_WIKI
|
||||
See: $_DNS_ALIAS_WIKI
|
||||
|
||||
--domain-alias <domain.tld> The domain alias for DNS alias mode.
|
||||
See: $_DNS_ALIAS_WIKI
|
||||
See: $_DNS_ALIAS_WIKI
|
||||
|
||||
--preferred-chain <chain> If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name.
|
||||
If no match, the default offered chain will be used. (default: empty)
|
||||
See: $_PREFERRED_CHAIN_WIKI
|
||||
If no match, the default offered chain will be used. (default: empty)
|
||||
See: $_PREFERRED_CHAIN_WIKI
|
||||
|
||||
--valid-to <date-time> Request the NotAfter field of the cert.
|
||||
See: $_VALIDITY_WIKI
|
||||
See: $_VALIDITY_WIKI
|
||||
--valid-from <date-time> Request the NotBefore field of the cert.
|
||||
See: $_VALIDITY_WIKI
|
||||
See: $_VALIDITY_WIKI
|
||||
|
||||
-f, --force Force install, force cert renewal or override sudo restrictions.
|
||||
--staging, --test Use staging server, for testing.
|
||||
--debug [0|1|2|3] Output debug info. Defaults to 1 if argument is omitted.
|
||||
--output-insecure Output all the sensitive messages.
|
||||
By default all the credentials/sensitive messages are hidden from the output/debug/log for security.
|
||||
By default all the credentials/sensitive messages are hidden from the output/debug/log for security.
|
||||
-w, --webroot <directory> Specifies the web root folder for web root mode.
|
||||
--standalone Use standalone mode.
|
||||
--alpn Use standalone alpn mode.
|
||||
--stateless Use stateless mode.
|
||||
See: $_STATELESS_WIKI
|
||||
See: $_STATELESS_WIKI
|
||||
|
||||
--apache Use apache mode.
|
||||
--dns [dns_hook] Use dns manual mode or dns api. Defaults to manual mode when argument is omitted.
|
||||
See: $_DNS_API_WIKI
|
||||
See: $_DNS_API_WIKI
|
||||
|
||||
--dnssleep <seconds> The time in seconds to wait for all the txt records to propagate in dns api mode.
|
||||
It's not necessary to use this by default, $PROJECT_NAME polls dns status by DOH automatically.
|
||||
It's not necessary to use this by default, $PROJECT_NAME polls dns status by DOH automatically.
|
||||
-k, --keylength <bits> Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521.
|
||||
-ak, --accountkeylength <bits> Specifies the account key length: 2048, 3072, 4096
|
||||
--log [file] Specifies the log file. Defaults to \"$DEFAULT_LOG_FILE\" if argument is omitted.
|
||||
@@ -6806,7 +6893,7 @@ Parameters:
|
||||
--reloadcmd <command> Command to execute after issue/renew to reload the server.
|
||||
|
||||
--server <server_uri> ACME Directory Resource URI. (default: $DEFAULT_CA)
|
||||
See: $_SERVER_WIKI
|
||||
See: $_SERVER_WIKI
|
||||
|
||||
--accountconf <file> Specifies a customized account config file.
|
||||
--home <directory> Specifies the home dir for $PROJECT_NAME.
|
||||
@@ -6825,7 +6912,7 @@ Parameters:
|
||||
--ca-bundle <file> Specifies the path to the CA certificate bundle to verify api server's certificate.
|
||||
--ca-path <directory> Specifies directory containing CA certificates in PEM format, used by wget or curl.
|
||||
--no-cron Only valid for '--install' command, which means: do not install the default cron job.
|
||||
In this case, the certs will not be renewed automatically.
|
||||
In this case, the certs will not be renewed automatically.
|
||||
--no-profile Only valid for '--install' command, which means: do not install aliases to user profile.
|
||||
--no-color Do not output color text.
|
||||
--force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails.
|
||||
@@ -6843,20 +6930,20 @@ Parameters:
|
||||
--openssl-bin <file> Specifies a custom openssl bin location.
|
||||
--use-wget Force to use wget, if you have both curl and wget installed.
|
||||
--yes-I-know-dns-manual-mode-enough-go-ahead-please Force use of dns manual mode.
|
||||
See: $_DNS_MANUAL_WIKI
|
||||
See: $_DNS_MANUAL_WIKI
|
||||
|
||||
-b, --branch <branch> Only valid for '--upgrade' command, specifies the branch name to upgrade to.
|
||||
--notify-level <0|1|2|3> Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT.
|
||||
0: disabled, no notification will be sent.
|
||||
1: send notifications only when there is an error.
|
||||
2: send notifications when a cert is successfully renewed, or there is an error.
|
||||
3: send notifications when a cert is skipped, renewed, or error.
|
||||
0: disabled, no notification will be sent.
|
||||
1: send notifications only when there is an error.
|
||||
2: send notifications when a cert is successfully renewed, or there is an error.
|
||||
3: send notifications when a cert is skipped, renewed, or error.
|
||||
--notify-mode <0|1> Set notification mode. Default value is $NOTIFY_MODE_DEFAULT.
|
||||
0: Bulk mode. Send all the domain's notifications in one message(mail).
|
||||
1: Cert mode. Send a message for every single cert.
|
||||
0: Bulk mode. Send all the domain's notifications in one message(mail).
|
||||
1: Cert mode. Send a message for every single cert.
|
||||
--notify-hook <hookname> Set the notify hook
|
||||
--revoke-reason <0-10> The reason for revocation, can be used in conjunction with the '--revoke' command.
|
||||
See: $_REVOKE_WIKI
|
||||
See: $_REVOKE_WIKI
|
||||
|
||||
--password <password> Add a password to exported pfx file. Use with --to-pkcs12.
|
||||
|
||||
@@ -6890,8 +6977,6 @@ installOnline() {
|
||||
chmod +x $PROJECT_ENTRY
|
||||
if ./$PROJECT_ENTRY --install "$@"; then
|
||||
_info "Install success!"
|
||||
_initpath
|
||||
_saveaccountconf "UPGRADE_HASH" "$(_getUpgradeHash)"
|
||||
fi
|
||||
|
||||
cd ..
|
||||
@@ -7411,17 +7496,17 @@ _process() {
|
||||
shift
|
||||
;;
|
||||
--home)
|
||||
LE_WORKING_DIR="$2"
|
||||
export LE_WORKING_DIR="$2"
|
||||
shift
|
||||
;;
|
||||
--cert-home | --certhome)
|
||||
_certhome="$2"
|
||||
CERT_HOME="$_certhome"
|
||||
export CERT_HOME="$_certhome"
|
||||
shift
|
||||
;;
|
||||
--config-home)
|
||||
_confighome="$2"
|
||||
LE_CONFIG_HOME="$_confighome"
|
||||
export LE_CONFIG_HOME="$_confighome"
|
||||
shift
|
||||
;;
|
||||
--useragent)
|
||||
@@ -7654,6 +7739,7 @@ _process() {
|
||||
|
||||
if [ "$_server" ]; then
|
||||
_selectServer "$_server" "${_ecc:-$_keylength}"
|
||||
_server="$ACME_DIRECTORY"
|
||||
fi
|
||||
|
||||
if [ "${_CMD}" != "install" ]; then
|
||||
@@ -7728,10 +7814,10 @@ _process() {
|
||||
installcert "$_domain" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_ecc"
|
||||
;;
|
||||
renew)
|
||||
renew "$_domain" "$_ecc"
|
||||
renew "$_domain" "$_ecc" "$_server"
|
||||
;;
|
||||
renewAll)
|
||||
renewAll "$_stopRenewOnError"
|
||||
renewAll "$_stopRenewOnError" "$_server"
|
||||
;;
|
||||
revoke)
|
||||
revoke "$_domain" "$_ecc" "$_revoke_reason"
|
||||
|
||||
@@ -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\"")"
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
132
deploy/proxmoxve.sh
Normal file
132
deploy/proxmoxve.sh
Normal file
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Deploy certificates to a proxmox virtual environment node using the API.
|
||||
#
|
||||
# Environment variables that can be set are:
|
||||
# `DEPLOY_PROXMOXVE_SERVER`: The hostname of the proxmox ve node. Defaults to
|
||||
# _cdomain.
|
||||
# `DEPLOY_PROXMOXVE_SERVER_PORT`: The port number the management interface is on.
|
||||
# Defaults to 8006.
|
||||
# `DEPLOY_PROXMOXVE_NODE_NAME`: The name of the node we'll be connecting to.
|
||||
# Defaults to the host portion of the server
|
||||
# domain name.
|
||||
# `DEPLOY_PROXMOXVE_USER`: The user we'll connect as. Defaults to root.
|
||||
# `DEPLOY_PROXMOXVE_USER_REALM`: The authentication realm the user authenticates
|
||||
# with. Defaults to pam.
|
||||
# `DEPLOY_PROXMOXVE_API_TOKEN_NAME`: The name of the API token created for the
|
||||
# user account. Defaults to acme.
|
||||
# `DEPLOY_PROXMOXVE_API_TOKEN_KEY`: The API token. Required.
|
||||
|
||||
proxmoxve_deploy() {
|
||||
_cdomain="$1"
|
||||
_ckey="$2"
|
||||
_ccert="$3"
|
||||
_cca="$4"
|
||||
_cfullchain="$5"
|
||||
|
||||
_debug _cdomain "$_cdomain"
|
||||
_debug2 _ckey "$_ckey"
|
||||
_debug _ccert "$_ccert"
|
||||
_debug _cca "$_cca"
|
||||
_debug _cfullchain "$_cfullchain"
|
||||
|
||||
# "Sane" defaults.
|
||||
_getdeployconf DEPLOY_PROXMOXVE_SERVER
|
||||
if [ -z "$DEPLOY_PROXMOXVE_SERVER" ]; then
|
||||
_target_hostname="$_cdomain"
|
||||
else
|
||||
_target_hostname="$DEPLOY_PROXMOXVE_SERVER"
|
||||
_savedeployconf DEPLOY_PROXMOXVE_SERVER "$DEPLOY_PROXMOXVE_SERVER"
|
||||
fi
|
||||
_debug2 DEPLOY_PROXMOXVE_SERVER "$_target_hostname"
|
||||
|
||||
_getdeployconf DEPLOY_PROXMOXVE_SERVER_PORT
|
||||
if [ -z "$DEPLOY_PROXMOXVE_SERVER_PORT" ]; then
|
||||
_target_port="8006"
|
||||
else
|
||||
_target_port="$DEPLOY_PROXMOXVE_SERVER_PORT"
|
||||
_savedeployconf DEPLOY_PROXMOXVE_SERVER_PORT "$DEPLOY_PROXMOXVE_SERVER_PORT"
|
||||
fi
|
||||
_debug2 DEPLOY_PROXMOXVE_SERVER_PORT "$_target_port"
|
||||
|
||||
_getdeployconf DEPLOY_PROXMOXVE_NODE_NAME
|
||||
if [ -z "$DEPLOY_PROXMOXVE_NODE_NAME" ]; then
|
||||
_node_name=$(echo "$_target_hostname" | cut -d. -f1)
|
||||
else
|
||||
_node_name="$DEPLOY_PROXMOXVE_NODE_NAME"
|
||||
_savedeployconf DEPLOY_PROXMOXVE_NODE_NAME "$DEPLOY_PROXMOXVE_NODE_NAME"
|
||||
fi
|
||||
_debug2 DEPLOY_PROXMOXVE_NODE_NAME "$_node_name"
|
||||
|
||||
# Complete URL.
|
||||
_target_url="https://${_target_hostname}:${_target_port}/api2/json/nodes/${_node_name}/certificates/custom"
|
||||
_debug TARGET_URL "$_target_url"
|
||||
|
||||
# More "sane" defaults.
|
||||
_getdeployconf DEPLOY_PROXMOXVE_USER
|
||||
if [ -z "$DEPLOY_PROXMOXVE_USER" ]; then
|
||||
_proxmoxve_user="root"
|
||||
else
|
||||
_proxmoxve_user="$DEPLOY_PROXMOXVE_USER"
|
||||
_savedeployconf DEPLOY_PROXMOXVE_USER "$DEPLOY_PROXMOXVE_USER"
|
||||
fi
|
||||
_debug2 DEPLOY_PROXMOXVE_USER "$_proxmoxve_user"
|
||||
|
||||
_getdeployconf DEPLOY_PROXMOXVE_USER_REALM
|
||||
if [ -z "$DEPLOY_PROXMOXVE_USER_REALM" ]; then
|
||||
_proxmoxve_user_realm="pam"
|
||||
else
|
||||
_proxmoxve_user_realm="$DEPLOY_PROXMOXVE_USER_REALM"
|
||||
_savedeployconf DEPLOY_PROXMOXVE_USER_REALM "$DEPLOY_PROXMOXVE_USER_REALM"
|
||||
fi
|
||||
_debug2 DEPLOY_PROXMOXVE_USER_REALM "$_proxmoxve_user_realm"
|
||||
|
||||
_getdeployconf DEPLOY_PROXMOXVE_API_TOKEN_NAME
|
||||
if [ -z "$DEPLOY_PROXMOXVE_API_TOKEN_NAME" ]; then
|
||||
_proxmoxve_api_token_name="acme"
|
||||
else
|
||||
_proxmoxve_api_token_name="$DEPLOY_PROXMOXVE_API_TOKEN_NAME"
|
||||
_savedeployconf DEPLOY_PROXMOXVE_API_TOKEN_NAME "$DEPLOY_PROXMOXVE_API_TOKEN_NAME"
|
||||
fi
|
||||
_debug2 DEPLOY_PROXMOXVE_API_TOKEN_NAME "$_proxmoxve_api_token_name"
|
||||
|
||||
# This is required.
|
||||
_getdeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY
|
||||
if [ -z "$DEPLOY_PROXMOXVE_API_TOKEN_KEY" ]; then
|
||||
_err "API key not provided."
|
||||
return 1
|
||||
else
|
||||
_proxmoxve_api_token_key="$DEPLOY_PROXMOXVE_API_TOKEN_KEY"
|
||||
_savedeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY "$DEPLOY_PROXMOXVE_API_TOKEN_KEY"
|
||||
fi
|
||||
_debug2 DEPLOY_PROXMOXVE_API_TOKEN_KEY _proxmoxve_api_token_key
|
||||
|
||||
# PVE API Token header value. Used in "Authorization: PVEAPIToken".
|
||||
_proxmoxve_header_api_token="${_proxmoxve_user}@${_proxmoxve_user_realm}!${_proxmoxve_api_token_name}=${_proxmoxve_api_token_key}"
|
||||
_debug2 "Auth Header" _proxmoxve_header_api_token
|
||||
|
||||
# Ugly. I hate putting heredocs inside functions because heredocs don't
|
||||
# account for whitespace correctly but it _does_ work and is several times
|
||||
# cleaner than anything else I had here.
|
||||
#
|
||||
# This dumps the json payload to a variable that should be passable to the
|
||||
# _psot function.
|
||||
_json_payload=$(
|
||||
cat <<HEREDOC
|
||||
{
|
||||
"certificates": "$(tr '\n' ':' <"$_cfullchain" | sed 's/:/\\n/g')",
|
||||
"key": "$(tr '\n' ':' <"$_ckey" | sed 's/:/\\n/g')",
|
||||
"node":"$_node_name",
|
||||
"restart":"1",
|
||||
"force":"1"
|
||||
}
|
||||
HEREDOC
|
||||
)
|
||||
_debug2 Payload "$_json_payload"
|
||||
|
||||
# Push certificates to server.
|
||||
export _HTTPS_INSECURE=1
|
||||
export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}"
|
||||
_post "$_json_payload" "$_target_url" "" POST "application/json"
|
||||
|
||||
}
|
||||
@@ -53,7 +53,7 @@ qiniu_deploy() {
|
||||
sslcert_access_token="$(_make_access_token "$sslcert_path")"
|
||||
_debug sslcert_access_token "$sslcert_access_token"
|
||||
export _H1="Authorization: QBox $sslcert_access_token"
|
||||
sslcert_response=$(_post "$sslcerl_body" "$QINIU_API_BASE$sslcert_path" 0 "POST" "application/json" | _dbase64 "multiline")
|
||||
sslcert_response=$(_post "$sslcerl_body" "$QINIU_API_BASE$sslcert_path" 0 "POST" "application/json" | _dbase64)
|
||||
|
||||
if ! _contains "$sslcert_response" "certID"; then
|
||||
_err "Error in creating certificate:"
|
||||
@@ -75,7 +75,7 @@ qiniu_deploy() {
|
||||
update_access_token="$(_make_access_token "$update_path")"
|
||||
_debug update_access_token "$update_access_token"
|
||||
export _H1="Authorization: QBox $update_access_token"
|
||||
update_response=$(_post "$update_body" "$QINIU_API_BASE$update_path" 0 "PUT" "application/json" | _dbase64 "multiline")
|
||||
update_response=$(_post "$update_body" "$QINIU_API_BASE$update_path" 0 "PUT" "application/json" | _dbase64)
|
||||
|
||||
if _contains "$update_response" "error"; then
|
||||
_err "Error in updating domain $domain httpsconf:"
|
||||
|
||||
@@ -108,7 +108,7 @@ synology_dsm_deploy() {
|
||||
_debug3 H1 "${_H1}"
|
||||
fi
|
||||
|
||||
response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$otp_code" "$_base_url/webapi/auth.cgi?enable_syno_token=yes")
|
||||
response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$otp_code&device_name=certrenewal&device_id=$SYNO_DID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes")
|
||||
token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p')
|
||||
_debug3 response "$response"
|
||||
_debug token "$token"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
## Acmeproxy DNS provider to be used with acmeproxy (http://github.com/mdbraber/acmeproxy)
|
||||
## Acmeproxy DNS provider to be used with acmeproxy (https://github.com/mdbraber/acmeproxy)
|
||||
## API integration by Maarten den Braber
|
||||
##
|
||||
## Report any bugs via https://github.com/mdbraber/acme.sh
|
||||
|
||||
@@ -152,34 +152,23 @@ dns_aws_rm() {
|
||||
|
||||
_get_root() {
|
||||
domain=$1
|
||||
i=2
|
||||
i=1
|
||||
p=1
|
||||
|
||||
if aws_rest GET "2013-04-01/hostedzone"; then
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
_debug2 "Checking domain: $h"
|
||||
if [ -z "$h" ]; then
|
||||
if _contains "$response" "<IsTruncated>true</IsTruncated>" && _contains "$response" "<NextMarker>"; then
|
||||
_debug "IsTruncated"
|
||||
_nextMarker="$(echo "$response" | _egrep_o "<NextMarker>.*</NextMarker>" | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
_debug "NextMarker" "$_nextMarker"
|
||||
if aws_rest GET "2013-04-01/hostedzone" "marker=$_nextMarker"; then
|
||||
_debug "Truncated request OK"
|
||||
i=2
|
||||
p=1
|
||||
continue
|
||||
else
|
||||
_err "Truncated request error."
|
||||
fi
|
||||
fi
|
||||
#not valid
|
||||
_err "Invalid domain"
|
||||
return 1
|
||||
fi
|
||||
# iterate over names (a.b.c.d -> b.c.d -> c.d -> d)
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
_debug "Checking domain: $h"
|
||||
if [ -z "$h" ]; then
|
||||
_error "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# iterate over paginated result for list_hosted_zones
|
||||
aws_rest GET "2013-04-01/hostedzone"
|
||||
while true; do
|
||||
if _contains "$response" "<Name>$h.</Name>"; then
|
||||
hostedzone="$(echo "$response" | sed 's/<HostedZone>/#&/g' | tr '#' '\n' | _egrep_o "<HostedZone><Id>[^<]*<.Id><Name>$h.<.Name>.*<PrivateZone>false<.PrivateZone>.*<.HostedZone>")"
|
||||
hostedzone="$(echo "$response" | tr -d '\n' | sed 's/<HostedZone>/#&/g' | tr '#' '\n' | _egrep_o "<HostedZone><Id>[^<]*<.Id><Name>$h.<.Name>.*<PrivateZone>false<.PrivateZone>.*<.HostedZone>")"
|
||||
_debug hostedzone "$hostedzone"
|
||||
if [ "$hostedzone" ]; then
|
||||
_domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "<Id>.*<.Id>" | head -n 1 | _egrep_o ">.*<" | tr -d "<>")
|
||||
@@ -192,10 +181,19 @@ _get_root() {
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
p=$i
|
||||
i=$(_math "$i" + 1)
|
||||
if _contains "$response" "<IsTruncated>true</IsTruncated>" && _contains "$response" "<NextMarker>"; then
|
||||
_debug "IsTruncated"
|
||||
_nextMarker="$(echo "$response" | _egrep_o "<NextMarker>.*</NextMarker>" | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
_debug "NextMarker" "$_nextMarker"
|
||||
else
|
||||
break
|
||||
fi
|
||||
_debug "Checking domain: $h - Next Page "
|
||||
aws_rest GET "2013-04-01/hostedzone" "marker=$_nextMarker"
|
||||
done
|
||||
fi
|
||||
p=$i
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
248
dnsapi/dns_bunny.sh
Normal file
248
dnsapi/dns_bunny.sh
Normal file
@@ -0,0 +1,248 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
## Will be called by acme.sh to add the TXT record via the Bunny DNS API.
|
||||
## returns 0 means success, otherwise error.
|
||||
|
||||
## Author: nosilver4u <nosilver4u at ewww.io>
|
||||
## GitHub: https://github.com/nosilver4u/acme.sh
|
||||
|
||||
##
|
||||
## Environment Variables Required:
|
||||
##
|
||||
## BUNNY_API_KEY="75310dc4-ca77-9ac3-9a19-f6355db573b49ce92ae1-2655-3ebd-61ac-3a3ae34834cc"
|
||||
##
|
||||
|
||||
##################### Public functions #####################
|
||||
|
||||
## Create the text record for validation.
|
||||
## Usage: fulldomain txtvalue
|
||||
## EG: "_acme-challenge.www.other.domain.com" "XKrxpRBosdq0HG9i01zxXp5CPBs"
|
||||
dns_bunny_add() {
|
||||
fulldomain="$(echo "$1" | _lower_case)"
|
||||
txtvalue=$2
|
||||
|
||||
BUNNY_API_KEY="${BUNNY_API_KEY:-$(_readaccountconf_mutable BUNNY_API_KEY)}"
|
||||
# Check if API Key is set
|
||||
if [ -z "$BUNNY_API_KEY" ]; then
|
||||
BUNNY_API_KEY=""
|
||||
_err "You did not specify Bunny.net API key."
|
||||
_err "Please export BUNNY_API_KEY and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Using Bunny.net dns validation - add record"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
## save the env vars (key and domain split location) for later automated use
|
||||
_saveaccountconf_mutable BUNNY_API_KEY "$BUNNY_API_KEY"
|
||||
|
||||
## split the domain for Bunny API
|
||||
if ! _get_base_domain "$fulldomain"; then
|
||||
_err "domain not found in your account for addition"
|
||||
return 1
|
||||
fi
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
_debug _domain_id "$_domain_id"
|
||||
|
||||
## Set the header with our post type and auth key
|
||||
export _H1="Accept: application/json"
|
||||
export _H2="AccessKey: $BUNNY_API_KEY"
|
||||
export _H3="Content-Type: application/json"
|
||||
PURL="https://api.bunny.net/dnszone/$_domain_id/records"
|
||||
PBODY='{"Id":'$_domain_id',"Type":3,"Name":"'$_sub_domain'","Value":"'$txtvalue'","ttl":120}'
|
||||
|
||||
_debug PURL "$PURL"
|
||||
_debug PBODY "$PBODY"
|
||||
|
||||
## the create request - POST
|
||||
## args: BODY, URL, [need64, httpmethod]
|
||||
response="$(_post "$PBODY" "$PURL" "" "PUT")"
|
||||
|
||||
## check response
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error in response: $response"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
|
||||
## finished correctly
|
||||
return 0
|
||||
}
|
||||
|
||||
## Remove the txt record after validation.
|
||||
## Usage: fulldomain txtvalue
|
||||
## EG: "_acme-challenge.www.other.domain.com" "XKrxpRBosdq0HG9i01zxXp5CPBs"
|
||||
dns_bunny_rm() {
|
||||
fulldomain="$(echo "$1" | _lower_case)"
|
||||
txtvalue=$2
|
||||
|
||||
BUNNY_API_KEY="${BUNNY_API_KEY:-$(_readaccountconf_mutable BUNNY_API_KEY)}"
|
||||
# Check if API Key Exists
|
||||
if [ -z "$BUNNY_API_KEY" ]; then
|
||||
BUNNY_API_KEY=""
|
||||
_err "You did not specify Bunny.net API key."
|
||||
_err "Please export BUNNY_API_KEY and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Using Bunny.net dns validation - remove record"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
## split the domain for Bunny API
|
||||
if ! _get_base_domain "$fulldomain"; then
|
||||
_err "Domain not found in your account for TXT record removal"
|
||||
return 1
|
||||
fi
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
_debug _domain_id "$_domain_id"
|
||||
|
||||
## Set the header with our post type and key auth key
|
||||
export _H1="Accept: application/json"
|
||||
export _H2="AccessKey: $BUNNY_API_KEY"
|
||||
## get URL for the list of DNS records
|
||||
GURL="https://api.bunny.net/dnszone/$_domain_id"
|
||||
|
||||
## 1) Get the domain/zone records
|
||||
## the fetch request - GET
|
||||
## args: URL, [onlyheader, timeout]
|
||||
domain_list="$(_get "$GURL")"
|
||||
|
||||
## check response
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error in domain_list response: $domain_list"
|
||||
return 1
|
||||
fi
|
||||
_debug2 domain_list "$domain_list"
|
||||
|
||||
## 2) search through records
|
||||
## check for what we are looking for: "Type":3,"Value":"$txtvalue","Name":"$_sub_domain"
|
||||
record="$(echo "$domain_list" | _egrep_o "\"Id\"\s*\:\s*\"*[0-9]+\"*,\s*\"Type\"[^}]*\"Value\"\s*\:\s*\"$txtvalue\"[^}]*\"Name\"\s*\:\s*\"$_sub_domain\"")"
|
||||
|
||||
if [ -n "$record" ]; then
|
||||
|
||||
## We found records
|
||||
rec_ids="$(echo "$record" | _egrep_o "Id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")"
|
||||
_debug rec_ids "$rec_ids"
|
||||
if [ -n "$rec_ids" ]; then
|
||||
echo "$rec_ids" | while IFS= read -r rec_id; do
|
||||
## delete the record
|
||||
## delete URL for removing the one we dont want
|
||||
DURL="https://api.bunny.net/dnszone/$_domain_id/records/$rec_id"
|
||||
|
||||
## the removal request - DELETE
|
||||
## args: BODY, URL, [need64, httpmethod]
|
||||
response="$(_post "" "$DURL" "" "DELETE")"
|
||||
|
||||
## check response (sort of)
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error in remove response: $response"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
## finished correctly
|
||||
return 0
|
||||
}
|
||||
|
||||
##################### Private functions below #####################
|
||||
|
||||
## Split the domain provided into the "base domain" and the "start prefix".
|
||||
## This function searches for the longest subdomain in your account
|
||||
## for the full domain given and splits it into the base domain (zone)
|
||||
## and the prefix/record to be added/removed
|
||||
## USAGE: fulldomain
|
||||
## EG: "_acme-challenge.two.three.four.domain.com"
|
||||
## returns
|
||||
## _sub_domain="_acme-challenge.two"
|
||||
## _domain="three.four.domain.com" *IF* zone "three.four.domain.com" exists
|
||||
## _domain_id=234
|
||||
## if only "domain.com" exists it will return
|
||||
## _sub_domain="_acme-challenge.two.three.four"
|
||||
## _domain="domain.com"
|
||||
## _domain_id=234
|
||||
_get_base_domain() {
|
||||
# args
|
||||
fulldomain="$(echo "$1" | _lower_case)"
|
||||
_debug fulldomain "$fulldomain"
|
||||
|
||||
# domain max legal length = 253
|
||||
MAX_DOM=255
|
||||
page=1
|
||||
|
||||
## get a list of domains for the account to check thru
|
||||
## Set the headers
|
||||
export _H1="Accept: application/json"
|
||||
export _H2="AccessKey: $BUNNY_API_KEY"
|
||||
_debug BUNNY_API_KEY "$BUNNY_API_KEY"
|
||||
## get URL for the list of domains
|
||||
## may get: "links":{"pages":{"last":".../v2/domains/DOM/records?page=2","next":".../v2/domains/DOM/records?page=2"}}
|
||||
DOMURL="https://api.bunny.net/dnszone"
|
||||
|
||||
## while we dont have a matching domain we keep going
|
||||
while [ -z "$found" ]; do
|
||||
## get the domain list (current page)
|
||||
domain_list="$(_get "$DOMURL")"
|
||||
|
||||
## check response
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error in domain_list response: $domain_list"
|
||||
return 1
|
||||
fi
|
||||
_debug2 domain_list "$domain_list"
|
||||
|
||||
i=1
|
||||
while [ $i -gt 0 ]; do
|
||||
## get next longest domain
|
||||
_domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM")
|
||||
## check we got something back from our cut (or are we at the end)
|
||||
if [ -z "$_domain" ]; then
|
||||
break
|
||||
fi
|
||||
## we got part of a domain back - grep it out
|
||||
found="$(echo "$domain_list" | _egrep_o "\"Id\"\s*:\s*\"*[0-9]+\"*,\s*\"Domain\"\s*\:\s*\"$_domain\"")"
|
||||
## check if it exists
|
||||
if [ -n "$found" ]; then
|
||||
## exists - exit loop returning the parts
|
||||
sub_point=$(_math $i - 1)
|
||||
_sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point")
|
||||
_domain_id="$(echo "$found" | _egrep_o "Id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")"
|
||||
_debug _domain_id "$_domain_id"
|
||||
_debug _domain "$_domain"
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
found=""
|
||||
return 0
|
||||
fi
|
||||
## increment cut point $i
|
||||
i=$(_math $i + 1)
|
||||
done
|
||||
|
||||
if [ -z "$found" ]; then
|
||||
page=$(_math $page + 1)
|
||||
nextpage="https://api.bunny.net/dnszone?page=$page"
|
||||
## Find the next page if we don't have a match.
|
||||
hasnextpage="$(echo "$domain_list" | _egrep_o "\"HasMoreItems\"\s*:\s*true")"
|
||||
if [ -z "$hasnextpage" ]; then
|
||||
_err "No record and no nextpage in Bunny.net domain search."
|
||||
found=""
|
||||
return 1
|
||||
fi
|
||||
_debug2 nextpage "$nextpage"
|
||||
DOMURL="$nextpage"
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
## We went through the entire domain zone list and didn't find one that matched.
|
||||
## If we ever get here, something is broken in the code...
|
||||
_err "Domain not found in Bunny.net account, but we should never get here!"
|
||||
found=""
|
||||
return 1
|
||||
}
|
||||
@@ -32,7 +32,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 +52,14 @@ dns_cf_add() {
|
||||
#save the api key and email to the account conf file.
|
||||
_saveaccountconf_mutable CF_Key "$CF_Key"
|
||||
_saveaccountconf_mutable CF_Email "$CF_Email"
|
||||
|
||||
_clearaccountconf_mutable CF_Token
|
||||
_clearaccountconf_mutable CF_Account_ID
|
||||
_clearaccountconf_mutable CF_Zone_ID
|
||||
_clearaccountconf CF_Token
|
||||
_clearaccountconf CF_Account_ID
|
||||
_clearaccountconf CF_Zone_ID
|
||||
|
||||
fi
|
||||
|
||||
_debug "First detect the root zone"
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
# cPanel_Hostname=hostname
|
||||
#
|
||||
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
|
||||
# Used to add txt record
|
||||
dns_cpanel_add() {
|
||||
fulldomain=$1
|
||||
@@ -120,7 +121,7 @@ _myget() {
|
||||
|
||||
_get_root() {
|
||||
_myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones'
|
||||
_domains=$(echo "$_result" | sed 's/.*\(zones.*\[\).*/\1/' | cut -d':' -f2 | sed 's/"//g' | sed 's/{//g')
|
||||
_domains=$(echo "$_result" | _egrep_o '"[a-z0-9\.\-]*":\["; cPanel first' | cut -d':' -f1 | sed 's/"//g' | sed 's/{//g')
|
||||
_debug "_result is: $_result"
|
||||
_debug "_domains is: $_domains"
|
||||
if [ -z "$_domains" ]; then
|
||||
@@ -138,15 +139,15 @@ _get_root() {
|
||||
}
|
||||
|
||||
_successful_update() {
|
||||
if (echo "$_result" | grep -q 'newserial'); then return 0; fi
|
||||
return 1
|
||||
if (echo "$_result" | _egrep_o 'data":\[[^]]*]' | grep -q '"newserial":null'); then return 1; fi
|
||||
return 0
|
||||
}
|
||||
|
||||
_findentry() {
|
||||
_debug "In _findentry"
|
||||
#returns id of dns entry, if it exists
|
||||
_myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&domain=$_domain"
|
||||
_id=$(echo "$_result" | sed "s/.*\(line.*$fulldomain.*$txtvalue\).*/\1/" | cut -d ':' -f 2 | cut -d ',' -f 1)
|
||||
_id=$(echo "$_result" | sed -e "s/},{/},\n{/g" | grep "$fulldomain" | grep "$txtvalue" | _egrep_o 'line":[0-9]+' | cut -d ':' -f 2)
|
||||
_debug "_result is: $_result"
|
||||
_debug "fulldomain. is $fulldomain."
|
||||
_debug "txtvalue is $txtvalue"
|
||||
|
||||
@@ -44,7 +44,7 @@ dns_cyon_rm() {
|
||||
_cyon_load_credentials() {
|
||||
# Convert loaded password to/from base64 as needed.
|
||||
if [ "${CY_Password_B64}" ]; then
|
||||
CY_Password="$(printf "%s" "${CY_Password_B64}" | _dbase64 "multiline")"
|
||||
CY_Password="$(printf "%s" "${CY_Password_B64}" | _dbase64)"
|
||||
elif [ "${CY_Password}" ]; then
|
||||
CY_Password_B64="$(printf "%s" "${CY_Password}" | _base64)"
|
||||
fi
|
||||
|
||||
@@ -192,6 +192,7 @@ _get_base_domain() {
|
||||
## get URL for the list of domains
|
||||
## may get: "links":{"pages":{"last":".../v2/domains/DOM/records?page=2","next":".../v2/domains/DOM/records?page=2"}}
|
||||
DOMURL="https://api.digitalocean.com/v2/domains"
|
||||
found=""
|
||||
|
||||
## while we dont have a matching domain we keep going
|
||||
while [ -z "$found" ]; do
|
||||
@@ -205,9 +206,7 @@ _get_base_domain() {
|
||||
fi
|
||||
_debug2 domain_list "$domain_list"
|
||||
|
||||
## for each shortening of our $fulldomain, check if it exists in the $domain_list
|
||||
## can never start on 1 (aka whole $fulldomain) as $fulldomain starts with "_acme-challenge"
|
||||
i=2
|
||||
i=1
|
||||
while [ $i -gt 0 ]; do
|
||||
## get next longest domain
|
||||
_domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM")
|
||||
|
||||
248
dnsapi/dns_dnsservices.sh
Executable file
248
dnsapi/dns_dnsservices.sh
Executable file
@@ -0,0 +1,248 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#This file name is "dns_dnsservices.sh"
|
||||
#Script for Danish DNS registra and DNS hosting provider https://dns.services
|
||||
|
||||
#Author: Bjarke Bruun <bbruun@gmail.com>
|
||||
#Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/4152
|
||||
|
||||
# Global variable to connect to the DNS.Services API
|
||||
DNSServices_API=https://dns.services/api
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: dns_dnsservices_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_dnsservices_add() {
|
||||
fulldomain="$1"
|
||||
txtvalue="$2"
|
||||
|
||||
_info "Using dns.services to create ACME DNS challenge"
|
||||
_debug2 add_fulldomain "$fulldomain"
|
||||
_debug2 add_txtvalue "$txtvalue"
|
||||
|
||||
# Read username/password from environment or .acme.sh/accounts.conf
|
||||
DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}"
|
||||
DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}"
|
||||
if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then
|
||||
DnsServices_Username=""
|
||||
DnsServices_Password=""
|
||||
_err "You didn't specify dns.services api username and password yet."
|
||||
_err "Set environment variables DnsServices_Username and DnsServices_Password"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Setup GET/POST/DELETE headers
|
||||
_setup_headers
|
||||
|
||||
#save the credentials to the account conf file.
|
||||
_saveaccountconf_mutable DnsServices_Username "$DnsServices_Username"
|
||||
_saveaccountconf_mutable DnsServices_Password "$DnsServices_Password"
|
||||
|
||||
if ! _contains "$DnsServices_Username" "@"; then
|
||||
_err "It seems that the username variable DnsServices_Username has not been set/left blank"
|
||||
_err "or is not a valid email. Please correct and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _get_root "${fulldomain}"; then
|
||||
_err "Invalid domain ${fulldomain}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! createRecord "$fulldomain" "${txtvalue}"; then
|
||||
_err "Error creating TXT record in domain $fulldomain in $rootZoneName"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 challenge-created "Created $fulldomain"
|
||||
return 0
|
||||
}
|
||||
|
||||
#Usage: fulldomain txtvalue
|
||||
#Description: Remove the txt record after validation.
|
||||
dns_dnsservices_rm() {
|
||||
fulldomain="$1"
|
||||
txtvalue="$2"
|
||||
|
||||
_info "Using dns.services to remove DNS record $fulldomain TXT $txtvalue"
|
||||
_debug rm_fulldomain "$fulldomain"
|
||||
_debug rm_txtvalue "$txtvalue"
|
||||
|
||||
# Read username/password from environment or .acme.sh/accounts.conf
|
||||
DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}"
|
||||
DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}"
|
||||
if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then
|
||||
DnsServices_Username=""
|
||||
DnsServices_Password=""
|
||||
_err "You didn't specify dns.services api username and password yet."
|
||||
_err "Set environment variables DnsServices_Username and DnsServices_Password"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Setup GET/POST/DELETE headers
|
||||
_setup_headers
|
||||
|
||||
if ! _get_root "${fulldomain}"; then
|
||||
_err "Invalid domain ${fulldomain}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 rm_rootDomainInfo "found root domain $rootZoneName for $fulldomain"
|
||||
|
||||
if ! deleteRecord "${fulldomain}" "${txtvalue}"; then
|
||||
_err "Error removing record: $fulldomain TXT ${txtvalue}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
|
||||
_setup_headers() {
|
||||
# Set up API Headers for _get() and _post()
|
||||
# The <function>_add or <function>_rm must have been called before to work
|
||||
|
||||
if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then
|
||||
_err "Could not setup BASIC authentication headers, they are missing"
|
||||
return 1
|
||||
fi
|
||||
|
||||
DnsServiceCredentials="$(printf "%s" "$DnsServices_Username:$DnsServices_Password" | _base64)"
|
||||
export _H1="Authorization: Basic $DnsServiceCredentials"
|
||||
export _H2="Content-Type: application/json"
|
||||
|
||||
# Just return if headers are set
|
||||
return 0
|
||||
}
|
||||
|
||||
_get_root() {
|
||||
domain="$1"
|
||||
_debug2 _get_root "Get the root domain of ${domain} for DNS API"
|
||||
|
||||
# Setup _get() and _post() headers
|
||||
#_setup_headers
|
||||
|
||||
result=$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/dns")
|
||||
result2="$(printf "%s\n" "$result" | tr '[' '\n' | grep '"name"')"
|
||||
result3="$(printf "%s\n" "$result2" | tr '}' '\n' | grep '"name"' | sed "s,^\,,,g" | sed "s,$,},g")"
|
||||
useResult=""
|
||||
_debug2 _get_root "Got the following root domain(s) $result"
|
||||
_debug2 _get_root "- JSON: $result"
|
||||
|
||||
if [ "$(printf "%s\n" "$result" | tr '}' '\n' | grep -c '"name"')" -gt "1" ]; then
|
||||
checkMultiZones="true"
|
||||
_debug2 _get_root "- multiple zones found"
|
||||
else
|
||||
checkMultiZones="false"
|
||||
_debug2 _get_root "- single zone found"
|
||||
fi
|
||||
|
||||
# Find/isolate the root zone to work with in createRecord() and deleteRecord()
|
||||
rootZone=""
|
||||
if [ "$checkMultiZones" = "true" ]; then
|
||||
#rootZone=$(for x in $(printf "%s" "${result3}" | tr ',' '\n' | sed -n 's/.*"name":"\(.*\)",.*/\1/p'); do if [ "$(echo "$domain" | grep "$x")" != "" ]; then echo "$x"; fi; done)
|
||||
rootZone=$(for x in $(printf "%s\n" "${result3}" | tr ',' '\n' | grep name | cut -d'"' -f4); do if [ "$(echo "$domain" | grep "$x")" != "" ]; then echo "$x"; fi; done)
|
||||
if [ "$rootZone" != "" ]; then
|
||||
_debug2 _rootZone "- root zone for $domain is $rootZone"
|
||||
else
|
||||
_err "Could not find root zone for $domain, is it correctly typed?"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
rootZone=$(echo "$result" | tr '}' '\n' | _egrep_o '"name":"[^"]*' | cut -d'"' -f4)
|
||||
_debug2 _get_root "- only found 1 domain in API: $rootZone"
|
||||
fi
|
||||
|
||||
if [ -z "$rootZone" ]; then
|
||||
_err "Could not find root domain for $domain - is it correctly typed?"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Make sure we use the correct API zone data
|
||||
useResult="$(printf "%s\n" "${result3}" tr ',' '\n' | grep "$rootZone")"
|
||||
_debug2 _useResult "useResult=$useResult"
|
||||
|
||||
# Setup variables used by other functions to communicate with DNS.Services API
|
||||
#zoneInfo=$(printf "%s\n" "$useResult" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g')
|
||||
zoneInfo=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep '"name"' | cut -d'"' -f4)
|
||||
rootZoneName="$rootZone"
|
||||
subDomainName="$(printf "%s\n" "$domain" | sed "s,\.$rootZone,,g")"
|
||||
subDomainNameClean="$(printf "%s\n" "$domain" | sed "s,_acme-challenge.,,g")"
|
||||
rootZoneDomainID=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep domain_id | cut -d'"' -f4)
|
||||
rootZoneServiceID=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep service_id | cut -d'"' -f4)
|
||||
|
||||
_debug2 _zoneInfo "Zone info from API : $zoneInfo"
|
||||
_debug2 _get_root "Root zone name : $rootZoneName"
|
||||
_debug2 _get_root "Root zone domain ID : $rootZoneDomainID"
|
||||
_debug2 _get_root "Root zone service ID: $rootZoneServiceID"
|
||||
_debug2 _get_root "Sub domain : $subDomainName"
|
||||
|
||||
_debug _get_root "Found valid root domain $rootZone for $subDomainNameClean"
|
||||
return 0
|
||||
}
|
||||
|
||||
createRecord() {
|
||||
fulldomain="$1"
|
||||
txtvalue="$2"
|
||||
|
||||
# Get root domain information - needed for DNS.Services API communication
|
||||
if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
|
||||
_get_root "$fulldomain"
|
||||
fi
|
||||
if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
|
||||
_err "Something happend - could not get the API zone information"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 createRecord "CNAME TXT value is: $txtvalue"
|
||||
|
||||
# Prepare data to send to API
|
||||
data="{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"${txtvalue}\", \"ttl\":\"10\"}"
|
||||
|
||||
_debug2 createRecord "data to API: $data"
|
||||
result=$(_post "$data" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records" "" "POST")
|
||||
_debug2 createRecord "result from API: $result"
|
||||
|
||||
if [ "$(echo "$result" | _egrep_o "\"success\":true")" = "" ]; then
|
||||
_err "Failed to create TXT record $fulldomain with content $txtvalue in zone $rootZoneName"
|
||||
_err "$result"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Record \"$fulldomain TXT $txtvalue\" has been created"
|
||||
return 0
|
||||
}
|
||||
|
||||
deleteRecord() {
|
||||
fulldomain="$1"
|
||||
txtvalue="$2"
|
||||
|
||||
_log deleteRecord "Deleting $fulldomain TXT $txtvalue record"
|
||||
|
||||
if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
|
||||
_get_root "$fulldomain"
|
||||
fi
|
||||
|
||||
result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")"
|
||||
#recordInfo="$(echo "$result" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}")"
|
||||
#recordID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"id":")([^"]*)"(.*)$,\2,g')"
|
||||
recordID="$(printf "%s\n" "$result" | tr '}' '\n' | grep -- "$txtvalue" | tr ',' '\n' | grep '"id"' | cut -d'"' -f4)"
|
||||
_debug2 _recordID "recordID used for deletion of record: $recordID"
|
||||
|
||||
if [ -z "$recordID" ]; then
|
||||
_info "Record $fulldomain TXT $txtvalue not found or already deleted"
|
||||
return 0
|
||||
else
|
||||
_debug2 deleteRecord "Found recordID=$recordID"
|
||||
fi
|
||||
|
||||
_debug2 deleteRecord "DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID"
|
||||
_log "curl DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID"
|
||||
result="$(_H1="$_H1" _H2="$_H2" _post "" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" "" "DELETE")"
|
||||
_debug2 deleteRecord "API Delete result \"$result\""
|
||||
_log "curl API Delete result \"$result\""
|
||||
|
||||
# Return OK regardless
|
||||
return 0
|
||||
}
|
||||
@@ -94,8 +94,8 @@ _get_domain() {
|
||||
_your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')"
|
||||
for l in $_your_hosts; do
|
||||
#echo "host: $l"
|
||||
if test "${_full_domain#*$l}" != "$_full_domain"; then
|
||||
_record="${_full_domain%.$l}"
|
||||
if test "${_full_domain#*"$l"}" != "$_full_domain"; then
|
||||
_record=${_full_domain%."$l"}
|
||||
_host=$l
|
||||
_debug "The host is $_host and the record $_record"
|
||||
return 0
|
||||
@@ -143,7 +143,7 @@ _dns_dynv6_add_http() {
|
||||
return 1
|
||||
fi
|
||||
_get_zone_name "$_zone_id"
|
||||
record="${fulldomain%%.$_zone_name}"
|
||||
record=${fulldomain%%."$_zone_name"}
|
||||
_set_record TXT "$record" "$txtvalue"
|
||||
if _contains "$response" "$txtvalue"; then
|
||||
_info "Successfully added record"
|
||||
@@ -161,7 +161,7 @@ _dns_dynv6_rm_http() {
|
||||
return 1
|
||||
fi
|
||||
_get_zone_name "$_zone_id"
|
||||
record="${fulldomain%%.$_zone_name}"
|
||||
record=${fulldomain%%."$_zone_name"}
|
||||
_get_record_id "$_zone_id" "$record" "$txtvalue"
|
||||
_del_record "$_zone_id" "$_record_id"
|
||||
if [ -z "$response" ]; then
|
||||
|
||||
@@ -176,6 +176,7 @@ _EDGEDNS_credentials() {
|
||||
_debug "GettingEdge DNS credentials"
|
||||
_log "$(printf "ACME DNSAPI Edge DNS version %s" ${ACME_EDGEDNS_VERSION})"
|
||||
args_missing=0
|
||||
AKAMAI_ACCESS_TOKEN="${AKAMAI_ACCESS_TOKEN:-$(_readaccountconf_mutable AKAMAI_ACCESS_TOKEN)}"
|
||||
if [ -z "$AKAMAI_ACCESS_TOKEN" ]; then
|
||||
AKAMAI_ACCESS_TOKEN=""
|
||||
AKAMAI_CLIENT_TOKEN=""
|
||||
@@ -184,6 +185,7 @@ _EDGEDNS_credentials() {
|
||||
_err "AKAMAI_ACCESS_TOKEN is missing"
|
||||
args_missing=1
|
||||
fi
|
||||
AKAMAI_CLIENT_TOKEN="${AKAMAI_CLIENT_TOKEN:-$(_readaccountconf_mutable AKAMAI_CLIENT_TOKEN)}"
|
||||
if [ -z "$AKAMAI_CLIENT_TOKEN" ]; then
|
||||
AKAMAI_ACCESS_TOKEN=""
|
||||
AKAMAI_CLIENT_TOKEN=""
|
||||
@@ -192,6 +194,7 @@ _EDGEDNS_credentials() {
|
||||
_err "AKAMAI_CLIENT_TOKEN is missing"
|
||||
args_missing=1
|
||||
fi
|
||||
AKAMAI_HOST="${AKAMAI_HOST:-$(_readaccountconf_mutable AKAMAI_HOST)}"
|
||||
if [ -z "$AKAMAI_HOST" ]; then
|
||||
AKAMAI_ACCESS_TOKEN=""
|
||||
AKAMAI_CLIENT_TOKEN=""
|
||||
@@ -200,6 +203,7 @@ _EDGEDNS_credentials() {
|
||||
_err "AKAMAI_HOST is missing"
|
||||
args_missing=1
|
||||
fi
|
||||
AKAMAI_CLIENT_SECRET="${AKAMAI_CLIENT_SECRET:-$(_readaccountconf_mutable AKAMAI_CLIENT_SECRET)}"
|
||||
if [ -z "$AKAMAI_CLIENT_SECRET" ]; then
|
||||
AKAMAI_ACCESS_TOKEN=""
|
||||
AKAMAI_CLIENT_TOKEN=""
|
||||
@@ -414,7 +418,7 @@ _edgedns_make_data_to_sign() {
|
||||
_secure_debug2 "hdr" "$hdr"
|
||||
_edgedns_make_content_hash
|
||||
path="$(echo "$_request_url_path" | tr -d "\n\r" | sed 's/https\?:\/\///')"
|
||||
path="${path#*$AKAMAI_HOST}"
|
||||
path=${path#*"$AKAMAI_HOST"}
|
||||
_debug "hier path" "$path"
|
||||
# dont expose headers to sign so use MT string
|
||||
_mdata="$(printf "%s\thttps\t%s\t%s\t%s\t%s\t%s" "$_request_method" "$AKAMAI_HOST" "$path" "" "$_hash" "$hdr")"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Gandi LiveDNS v5 API
|
||||
# http://doc.livedns.gandi.net/
|
||||
# https://doc.livedns.gandi.net/
|
||||
# currently under beta
|
||||
#
|
||||
# Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable
|
||||
|
||||
@@ -39,7 +39,7 @@ dns_gcloud_rm() {
|
||||
_dns_gcloud_start_tr || return $?
|
||||
_dns_gcloud_get_rrdatas || return $?
|
||||
echo "$rrdatas" | _dns_gcloud_remove_rrs || return $?
|
||||
echo "$rrdatas" | grep -F -v "\"$txtvalue\"" | _dns_gcloud_add_rrs || return $?
|
||||
echo "$rrdatas" | grep -F -v -- "\"$txtvalue\"" | _dns_gcloud_add_rrs || return $?
|
||||
_dns_gcloud_execute_tr || return $?
|
||||
|
||||
_info "$fulldomain record added"
|
||||
@@ -98,7 +98,7 @@ _dns_gcloud_remove_rrs() {
|
||||
--ttl="$ttl" \
|
||||
--type=TXT \
|
||||
--zone="$managedZone" \
|
||||
--transaction-file="$tr"; then
|
||||
--transaction-file="$tr" --; then
|
||||
_debug tr "$(cat "$tr")"
|
||||
rm -r "$trd"
|
||||
_err "_dns_gcloud_remove_rrs: failed to remove RRs"
|
||||
@@ -113,7 +113,7 @@ _dns_gcloud_add_rrs() {
|
||||
--ttl="$ttl" \
|
||||
--type=TXT \
|
||||
--zone="$managedZone" \
|
||||
--transaction-file="$tr"; then
|
||||
--transaction-file="$tr" --; then
|
||||
_debug tr "$(cat "$tr")"
|
||||
rm -r "$trd"
|
||||
_err "_dns_gcloud_add_rrs: failed to add RRs"
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Godaddy domain api
|
||||
# Get API key and secret from https://developer.godaddy.com/
|
||||
#
|
||||
#GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
|
||||
# GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
|
||||
# GD_Secret="asdfsdfsfsdfsdfdfsdf"
|
||||
#
|
||||
#GD_Secret="asdfsdfsfsdfsdfdfsdf"
|
||||
# Ex.: acme.sh --issue --staging --dns dns_gd -d "*.s.example.com" -d "s.example.com"
|
||||
|
||||
GD_Api="https://api.godaddy.com/v1"
|
||||
|
||||
@@ -51,7 +53,8 @@ dns_gd_add() {
|
||||
_add_data="{\"data\":\"$txtvalue\"}"
|
||||
for t in $(echo "$response" | tr '{' "\n" | grep "\"name\":\"$_sub_domain\"" | tr ',' "\n" | grep '"data"' | cut -d : -f 2); do
|
||||
_debug2 t "$t"
|
||||
if [ "$t" ]; then
|
||||
# ignore empty (previously removed) records, to prevent useless _acme-challenge TXT entries
|
||||
if [ "$t" ] && [ "$t" != '""' ]; then
|
||||
_add_data="$_add_data,{\"data\":$t}"
|
||||
fi
|
||||
done
|
||||
@@ -59,13 +62,25 @@ dns_gd_add() {
|
||||
|
||||
_info "Adding record"
|
||||
if _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"; then
|
||||
_info "Added, sleeping 10 seconds"
|
||||
_sleep 10
|
||||
#todo: check if the record takes effect
|
||||
return 0
|
||||
_debug "Checking updated records of '${fulldomain}'"
|
||||
|
||||
if ! _gd_rest GET "domains/$_domain/records/TXT/$_sub_domain"; then
|
||||
_err "Validating TXT record for '${fulldomain}' with rest error [$?]." "$response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _contains "$response" "$txtvalue"; then
|
||||
_err "TXT record '${txtvalue}' for '${fulldomain}', value wasn't set!"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
_err "Add txt record error, value '${txtvalue}' for '${fulldomain}' was not set."
|
||||
return 1
|
||||
fi
|
||||
_err "Add txt record error."
|
||||
return 1
|
||||
|
||||
_sleep 10
|
||||
_info "Added TXT record '${txtvalue}' for '${fulldomain}'."
|
||||
return 0
|
||||
}
|
||||
|
||||
#fulldomain
|
||||
@@ -107,11 +122,20 @@ dns_gd_rm() {
|
||||
fi
|
||||
done
|
||||
if [ -z "$_add_data" ]; then
|
||||
_add_data="{\"data\":\"\"}"
|
||||
# delete empty record
|
||||
_debug "Delete last record for '${fulldomain}'"
|
||||
if ! _gd_rest DELETE "domains/$_domain/records/TXT/$_sub_domain"; then
|
||||
_err "Cannot delete empty TXT record for '$fulldomain'"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
# remove specific TXT value, keeping other entries
|
||||
_debug2 _add_data "$_add_data"
|
||||
if ! _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"; then
|
||||
_err "Cannot update TXT record for '$fulldomain'"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
_debug2 _add_data "$_add_data"
|
||||
|
||||
_gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
@@ -156,15 +180,15 @@ _gd_rest() {
|
||||
export _H1="Authorization: sso-key $GD_Key:$GD_Secret"
|
||||
export _H2="Content-Type: application/json"
|
||||
|
||||
if [ "$data" ]; then
|
||||
_debug data "$data"
|
||||
if [ "$data" ] || [ "$m" = "DELETE" ]; then
|
||||
_debug "data ($m): " "$data"
|
||||
response="$(_post "$data" "$GD_Api/$ep" "" "$m")"
|
||||
else
|
||||
response="$(_get "$GD_Api/$ep")"
|
||||
fi
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error $ep"
|
||||
_err "error on rest call ($m): $ep"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# HUAWEICLOUD_Username
|
||||
# HUAWEICLOUD_Password
|
||||
# HUAWEICLOUD_ProjectID
|
||||
# HUAWEICLOUD_DomainName
|
||||
|
||||
iam_api="https://iam.myhuaweicloud.com"
|
||||
dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work
|
||||
@@ -14,6 +14,8 @@ dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work
|
||||
#
|
||||
# Ref: https://support.huaweicloud.com/intl/zh-cn/api-dns/zh-cn_topic_0132421999.html
|
||||
#
|
||||
# About "DomainName" parameters see: https://support.huaweicloud.com/api-iam/iam_01_0006.html
|
||||
#
|
||||
|
||||
dns_huaweicloud_add() {
|
||||
fulldomain=$1
|
||||
@@ -21,16 +23,16 @@ dns_huaweicloud_add() {
|
||||
|
||||
HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
|
||||
HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
|
||||
HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}"
|
||||
HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
|
||||
|
||||
# Check information
|
||||
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_ProjectID}" ]; then
|
||||
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
|
||||
_err "Not enough information provided to dns_huaweicloud!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
unset token # Clear token
|
||||
token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")"
|
||||
token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_DomainName}")"
|
||||
if [ -z "${token}" ]; then # Check token
|
||||
_err "dns_api(dns_huaweicloud): Error getting token."
|
||||
return 1
|
||||
@@ -56,7 +58,7 @@ dns_huaweicloud_add() {
|
||||
# Do saving work if all succeeded
|
||||
_saveaccountconf_mutable HUAWEICLOUD_Username "${HUAWEICLOUD_Username}"
|
||||
_saveaccountconf_mutable HUAWEICLOUD_Password "${HUAWEICLOUD_Password}"
|
||||
_saveaccountconf_mutable HUAWEICLOUD_ProjectID "${HUAWEICLOUD_ProjectID}"
|
||||
_saveaccountconf_mutable HUAWEICLOUD_DomainName "${HUAWEICLOUD_DomainName}"
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -72,16 +74,16 @@ dns_huaweicloud_rm() {
|
||||
|
||||
HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
|
||||
HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
|
||||
HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}"
|
||||
HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
|
||||
|
||||
# Check information
|
||||
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_ProjectID}" ]; then
|
||||
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
|
||||
_err "Not enough information provided to dns_huaweicloud!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
unset token # Clear token
|
||||
token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")"
|
||||
token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_DomainName}")"
|
||||
if [ -z "${token}" ]; then # Check token
|
||||
_err "dns_api(dns_huaweicloud): Error getting token."
|
||||
return 1
|
||||
@@ -253,7 +255,7 @@ _rm_record() {
|
||||
_get_token() {
|
||||
_username=$1
|
||||
_password=$2
|
||||
_project=$3
|
||||
_domain_name=$3
|
||||
|
||||
_debug "Getting Token"
|
||||
body="{
|
||||
@@ -267,14 +269,14 @@ _get_token() {
|
||||
\"name\": \"${_username}\",
|
||||
\"password\": \"${_password}\",
|
||||
\"domain\": {
|
||||
\"name\": \"${_username}\"
|
||||
\"name\": \"${_domain_name}\"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
\"scope\": {
|
||||
\"project\": {
|
||||
\"id\": \"${_project}\"
|
||||
\"name\": \"ap-southeast-1\"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ dns_infomaniak_add() {
|
||||
domain_id=${zone_and_id#* }
|
||||
|
||||
# extract first part of domain
|
||||
key=${fulldomain%.$zone}
|
||||
key=${fulldomain%."$zone"}
|
||||
|
||||
_debug "zone:$zone id:$domain_id key:$key"
|
||||
|
||||
@@ -149,7 +149,7 @@ dns_infomaniak_rm() {
|
||||
domain_id=${zone_and_id#* }
|
||||
|
||||
# extract first part of domain
|
||||
key=${fulldomain%.$zone}
|
||||
key=${fulldomain%."$zone"}
|
||||
|
||||
_debug "zone:$zone id:$domain_id key:$key"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Supports IONOS DNS API Beta v1.0.0
|
||||
# Supports IONOS DNS API v1.0.1
|
||||
#
|
||||
# Usage:
|
||||
# Export IONOS_PREFIX and IONOS_SECRET before calling acme.sh:
|
||||
@@ -26,7 +26,7 @@ dns_ionos_add() {
|
||||
|
||||
_body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]"
|
||||
|
||||
if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ -z "$response" ]; then
|
||||
if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "201" ]; then
|
||||
_info "TXT record has been created successfully."
|
||||
return 0
|
||||
fi
|
||||
@@ -47,7 +47,7 @@ dns_ionos_rm() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ -z "$response" ]; then
|
||||
if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "200" ]; then
|
||||
_info "TXT record has been deleted successfully."
|
||||
return 0
|
||||
fi
|
||||
@@ -85,7 +85,7 @@ _get_root() {
|
||||
p=1
|
||||
|
||||
if _ionos_rest GET "$IONOS_ROUTE_ZONES"; then
|
||||
response="$(echo "$response" | tr -d "\n")"
|
||||
_response="$(echo "$_response" | tr -d "\n")"
|
||||
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
@@ -93,7 +93,7 @@ _get_root() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
_zone="$(echo "$response" | _egrep_o "\"name\":\"$h\".*\}")"
|
||||
_zone="$(echo "$_response" | _egrep_o "\"name\":\"$h\".*\}")"
|
||||
if [ "$_zone" ]; then
|
||||
_zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"')
|
||||
if [ "$_zone_id" ]; then
|
||||
@@ -120,9 +120,9 @@ _ionos_get_record() {
|
||||
txtrecord=$3
|
||||
|
||||
if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then
|
||||
response="$(echo "$response" | tr -d "\n")"
|
||||
_response="$(echo "$_response" | tr -d "\n")"
|
||||
|
||||
_record="$(echo "$response" | _egrep_o "\"name\":\"$fulldomain\"[^\}]*\"type\":\"TXT\"[^\}]*\"content\":\"\\\\\"$txtrecord\\\\\"\".*\}")"
|
||||
_record="$(echo "$_response" | _egrep_o "\"name\":\"$fulldomain\"[^\}]*\"type\":\"TXT\"[^\}]*\"content\":\"\\\\\"$txtrecord\\\\\"\".*\}")"
|
||||
if [ "$_record" ]; then
|
||||
_record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"')
|
||||
|
||||
@@ -142,22 +142,30 @@ _ionos_rest() {
|
||||
|
||||
export _H1="X-API-Key: $IONOS_API_KEY"
|
||||
|
||||
# clear headers
|
||||
: >"$HTTP_HEADER"
|
||||
|
||||
if [ "$method" != "GET" ]; then
|
||||
export _H2="Accept: application/json"
|
||||
export _H3="Content-Type: application/json"
|
||||
|
||||
response="$(_post "$data" "$IONOS_API$route" "" "$method" "application/json")"
|
||||
_response="$(_post "$data" "$IONOS_API$route" "" "$method" "application/json")"
|
||||
else
|
||||
export _H2="Accept: */*"
|
||||
export _H3=
|
||||
response="$(_get "$IONOS_API$route")"
|
||||
|
||||
_response="$(_get "$IONOS_API$route")"
|
||||
fi
|
||||
|
||||
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "Error $route: $response"
|
||||
_err "Error $route: $_response"
|
||||
return 1
|
||||
fi
|
||||
_debug2 "response" "$response"
|
||||
|
||||
_debug2 "_response" "$_response"
|
||||
_debug2 "_code" "$_code"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -32,6 +32,10 @@ dns_ispconfig_rm() {
|
||||
#################### Private functions below ##################################
|
||||
|
||||
_ISPC_credentials() {
|
||||
ISPC_User="${ISPC_User:-$(_readaccountconf_mutable ISPC_User)}"
|
||||
ISPC_Password="${ISPC_Password:-$(_readaccountconf_mutable ISPC_Password)}"
|
||||
ISPC_Api="${ISPC_Api:-$(_readaccountconf_mutable ISPC_Api)}"
|
||||
ISPC_Api_Insecure="${ISPC_Api_Insecure:-$(_readaccountconf_mutable ISPC_Api_Insecure)}"
|
||||
if [ -z "${ISPC_User}" ] || [ -z "${ISPC_Password}" ] || [ -z "${ISPC_Api}" ] || [ -z "${ISPC_Api_Insecure}" ]; then
|
||||
ISPC_User=""
|
||||
ISPC_Password=""
|
||||
@@ -40,10 +44,10 @@ _ISPC_credentials() {
|
||||
_err "You haven't specified the ISPConfig Login data, URL and whether you want check the ISPC SSL cert. Please try again."
|
||||
return 1
|
||||
else
|
||||
_saveaccountconf ISPC_User "${ISPC_User}"
|
||||
_saveaccountconf ISPC_Password "${ISPC_Password}"
|
||||
_saveaccountconf ISPC_Api "${ISPC_Api}"
|
||||
_saveaccountconf ISPC_Api_Insecure "${ISPC_Api_Insecure}"
|
||||
_saveaccountconf_mutable ISPC_User "${ISPC_User}"
|
||||
_saveaccountconf_mutable ISPC_Password "${ISPC_Password}"
|
||||
_saveaccountconf_mutable ISPC_Api "${ISPC_Api}"
|
||||
_saveaccountconf_mutable ISPC_Api_Insecure "${ISPC_Api_Insecure}"
|
||||
# Set whether curl should use secure or insecure mode
|
||||
export HTTPS_INSECURE="${ISPC_Api_Insecure}"
|
||||
fi
|
||||
|
||||
@@ -5,51 +5,81 @@
|
||||
# Environment variables:
|
||||
#
|
||||
# - $KAS_Login (Kasserver API login name)
|
||||
# - $KAS_Authtype (Kasserver API auth type. Default: sha1)
|
||||
# - $KAS_Authtype (Kasserver API auth type. Default: plain)
|
||||
# - $KAS_Authdata (Kasserver API auth data.)
|
||||
#
|
||||
# Author: Martin Kammerlander, Phlegx Systems OG <martin.kammerlander@phlegx.com>
|
||||
# Updated by: Marc-Oliver Lange <git@die-lang.es>
|
||||
# Credits: Inspired by dns_he.sh. Thanks a lot man!
|
||||
# Git repo: https://github.com/phlegx/acme.sh
|
||||
# TODO: Better Error handling
|
||||
# Last update: squared GmbH <github@squaredgmbh.de>
|
||||
# Credits:
|
||||
# - dns_he.sh. Thanks a lot man!
|
||||
# - Martin Kammerlander, Phlegx Systems OG <martin.kammerlander@phlegx.com>
|
||||
# - Marc-Oliver Lange <git@die-lang.es>
|
||||
# - https://github.com/o1oo11oo/kasapi.sh
|
||||
########################################################################
|
||||
KAS_Api="https://kasapi.kasserver.com/dokumentation/formular.php"
|
||||
KAS_Api_GET="$(_get "https://kasapi.kasserver.com/soap/wsdl/KasApi.wsdl")"
|
||||
KAS_Api="$(echo "$KAS_Api_GET" | tr -d ' ' | grep -i "<soap:addresslocation=" | sed "s/='/\n/g" | grep -i "http" | sed "s/'\/>//g")"
|
||||
_info "[KAS] -> API URL $KAS_Api"
|
||||
|
||||
KAS_Auth_GET="$(_get "https://kasapi.kasserver.com/soap/wsdl/KasAuth.wsdl")"
|
||||
KAS_Auth="$(echo "$KAS_Auth_GET" | tr -d ' ' | grep -i "<soap:addresslocation=" | sed "s/='/\n/g" | grep -i "http" | sed "s/'\/>//g")"
|
||||
_info "[KAS] -> AUTH URL $KAS_Auth"
|
||||
|
||||
KAS_default_ratelimit=5 # TODO - Every response delivers a ratelimit (seconds) where KASAPI is blocking a request.
|
||||
|
||||
######## Public functions #####################
|
||||
dns_kas_add() {
|
||||
_fulldomain=$1
|
||||
_txtvalue=$2
|
||||
_info "Using DNS-01 All-inkl/Kasserver hook"
|
||||
_info "Adding $_fulldomain DNS TXT entry on All-inkl/Kasserver"
|
||||
_info "Check and Save Props"
|
||||
|
||||
_info "[KAS] -> Using DNS-01 All-inkl/Kasserver hook"
|
||||
_info "[KAS] -> Check and Save Props"
|
||||
_check_and_save
|
||||
_info "Checking Zone and Record_Name"
|
||||
|
||||
_info "[KAS] -> Adding $_fulldomain DNS TXT entry on all-inkl.com/Kasserver"
|
||||
_info "[KAS] -> Retriving Credential Token"
|
||||
_get_credential_token
|
||||
|
||||
_info "[KAS] -> Checking Zone and Record_Name"
|
||||
_get_zone_and_record_name "$_fulldomain"
|
||||
_info "Getting Record ID"
|
||||
|
||||
_info "[KAS] -> Checking for existing Record entries"
|
||||
_get_record_id
|
||||
|
||||
_info "Creating TXT DNS record"
|
||||
params="?kas_login=$KAS_Login"
|
||||
params="$params&kas_auth_type=$KAS_Authtype"
|
||||
params="$params&kas_auth_data=$KAS_Authdata"
|
||||
params="$params&var1=record_name"
|
||||
params="$params&wert1=$_record_name"
|
||||
params="$params&var2=record_type"
|
||||
params="$params&wert2=TXT"
|
||||
params="$params&var3=record_data"
|
||||
params="$params&wert3=$_txtvalue"
|
||||
params="$params&var4=record_aux"
|
||||
params="$params&wert4=0"
|
||||
params="$params&kas_action=add_dns_settings"
|
||||
params="$params&var5=zone_host"
|
||||
params="$params&wert5=$_zone"
|
||||
_debug2 "Wait for 10 seconds by default before calling KAS API."
|
||||
_sleep 10
|
||||
response="$(_get "$KAS_Api$params")"
|
||||
_debug2 "response" "$response"
|
||||
# If there is a record_id, delete the entry
|
||||
if [ -n "$_record_id" ]; then
|
||||
_info "[KAS] -> Existing records found. Now deleting old entries"
|
||||
for i in $_record_id; do
|
||||
_delete_RecordByID "$i"
|
||||
done
|
||||
else
|
||||
_info "[KAS] -> No record found."
|
||||
fi
|
||||
|
||||
if ! _contains "$response" "TRUE"; then
|
||||
_err "An unkown error occurred, please check manually."
|
||||
_info "[KAS] -> Creating TXT DNS record"
|
||||
action="add_dns_settings"
|
||||
kasReqParam="\"record_name\":\"$_record_name\""
|
||||
kasReqParam="$kasReqParam,\"record_type\":\"TXT\""
|
||||
kasReqParam="$kasReqParam,\"record_data\":\"$_txtvalue\""
|
||||
kasReqParam="$kasReqParam,\"record_aux\":\"0\""
|
||||
kasReqParam="$kasReqParam,\"zone_host\":\"$_zone\""
|
||||
response="$(_callAPI "$action" "$kasReqParam")"
|
||||
_debug2 "[KAS] -> Response" "$response"
|
||||
|
||||
if [ -z "$response" ]; then
|
||||
_info "[KAS] -> Response was empty, please check manually."
|
||||
return 1
|
||||
elif _contains "$response" "<SOAP-ENV:Fault>"; then
|
||||
faultstring="$(echo "$response" | tr -d '\n\r' | sed "s/<faultstring>/\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
|
||||
case "${faultstring}" in
|
||||
"record_already_exists")
|
||||
_info "[KAS] -> The record already exists, which must not be a problem. Please check manually."
|
||||
;;
|
||||
*)
|
||||
_err "[KAS] -> An error =>$faultstring<= occurred, please check manually."
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
elif ! _contains "$response" "<item><key xsi:type=\"xsd:string\">ReturnString</key><value xsi:type=\"xsd:string\">TRUE</value></item>"; then
|
||||
_err "[KAS] -> An unknown error occurred, please check manually."
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
@@ -58,45 +88,62 @@ dns_kas_add() {
|
||||
dns_kas_rm() {
|
||||
_fulldomain=$1
|
||||
_txtvalue=$2
|
||||
_info "Using DNS-01 All-inkl/Kasserver hook"
|
||||
_info "Cleaning up after All-inkl/Kasserver hook"
|
||||
_info "Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver"
|
||||
|
||||
_info "Check and Save Props"
|
||||
_info "[KAS] -> Using DNS-01 All-inkl/Kasserver hook"
|
||||
_info "[KAS] -> Check and Save Props"
|
||||
_check_and_save
|
||||
_info "Checking Zone and Record_Name"
|
||||
|
||||
_info "[KAS] -> Cleaning up after All-inkl/Kasserver hook"
|
||||
_info "[KAS] -> Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver"
|
||||
_info "[KAS] -> Retriving Credential Token"
|
||||
_get_credential_token
|
||||
|
||||
_info "[KAS] -> Checking Zone and Record_Name"
|
||||
_get_zone_and_record_name "$_fulldomain"
|
||||
_info "Getting Record ID"
|
||||
|
||||
_info "[KAS] -> Getting Record ID"
|
||||
_get_record_id
|
||||
|
||||
_info "[KAS] -> Removing entries with ID: $_record_id"
|
||||
# If there is a record_id, delete the entry
|
||||
if [ -n "$_record_id" ]; then
|
||||
params="?kas_login=$KAS_Login"
|
||||
params="$params&kas_auth_type=$KAS_Authtype"
|
||||
params="$params&kas_auth_data=$KAS_Authdata"
|
||||
params="$params&kas_action=delete_dns_settings"
|
||||
|
||||
for i in $_record_id; do
|
||||
params2="$params&var1=record_id"
|
||||
params2="$params2&wert1=$i"
|
||||
_debug2 "Wait for 10 seconds by default before calling KAS API."
|
||||
_sleep 10
|
||||
response="$(_get "$KAS_Api$params2")"
|
||||
_debug2 "response" "$response"
|
||||
if ! _contains "$response" "TRUE"; then
|
||||
_err "Either the txt record is not found or another error occurred, please check manually."
|
||||
return 1
|
||||
fi
|
||||
_delete_RecordByID "$i"
|
||||
done
|
||||
else # Cannot delete or unkown error
|
||||
_err "No record_id found that can be deleted. Please check manually."
|
||||
return 1
|
||||
_info "[KAS] -> No record_id found that can be deleted. Please check manually."
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
########################## PRIVATE FUNCTIONS ###########################
|
||||
# Delete Record ID
|
||||
_delete_RecordByID() {
|
||||
recId=$1
|
||||
action="delete_dns_settings"
|
||||
kasReqParam="\"record_id\":\"$recId\""
|
||||
response="$(_callAPI "$action" "$kasReqParam")"
|
||||
_debug2 "[KAS] -> Response" "$response"
|
||||
|
||||
if [ -z "$response" ]; then
|
||||
_info "[KAS] -> Response was empty, please check manually."
|
||||
return 1
|
||||
elif _contains "$response" "<SOAP-ENV:Fault>"; then
|
||||
faultstring="$(echo "$response" | tr -d '\n\r' | sed "s/<faultstring>/\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
|
||||
case "${faultstring}" in
|
||||
"record_id_not_found")
|
||||
_info "[KAS] -> The record was not found, which perhaps is not a problem. Please check manually."
|
||||
;;
|
||||
*)
|
||||
_err "[KAS] -> An error =>$faultstring<= occurred, please check manually."
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
elif ! _contains "$response" "<item><key xsi:type=\"xsd:string\">ReturnString</key><value xsi:type=\"xsd:string\">TRUE</value></item>"; then
|
||||
_err "[KAS] -> An unknown error occurred, please check manually."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
# Checks for the ENV variables and saves them
|
||||
_check_and_save() {
|
||||
KAS_Login="${KAS_Login:-$(_readaccountconf_mutable KAS_Login)}"
|
||||
@@ -107,7 +154,7 @@ _check_and_save() {
|
||||
KAS_Login=
|
||||
KAS_Authtype=
|
||||
KAS_Authdata=
|
||||
_err "No auth details provided. Please set user credentials using the \$KAS_Login, \$KAS_Authtype, and \$KAS_Authdata environment variables."
|
||||
_err "[KAS] -> No auth details provided. Please set user credentials using the \$KAS_Login, \$KAS_Authtype, and \$KAS_Authdata environment variables."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable KAS_Login "$KAS_Login"
|
||||
@@ -119,50 +166,116 @@ _check_and_save() {
|
||||
# Gets back the base domain/zone and record name.
|
||||
# See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide
|
||||
_get_zone_and_record_name() {
|
||||
params="?kas_login=$KAS_Login"
|
||||
params="?kas_login=$KAS_Login"
|
||||
params="$params&kas_auth_type=$KAS_Authtype"
|
||||
params="$params&kas_auth_data=$KAS_Authdata"
|
||||
params="$params&kas_action=get_domains"
|
||||
action="get_domains"
|
||||
response="$(_callAPI "$action")"
|
||||
_debug2 "[KAS] -> Response" "$response"
|
||||
|
||||
_debug2 "Wait for 10 seconds by default before calling KAS API."
|
||||
_sleep 10
|
||||
response="$(_get "$KAS_Api$params")"
|
||||
_debug2 "response" "$response"
|
||||
_zonen="$(echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "domain_name" | tr '<' '\n' | grep "domain_name" | sed "s/domain_name>=>//g")"
|
||||
_domain="$1"
|
||||
_temp_domain="$(echo "$1" | sed 's/\.$//')"
|
||||
_rootzone="$_domain"
|
||||
for i in $_zonen; do
|
||||
l1=${#_rootzone}
|
||||
if [ -z "$response" ]; then
|
||||
_info "[KAS] -> Response was empty, please check manually."
|
||||
return 1
|
||||
elif _contains "$response" "<SOAP-ENV:Fault>"; then
|
||||
faultstring="$(echo "$response" | tr -d '\n\r' | sed "s/<faultstring>/\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
|
||||
_err "[KAS] -> Either no domains were found or another error =>$faultstring<= occurred, please check manually."
|
||||
return 1
|
||||
fi
|
||||
|
||||
zonen="$(echo "$response" | sed 's/<item>/\n/g' | sed -r 's/(.*<key xsi:type="xsd:string">domain_name<\/key><value xsi:type="xsd:string">)(.*)(<\/value.*)/\2/' | sed '/^</d')"
|
||||
domain="$1"
|
||||
temp_domain="$(echo "$1" | sed 's/\.$//')"
|
||||
rootzone="$domain"
|
||||
for i in $zonen; do
|
||||
l1=${#rootzone}
|
||||
l2=${#i}
|
||||
if _endswith "$_domain" "$i" && [ "$l1" -ge "$l2" ]; then
|
||||
_rootzone="$i"
|
||||
if _endswith "$domain" "$i" && [ "$l1" -ge "$l2" ]; then
|
||||
rootzone="$i"
|
||||
fi
|
||||
done
|
||||
_zone="${_rootzone}."
|
||||
_temp_record_name="$(echo "$_temp_domain" | sed "s/$_rootzone//g")"
|
||||
_record_name="$(echo "$_temp_record_name" | sed 's/\.$//')"
|
||||
_debug2 "Zone:" "$_zone"
|
||||
_debug2 "Domain:" "$_domain"
|
||||
_debug2 "Record_Name:" "$_record_name"
|
||||
_zone="${rootzone}."
|
||||
temp_record_name="$(echo "$temp_domain" | sed "s/$rootzone//g")"
|
||||
_record_name="$(echo "$temp_record_name" | sed 's/\.$//')"
|
||||
_debug "[KAS] -> Zone:" "$_zone"
|
||||
_debug "[KAS] -> Domain:" "$domain"
|
||||
_debug "[KAS] -> Record_Name:" "$_record_name"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Retrieve the DNS record ID
|
||||
_get_record_id() {
|
||||
params="?kas_login=$KAS_Login"
|
||||
params="$params&kas_auth_type=$KAS_Authtype"
|
||||
params="$params&kas_auth_data=$KAS_Authdata"
|
||||
params="$params&kas_action=get_dns_settings"
|
||||
params="$params&var1=zone_host"
|
||||
params="$params&wert1=$_zone"
|
||||
action="get_dns_settings"
|
||||
kasReqParam="\"zone_host\":\"$_zone\""
|
||||
response="$(_callAPI "$action" "$kasReqParam")"
|
||||
_debug2 "[KAS] -> Response" "$response"
|
||||
|
||||
_debug2 "Wait for 10 seconds by default before calling KAS API."
|
||||
_sleep 10
|
||||
response="$(_get "$KAS_Api$params")"
|
||||
_debug2 "response" "$response"
|
||||
_record_id="$(echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "=>$_record_name<" | grep '>TXT<' | tr '<' '\n' | grep record_id | sed "s/record_id>=>//g")"
|
||||
_debug2 _record_id "$_record_id"
|
||||
if [ -z "$response" ]; then
|
||||
_info "[KAS] -> Response was empty, please check manually."
|
||||
return 1
|
||||
elif _contains "$response" "<SOAP-ENV:Fault>"; then
|
||||
faultstring="$(echo "$response" | tr -d '\n\r' | sed "s/<faultstring>/\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
|
||||
_err "[KAS] -> Either no domains were found or another error =>$faultstring<= occurred, please check manually."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_record_id="$(echo "$response" | tr -d '\n\r' | sed "s/<item xsi:type=\"ns2:Map\">/\n/g" | grep -i "$_record_name" | grep -i ">TXT<" | sed "s/<item><key xsi:type=\"xsd:string\">record_id<\/key><value xsi:type=\"xsd:string\">/=>/g" | sed "s/<\/value><\/item>/\n/g" | grep "=>" | sed "s/=>//g")"
|
||||
_debug "[KAS] -> Record Id: " "$_record_id"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Retrieve credential token
|
||||
_get_credential_token() {
|
||||
baseParamAuth="\"kas_login\":\"$KAS_Login\""
|
||||
baseParamAuth="$baseParamAuth,\"kas_auth_type\":\"$KAS_Authtype\""
|
||||
baseParamAuth="$baseParamAuth,\"kas_auth_data\":\"$KAS_Authdata\""
|
||||
baseParamAuth="$baseParamAuth,\"session_lifetime\":600"
|
||||
baseParamAuth="$baseParamAuth,\"session_update_lifetime\":\"Y\""
|
||||
|
||||
data='<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:xmethodsKasApiAuthentication" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:KasAuth><Params xsi:type="xsd:string">{'
|
||||
data="$data$baseParamAuth}</Params></ns1:KasAuth></SOAP-ENV:Body></SOAP-ENV:Envelope>"
|
||||
|
||||
_debug "[KAS] -> Be friendly and wait $KAS_default_ratelimit seconds by default before calling KAS API."
|
||||
_sleep $KAS_default_ratelimit
|
||||
|
||||
contentType="text/xml"
|
||||
export _H1="SOAPAction: urn:xmethodsKasApiAuthentication#KasAuth"
|
||||
response="$(_post "$data" "$KAS_Auth" "" "POST" "$contentType")"
|
||||
_debug2 "[KAS] -> Response" "$response"
|
||||
|
||||
if [ -z "$response" ]; then
|
||||
_info "[KAS] -> Response was empty, please check manually."
|
||||
return 1
|
||||
elif _contains "$response" "<SOAP-ENV:Fault>"; then
|
||||
faultstring="$(echo "$response" | tr -d '\n\r' | sed "s/<faultstring>/\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
|
||||
_err "[KAS] -> Could not retrieve login token or antoher error =>$faultstring<= occurred, please check manually."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_credential_token="$(echo "$response" | tr '\n' ' ' | sed 's/.*return xsi:type="xsd:string">\(.*\)<\/return>/\1/' | sed 's/<\/ns1:KasAuthResponse\(.*\)Envelope>.*//')"
|
||||
_debug "[KAS] -> Credential Token: " "$_credential_token"
|
||||
return 0
|
||||
}
|
||||
|
||||
_callAPI() {
|
||||
kasaction=$1
|
||||
kasReqParams=$2
|
||||
|
||||
baseParamAuth="\"kas_login\":\"$KAS_Login\""
|
||||
baseParamAuth="$baseParamAuth,\"kas_auth_type\":\"session\""
|
||||
baseParamAuth="$baseParamAuth,\"kas_auth_data\":\"$_credential_token\""
|
||||
|
||||
data='<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:xmethodsKasApi" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:KasApi><Params xsi:type="xsd:string">{'
|
||||
data="$data$baseParamAuth,\"kas_action\":\"$kasaction\""
|
||||
if [ -n "$kasReqParams" ]; then
|
||||
data="$data,\"KasRequestParams\":{$kasReqParams}"
|
||||
fi
|
||||
data="$data}</Params></ns1:KasApi></SOAP-ENV:Body></SOAP-ENV:Envelope>"
|
||||
|
||||
_debug2 "[KAS] -> Request" "$data"
|
||||
|
||||
_debug "[KAS] -> Be friendly and wait $KAS_default_ratelimit seconds by default before calling KAS API."
|
||||
_sleep $KAS_default_ratelimit
|
||||
|
||||
contentType="text/xml"
|
||||
export _H1="SOAPAction: urn:xmethodsKasApi#KasApi"
|
||||
response="$(_post "$data" "$KAS_Api" "" "POST" "$contentType")"
|
||||
_debug2 "[KAS] -> Response" "$response"
|
||||
echo "$response"
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
############################################################
|
||||
# KingHost API support #
|
||||
# http://api.kinghost.net/doc/ #
|
||||
# https://api.kinghost.net/doc/ #
|
||||
# #
|
||||
# Author: Felipe Keller Braz <felipebraz@kinghost.com.br> #
|
||||
# Report Bugs here: https://github.com/kinghost/acme.sh #
|
||||
|
||||
147
dnsapi/dns_la.sh
Normal file
147
dnsapi/dns_la.sh
Normal file
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#LA_Id="test123"
|
||||
#LA_Key="d1j2fdo4dee3948"
|
||||
|
||||
LA_Api="https://api.dns.la/api"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: dns_la_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_la_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}"
|
||||
LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}"
|
||||
|
||||
if [ -z "$LA_Id" ] || [ -z "$LA_Key" ]; then
|
||||
LA_Id=""
|
||||
LA_Key=""
|
||||
_err "You didn't specify a dnsla api id and key yet."
|
||||
return 1
|
||||
fi
|
||||
|
||||
#save the api key and email to the account conf file.
|
||||
_saveaccountconf_mutable LA_Id "$LA_Id"
|
||||
_saveaccountconf_mutable LA_Key "$LA_Key"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
_debug _domain_id "$_domain_id"
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_info "Adding record"
|
||||
if _la_rest "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then
|
||||
if _contains "$response" '"resultid":'; then
|
||||
_info "Added, OK"
|
||||
return 0
|
||||
elif _contains "$response" '"code":532'; then
|
||||
_info "Already exists, OK"
|
||||
return 0
|
||||
else
|
||||
_err "Add txt record error."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
_err "Add txt record error."
|
||||
return 1
|
||||
|
||||
}
|
||||
|
||||
#fulldomain txtvalue
|
||||
dns_la_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}"
|
||||
LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
_debug _domain_id "$_domain_id"
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug "Getting txt records"
|
||||
if ! _la_rest "record.ashx?cmd=listn&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue"; then
|
||||
_err "Error"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _contains "$response" '"recordid":'; then
|
||||
_info "Don't need to remove."
|
||||
return 0
|
||||
fi
|
||||
|
||||
record_id=$(printf "%s" "$response" | grep '"recordid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n')
|
||||
_debug "record_id" "$record_id"
|
||||
if [ -z "$record_id" ]; then
|
||||
_err "Can not get record id to remove."
|
||||
return 1
|
||||
fi
|
||||
if ! _la_rest "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$record_id"; then
|
||||
_err "Delete record error."
|
||||
return 1
|
||||
fi
|
||||
_contains "$response" '"code":300'
|
||||
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
#_acme-challenge.www.domain.com
|
||||
#returns
|
||||
# _sub_domain=_acme-challenge.www
|
||||
# _domain=domain.com
|
||||
# _domain_id=sdjkglgdfewsdfg
|
||||
_get_root() {
|
||||
domain=$1
|
||||
i=1
|
||||
p=1
|
||||
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
if [ -z "$h" ]; then
|
||||
#not valid
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _la_rest "domain.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domain=$h"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" '"domainid":'; then
|
||||
_domain_id=$(printf "%s" "$response" | grep '"domainid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n')
|
||||
if [ "$_domain_id" ]; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain="$h"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
p="$i"
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
#Usage: URI
|
||||
_la_rest() {
|
||||
url="$LA_Api/$1"
|
||||
_debug "$url"
|
||||
|
||||
if ! response="$(_get "$url" | tr -d ' ' | tr "}" ",")"; then
|
||||
_err "Error: $url"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
#Author: Rolph Haspers <r.haspers@global.leaseweb.com>
|
||||
#Utilize leaseweb.com API to finish dns-01 verifications.
|
||||
#Requires a Leaseweb API Key (export LSW_Key="Your Key")
|
||||
#See http://developer.leaseweb.com for more information.
|
||||
#See https://developer.leaseweb.com for more information.
|
||||
######## Public functions #####################
|
||||
|
||||
LSW_API="https://api.leaseweb.com/hosting/v2/domains/"
|
||||
|
||||
@@ -163,6 +163,7 @@ _retrieve_miab_env() {
|
||||
_saveaccountconf_mutable MIAB_Username "$MIAB_Username"
|
||||
_saveaccountconf_mutable MIAB_Password "$MIAB_Password"
|
||||
_saveaccountconf_mutable MIAB_Server "$MIAB_Server"
|
||||
return 0
|
||||
}
|
||||
|
||||
#Useage: _miab_rest "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" "custom/_acme-challenge.www.domain.com/txt "POST"
|
||||
|
||||
@@ -150,7 +150,7 @@ _get_root() {
|
||||
_mydnsjp_retrieve_domain() {
|
||||
_debug "Login to MyDNS.JP"
|
||||
|
||||
response="$(_post "masterid=$MYDNSJP_MasterID&masterpwd=$MYDNSJP_Password" "$MYDNSJP_API/?MENU=100")"
|
||||
response="$(_post "MENU=100&masterid=$MYDNSJP_MasterID&masterpwd=$MYDNSJP_Password" "$MYDNSJP_API/members/")"
|
||||
cookie="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2)"
|
||||
|
||||
# If cookies is not empty then logon successful
|
||||
@@ -159,22 +159,8 @@ _mydnsjp_retrieve_domain() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "Retrieve DOMAIN INFO page"
|
||||
|
||||
export _H1="Cookie:${cookie}"
|
||||
|
||||
response="$(_get "$MYDNSJP_API/?MENU=300")"
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "Fail to retrieve DOMAIN INFO."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_root_domain=$(echo "$response" | grep "DNSINFO\[domainname\]" | sed 's/^.*value="\([^"]*\)".*/\1/')
|
||||
|
||||
# Logout
|
||||
response="$(_get "$MYDNSJP_API/?MENU=090")"
|
||||
|
||||
_debug _root_domain "$_root_domain"
|
||||
|
||||
if [ -z "$_root_domain" ]; then
|
||||
|
||||
@@ -82,7 +82,7 @@ _get_root() {
|
||||
_debug "Failed domain lookup via domains.getList api call. Trying domain lookup via domains.dns.getHosts api."
|
||||
# The above "getList" api will only return hosts *owned* by the calling user. However, if the calling
|
||||
# user is not the owner, but still has administrative rights, we must query the getHosts api directly.
|
||||
# See this comment and the official namecheap response: http://disq.us/p/1q6v9x9
|
||||
# See this comment and the official namecheap response: https://disq.us/p/1q6v9x9
|
||||
if ! _get_root_by_getHosts "$fulldomain"; then
|
||||
return 1
|
||||
fi
|
||||
@@ -259,7 +259,7 @@ _set_namecheap_TXT() {
|
||||
_debug hosts "$hosts"
|
||||
|
||||
if [ -z "$hosts" ]; then
|
||||
_error "Hosts not found"
|
||||
_err "Hosts not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -313,7 +313,7 @@ _del_namecheap_TXT() {
|
||||
_debug hosts "$hosts"
|
||||
|
||||
if [ -z "$hosts" ]; then
|
||||
_error "Hosts not found"
|
||||
_err "Hosts not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ _get_root() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "<domain>$host"; then
|
||||
if _contains "$response" ">$host</domain>"; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain="$host"
|
||||
return 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#NederHost_Key="sdfgikogfdfghjklkjhgfcdcfghjk"
|
||||
#NederHost_Key="sdfgikogfdfghjklkjhgfcdcfghj"
|
||||
|
||||
NederHost_Api="https://api.nederhost.nl/dns/v1"
|
||||
|
||||
@@ -112,12 +112,8 @@ _nederhost_rest() {
|
||||
export _H1="Authorization: Bearer $NederHost_Key"
|
||||
export _H2="Content-Type: application/json"
|
||||
|
||||
if [ "$m" != "GET" ]; then
|
||||
_debug data "$data"
|
||||
response="$(_post "$data" "$NederHost_Api/$ep" "" "$m")"
|
||||
else
|
||||
response="$(_get "$NederHost_Api/$ep")"
|
||||
fi
|
||||
_debug data "$data"
|
||||
response="$(_post "$data" "$NederHost_Api/$ep" "" "$m")"
|
||||
|
||||
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
|
||||
_debug "http response code $_code"
|
||||
|
||||
@@ -18,15 +18,15 @@ dns_netlify_add() {
|
||||
NETLIFY_ACCESS_TOKEN=""
|
||||
_err "Please specify your Netlify Access Token and try again."
|
||||
return 1
|
||||
else
|
||||
_saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN"
|
||||
fi
|
||||
|
||||
_info "Using Netlify"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
_saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN"
|
||||
|
||||
if ! _get_root "$fulldomain" "$accesstoken"; then
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
@@ -62,9 +62,9 @@ dns_netlify_rm() {
|
||||
_debug txtdomain "$txtdomain"
|
||||
_debug txt "$txt"
|
||||
|
||||
_saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN"
|
||||
NETLIFY_ACCESS_TOKEN="${NETLIFY_ACCESS_TOKEN:-$(_readaccountconf_mutable NETLIFY_ACCESS_TOKEN)}"
|
||||
|
||||
if ! _get_root "$txtdomain" "$accesstoken"; then
|
||||
if ! _get_root "$txtdomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -159,7 +159,7 @@ _oci_config() {
|
||||
fi
|
||||
|
||||
if [ "$(printf "%s\n" "$OCI_CLI_KEY" | wc -l)" -eq 1 ]; then
|
||||
OCI_CLI_KEY=$(printf "%s" "$OCI_CLI_KEY" | _dbase64 multiline)
|
||||
OCI_CLI_KEY=$(printf "%s" "$OCI_CLI_KEY" | _dbase64)
|
||||
fi
|
||||
|
||||
return 0
|
||||
@@ -265,6 +265,7 @@ _signed_request() {
|
||||
_response="$(_get "https://${_sig_host}${_sig_target}")"
|
||||
elif [ "$_curl_method" = "PATCH" ]; then
|
||||
export _H1="$_date_header"
|
||||
# shellcheck disable=SC2090
|
||||
export _H2="$_sig_body_sha256"
|
||||
export _H3="$_sig_body_type"
|
||||
export _H4="$_sig_body_length"
|
||||
|
||||
@@ -137,7 +137,7 @@ _get_root() {
|
||||
domain=$1
|
||||
i=2
|
||||
p=1
|
||||
if _opns_rest "GET" "/domain/get"; then
|
||||
if _opns_rest "GET" "/domain/searchMasterDomain"; then
|
||||
_domain_response="$response"
|
||||
else
|
||||
return 1
|
||||
@@ -150,7 +150,7 @@ _get_root() {
|
||||
return 1
|
||||
fi
|
||||
_debug h "$h"
|
||||
id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":{\"[^\"]*\":{[^}]*}},\"transferkeyalgo\":{[^{]*{[^{]*{[^{]*{[^{]*{[^{]*{[^{]*{[^{]*{[^}]*}},\"transferkey\":\"[^\"]*\"(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2)
|
||||
id=$(echo "$_domain_response" | _egrep_o "\"uuid\":\"[a-z0-9\-]*\",\"enabled\":\"1\",\"type\":\"master\",\"domainname\":\"${h}\"" | cut -d ':' -f 2 | cut -d '"' -f 2)
|
||||
if [ -n "$id" ]; then
|
||||
_debug id "$id"
|
||||
_host=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
|
||||
@@ -92,7 +92,7 @@ _initAuth() {
|
||||
|
||||
if [ "$OVH_AK" != "$(_readaccountconf OVH_AK)" ]; then
|
||||
_info "It seems that your ovh key is changed, let's clear consumer key first."
|
||||
_clearaccountconf OVH_CK
|
||||
_clearaccountconf_mutable OVH_CK
|
||||
fi
|
||||
_saveaccountconf_mutable OVH_AK "$OVH_AK"
|
||||
_saveaccountconf_mutable OVH_AS "$OVH_AS"
|
||||
@@ -118,13 +118,14 @@ _initAuth() {
|
||||
#return and wait for retry.
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable OVH_CK "$OVH_CK"
|
||||
|
||||
_info "Checking authentication"
|
||||
|
||||
if ! _ovh_rest GET "domain" || _contains "$response" "INVALID_CREDENTIAL" || _contains "$response" "NOT_CREDENTIAL"; then
|
||||
_err "The consumer key is invalid: $OVH_CK"
|
||||
_err "Please retry to create a new one."
|
||||
_clearaccountconf OVH_CK
|
||||
_clearaccountconf_mutable OVH_CK
|
||||
return 1
|
||||
fi
|
||||
_info "Consumer key is ok."
|
||||
@@ -235,8 +236,7 @@ _ovh_authentication() {
|
||||
_secure_debug consumerKey "$consumerKey"
|
||||
|
||||
OVH_CK="$consumerKey"
|
||||
_saveaccountconf OVH_CK "$OVH_CK"
|
||||
|
||||
_saveaccountconf_mutable OVH_CK "$OVH_CK"
|
||||
_info "Please open this link to do authentication: $(__green "$validationUrl")"
|
||||
|
||||
_info "Here is a guide for you: $(__green "$wiki")"
|
||||
|
||||
115
dnsapi/dns_rage4.sh
Executable file
115
dnsapi/dns_rage4.sh
Executable file
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
#RAGE4_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje"
|
||||
#
|
||||
#RAGE4_USERNAME="xxxx@sss.com"
|
||||
|
||||
RAGE4_Api="https://rage4.com/rapi/"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_rage4_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
unquotedtxtvalue=$(echo "$txtvalue" | tr -d \")
|
||||
|
||||
RAGE4_USERNAME="${RAGE4_USERNAME:-$(_readaccountconf_mutable RAGE4_USERNAME)}"
|
||||
RAGE4_TOKEN="${RAGE4_TOKEN:-$(_readaccountconf_mutable RAGE4_TOKEN)}"
|
||||
|
||||
if [ -z "$RAGE4_USERNAME" ] || [ -z "$RAGE4_TOKEN" ]; then
|
||||
RAGE4_USERNAME=""
|
||||
RAGE4_TOKEN=""
|
||||
_err "You didn't specify a Rage4 api token and username yet."
|
||||
return 1
|
||||
fi
|
||||
|
||||
#save the api key and email to the account conf file.
|
||||
_saveaccountconf_mutable RAGE4_USERNAME "$RAGE4_USERNAME"
|
||||
_saveaccountconf_mutable RAGE4_TOKEN "$RAGE4_TOKEN"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
_debug _domain_id "$_domain_id"
|
||||
|
||||
_rage4_rest "createrecord/?id=$_domain_id&name=$fulldomain&content=$unquotedtxtvalue&type=TXT&active=true&ttl=1"
|
||||
return 0
|
||||
}
|
||||
|
||||
#fulldomain txtvalue
|
||||
dns_rage4_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
RAGE4_USERNAME="${RAGE4_USERNAME:-$(_readaccountconf_mutable RAGE4_USERNAME)}"
|
||||
RAGE4_TOKEN="${RAGE4_TOKEN:-$(_readaccountconf_mutable RAGE4_TOKEN)}"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
_debug _domain_id "$_domain_id"
|
||||
|
||||
_debug "Getting txt records"
|
||||
_rage4_rest "getrecords/?id=${_domain_id}"
|
||||
|
||||
_record_id=$(echo "$response" | sed -rn 's/.*"id":([[:digit:]]+)[^\}]*'"$txtvalue"'.*/\1/p')
|
||||
_rage4_rest "deleterecord/?id=${_record_id}"
|
||||
return 0
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
#_acme-challenge.www.domain.com
|
||||
#returns
|
||||
# _domain=domain.com
|
||||
# _domain_id=sdjkglgdfewsdfg
|
||||
_get_root() {
|
||||
domain=$1
|
||||
|
||||
if ! _rage4_rest "getdomains"; then
|
||||
return 1
|
||||
fi
|
||||
_debug _get_root_domain "$domain"
|
||||
|
||||
for line in $(echo "$response" | tr '}' '\n'); do
|
||||
__domain=$(echo "$line" | sed -rn 's/.*"name":"([^"]*)",.*/\1/p')
|
||||
__domain_id=$(echo "$line" | sed -rn 's/.*"id":([^,]*),.*/\1/p')
|
||||
if [ "$domain" != "${domain%"$__domain"*}" ]; then
|
||||
_domain_id="$__domain_id"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$_domain_id" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_rage4_rest() {
|
||||
ep="$1"
|
||||
_debug "$ep"
|
||||
|
||||
username_trimmed=$(echo "$RAGE4_USERNAME" | tr -d '"')
|
||||
token_trimmed=$(echo "$RAGE4_TOKEN" | tr -d '"')
|
||||
auth=$(printf '%s:%s' "$username_trimmed" "$token_trimmed" | _base64)
|
||||
|
||||
export _H1="Content-Type: application/json"
|
||||
export _H2="Authorization: Basic $auth"
|
||||
|
||||
response="$(_get "$RAGE4_Api$ep")"
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error $ep"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
||||
@@ -92,10 +92,10 @@ _get_root() {
|
||||
domains_list=$(echo "${response}" | grep dname | sed -r "s/.*dname=\"([^\"]+)\".*/\\1/g")
|
||||
|
||||
for ITEM in ${domains_list}; do
|
||||
IDN_ITEM="$(_idn "${ITEM}")"
|
||||
IDN_ITEM=${ITEM}
|
||||
case "${domain}" in
|
||||
*${IDN_ITEM}*)
|
||||
_domain=${IDN_ITEM}
|
||||
_domain="$(_idn "${ITEM}")"
|
||||
_debug _domain "${_domain}"
|
||||
return 0
|
||||
;;
|
||||
|
||||
@@ -76,7 +76,7 @@ dns_selectel_rm() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
_record_seg="$(echo "$response" | _egrep_o "\"content\" *: *\"$txtvalue\"[^}]*}")"
|
||||
_record_seg="$(echo "$response" | _egrep_o "[^{]*\"content\" *: *\"$txtvalue\"[^}]*}")"
|
||||
_debug2 "_record_seg" "$_record_seg"
|
||||
if [ -z "$_record_seg" ]; then
|
||||
_err "can not find _record_seg"
|
||||
@@ -120,7 +120,7 @@ _get_root() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "\"name\": \"$h\","; then
|
||||
if _contains "$response" "\"name\" *: *\"$h\","; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain=$h
|
||||
_debug "Getting domain id for $h"
|
||||
|
||||
94
dnsapi/dns_selfhost.sh
Normal file
94
dnsapi/dns_selfhost.sh
Normal file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env sh
|
||||
#
|
||||
# Author: Marvin Edeler
|
||||
# Report Bugs here: https://github.com/Marvo2011/acme.sh/issues/1
|
||||
# Last Edit: 17.02.2022
|
||||
|
||||
dns_selfhost_add() {
|
||||
fulldomain=$1
|
||||
txt=$2
|
||||
_info "Calling acme-dns on selfhost"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txt"
|
||||
|
||||
SELFHOSTDNS_UPDATE_URL="https://selfhost.de/cgi-bin/api.pl"
|
||||
|
||||
# Get values, but don't save until we successfully validated
|
||||
SELFHOSTDNS_USERNAME="${SELFHOSTDNS_USERNAME:-$(_readaccountconf_mutable SELFHOSTDNS_USERNAME)}"
|
||||
SELFHOSTDNS_PASSWORD="${SELFHOSTDNS_PASSWORD:-$(_readaccountconf_mutable SELFHOSTDNS_PASSWORD)}"
|
||||
# These values are domain dependent, so read them from there
|
||||
SELFHOSTDNS_MAP="${SELFHOSTDNS_MAP:-$(_readdomainconf SELFHOSTDNS_MAP)}"
|
||||
# Selfhost api can't dynamically add TXT record,
|
||||
# so we have to store the last used RID of the domain to support a second RID for wildcard domains
|
||||
# (format: 'fulldomainA:lastRid fulldomainB:lastRid ...')
|
||||
SELFHOSTDNS_MAP_LAST_USED_INTERNAL=$(_readdomainconf SELFHOSTDNS_MAP_LAST_USED_INTERNAL)
|
||||
|
||||
if [ -z "${SELFHOSTDNS_USERNAME:-}" ] || [ -z "${SELFHOSTDNS_PASSWORD:-}" ]; then
|
||||
_err "SELFHOSTDNS_USERNAME and SELFHOSTDNS_PASSWORD must be set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# get the domain entry from SELFHOSTDNS_MAP
|
||||
# only match full domains (at the beginning of the string or with a leading whitespace),
|
||||
# e.g. don't match mytest.example.com or sub.test.example.com for test.example.com
|
||||
# if the domain is defined multiple times only the last occurance will be matched
|
||||
mapEntry=$(echo "$SELFHOSTDNS_MAP" | sed -n -E "s/(^|^.*[[:space:]])($fulldomain)(:[[:digit:]]+)([:]?[[:digit:]]*)(.*)/\2\3\4/p")
|
||||
_debug2 mapEntry "$mapEntry"
|
||||
if test -z "$mapEntry"; then
|
||||
_err "SELFHOSTDNS_MAP must contain the fulldomain incl. prefix and at least one RID"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# get the RIDs from the map entry
|
||||
rid1=$(echo "$mapEntry" | cut -d: -f2)
|
||||
rid2=$(echo "$mapEntry" | cut -d: -f3)
|
||||
|
||||
# read last used rid domain
|
||||
lastUsedRidForDomainEntry=$(echo "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL" | sed -n -E "s/(^|^.*[[:space:]])($fulldomain:[[:digit:]]+)(.*)/\2/p")
|
||||
_debug2 lastUsedRidForDomainEntry "$lastUsedRidForDomainEntry"
|
||||
lastUsedRidForDomain=$(echo "$lastUsedRidForDomainEntry" | cut -d: -f2)
|
||||
|
||||
rid="$rid1"
|
||||
if [ "$lastUsedRidForDomain" = "$rid" ] && ! test -z "$rid2"; then
|
||||
rid="$rid2"
|
||||
fi
|
||||
|
||||
_info "Trying to add $txt on selfhost for rid: $rid"
|
||||
|
||||
data="?username=$SELFHOSTDNS_USERNAME&password=$SELFHOSTDNS_PASSWORD&rid=$rid&content=$txt"
|
||||
response="$(_get "$SELFHOSTDNS_UPDATE_URL$data")"
|
||||
|
||||
if ! echo "$response" | grep "200 OK" >/dev/null; then
|
||||
_err "Invalid response of acme-dns for selfhost"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# write last used rid domain
|
||||
newLastUsedRidForDomainEntry="$fulldomain:$rid"
|
||||
if ! test -z "$lastUsedRidForDomainEntry"; then
|
||||
# replace last used rid entry for domain
|
||||
SELFHOSTDNS_MAP_LAST_USED_INTERNAL=$(echo "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL" | sed -n -E "s/$lastUsedRidForDomainEntry/$newLastUsedRidForDomainEntry/p")
|
||||
else
|
||||
# add last used rid entry for domain
|
||||
if test -z "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL"; then
|
||||
SELFHOSTDNS_MAP_LAST_USED_INTERNAL="$newLastUsedRidForDomainEntry"
|
||||
else
|
||||
SELFHOSTDNS_MAP_LAST_USED_INTERNAL="$SELFHOSTDNS_MAP_LAST_USED_INTERNAL $newLastUsedRidForDomainEntry"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Now that we know the values are good, save them
|
||||
_saveaccountconf_mutable SELFHOSTDNS_USERNAME "$SELFHOSTDNS_USERNAME"
|
||||
_saveaccountconf_mutable SELFHOSTDNS_PASSWORD "$SELFHOSTDNS_PASSWORD"
|
||||
# These values are domain dependent, so store them there
|
||||
_savedomainconf SELFHOSTDNS_MAP "$SELFHOSTDNS_MAP"
|
||||
_savedomainconf SELFHOSTDNS_MAP_LAST_USED_INTERNAL "$SELFHOSTDNS_MAP_LAST_USED_INTERNAL"
|
||||
}
|
||||
|
||||
dns_selfhost_rm() {
|
||||
fulldomain=$1
|
||||
txt=$2
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txt"
|
||||
_info "Creating and removing of records is not supported by selfhost API, will not delete anything."
|
||||
}
|
||||
@@ -53,7 +53,7 @@ dns_servercow_add() {
|
||||
if printf -- "%s" "$response" | grep "{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\"" >/dev/null; then
|
||||
_info "A txt record with the same name already exists."
|
||||
# trim the string on the left
|
||||
txtvalue_old=${response#*{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"}
|
||||
txtvalue_old=${response#*{\"name\":\""$_sub_domain"\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"}
|
||||
# trim the string on the right
|
||||
txtvalue_old=${txtvalue_old%%\"*}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
TRANSIP_Api_Url="https://api.transip.nl/v6"
|
||||
TRANSIP_Token_Read_Only="false"
|
||||
TRANSIP_Token_Global_Key="false"
|
||||
TRANSIP_Token_Expiration="30 minutes"
|
||||
# You can't reuse a label token, so we leave this empty normally
|
||||
TRANSIP_Token_Label=""
|
||||
@@ -96,7 +95,11 @@ _transip_get_token() {
|
||||
nonce=$(echo "TRANSIP$(_time)" | _digest sha1 hex | cut -c 1-32)
|
||||
_debug nonce "$nonce"
|
||||
|
||||
data="{\"login\":\"${TRANSIP_Username}\",\"nonce\":\"${nonce}\",\"read_only\":\"${TRANSIP_Token_Read_Only}\",\"expiration_time\":\"${TRANSIP_Token_Expiration}\",\"label\":\"${TRANSIP_Token_Label}\",\"global_key\":\"${TRANSIP_Token_Global_Key}\"}"
|
||||
# make IP whitelisting configurable
|
||||
TRANSIP_Token_Global_Key="${TRANSIP_Token_Global_Key:-$(_readaccountconf_mutable TRANSIP_Token_Global_Key)}"
|
||||
_saveaccountconf_mutable TRANSIP_Token_Global_Key "$TRANSIP_Token_Global_Key"
|
||||
|
||||
data="{\"login\":\"${TRANSIP_Username}\",\"nonce\":\"${nonce}\",\"read_only\":\"${TRANSIP_Token_Read_Only}\",\"expiration_time\":\"${TRANSIP_Token_Expiration}\",\"label\":\"${TRANSIP_Token_Label}\",\"global_key\":\"${TRANSIP_Token_Global_Key:-false}\"}"
|
||||
_debug data "$data"
|
||||
|
||||
#_signature=$(printf "%s" "$data" | openssl dgst -sha512 -sign "$TRANSIP_Key_File" | _base64)
|
||||
@@ -139,6 +142,18 @@ _transip_setup() {
|
||||
_saveaccountconf_mutable TRANSIP_Username "$TRANSIP_Username"
|
||||
_saveaccountconf_mutable TRANSIP_Key_File "$TRANSIP_Key_File"
|
||||
|
||||
# download key file if it's an URL
|
||||
if _startswith "$TRANSIP_Key_File" "http"; then
|
||||
_debug "download transip key file"
|
||||
TRANSIP_Key_URL=$TRANSIP_Key_File
|
||||
TRANSIP_Key_File="$(_mktemp)"
|
||||
chmod 600 "$TRANSIP_Key_File"
|
||||
if ! _get "$TRANSIP_Key_URL" >"$TRANSIP_Key_File"; then
|
||||
_err "Error getting key file from : $TRANSIP_Key_URL"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f "$TRANSIP_Key_File" ]; then
|
||||
if ! grep "BEGIN PRIVATE KEY" "$TRANSIP_Key_File" >/dev/null 2>&1; then
|
||||
_err "Key file doesn't seem to be a valid key: ${TRANSIP_Key_File}"
|
||||
@@ -156,6 +171,12 @@ _transip_setup() {
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${TRANSIP_Key_URL}" ]; then
|
||||
_debug "delete transip key file"
|
||||
rm "${TRANSIP_Key_File}"
|
||||
TRANSIP_Key_File=$TRANSIP_Key_URL
|
||||
fi
|
||||
|
||||
_get_root "$fulldomain" || return 1
|
||||
|
||||
return 0
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
#
|
||||
# ULTRA_PWD="some_password_goes_here"
|
||||
|
||||
ULTRA_API="https://restapi.ultradns.com/v2/"
|
||||
ULTRA_API="https://api.ultradns.com/v3/"
|
||||
ULTRA_AUTH_API="https://api.ultradns.com/v2/"
|
||||
|
||||
#Usage: add _acme-challenge.www.domain.com "some_long_string_of_characters_go_here_from_lets_encrypt"
|
||||
dns_ultra_add() {
|
||||
@@ -121,7 +122,7 @@ _get_root() {
|
||||
return 1
|
||||
fi
|
||||
if _contains "${response}" "${h}." >/dev/null; then
|
||||
_domain_id=$(echo "$response" | _egrep_o "${h}")
|
||||
_domain_id=$(echo "$response" | _egrep_o "${h}" | head -1)
|
||||
if [ "$_domain_id" ]; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain="${h}"
|
||||
@@ -142,23 +143,25 @@ _ultra_rest() {
|
||||
ep="$2"
|
||||
data="$3"
|
||||
_debug "$ep"
|
||||
_debug TOKEN "${AUTH_TOKEN}"
|
||||
if [ -z "$AUTH_TOKEN" ]; then
|
||||
_ultra_login
|
||||
fi
|
||||
_debug TOKEN "$AUTH_TOKEN"
|
||||
|
||||
_ultra_login
|
||||
export _H1="Content-Type: application/json"
|
||||
export _H2="Authorization: Bearer ${AUTH_TOKEN}"
|
||||
export _H2="Authorization: Bearer $AUTH_TOKEN"
|
||||
|
||||
if [ "$m" != "GET" ]; then
|
||||
_debug data "${data}"
|
||||
response="$(_post "${data}" "${ULTRA_API}"/"${ep}" "" "${m}")"
|
||||
_debug data "$data"
|
||||
response="$(_post "$data" "$ULTRA_API$ep" "" "$m")"
|
||||
else
|
||||
response="$(_get "$ULTRA_API/$ep")"
|
||||
response="$(_get "$ULTRA_API$ep")"
|
||||
fi
|
||||
}
|
||||
|
||||
_ultra_login() {
|
||||
export _H1=""
|
||||
export _H2=""
|
||||
AUTH_TOKEN=$(_post "grant_type=password&username=${ULTRA_USR}&password=${ULTRA_PWD}" "${ULTRA_API}authorization/token" | cut -d, -f3 | cut -d\" -f4)
|
||||
AUTH_TOKEN=$(_post "grant_type=password&username=${ULTRA_USR}&password=${ULTRA_PWD}" "${ULTRA_AUTH_API}authorization/token" | cut -d, -f3 | cut -d\" -f4)
|
||||
export AUTH_TOKEN
|
||||
}
|
||||
|
||||
142
dnsapi/dns_vercel.sh
Normal file
142
dnsapi/dns_vercel.sh
Normal file
@@ -0,0 +1,142 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Vercel DNS API
|
||||
#
|
||||
# This is your API token which can be acquired on the account page.
|
||||
# https://vercel.com/account/tokens
|
||||
#
|
||||
# VERCEL_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje"
|
||||
|
||||
VERCEL_API="https://api.vercel.com"
|
||||
|
||||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_vercel_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
VERCEL_TOKEN="${VERCEL_TOKEN:-$(_readaccountconf_mutable VERCEL_TOKEN)}"
|
||||
|
||||
if [ -z "$VERCEL_TOKEN" ]; then
|
||||
VERCEL_TOKEN=""
|
||||
_err "You have not set the Vercel API token yet."
|
||||
_err "Please visit https://vercel.com/account/tokens to generate it."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable VERCEL_TOKEN "$VERCEL_TOKEN"
|
||||
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_info "Adding record"
|
||||
if _vercel_rest POST "v2/domains/$_domain/records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\"}"; then
|
||||
if printf -- "%s" "$response" | grep "\"uid\":\"" >/dev/null; then
|
||||
_info "Added"
|
||||
return 0
|
||||
else
|
||||
_err "Unexpected response while adding text record."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
_err "Add txt record error."
|
||||
}
|
||||
|
||||
dns_vercel_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_vercel_rest GET "v2/domains/$_domain/records"
|
||||
|
||||
count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$_sub_domain\",[^{]*\"type\":\"TXT\"" | wc -l | tr -d " ")
|
||||
|
||||
if [ "$count" = "0" ]; then
|
||||
_info "Don't need to remove."
|
||||
else
|
||||
_record_id=$(printf "%s" "$response" | _egrep_o "\"id\":[^,]*,\"slug\":\"[^,]*\",\"name\":\"$_sub_domain\",[^{]*\"type\":\"TXT\",\"value\":\"$txtvalue\"" | cut -d: -f2 | cut -d, -f1 | tr -d '"')
|
||||
|
||||
if [ "$_record_id" ]; then
|
||||
echo "$_record_id" | while read -r item; do
|
||||
if _vercel_rest DELETE "v2/domains/$_domain/records/$item"; then
|
||||
_info "removed record" "$item"
|
||||
return 0
|
||||
else
|
||||
_err "failed to remove record" "$item"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
#_acme-challenge.www.domain.com
|
||||
#returns
|
||||
# _sub_domain=_acme-challenge.www
|
||||
# _domain=domain.com
|
||||
_get_root() {
|
||||
domain="$1"
|
||||
ep="$2"
|
||||
i=1
|
||||
p=1
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
if [ -z "$h" ]; then
|
||||
#not valid
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _vercel_rest GET "v4/domains/$h"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain=$h
|
||||
return 0
|
||||
fi
|
||||
p=$i
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
_vercel_rest() {
|
||||
m="$1"
|
||||
ep="$2"
|
||||
data="$3"
|
||||
|
||||
path="$VERCEL_API/$ep"
|
||||
|
||||
export _H1="Content-Type: application/json"
|
||||
export _H2="Authorization: Bearer $VERCEL_TOKEN"
|
||||
|
||||
if [ "$m" != "GET" ]; then
|
||||
_secure_debug2 data "$data"
|
||||
response="$(_post "$data" "$path" "" "$m")"
|
||||
else
|
||||
response="$(_get "$path")"
|
||||
fi
|
||||
_ret="$?"
|
||||
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
|
||||
_debug "http response code $_code"
|
||||
_secure_debug2 response "$response"
|
||||
if [ "$_ret" != "0" ]; then
|
||||
_err "error $ep"
|
||||
return 1
|
||||
fi
|
||||
|
||||
response="$(printf "%s" "$response" | _normalizeJson)"
|
||||
return 0
|
||||
}
|
||||
@@ -3,10 +3,10 @@
|
||||
#
|
||||
#VULTR_API_KEY=000011112222333344445555666677778888
|
||||
|
||||
VULTR_Api="https://api.vultr.com/v1"
|
||||
VULTR_Api="https://api.vultr.com/v2"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#
|
||||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_vultr_add() {
|
||||
fulldomain=$1
|
||||
@@ -31,14 +31,14 @@ dns_vultr_add() {
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug 'Getting txt records'
|
||||
_vultr_rest GET "dns/records?domain=$_domain"
|
||||
_vultr_rest GET "domains/$_domain/records"
|
||||
|
||||
if printf "%s\n" "$response" | grep -- "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then
|
||||
_err 'Error'
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _vultr_rest POST 'dns/create_record' "domain=$_domain&name=$_sub_domain&data=\"$txtvalue\"&type=TXT"; then
|
||||
if ! _vultr_rest POST "domains/$_domain/records" "{\"name\":\"$_sub_domain\",\"data\":\"$txtvalue\",\"type\":\"TXT\"}"; then
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
@@ -71,14 +71,14 @@ dns_vultr_rm() {
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug 'Getting txt records'
|
||||
_vultr_rest GET "dns/records?domain=$_domain"
|
||||
_vultr_rest GET "domains/$_domain/records"
|
||||
|
||||
if printf "%s\n" "$response" | grep -- "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then
|
||||
_err 'Error'
|
||||
return 1
|
||||
fi
|
||||
|
||||
_record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'RECORDID' | cut -d : -f 2)"
|
||||
_record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'id' | cut -d : -f 2)"
|
||||
_debug _record_id "$_record_id"
|
||||
if [ "$_record_id" ]; then
|
||||
_info "Successfully retrieved the record id for ACME challenge."
|
||||
@@ -87,7 +87,7 @@ dns_vultr_rm() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! _vultr_rest POST 'dns/delete_record' "domain=$_domain&RECORDID=$_record_id"; then
|
||||
if ! _vultr_rest DELETE "domains/$_domain/records/$_record_id"; then
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
@@ -112,11 +112,11 @@ _get_root() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _vultr_rest GET "dns/list"; then
|
||||
if ! _vultr_rest GET "domains"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if printf "%s\n" "$response" | grep '^\[.*\]' >/dev/null; then
|
||||
if printf "%s\n" "$response" | grep '^\{.*\}' >/dev/null; then
|
||||
if _contains "$response" "\"domain\":\"$_domain\""; then
|
||||
_sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")"
|
||||
return 0
|
||||
@@ -139,10 +139,10 @@ _vultr_rest() {
|
||||
data="$3"
|
||||
_debug "$ep"
|
||||
|
||||
api_key_trimmed=$(echo $VULTR_API_KEY | tr -d '"')
|
||||
api_key_trimmed=$(echo "$VULTR_API_KEY" | tr -d '"')
|
||||
|
||||
export _H1="Api-Key: $api_key_trimmed"
|
||||
export _H2='Content-Type: application/x-www-form-urlencoded'
|
||||
export _H1="Authorization: Bearer $api_key_trimmed"
|
||||
export _H2='Content-Type: application/json'
|
||||
|
||||
if [ "$m" != "GET" ]; then
|
||||
_debug data "$data"
|
||||
|
||||
@@ -12,7 +12,7 @@ RECORD=''
|
||||
|
||||
# Usage: dns_world4you_add <fqdn> <value>
|
||||
dns_world4you_add() {
|
||||
fqdn="$1"
|
||||
fqdn=$(echo "$1" | _lower_case)
|
||||
value="$2"
|
||||
_info "Using world4you to add record"
|
||||
_debug fulldomain "$fqdn"
|
||||
@@ -49,12 +49,12 @@ dns_world4you_add() {
|
||||
ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns" '' POST 'application/x-www-form-urlencoded')
|
||||
_resethttp
|
||||
|
||||
if _contains "$(_head_n 3 <"$HTTP_HEADER")" '302'; then
|
||||
if _contains "$(_head_n 1 <"$HTTP_HEADER")" '302'; then
|
||||
res=$(_get "$WORLD4YOU_API/$paketnr/dns")
|
||||
if _contains "$res" "successfully"; then
|
||||
return 0
|
||||
else
|
||||
msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "<h3[^>]*>[^<]" | sed 's/<[^>]*>\|^\s*//g')
|
||||
msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "<h3[^>]*>[^<]" | sed 's/<[^>]*>//g' | sed 's/^\s*//g')
|
||||
if [ "$msg" = '' ]; then
|
||||
_err "Unable to add record: Unknown error"
|
||||
echo "$ret" >'error-01.html'
|
||||
@@ -66,15 +66,15 @@ dns_world4you_add() {
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
_err "$(_head_n 3 <"$HTTP_HEADER")"
|
||||
_err "View $HTTP_HEADER for debugging"
|
||||
msg=$(echo "$ret" | grep '"form-error-message"' | sed 's/^.*<div class="form-error-message">\([^<]*\)<\/div>.*$/\1/')
|
||||
_err "Unable to add record: my.world4you.com: $msg"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Usage: dns_world4you_rm <fqdn> <value>
|
||||
dns_world4you_rm() {
|
||||
fqdn="$1"
|
||||
fqdn=$(echo "$1" | _lower_case)
|
||||
value="$2"
|
||||
_info "Using world4you to remove record"
|
||||
_debug fulldomain "$fqdn"
|
||||
@@ -113,12 +113,12 @@ dns_world4you_rm() {
|
||||
ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns/record/delete" '' POST 'application/x-www-form-urlencoded')
|
||||
_resethttp
|
||||
|
||||
if _contains "$(_head_n 3 <"$HTTP_HEADER")" '302'; then
|
||||
if _contains "$(_head_n 1 <"$HTTP_HEADER")" '302'; then
|
||||
res=$(_get "$WORLD4YOU_API/$paketnr/dns")
|
||||
if _contains "$res" "successfully"; then
|
||||
return 0
|
||||
else
|
||||
msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "<h3[^>]*>[^<]" | sed 's/<[^>]*>\|^\s*//g')
|
||||
msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "<h3[^>]*>[^<]" | sed 's/<[^>]*>//g' | sed 's/^\s*//g')
|
||||
if [ "$msg" = '' ]; then
|
||||
_err "Unable to remove record: Unknown error"
|
||||
echo "$ret" >'error-01.html'
|
||||
@@ -130,8 +130,8 @@ dns_world4you_rm() {
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
_err "$(_head_n 3 <"$HTTP_HEADER")"
|
||||
_err "View $HTTP_HEADER for debugging"
|
||||
msg=$(echo "$ret" | grep "form-error-message" | sed 's/^.*<div class="form-error-message">\([^<]*\)<\/div>.*$/\1/')
|
||||
_err "Unable to remove record: my.world4you.com: $msg"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -155,34 +155,47 @@ _login() {
|
||||
_saveaccountconf_mutable WORLD4YOU_USERNAME "$WORLD4YOU_USERNAME"
|
||||
_saveaccountconf_mutable WORLD4YOU_PASSWORD "$WORLD4YOU_PASSWORD"
|
||||
|
||||
_resethttp
|
||||
export ACME_HTTP_NO_REDIRECTS=1
|
||||
page=$(_get "$WORLD4YOU_API/login")
|
||||
_resethttp
|
||||
|
||||
if _contains "$(_head_n 1 <"$HTTP_HEADER")" '302'; then
|
||||
_info "Already logged in"
|
||||
_parse_sessid
|
||||
return 0
|
||||
fi
|
||||
|
||||
_info "Logging in..."
|
||||
|
||||
username="$WORLD4YOU_USERNAME"
|
||||
password="$WORLD4YOU_PASSWORD"
|
||||
csrf_token=$(_get "$WORLD4YOU_API/login" | grep '_csrf_token' | sed 's/^.*<input[^>]*value=\"\([^"]*\)\".*$/\1/')
|
||||
sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/')
|
||||
csrf_token=$(echo "$page" | grep '_csrf_token' | sed 's/^.*<input[^>]*value=\"\([^"]*\)\".*$/\1/')
|
||||
_parse_sessid
|
||||
|
||||
export _H1="Cookie: W4YSESSID=$sessid"
|
||||
export _H2="X-Requested-With: XMLHttpRequest"
|
||||
body="_username=$username&_password=$password&_csrf_token=$csrf_token"
|
||||
ret=$(_post "$body" "$WORLD4YOU_API/login" '' POST 'application/x-www-form-urlencoded')
|
||||
unset _H2
|
||||
|
||||
_debug ret "$ret"
|
||||
if _contains "$ret" "\"success\":true"; then
|
||||
_info "Successfully logged in"
|
||||
sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/')
|
||||
_parse_sessid
|
||||
else
|
||||
_err "Unable to log in: $(echo "$ret" | sed 's/^.*"message":"\([^\"]*\)".*$/\1/')"
|
||||
msg=$(echo "$ret" | sed 's/^.*"message":"\([^\"]*\)".*$/\1/')
|
||||
_err "Unable to log in: my.world4you.com: $msg"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Usage _get_paketnr <fqdn> <form>
|
||||
# Usage: _get_paketnr <fqdn> <form>
|
||||
_get_paketnr() {
|
||||
fqdn="$1"
|
||||
form="$2"
|
||||
|
||||
domains=$(echo "$form" | grep 'header-paket-domain' | sed 's/<[^>]*>//g' | sed 's/^.*>\([^>]*\)$/\1/')
|
||||
domains=$(echo "$form" | grep '<ul class="nav header-paket-list">' | sed 's/<li/\n<li/g' | sed 's/<[^>]*>/ /g' | sed 's/^.*>\([^>]*\)$/\1/')
|
||||
domain=''
|
||||
for domain in $domains; do
|
||||
if _contains "$fqdn" "$domain\$"; then
|
||||
@@ -197,6 +210,11 @@ _get_paketnr() {
|
||||
TLD="$domain"
|
||||
_debug domain "$domain"
|
||||
RECORD=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#TLD} - 1))")
|
||||
PAKETNR=$(echo "$form" | grep "data-textfilter=\".* $domain " | _tail_n 1 | sed "s|.*$WORLD4YOU_API/\\([0-9]*\\)/.*|\\1|")
|
||||
PAKETNR=$(echo "$domains" | grep "$domain" | sed 's/^[^,]*, *\([0-9]*\).*$/\1/')
|
||||
return 0
|
||||
}
|
||||
|
||||
# Usage: _parse_sessid
|
||||
_parse_sessid() {
|
||||
sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | _tail_n 1 | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/')
|
||||
}
|
||||
|
||||
264
dnsapi/dns_yc.sh
Normal file
264
dnsapi/dns_yc.sh
Normal file
@@ -0,0 +1,264 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#YC_Zone_ID="" # DNS Zone ID
|
||||
#YC_Folder_ID="" # YC Folder ID
|
||||
#YC_SA_ID="" # Service Account ID
|
||||
#YC_SA_Key_ID="" # Service Account IAM Key ID
|
||||
#YC_SA_Key_File_Path="/path/to/private.key" # Path to private.key use instead of YC_SA_Key_File_PEM_b64
|
||||
#YC_SA_Key_File_PEM_b64="" # Base64 content of private.key use instead of YC_SA_Key_File_Path
|
||||
YC_Api="https://dns.api.cloud.yandex.net/dns/v1"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_yc_add() {
|
||||
fulldomain="$(echo "$1". | _lower_case)" # Add dot at end of domain name
|
||||
txtvalue=$2
|
||||
|
||||
YC_SA_Key_File_PEM_b64="${YC_SA_Key_File_PEM_b64:-$(_readaccountconf_mutable YC_SA_Key_File_PEM_b64)}"
|
||||
YC_SA_Key_File_Path="${YC_SA_Key_File_Path:-$(_readaccountconf_mutable YC_SA_Key_File_Path)}"
|
||||
|
||||
if [ "$YC_SA_Key_File_PEM_b64" ]; then
|
||||
echo "$YC_SA_Key_File_PEM_b64" | _dbase64 >private.key
|
||||
YC_SA_Key_File="private.key"
|
||||
_savedomainconf YC_SA_Key_File_PEM_b64 "$YC_SA_Key_File_PEM_b64"
|
||||
else
|
||||
YC_SA_Key_File="$YC_SA_Key_File_Path"
|
||||
_savedomainconf YC_SA_Key_File_Path "$YC_SA_Key_File_Path"
|
||||
fi
|
||||
|
||||
YC_Zone_ID="${YC_Zone_ID:-$(_readaccountconf_mutable YC_Zone_ID)}"
|
||||
YC_Folder_ID="${YC_Folder_ID:-$(_readaccountconf_mutable YC_Folder_ID)}"
|
||||
YC_SA_ID="${YC_SA_ID:-$(_readaccountconf_mutable YC_SA_ID)}"
|
||||
YC_SA_Key_ID="${YC_SA_Key_ID:-$(_readaccountconf_mutable YC_SA_Key_ID)}"
|
||||
|
||||
if [ "$YC_SA_ID" ] && [ "$YC_SA_Key_ID" ] && [ "$YC_SA_Key_File" ]; then
|
||||
if [ -f "$YC_SA_Key_File" ]; then
|
||||
if _isRSA "$YC_SA_Key_File" >/dev/null 2>&1; then
|
||||
if [ "$YC_Zone_ID" ]; then
|
||||
_savedomainconf YC_Zone_ID "$YC_Zone_ID"
|
||||
_savedomainconf YC_SA_ID "$YC_SA_ID"
|
||||
_savedomainconf YC_SA_Key_ID "$YC_SA_Key_ID"
|
||||
elif [ "$YC_Folder_ID" ]; then
|
||||
_savedomainconf YC_Folder_ID "$YC_Folder_ID"
|
||||
_saveaccountconf_mutable YC_SA_ID "$YC_SA_ID"
|
||||
_saveaccountconf_mutable YC_SA_Key_ID "$YC_SA_Key_ID"
|
||||
_clearaccountconf_mutable YC_Zone_ID
|
||||
_clearaccountconf YC_Zone_ID
|
||||
else
|
||||
_err "You didn't specify a Yandex Cloud Zone ID or Folder ID yet."
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
_err "YC_SA_Key_File not a RSA file(_isRSA function return false)."
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
_err "YC_SA_Key_File not found in path $YC_SA_Key_File."
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
_clearaccountconf YC_Zone_ID
|
||||
_clearaccountconf YC_Folder_ID
|
||||
_clearaccountconf YC_SA_ID
|
||||
_clearaccountconf YC_SA_Key_ID
|
||||
_clearaccountconf YC_SA_Key_File_PEM_b64
|
||||
_clearaccountconf YC_SA_Key_File_Path
|
||||
_err "You didn't specify a YC_SA_ID or YC_SA_Key_ID or YC_SA_Key_File."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
_debug _domain_id "$_domain_id"
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug "Getting txt records"
|
||||
if ! _yc_rest GET "zones/${_domain_id}:getRecordSet?type=TXT&name=$_sub_domain"; then
|
||||
_err "Error: $response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Adding record"
|
||||
if _yc_rest POST "zones/$_domain_id:upsertRecordSets" "{\"merges\": [ { \"name\":\"$_sub_domain\",\"type\":\"TXT\",\"ttl\":\"120\",\"data\":[\"$txtvalue\"]}]}"; then
|
||||
if _contains "$response" "\"done\": true"; then
|
||||
_info "Added, OK"
|
||||
return 0
|
||||
else
|
||||
_err "Add txt record error."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
_err "Add txt record error."
|
||||
return 1
|
||||
|
||||
}
|
||||
|
||||
#fulldomain txtvalue
|
||||
dns_yc_rm() {
|
||||
fulldomain="$(echo "$1". | _lower_case)" # Add dot at end of domain name
|
||||
txtvalue=$2
|
||||
|
||||
YC_Zone_ID="${YC_Zone_ID:-$(_readaccountconf_mutable YC_Zone_ID)}"
|
||||
YC_Folder_ID="${YC_Folder_ID:-$(_readaccountconf_mutable YC_Folder_ID)}"
|
||||
YC_SA_ID="${YC_SA_ID:-$(_readaccountconf_mutable YC_SA_ID)}"
|
||||
YC_SA_Key_ID="${YC_SA_Key_ID:-$(_readaccountconf_mutable YC_SA_Key_ID)}"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
_debug _domain_id "$_domain_id"
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug "Getting txt records"
|
||||
if _yc_rest GET "zones/${_domain_id}:getRecordSet?type=TXT&name=$_sub_domain"; then
|
||||
exists_txtvalue=$(echo "$response" | _normalizeJson | _egrep_o "\"data\".*\][^,]*" | _egrep_o "[^:]*$")
|
||||
_debug exists_txtvalue "$exists_txtvalue"
|
||||
else
|
||||
_err "Error: $response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _yc_rest POST "zones/$_domain_id:updateRecordSets" "{\"deletions\": [ { \"name\":\"$_sub_domain\",\"type\":\"TXT\",\"ttl\":\"120\",\"data\":$exists_txtvalue}]}"; then
|
||||
if _contains "$response" "\"done\": true"; then
|
||||
_info "Delete, OK"
|
||||
return 0
|
||||
else
|
||||
_err "Delete record error."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
_err "Delete record error."
|
||||
return 1
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
#_acme-challenge.www.domain.com
|
||||
#returns
|
||||
# _sub_domain=_acme-challenge.www
|
||||
# _domain=domain.com
|
||||
# _domain_id=sdjkglgdfewsdfg
|
||||
_get_root() {
|
||||
domain=$1
|
||||
i=1
|
||||
p=1
|
||||
|
||||
# Use Zone ID directly if provided
|
||||
if [ "$YC_Zone_ID" ]; then
|
||||
if ! _yc_rest GET "zones/$YC_Zone_ID"; then
|
||||
return 1
|
||||
else
|
||||
if echo "$response" | tr -d " " | _egrep_o "\"id\":\"$YC_Zone_ID\"" >/dev/null; then
|
||||
_domain=$(echo "$response" | _egrep_o "\"zone\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ")
|
||||
if [ "$_domain" ]; then
|
||||
_cutlength=$((${#domain} - ${#_domain}))
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -c "1-$_cutlength")
|
||||
_domain_id=$YC_Zone_ID
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
_debug h "$h"
|
||||
if [ -z "$h" ]; then
|
||||
#not valid
|
||||
return 1
|
||||
fi
|
||||
if [ "$YC_Folder_ID" ]; then
|
||||
if ! _yc_rest GET "zones?folderId=$YC_Folder_ID"; then
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
echo "You didn't specify a Yandex Cloud Folder ID."
|
||||
return 1
|
||||
fi
|
||||
if _contains "$response" "\"zone\": \"$h\""; then
|
||||
_domain_id=$(echo "$response" | _normalizeJson | _egrep_o "[^{]*\"zone\":\"$h\"[^}]*" | _egrep_o "\"id\"[^,]*" | _egrep_o "[^:]*$" | tr -d '"')
|
||||
_debug _domain_id "$_domain_id"
|
||||
if [ "$_domain_id" ]; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain=$h
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
p=$i
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
_yc_rest() {
|
||||
m=$1
|
||||
ep="$2"
|
||||
data="$3"
|
||||
_debug "$ep"
|
||||
|
||||
if [ ! "$YC_Token" ]; then
|
||||
_debug "Login"
|
||||
_yc_login
|
||||
else
|
||||
_debug "Token already exists. Skip Login."
|
||||
fi
|
||||
|
||||
token_trimmed=$(echo "$YC_Token" | tr -d '"')
|
||||
|
||||
export _H1="Content-Type: application/json"
|
||||
export _H2="Authorization: Bearer $token_trimmed"
|
||||
|
||||
if [ "$m" != "GET" ]; then
|
||||
_debug data "$data"
|
||||
response="$(_post "$data" "$YC_Api/$ep" "" "$m")"
|
||||
else
|
||||
response="$(_get "$YC_Api/$ep")"
|
||||
fi
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error $ep"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
||||
|
||||
_yc_login() {
|
||||
header=$(echo "{\"typ\":\"JWT\",\"alg\":\"PS256\",\"kid\":\"$YC_SA_Key_ID\"}" | _normalizeJson | _base64 | _url_replace)
|
||||
_debug header "$header"
|
||||
|
||||
_current_timestamp=$(_time)
|
||||
_expire_timestamp=$(_math "$_current_timestamp" + 1200) # 20 minutes
|
||||
payload=$(echo "{\"iss\":\"$YC_SA_ID\",\"aud\":\"https://iam.api.cloud.yandex.net/iam/v1/tokens\",\"iat\":$_current_timestamp,\"exp\":$_expire_timestamp}" | _normalizeJson | _base64 | _url_replace)
|
||||
_debug payload "$payload"
|
||||
|
||||
#signature=$(printf "%s.%s" "$header" "$payload" | ${ACME_OPENSSL_BIN:-openssl} dgst -sign "$YC_SA_Key_File -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1" | _base64 | _url_replace )
|
||||
_signature=$(printf "%s.%s" "$header" "$payload" | _sign "$YC_SA_Key_File" "sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1" | _url_replace)
|
||||
_debug2 _signature "$_signature"
|
||||
|
||||
rm -rf "$YC_SA_Key_File"
|
||||
|
||||
_jwt=$(printf "{\"jwt\": \"%s.%s.%s\"}" "$header" "$payload" "$_signature")
|
||||
_debug2 _jwt "$_jwt"
|
||||
|
||||
export _H1="Content-Type: application/json"
|
||||
_iam_response="$(_post "$_jwt" "https://iam.api.cloud.yandex.net/iam/v1/tokens" "" "POST")"
|
||||
_debug3 _iam_response "$(echo "$_iam_response" | _normalizeJson)"
|
||||
|
||||
YC_Token="$(echo "$_iam_response" | _normalizeJson | _egrep_o "\"iamToken\"[^,]*" | _egrep_o "[^:]*$" | tr -d '"')"
|
||||
_debug3 YC_Token
|
||||
|
||||
return 0
|
||||
}
|
||||
44
notify/callmebotWhatsApp.sh
Normal file
44
notify/callmebotWhatsApp.sh
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Support CallMeBot Whatsapp webhooks
|
||||
|
||||
#CALLMEBOT_YOUR_PHONE_NO=""
|
||||
#CALLMEBOT_API_KEY=""
|
||||
|
||||
callmebotWhatsApp_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
CALLMEBOT_YOUR_PHONE_NO="${CALLMEBOT_YOUR_PHONE_NO:-$(_readaccountconf_mutable CALLMEBOT_YOUR_PHONE_NO)}"
|
||||
if [ -z "$CALLMEBOT_YOUR_PHONE_NO" ]; then
|
||||
CALLMEBOT_YOUR_PHONE_NO=""
|
||||
_err "You didn't specify a Slack webhook url CALLMEBOT_YOUR_PHONE_NO yet."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable CALLMEBOT_YOUR_PHONE_NO "$CALLMEBOT_YOUR_PHONE_NO"
|
||||
|
||||
CALLMEBOT_API_KEY="${CALLMEBOT_API_KEY:-$(_readaccountconf_mutable CALLMEBOT_API_KEY)}"
|
||||
if [ "$CALLMEBOT_API_KEY" ]; then
|
||||
_saveaccountconf_mutable CALLMEBOT_API_KEY "$CALLMEBOT_API_KEY"
|
||||
fi
|
||||
|
||||
_waUrl="https://api.callmebot.com/whatsapp.php"
|
||||
|
||||
_Phone_No="$(printf "%s" "$CALLMEBOT_YOUR_PHONE_NO" | _url_encode)"
|
||||
_apikey="$(printf "%s" "$CALLMEBOT_API_KEY" | _url_encode)"
|
||||
_message="$(printf "*%s*\\n%s" "$_subject" "$_content" | _url_encode)"
|
||||
|
||||
_finalUrl="$_waUrl?phone=$_Phone_No&apikey=$_apikey&text=$_message"
|
||||
response="$(_get "$_finalUrl")"
|
||||
|
||||
if [ "$?" = "0" ] && _contains ".<p><b>Message queued.</b> You will receive it in a few seconds."; then
|
||||
_info "wa send success."
|
||||
return 0
|
||||
fi
|
||||
_err "wa send error."
|
||||
_debug "URL" "$_finalUrl"
|
||||
_debug "Response" "$response"
|
||||
return 1
|
||||
}
|
||||
45
notify/slack_app.sh
Executable file
45
notify/slack_app.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Support Slack APP notifications
|
||||
|
||||
#SLACK_APP_CHANNEL=""
|
||||
#SLACK_APP_TOKEN=""
|
||||
|
||||
slack_app_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
SLACK_APP_CHANNEL="${SLACK_APP_CHANNEL:-$(_readaccountconf_mutable SLACK_APP_CHANNEL)}"
|
||||
if [ -n "$SLACK_APP_CHANNEL" ]; then
|
||||
_saveaccountconf_mutable SLACK_APP_CHANNEL "$SLACK_APP_CHANNEL"
|
||||
fi
|
||||
|
||||
SLACK_APP_TOKEN="${SLACK_APP_TOKEN:-$(_readaccountconf_mutable SLACK_APP_TOKEN)}"
|
||||
if [ -n "$SLACK_APP_TOKEN" ]; then
|
||||
_saveaccountconf_mutable SLACK_APP_TOKEN "$SLACK_APP_TOKEN"
|
||||
fi
|
||||
|
||||
_content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)"
|
||||
_data="{\"text\": \"$_content\", "
|
||||
if [ -n "$SLACK_APP_CHANNEL" ]; then
|
||||
_data="$_data\"channel\": \"$SLACK_APP_CHANNEL\", "
|
||||
fi
|
||||
_data="$_data\"mrkdwn\": \"true\"}"
|
||||
|
||||
export _H1="Authorization: Bearer $SLACK_APP_TOKEN"
|
||||
|
||||
SLACK_APP_API_URL="https://slack.com/api/chat.postMessage"
|
||||
if _post "$_data" "$SLACK_APP_API_URL" "" "POST" "application/json; charset=utf-8"; then
|
||||
# shellcheck disable=SC2154
|
||||
SLACK_APP_RESULT_OK=$(echo "$response" | _egrep_o 'ok" *: *true')
|
||||
if [ "$?" = "0" ] && [ "$SLACK_APP_RESULT_OK" ]; then
|
||||
_info "slack send success."
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
_err "slack send error."
|
||||
_err "$response"
|
||||
return 1
|
||||
}
|
||||
Reference in New Issue
Block a user