mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2025-06-17 00:22:45 +00:00
Merge branch 'acmesh-official:master' into fix_dnsmadeeasy_on_non_english_systems
This commit is contained in:
commit
b844761f19
239
.github/workflows/DNS.yml
vendored
239
.github/workflows/DNS.yml
vendored
@ -59,10 +59,15 @@ jobs:
|
|||||||
DEBUG: ${{ secrets.DEBUG }}
|
DEBUG: ${{ secrets.DEBUG }}
|
||||||
http_proxy: ${{ secrets.http_proxy }}
|
http_proxy: ${{ secrets.http_proxy }}
|
||||||
https_proxy: ${{ secrets.https_proxy }}
|
https_proxy: ${{ secrets.https_proxy }}
|
||||||
|
TokenName1: ${{ secrets.TokenName1}}
|
||||||
|
TokenName2: ${{ secrets.TokenName2}}
|
||||||
|
TokenName3: ${{ secrets.TokenName3}}
|
||||||
|
TokenName4: ${{ secrets.TokenName4}}
|
||||||
|
TokenName5: ${{ secrets.TokenName5}}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Clone acmetest
|
- 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: Set env file
|
- name: Set env file
|
||||||
run: |
|
run: |
|
||||||
cd ../acmetest
|
cd ../acmetest
|
||||||
@ -81,9 +86,7 @@ jobs:
|
|||||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||||
echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env
|
echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env
|
||||||
fi
|
fi
|
||||||
echo "TEST_DNS_NO_WILDCARD" >> docker.env
|
|
||||||
echo "http_proxy" >> docker.env
|
|
||||||
echo "https_proxy" >> docker.env
|
|
||||||
- name: Run acmetest
|
- name: Run acmetest
|
||||||
run: cd ../acmetest && ./rundocker.sh testall
|
run: cd ../acmetest && ./rundocker.sh testall
|
||||||
|
|
||||||
@ -104,28 +107,33 @@ jobs:
|
|||||||
DEBUG: ${{ secrets.DEBUG }}
|
DEBUG: ${{ secrets.DEBUG }}
|
||||||
http_proxy: ${{ secrets.http_proxy }}
|
http_proxy: ${{ secrets.http_proxy }}
|
||||||
https_proxy: ${{ secrets.https_proxy }}
|
https_proxy: ${{ secrets.https_proxy }}
|
||||||
|
TokenName1: ${{ secrets.TokenName1}}
|
||||||
|
TokenName2: ${{ secrets.TokenName2}}
|
||||||
|
TokenName3: ${{ secrets.TokenName3}}
|
||||||
|
TokenName4: ${{ secrets.TokenName4}}
|
||||||
|
TokenName5: ${{ secrets.TokenName5}}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Install tools
|
- name: Install tools
|
||||||
run: brew install socat
|
run: brew install socat
|
||||||
- name: Clone acmetest
|
- 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
|
- name: Run acmetest
|
||||||
run: |
|
run: |
|
||||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}"
|
||||||
fi
|
fi
|
||||||
cd ../acmetest
|
cd ../acmetest
|
||||||
./letest.sh
|
./letest.sh
|
||||||
@ -147,11 +155,16 @@ jobs:
|
|||||||
DEBUG: ${{ secrets.DEBUG }}
|
DEBUG: ${{ secrets.DEBUG }}
|
||||||
http_proxy: ${{ secrets.http_proxy }}
|
http_proxy: ${{ secrets.http_proxy }}
|
||||||
https_proxy: ${{ secrets.https_proxy }}
|
https_proxy: ${{ secrets.https_proxy }}
|
||||||
|
TokenName1: ${{ secrets.TokenName1}}
|
||||||
|
TokenName2: ${{ secrets.TokenName2}}
|
||||||
|
TokenName3: ${{ secrets.TokenName3}}
|
||||||
|
TokenName4: ${{ secrets.TokenName4}}
|
||||||
|
TokenName5: ${{ secrets.TokenName5}}
|
||||||
steps:
|
steps:
|
||||||
- name: Set git to use LF
|
- name: Set git to use LF
|
||||||
run: |
|
run: |
|
||||||
git config --global core.autocrlf false
|
git config --global core.autocrlf false
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Install cygwin base packages with chocolatey
|
- name: Install cygwin base packages with chocolatey
|
||||||
run: |
|
run: |
|
||||||
choco config get cacheLocation
|
choco config get cacheLocation
|
||||||
@ -159,31 +172,31 @@ jobs:
|
|||||||
shell: cmd
|
shell: cmd
|
||||||
- name: Install cygwin additional packages
|
- name: Install cygwin additional packages
|
||||||
run: |
|
run: |
|
||||||
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git
|
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
|
shell: cmd
|
||||||
- name: Set ENV
|
- name: Set ENV
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV%
|
echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV%
|
||||||
- name: Clone acmetest
|
- 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
|
- name: Run acmetest
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}"
|
||||||
fi
|
fi
|
||||||
cd ../acmetest
|
cd ../acmetest
|
||||||
./letest.sh
|
./letest.sh
|
||||||
@ -204,31 +217,36 @@ jobs:
|
|||||||
DEBUG: ${{ secrets.DEBUG }}
|
DEBUG: ${{ secrets.DEBUG }}
|
||||||
http_proxy: ${{ secrets.http_proxy }}
|
http_proxy: ${{ secrets.http_proxy }}
|
||||||
https_proxy: ${{ secrets.https_proxy }}
|
https_proxy: ${{ secrets.https_proxy }}
|
||||||
|
TokenName1: ${{ secrets.TokenName1}}
|
||||||
|
TokenName2: ${{ secrets.TokenName2}}
|
||||||
|
TokenName3: ${{ secrets.TokenName3}}
|
||||||
|
TokenName4: ${{ secrets.TokenName4}}
|
||||||
|
TokenName5: ${{ secrets.TokenName5}}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Clone acmetest
|
- 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/
|
||||||
- uses: vmactions/freebsd-vm@v0
|
- uses: vmactions/freebsd-vm@v0
|
||||||
with:
|
with:
|
||||||
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
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
|
prepare: pkg install -y socat curl
|
||||||
usesh: true
|
usesh: true
|
||||||
copyback: false
|
copyback: false
|
||||||
run: |
|
run: |
|
||||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}"
|
||||||
fi
|
fi
|
||||||
cd ../acmetest
|
cd ../acmetest
|
||||||
./letest.sh
|
./letest.sh
|
||||||
@ -236,7 +254,7 @@ jobs:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Solaris:
|
OpenBSD:
|
||||||
runs-on: macos-12
|
runs-on: macos-12
|
||||||
needs: FreeBSD
|
needs: FreeBSD
|
||||||
env:
|
env:
|
||||||
@ -250,78 +268,36 @@ jobs:
|
|||||||
DEBUG: ${{ secrets.DEBUG }}
|
DEBUG: ${{ secrets.DEBUG }}
|
||||||
http_proxy: ${{ secrets.http_proxy }}
|
http_proxy: ${{ secrets.http_proxy }}
|
||||||
https_proxy: ${{ secrets.https_proxy }}
|
https_proxy: ${{ secrets.https_proxy }}
|
||||||
|
TokenName1: ${{ secrets.TokenName1}}
|
||||||
|
TokenName2: ${{ secrets.TokenName2}}
|
||||||
|
TokenName3: ${{ secrets.TokenName3}}
|
||||||
|
TokenName4: ${{ secrets.TokenName4}}
|
||||||
|
TokenName5: ${{ secrets.TokenName5}}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Clone acmetest
|
- 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/
|
||||||
- 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 ${{ 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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
OpenBSD:
|
|
||||||
runs-on: macos-12
|
|
||||||
needs: Solaris
|
|
||||||
env:
|
|
||||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
|
||||||
TestingDomain: ${{ secrets.TestingDomain }}
|
|
||||||
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
|
||||||
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
|
|
||||||
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
|
||||||
CASE: le_test_dnsapi
|
|
||||||
TEST_LOCAL: 1
|
|
||||||
DEBUG: ${{ secrets.DEBUG }}
|
|
||||||
http_proxy: ${{ secrets.http_proxy }}
|
|
||||||
https_proxy: ${{ secrets.https_proxy }}
|
|
||||||
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/openbsd-vm@v0
|
- uses: vmactions/openbsd-vm@v0
|
||||||
with:
|
with:
|
||||||
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
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
|
prepare: pkg_add socat curl
|
||||||
usesh: true
|
usesh: true
|
||||||
copyback: false
|
copyback: false
|
||||||
run: |
|
run: |
|
||||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}"
|
||||||
fi
|
fi
|
||||||
cd ../acmetest
|
cd ../acmetest
|
||||||
./letest.sh
|
./letest.sh
|
||||||
@ -343,32 +319,37 @@ jobs:
|
|||||||
DEBUG: ${{ secrets.DEBUG }}
|
DEBUG: ${{ secrets.DEBUG }}
|
||||||
http_proxy: ${{ secrets.http_proxy }}
|
http_proxy: ${{ secrets.http_proxy }}
|
||||||
https_proxy: ${{ secrets.https_proxy }}
|
https_proxy: ${{ secrets.https_proxy }}
|
||||||
|
TokenName1: ${{ secrets.TokenName1}}
|
||||||
|
TokenName2: ${{ secrets.TokenName2}}
|
||||||
|
TokenName3: ${{ secrets.TokenName3}}
|
||||||
|
TokenName4: ${{ secrets.TokenName4}}
|
||||||
|
TokenName5: ${{ secrets.TokenName5}}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Clone acmetest
|
- 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/
|
||||||
- uses: vmactions/netbsd-vm@v0
|
- uses: vmactions/netbsd-vm@v0
|
||||||
with:
|
with:
|
||||||
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
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: |
|
prepare: |
|
||||||
pkg_add curl socat
|
pkg_add curl socat
|
||||||
usesh: true
|
usesh: true
|
||||||
copyback: false
|
copyback: false
|
||||||
run: |
|
run: |
|
||||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}"
|
||||||
fi
|
fi
|
||||||
cd ../acmetest
|
cd ../acmetest
|
||||||
./letest.sh
|
./letest.sh
|
||||||
@ -390,32 +371,37 @@ jobs:
|
|||||||
DEBUG: ${{ secrets.DEBUG }}
|
DEBUG: ${{ secrets.DEBUG }}
|
||||||
http_proxy: ${{ secrets.http_proxy }}
|
http_proxy: ${{ secrets.http_proxy }}
|
||||||
https_proxy: ${{ secrets.https_proxy }}
|
https_proxy: ${{ secrets.https_proxy }}
|
||||||
|
TokenName1: ${{ secrets.TokenName1}}
|
||||||
|
TokenName2: ${{ secrets.TokenName2}}
|
||||||
|
TokenName3: ${{ secrets.TokenName3}}
|
||||||
|
TokenName4: ${{ secrets.TokenName4}}
|
||||||
|
TokenName5: ${{ secrets.TokenName5}}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Clone acmetest
|
- 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/
|
||||||
- uses: vmactions/dragonflybsd-vm@v0
|
- uses: vmactions/dragonflybsd-vm@v0
|
||||||
with:
|
with:
|
||||||
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
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: |
|
prepare: |
|
||||||
pkg install -y curl socat
|
pkg install -y curl socat
|
||||||
usesh: true
|
usesh: true
|
||||||
copyback: false
|
copyback: false
|
||||||
run: |
|
run: |
|
||||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||||
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||||
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||||
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||||
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}"
|
||||||
fi
|
fi
|
||||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||||
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}"
|
||||||
fi
|
fi
|
||||||
cd ../acmetest
|
cd ../acmetest
|
||||||
./letest.sh
|
./letest.sh
|
||||||
@ -424,3 +410,56 @@ jobs:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
6
.github/workflows/DragonFlyBSD.yml
vendored
6
.github/workflows/DragonFlyBSD.yml
vendored
@ -45,8 +45,8 @@ jobs:
|
|||||||
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
||||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- uses: vmactions/cf-tunnel@v0.0.3
|
- uses: vmactions/cf-tunnel@v0
|
||||||
id: tunnel
|
id: tunnel
|
||||||
with:
|
with:
|
||||||
protocol: http
|
protocol: http
|
||||||
@ -54,7 +54,7 @@ jobs:
|
|||||||
- name: Set envs
|
- name: Set envs
|
||||||
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
||||||
- name: Clone acmetest
|
- 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/
|
||||||
- uses: vmactions/dragonflybsd-vm@v0
|
- uses: vmactions/dragonflybsd-vm@v0
|
||||||
with:
|
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'
|
||||||
|
6
.github/workflows/FreeBSD.yml
vendored
6
.github/workflows/FreeBSD.yml
vendored
@ -51,8 +51,8 @@ jobs:
|
|||||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||||
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
|
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- uses: vmactions/cf-tunnel@v0.0.3
|
- uses: vmactions/cf-tunnel@v0
|
||||||
id: tunnel
|
id: tunnel
|
||||||
with:
|
with:
|
||||||
protocol: http
|
protocol: http
|
||||||
@ -60,7 +60,7 @@ jobs:
|
|||||||
- name: Set envs
|
- name: Set envs
|
||||||
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
||||||
- name: Clone acmetest
|
- 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/
|
||||||
- uses: vmactions/freebsd-vm@v0
|
- uses: vmactions/freebsd-vm@v0
|
||||||
with:
|
with:
|
||||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
|
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
|
||||||
|
4
.github/workflows/Linux.yml
vendored
4
.github/workflows/Linux.yml
vendored
@ -33,11 +33,11 @@ jobs:
|
|||||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||||
TEST_ACME_Server: "LetsEncrypt.org_test"
|
TEST_ACME_Server: "LetsEncrypt.org_test"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Clone acmetest
|
- name: Clone acmetest
|
||||||
run: |
|
run: |
|
||||||
cd .. \
|
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/
|
&& cp -r acme.sh acmetest/
|
||||||
- name: Run acmetest
|
- name: Run acmetest
|
||||||
run: |
|
run: |
|
||||||
|
4
.github/workflows/MacOS.yml
vendored
4
.github/workflows/MacOS.yml
vendored
@ -44,13 +44,13 @@ jobs:
|
|||||||
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
||||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Install tools
|
- name: Install tools
|
||||||
run: brew install socat
|
run: brew install socat
|
||||||
- name: Clone acmetest
|
- name: Clone acmetest
|
||||||
run: |
|
run: |
|
||||||
cd .. \
|
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/
|
&& cp -r acme.sh acmetest/
|
||||||
- name: Run acmetest
|
- name: Run acmetest
|
||||||
run: |
|
run: |
|
||||||
|
7
.github/workflows/NetBSD.yml
vendored
7
.github/workflows/NetBSD.yml
vendored
@ -45,8 +45,8 @@ jobs:
|
|||||||
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
||||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- uses: vmactions/cf-tunnel@v0.0.3
|
- uses: vmactions/cf-tunnel@v0
|
||||||
id: tunnel
|
id: tunnel
|
||||||
with:
|
with:
|
||||||
protocol: http
|
protocol: http
|
||||||
@ -54,14 +54,13 @@ jobs:
|
|||||||
- name: Set envs
|
- name: Set envs
|
||||||
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
||||||
- name: Clone acmetest
|
- 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/
|
||||||
- uses: vmactions/netbsd-vm@v0
|
- uses: vmactions/netbsd-vm@v0
|
||||||
with:
|
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'
|
||||||
nat: |
|
nat: |
|
||||||
"8080": "80"
|
"8080": "80"
|
||||||
prepare: |
|
prepare: |
|
||||||
export PKG_PATH="http://cdn.NetBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f '1 2' -d.)/All/"
|
|
||||||
pkg_add curl socat
|
pkg_add curl socat
|
||||||
usesh: true
|
usesh: true
|
||||||
copyback: false
|
copyback: false
|
||||||
|
6
.github/workflows/OpenBSD.yml
vendored
6
.github/workflows/OpenBSD.yml
vendored
@ -51,8 +51,8 @@ jobs:
|
|||||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||||
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
|
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- uses: vmactions/cf-tunnel@v0.0.3
|
- uses: vmactions/cf-tunnel@v0
|
||||||
id: tunnel
|
id: tunnel
|
||||||
with:
|
with:
|
||||||
protocol: http
|
protocol: http
|
||||||
@ -60,7 +60,7 @@ jobs:
|
|||||||
- name: Set envs
|
- name: Set envs
|
||||||
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
||||||
- name: Clone acmetest
|
- 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/
|
||||||
- uses: vmactions/openbsd-vm@v0
|
- uses: vmactions/openbsd-vm@v0
|
||||||
with:
|
with:
|
||||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
|
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
|
||||||
|
8
.github/workflows/PebbleStrict.yml
vendored
8
.github/workflows/PebbleStrict.yml
vendored
@ -33,7 +33,7 @@ jobs:
|
|||||||
TEST_CA: "Pebble Intermediate CA"
|
TEST_CA: "Pebble Intermediate CA"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Install tools
|
- name: Install tools
|
||||||
run: sudo apt-get install -y socat
|
run: sudo apt-get install -y socat
|
||||||
- name: Run Pebble
|
- name: Run Pebble
|
||||||
@ -41,7 +41,7 @@ jobs:
|
|||||||
- name: Set up Pebble
|
- name: Set up Pebble
|
||||||
run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4
|
run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4
|
||||||
- name: Clone acmetest
|
- 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
|
- name: Run acmetest
|
||||||
run: cd ../acmetest && ./letest.sh
|
run: cd ../acmetest && ./letest.sh
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ jobs:
|
|||||||
TEST_IPCERT: 1
|
TEST_IPCERT: 1
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Install tools
|
- name: Install tools
|
||||||
run: sudo apt-get install -y socat
|
run: sudo apt-get install -y socat
|
||||||
- name: Run Pebble
|
- name: Run Pebble
|
||||||
@ -67,6 +67,6 @@ jobs:
|
|||||||
-e PEBBLE_VA_ALWAYS_VALID=1 \
|
-e PEBBLE_VA_ALWAYS_VALID=1 \
|
||||||
-p 14000:14000 -p 15000:15000 letsencrypt/pebble:latest pebble -config /test/config/pebble-config.json -strict
|
-p 14000:14000 -p 15000:15000 letsencrypt/pebble:latest pebble -config /test/config/pebble-config.json -strict
|
||||||
- name: Clone acmetest
|
- 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
|
- name: Run acmetest
|
||||||
run: cd ../acmetest && ./letest.sh
|
run: cd ../acmetest && ./letest.sh
|
6
.github/workflows/Solaris.yml
vendored
6
.github/workflows/Solaris.yml
vendored
@ -51,8 +51,8 @@ jobs:
|
|||||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||||
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
|
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- uses: vmactions/cf-tunnel@v0.0.3
|
- uses: vmactions/cf-tunnel@v0
|
||||||
id: tunnel
|
id: tunnel
|
||||||
with:
|
with:
|
||||||
protocol: http
|
protocol: http
|
||||||
@ -60,7 +60,7 @@ jobs:
|
|||||||
- name: Set envs
|
- name: Set envs
|
||||||
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
||||||
- name: Clone acmetest
|
- 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/
|
||||||
- uses: vmactions/solaris-vm@v0
|
- uses: vmactions/solaris-vm@v0
|
||||||
with:
|
with:
|
||||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
|
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
|
||||||
|
13
.github/workflows/Ubuntu.yml
vendored
13
.github/workflows/Ubuntu.yml
vendored
@ -70,7 +70,7 @@ jobs:
|
|||||||
TestingDomain: ${{ matrix.TestingDomain }}
|
TestingDomain: ${{ matrix.TestingDomain }}
|
||||||
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
|
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Install tools
|
- name: Install tools
|
||||||
run: sudo apt-get install -y socat wget
|
run: sudo apt-get install -y socat wget
|
||||||
- name: Start StepCA
|
- name: Start StepCA
|
||||||
@ -80,15 +80,20 @@ jobs:
|
|||||||
-p 9000:9000 \
|
-p 9000:9000 \
|
||||||
-e "DOCKER_STEPCA_INIT_NAME=Smallstep" \
|
-e "DOCKER_STEPCA_INIT_NAME=Smallstep" \
|
||||||
-e "DOCKER_STEPCA_INIT_DNS_NAMES=localhost,$(hostname -f)" \
|
-e "DOCKER_STEPCA_INIT_DNS_NAMES=localhost,$(hostname -f)" \
|
||||||
|
-e "DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT=true" \
|
||||||
|
-e "DOCKER_STEPCA_INIT_PASSWORD=test" \
|
||||||
--name stepca \
|
--name stepca \
|
||||||
smallstep/step-ca \
|
smallstep/step-ca:0.23.1
|
||||||
&& sleep 5 && docker exec stepca step ca provisioner add acme --type ACME \
|
|
||||||
|
sleep 5
|
||||||
|
docker exec stepca bash -c "echo test >test" \
|
||||||
|
&& docker exec stepca step ca provisioner add acme --type ACME --admin-subject step --admin-password-file=/home/step/test \
|
||||||
&& docker exec stepca kill -1 1 \
|
&& docker exec stepca kill -1 1 \
|
||||||
&& docker exec stepca cat /home/step/certs/root_ca.crt | sudo bash -c "cat - >>/etc/ssl/certs/ca-certificates.crt"
|
&& docker exec stepca cat /home/step/certs/root_ca.crt | sudo bash -c "cat - >>/etc/ssl/certs/ca-certificates.crt"
|
||||||
- name: Clone acmetest
|
- name: Clone acmetest
|
||||||
run: |
|
run: |
|
||||||
cd .. \
|
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/
|
&& cp -r acme.sh acmetest/
|
||||||
- name: Run acmetest
|
- name: Run acmetest
|
||||||
run: |
|
run: |
|
||||||
|
6
.github/workflows/Windows.yml
vendored
6
.github/workflows/Windows.yml
vendored
@ -49,7 +49,7 @@ jobs:
|
|||||||
- name: Set git to use LF
|
- name: Set git to use LF
|
||||||
run: |
|
run: |
|
||||||
git config --global core.autocrlf false
|
git config --global core.autocrlf false
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Install cygwin base packages with chocolatey
|
- name: Install cygwin base packages with chocolatey
|
||||||
run: |
|
run: |
|
||||||
choco config get cacheLocation
|
choco config get cacheLocation
|
||||||
@ -57,7 +57,7 @@ jobs:
|
|||||||
shell: cmd
|
shell: cmd
|
||||||
- name: Install cygwin additional packages
|
- name: Install cygwin additional packages
|
||||||
run: |
|
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
|
shell: cmd
|
||||||
- name: Set ENV
|
- name: Set ENV
|
||||||
shell: cmd
|
shell: cmd
|
||||||
@ -69,7 +69,7 @@ jobs:
|
|||||||
echo "PATH=%PATH%"
|
echo "PATH=%PATH%"
|
||||||
- name: Clone acmetest
|
- name: Clone acmetest
|
||||||
shell: cmd
|
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
|
- name: Run acmetest
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: cd ../acmetest && bash.exe -c ./letest.sh
|
run: cd ../acmetest && bash.exe -c ./letest.sh
|
||||||
|
10
.github/workflows/dockerhub.yml
vendored
10
.github/workflows/dockerhub.yml
vendored
@ -28,9 +28,9 @@ jobs:
|
|||||||
id: step_one
|
id: step_one
|
||||||
run: |
|
run: |
|
||||||
if [ "$DOCKER_PASSWORD" ] ; then
|
if [ "$DOCKER_PASSWORD" ] ; then
|
||||||
echo "::set-output name=hasToken::true"
|
echo "hasToken=true" >>$GITHUB_OUTPUT
|
||||||
else
|
else
|
||||||
echo "::set-output name=hasToken::false"
|
echo "hasToken=false" >>$GITHUB_OUTPUT
|
||||||
fi
|
fi
|
||||||
- name: Check the value
|
- name: Check the value
|
||||||
run: echo ${{ steps.step_one.outputs.hasToken }}
|
run: echo ${{ steps.step_one.outputs.hasToken }}
|
||||||
@ -41,11 +41,11 @@ jobs:
|
|||||||
if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
|
if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
|
||||||
steps:
|
steps:
|
||||||
- name: checkout code
|
- name: checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v1
|
uses: docker/setup-qemu-action@v2
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v1
|
uses: docker/setup-buildx-action@v2
|
||||||
- name: login to docker hub
|
- name: login to docker hub
|
||||||
run: |
|
run: |
|
||||||
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
|
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
|
||||||
|
6
.github/workflows/shellcheck.yml
vendored
6
.github/workflows/shellcheck.yml
vendored
@ -22,16 +22,16 @@ jobs:
|
|||||||
ShellCheck:
|
ShellCheck:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Install Shellcheck
|
- name: Install Shellcheck
|
||||||
run: sudo apt-get install -y shellcheck
|
run: sudo apt-get install -y shellcheck
|
||||||
- name: DoShellcheck
|
- 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:
|
shfmt:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Install shfmt
|
- 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
|
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
|
- name: shfmt
|
||||||
|
13
Dockerfile
13
Dockerfile
@ -1,4 +1,4 @@
|
|||||||
FROM alpine:3.15
|
FROM alpine:3.17
|
||||||
|
|
||||||
RUN apk --no-cache add -f \
|
RUN apk --no-cache add -f \
|
||||||
openssl \
|
openssl \
|
||||||
@ -12,7 +12,8 @@ RUN apk --no-cache add -f \
|
|||||||
oath-toolkit-oathtool \
|
oath-toolkit-oathtool \
|
||||||
tar \
|
tar \
|
||||||
libidn \
|
libidn \
|
||||||
jq
|
jq \
|
||||||
|
cronie
|
||||||
|
|
||||||
ENV LE_CONFIG_HOME /acme.sh
|
ENV LE_CONFIG_HOME /acme.sh
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ COPY ./ /install_acme.sh/
|
|||||||
RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/
|
RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/
|
||||||
|
|
||||||
|
|
||||||
RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh && crontab -l | grep acme.sh | sed 's#> /dev/null##' | crontab -
|
RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh && crontab -l | grep acme.sh | sed 's#> /dev/null#> /proc/1/fd/1 2>/proc/1/fd/2#' | crontab -
|
||||||
|
|
||||||
RUN for verb in help \
|
RUN for verb in help \
|
||||||
version \
|
version \
|
||||||
@ -64,12 +65,10 @@ RUN for verb in help \
|
|||||||
|
|
||||||
RUN printf "%b" '#!'"/usr/bin/env sh\n \
|
RUN printf "%b" '#!'"/usr/bin/env sh\n \
|
||||||
if [ \"\$1\" = \"daemon\" ]; then \n \
|
if [ \"\$1\" = \"daemon\" ]; then \n \
|
||||||
trap \"echo stop && killall crond && exit 0\" SIGTERM SIGINT \n \
|
exec crond -n -s -m off \n \
|
||||||
crond && sleep infinity &\n \
|
|
||||||
wait \n \
|
|
||||||
else \n \
|
else \n \
|
||||||
exec -- \"\$@\"\n \
|
exec -- \"\$@\"\n \
|
||||||
fi" >/entry.sh && chmod +x /entry.sh
|
fi\n" >/entry.sh && chmod +x /entry.sh
|
||||||
|
|
||||||
VOLUME /acme.sh
|
VOLUME /acme.sh
|
||||||
|
|
||||||
|
10
README.md
10
README.md
@ -361,10 +361,6 @@ Ok, it's done.
|
|||||||
|
|
||||||
# 10. Issue ECC certificates
|
# 10. Issue ECC certificates
|
||||||
|
|
||||||
`Let's Encrypt` can now issue **ECDSA** certificates.
|
|
||||||
|
|
||||||
And we support them too!
|
|
||||||
|
|
||||||
Just set the `keylength` parameter with a prefix `ec-`.
|
Just set the `keylength` parameter with a prefix `ec-`.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
@ -385,10 +381,12 @@ Please look at the `keylength` parameter above.
|
|||||||
|
|
||||||
Valid values are:
|
Valid values are:
|
||||||
|
|
||||||
1. **ec-256 (prime256v1, "ECDSA P-256")**
|
1. **ec-256 (prime256v1, "ECDSA P-256", which is the default key type)**
|
||||||
2. **ec-384 (secp384r1, "ECDSA P-384")**
|
2. **ec-384 (secp384r1, "ECDSA P-384")**
|
||||||
3. **ec-521 (secp521r1, "ECDSA P-521", which is not supported by Let's Encrypt yet.)**
|
3. **ec-521 (secp521r1, "ECDSA P-521", which is not supported by Let's Encrypt yet.)**
|
||||||
|
4. **2048 (RSA2048)**
|
||||||
|
5. **3072 (RSA3072)**
|
||||||
|
6. **4096 (RSA4096)**
|
||||||
|
|
||||||
|
|
||||||
# 11. Issue Wildcard certificates
|
# 11. Issue Wildcard certificates
|
||||||
|
287
acme.sh
287
acme.sh
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
VER=3.0.5
|
VER=3.0.6
|
||||||
|
|
||||||
PROJECT_NAME="acme.sh"
|
PROJECT_NAME="acme.sh"
|
||||||
|
|
||||||
@ -53,8 +53,8 @@ CA_SERVERS="$CA_ZEROSSL,$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$
|
|||||||
|
|
||||||
DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)"
|
DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)"
|
||||||
|
|
||||||
DEFAULT_ACCOUNT_KEY_LENGTH=2048
|
DEFAULT_ACCOUNT_KEY_LENGTH=ec-256
|
||||||
DEFAULT_DOMAIN_KEY_LENGTH=2048
|
DEFAULT_DOMAIN_KEY_LENGTH=ec-256
|
||||||
|
|
||||||
DEFAULT_OPENSSL_BIN="openssl"
|
DEFAULT_OPENSSL_BIN="openssl"
|
||||||
|
|
||||||
@ -1235,7 +1235,7 @@ _createcsr() {
|
|||||||
_debug2 csr "$csr"
|
_debug2 csr "$csr"
|
||||||
_debug2 csrconf "$csrconf"
|
_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
|
if [ "$acmeValidationv1" ]; then
|
||||||
domainlist="$(_idn "$domainlist")"
|
domainlist="$(_idn "$domainlist")"
|
||||||
@ -1637,7 +1637,7 @@ _stat() {
|
|||||||
#keyfile
|
#keyfile
|
||||||
_isRSA() {
|
_isRSA() {
|
||||||
keyfile=$1
|
keyfile=$1
|
||||||
if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || ${ACME_OPENSSL_BIN:-openssl} rsa -in "$keyfile" -noout -text | grep "^publicExponent:" >/dev/null 2>&1; then
|
if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || ${ACME_OPENSSL_BIN:-openssl} rsa -in "$keyfile" -noout -text 2>&1 | grep "^publicExponent:" 2>&1 >/dev/null; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
return 1
|
return 1
|
||||||
@ -1646,7 +1646,7 @@ _isRSA() {
|
|||||||
#keyfile
|
#keyfile
|
||||||
_isEcc() {
|
_isEcc() {
|
||||||
keyfile=$1
|
keyfile=$1
|
||||||
if grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || ${ACME_OPENSSL_BIN:-openssl} ec -in "$keyfile" -noout -text 2>/dev/null | grep "^NIST CURVE:" >/dev/null 2>&1; then
|
if grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || ${ACME_OPENSSL_BIN:-openssl} ec -in "$keyfile" -noout -text 2>/dev/null | grep "^NIST CURVE:" 2>&1 >/dev/null; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
return 1
|
return 1
|
||||||
@ -1744,7 +1744,7 @@ _calcjwk() {
|
|||||||
_debug3 x64 "$x64"
|
_debug3 x64 "$x64"
|
||||||
|
|
||||||
xend=$(_math "$xend" + 1)
|
xend=$(_math "$xend" + 1)
|
||||||
y="$(printf "%s" "$pubtext" | cut -d : -f "$xend"-10000)"
|
y="$(printf "%s" "$pubtext" | cut -d : -f "$xend"-2048)"
|
||||||
_debug3 y "$y"
|
_debug3 y "$y"
|
||||||
|
|
||||||
y64="$(printf "%s" "$y" | tr -d : | _h2b | _base64 | _url_replace)"
|
y64="$(printf "%s" "$y" | tr -d : | _h2b | _base64 | _url_replace)"
|
||||||
@ -1852,9 +1852,15 @@ _inithttp() {
|
|||||||
_ACME_CURL="$_ACME_CURL --cacert $CA_BUNDLE "
|
_ACME_CURL="$_ACME_CURL --cacert $CA_BUNDLE "
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if _contains "$(curl --help 2>&1)" "--globoff"; then
|
if _contains "$(curl --help 2>&1)" "--globoff" || _contains "$(curl --help curl 2>&1)" "--globoff"; then
|
||||||
_ACME_CURL="$_ACME_CURL -g "
|
_ACME_CURL="$_ACME_CURL -g "
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#don't use --fail-with-body
|
||||||
|
##from curl 7.76: return fail on HTTP errors but keep the body
|
||||||
|
#if _contains "$(curl --help http 2>&1)" "--fail-with-body"; then
|
||||||
|
# _ACME_CURL="$_ACME_CURL --fail-with-body "
|
||||||
|
#fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$_ACME_WGET" ] && _exists "wget"; then
|
if [ -z "$_ACME_WGET" ] && _exists "wget"; then
|
||||||
@ -1872,11 +1878,11 @@ _inithttp() {
|
|||||||
elif [ "$CA_BUNDLE" ]; then
|
elif [ "$CA_BUNDLE" ]; then
|
||||||
_ACME_WGET="$_ACME_WGET --ca-certificate=$CA_BUNDLE "
|
_ACME_WGET="$_ACME_WGET --ca-certificate=$CA_BUNDLE "
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
#from wget 1.14: do not skip body on 404 error
|
#from wget 1.14: do not skip body on 404 error
|
||||||
if [ "$_ACME_WGET" ] && _contains "$($_ACME_WGET --help 2>&1)" "--content-on-error"; then
|
if _contains "$(wget --help 2>&1)" "--content-on-error"; then
|
||||||
_ACME_WGET="$_ACME_WGET --content-on-error "
|
_ACME_WGET="$_ACME_WGET --content-on-error "
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
__HTTP_INITIALIZED=1
|
__HTTP_INITIALIZED=1
|
||||||
@ -1999,7 +2005,13 @@ _post() {
|
|||||||
if [ "$_ret" != "0" ]; then
|
if [ "$_ret" != "0" ]; then
|
||||||
_err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret"
|
_err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret"
|
||||||
fi
|
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
|
else
|
||||||
_ret="$?"
|
_ret="$?"
|
||||||
_err "Neither curl nor wget is found, can not do $httpmethod."
|
_err "Neither curl nor wget is found, can not do $httpmethod."
|
||||||
@ -2052,9 +2064,21 @@ _get() {
|
|||||||
fi
|
fi
|
||||||
_debug "_WGET" "$_WGET"
|
_debug "_WGET" "$_WGET"
|
||||||
if [ "$onlyheader" ]; then
|
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
|
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
|
fi
|
||||||
ret=$?
|
ret=$?
|
||||||
if [ "$ret" = "8" ]; then
|
if [ "$ret" = "8" ]; then
|
||||||
@ -2205,6 +2229,20 @@ _send_signed_request() {
|
|||||||
_debug3 _body "$_body"
|
_debug3 _body "$_body"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
_retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *: *[0-9]\+ *" | cut -d : -f 2 | tr -d ' ' | tr -d '\r')
|
||||||
|
if [ "$code" = '503' ]; then
|
||||||
|
_sleep_overload_retry_sec=$_retryafter
|
||||||
|
if [ -z "$_sleep_overload_retry_sec" ]; then
|
||||||
|
_sleep_overload_retry_sec=5
|
||||||
|
fi
|
||||||
|
if [ $_sleep_overload_retry_sec -le 600 ]; then
|
||||||
|
_info "It seems the CA server is currently overloaded, let's wait and retry. Sleeping $_sleep_overload_retry_sec seconds."
|
||||||
|
_sleep $_sleep_overload_retry_sec
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
_info "The retryafter=$_retryafter is too large > 600, not retry anymore."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
if _contains "$_body" "JWS has invalid anti-replay nonce" || _contains "$_body" "JWS has an invalid anti-replay nonce"; then
|
if _contains "$_body" "JWS has invalid anti-replay nonce" || _contains "$_body" "JWS has an invalid anti-replay nonce"; then
|
||||||
_info "It seems the CA server is busy now, let's wait and retry. Sleeping $_sleep_retry_sec seconds."
|
_info "It seems the CA server is busy now, let's wait and retry. Sleeping $_sleep_retry_sec seconds."
|
||||||
_CACHED_NONCE=""
|
_CACHED_NONCE=""
|
||||||
@ -2239,12 +2277,18 @@ _setopt() {
|
|||||||
if [ ! -f "$__conf" ]; then
|
if [ ! -f "$__conf" ]; then
|
||||||
touch "$__conf"
|
touch "$__conf"
|
||||||
fi
|
fi
|
||||||
|
if [ -n "$(tail -c 1 <"$__conf")" ]; then
|
||||||
|
echo >>"$__conf"
|
||||||
|
fi
|
||||||
|
|
||||||
if grep -n "^$__opt$__sep" "$__conf" >/dev/null; then
|
if grep -n "^$__opt$__sep" "$__conf" >/dev/null; then
|
||||||
_debug3 OK
|
_debug3 OK
|
||||||
if _contains "$__val" "&"; then
|
if _contains "$__val" "&"; then
|
||||||
__val="$(echo "$__val" | sed 's/&/\\&/g')"
|
__val="$(echo "$__val" | sed 's/&/\\&/g')"
|
||||||
fi
|
fi
|
||||||
|
if _contains "$__val" "|"; then
|
||||||
|
__val="$(echo "$__val" | sed 's/|/\\|/g')"
|
||||||
|
fi
|
||||||
text="$(cat "$__conf")"
|
text="$(cat "$__conf")"
|
||||||
printf -- "%s\n" "$text" | sed "s|^$__opt$__sep.*$|$__opt$__sep$__val$__end|" >"$__conf"
|
printf -- "%s\n" "$text" | sed "s|^$__opt$__sep.*$|$__opt$__sep$__val$__end|" >"$__conf"
|
||||||
|
|
||||||
@ -2252,6 +2296,9 @@ _setopt() {
|
|||||||
if _contains "$__val" "&"; then
|
if _contains "$__val" "&"; then
|
||||||
__val="$(echo "$__val" | sed 's/&/\\&/g')"
|
__val="$(echo "$__val" | sed 's/&/\\&/g')"
|
||||||
fi
|
fi
|
||||||
|
if _contains "$__val" "|"; then
|
||||||
|
__val="$(echo "$__val" | sed 's/|/\\|/g')"
|
||||||
|
fi
|
||||||
text="$(cat "$__conf")"
|
text="$(cat "$__conf")"
|
||||||
printf -- "%s\n" "$text" | sed "s|^#$__opt$__sep.*$|$__opt$__sep$__val$__end|" >"$__conf"
|
printf -- "%s\n" "$text" | sed "s|^#$__opt$__sep.*$|$__opt$__sep$__val$__end|" >"$__conf"
|
||||||
|
|
||||||
@ -2325,6 +2372,26 @@ _readdomainconf() {
|
|||||||
_read_conf "$DOMAIN_CONF" "$1"
|
_read_conf "$DOMAIN_CONF" "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#_migratedomainconf oldkey newkey base64encode
|
||||||
|
_migratedomainconf() {
|
||||||
|
_old_key="$1"
|
||||||
|
_new_key="$2"
|
||||||
|
_b64encode="$3"
|
||||||
|
_value=$(_readdomainconf "$_old_key")
|
||||||
|
if [ -z "$_value" ]; then
|
||||||
|
return 1 # oldkey is not found
|
||||||
|
fi
|
||||||
|
_savedomainconf "$_new_key" "$_value" "$_b64encode"
|
||||||
|
_cleardomainconf "$_old_key"
|
||||||
|
_debug "Domain config $_old_key has been migrated to $_new_key"
|
||||||
|
}
|
||||||
|
|
||||||
|
#_migratedeployconf oldkey newkey base64encode
|
||||||
|
_migratedeployconf() {
|
||||||
|
_migratedomainconf "$1" "SAVED_$2" "$3" ||
|
||||||
|
_migratedomainconf "SAVED_$1" "SAVED_$2" "$3" # try only when oldkey itself is not found
|
||||||
|
}
|
||||||
|
|
||||||
#key value base64encode
|
#key value base64encode
|
||||||
_savedeployconf() {
|
_savedeployconf() {
|
||||||
_savedomainconf "SAVED_$1" "$2" "$3"
|
_savedomainconf "SAVED_$1" "$2" "$3"
|
||||||
@ -2339,12 +2406,14 @@ _getdeployconf() {
|
|||||||
if [ "$_rac_value" ]; then
|
if [ "$_rac_value" ]; then
|
||||||
if _startswith "$_rac_value" '"' && _endswith "$_rac_value" '"'; then
|
if _startswith "$_rac_value" '"' && _endswith "$_rac_value" '"'; then
|
||||||
_debug2 "trim quotation marks"
|
_debug2 "trim quotation marks"
|
||||||
eval "export $_rac_key=$_rac_value"
|
eval $_rac_key=$_rac_value
|
||||||
|
export $_rac_key
|
||||||
fi
|
fi
|
||||||
return 0 # do nothing
|
return 0 # do nothing
|
||||||
fi
|
fi
|
||||||
_saved=$(_readdomainconf "SAVED_$_rac_key")
|
_saved="$(_readdomainconf "SAVED_$_rac_key")"
|
||||||
eval "export $_rac_key=\"\$_saved\""
|
eval $_rac_key=\$_saved
|
||||||
|
export $_rac_key
|
||||||
}
|
}
|
||||||
|
|
||||||
#_saveaccountconf key value base64encode
|
#_saveaccountconf key value base64encode
|
||||||
@ -2561,7 +2630,7 @@ __initHome() {
|
|||||||
_script_home="$(dirname "$_script")"
|
_script_home="$(dirname "$_script")"
|
||||||
_debug "_script_home" "$_script_home"
|
_debug "_script_home" "$_script_home"
|
||||||
if [ -d "$_script_home" ]; then
|
if [ -d "$_script_home" ]; then
|
||||||
_SCRIPT_HOME="$_script_home"
|
export _SCRIPT_HOME="$_script_home"
|
||||||
else
|
else
|
||||||
_err "It seems the script home is not correct:$_script_home"
|
_err "It seems the script home is not correct:$_script_home"
|
||||||
fi
|
fi
|
||||||
@ -2808,9 +2877,10 @@ _initpath() {
|
|||||||
|
|
||||||
if _isEccKey "$_ilength"; then
|
if _isEccKey "$_ilength"; then
|
||||||
DOMAIN_PATH="$domainhomeecc"
|
DOMAIN_PATH="$domainhomeecc"
|
||||||
else
|
elif [ -z "$__SELECTED_RSA_KEY" ]; then
|
||||||
if [ ! -d "$domainhome" ] && [ -d "$domainhomeecc" ]; then
|
if [ ! -d "$domainhome" ] && [ -d "$domainhomeecc" ]; then
|
||||||
_info "The domain '$domain' seems to have a ECC cert already, please add '$(__red "--ecc")' parameter if you want to use that cert."
|
_info "The domain '$domain' seems to have a ECC cert already, lets use ecc cert."
|
||||||
|
DOMAIN_PATH="$domainhomeecc"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
_debug DOMAIN_PATH "$DOMAIN_PATH"
|
_debug DOMAIN_PATH "$DOMAIN_PATH"
|
||||||
@ -3968,7 +4038,7 @@ _ns_purge_cf() {
|
|||||||
|
|
||||||
#checks if cf server is available
|
#checks if cf server is available
|
||||||
_ns_is_available_cf() {
|
_ns_is_available_cf() {
|
||||||
if _get "https://cloudflare-dns.com" "" 1 >/dev/null 2>&1; then
|
if _get "https://cloudflare-dns.com" "" 10 >/dev/null; then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
@ -3976,7 +4046,7 @@ _ns_is_available_cf() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ns_is_available_google() {
|
_ns_is_available_google() {
|
||||||
if _get "https://dns.google" "" 1 >/dev/null 2>&1; then
|
if _get "https://dns.google" "" 10 >/dev/null; then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
@ -3992,7 +4062,7 @@ _ns_lookup_google() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ns_is_available_ali() {
|
_ns_is_available_ali() {
|
||||||
if _get "https://dns.alidns.com" "" 1 >/dev/null 2>&1; then
|
if _get "https://dns.alidns.com" "" 10 >/dev/null; then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
@ -4008,7 +4078,7 @@ _ns_lookup_ali() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ns_is_available_dp() {
|
_ns_is_available_dp() {
|
||||||
if _get "https://doh.pub" "" 1 >/dev/null 2>&1; then
|
if _get "https://doh.pub" "" 10 >/dev/null; then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
@ -4023,8 +4093,7 @@ _ns_lookup_dp() {
|
|||||||
_ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type"
|
_ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type"
|
||||||
}
|
}
|
||||||
|
|
||||||
#domain, type
|
_ns_select_doh() {
|
||||||
_ns_lookup() {
|
|
||||||
if [ -z "$DOH_USE" ]; then
|
if [ -z "$DOH_USE" ]; then
|
||||||
_debug "Detect dns server first."
|
_debug "Detect dns server first."
|
||||||
if _ns_is_available_cf; then
|
if _ns_is_available_cf; then
|
||||||
@ -4043,7 +4112,11 @@ _ns_lookup() {
|
|||||||
_err "No doh"
|
_err "No doh"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#domain, type
|
||||||
|
_ns_lookup() {
|
||||||
|
_ns_select_doh
|
||||||
if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then
|
if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then
|
||||||
_ns_lookup_cf "$@"
|
_ns_lookup_cf "$@"
|
||||||
elif [ "$DOH_USE" = "$DOH_GOOGLE" ]; then
|
elif [ "$DOH_USE" = "$DOH_GOOGLE" ]; then
|
||||||
@ -4066,6 +4139,7 @@ __check_txt() {
|
|||||||
_debug "_c_txtdomain" "$_c_txtdomain"
|
_debug "_c_txtdomain" "$_c_txtdomain"
|
||||||
_debug "_c_aliasdomain" "$_c_aliasdomain"
|
_debug "_c_aliasdomain" "$_c_aliasdomain"
|
||||||
_debug "_c_txt" "$_c_txt"
|
_debug "_c_txt" "$_c_txt"
|
||||||
|
_ns_select_doh
|
||||||
_answers="$(_ns_lookup "$_c_aliasdomain" TXT)"
|
_answers="$(_ns_lookup "$_c_aliasdomain" TXT)"
|
||||||
_contains "$_answers" "$_c_txt"
|
_contains "$_answers" "$_c_txt"
|
||||||
|
|
||||||
@ -4396,6 +4470,7 @@ issue() {
|
|||||||
_debug "_saved_account_key_hash is not changed, skip register account."
|
_debug "_saved_account_key_hash is not changed, skip register account."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
export Le_Next_Domain_Key="$CERT_KEY_PATH.next"
|
||||||
if [ -f "$CSR_PATH" ] && [ ! -f "$CERT_KEY_PATH" ]; then
|
if [ -f "$CSR_PATH" ] && [ ! -f "$CERT_KEY_PATH" ]; then
|
||||||
_info "Signing from existing CSR."
|
_info "Signing from existing CSR."
|
||||||
else
|
else
|
||||||
@ -4408,14 +4483,30 @@ issue() {
|
|||||||
fi
|
fi
|
||||||
_debug "Read key length:$_key"
|
_debug "Read key length:$_key"
|
||||||
if [ ! -f "$CERT_KEY_PATH" ] || [ "$_key_length" != "$_key" ] || [ "$Le_ForceNewDomainKey" = "1" ]; then
|
if [ ! -f "$CERT_KEY_PATH" ] || [ "$_key_length" != "$_key" ] || [ "$Le_ForceNewDomainKey" = "1" ]; then
|
||||||
if ! createDomainKey "$_main_domain" "$_key_length"; then
|
if [ "$Le_ForceNewDomainKey" = "1" ] && [ -f "$Le_Next_Domain_Key" ]; then
|
||||||
_err "Create domain key error."
|
_info "Using pre generated key: $Le_Next_Domain_Key"
|
||||||
_clearup
|
cat "$Le_Next_Domain_Key" >"$CERT_KEY_PATH"
|
||||||
_on_issue_err "$_post_hook"
|
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
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! _createcsr "$_main_domain" "$_alt_domains" "$CERT_KEY_PATH" "$CSR_PATH" "$DOMAIN_SSL_CONF"; then
|
if ! _createcsr "$_main_domain" "$_alt_domains" "$CERT_KEY_PATH" "$CSR_PATH" "$DOMAIN_SSL_CONF"; then
|
||||||
_err "Create CSR error."
|
_err "Create CSR error."
|
||||||
_clearup
|
_clearup
|
||||||
@ -4866,7 +4957,9 @@ $_authorizations_map"
|
|||||||
_on_issue_err "$_post_hook" "$vlist"
|
_on_issue_err "$_post_hook" "$vlist"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
if ! chmod a+r "$wellknown_path/$token"; then
|
||||||
|
_debug "chmod failed, but we just continue."
|
||||||
|
fi
|
||||||
if [ ! "$usingApache" ]; then
|
if [ ! "$usingApache" ]; then
|
||||||
if webroot_owner=$(_stat "$_currentRoot"); then
|
if webroot_owner=$(_stat "$_currentRoot"); then
|
||||||
_debug "Changing owner/group of .well-known to $webroot_owner"
|
_debug "Changing owner/group of .well-known to $webroot_owner"
|
||||||
@ -5149,6 +5242,9 @@ $_authorizations_map"
|
|||||||
|
|
||||||
[ -f "$CA_CERT_PATH" ] && _info "The intermediate CA cert is in: $(__green "$CA_CERT_PATH")"
|
[ -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")"
|
[ -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)
|
Le_CertCreateTime=$(_time)
|
||||||
_savedomainconf "Le_CertCreateTime" "$Le_CertCreateTime"
|
_savedomainconf "Le_CertCreateTime" "$Le_CertCreateTime"
|
||||||
@ -5690,6 +5786,7 @@ deploy() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
_debug2 DOMAIN_CONF "$DOMAIN_CONF"
|
||||||
. "$DOMAIN_CONF"
|
. "$DOMAIN_CONF"
|
||||||
|
|
||||||
_savedomainconf Le_DeployHook "$_hooks"
|
_savedomainconf Le_DeployHook "$_hooks"
|
||||||
@ -5723,7 +5820,8 @@ installcert() {
|
|||||||
_savedomainconf "Le_RealKeyPath" "$_real_key"
|
_savedomainconf "Le_RealKeyPath" "$_real_key"
|
||||||
_savedomainconf "Le_ReloadCmd" "$_reload_cmd" "base64"
|
_savedomainconf "Le_ReloadCmd" "$_reload_cmd" "base64"
|
||||||
_savedomainconf "Le_RealFullChainPath" "$_real_fullchain"
|
_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"
|
_installcert "$_main_domain" "$_real_cert" "$_real_key" "$_real_ca" "$_real_fullchain" "$_reload_cmd"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5815,6 +5913,8 @@ _installcert() {
|
|||||||
export CA_CERT_PATH
|
export CA_CERT_PATH
|
||||||
export CERT_FULLCHAIN_PATH
|
export CERT_FULLCHAIN_PATH
|
||||||
export Le_Domain="$_main_domain"
|
export Le_Domain="$_main_domain"
|
||||||
|
export Le_ForceNewDomainKey
|
||||||
|
export Le_Next_Domain_Key
|
||||||
cd "$DOMAIN_PATH" && eval "$_reload_cmd"
|
cd "$DOMAIN_PATH" && eval "$_reload_cmd"
|
||||||
); then
|
); then
|
||||||
_info "$(__green "Reload success")"
|
_info "$(__green "Reload success")"
|
||||||
@ -6046,8 +6146,22 @@ revoke() {
|
|||||||
|
|
||||||
uri="${ACME_REVOKE_CERT}"
|
uri="${ACME_REVOKE_CERT}"
|
||||||
|
|
||||||
|
_info "Try account key first."
|
||||||
|
if _send_signed_request "$uri" "$data" "" "$ACCOUNT_KEY_PATH"; then
|
||||||
|
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."
|
||||||
|
_debug "$response"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -f "$CERT_KEY_PATH" ]; then
|
if [ -f "$CERT_KEY_PATH" ]; then
|
||||||
_info "Try domain key first."
|
_info "Try domain key."
|
||||||
if _send_signed_request "$uri" "$data" "" "$CERT_KEY_PATH"; then
|
if _send_signed_request "$uri" "$data" "" "$CERT_KEY_PATH"; then
|
||||||
if [ -z "$response" ]; then
|
if [ -z "$response" ]; then
|
||||||
_info "Revoke success."
|
_info "Revoke success."
|
||||||
@ -6063,21 +6177,6 @@ revoke() {
|
|||||||
else
|
else
|
||||||
_info "Domain key file doesn't exist."
|
_info "Domain key file doesn't exist."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_info "Try account key."
|
|
||||||
|
|
||||||
if _send_signed_request "$uri" "$data" "" "$ACCOUNT_KEY_PATH"; then
|
|
||||||
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."
|
|
||||||
_debug "$response"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6557,7 +6656,7 @@ install() {
|
|||||||
if [ "$_accountemail" ]; then
|
if [ "$_accountemail" ]; then
|
||||||
_saveaccountconf "ACCOUNT_EMAIL" "$_accountemail"
|
_saveaccountconf "ACCOUNT_EMAIL" "$_accountemail"
|
||||||
fi
|
fi
|
||||||
|
_saveaccountconf "UPGRADE_HASH" "$(_getUpgradeHash)"
|
||||||
_info OK
|
_info OK
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6651,6 +6750,13 @@ _send_notify() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
_nsource="$NOTIFY_SOURCE"
|
||||||
|
if [ -z "$_nsource" ]; then
|
||||||
|
_nsource="$(hostname)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_nsubject="$_nsubject by $_nsource"
|
||||||
|
|
||||||
_send_err=0
|
_send_err=0
|
||||||
for _n_hook in $(echo "$_nhooks" | tr ',' " "); do
|
for _n_hook in $(echo "$_nhooks" | tr ',' " "); do
|
||||||
_n_hook_file="$(_findHook "" $_SUB_FOLDER_NOTIFY "$_n_hook")"
|
_n_hook_file="$(_findHook "" $_SUB_FOLDER_NOTIFY "$_n_hook")"
|
||||||
@ -6705,11 +6811,12 @@ setnotify() {
|
|||||||
_nhook="$1"
|
_nhook="$1"
|
||||||
_nlevel="$2"
|
_nlevel="$2"
|
||||||
_nmode="$3"
|
_nmode="$3"
|
||||||
|
_nsource="$4"
|
||||||
|
|
||||||
_initpath
|
_initpath
|
||||||
|
|
||||||
if [ -z "$_nhook$_nlevel$_nmode" ]; then
|
if [ -z "$_nhook$_nlevel$_nmode$_nsource" ]; then
|
||||||
_usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook <hookname>] [--notify-level <0|1|2|3>] [--notify-mode <0|1>]"
|
_usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook <hookname>] [--notify-level <0|1|2|3>] [--notify-mode <0|1>] [--notify-source <hostname>]"
|
||||||
_usage "$_NOTIFY_WIKI"
|
_usage "$_NOTIFY_WIKI"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@ -6726,6 +6833,12 @@ setnotify() {
|
|||||||
_saveaccountconf "NOTIFY_MODE" "$NOTIFY_MODE"
|
_saveaccountconf "NOTIFY_MODE" "$NOTIFY_MODE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$_nsource" ]; then
|
||||||
|
_info "Set notify source to: $_nsource"
|
||||||
|
export "NOTIFY_SOURCE=$_nsource"
|
||||||
|
_saveaccountconf "NOTIFY_SOURCE" "$NOTIFY_SOURCE"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$_nhook" ]; then
|
if [ "$_nhook" ]; then
|
||||||
_info "Set notify hook to: $_nhook"
|
_info "Set notify hook to: $_nhook"
|
||||||
if [ "$_nhook" = "$NO_VALUE" ]; then
|
if [ "$_nhook" = "$NO_VALUE" ]; then
|
||||||
@ -6788,37 +6901,37 @@ Commands:
|
|||||||
Parameters:
|
Parameters:
|
||||||
-d, --domain <domain.tld> Specifies a domain, used to issue, renew or revoke etc.
|
-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.
|
--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.
|
--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.
|
--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)
|
If no match, the default offered chain will be used. (default: empty)
|
||||||
See: $_PREFERRED_CHAIN_WIKI
|
See: $_PREFERRED_CHAIN_WIKI
|
||||||
|
|
||||||
--valid-to <date-time> Request the NotAfter field of the cert.
|
--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.
|
--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.
|
-f, --force Force install, force cert renewal or override sudo restrictions.
|
||||||
--staging, --test Use staging server, for testing.
|
--staging, --test Use staging server, for testing.
|
||||||
--debug [0|1|2|3] Output debug info. Defaults to 1 if argument is omitted.
|
--debug [0|1|2|3] Output debug info. Defaults to 1 if argument is omitted.
|
||||||
--output-insecure Output all the sensitive messages.
|
--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.
|
-w, --webroot <directory> Specifies the web root folder for web root mode.
|
||||||
--standalone Use standalone mode.
|
--standalone Use standalone mode.
|
||||||
--alpn Use standalone alpn mode.
|
--alpn Use standalone alpn mode.
|
||||||
--stateless Use stateless mode.
|
--stateless Use stateless mode.
|
||||||
See: $_STATELESS_WIKI
|
See: $_STATELESS_WIKI
|
||||||
|
|
||||||
--apache Use apache mode.
|
--apache Use apache mode.
|
||||||
--dns [dns_hook] Use dns manual mode or dns api. Defaults to manual mode when argument is omitted.
|
--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.
|
--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.
|
-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
|
-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.
|
--log [file] Specifies the log file. Defaults to \"$DEFAULT_LOG_FILE\" if argument is omitted.
|
||||||
@ -6837,7 +6950,7 @@ Parameters:
|
|||||||
--reloadcmd <command> Command to execute after issue/renew to reload the server.
|
--reloadcmd <command> Command to execute after issue/renew to reload the server.
|
||||||
|
|
||||||
--server <server_uri> ACME Directory Resource URI. (default: $DEFAULT_CA)
|
--server <server_uri> ACME Directory Resource URI. (default: $DEFAULT_CA)
|
||||||
See: $_SERVER_WIKI
|
See: $_SERVER_WIKI
|
||||||
|
|
||||||
--accountconf <file> Specifies a customized account config file.
|
--accountconf <file> Specifies a customized account config file.
|
||||||
--home <directory> Specifies the home dir for $PROJECT_NAME.
|
--home <directory> Specifies the home dir for $PROJECT_NAME.
|
||||||
@ -6856,7 +6969,7 @@ Parameters:
|
|||||||
--ca-bundle <file> Specifies the path to the CA certificate bundle to verify api server's certificate.
|
--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.
|
--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.
|
--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-profile Only valid for '--install' command, which means: do not install aliases to user profile.
|
||||||
--no-color Do not output color text.
|
--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.
|
--force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails.
|
||||||
@ -6874,20 +6987,21 @@ Parameters:
|
|||||||
--openssl-bin <file> Specifies a custom openssl bin location.
|
--openssl-bin <file> Specifies a custom openssl bin location.
|
||||||
--use-wget Force to use wget, if you have both curl and wget installed.
|
--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.
|
--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.
|
-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.
|
--notify-level <0|1|2|3> Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT.
|
||||||
0: disabled, no notification will be sent.
|
0: disabled, no notification will be sent.
|
||||||
1: send notifications only when there is an error.
|
1: send notifications only when there is an error.
|
||||||
2: send notifications when a cert is successfully renewed, or 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.
|
3: send notifications when a cert is skipped, renewed, or error.
|
||||||
--notify-mode <0|1> Set notification mode. Default value is $NOTIFY_MODE_DEFAULT.
|
--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).
|
0: Bulk mode. Send all the domain's notifications in one message(mail).
|
||||||
1: Cert mode. Send a message for every single cert.
|
1: Cert mode. Send a message for every single cert.
|
||||||
--notify-hook <hookname> Set the notify hook
|
--notify-hook <hookname> Set the notify hook
|
||||||
|
--notify-source <server name> Set the server name in the notification message
|
||||||
--revoke-reason <0-10> The reason for revocation, can be used in conjunction with the '--revoke' command.
|
--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.
|
--password <password> Add a password to exported pfx file. Use with --to-pkcs12.
|
||||||
|
|
||||||
@ -6921,8 +7035,6 @@ installOnline() {
|
|||||||
chmod +x $PROJECT_ENTRY
|
chmod +x $PROJECT_ENTRY
|
||||||
if ./$PROJECT_ENTRY --install "$@"; then
|
if ./$PROJECT_ENTRY --install "$@"; then
|
||||||
_info "Install success!"
|
_info "Install success!"
|
||||||
_initpath
|
|
||||||
_saveaccountconf "UPGRADE_HASH" "$(_getUpgradeHash)"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
@ -7045,7 +7157,9 @@ _selectServer() {
|
|||||||
_getCAShortName() {
|
_getCAShortName() {
|
||||||
caurl="$1"
|
caurl="$1"
|
||||||
if [ -z "$caurl" ]; then
|
if [ -z "$caurl" ]; then
|
||||||
caurl="$DEFAULT_CA"
|
#use letsencrypt as default value if the Le_API is empty
|
||||||
|
#this case can only come from the old upgrading.
|
||||||
|
caurl="$CA_LETSENCRYPT_V2"
|
||||||
fi
|
fi
|
||||||
if [ "$CA_SSLCOM_ECC" = "$caurl" ]; then
|
if [ "$CA_SSLCOM_ECC" = "$caurl" ]; then
|
||||||
caurl="$CA_SSLCOM_RSA" #just hack to get the short name
|
caurl="$CA_SSLCOM_RSA" #just hack to get the short name
|
||||||
@ -7162,6 +7276,7 @@ _process() {
|
|||||||
_notify_hook=""
|
_notify_hook=""
|
||||||
_notify_level=""
|
_notify_level=""
|
||||||
_notify_mode=""
|
_notify_mode=""
|
||||||
|
_notify_source=""
|
||||||
_revoke_reason=""
|
_revoke_reason=""
|
||||||
_eab_kid=""
|
_eab_kid=""
|
||||||
_eab_hmac_key=""
|
_eab_hmac_key=""
|
||||||
@ -7407,6 +7522,9 @@ _process() {
|
|||||||
--keylength | -k)
|
--keylength | -k)
|
||||||
_keylength="$2"
|
_keylength="$2"
|
||||||
shift
|
shift
|
||||||
|
if [ "$_keylength" ] && ! _isEccKey "$_keylength"; then
|
||||||
|
export __SELECTED_RSA_KEY=1
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
-ak | --accountkeylength)
|
-ak | --accountkeylength)
|
||||||
_accountkeylength="$2"
|
_accountkeylength="$2"
|
||||||
@ -7442,17 +7560,17 @@ _process() {
|
|||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--home)
|
--home)
|
||||||
LE_WORKING_DIR="$2"
|
export LE_WORKING_DIR="$(echo "$2" | sed 's|/$||')"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--cert-home | --certhome)
|
--cert-home | --certhome)
|
||||||
_certhome="$2"
|
_certhome="$2"
|
||||||
CERT_HOME="$_certhome"
|
export CERT_HOME="$_certhome"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--config-home)
|
--config-home)
|
||||||
_confighome="$2"
|
_confighome="$2"
|
||||||
LE_CONFIG_HOME="$_confighome"
|
export LE_CONFIG_HOME="$_confighome"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--useragent)
|
--useragent)
|
||||||
@ -7654,6 +7772,15 @@ _process() {
|
|||||||
_notify_mode="$_nmode"
|
_notify_mode="$_nmode"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
--notify-source)
|
||||||
|
_nsource="$2"
|
||||||
|
if _startswith "$_nsource" "-"; then
|
||||||
|
_err "'$_nsource' is not valid host name for '$1'"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_notify_source="$_nsource"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
--revoke-reason)
|
--revoke-reason)
|
||||||
_revoke_reason="$2"
|
_revoke_reason="$2"
|
||||||
if _startswith "$_revoke_reason" "-"; then
|
if _startswith "$_revoke_reason" "-"; then
|
||||||
@ -7808,7 +7935,7 @@ _process() {
|
|||||||
createCSR "$_domain" "$_altdomains" "$_ecc"
|
createCSR "$_domain" "$_altdomains" "$_ecc"
|
||||||
;;
|
;;
|
||||||
setnotify)
|
setnotify)
|
||||||
setnotify "$_notify_hook" "$_notify_level" "$_notify_mode"
|
setnotify "$_notify_hook" "$_notify_level" "$_notify_mode" "$_notify_source"
|
||||||
;;
|
;;
|
||||||
setdefaultca)
|
setdefaultca)
|
||||||
setdefaultca
|
setdefaultca
|
||||||
|
@ -3,18 +3,29 @@
|
|||||||
# Uses command line uapi. --user option is needed only if run as root.
|
# Uses command line uapi. --user option is needed only if run as root.
|
||||||
# Returns 0 when success.
|
# 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
|
# 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/
|
# or contact me, visit https://forum.webseodesigners.com/web-design-seo-and-hosting-f16/
|
||||||
#
|
#
|
||||||
# Written by Santeri Kannisto <santeri.kannisto@webseodesigners.com>
|
# Written by Santeri Kannisto <santeri.kannisto@webseodesigners.com>
|
||||||
# Public domain, 2017-2018
|
# 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 #####################
|
######## Public functions #####################
|
||||||
|
|
||||||
#domain keyfile certfile cafile fullchain
|
#domain keyfile certfile cafile fullchain
|
||||||
|
|
||||||
cpanel_uapi_deploy() {
|
cpanel_uapi_deploy() {
|
||||||
_cdomain="$1"
|
_cdomain="$1"
|
||||||
_ckey="$2"
|
_ckey="$2"
|
||||||
@ -22,6 +33,9 @@ cpanel_uapi_deploy() {
|
|||||||
_cca="$4"
|
_cca="$4"
|
||||||
_cfullchain="$5"
|
_cfullchain="$5"
|
||||||
|
|
||||||
|
# re-declare vars inherited from acme.sh but not passed to make ShellCheck happy
|
||||||
|
: "${Le_Alt:=""}"
|
||||||
|
|
||||||
_debug _cdomain "$_cdomain"
|
_debug _cdomain "$_cdomain"
|
||||||
_debug _ckey "$_ckey"
|
_debug _ckey "$_ckey"
|
||||||
_debug _ccert "$_ccert"
|
_debug _ccert "$_ccert"
|
||||||
@ -32,31 +46,166 @@ cpanel_uapi_deploy() {
|
|||||||
_err "The command uapi is not found."
|
_err "The command uapi is not found."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# declare useful constants
|
||||||
|
uapi_error_response='status: 0'
|
||||||
|
|
||||||
# read cert and key files and urlencode both
|
# read cert and key files and urlencode both
|
||||||
_cert=$(_url_encode <"$_ccert")
|
_cert=$(_url_encode <"$_ccert")
|
||||||
_key=$(_url_encode <"$_ckey")
|
_key=$(_url_encode <"$_ckey")
|
||||||
|
|
||||||
_debug _cert "$_cert"
|
_debug2 _cert "$_cert"
|
||||||
_debug _key "$_key"
|
_debug2 _key "$_key"
|
||||||
|
|
||||||
if [ "$(id -u)" = 0 ]; then
|
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"
|
_err "It seems that you are root, please define the target user name: export DEPLOY_CPANEL_USER=username"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_savedomainconf DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER"
|
_debug DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER"
|
||||||
_response=$(uapi --user="$DEPLOY_CPANEL_USER" SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
|
_savedeployconf DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER"
|
||||||
else
|
|
||||||
_response=$(uapi SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
|
_uapi_user="$DEPLOY_CPANEL_USER"
|
||||||
fi
|
|
||||||
error_response="status: 0"
|
|
||||||
if test "${_response#*$error_response}" != "$_response"; then
|
|
||||||
_err "Error in deploying certificate:"
|
|
||||||
_err "$_response"
|
|
||||||
return 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_debug response "$_response"
|
# Load all AUTO envars and set defaults - see above for usage
|
||||||
_info "Certificate successfully deployed"
|
__cpanel_initautoparam ENABLED 'true'
|
||||||
return 0
|
__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\"")"
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
# Here is the script to deploy the cert to G-Core CDN service (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/).
|
# Here is the script to deploy the cert to G-Core CDN service (https://gcore.com/) using the G-Core Labs API (https://apidocs.gcore.com/cdn).
|
||||||
# Returns 0 when success.
|
# Returns 0 when success.
|
||||||
#
|
#
|
||||||
# Written by temoffey <temofffey@gmail.com>
|
# Written by temoffey <temofffey@gmail.com>
|
||||||
# Public domain, 2019
|
# Public domain, 2019
|
||||||
|
# Update by DreamOfIce <admin@dreamofice.cn> in 2023
|
||||||
|
|
||||||
#export DEPLOY_GCORE_CDN_USERNAME=myusername
|
#export DEPLOY_GCORE_CDN_USERNAME=myusername
|
||||||
#export DEPLOY_GCORE_CDN_PASSWORD=mypassword
|
#export DEPLOY_GCORE_CDN_PASSWORD=mypassword
|
||||||
@ -56,7 +57,7 @@ gcore_cdn_deploy() {
|
|||||||
_request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}"
|
_request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}"
|
||||||
_debug _request "$_request"
|
_debug _request "$_request"
|
||||||
export _H1="Content-Type:application/json"
|
export _H1="Content-Type:application/json"
|
||||||
_response=$(_post "$_request" "https://api.gcdn.co/auth/jwt/login")
|
_response=$(_post "$_request" "https://api.gcore.com/auth/jwt/login")
|
||||||
_debug _response "$_response"
|
_debug _response "$_response"
|
||||||
_regex=".*\"access\":\"\([-._0-9A-Za-z]*\)\".*$"
|
_regex=".*\"access\":\"\([-._0-9A-Za-z]*\)\".*$"
|
||||||
_debug _regex "$_regex"
|
_debug _regex "$_regex"
|
||||||
@ -69,8 +70,8 @@ gcore_cdn_deploy() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
_info "Find CDN resource with cname $_cdomain"
|
_info "Find CDN resource with cname $_cdomain"
|
||||||
export _H2="Authorization:Token $_token"
|
export _H2="Authorization:Bearer $_token"
|
||||||
_response=$(_get "https://api.gcdn.co/resources")
|
_response=$(_get "https://api.gcore.com/cdn/resources")
|
||||||
_debug _response "$_response"
|
_debug _response "$_response"
|
||||||
_regex="\"primary_resource\":null},"
|
_regex="\"primary_resource\":null},"
|
||||||
_debug _regex "$_regex"
|
_debug _regex "$_regex"
|
||||||
@ -102,7 +103,7 @@ gcore_cdn_deploy() {
|
|||||||
_date=$(date "+%d.%m.%Y %H:%M:%S")
|
_date=$(date "+%d.%m.%Y %H:%M:%S")
|
||||||
_request="{\"name\":\"$_cdomain ($_date)\",\"sslCertificate\":\"$_fullchain\",\"sslPrivateKey\":\"$_key\"}"
|
_request="{\"name\":\"$_cdomain ($_date)\",\"sslCertificate\":\"$_fullchain\",\"sslPrivateKey\":\"$_key\"}"
|
||||||
_debug _request "$_request"
|
_debug _request "$_request"
|
||||||
_response=$(_post "$_request" "https://api.gcdn.co/sslData")
|
_response=$(_post "$_request" "https://api.gcore.com/cdn/sslData")
|
||||||
_debug _response "$_response"
|
_debug _response "$_response"
|
||||||
_regex=".*\"id\":\([0-9]*\).*$"
|
_regex=".*\"id\":\([0-9]*\).*$"
|
||||||
_debug _regex "$_regex"
|
_debug _regex "$_regex"
|
||||||
@ -117,7 +118,7 @@ gcore_cdn_deploy() {
|
|||||||
_info "Update CDN resource"
|
_info "Update CDN resource"
|
||||||
_request="{\"originGroup\":$_originGroup,\"sslData\":$_sslDataAdd}"
|
_request="{\"originGroup\":$_originGroup,\"sslData\":$_sslDataAdd}"
|
||||||
_debug _request "$_request"
|
_debug _request "$_request"
|
||||||
_response=$(_post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT")
|
_response=$(_post "$_request" "https://api.gcore.com/cdn/resources/$_resourceId" '' "PUT")
|
||||||
_debug _response "$_response"
|
_debug _response "$_response"
|
||||||
_regex=".*\"sslData\":\([0-9]*\).*$"
|
_regex=".*\"sslData\":\([0-9]*\).*$"
|
||||||
_debug _regex "$_regex"
|
_debug _regex "$_regex"
|
||||||
@ -133,7 +134,7 @@ gcore_cdn_deploy() {
|
|||||||
_info "Not found old SSL certificate"
|
_info "Not found old SSL certificate"
|
||||||
else
|
else
|
||||||
_info "Delete old SSL certificate"
|
_info "Delete old SSL certificate"
|
||||||
_response=$(_post '' "https://api.gcdn.co/sslData/$_sslDataOld" '' "DELETE")
|
_response=$(_post '' "https://api.gcore.com/cdn/sslData/$_sslDataOld" '' "DELETE")
|
||||||
_debug _response "$_response"
|
_debug _response "$_response"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ gitlab_deploy() {
|
|||||||
|
|
||||||
error_response="error"
|
error_response="error"
|
||||||
|
|
||||||
if test "${_response#*$error_response}" != "$_response"; then
|
if test "${_response#*"$error_response"}" != "$_response"; then
|
||||||
_err "Error in deploying certificate:"
|
_err "Error in deploying certificate:"
|
||||||
_err "$_response"
|
_err "$_response"
|
||||||
return 1
|
return 1
|
||||||
|
409
deploy/ssh.sh
409
deploy/ssh.sh
@ -14,7 +14,7 @@
|
|||||||
# The following examples are for QNAP NAS running QTS 4.2
|
# The following examples are for QNAP NAS running QTS 4.2
|
||||||
# export DEPLOY_SSH_CMD="" # defaults to "ssh -T"
|
# export DEPLOY_SSH_CMD="" # defaults to "ssh -T"
|
||||||
# export DEPLOY_SSH_USER="admin" # required
|
# export DEPLOY_SSH_USER="admin" # required
|
||||||
# export DEPLOY_SSH_SERVER="qnap" # defaults to domain name
|
# export DEPLOY_SSH_SERVER="host1 host2:8022 192.168.0.1:9022" # defaults to domain name, support multiple servers with optional port
|
||||||
# export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem"
|
# export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem"
|
||||||
# export DEPLOY_SSH_CERTFILE="/etc/stunnel/stunnel.pem"
|
# export DEPLOY_SSH_CERTFILE="/etc/stunnel/stunnel.pem"
|
||||||
# export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem"
|
# export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem"
|
||||||
@ -23,6 +23,8 @@
|
|||||||
# export DEPLOY_SSH_BACKUP="" # yes or no, default to yes or previously saved value
|
# export DEPLOY_SSH_BACKUP="" # yes or no, default to yes or previously saved value
|
||||||
# export DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" # path on remote system. Defaults to .acme_ssh_deploy
|
# export DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" # path on remote system. Defaults to .acme_ssh_deploy
|
||||||
# export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value
|
# export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value
|
||||||
|
# export DEPLOY_SSH_USE_SCP="" yes or no, default to no
|
||||||
|
# export DEPLOY_SSH_SCP_CMD="" defaults to "scp -q"
|
||||||
#
|
#
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
||||||
@ -42,72 +44,134 @@ ssh_deploy() {
|
|||||||
_debug _cfullchain "$_cfullchain"
|
_debug _cfullchain "$_cfullchain"
|
||||||
|
|
||||||
# USER is required to login by SSH to remote host.
|
# USER is required to login by SSH to remote host.
|
||||||
|
_migratedeployconf Le_Deploy_ssh_user DEPLOY_SSH_USER
|
||||||
_getdeployconf DEPLOY_SSH_USER
|
_getdeployconf DEPLOY_SSH_USER
|
||||||
_debug2 DEPLOY_SSH_USER "$DEPLOY_SSH_USER"
|
_debug2 DEPLOY_SSH_USER "$DEPLOY_SSH_USER"
|
||||||
if [ -z "$DEPLOY_SSH_USER" ]; then
|
if [ -z "$DEPLOY_SSH_USER" ]; then
|
||||||
if [ -z "$Le_Deploy_ssh_user" ]; then
|
_err "DEPLOY_SSH_USER not defined."
|
||||||
_err "DEPLOY_SSH_USER not defined."
|
return 1
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
Le_Deploy_ssh_user="$DEPLOY_SSH_USER"
|
|
||||||
_savedomainconf Le_Deploy_ssh_user "$Le_Deploy_ssh_user"
|
|
||||||
fi
|
fi
|
||||||
|
_savedeployconf DEPLOY_SSH_USER "$DEPLOY_SSH_USER"
|
||||||
|
|
||||||
# SERVER is optional. If not provided then use _cdomain
|
# SERVER is optional. If not provided then use _cdomain
|
||||||
|
_migratedeployconf Le_Deploy_ssh_server DEPLOY_SSH_SERVER
|
||||||
_getdeployconf DEPLOY_SSH_SERVER
|
_getdeployconf DEPLOY_SSH_SERVER
|
||||||
_debug2 DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER"
|
_debug2 DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER"
|
||||||
if [ -n "$DEPLOY_SSH_SERVER" ]; then
|
if [ -z "$DEPLOY_SSH_SERVER" ]; then
|
||||||
Le_Deploy_ssh_server="$DEPLOY_SSH_SERVER"
|
DEPLOY_SSH_SERVER="$_cdomain"
|
||||||
_savedomainconf Le_Deploy_ssh_server "$Le_Deploy_ssh_server"
|
|
||||||
elif [ -z "$Le_Deploy_ssh_server" ]; then
|
|
||||||
Le_Deploy_ssh_server="$_cdomain"
|
|
||||||
fi
|
fi
|
||||||
|
_savedeployconf DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER"
|
||||||
|
|
||||||
# CMD is optional. If not provided then use ssh
|
# CMD is optional. If not provided then use ssh
|
||||||
|
_migratedeployconf Le_Deploy_ssh_cmd DEPLOY_SSH_CMD
|
||||||
_getdeployconf DEPLOY_SSH_CMD
|
_getdeployconf DEPLOY_SSH_CMD
|
||||||
_debug2 DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD"
|
_debug2 DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD"
|
||||||
if [ -n "$DEPLOY_SSH_CMD" ]; then
|
if [ -z "$DEPLOY_SSH_CMD" ]; then
|
||||||
Le_Deploy_ssh_cmd="$DEPLOY_SSH_CMD"
|
DEPLOY_SSH_CMD="ssh -T"
|
||||||
_savedomainconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd"
|
|
||||||
elif [ -z "$Le_Deploy_ssh_cmd" ]; then
|
|
||||||
Le_Deploy_ssh_cmd="ssh -T"
|
|
||||||
fi
|
fi
|
||||||
|
_savedeployconf DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD"
|
||||||
|
|
||||||
# BACKUP is optional. If not provided then default to previously saved value or yes.
|
# BACKUP is optional. If not provided then default to previously saved value or yes.
|
||||||
|
_migratedeployconf Le_Deploy_ssh_backup DEPLOY_SSH_BACKUP
|
||||||
_getdeployconf DEPLOY_SSH_BACKUP
|
_getdeployconf DEPLOY_SSH_BACKUP
|
||||||
_debug2 DEPLOY_SSH_BACKUP "$DEPLOY_SSH_BACKUP"
|
_debug2 DEPLOY_SSH_BACKUP "$DEPLOY_SSH_BACKUP"
|
||||||
if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then
|
if [ -z "$DEPLOY_SSH_BACKUP" ]; then
|
||||||
Le_Deploy_ssh_backup="no"
|
DEPLOY_SSH_BACKUP="yes"
|
||||||
elif [ -z "$Le_Deploy_ssh_backup" ] || [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
|
|
||||||
Le_Deploy_ssh_backup="yes"
|
|
||||||
fi
|
fi
|
||||||
_savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup"
|
_savedeployconf DEPLOY_SSH_BACKUP "$DEPLOY_SSH_BACKUP"
|
||||||
|
|
||||||
# BACKUP_PATH is optional. If not provided then default to previously saved value or .acme_ssh_deploy
|
# BACKUP_PATH is optional. If not provided then default to previously saved value or .acme_ssh_deploy
|
||||||
|
_migratedeployconf Le_Deploy_ssh_backup_path DEPLOY_SSH_BACKUP_PATH
|
||||||
_getdeployconf DEPLOY_SSH_BACKUP_PATH
|
_getdeployconf DEPLOY_SSH_BACKUP_PATH
|
||||||
_debug2 DEPLOY_SSH_BACKUP_PATH "$DEPLOY_SSH_BACKUP_PATH"
|
_debug2 DEPLOY_SSH_BACKUP_PATH "$DEPLOY_SSH_BACKUP_PATH"
|
||||||
if [ -n "$DEPLOY_SSH_BACKUP_PATH" ]; then
|
if [ -z "$DEPLOY_SSH_BACKUP_PATH" ]; then
|
||||||
Le_Deploy_ssh_backup_path="$DEPLOY_SSH_BACKUP_PATH"
|
DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy"
|
||||||
elif [ -z "$Le_Deploy_ssh_backup_path" ]; then
|
|
||||||
Le_Deploy_ssh_backup_path=".acme_ssh_deploy"
|
|
||||||
fi
|
fi
|
||||||
_savedomainconf Le_Deploy_ssh_backup_path "$Le_Deploy_ssh_backup_path"
|
_savedeployconf DEPLOY_SSH_BACKUP_PATH "$DEPLOY_SSH_BACKUP_PATH"
|
||||||
|
|
||||||
# MULTI_CALL is optional. If not provided then default to previously saved
|
# MULTI_CALL is optional. If not provided then default to previously saved
|
||||||
# value (which may be undefined... equivalent to "no").
|
# value (which may be undefined... equivalent to "no").
|
||||||
|
_migratedeployconf Le_Deploy_ssh_multi_call DEPLOY_SSH_MULTI_CALL
|
||||||
_getdeployconf DEPLOY_SSH_MULTI_CALL
|
_getdeployconf DEPLOY_SSH_MULTI_CALL
|
||||||
_debug2 DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL"
|
_debug2 DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL"
|
||||||
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
|
if [ -z "$DEPLOY_SSH_MULTI_CALL" ]; then
|
||||||
Le_Deploy_ssh_multi_call="yes"
|
DEPLOY_SSH_MULTI_CALL="no"
|
||||||
_savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call"
|
fi
|
||||||
elif [ "$DEPLOY_SSH_MULTI_CALL" = "no" ]; then
|
_savedeployconf DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL"
|
||||||
Le_Deploy_ssh_multi_call=""
|
|
||||||
_cleardomainconf Le_Deploy_ssh_multi_call
|
# KEYFILE is optional.
|
||||||
|
# If provided then private key will be copied to provided filename.
|
||||||
|
_migratedeployconf Le_Deploy_ssh_keyfile DEPLOY_SSH_KEYFILE
|
||||||
|
_getdeployconf DEPLOY_SSH_KEYFILE
|
||||||
|
_debug2 DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE"
|
||||||
|
if [ -n "$DEPLOY_SSH_KEYFILE" ]; then
|
||||||
|
_savedeployconf DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_deploy_ssh_servers=$Le_Deploy_ssh_server
|
# CERTFILE is optional.
|
||||||
for Le_Deploy_ssh_server in $_deploy_ssh_servers; do
|
# If provided then certificate will be copied or appended to provided filename.
|
||||||
|
_migratedeployconf Le_Deploy_ssh_certfile DEPLOY_SSH_CERTFILE
|
||||||
|
_getdeployconf DEPLOY_SSH_CERTFILE
|
||||||
|
_debug2 DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE"
|
||||||
|
if [ -n "$DEPLOY_SSH_CERTFILE" ]; then
|
||||||
|
_savedeployconf DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# CAFILE is optional.
|
||||||
|
# If provided then CA intermediate certificate will be copied or appended to provided filename.
|
||||||
|
_migratedeployconf Le_Deploy_ssh_cafile DEPLOY_SSH_CAFILE
|
||||||
|
_getdeployconf DEPLOY_SSH_CAFILE
|
||||||
|
_debug2 DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE"
|
||||||
|
if [ -n "$DEPLOY_SSH_CAFILE" ]; then
|
||||||
|
_savedeployconf DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# FULLCHAIN is optional.
|
||||||
|
# If provided then fullchain certificate will be copied or appended to provided filename.
|
||||||
|
_migratedeployconf Le_Deploy_ssh_fullchain DEPLOY_SSH_FULLCHAIN
|
||||||
|
_getdeployconf DEPLOY_SSH_FULLCHAIN
|
||||||
|
_debug2 DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN"
|
||||||
|
if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then
|
||||||
|
_savedeployconf DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# REMOTE_CMD is optional.
|
||||||
|
# If provided then this command will be executed on remote host.
|
||||||
|
_migratedeployconf Le_Deploy_ssh_remote_cmd DEPLOY_SSH_REMOTE_CMD
|
||||||
|
_getdeployconf DEPLOY_SSH_REMOTE_CMD
|
||||||
|
_debug2 DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD"
|
||||||
|
if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then
|
||||||
|
_savedeployconf DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# USE_SCP is optional. If not provided then default to previously saved
|
||||||
|
# value (which may be undefined... equivalent to "no").
|
||||||
|
_getdeployconf DEPLOY_SSH_USE_SCP
|
||||||
|
_debug2 DEPLOY_SSH_USE_SCP "$DEPLOY_SSH_USE_SCP"
|
||||||
|
if [ -z "$DEPLOY_SSH_USE_SCP" ]; then
|
||||||
|
DEPLOY_SSH_USE_SCP="no"
|
||||||
|
fi
|
||||||
|
_savedeployconf DEPLOY_SSH_USE_SCP "$DEPLOY_SSH_USE_SCP"
|
||||||
|
|
||||||
|
# SCP_CMD is optional. If not provided then use scp
|
||||||
|
_getdeployconf DEPLOY_SSH_SCP_CMD
|
||||||
|
_debug2 DEPLOY_SSH_SCP_CMD "$DEPLOY_SSH_SCP_CMD"
|
||||||
|
if [ -z "$DEPLOY_SSH_SCP_CMD" ]; then
|
||||||
|
DEPLOY_SSH_SCP_CMD="scp -q"
|
||||||
|
fi
|
||||||
|
_savedeployconf DEPLOY_SSH_SCP_CMD "$DEPLOY_SSH_SCP_CMD"
|
||||||
|
|
||||||
|
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then
|
||||||
|
DEPLOY_SSH_MULTI_CALL="yes"
|
||||||
|
_info "Using scp as alternate method for copying files. Multicall Mode is implicit"
|
||||||
|
elif [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
|
||||||
|
_info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host"
|
||||||
|
else
|
||||||
|
_info "Required commands batched and sent in single call to remote host"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_deploy_ssh_servers="$DEPLOY_SSH_SERVER"
|
||||||
|
for DEPLOY_SSH_SERVER in $_deploy_ssh_servers; do
|
||||||
_ssh_deploy
|
_ssh_deploy
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@ -117,16 +181,25 @@ _ssh_deploy() {
|
|||||||
_cmdstr=""
|
_cmdstr=""
|
||||||
_backupprefix=""
|
_backupprefix=""
|
||||||
_backupdir=""
|
_backupdir=""
|
||||||
|
_local_cert_file=""
|
||||||
|
_local_ca_file=""
|
||||||
|
_local_full_file=""
|
||||||
|
|
||||||
_info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server"
|
case $DEPLOY_SSH_SERVER in
|
||||||
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
|
*:*)
|
||||||
_info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host"
|
_host=${DEPLOY_SSH_SERVER%:*}
|
||||||
else
|
_port=${DEPLOY_SSH_SERVER##*:}
|
||||||
_info "Required commands batched and sent in single call to remote host"
|
;;
|
||||||
fi
|
*)
|
||||||
|
_host=$DEPLOY_SSH_SERVER
|
||||||
|
_port=
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
if [ "$Le_Deploy_ssh_backup" = "yes" ]; then
|
_info "Deploy certificates to remote server $DEPLOY_SSH_USER@$_host:$_port"
|
||||||
_backupprefix="$Le_Deploy_ssh_backup_path/$_cdomain-backup"
|
|
||||||
|
if [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
|
||||||
|
_backupprefix="$DEPLOY_SSH_BACKUP_PATH/$_cdomain-backup"
|
||||||
_backupdir="$_backupprefix-$(_utc_date | tr ' ' '-')"
|
_backupdir="$_backupprefix-$(_utc_date | tr ' ' '-')"
|
||||||
# run cleanup on the backup directory, erase all older
|
# run cleanup on the backup directory, erase all older
|
||||||
# than 180 days (15552000 seconds).
|
# than 180 days (15552000 seconds).
|
||||||
@ -138,7 +211,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
|
|||||||
_cmdstr="mkdir -p $_backupdir; $_cmdstr"
|
_cmdstr="mkdir -p $_backupdir; $_cmdstr"
|
||||||
_info "Backup of old certificate files will be placed in remote directory $_backupdir"
|
_info "Backup of old certificate files will be placed in remote directory $_backupdir"
|
||||||
_info "Backup directories erased after 180 days."
|
_info "Backup directories erased after 180 days."
|
||||||
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
|
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
|
||||||
if ! _ssh_remote_cmd "$_cmdstr"; then
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
return $_err_code
|
return $_err_code
|
||||||
fi
|
fi
|
||||||
@ -146,129 +219,184 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# KEYFILE is optional.
|
|
||||||
# If provided then private key will be copied to provided filename.
|
|
||||||
_getdeployconf DEPLOY_SSH_KEYFILE
|
|
||||||
_debug2 DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE"
|
|
||||||
if [ -n "$DEPLOY_SSH_KEYFILE" ]; then
|
if [ -n "$DEPLOY_SSH_KEYFILE" ]; then
|
||||||
Le_Deploy_ssh_keyfile="$DEPLOY_SSH_KEYFILE"
|
if [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
|
||||||
_savedomainconf Le_Deploy_ssh_keyfile "$Le_Deploy_ssh_keyfile"
|
|
||||||
fi
|
|
||||||
if [ -n "$Le_Deploy_ssh_keyfile" ]; then
|
|
||||||
if [ "$Le_Deploy_ssh_backup" = "yes" ]; then
|
|
||||||
# backup file we are about to overwrite.
|
# backup file we are about to overwrite.
|
||||||
_cmdstr="$_cmdstr cp $Le_Deploy_ssh_keyfile $_backupdir >/dev/null;"
|
_cmdstr="$_cmdstr cp $DEPLOY_SSH_KEYFILE $_backupdir >/dev/null;"
|
||||||
|
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
|
||||||
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
|
return $_err_code
|
||||||
|
fi
|
||||||
|
_cmdstr=""
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
# copy new certificate into file.
|
|
||||||
_cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;"
|
# copy new key into file.
|
||||||
_info "will copy private key to remote file $Le_Deploy_ssh_keyfile"
|
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then
|
||||||
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
|
# scp the file
|
||||||
if ! _ssh_remote_cmd "$_cmdstr"; then
|
if ! _scp_remote_cmd "$_ckey" "$DEPLOY_SSH_KEYFILE"; then
|
||||||
return $_err_code
|
return $_err_code
|
||||||
fi
|
fi
|
||||||
_cmdstr=""
|
else
|
||||||
|
# ssh echo to the file
|
||||||
|
_cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $DEPLOY_SSH_KEYFILE;"
|
||||||
|
_info "will copy private key to remote file $DEPLOY_SSH_KEYFILE"
|
||||||
|
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
|
||||||
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
|
return $_err_code
|
||||||
|
fi
|
||||||
|
_cmdstr=""
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# CERTFILE is optional.
|
|
||||||
# If provided then certificate will be copied or appended to provided filename.
|
|
||||||
_getdeployconf DEPLOY_SSH_CERTFILE
|
|
||||||
_debug2 DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE"
|
|
||||||
if [ -n "$DEPLOY_SSH_CERTFILE" ]; then
|
if [ -n "$DEPLOY_SSH_CERTFILE" ]; then
|
||||||
Le_Deploy_ssh_certfile="$DEPLOY_SSH_CERTFILE"
|
|
||||||
_savedomainconf Le_Deploy_ssh_certfile "$Le_Deploy_ssh_certfile"
|
|
||||||
fi
|
|
||||||
if [ -n "$Le_Deploy_ssh_certfile" ]; then
|
|
||||||
_pipe=">"
|
_pipe=">"
|
||||||
if [ "$Le_Deploy_ssh_certfile" = "$Le_Deploy_ssh_keyfile" ]; then
|
if [ "$DEPLOY_SSH_CERTFILE" = "$DEPLOY_SSH_KEYFILE" ]; then
|
||||||
# if filename is same as previous file then append.
|
# if filename is same as previous file then append.
|
||||||
_pipe=">>"
|
_pipe=">>"
|
||||||
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
|
elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
|
||||||
# backup file we are about to overwrite.
|
# backup file we are about to overwrite.
|
||||||
_cmdstr="$_cmdstr cp $Le_Deploy_ssh_certfile $_backupdir >/dev/null;"
|
_cmdstr="$_cmdstr cp $DEPLOY_SSH_CERTFILE $_backupdir >/dev/null;"
|
||||||
|
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
|
||||||
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
|
return $_err_code
|
||||||
|
fi
|
||||||
|
_cmdstr=""
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# copy new certificate into file.
|
# copy new certificate into file.
|
||||||
_cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;"
|
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then
|
||||||
_info "will copy certificate to remote file $Le_Deploy_ssh_certfile"
|
# scp the file
|
||||||
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
|
_local_cert_file=$(_mktemp)
|
||||||
if ! _ssh_remote_cmd "$_cmdstr"; then
|
if [ "$DEPLOY_SSH_CERTFILE" = "$DEPLOY_SSH_KEYFILE" ]; then
|
||||||
|
cat "$_ckey" >>"$_local_cert_file"
|
||||||
|
fi
|
||||||
|
cat "$_ccert" >>"$_local_cert_file"
|
||||||
|
if ! _scp_remote_cmd "$_local_cert_file" "$DEPLOY_SSH_CERTFILE"; then
|
||||||
return $_err_code
|
return $_err_code
|
||||||
fi
|
fi
|
||||||
_cmdstr=""
|
else
|
||||||
|
# ssh echo to the file
|
||||||
|
_cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $DEPLOY_SSH_CERTFILE;"
|
||||||
|
_info "will copy certificate to remote file $DEPLOY_SSH_CERTFILE"
|
||||||
|
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
|
||||||
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
|
return $_err_code
|
||||||
|
fi
|
||||||
|
_cmdstr=""
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# CAFILE is optional.
|
|
||||||
# If provided then CA intermediate certificate will be copied or appended to provided filename.
|
|
||||||
_getdeployconf DEPLOY_SSH_CAFILE
|
|
||||||
_debug2 DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE"
|
|
||||||
if [ -n "$DEPLOY_SSH_CAFILE" ]; then
|
if [ -n "$DEPLOY_SSH_CAFILE" ]; then
|
||||||
Le_Deploy_ssh_cafile="$DEPLOY_SSH_CAFILE"
|
|
||||||
_savedomainconf Le_Deploy_ssh_cafile "$Le_Deploy_ssh_cafile"
|
|
||||||
fi
|
|
||||||
if [ -n "$Le_Deploy_ssh_cafile" ]; then
|
|
||||||
_pipe=">"
|
_pipe=">"
|
||||||
if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] ||
|
if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_KEYFILE" ] ||
|
||||||
[ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then
|
[ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_CERTFILE" ]; then
|
||||||
# if filename is same as previous file then append.
|
# if filename is same as previous file then append.
|
||||||
_pipe=">>"
|
_pipe=">>"
|
||||||
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
|
elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
|
||||||
# backup file we are about to overwrite.
|
# backup file we are about to overwrite.
|
||||||
_cmdstr="$_cmdstr cp $Le_Deploy_ssh_cafile $_backupdir >/dev/null;"
|
_cmdstr="$_cmdstr cp $DEPLOY_SSH_CAFILE $_backupdir >/dev/null;"
|
||||||
|
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
|
||||||
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
|
return $_err_code
|
||||||
|
fi
|
||||||
|
_cmdstr=""
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# copy new certificate into file.
|
# copy new certificate into file.
|
||||||
_cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;"
|
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then
|
||||||
_info "will copy CA file to remote file $Le_Deploy_ssh_cafile"
|
# scp the file
|
||||||
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
|
_local_ca_file=$(_mktemp)
|
||||||
if ! _ssh_remote_cmd "$_cmdstr"; then
|
if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_KEYFILE" ]; then
|
||||||
|
cat "$_ckey" >>"$_local_ca_file"
|
||||||
|
fi
|
||||||
|
if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_CERTFILE" ]; then
|
||||||
|
cat "$_ccert" >>"$_local_ca_file"
|
||||||
|
fi
|
||||||
|
cat "$_cca" >>"$_local_ca_file"
|
||||||
|
if ! _scp_remote_cmd "$_local_ca_file" "$DEPLOY_SSH_CAFILE"; then
|
||||||
return $_err_code
|
return $_err_code
|
||||||
fi
|
fi
|
||||||
_cmdstr=""
|
else
|
||||||
|
# ssh echo to the file
|
||||||
|
_cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $DEPLOY_SSH_CAFILE;"
|
||||||
|
_info "will copy CA file to remote file $DEPLOY_SSH_CAFILE"
|
||||||
|
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
|
||||||
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
|
return $_err_code
|
||||||
|
fi
|
||||||
|
_cmdstr=""
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# FULLCHAIN is optional.
|
|
||||||
# If provided then fullchain certificate will be copied or appended to provided filename.
|
|
||||||
_getdeployconf DEPLOY_SSH_FULLCHAIN
|
|
||||||
_debug2 DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN"
|
|
||||||
if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then
|
if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then
|
||||||
Le_Deploy_ssh_fullchain="$DEPLOY_SSH_FULLCHAIN"
|
|
||||||
_savedomainconf Le_Deploy_ssh_fullchain "$Le_Deploy_ssh_fullchain"
|
|
||||||
fi
|
|
||||||
if [ -n "$Le_Deploy_ssh_fullchain" ]; then
|
|
||||||
_pipe=">"
|
_pipe=">"
|
||||||
if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] ||
|
if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_KEYFILE" ] ||
|
||||||
[ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ] ||
|
[ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CERTFILE" ] ||
|
||||||
[ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then
|
[ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CAFILE" ]; then
|
||||||
# if filename is same as previous file then append.
|
# if filename is same as previous file then append.
|
||||||
_pipe=">>"
|
_pipe=">>"
|
||||||
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
|
elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
|
||||||
# backup file we are about to overwrite.
|
# backup file we are about to overwrite.
|
||||||
_cmdstr="$_cmdstr cp $Le_Deploy_ssh_fullchain $_backupdir >/dev/null;"
|
_cmdstr="$_cmdstr cp $DEPLOY_SSH_FULLCHAIN $_backupdir >/dev/null;"
|
||||||
|
if [ "$DEPLOY_SSH_FULLCHAIN" = "yes" ]; then
|
||||||
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
|
return $_err_code
|
||||||
|
fi
|
||||||
|
_cmdstr=""
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# copy new certificate into file.
|
# copy new certificate into file.
|
||||||
_cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;"
|
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then
|
||||||
_info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain"
|
# scp the file
|
||||||
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
|
_local_full_file=$(_mktemp)
|
||||||
if ! _ssh_remote_cmd "$_cmdstr"; then
|
if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_KEYFILE" ]; then
|
||||||
|
cat "$_ckey" >>"$_local_full_file"
|
||||||
|
fi
|
||||||
|
if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CERTFILE" ]; then
|
||||||
|
cat "$_ccert" >>"$_local_full_file"
|
||||||
|
fi
|
||||||
|
if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CAFILE" ]; then
|
||||||
|
cat "$_cca" >>"$_local_full_file"
|
||||||
|
fi
|
||||||
|
cat "$_cfullchain" >>"$_local_full_file"
|
||||||
|
if ! _scp_remote_cmd "$_local_full_file" "$DEPLOY_SSH_FULLCHAIN"; then
|
||||||
return $_err_code
|
return $_err_code
|
||||||
fi
|
fi
|
||||||
_cmdstr=""
|
else
|
||||||
|
# ssh echo to the file
|
||||||
|
_cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $DEPLOY_SSH_FULLCHAIN;"
|
||||||
|
_info "will copy fullchain to remote file $DEPLOY_SSH_FULLCHAIN"
|
||||||
|
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
|
||||||
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
|
return $_err_code
|
||||||
|
fi
|
||||||
|
_cmdstr=""
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# REMOTE_CMD is optional.
|
# cleanup local files if any
|
||||||
# If provided then this command will be executed on remote host.
|
if [ -f "$_local_cert_file" ]; then
|
||||||
_getdeployconf DEPLOY_SSH_REMOTE_CMD
|
rm -f "$_local_cert_file"
|
||||||
_debug2 DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD"
|
|
||||||
if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then
|
|
||||||
Le_Deploy_ssh_remote_cmd="$DEPLOY_SSH_REMOTE_CMD"
|
|
||||||
_savedomainconf Le_Deploy_ssh_remote_cmd "$Le_Deploy_ssh_remote_cmd"
|
|
||||||
fi
|
fi
|
||||||
if [ -n "$Le_Deploy_ssh_remote_cmd" ]; then
|
if [ -f "$_local_ca_file" ]; then
|
||||||
_cmdstr="$_cmdstr $Le_Deploy_ssh_remote_cmd;"
|
rm -f "$_local_ca_file"
|
||||||
_info "Will execute remote command $Le_Deploy_ssh_remote_cmd"
|
fi
|
||||||
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
|
if [ -f "$_local_full_file" ]; then
|
||||||
|
rm -f "$_local_full_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then
|
||||||
|
_cmdstr="$_cmdstr $DEPLOY_SSH_REMOTE_CMD;"
|
||||||
|
_info "Will execute remote command $DEPLOY_SSH_REMOTE_CMD"
|
||||||
|
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
|
||||||
if ! _ssh_remote_cmd "$_cmdstr"; then
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
return $_err_code
|
return $_err_code
|
||||||
fi
|
fi
|
||||||
@ -282,17 +410,25 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
|
|||||||
return $_err_code
|
return $_err_code
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
# cleanup in case all is ok
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
#cmd
|
#cmd
|
||||||
_ssh_remote_cmd() {
|
_ssh_remote_cmd() {
|
||||||
_cmd="$1"
|
_cmd="$1"
|
||||||
|
|
||||||
|
_ssh_cmd="$DEPLOY_SSH_CMD"
|
||||||
|
if [ -n "$_port" ]; then
|
||||||
|
_ssh_cmd="$_ssh_cmd -p $_port"
|
||||||
|
fi
|
||||||
|
|
||||||
_secure_debug "Remote commands to execute: $_cmd"
|
_secure_debug "Remote commands to execute: $_cmd"
|
||||||
_info "Submitting sequence of commands to remote server by ssh"
|
_info "Submitting sequence of commands to remote server by $_ssh_cmd"
|
||||||
|
|
||||||
# quotations in bash cmd below intended. Squash travis spellcheck error
|
# quotations in bash cmd below intended. Squash travis spellcheck error
|
||||||
# shellcheck disable=SC2029
|
# shellcheck disable=SC2029
|
||||||
$Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmd'"
|
$_ssh_cmd "$DEPLOY_SSH_USER@$_host" sh -c "'$_cmd'"
|
||||||
_err_code="$?"
|
_err_code="$?"
|
||||||
|
|
||||||
if [ "$_err_code" != "0" ]; then
|
if [ "$_err_code" != "0" ]; then
|
||||||
@ -301,3 +437,26 @@ _ssh_remote_cmd() {
|
|||||||
|
|
||||||
return $_err_code
|
return $_err_code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# cmd scp
|
||||||
|
_scp_remote_cmd() {
|
||||||
|
_src=$1
|
||||||
|
_dest=$2
|
||||||
|
|
||||||
|
_scp_cmd="$DEPLOY_SSH_SCP_CMD"
|
||||||
|
if [ -n "$_port" ]; then
|
||||||
|
_scp_cmd="$_scp_cmd -P $_port"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_secure_debug "Remote copy source $_src to destination $_dest"
|
||||||
|
_info "Submitting secure copy by $_scp_cmd"
|
||||||
|
|
||||||
|
$_scp_cmd "$_src" "$DEPLOY_SSH_USER"@"$_host":"$_dest"
|
||||||
|
_err_code="$?"
|
||||||
|
|
||||||
|
if [ "$_err_code" != "0" ]; then
|
||||||
|
_err "Error code $_err_code returned from scp"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return $_err_code
|
||||||
|
}
|
||||||
|
@ -108,7 +108,7 @@ synology_dsm_deploy() {
|
|||||||
_debug3 H1 "${_H1}"
|
_debug3 H1 "${_H1}"
|
||||||
fi
|
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')
|
token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p')
|
||||||
_debug3 response "$response"
|
_debug3 response "$response"
|
||||||
_debug token "$token"
|
_debug token "$token"
|
||||||
|
@ -184,6 +184,27 @@ truenas_deploy() {
|
|||||||
_info "S3 certificate is not configured or is not the same as TrueNAS web UI"
|
_info "S3 certificate is not configured or is not the same as TrueNAS web UI"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
_info "Checking if any chart release Apps is using the same certificate as TrueNAS web UI. Tool 'jq' is required"
|
||||||
|
if _exists jq; then
|
||||||
|
_info "Query all chart release"
|
||||||
|
_release_list=$(_get "$_api_url/chart/release")
|
||||||
|
_related_name_list=$(printf "%s" "$_release_list" | jq -r "[.[] | {name,certId: .config.ingress?.main.tls[]?.scaleCert} | select(.certId==$_active_cert_id) | .name ] | unique")
|
||||||
|
_release_length=$(printf "%s" "$_related_name_list" | jq -r "length")
|
||||||
|
_info "Found $_release_length related chart release in list: $_related_name_list"
|
||||||
|
for i in $(seq 0 $((_release_length - 1))); do
|
||||||
|
_release_name=$(echo "$_related_name_list" | jq -r ".[$i]")
|
||||||
|
_info "Updating certificate from $_active_cert_id to $_cert_id for chart release: $_release_name"
|
||||||
|
#Read the chart release configuration
|
||||||
|
_chart_config=$(printf "%s" "$_release_list" | jq -r ".[] | select(.name==\"$_release_name\")")
|
||||||
|
#Replace the old certificate id with the new one in path .config.ingress.main.tls[].scaleCert. Then update .config.ingress
|
||||||
|
_updated_chart_config=$(printf "%s" "$_chart_config" | jq "(.config.ingress?.main.tls[]? | select(.scaleCert==$_active_cert_id) | .scaleCert ) |= $_cert_id | .config.ingress ")
|
||||||
|
_update_chart_result="$(_post "{\"values\" : { \"ingress\" : $_updated_chart_config } }" "$_api_url/chart/release/id/$_release_name" "" "PUT" "application/json")"
|
||||||
|
_debug3 _update_chart_result "$_update_chart_result"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
_info "Tool 'jq' does not exists, skip chart release checking"
|
||||||
|
fi
|
||||||
|
|
||||||
_info "Deleting old certificate"
|
_info "Deleting old certificate"
|
||||||
_delete_result="$(_post "" "$_api_url/certificate/id/$_active_cert_id" "" "DELETE" "application/json")"
|
_delete_result="$(_post "" "$_api_url/certificate/id/$_active_cert_id" "" "DELETE" "application/json")"
|
||||||
|
|
||||||
|
@ -7,13 +7,16 @@
|
|||||||
#
|
#
|
||||||
# VAULT_PREFIX - this contains the prefix path in vault
|
# VAULT_PREFIX - this contains the prefix path in vault
|
||||||
# VAULT_ADDR - vault requires this to find your vault server
|
# VAULT_ADDR - vault requires this to find your vault server
|
||||||
|
# VAULT_SAVE_TOKEN - set to anything if you want to save the token
|
||||||
|
# VAULT_RENEW_TOKEN - set to anything if you want to renew the token to default TTL before deploying
|
||||||
|
# VAULT_KV_V2 - set to anything if you are using v2 of the kv engine
|
||||||
#
|
#
|
||||||
# additionally, you need to ensure that VAULT_TOKEN is avialable
|
# additionally, you need to ensure that VAULT_TOKEN is avialable
|
||||||
# to access the vault server
|
# to access the vault server
|
||||||
|
|
||||||
#returns 0 means success, otherwise error.
|
#returns 0 means success, otherwise error.
|
||||||
|
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
||||||
#domain keyfile certfile cafile fullchain
|
#domain keyfile certfile cafile fullchain
|
||||||
vault_deploy() {
|
vault_deploy() {
|
||||||
@ -45,6 +48,26 @@ vault_deploy() {
|
|||||||
fi
|
fi
|
||||||
_savedeployconf VAULT_ADDR "$VAULT_ADDR"
|
_savedeployconf VAULT_ADDR "$VAULT_ADDR"
|
||||||
|
|
||||||
|
_getdeployconf VAULT_SAVE_TOKEN
|
||||||
|
_savedeployconf VAULT_SAVE_TOKEN "$VAULT_SAVE_TOKEN"
|
||||||
|
|
||||||
|
_getdeployconf VAULT_RENEW_TOKEN
|
||||||
|
_savedeployconf VAULT_RENEW_TOKEN "$VAULT_RENEW_TOKEN"
|
||||||
|
|
||||||
|
_getdeployconf VAULT_KV_V2
|
||||||
|
_savedeployconf VAULT_KV_V2 "$VAULT_KV_V2"
|
||||||
|
|
||||||
|
_getdeployconf VAULT_TOKEN
|
||||||
|
if [ -z "$VAULT_TOKEN" ]; then
|
||||||
|
_err "VAULT_TOKEN needs to be defined"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ -n "$VAULT_SAVE_TOKEN" ]; then
|
||||||
|
_savedeployconf VAULT_TOKEN "$VAULT_TOKEN"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_migratedeployconf FABIO VAULT_FABIO_MODE
|
||||||
|
|
||||||
# JSON does not allow multiline strings.
|
# JSON does not allow multiline strings.
|
||||||
# So replacing new-lines with "\n" here
|
# So replacing new-lines with "\n" here
|
||||||
_ckey=$(sed -z 's/\n/\\n/g' <"$2")
|
_ckey=$(sed -z 's/\n/\\n/g' <"$2")
|
||||||
@ -52,26 +75,56 @@ vault_deploy() {
|
|||||||
_cca=$(sed -z 's/\n/\\n/g' <"$4")
|
_cca=$(sed -z 's/\n/\\n/g' <"$4")
|
||||||
_cfullchain=$(sed -z 's/\n/\\n/g' <"$5")
|
_cfullchain=$(sed -z 's/\n/\\n/g' <"$5")
|
||||||
|
|
||||||
URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain"
|
|
||||||
export _H1="X-Vault-Token: $VAULT_TOKEN"
|
export _H1="X-Vault-Token: $VAULT_TOKEN"
|
||||||
|
|
||||||
if [ -n "$FABIO" ]; then
|
if [ -n "$VAULT_RENEW_TOKEN" ]; then
|
||||||
|
URL="$VAULT_ADDR/v1/auth/token/renew-self"
|
||||||
|
_info "Renew the Vault token to default TTL"
|
||||||
|
if ! _post "" "$URL" >/dev/null; then
|
||||||
|
_err "Failed to renew the Vault token"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain"
|
||||||
|
|
||||||
|
if [ -n "$VAULT_FABIO_MODE" ]; then
|
||||||
|
_info "Writing certificate and key to $URL in Fabio mode"
|
||||||
if [ -n "$VAULT_KV_V2" ]; then
|
if [ -n "$VAULT_KV_V2" ]; then
|
||||||
_post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL"
|
_post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL" >/dev/null || return 1
|
||||||
else
|
else
|
||||||
_post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL"
|
_post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" >/dev/null || return 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [ -n "$VAULT_KV_V2" ]; then
|
if [ -n "$VAULT_KV_V2" ]; then
|
||||||
_post "{\"data\": {\"value\": \"$_ccert\"}}" "$URL/cert.pem"
|
_info "Writing certificate to $URL/cert.pem"
|
||||||
_post "{\"data\": {\"value\": \"$_ckey\"}}" "$URL/cert.key"
|
_post "{\"data\": {\"value\": \"$_ccert\"}}" "$URL/cert.pem" >/dev/null || return 1
|
||||||
_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/chain.pem"
|
_info "Writing key to $URL/cert.key"
|
||||||
_post "{\"data\": {\"value\": \"$_cfullchain\"}}" "$URL/fullchain.pem"
|
_post "{\"data\": {\"value\": \"$_ckey\"}}" "$URL/cert.key" >/dev/null || return 1
|
||||||
|
_info "Writing CA certificate to $URL/ca.pem"
|
||||||
|
_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/ca.pem" >/dev/null || return 1
|
||||||
|
_info "Writing full-chain certificate to $URL/fullchain.pem"
|
||||||
|
_post "{\"data\": {\"value\": \"$_cfullchain\"}}" "$URL/fullchain.pem" >/dev/null || return 1
|
||||||
else
|
else
|
||||||
_post "{\"value\": \"$_ccert\"}" "$URL/cert.pem"
|
_info "Writing certificate to $URL/cert.pem"
|
||||||
_post "{\"value\": \"$_ckey\"}" "$URL/cert.key"
|
_post "{\"value\": \"$_ccert\"}" "$URL/cert.pem" >/dev/null || return 1
|
||||||
_post "{\"value\": \"$_cca\"}" "$URL/chain.pem"
|
_info "Writing key to $URL/cert.key"
|
||||||
_post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem"
|
_post "{\"value\": \"$_ckey\"}" "$URL/cert.key" >/dev/null || return 1
|
||||||
|
_info "Writing CA certificate to $URL/ca.pem"
|
||||||
|
_post "{\"value\": \"$_cca\"}" "$URL/ca.pem" >/dev/null || return 1
|
||||||
|
_info "Writing full-chain certificate to $URL/fullchain.pem"
|
||||||
|
_post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" >/dev/null || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# To make it compatible with the wrong ca path `chain.pem` which was used in former versions
|
||||||
|
if _contains "$(_get "$URL/chain.pem")" "-----BEGIN CERTIFICATE-----"; then
|
||||||
|
_err "The CA certificate has moved from chain.pem to ca.pem, if you don't depend on chain.pem anymore, you can delete it to avoid this warning"
|
||||||
|
_info "Updating CA certificate to $URL/chain.pem for backward compatibility"
|
||||||
|
if [ -n "$VAULT_KV_V2" ]; then
|
||||||
|
_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/chain.pem" >/dev/null || return 1
|
||||||
|
else
|
||||||
|
_post "{\"value\": \"$_cca\"}" "$URL/chain.pem" >/dev/null || return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#
|
#
|
||||||
# VAULT_PREFIX - this contains the prefix path in vault
|
# VAULT_PREFIX - this contains the prefix path in vault
|
||||||
# VAULT_ADDR - vault requires this to find your vault server
|
# VAULT_ADDR - vault requires this to find your vault server
|
||||||
|
# VAULT_SAVE_TOKEN - set to anything if you want to save the token
|
||||||
|
# VAULT_RENEW_TOKEN - set to anything if you want to renew the token to default TTL before deploying
|
||||||
#
|
#
|
||||||
# additionally, you need to ensure that VAULT_TOKEN is avialable or
|
# additionally, you need to ensure that VAULT_TOKEN is avialable or
|
||||||
# `vault auth` has applied the appropriate authorization for the vault binary
|
# `vault auth` has applied the appropriate authorization for the vault binary
|
||||||
@ -33,15 +35,36 @@ vault_cli_deploy() {
|
|||||||
_debug _cfullchain "$_cfullchain"
|
_debug _cfullchain "$_cfullchain"
|
||||||
|
|
||||||
# validate required env vars
|
# validate required env vars
|
||||||
|
_getdeployconf VAULT_PREFIX
|
||||||
if [ -z "$VAULT_PREFIX" ]; then
|
if [ -z "$VAULT_PREFIX" ]; then
|
||||||
_err "VAULT_PREFIX needs to be defined (contains prefix path in vault)"
|
_err "VAULT_PREFIX needs to be defined (contains prefix path in vault)"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
_savedeployconf VAULT_PREFIX "$VAULT_PREFIX"
|
||||||
|
|
||||||
|
_getdeployconf VAULT_ADDR
|
||||||
if [ -z "$VAULT_ADDR" ]; then
|
if [ -z "$VAULT_ADDR" ]; then
|
||||||
_err "VAULT_ADDR needs to be defined (contains vault connection address)"
|
_err "VAULT_ADDR needs to be defined (contains vault connection address)"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
_savedeployconf VAULT_ADDR "$VAULT_ADDR"
|
||||||
|
|
||||||
|
_getdeployconf VAULT_SAVE_TOKEN
|
||||||
|
_savedeployconf VAULT_SAVE_TOKEN "$VAULT_SAVE_TOKEN"
|
||||||
|
|
||||||
|
_getdeployconf VAULT_RENEW_TOKEN
|
||||||
|
_savedeployconf VAULT_RENEW_TOKEN "$VAULT_RENEW_TOKEN"
|
||||||
|
|
||||||
|
_getdeployconf VAULT_TOKEN
|
||||||
|
if [ -z "$VAULT_TOKEN" ]; then
|
||||||
|
_err "VAULT_TOKEN needs to be defined"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ -n "$VAULT_SAVE_TOKEN" ]; then
|
||||||
|
_savedeployconf VAULT_TOKEN "$VAULT_TOKEN"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_migratedeployconf FABIO VAULT_FABIO_MODE
|
||||||
|
|
||||||
VAULT_CMD=$(command -v vault)
|
VAULT_CMD=$(command -v vault)
|
||||||
if [ ! $? ]; then
|
if [ ! $? ]; then
|
||||||
@ -49,13 +72,33 @@ vault_cli_deploy() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$FABIO" ]; then
|
if [ -n "$VAULT_RENEW_TOKEN" ]; then
|
||||||
|
_info "Renew the Vault token to default TTL"
|
||||||
|
if ! $VAULT_CMD token renew; then
|
||||||
|
_err "Failed to renew the Vault token"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$VAULT_FABIO_MODE" ]; then
|
||||||
|
_info "Writing certificate and key to ${VAULT_PREFIX}/${_cdomain} in Fabio mode"
|
||||||
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1
|
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1
|
||||||
else
|
else
|
||||||
|
_info "Writing certificate to ${VAULT_PREFIX}/${_cdomain}/cert.pem"
|
||||||
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1
|
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1
|
||||||
|
_info "Writing key to ${VAULT_PREFIX}/${_cdomain}/cert.key"
|
||||||
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1
|
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1
|
||||||
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1
|
_info "Writing CA certificate to ${VAULT_PREFIX}/${_cdomain}/ca.pem"
|
||||||
|
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/ca.pem" value=@"$_cca" || return 1
|
||||||
|
_info "Writing full-chain certificate to ${VAULT_PREFIX}/${_cdomain}/fullchain.pem"
|
||||||
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1
|
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1
|
||||||
|
|
||||||
|
# To make it compatible with the wrong ca path `chain.pem` which was used in former versions
|
||||||
|
if $VAULT_CMD kv get "${VAULT_PREFIX}/${_cdomain}/chain.pem" >/dev/null; then
|
||||||
|
_err "The CA certificate has moved from chain.pem to ca.pem, if you don't depend on chain.pem anymore, you can delete it to avoid this warning"
|
||||||
|
_info "Updating CA certificate to ${VAULT_PREFIX}/${_cdomain}/chain.pem for backward compatibility"
|
||||||
|
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env sh
|
#!/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
|
## API integration by Maarten den Braber
|
||||||
##
|
##
|
||||||
## Report any bugs via https://github.com/mdbraber/acme.sh
|
## Report any bugs via https://github.com/mdbraber/acme.sh
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
#Arvan_Token="Apikey xxxx"
|
# Arvan_Token="Apikey xxxx"
|
||||||
|
|
||||||
ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains"
|
ARVAN_API_URL="https://napi.arvancloud.ir/cdn/4.0/domains"
|
||||||
#Author: Vahid Fardi
|
# Author: Vahid Fardi
|
||||||
#Report Bugs here: https://github.com/Neilpang/acme.sh
|
# Report Bugs here: https://github.com/Neilpang/acme.sh
|
||||||
#
|
#
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ dns_arvan_add() {
|
|||||||
|
|
||||||
if [ -z "$Arvan_Token" ]; then
|
if [ -z "$Arvan_Token" ]; then
|
||||||
_err "You didn't specify \"Arvan_Token\" token yet."
|
_err "You didn't specify \"Arvan_Token\" token yet."
|
||||||
_err "You can get yours from here https://npanel.arvancloud.com/profile/api-keys"
|
_err "You can get yours from here https://npanel.arvancloud.ir/profile/api-keys"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
#save the api token to the account conf file.
|
#save the api token to the account conf file.
|
||||||
@ -40,7 +40,7 @@ dns_arvan_add() {
|
|||||||
_info "response id is $response"
|
_info "response id is $response"
|
||||||
_info "Added, OK"
|
_info "Added, OK"
|
||||||
return 0
|
return 0
|
||||||
elif _contains "$response" "Record Data is Duplicated"; then
|
elif _contains "$response" "Record Data is duplicate"; then
|
||||||
_info "Already exists, OK"
|
_info "Already exists, OK"
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
@ -141,6 +141,7 @@ _arvan_rest() {
|
|||||||
response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")"
|
response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")"
|
||||||
elif [ "$mtd" = "POST" ]; then
|
elif [ "$mtd" = "POST" ]; then
|
||||||
export _H2="Content-Type: application/json"
|
export _H2="Content-Type: application/json"
|
||||||
|
export _H3="Accept: application/json"
|
||||||
_debug data "$data"
|
_debug data "$data"
|
||||||
response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")"
|
response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")"
|
||||||
else
|
else
|
||||||
|
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
|
||||||
|
}
|
@ -78,7 +78,7 @@ dns_cloudns_rm() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for i in $(echo "$response" | tr '{' "\n" | grep "$record"); do
|
for i in $(echo "$response" | tr '{' "\n" | grep -- "$record"); do
|
||||||
record_id=$(echo "$i" | tr ',' "\n" | grep -E '^"id"' | sed -re 's/^\"id\"\:\"([0-9]+)\"$/\1/g')
|
record_id=$(echo "$i" | tr ',' "\n" | grep -E '^"id"' | sed -re 's/^\"id\"\:\"([0-9]+)\"$/\1/g')
|
||||||
|
|
||||||
if [ -n "$record_id" ]; then
|
if [ -n "$record_id" ]; then
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
# cPanel_Hostname=hostname
|
# cPanel_Hostname=hostname
|
||||||
#
|
#
|
||||||
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
|
||||||
# Used to add txt record
|
# Used to add txt record
|
||||||
dns_cpanel_add() {
|
dns_cpanel_add() {
|
||||||
fulldomain=$1
|
fulldomain=$1
|
||||||
@ -120,7 +121,7 @@ _myget() {
|
|||||||
|
|
||||||
_get_root() {
|
_get_root() {
|
||||||
_myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones'
|
_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 "_result is: $_result"
|
||||||
_debug "_domains is: $_domains"
|
_debug "_domains is: $_domains"
|
||||||
if [ -z "$_domains" ]; then
|
if [ -z "$_domains" ]; then
|
||||||
@ -138,15 +139,15 @@ _get_root() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_successful_update() {
|
_successful_update() {
|
||||||
if (echo "$_result" | grep -q 'newserial'); then return 0; fi
|
if (echo "$_result" | _egrep_o 'data":\[[^]]*]' | grep -q '"newserial":null'); then return 1; fi
|
||||||
return 1
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
_findentry() {
|
_findentry() {
|
||||||
_debug "In _findentry"
|
_debug "In _findentry"
|
||||||
#returns id of dns entry, if it exists
|
#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"
|
_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 "_result is: $_result"
|
||||||
_debug "fulldomain. is $fulldomain."
|
_debug "fulldomain. is $fulldomain."
|
||||||
_debug "txtvalue is $txtvalue"
|
_debug "txtvalue is $txtvalue"
|
||||||
|
@ -192,6 +192,7 @@ _get_base_domain() {
|
|||||||
## get URL for the list of domains
|
## 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"}}
|
## 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"
|
DOMURL="https://api.digitalocean.com/v2/domains"
|
||||||
|
found=""
|
||||||
|
|
||||||
## while we dont have a matching domain we keep going
|
## while we dont have a matching domain we keep going
|
||||||
while [ -z "$found" ]; do
|
while [ -z "$found" ]; do
|
||||||
@ -205,9 +206,7 @@ _get_base_domain() {
|
|||||||
fi
|
fi
|
||||||
_debug2 domain_list "$domain_list"
|
_debug2 domain_list "$domain_list"
|
||||||
|
|
||||||
## for each shortening of our $fulldomain, check if it exists in the $domain_list
|
i=1
|
||||||
## can never start on 1 (aka whole $fulldomain) as $fulldomain starts with "_acme-challenge"
|
|
||||||
i=2
|
|
||||||
while [ $i -gt 0 ]; do
|
while [ $i -gt 0 ]; do
|
||||||
## get next longest domain
|
## get next longest domain
|
||||||
_domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM")
|
_domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM")
|
||||||
|
@ -13,8 +13,8 @@ DNSServices_API=https://dns.services/api
|
|||||||
|
|
||||||
#Usage: dns_dnsservices_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
#Usage: dns_dnsservices_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
dns_dnsservices_add() {
|
dns_dnsservices_add() {
|
||||||
fulldomain=$1
|
fulldomain="$1"
|
||||||
txtvalue=$2
|
txtvalue="$2"
|
||||||
|
|
||||||
_info "Using dns.services to create ACME DNS challenge"
|
_info "Using dns.services to create ACME DNS challenge"
|
||||||
_debug2 add_fulldomain "$fulldomain"
|
_debug2 add_fulldomain "$fulldomain"
|
||||||
@ -61,8 +61,8 @@ dns_dnsservices_add() {
|
|||||||
#Usage: fulldomain txtvalue
|
#Usage: fulldomain txtvalue
|
||||||
#Description: Remove the txt record after validation.
|
#Description: Remove the txt record after validation.
|
||||||
dns_dnsservices_rm() {
|
dns_dnsservices_rm() {
|
||||||
fulldomain=$1
|
fulldomain="$1"
|
||||||
txtvalue=$2
|
txtvalue="$2"
|
||||||
|
|
||||||
_info "Using dns.services to remove DNS record $fulldomain TXT $txtvalue"
|
_info "Using dns.services to remove DNS record $fulldomain TXT $txtvalue"
|
||||||
_debug rm_fulldomain "$fulldomain"
|
_debug rm_fulldomain "$fulldomain"
|
||||||
@ -117,36 +117,40 @@ _setup_headers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_get_root() {
|
_get_root() {
|
||||||
domain=$1
|
domain="$1"
|
||||||
_debug2 _get_root "Get the root domain of ${domain} for DNS API"
|
_debug2 _get_root "Get the root domain of ${domain} for DNS API"
|
||||||
|
|
||||||
# Setup _get() and _post() headers
|
# Setup _get() and _post() headers
|
||||||
#_setup_headers
|
#_setup_headers
|
||||||
|
|
||||||
result=$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/dns")
|
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 "Got the following root domain(s) $result"
|
||||||
_debug2 _get_root "- JSON: $result"
|
_debug2 _get_root "- JSON: $result"
|
||||||
|
|
||||||
if [ "$(echo "$result" | grep -c '"name"')" -gt "1" ]; then
|
if [ "$(printf "%s\n" "$result" | tr '}' '\n' | grep -c '"name"')" -gt "1" ]; then
|
||||||
checkMultiZones="true"
|
checkMultiZones="true"
|
||||||
_debug2 _get_root "- multiple zones found"
|
_debug2 _get_root "- multiple zones found"
|
||||||
else
|
else
|
||||||
checkMultiZones="false"
|
checkMultiZones="false"
|
||||||
|
_debug2 _get_root "- single zone found"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Find/isolate the root zone to work with in createRecord() and deleteRecord()
|
# Find/isolate the root zone to work with in createRecord() and deleteRecord()
|
||||||
rootZone=""
|
rootZone=""
|
||||||
if [ "$checkMultiZones" = "true" ]; then
|
if [ "$checkMultiZones" = "true" ]; then
|
||||||
rootZone=$(for zone in $(echo "$result" | tr -d '\n' ' '); do
|
#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)
|
||||||
if [ "$(echo "$domain" | grep "$zone")" != "" ]; then
|
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)
|
||||||
_debug2 _get_root "- trying to figure out if $zone is in $domain"
|
if [ "$rootZone" != "" ]; then
|
||||||
echo "$zone"
|
_debug2 _rootZone "- root zone for $domain is $rootZone"
|
||||||
break
|
else
|
||||||
fi
|
_err "Could not find root zone for $domain, is it correctly typed?"
|
||||||
done)
|
return 1
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
rootZone=$(echo "$result" | _egrep_o '"name":"[^"]*' | cut -d'"' -f4)
|
rootZone=$(echo "$result" | tr '}' '\n' | _egrep_o '"name":"[^"]*' | cut -d'"' -f4)
|
||||||
_debug2 _get_root "- only found 1 domain in API: $rootZone"
|
_debug2 _get_root "- only found 1 domain in API: $rootZone"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -155,14 +159,18 @@ _get_root() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
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
|
# Setup variables used by other functions to communicate with DNS.Services API
|
||||||
#zoneInfo=$(echo "$result" | sed "s,\"zones,\n&,g" | grep zones | cut -d'[' -f2 | cut -d']' -f1 | tr '}' '\n' | grep "\"$rootZone\"")
|
#zoneInfo=$(printf "%s\n" "$useResult" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g')
|
||||||
zoneInfo=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g' | grep "\"$rootZone\"")
|
zoneInfo=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep '"name"' | cut -d'"' -f4)
|
||||||
rootZoneName="$rootZone"
|
rootZoneName="$rootZone"
|
||||||
subDomainName="$(echo "$domain" | sed "s,\.$rootZone,,g")"
|
subDomainName="$(printf "%s\n" "$domain" | sed "s,\.$rootZone,,g")"
|
||||||
subDomainNameClean="$(echo "$domain" | sed "s,_acme-challenge.,,g")"
|
subDomainNameClean="$(printf "%s\n" "$domain" | sed "s,_acme-challenge.,,g")"
|
||||||
rootZoneDomainID=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"domain_id":")([^"]*)"(.*)$,\2,g')
|
rootZoneDomainID=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep domain_id | cut -d'"' -f4)
|
||||||
rootZoneServiceID=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"service_id":")([^"]*)"(.*)$,\2,g')
|
rootZoneServiceID=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep service_id | cut -d'"' -f4)
|
||||||
|
|
||||||
_debug2 _zoneInfo "Zone info from API : $zoneInfo"
|
_debug2 _zoneInfo "Zone info from API : $zoneInfo"
|
||||||
_debug2 _get_root "Root zone name : $rootZoneName"
|
_debug2 _get_root "Root zone name : $rootZoneName"
|
||||||
@ -175,13 +183,17 @@ _get_root() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createRecord() {
|
createRecord() {
|
||||||
fulldomain=$1
|
fulldomain="$1"
|
||||||
txtvalue="$2"
|
txtvalue="$2"
|
||||||
|
|
||||||
# Get root domain information - needed for DNS.Services API communication
|
# Get root domain information - needed for DNS.Services API communication
|
||||||
if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
|
if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
|
||||||
_get_root "$fulldomain"
|
_get_root "$fulldomain"
|
||||||
fi
|
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"
|
_debug2 createRecord "CNAME TXT value is: $txtvalue"
|
||||||
|
|
||||||
@ -203,8 +215,8 @@ createRecord() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteRecord() {
|
deleteRecord() {
|
||||||
fulldomain=$1
|
fulldomain="$1"
|
||||||
txtvalue=$2
|
txtvalue="$2"
|
||||||
|
|
||||||
_log deleteRecord "Deleting $fulldomain TXT $txtvalue record"
|
_log deleteRecord "Deleting $fulldomain TXT $txtvalue record"
|
||||||
|
|
||||||
@ -213,8 +225,10 @@ deleteRecord() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")"
|
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}")"
|
#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="$(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
|
if [ -z "$recordID" ]; then
|
||||||
_info "Record $fulldomain TXT $txtvalue not found or already deleted"
|
_info "Record $fulldomain TXT $txtvalue not found or already deleted"
|
||||||
|
@ -94,8 +94,8 @@ _get_domain() {
|
|||||||
_your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')"
|
_your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')"
|
||||||
for l in $_your_hosts; do
|
for l in $_your_hosts; do
|
||||||
#echo "host: $l"
|
#echo "host: $l"
|
||||||
if test "${_full_domain#*$l}" != "$_full_domain"; then
|
if test "${_full_domain#*"$l"}" != "$_full_domain"; then
|
||||||
_record="${_full_domain%.$l}"
|
_record=${_full_domain%."$l"}
|
||||||
_host=$l
|
_host=$l
|
||||||
_debug "The host is $_host and the record $_record"
|
_debug "The host is $_host and the record $_record"
|
||||||
return 0
|
return 0
|
||||||
@ -143,7 +143,7 @@ _dns_dynv6_add_http() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_get_zone_name "$_zone_id"
|
_get_zone_name "$_zone_id"
|
||||||
record="${fulldomain%%.$_zone_name}"
|
record=${fulldomain%%."$_zone_name"}
|
||||||
_set_record TXT "$record" "$txtvalue"
|
_set_record TXT "$record" "$txtvalue"
|
||||||
if _contains "$response" "$txtvalue"; then
|
if _contains "$response" "$txtvalue"; then
|
||||||
_info "Successfully added record"
|
_info "Successfully added record"
|
||||||
@ -161,7 +161,7 @@ _dns_dynv6_rm_http() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_get_zone_name "$_zone_id"
|
_get_zone_name "$_zone_id"
|
||||||
record="${fulldomain%%.$_zone_name}"
|
record=${fulldomain%%."$_zone_name"}
|
||||||
_get_record_id "$_zone_id" "$record" "$txtvalue"
|
_get_record_id "$_zone_id" "$record" "$txtvalue"
|
||||||
_del_record "$_zone_id" "$_record_id"
|
_del_record "$_zone_id" "$_record_id"
|
||||||
if [ -z "$response" ]; then
|
if [ -z "$response" ]; then
|
||||||
|
@ -418,7 +418,7 @@ _edgedns_make_data_to_sign() {
|
|||||||
_secure_debug2 "hdr" "$hdr"
|
_secure_debug2 "hdr" "$hdr"
|
||||||
_edgedns_make_content_hash
|
_edgedns_make_content_hash
|
||||||
path="$(echo "$_request_url_path" | tr -d "\n\r" | sed 's/https\?:\/\///')"
|
path="$(echo "$_request_url_path" | tr -d "\n\r" | sed 's/https\?:\/\///')"
|
||||||
path="${path#*$AKAMAI_HOST}"
|
path=${path#*"$AKAMAI_HOST"}
|
||||||
_debug "hier path" "$path"
|
_debug "hier path" "$path"
|
||||||
# dont expose headers to sign so use MT string
|
# 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")"
|
_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
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
# Gandi LiveDNS v5 API
|
# Gandi LiveDNS v5 API
|
||||||
# http://doc.livedns.gandi.net/
|
# https://doc.livedns.gandi.net/
|
||||||
# currently under beta
|
# currently under beta
|
||||||
#
|
#
|
||||||
# Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable
|
# 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_start_tr || return $?
|
||||||
_dns_gcloud_get_rrdatas || return $?
|
_dns_gcloud_get_rrdatas || return $?
|
||||||
echo "$rrdatas" | _dns_gcloud_remove_rrs || 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 $?
|
_dns_gcloud_execute_tr || return $?
|
||||||
|
|
||||||
_info "$fulldomain record added"
|
_info "$fulldomain record added"
|
||||||
|
187
dnsapi/dns_gcore.sh
Executable file
187
dnsapi/dns_gcore.sh
Executable file
@ -0,0 +1,187 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
#GCORE_Key='773$7b7adaf2a2b32bfb1b83787b4ff32a67eb178e3ada1af733e47b1411f2461f7f4fa7ed7138e2772a46124377bad7384b3bb8d87748f87b3f23db4b8bbe41b2bb'
|
||||||
|
#
|
||||||
|
|
||||||
|
GCORE_Api="https://api.gcorelabs.com/dns/v2"
|
||||||
|
GCORE_Doc="https://apidocs.gcore.com/dns"
|
||||||
|
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
dns_gcore_add() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
GCORE_Key="${GCORE_Key:-$(_readaccountconf_mutable GCORE_Key)}"
|
||||||
|
|
||||||
|
if [ -z "$GCORE_Key" ]; then
|
||||||
|
GCORE_Key=""
|
||||||
|
_err "You didn't specify a Gcore api key yet."
|
||||||
|
_err "You can get yours from here $GCORE_Doc"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#save the api key to the account conf file.
|
||||||
|
_saveaccountconf_mutable GCORE_Key "$GCORE_Key"
|
||||||
|
|
||||||
|
_debug "First detect the zone name"
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
_err "invalid domain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug _zone_name "$_zone_name"
|
||||||
|
_debug _sub_domain "$_sub_domain"
|
||||||
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
|
_debug "Getting txt records"
|
||||||
|
_gcore_rest GET "zones/$_zone_name/$fulldomain/TXT"
|
||||||
|
payload=""
|
||||||
|
|
||||||
|
if echo "$response" | grep "record is not found" >/dev/null; then
|
||||||
|
_info "Record doesn't exists"
|
||||||
|
payload="{\"resource_records\":[{\"content\":[\"$txtvalue\"],\"enabled\":true}],\"ttl\":120}"
|
||||||
|
elif echo "$response" | grep "$txtvalue" >/dev/null; then
|
||||||
|
_info "Already exists, OK"
|
||||||
|
return 0
|
||||||
|
elif echo "$response" | tr -d " " | grep \"name\":\""$fulldomain"\",\"type\":\"TXT\" >/dev/null; then
|
||||||
|
_info "Record with mismatch txtvalue, try update it"
|
||||||
|
payload=$(echo "$response" | tr -d " " | sed 's/"updated_at":[0-9]\+,//g' | sed 's/"meta":{}}]}/"meta":{}},{"content":['\""$txtvalue"\"'],"enabled":true}]}/')
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so
|
||||||
|
# we can not use updating anymore.
|
||||||
|
# count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2)
|
||||||
|
# _debug count "$count"
|
||||||
|
# if [ "$count" = "0" ]; then
|
||||||
|
_info "Adding record"
|
||||||
|
if _gcore_rest PUT "zones/$_zone_name/$fulldomain/TXT" "$payload"; then
|
||||||
|
if _contains "$response" "$txtvalue"; then
|
||||||
|
_info "Added, OK"
|
||||||
|
return 0
|
||||||
|
elif _contains "$response" "rrset is already exists"; then
|
||||||
|
_info "Already exists, OK"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Add txt record error."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_err "Add txt record error."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#fulldomain txtvalue
|
||||||
|
dns_gcore_rm() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
GCORE_Key="${GCORE_Key:-$(_readaccountconf_mutable GCORE_Key)}"
|
||||||
|
|
||||||
|
_debug "First detect the root zone"
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
_err "invalid domain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug _zone_name "$_zone_name"
|
||||||
|
_debug _sub_domain "$_sub_domain"
|
||||||
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
|
_debug "Getting txt records"
|
||||||
|
_gcore_rest GET "zones/$_zone_name/$fulldomain/TXT"
|
||||||
|
|
||||||
|
if echo "$response" | grep "record is not found" >/dev/null; then
|
||||||
|
_info "No such txt recrod"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! echo "$response" | tr -d " " | grep \"name\":\""$fulldomain"\",\"type\":\"TXT\" >/dev/null; then
|
||||||
|
_err "Error: $response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! echo "$response" | tr -d " " | grep \""$txtvalue"\" >/dev/null; then
|
||||||
|
_info "No such txt recrod"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
count="$(echo "$response" | grep -o "content" | wc -l)"
|
||||||
|
|
||||||
|
if [ "$count" = "1" ]; then
|
||||||
|
if ! _gcore_rest DELETE "zones/$_zone_name/$fulldomain/TXT"; then
|
||||||
|
_err "Delete record error. $response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
payload="$(echo "$response" | tr -d " " | sed 's/"updated_at":[0-9]\+,//g' | sed 's/{"id":[0-9]\+,"content":\["'"$txtvalue"'"\],"enabled":true,"meta":{}}//' | sed 's/\[,/\[/' | sed 's/,,/,/' | sed 's/,\]/\]/')"
|
||||||
|
if ! _gcore_rest PUT "zones/$_zone_name/$fulldomain/TXT" "$payload"; then
|
||||||
|
_err "Delete record error. $response"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#################### Private functions below ##################################
|
||||||
|
#_acme-challenge.sub.domain.com
|
||||||
|
#returns
|
||||||
|
# _sub_domain=_acme-challenge.sub or _acme-challenge
|
||||||
|
# _domain=domain.com
|
||||||
|
# _zone_name=domain.com or sub.domain.com
|
||||||
|
_get_root() {
|
||||||
|
domain=$1
|
||||||
|
i=1
|
||||||
|
p=1
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||||
|
_debug h "$h"
|
||||||
|
if [ -z "$h" ]; then
|
||||||
|
#not valid
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! _gcore_rest GET "zones/$h"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if _contains "$response" "\"name\":\"$h\""; then
|
||||||
|
_zone_name=$h
|
||||||
|
if [ "$_zone_name" ]; then
|
||||||
|
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||||
|
_domain=$h
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
p=$i
|
||||||
|
i=$(_math "$i" + 1)
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_gcore_rest() {
|
||||||
|
m=$1
|
||||||
|
ep="$2"
|
||||||
|
data="$3"
|
||||||
|
_debug "$ep"
|
||||||
|
|
||||||
|
key_trimmed=$(echo "$GCORE_Key" | tr -d '"')
|
||||||
|
|
||||||
|
export _H1="Content-Type: application/json"
|
||||||
|
export _H2="Authorization: APIKey $key_trimmed"
|
||||||
|
|
||||||
|
if [ "$m" != "GET" ]; then
|
||||||
|
_debug data "$data"
|
||||||
|
response="$(_post "$data" "$GCORE_Api/$ep" "" "$m")"
|
||||||
|
else
|
||||||
|
response="$(_get "$GCORE_Api/$ep")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$?" != "0" ]; then
|
||||||
|
_err "error $ep"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug2 response "$response"
|
||||||
|
return 0
|
||||||
|
}
|
@ -22,8 +22,8 @@ dns_gd_add() {
|
|||||||
if [ -z "$GD_Key" ] || [ -z "$GD_Secret" ]; then
|
if [ -z "$GD_Key" ] || [ -z "$GD_Secret" ]; then
|
||||||
GD_Key=""
|
GD_Key=""
|
||||||
GD_Secret=""
|
GD_Secret=""
|
||||||
_err "You don't specify godaddy api key and secret yet."
|
_err "You didn't specify godaddy api key and secret yet."
|
||||||
_err "Please create you key and try again."
|
_err "Please create your key and try again."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ dns_gd_add() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if _contains "$response" "$txtvalue"; then
|
if _contains "$response" "$txtvalue"; then
|
||||||
_info "The record is existing, skip"
|
_info "This record already exists, skipping"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
173
dnsapi/dns_googledomains.sh
Executable file
173
dnsapi/dns_googledomains.sh
Executable file
@ -0,0 +1,173 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Author: Alex Leigh <leigh at alexleigh dot me>
|
||||||
|
# Created: 2023-03-02
|
||||||
|
|
||||||
|
#GOOGLEDOMAINS_ACCESS_TOKEN="xxxx"
|
||||||
|
#GOOGLEDOMAINS_ZONE="xxxx"
|
||||||
|
GOOGLEDOMAINS_API="https://acmedns.googleapis.com/v1/acmeChallengeSets"
|
||||||
|
|
||||||
|
######## Public functions ########
|
||||||
|
|
||||||
|
#Usage: dns_googledomains_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
dns_googledomains_add() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
_info "Invoking Google Domains ACME DNS API."
|
||||||
|
|
||||||
|
if ! _dns_googledomains_setup; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
zone="$(_dns_googledomains_get_zone "$fulldomain")"
|
||||||
|
if [ -z "$zone" ]; then
|
||||||
|
_err "Could not find a Google Domains-managed zone containing the requested domain."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug zone "$zone"
|
||||||
|
_debug txtvalue "$txtvalue"
|
||||||
|
|
||||||
|
_info "Adding TXT record for $fulldomain."
|
||||||
|
if _dns_googledomains_api "$zone" ":rotateChallenges" "{\"accessToken\":\"$GOOGLEDOMAINS_ACCESS_TOKEN\",\"recordsToAdd\":[{\"fqdn\":\"$fulldomain\",\"digest\":\"$txtvalue\"}],\"keepExpiredRecords\":true}"; then
|
||||||
|
if _contains "$response" "$txtvalue"; then
|
||||||
|
_info "TXT record added."
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Error adding TXT record."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
_err "Error adding TXT record."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#Usage: dns_googledomains_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
dns_googledomains_rm() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
_info "Invoking Google Domains ACME DNS API."
|
||||||
|
|
||||||
|
if ! _dns_googledomains_setup; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
zone="$(_dns_googledomains_get_zone "$fulldomain")"
|
||||||
|
if [ -z "$zone" ]; then
|
||||||
|
_err "Could not find a Google Domains-managed domain based on request."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug zone "$zone"
|
||||||
|
_debug txtvalue "$txtvalue"
|
||||||
|
|
||||||
|
_info "Removing TXT record for $fulldomain."
|
||||||
|
if _dns_googledomains_api "$zone" ":rotateChallenges" "{\"accessToken\":\"$GOOGLEDOMAINS_ACCESS_TOKEN\",\"recordsToRemove\":[{\"fqdn\":\"$fulldomain\",\"digest\":\"$txtvalue\"}],\"keepExpiredRecords\":true}"; then
|
||||||
|
if _contains "$response" "$txtvalue"; then
|
||||||
|
_err "Error removing TXT record."
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
_info "TXT record removed."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
_err "Error removing TXT record."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
######## Private functions ########
|
||||||
|
|
||||||
|
_dns_googledomains_setup() {
|
||||||
|
if [ -n "$GOOGLEDOMAINS_SETUP_COMPLETED" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
GOOGLEDOMAINS_ACCESS_TOKEN="${GOOGLEDOMAINS_ACCESS_TOKEN:-$(_readaccountconf_mutable GOOGLEDOMAINS_ACCESS_TOKEN)}"
|
||||||
|
GOOGLEDOMAINS_ZONE="${GOOGLEDOMAINS_ZONE:-$(_readaccountconf_mutable GOOGLEDOMAINS_ZONE)}"
|
||||||
|
|
||||||
|
if [ -z "$GOOGLEDOMAINS_ACCESS_TOKEN" ]; then
|
||||||
|
GOOGLEDOMAINS_ACCESS_TOKEN=""
|
||||||
|
_err "Google Domains access token was not specified."
|
||||||
|
_err "Please visit Google Domains Security settings to provision an ACME DNS API access token."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$GOOGLEDOMAINS_ZONE" ]; then
|
||||||
|
_savedomainconf GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN"
|
||||||
|
_savedomainconf GOOGLEDOMAINS_ZONE "$GOOGLEDOMAINS_ZONE"
|
||||||
|
else
|
||||||
|
_saveaccountconf_mutable GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN"
|
||||||
|
_clearaccountconf_mutable GOOGLEDOMAINS_ZONE
|
||||||
|
_clearaccountconf GOOGLEDOMAINS_ZONE
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN"
|
||||||
|
_debug GOOGLEDOMAINS_ZONE "$GOOGLEDOMAINS_ZONE"
|
||||||
|
|
||||||
|
GOOGLEDOMAINS_SETUP_COMPLETED=1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_dns_googledomains_get_zone() {
|
||||||
|
domain=$1
|
||||||
|
|
||||||
|
# Use zone directly if provided
|
||||||
|
if [ "$GOOGLEDOMAINS_ZONE" ]; then
|
||||||
|
if ! _dns_googledomains_api "$GOOGLEDOMAINS_ZONE"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$GOOGLEDOMAINS_ZONE"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
i=2
|
||||||
|
while true; do
|
||||||
|
curr=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||||
|
_debug curr "$curr"
|
||||||
|
|
||||||
|
if [ -z "$curr" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if _dns_googledomains_api "$curr"; then
|
||||||
|
echo "$curr"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
i=$(_math "$i" + 1)
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_dns_googledomains_api() {
|
||||||
|
zone=$1
|
||||||
|
apimethod=$2
|
||||||
|
data="$3"
|
||||||
|
|
||||||
|
if [ -z "$data" ]; then
|
||||||
|
response="$(_get "$GOOGLEDOMAINS_API/$zone$apimethod")"
|
||||||
|
else
|
||||||
|
_debug data "$data"
|
||||||
|
export _H1="Content-Type: application/json"
|
||||||
|
response="$(_post "$data" "$GOOGLEDOMAINS_API/$zone$apimethod")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug response "$response"
|
||||||
|
|
||||||
|
if [ "$?" != "0" ]; then
|
||||||
|
_err "Error"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if _contains "$response" "\"error\": {"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
@ -23,7 +23,7 @@ dns_huaweicloud_add() {
|
|||||||
|
|
||||||
HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
|
HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
|
||||||
HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
|
HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
|
||||||
HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
|
HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_DomainName)}"
|
||||||
|
|
||||||
# Check information
|
# Check information
|
||||||
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
|
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
|
||||||
@ -74,7 +74,7 @@ dns_huaweicloud_rm() {
|
|||||||
|
|
||||||
HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
|
HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
|
||||||
HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
|
HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
|
||||||
HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
|
HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_DomainName)}"
|
||||||
|
|
||||||
# Check information
|
# Check information
|
||||||
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
|
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
|
||||||
@ -98,19 +98,59 @@ dns_huaweicloud_rm() {
|
|||||||
fi
|
fi
|
||||||
_debug "Zone ID is:" "${zoneid}"
|
_debug "Zone ID is:" "${zoneid}"
|
||||||
|
|
||||||
# Remove all records
|
record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")"
|
||||||
# Therotically HuaweiCloud does not allow more than one record set
|
_recursive_rm_record "${token}" "${fulldomain}" "${zoneid}" "${record_id}"
|
||||||
# But remove them recurringly to increase robusty
|
ret="$?"
|
||||||
while [ "${record_id}" != "0" ]; do
|
if [ "${ret}" != "0" ]; then
|
||||||
_debug "Removing Record"
|
_err "dns_api(dns_huaweicloud): Error removing record."
|
||||||
_rm_record "${token}" "${zoneid}" "${record_id}"
|
return 1
|
||||||
record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")"
|
fi
|
||||||
done
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
################### Private functions below ##################################
|
################### Private functions below ##################################
|
||||||
|
|
||||||
|
# _recursive_rm_record
|
||||||
|
# remove all records from the record set
|
||||||
|
#
|
||||||
|
# _token=$1
|
||||||
|
# _domain=$2
|
||||||
|
# _zoneid=$3
|
||||||
|
# _record_id=$4
|
||||||
|
#
|
||||||
|
# Returns 0 on success
|
||||||
|
_recursive_rm_record() {
|
||||||
|
_token=$1
|
||||||
|
_domain=$2
|
||||||
|
_zoneid=$3
|
||||||
|
_record_id=$4
|
||||||
|
|
||||||
|
# Most likely to have problems will huaweicloud side if more than 50 attempts but still cannot fully remove the record set
|
||||||
|
# Maybe can be removed manually in the dashboard
|
||||||
|
_retry_cnt=50
|
||||||
|
|
||||||
|
# Remove all records
|
||||||
|
# Therotically HuaweiCloud does not allow more than one record set
|
||||||
|
# But remove them recurringly to increase robusty
|
||||||
|
|
||||||
|
while [ "${_record_id}" != "0" ] && [ "${_retry_cnt}" != "0" ]; do
|
||||||
|
_debug "Removing Record"
|
||||||
|
_retry_cnt=$((_retry_cnt - 1))
|
||||||
|
_rm_record "${_token}" "${_zoneid}" "${_record_id}"
|
||||||
|
_record_id="$(_get_recordset_id "${_token}" "${_domain}" "${_zoneid}")"
|
||||||
|
_debug2 "Checking record exists: record_id=${_record_id}"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Check if retry count is reached
|
||||||
|
if [ "${_retry_cnt}" = "0" ]; then
|
||||||
|
_debug "Failed to remove record after 50 attempts, please try removing it manually in the dashboard"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
# _get_zoneid
|
# _get_zoneid
|
||||||
#
|
#
|
||||||
# _token=$1
|
# _token=$1
|
||||||
@ -124,7 +164,7 @@ _get_zoneid() {
|
|||||||
|
|
||||||
i=1
|
i=1
|
||||||
while true; do
|
while true; do
|
||||||
h=$(printf "%s" "${_domain_string}" | cut -d . -f $i-100)
|
h=$(printf "%s" "${_domain_string}" | cut -d . -f "$i"-100)
|
||||||
if [ -z "$h" ]; then
|
if [ -z "$h" ]; then
|
||||||
#not valid
|
#not valid
|
||||||
return 1
|
return 1
|
||||||
@ -135,11 +175,11 @@ _get_zoneid() {
|
|||||||
if _contains "${response}" '"id"'; then
|
if _contains "${response}" '"id"'; then
|
||||||
zoneidlist=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
|
zoneidlist=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
|
||||||
zonenamelist=$(echo "${response}" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
|
zonenamelist=$(echo "${response}" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
|
||||||
_debug2 "Return Zone ID(s):" "${zoneidlist}"
|
_debug2 "Returned Zone ID(s):" "${zoneidlist}"
|
||||||
_debug2 "Return Zone Name(s):" "${zonenamelist}"
|
_debug2 "Returned Zone Name(s):" "${zonenamelist}"
|
||||||
zoneidnum=0
|
zoneidnum=0
|
||||||
zoneidcount=$(echo "${zoneidlist}" | grep -c '^')
|
zoneidcount=$(echo "${zoneidlist}" | grep -c '^')
|
||||||
_debug "Retund Zone ID(s) Count:" "${zoneidcount}"
|
_debug "Returned Zone ID(s) Count:" "${zoneidcount}"
|
||||||
while [ "${zoneidnum}" -lt "${zoneidcount}" ]; do
|
while [ "${zoneidnum}" -lt "${zoneidcount}" ]; do
|
||||||
zoneidnum=$(_math "$zoneidnum" + 1)
|
zoneidnum=$(_math "$zoneidnum" + 1)
|
||||||
_zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p")
|
_zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p")
|
||||||
@ -206,8 +246,7 @@ _add_record() {
|
|||||||
\"type\": \"TXT\",
|
\"type\": \"TXT\",
|
||||||
\"ttl\": 1,
|
\"ttl\": 1,
|
||||||
\"records\": [
|
\"records\": [
|
||||||
${_exist_record},
|
${_exist_record},\"\\\"${_txtvalue}\\\"\"
|
||||||
\"\\\"${_txtvalue}\\\"\"
|
|
||||||
]
|
]
|
||||||
}"
|
}"
|
||||||
fi
|
fi
|
||||||
@ -215,19 +254,16 @@ _add_record() {
|
|||||||
_record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")"
|
_record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")"
|
||||||
_debug "Record Set ID is:" "${_record_id}"
|
_debug "Record Set ID is:" "${_record_id}"
|
||||||
|
|
||||||
# Remove all records
|
|
||||||
while [ "${_record_id}" != "0" ]; do
|
|
||||||
_debug "Removing Record"
|
|
||||||
_rm_record "${_token}" "${zoneid}" "${_record_id}"
|
|
||||||
_record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Add brand new records with all old and new records
|
# Add brand new records with all old and new records
|
||||||
export _H2="Content-Type: application/json"
|
export _H2="Content-Type: application/json"
|
||||||
export _H1="X-Auth-Token: ${_token}"
|
export _H1="X-Auth-Token: ${_token}"
|
||||||
|
|
||||||
_debug2 "${_post_body}"
|
_debug2 "${_post_body}"
|
||||||
_post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null
|
if [ -z "${_exist_record}" ]; then
|
||||||
|
_post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null
|
||||||
|
else
|
||||||
|
_post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets/${_record_id}" false "PUT" >/dev/null
|
||||||
|
fi
|
||||||
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
|
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
|
||||||
if [ "$_code" != "202" ]; then
|
if [ "$_code" != "202" ]; then
|
||||||
_err "dns_huaweicloud: http code ${_code}"
|
_err "dns_huaweicloud: http code ${_code}"
|
||||||
|
@ -76,7 +76,7 @@ dns_infomaniak_add() {
|
|||||||
domain_id=${zone_and_id#* }
|
domain_id=${zone_and_id#* }
|
||||||
|
|
||||||
# extract first part of domain
|
# extract first part of domain
|
||||||
key=${fulldomain%.$zone}
|
key=${fulldomain%."$zone"}
|
||||||
|
|
||||||
_debug "zone:$zone id:$domain_id key:$key"
|
_debug "zone:$zone id:$domain_id key:$key"
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ dns_infomaniak_rm() {
|
|||||||
domain_id=${zone_and_id#* }
|
domain_id=${zone_and_id#* }
|
||||||
|
|
||||||
# extract first part of domain
|
# extract first part of domain
|
||||||
key=${fulldomain%.$zone}
|
key=${fulldomain%."$zone"}
|
||||||
|
|
||||||
_debug "zone:$zone id:$domain_id key:$key"
|
_debug "zone:$zone id:$domain_id key:$key"
|
||||||
|
|
||||||
|
157
dnsapi/dns_ipv64.sh
Executable file
157
dnsapi/dns_ipv64.sh
Executable file
@ -0,0 +1,157 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#Created by Roman Lumetsberger, to use ipv64.net's API to add/remove text records
|
||||||
|
#2022/11/29
|
||||||
|
|
||||||
|
# Pass credentials before "acme.sh --issue --dns dns_ipv64 ..."
|
||||||
|
# --
|
||||||
|
# export IPv64_Token="aaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
|
||||||
|
IPv64_API="https://ipv64.net/api"
|
||||||
|
|
||||||
|
######## Public functions ######################
|
||||||
|
|
||||||
|
#Usage: dns_ipv64_add _acme-challenge.domain.ipv64.net "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
dns_ipv64_add() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
IPv64_Token="${IPv64_Token:-$(_readaccountconf_mutable IPv64_Token)}"
|
||||||
|
if [ -z "$IPv64_Token" ]; then
|
||||||
|
_err "You must export variable: IPv64_Token"
|
||||||
|
_err "The API Key for your IPv64 account is necessary."
|
||||||
|
_err "You can look it up in your IPv64 account."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Now save the credentials.
|
||||||
|
_saveaccountconf_mutable IPv64_Token "$IPv64_Token"
|
||||||
|
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
_err "invalid domain" "$fulldomain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug _sub_domain "$_sub_domain"
|
||||||
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
|
# convert to lower case
|
||||||
|
_domain="$(echo "$_domain" | _lower_case)"
|
||||||
|
_sub_domain="$(echo "$_sub_domain" | _lower_case)"
|
||||||
|
# Now add the TXT record
|
||||||
|
_info "Trying to add TXT record"
|
||||||
|
if _ipv64_rest "POST" "add_record=$_domain&praefix=$_sub_domain&type=TXT&content=$txtvalue"; then
|
||||||
|
_info "TXT record has been successfully added."
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Errors happened during adding the TXT record, response=$_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#Usage: fulldomain txtvalue
|
||||||
|
#Usage: dns_ipv64_rm _acme-challenge.domain.ipv64.net "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
#Remove the txt record after validation.
|
||||||
|
dns_ipv64_rm() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
IPv64_Token="${IPv64_Token:-$(_readaccountconf_mutable IPv64_Token)}"
|
||||||
|
if [ -z "$IPv64_Token" ]; then
|
||||||
|
_err "You must export variable: IPv64_Token"
|
||||||
|
_err "The API Key for your IPv64 account is necessary."
|
||||||
|
_err "You can look it up in your IPv64 account."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
_err "invalid domain" "$fulldomain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug _sub_domain "$_sub_domain"
|
||||||
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
|
# convert to lower case
|
||||||
|
_domain="$(echo "$_domain" | _lower_case)"
|
||||||
|
_sub_domain="$(echo "$_sub_domain" | _lower_case)"
|
||||||
|
# Now delete the TXT record
|
||||||
|
_info "Trying to delete TXT record"
|
||||||
|
if _ipv64_rest "DELETE" "del_record=$_domain&praefix=$_sub_domain&type=TXT&content=$txtvalue"; then
|
||||||
|
_info "TXT record has been successfully deleted."
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Errors happened during deleting the TXT record, response=$_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#################### Private functions below ##################################
|
||||||
|
#_acme-challenge.www.domain.com
|
||||||
|
#returns
|
||||||
|
# _sub_domain=_acme-challenge.www
|
||||||
|
# _domain=domain.com
|
||||||
|
_get_root() {
|
||||||
|
domain="$1"
|
||||||
|
i=1
|
||||||
|
p=1
|
||||||
|
|
||||||
|
_ipv64_get "get_domains"
|
||||||
|
domain_data=$_response
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
|
||||||
|
if [ -z "$h" ]; then
|
||||||
|
#not valid
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#if _contains "$domain_data" "\""$h"\"\:"; then
|
||||||
|
if _contains "$domain_data" "\"""$h""\"\:"; then
|
||||||
|
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
|
||||||
|
_domain="$h"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
p=$i
|
||||||
|
i=$(_math "$i" + 1)
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#send get request to api
|
||||||
|
# $1 has to set the api-function
|
||||||
|
_ipv64_get() {
|
||||||
|
url="$IPv64_API?$1"
|
||||||
|
export _H1="Authorization: Bearer $IPv64_Token"
|
||||||
|
|
||||||
|
_response=$(_get "$url")
|
||||||
|
_response="$(echo "$_response" | _normalizeJson)"
|
||||||
|
|
||||||
|
if _contains "$_response" "429 Too Many Requests"; then
|
||||||
|
_info "API throttled, sleeping to reset the limit"
|
||||||
|
_sleep 10
|
||||||
|
_response=$(_get "$url")
|
||||||
|
_response="$(echo "$_response" | _normalizeJson)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_ipv64_rest() {
|
||||||
|
url="$IPv64_API"
|
||||||
|
export _H1="Authorization: Bearer $IPv64_Token"
|
||||||
|
export _H2="Content-Type: application/x-www-form-urlencoded"
|
||||||
|
_response=$(_post "$2" "$url" "" "$1")
|
||||||
|
|
||||||
|
if _contains "$_response" "429 Too Many Requests"; then
|
||||||
|
_info "API throttled, sleeping to reset the limit"
|
||||||
|
_sleep 10
|
||||||
|
_response=$(_post "$2" "$url" "" "$1")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! _contains "$_response" "\"info\":\"success\""; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug2 response "$_response"
|
||||||
|
return 0
|
||||||
|
}
|
@ -215,7 +215,7 @@ _get_record_id() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
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")"
|
_record_id="$(echo "$response" | tr -d '\n\r' | sed "s/<item xsi:type=\"ns2:Map\">/\n/g" | grep -i "$_record_name" | grep -i ">TXT<" | sed "s/<item><key xsi:type=\"xsd:string\">record_id<\/key><value xsi:type=\"xsd:string\">/=>/g" | grep -i "$_txtvalue" | sed "s/<\/value><\/item>/\n/g" | grep "=>" | sed "s/=>//g")"
|
||||||
_debug "[KAS] -> Record Id: " "$_record_id"
|
_debug "[KAS] -> Record Id: " "$_record_id"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
# KingHost API support #
|
# KingHost API support #
|
||||||
# http://api.kinghost.net/doc/ #
|
# https://api.kinghost.net/doc/ #
|
||||||
# #
|
# #
|
||||||
# Author: Felipe Keller Braz <felipebraz@kinghost.com.br> #
|
# Author: Felipe Keller Braz <felipebraz@kinghost.com.br> #
|
||||||
# Report Bugs here: https://github.com/kinghost/acme.sh #
|
# Report Bugs here: https://github.com/kinghost/acme.sh #
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
#Author: Rolph Haspers <r.haspers@global.leaseweb.com>
|
#Author: Rolph Haspers <r.haspers@global.leaseweb.com>
|
||||||
#Utilize leaseweb.com API to finish dns-01 verifications.
|
#Utilize leaseweb.com API to finish dns-01 verifications.
|
||||||
#Requires a Leaseweb API Key (export LSW_Key="Your Key")
|
#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 #####################
|
######## Public functions #####################
|
||||||
|
|
||||||
LSW_API="https://api.leaseweb.com/hosting/v2/domains/"
|
LSW_API="https://api.leaseweb.com/hosting/v2/domains"
|
||||||
|
|
||||||
#Usage: dns_leaseweb_add _acme-challenge.www.domain.com
|
#Usage: dns_leaseweb_add _acme-challenge.www.domain.com
|
||||||
dns_leaseweb_add() {
|
dns_leaseweb_add() {
|
||||||
|
@ -82,7 +82,7 @@ _get_root() {
|
|||||||
_debug "Failed domain lookup via domains.getList api call. Trying domain lookup via domains.dns.getHosts api."
|
_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
|
# 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.
|
# 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
|
if ! _get_root_by_getHosts "$fulldomain"; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
59
dnsapi/dns_nanelo.sh
Normal file
59
dnsapi/dns_nanelo.sh
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Official DNS API for Nanelo.com
|
||||||
|
|
||||||
|
# Provide the required API Key like this:
|
||||||
|
# NANELO_TOKEN="FmD408PdqT1E269gUK57"
|
||||||
|
|
||||||
|
NANELO_API="https://api.nanelo.com/v1/"
|
||||||
|
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
dns_nanelo_add() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
NANELO_TOKEN="${NANELO_TOKEN:-$(_readaccountconf_mutable NANELO_TOKEN)}"
|
||||||
|
if [ -z "$NANELO_TOKEN" ]; then
|
||||||
|
NANELO_TOKEN=""
|
||||||
|
_err "You didn't configure a Nanelo API Key yet."
|
||||||
|
_err "Please set NANELO_TOKEN and try again."
|
||||||
|
_err "Login to Nanelo.com and go to Settings > API Keys to get a Key"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_saveaccountconf_mutable NANELO_TOKEN "$NANELO_TOKEN"
|
||||||
|
|
||||||
|
_info "Adding TXT record to ${fulldomain}"
|
||||||
|
response="$(_get "$NANELO_API$NANELO_TOKEN/dns/addrecord?type=TXT&ttl=60&name=${fulldomain}&value=${txtvalue}")"
|
||||||
|
if _contains "${response}" 'success'; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
_err "Could not create resource record, please check the logs"
|
||||||
|
_err "${response}"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_nanelo_rm() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
NANELO_TOKEN="${NANELO_TOKEN:-$(_readaccountconf_mutable NANELO_TOKEN)}"
|
||||||
|
if [ -z "$NANELO_TOKEN" ]; then
|
||||||
|
NANELO_TOKEN=""
|
||||||
|
_err "You didn't configure a Nanelo API Key yet."
|
||||||
|
_err "Please set NANELO_TOKEN and try again."
|
||||||
|
_err "Login to Nanelo.com and go to Settings > API Keys to get a Key"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_saveaccountconf_mutable NANELO_TOKEN "$NANELO_TOKEN"
|
||||||
|
|
||||||
|
_info "Deleting resource record $fulldomain"
|
||||||
|
response="$(_get "$NANELO_API$NANELO_TOKEN/dns/deleterecord?type=TXT&ttl=60&name=${fulldomain}&value=${txtvalue}")"
|
||||||
|
if _contains "${response}" 'success'; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
_err "Could not delete resource record, please check the logs"
|
||||||
|
_err "${response}"
|
||||||
|
return 1
|
||||||
|
}
|
@ -18,15 +18,15 @@ dns_netlify_add() {
|
|||||||
NETLIFY_ACCESS_TOKEN=""
|
NETLIFY_ACCESS_TOKEN=""
|
||||||
_err "Please specify your Netlify Access Token and try again."
|
_err "Please specify your Netlify Access Token and try again."
|
||||||
return 1
|
return 1
|
||||||
|
else
|
||||||
|
_saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_info "Using Netlify"
|
_info "Using Netlify"
|
||||||
_debug fulldomain "$fulldomain"
|
_debug fulldomain "$fulldomain"
|
||||||
_debug txtvalue "$txtvalue"
|
_debug txtvalue "$txtvalue"
|
||||||
|
|
||||||
_saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN"
|
if ! _get_root "$fulldomain"; then
|
||||||
|
|
||||||
if ! _get_root "$fulldomain" "$accesstoken"; then
|
|
||||||
_err "invalid domain"
|
_err "invalid domain"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@ -62,9 +62,9 @@ dns_netlify_rm() {
|
|||||||
_debug txtdomain "$txtdomain"
|
_debug txtdomain "$txtdomain"
|
||||||
_debug txt "$txt"
|
_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"
|
_err "invalid domain"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
@ -265,6 +265,7 @@ _signed_request() {
|
|||||||
_response="$(_get "https://${_sig_host}${_sig_target}")"
|
_response="$(_get "https://${_sig_host}${_sig_target}")"
|
||||||
elif [ "$_curl_method" = "PATCH" ]; then
|
elif [ "$_curl_method" = "PATCH" ]; then
|
||||||
export _H1="$_date_header"
|
export _H1="$_date_header"
|
||||||
|
# shellcheck disable=SC2090
|
||||||
export _H2="$_sig_body_sha256"
|
export _H2="$_sig_body_sha256"
|
||||||
export _H3="$_sig_body_type"
|
export _H3="$_sig_body_type"
|
||||||
export _H4="$_sig_body_length"
|
export _H4="$_sig_body_length"
|
||||||
|
@ -57,16 +57,16 @@ _dns_openstack_create_recordset() {
|
|||||||
|
|
||||||
if [ -z "$_recordset_id" ]; then
|
if [ -z "$_recordset_id" ]; then
|
||||||
_info "Creating a new recordset"
|
_info "Creating a new recordset"
|
||||||
if ! _recordset_id=$(openstack recordset create -c id -f value --type TXT --record "$txtvalue" "$_zone_id" "$fulldomain."); then
|
if ! _recordset_id=$(openstack recordset create -c id -f value --type TXT --record="$txtvalue" "$_zone_id" "$fulldomain."); then
|
||||||
_err "No recordset ID found after create"
|
_err "No recordset ID found after create"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
_info "Updating existing recordset"
|
_info "Updating existing recordset"
|
||||||
# Build new list of --record <rec> args for update
|
# Build new list of --record=<rec> args for update
|
||||||
_record_args="--record $txtvalue"
|
_record_args="--record=$txtvalue"
|
||||||
for _rec in $_records; do
|
for _rec in $_records; do
|
||||||
_record_args="$_record_args --record $_rec"
|
_record_args="$_record_args --record=$_rec"
|
||||||
done
|
done
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
if ! _recordset_id=$(openstack recordset set -c id -f value $_record_args "$_zone_id" "$fulldomain."); then
|
if ! _recordset_id=$(openstack recordset set -c id -f value $_record_args "$_zone_id" "$fulldomain."); then
|
||||||
@ -107,13 +107,13 @@ _dns_openstack_delete_recordset() {
|
|||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
_info "Found existing records, updating recordset"
|
_info "Found existing records, updating recordset"
|
||||||
# Build new list of --record <rec> args for update
|
# Build new list of --record=<rec> args for update
|
||||||
_record_args=""
|
_record_args=""
|
||||||
for _rec in $_records; do
|
for _rec in $_records; do
|
||||||
if [ "$_rec" = "$txtvalue" ]; then
|
if [ "$_rec" = "$txtvalue" ]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
_record_args="$_record_args --record $_rec"
|
_record_args="$_record_args --record=$_rec"
|
||||||
done
|
done
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
if ! openstack recordset set -c id -f value $_record_args "$_zone_id" "$fulldomain." >/dev/null; then
|
if ! openstack recordset set -c id -f value $_record_args "$_zone_id" "$fulldomain." >/dev/null; then
|
||||||
|
@ -137,7 +137,7 @@ _get_root() {
|
|||||||
domain=$1
|
domain=$1
|
||||||
i=2
|
i=2
|
||||||
p=1
|
p=1
|
||||||
if _opns_rest "GET" "/domain/searchDomain"; then
|
if _opns_rest "GET" "/domain/searchMasterDomain"; then
|
||||||
_domain_response="$response"
|
_domain_response="$response"
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
@ -150,7 +150,7 @@ _get_root() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_debug h "$h"
|
_debug h "$h"
|
||||||
id=$(echo "$_domain_response" | _egrep_o "\"uuid\":\"[a-z0-9\-]*\",\"enabled\":\"1\",\"type\":\"master\",[^.]*,\"domainname\":\"${h}\"" | cut -d ':' -f 2 | 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
|
if [ -n "$id" ]; then
|
||||||
_debug id "$id"
|
_debug id "$id"
|
||||||
_host=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
_host=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||||
|
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
|
||||||
|
}
|
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
|
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."
|
_info "A txt record with the same name already exists."
|
||||||
# trim the string on the left
|
# 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
|
# trim the string on the right
|
||||||
txtvalue_old=${txtvalue_old%%\"*}
|
txtvalue_old=${txtvalue_old%%\"*}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
TRANSIP_Api_Url="https://api.transip.nl/v6"
|
TRANSIP_Api_Url="https://api.transip.nl/v6"
|
||||||
TRANSIP_Token_Read_Only="false"
|
TRANSIP_Token_Read_Only="false"
|
||||||
TRANSIP_Token_Global_Key="false"
|
|
||||||
TRANSIP_Token_Expiration="30 minutes"
|
TRANSIP_Token_Expiration="30 minutes"
|
||||||
# You can't reuse a label token, so we leave this empty normally
|
# You can't reuse a label token, so we leave this empty normally
|
||||||
TRANSIP_Token_Label=""
|
TRANSIP_Token_Label=""
|
||||||
@ -96,7 +95,11 @@ _transip_get_token() {
|
|||||||
nonce=$(echo "TRANSIP$(_time)" | _digest sha1 hex | cut -c 1-32)
|
nonce=$(echo "TRANSIP$(_time)" | _digest sha1 hex | cut -c 1-32)
|
||||||
_debug nonce "$nonce"
|
_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"
|
_debug data "$data"
|
||||||
|
|
||||||
#_signature=$(printf "%s" "$data" | openssl dgst -sha512 -sign "$TRANSIP_Key_File" | _base64)
|
#_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_Username "$TRANSIP_Username"
|
||||||
_saveaccountconf_mutable TRANSIP_Key_File "$TRANSIP_Key_File"
|
_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 [ -f "$TRANSIP_Key_File" ]; then
|
||||||
if ! grep "BEGIN PRIVATE KEY" "$TRANSIP_Key_File" >/dev/null 2>&1; 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}"
|
_err "Key file doesn't seem to be a valid key: ${TRANSIP_Key_File}"
|
||||||
@ -156,6 +171,12 @@ _transip_setup() {
|
|||||||
fi
|
fi
|
||||||
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
|
_get_root "$fulldomain" || return 1
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
@ -78,7 +78,7 @@ dns_vultr_rm() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'id' | cut -d : -f 2)"
|
_record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'id' | cut -d : -f 2 | tr -d '"')"
|
||||||
_debug _record_id "$_record_id"
|
_debug _record_id "$_record_id"
|
||||||
if [ "$_record_id" ]; then
|
if [ "$_record_id" ]; then
|
||||||
_info "Successfully retrieved the record id for ACME challenge."
|
_info "Successfully retrieved the record id for ACME challenge."
|
||||||
@ -116,7 +116,7 @@ _get_root() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if printf "%s\n" "$response" | grep '^\{.*\}' >/dev/null; then
|
if printf "%s\n" "$response" | grep -E '^\{.*\}' >/dev/null; then
|
||||||
if _contains "$response" "\"domain\":\"$_domain\""; then
|
if _contains "$response" "\"domain\":\"$_domain\""; then
|
||||||
_sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")"
|
_sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")"
|
||||||
return 0
|
return 0
|
||||||
@ -139,7 +139,7 @@ _vultr_rest() {
|
|||||||
data="$3"
|
data="$3"
|
||||||
_debug "$ep"
|
_debug "$ep"
|
||||||
|
|
||||||
api_key_trimmed=$(echo $VULTR_API_KEY | tr -d '"')
|
api_key_trimmed=$(echo "$VULTR_API_KEY" | tr -d '"')
|
||||||
|
|
||||||
export _H1="Authorization: Bearer $api_key_trimmed"
|
export _H1="Authorization: Bearer $api_key_trimmed"
|
||||||
export _H2='Content-Type: application/json'
|
export _H2='Content-Type: application/json'
|
||||||
|
@ -195,7 +195,7 @@ _get_paketnr() {
|
|||||||
fqdn="$1"
|
fqdn="$1"
|
||||||
form="$2"
|
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=''
|
domain=''
|
||||||
for domain in $domains; do
|
for domain in $domains; do
|
||||||
if _contains "$fqdn" "$domain\$"; then
|
if _contains "$fqdn" "$domain\$"; then
|
||||||
@ -210,7 +210,7 @@ _get_paketnr() {
|
|||||||
TLD="$domain"
|
TLD="$domain"
|
||||||
_debug domain "$domain"
|
_debug domain "$domain"
|
||||||
RECORD=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#TLD} - 1))")
|
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
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
@ -169,7 +169,7 @@ _clean_email_header() {
|
|||||||
# email
|
# email
|
||||||
_email_has_display_name() {
|
_email_has_display_name() {
|
||||||
_email="$1"
|
_email="$1"
|
||||||
expr "$_email" : '^.*[<>"]' >/dev/null
|
echo "$_email" | grep -q -E '^.*[<>"]'
|
||||||
}
|
}
|
||||||
|
|
||||||
##
|
##
|
||||||
@ -249,7 +249,7 @@ _mime_encoded_word() {
|
|||||||
_text="$1"
|
_text="$1"
|
||||||
# (regex character ranges like [a-z] can be locale-dependent; enumerate ASCII chars to avoid that)
|
# (regex character ranges like [a-z] can be locale-dependent; enumerate ASCII chars to avoid that)
|
||||||
_ascii='] $`"'"[!#%&'()*+,./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ~^_abcdefghijklmnopqrstuvwxyz{|}~-"
|
_ascii='] $`"'"[!#%&'()*+,./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ~^_abcdefghijklmnopqrstuvwxyz{|}~-"
|
||||||
if expr "$_text" : "^.*[^$_ascii]" >/dev/null; then
|
if echo "$_text" | grep -q -E "^.*[^$_ascii]"; then
|
||||||
# At least one non-ASCII char; convert entire thing to encoded word
|
# At least one non-ASCII char; convert entire thing to encoded word
|
||||||
printf "%s" "=?UTF-8?B?$(printf "%s" "$_text" | _base64)?="
|
printf "%s" "=?UTF-8?B?$(printf "%s" "$_text" | _base64)?="
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user