diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml
index b9389438..17e98ae3 100644
--- a/.github/workflows/DNS.yml
+++ b/.github/workflows/DNS.yml
@@ -1,339 +1,465 @@
-name: DNS
-on:
- push:
- paths:
- - 'dnsapi/*.sh'
- - '.github/workflows/DNS.yml'
- pull_request:
- branches:
- - 'dev'
- paths:
- - 'dnsapi/*.sh'
- - '.github/workflows/DNS.yml'
-
-
-jobs:
- CheckToken:
- runs-on: ubuntu-latest
- outputs:
- hasToken: ${{ steps.step_one.outputs.hasToken }}
- steps:
- - name: Set the value
- id: step_one
- run: |
- if [ "${{secrets.TokenName1}}" ] ; then
- echo "::set-output name=hasToken::true"
- else
- echo "::set-output name=hasToken::false"
- fi
- - name: Check the value
- run: echo ${{ steps.step_one.outputs.hasToken }}
-
- Fail:
- runs-on: ubuntu-latest
- needs: CheckToken
- if: "contains(needs.CheckToken.outputs.hasToken, 'false')"
- steps:
- - name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test"
- run: |
- echo "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test"
- if [ "${{github.repository_owner}}" != "acmesh-official" ]; then
- false
- fi
-
- Docker:
- runs-on: ubuntu-latest
- needs: CheckToken
- if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
- env:
- TEST_DNS : ${{ secrets.TEST_DNS }}
- TestingDomain: ${{ secrets.TestingDomain }}
- TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
- TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
- TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
- CASE: le_test_dnsapi
- TEST_LOCAL: 1
- DEBUG: 1
- steps:
- - uses: actions/checkout@v2
- - name: Clone acmetest
- run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- - name: Set env file
- run: |
- cd ../acmetest
- if [ "${{ secrets.TokenName1}}" ] ; then
- echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> docker.env
- fi
- if [ "${{ secrets.TokenName2}}" ] ; then
- echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> docker.env
- fi
- if [ "${{ secrets.TokenName3}}" ] ; then
- echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> docker.env
- fi
- if [ "${{ secrets.TokenName4}}" ] ; then
- echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> docker.env
- fi
- if [ "${{ secrets.TokenName5}}" ] ; then
- echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env
- fi
- echo "TEST_DNS_NO_WILDCARD" >> docker.env
- echo "TEST_DNS_SLEEP" >> docker.env
- - name: Run acmetest
- run: cd ../acmetest && ./rundocker.sh testall
-
- MacOS:
- runs-on: macos-latest
- needs: Docker
- env:
- TEST_DNS : ${{ secrets.TEST_DNS }}
- TestingDomain: ${{ secrets.TestingDomain }}
- TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
- TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
- TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
- CASE: le_test_dnsapi
- TEST_LOCAL: 1
- DEBUG: 1
- steps:
- - uses: actions/checkout@v2
- - name: Install tools
- run: brew install socat
- - name: Clone acmetest
- run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- - name: Run acmetest
- run: |
- if [ "${{ secrets.TokenName1}}" ] ; then
- export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
- fi
- if [ "${{ secrets.TokenName2}}" ] ; then
- export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
- fi
- if [ "${{ secrets.TokenName3}}" ] ; then
- export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
- fi
- if [ "${{ secrets.TokenName4}}" ] ; then
- export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
- fi
- if [ "${{ secrets.TokenName5}}" ] ; then
- export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
- fi
- cd ../acmetest
- ./letest.sh
-
- Windows:
- runs-on: windows-latest
- needs: MacOS
- env:
- TEST_DNS : ${{ secrets.TEST_DNS }}
- TestingDomain: ${{ secrets.TestingDomain }}
- TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
- TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
- TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
- CASE: le_test_dnsapi
- TEST_LOCAL: 1
- DEBUG: 1
- steps:
- - name: Set git to use LF
- run: |
- git config --global core.autocrlf false
- - uses: actions/checkout@v2
- - name: Install cygwin base packages with chocolatey
- run: |
- choco config get cacheLocation
- choco install --no-progress cygwin
- shell: cmd
- - name: Install cygwin additional packages
- run: |
- C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git
- shell: cmd
- - name: Set ENV
- shell: cmd
- run: |
- echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV%
- - name: Clone acmetest
- run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- - name: Run acmetest
- shell: bash
- run: |
- if [ "${{ secrets.TokenName1}}" ] ; then
- export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
- fi
- if [ "${{ secrets.TokenName2}}" ] ; then
- export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
- fi
- if [ "${{ secrets.TokenName3}}" ] ; then
- export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
- fi
- if [ "${{ secrets.TokenName4}}" ] ; then
- export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
- fi
- if [ "${{ secrets.TokenName5}}" ] ; then
- export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
- fi
- cd ../acmetest
- ./letest.sh
-
- FreeBSD:
- runs-on: macos-12
- needs: Windows
- env:
- TEST_DNS : ${{ secrets.TEST_DNS }}
- TestingDomain: ${{ secrets.TestingDomain }}
- TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
- TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
- TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
- CASE: le_test_dnsapi
- TEST_LOCAL: 1
- DEBUG: 1
- steps:
- - uses: actions/checkout@v2
- - name: Clone acmetest
- run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- - uses: vmactions/freebsd-vm@v0.1.8
- with:
- envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
- prepare: pkg install -y socat curl
- usesh: true
- run: |
- if [ "${{ secrets.TokenName1}}" ] ; then
- export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
- fi
- if [ "${{ secrets.TokenName2}}" ] ; then
- export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
- fi
- if [ "${{ secrets.TokenName3}}" ] ; then
- export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
- fi
- if [ "${{ secrets.TokenName4}}" ] ; then
- export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
- fi
- if [ "${{ secrets.TokenName5}}" ] ; then
- export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
- fi
- cd ../acmetest
- ./letest.sh
-
- Solaris:
- runs-on: macos-12
- needs: FreeBSD
- env:
- TEST_DNS : ${{ secrets.TEST_DNS }}
- TestingDomain: ${{ secrets.TestingDomain }}
- TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
- TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
- TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
- CASE: le_test_dnsapi
- TEST_LOCAL: 1
- DEBUG: 1
- steps:
- - uses: actions/checkout@v2
- - name: Clone acmetest
- run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- - uses: vmactions/solaris-vm@v0.0.5
- with:
- envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
- prepare: pkgutil -y -i socat
- run: |
- pkg set-mediator -v -I default@1.1 openssl
- export PATH=/usr/gnu/bin:$PATH
- if [ "${{ secrets.TokenName1}}" ] ; then
- export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
- fi
- if [ "${{ secrets.TokenName2}}" ] ; then
- export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
- fi
- if [ "${{ secrets.TokenName3}}" ] ; then
- export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
- fi
- if [ "${{ secrets.TokenName4}}" ] ; then
- export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
- fi
- if [ "${{ secrets.TokenName5}}" ] ; then
- export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
- fi
- cd ../acmetest
- ./letest.sh
-
-
- 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: 1
- steps:
- - uses: actions/checkout@v2
- - name: Clone acmetest
- run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- - uses: vmactions/openbsd-vm@v0.0.4
- with:
- envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
- prepare: pkg_add socat curl
- usesh: true
- run: |
- if [ "${{ secrets.TokenName1}}" ] ; then
- export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
- fi
- if [ "${{ secrets.TokenName2}}" ] ; then
- export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
- fi
- if [ "${{ secrets.TokenName3}}" ] ; then
- export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
- fi
- if [ "${{ secrets.TokenName4}}" ] ; then
- export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
- fi
- if [ "${{ secrets.TokenName5}}" ] ; then
- export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
- fi
- cd ../acmetest
- ./letest.sh
-
- NetBSD:
- runs-on: macos-12
- needs: OpenBSD
- env:
- TEST_DNS : ${{ secrets.TEST_DNS }}
- TestingDomain: ${{ secrets.TestingDomain }}
- TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
- TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
- TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
- CASE: le_test_dnsapi
- TEST_LOCAL: 1
- DEBUG: 1
- steps:
- - uses: actions/checkout@v2
- - name: Clone acmetest
- run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- - uses: vmactions/netbsd-vm@v0.0.2
- with:
- envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
- prepare: |
- 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
- usesh: true
- run: |
- if [ "${{ secrets.TokenName1}}" ] ; then
- export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
- fi
- if [ "${{ secrets.TokenName2}}" ] ; then
- export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
- fi
- if [ "${{ secrets.TokenName3}}" ] ; then
- export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
- fi
- if [ "${{ secrets.TokenName4}}" ] ; then
- export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
- fi
- if [ "${{ secrets.TokenName5}}" ] ; then
- export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
- fi
- cd ../acmetest
- ./letest.sh
-
-
\ No newline at end of file
+name: DNS
+on:
+ push:
+ paths:
+ - 'dnsapi/*.sh'
+ - '.github/workflows/DNS.yml'
+ pull_request:
+ branches:
+ - 'dev'
+ paths:
+ - 'dnsapi/*.sh'
+ - '.github/workflows/DNS.yml'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ CheckToken:
+ runs-on: ubuntu-latest
+ outputs:
+ hasToken: ${{ steps.step_one.outputs.hasToken }}
+ steps:
+ - name: Set the value
+ id: step_one
+ run: |
+ if [ "${{secrets.TokenName1}}" ] ; then
+ echo "::set-output name=hasToken::true"
+ else
+ echo "::set-output name=hasToken::false"
+ fi
+ - name: Check the value
+ run: echo ${{ steps.step_one.outputs.hasToken }}
+
+ Fail:
+ runs-on: ubuntu-latest
+ needs: CheckToken
+ if: "contains(needs.CheckToken.outputs.hasToken, 'false')"
+ steps:
+ - name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test"
+ run: |
+ echo "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test"
+ if [ "${{github.repository_owner}}" != "acmesh-official" ]; then
+ false
+ fi
+
+ Docker:
+ runs-on: ubuntu-latest
+ needs: CheckToken
+ if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
+ env:
+ TEST_DNS : ${{ secrets.TEST_DNS }}
+ TestingDomain: ${{ secrets.TestingDomain }}
+ TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
+ TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
+ TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
+ CASE: le_test_dnsapi
+ TEST_LOCAL: 1
+ DEBUG: ${{ secrets.DEBUG }}
+ http_proxy: ${{ secrets.http_proxy }}
+ https_proxy: ${{ secrets.https_proxy }}
+ TokenName1: ${{ secrets.TokenName1}}
+ TokenName2: ${{ secrets.TokenName2}}
+ TokenName3: ${{ secrets.TokenName3}}
+ TokenName4: ${{ secrets.TokenName4}}
+ TokenName5: ${{ secrets.TokenName5}}
+ steps:
+ - uses: actions/checkout@v3
+ - name: Clone acmetest
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ - name: Set env file
+ run: |
+ cd ../acmetest
+ if [ "${{ secrets.TokenName1}}" ] ; then
+ echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> docker.env
+ fi
+ if [ "${{ secrets.TokenName2}}" ] ; then
+ echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> docker.env
+ fi
+ if [ "${{ secrets.TokenName3}}" ] ; then
+ echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> docker.env
+ fi
+ if [ "${{ secrets.TokenName4}}" ] ; then
+ echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> docker.env
+ fi
+ if [ "${{ secrets.TokenName5}}" ] ; then
+ echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env
+ fi
+
+ - name: Run acmetest
+ run: cd ../acmetest && ./rundocker.sh testall
+
+
+
+
+ MacOS:
+ runs-on: macos-latest
+ needs: Docker
+ env:
+ TEST_DNS : ${{ secrets.TEST_DNS }}
+ TestingDomain: ${{ secrets.TestingDomain }}
+ TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
+ TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
+ TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
+ CASE: le_test_dnsapi
+ TEST_LOCAL: 1
+ DEBUG: ${{ secrets.DEBUG }}
+ http_proxy: ${{ secrets.http_proxy }}
+ https_proxy: ${{ secrets.https_proxy }}
+ TokenName1: ${{ secrets.TokenName1}}
+ TokenName2: ${{ secrets.TokenName2}}
+ TokenName3: ${{ secrets.TokenName3}}
+ TokenName4: ${{ secrets.TokenName4}}
+ TokenName5: ${{ secrets.TokenName5}}
+ steps:
+ - uses: actions/checkout@v3
+ - name: Install tools
+ run: brew install socat
+ - name: Clone acmetest
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ - name: Run acmetest
+ run: |
+ if [ "${{ secrets.TokenName1}}" ] ; then
+ export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
+ fi
+ if [ "${{ secrets.TokenName2}}" ] ; then
+ export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
+ fi
+ if [ "${{ secrets.TokenName3}}" ] ; then
+ export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
+ fi
+ if [ "${{ secrets.TokenName4}}" ] ; then
+ export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
+ fi
+ if [ "${{ secrets.TokenName5}}" ] ; then
+ export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
+ fi
+ cd ../acmetest
+ ./letest.sh
+
+
+
+
+ Windows:
+ runs-on: windows-latest
+ needs: MacOS
+ env:
+ TEST_DNS : ${{ secrets.TEST_DNS }}
+ TestingDomain: ${{ secrets.TestingDomain }}
+ TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
+ TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
+ TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
+ CASE: le_test_dnsapi
+ TEST_LOCAL: 1
+ DEBUG: ${{ secrets.DEBUG }}
+ http_proxy: ${{ secrets.http_proxy }}
+ https_proxy: ${{ secrets.https_proxy }}
+ TokenName1: ${{ secrets.TokenName1}}
+ TokenName2: ${{ secrets.TokenName2}}
+ TokenName3: ${{ secrets.TokenName3}}
+ TokenName4: ${{ secrets.TokenName4}}
+ TokenName5: ${{ secrets.TokenName5}}
+ steps:
+ - name: Set git to use LF
+ run: |
+ git config --global core.autocrlf false
+ - uses: actions/checkout@v3
+ - name: Install cygwin base packages with chocolatey
+ run: |
+ choco config get cacheLocation
+ choco install --no-progress cygwin
+ shell: cmd
+ - name: Install cygwin additional packages
+ run: |
+ C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s https://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git
+ shell: cmd
+ - name: Set ENV
+ shell: cmd
+ run: |
+ echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV%
+ - name: Clone acmetest
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ - name: Run acmetest
+ shell: bash
+ run: |
+ if [ "${{ secrets.TokenName1}}" ] ; then
+ export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
+ fi
+ if [ "${{ secrets.TokenName2}}" ] ; then
+ export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
+ fi
+ if [ "${{ secrets.TokenName3}}" ] ; then
+ export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
+ fi
+ if [ "${{ secrets.TokenName4}}" ] ; then
+ export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
+ fi
+ if [ "${{ secrets.TokenName5}}" ] ; then
+ export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
+ fi
+ cd ../acmetest
+ ./letest.sh
+
+
+
+ FreeBSD:
+ runs-on: macos-12
+ needs: Windows
+ env:
+ TEST_DNS : ${{ secrets.TEST_DNS }}
+ TestingDomain: ${{ secrets.TestingDomain }}
+ TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
+ TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
+ TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
+ CASE: le_test_dnsapi
+ TEST_LOCAL: 1
+ DEBUG: ${{ secrets.DEBUG }}
+ http_proxy: ${{ secrets.http_proxy }}
+ https_proxy: ${{ secrets.https_proxy }}
+ TokenName1: ${{ secrets.TokenName1}}
+ TokenName2: ${{ secrets.TokenName2}}
+ TokenName3: ${{ secrets.TokenName3}}
+ TokenName4: ${{ secrets.TokenName4}}
+ TokenName5: ${{ secrets.TokenName5}}
+ steps:
+ - uses: actions/checkout@v3
+ - name: Clone acmetest
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ - uses: vmactions/freebsd-vm@v0
+ with:
+ envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
+ prepare: pkg install -y socat curl
+ usesh: true
+ copyback: false
+ run: |
+ if [ "${{ secrets.TokenName1}}" ] ; then
+ export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
+ fi
+ if [ "${{ secrets.TokenName2}}" ] ; then
+ export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
+ fi
+ if [ "${{ secrets.TokenName3}}" ] ; then
+ export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
+ fi
+ if [ "${{ secrets.TokenName4}}" ] ; then
+ export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
+ fi
+ if [ "${{ secrets.TokenName5}}" ] ; then
+ export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
+ fi
+ cd ../acmetest
+ ./letest.sh
+
+
+
+
+ OpenBSD:
+ runs-on: macos-12
+ needs: FreeBSD
+ env:
+ TEST_DNS : ${{ secrets.TEST_DNS }}
+ TestingDomain: ${{ secrets.TestingDomain }}
+ TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
+ TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
+ TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
+ CASE: le_test_dnsapi
+ TEST_LOCAL: 1
+ DEBUG: ${{ secrets.DEBUG }}
+ http_proxy: ${{ secrets.http_proxy }}
+ https_proxy: ${{ secrets.https_proxy }}
+ TokenName1: ${{ secrets.TokenName1}}
+ TokenName2: ${{ secrets.TokenName2}}
+ TokenName3: ${{ secrets.TokenName3}}
+ TokenName4: ${{ secrets.TokenName4}}
+ TokenName5: ${{ secrets.TokenName5}}
+ steps:
+ - uses: actions/checkout@v3
+ - name: Clone acmetest
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ - uses: vmactions/openbsd-vm@v0
+ with:
+ envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
+ prepare: pkg_add socat curl
+ usesh: true
+ copyback: false
+ run: |
+ if [ "${{ secrets.TokenName1}}" ] ; then
+ export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
+ fi
+ if [ "${{ secrets.TokenName2}}" ] ; then
+ export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
+ fi
+ if [ "${{ secrets.TokenName3}}" ] ; then
+ export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
+ fi
+ if [ "${{ secrets.TokenName4}}" ] ; then
+ export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
+ fi
+ if [ "${{ secrets.TokenName5}}" ] ; then
+ export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
+ fi
+ cd ../acmetest
+ ./letest.sh
+
+
+
+
+ NetBSD:
+ runs-on: macos-12
+ needs: OpenBSD
+ env:
+ TEST_DNS : ${{ secrets.TEST_DNS }}
+ TestingDomain: ${{ secrets.TestingDomain }}
+ TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
+ TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
+ TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
+ CASE: le_test_dnsapi
+ TEST_LOCAL: 1
+ DEBUG: ${{ secrets.DEBUG }}
+ http_proxy: ${{ secrets.http_proxy }}
+ https_proxy: ${{ secrets.https_proxy }}
+ TokenName1: ${{ secrets.TokenName1}}
+ TokenName2: ${{ secrets.TokenName2}}
+ TokenName3: ${{ secrets.TokenName3}}
+ TokenName4: ${{ secrets.TokenName4}}
+ TokenName5: ${{ secrets.TokenName5}}
+ steps:
+ - uses: actions/checkout@v3
+ - name: Clone acmetest
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ - uses: vmactions/netbsd-vm@v0
+ with:
+ envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
+ prepare: |
+ pkg_add curl socat
+ usesh: true
+ copyback: false
+ run: |
+ if [ "${{ secrets.TokenName1}}" ] ; then
+ export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
+ fi
+ if [ "${{ secrets.TokenName2}}" ] ; then
+ export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
+ fi
+ if [ "${{ secrets.TokenName3}}" ] ; then
+ export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
+ fi
+ if [ "${{ secrets.TokenName4}}" ] ; then
+ export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
+ fi
+ if [ "${{ secrets.TokenName5}}" ] ; then
+ export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
+ fi
+ cd ../acmetest
+ ./letest.sh
+
+
+
+
+ DragonFlyBSD:
+ runs-on: macos-12
+ needs: NetBSD
+ env:
+ TEST_DNS : ${{ secrets.TEST_DNS }}
+ TestingDomain: ${{ secrets.TestingDomain }}
+ TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
+ TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
+ TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
+ CASE: le_test_dnsapi
+ TEST_LOCAL: 1
+ DEBUG: ${{ secrets.DEBUG }}
+ http_proxy: ${{ secrets.http_proxy }}
+ https_proxy: ${{ secrets.https_proxy }}
+ TokenName1: ${{ secrets.TokenName1}}
+ TokenName2: ${{ secrets.TokenName2}}
+ TokenName3: ${{ secrets.TokenName3}}
+ TokenName4: ${{ secrets.TokenName4}}
+ TokenName5: ${{ secrets.TokenName5}}
+ steps:
+ - uses: actions/checkout@v3
+ - name: Clone acmetest
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ - uses: vmactions/dragonflybsd-vm@v0
+ with:
+ envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
+ prepare: |
+ pkg install -y curl socat
+ usesh: true
+ copyback: false
+ run: |
+ if [ "${{ secrets.TokenName1}}" ] ; then
+ export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
+ fi
+ if [ "${{ secrets.TokenName2}}" ] ; then
+ export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
+ fi
+ if [ "${{ secrets.TokenName3}}" ] ; then
+ export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
+ fi
+ if [ "${{ secrets.TokenName4}}" ] ; then
+ export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
+ fi
+ if [ "${{ secrets.TokenName5}}" ] ; then
+ export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
+ fi
+ cd ../acmetest
+ ./letest.sh
+
+
+
+
+
+
+
+ Solaris:
+ runs-on: macos-12
+ needs: DragonFlyBSD
+ env:
+ TEST_DNS : ${{ secrets.TEST_DNS }}
+ TestingDomain: ${{ secrets.TestingDomain }}
+ TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
+ TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
+ TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
+ CASE: le_test_dnsapi
+ TEST_LOCAL: 1
+ DEBUG: ${{ secrets.DEBUG }}
+ http_proxy: ${{ secrets.http_proxy }}
+ https_proxy: ${{ secrets.https_proxy }}
+ HTTPS_INSECURE: 1 # always set to 1 to ignore https error, since Solaris doesn't accept the expired ISRG X1 root
+ TokenName1: ${{ secrets.TokenName1}}
+ TokenName2: ${{ secrets.TokenName2}}
+ TokenName3: ${{ secrets.TokenName3}}
+ TokenName4: ${{ secrets.TokenName4}}
+ TokenName5: ${{ secrets.TokenName5}}
+ steps:
+ - uses: actions/checkout@v3
+ - name: Clone acmetest
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ - uses: vmactions/solaris-vm@v0
+ with:
+ envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy HTTPS_INSECURE TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
+ copyback: false
+ prepare: pkgutil -y -i socat
+ run: |
+ pkg set-mediator -v -I default@1.1 openssl
+ export PATH=/usr/gnu/bin:$PATH
+ if [ "${{ secrets.TokenName1}}" ] ; then
+ export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
+ fi
+ if [ "${{ secrets.TokenName2}}" ] ; then
+ export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
+ fi
+ if [ "${{ secrets.TokenName3}}" ] ; then
+ export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
+ fi
+ if [ "${{ secrets.TokenName4}}" ] ; then
+ export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
+ fi
+ if [ "${{ secrets.TokenName5}}" ] ; then
+ export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
+ fi
+ cd ../acmetest
+ ./letest.sh
+
+
diff --git a/.github/workflows/DragonFlyBSD.yml b/.github/workflows/DragonFlyBSD.yml
new file mode 100644
index 00000000..6daa9be4
--- /dev/null
+++ b/.github/workflows/DragonFlyBSD.yml
@@ -0,0 +1,71 @@
+name: DragonFlyBSD
+on:
+ push:
+ branches:
+ - '*'
+ paths:
+ - '*.sh'
+ - '.github/workflows/DragonFlyBSD.yml'
+
+ pull_request:
+ branches:
+ - dev
+ paths:
+ - '*.sh'
+ - '.github/workflows/DragonFlyBSD.yml'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+
+
+
+jobs:
+ DragonFlyBSD:
+ strategy:
+ matrix:
+ include:
+ - TEST_ACME_Server: "LetsEncrypt.org_test"
+ CA_ECDSA: ""
+ CA: ""
+ CA_EMAIL: ""
+ TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
+ #- TEST_ACME_Server: "ZeroSSL.com"
+ # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
+ # CA: "ZeroSSL RSA Domain Secure Site CA"
+ # CA_EMAIL: "githubtest@acme.sh"
+ # TEST_PREFERRED_CHAIN: ""
+ runs-on: macos-12
+ env:
+ TEST_LOCAL: 1
+ TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
+ CA_ECDSA: ${{ matrix.CA_ECDSA }}
+ CA: ${{ matrix.CA }}
+ CA_EMAIL: ${{ matrix.CA_EMAIL }}
+ TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
+ steps:
+ - uses: actions/checkout@v3
+ - uses: vmactions/cf-tunnel@v0
+ id: tunnel
+ with:
+ protocol: http
+ port: 8080
+ - name: Set envs
+ run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
+ - name: Clone acmetest
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ - uses: vmactions/dragonflybsd-vm@v0
+ with:
+ envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
+ copyback: "false"
+ nat: |
+ "8080": "80"
+ prepare: |
+ pkg install -y curl socat
+ usesh: true
+ run: |
+ cd ../acmetest \
+ && ./letest.sh
+
+
diff --git a/.github/workflows/FreeBSD.yml b/.github/workflows/FreeBSD.yml
index 027b7caf..0fa55fd4 100644
--- a/.github/workflows/FreeBSD.yml
+++ b/.github/workflows/FreeBSD.yml
@@ -14,6 +14,11 @@ on:
- '*.sh'
- '.github/workflows/FreeBSD.yml'
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+
jobs:
FreeBSD:
@@ -25,6 +30,12 @@ jobs:
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
+ - TEST_ACME_Server: "LetsEncrypt.org_test"
+ CA_ECDSA: ""
+ CA: ""
+ CA_EMAIL: ""
+ TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
+ ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA"
@@ -38,9 +49,10 @@ jobs:
CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
+ ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
steps:
- - uses: actions/checkout@v2
- - uses: vmactions/cf-tunnel@v0.0.3
+ - uses: actions/checkout@v3
+ - uses: vmactions/cf-tunnel@v0
id: tunnel
with:
protocol: http
@@ -48,14 +60,15 @@ jobs:
- name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest
- run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- - uses: vmactions/freebsd-vm@v0.1.8
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ - uses: vmactions/freebsd-vm@v0
with:
- envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
+ envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: |
"8080": "80"
- prepare: pkg install -y socat curl
+ prepare: pkg install -y socat curl wget
usesh: true
+ copyback: false
run: |
cd ../acmetest \
&& ./letest.sh
diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml
index c665652a..156fa5df 100644
--- a/.github/workflows/Linux.yml
+++ b/.github/workflows/Linux.yml
@@ -15,6 +15,12 @@ on:
- '.github/workflows/Linux.yml'
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+
+
jobs:
Linux:
@@ -27,11 +33,11 @@ jobs:
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
TEST_ACME_Server: "LetsEncrypt.org_test"
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Clone acmetest
run: |
cd .. \
- && git clone https://github.com/acmesh-official/acmetest.git \
+ && git clone --depth=1 https://github.com/acmesh-official/acmetest.git \
&& cp -r acme.sh acmetest/
- name: Run acmetest
run: |
diff --git a/.github/workflows/MacOS.yml b/.github/workflows/MacOS.yml
index 8d52b3f6..c1f29769 100644
--- a/.github/workflows/MacOS.yml
+++ b/.github/workflows/MacOS.yml
@@ -14,6 +14,11 @@ on:
- '*.sh'
- '.github/workflows/MacOS.yml'
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+
jobs:
MacOS:
@@ -39,13 +44,13 @@ jobs:
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Install tools
run: brew install socat
- name: Clone acmetest
run: |
cd .. \
- && git clone https://github.com/acmesh-official/acmetest.git \
+ && git clone --depth=1 https://github.com/acmesh-official/acmetest.git \
&& cp -r acme.sh acmetest/
- name: Run acmetest
run: |
diff --git a/.github/workflows/NetBSD.yml b/.github/workflows/NetBSD.yml
index 609d1131..33bcf23c 100644
--- a/.github/workflows/NetBSD.yml
+++ b/.github/workflows/NetBSD.yml
@@ -14,6 +14,12 @@ on:
- '*.sh'
- '.github/workflows/NetBSD.yml'
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+
+
jobs:
NetBSD:
@@ -39,8 +45,8 @@ jobs:
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
steps:
- - uses: actions/checkout@v2
- - uses: vmactions/cf-tunnel@v0.0.3
+ - uses: actions/checkout@v3
+ - uses: vmactions/cf-tunnel@v0
id: tunnel
with:
protocol: http
@@ -48,16 +54,17 @@ jobs:
- name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest
- run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- - uses: vmactions/netbsd-vm@v0.0.2
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ - uses: vmactions/netbsd-vm@v0
with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
nat: |
"8080": "80"
prepare: |
- export PKG_PATH="http://cdn.NetBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f '1 2' -d.)/All/"
+ export PKG_PATH="https://cdn.NetBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f '1 2' -d.)/All/"
pkg_add curl socat
usesh: true
+ copyback: false
run: |
cd ../acmetest \
&& ./letest.sh
diff --git a/.github/workflows/OpenBSD.yml b/.github/workflows/OpenBSD.yml
index 0d3465de..7746645a 100644
--- a/.github/workflows/OpenBSD.yml
+++ b/.github/workflows/OpenBSD.yml
@@ -14,6 +14,11 @@ on:
- '*.sh'
- '.github/workflows/OpenBSD.yml'
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+
jobs:
OpenBSD:
@@ -25,6 +30,12 @@ jobs:
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
+ - TEST_ACME_Server: "LetsEncrypt.org_test"
+ CA_ECDSA: ""
+ CA: ""
+ CA_EMAIL: ""
+ TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
+ ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA"
@@ -38,9 +49,10 @@ jobs:
CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
+ ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
steps:
- - uses: actions/checkout@v2
- - uses: vmactions/cf-tunnel@v0.0.3
+ - uses: actions/checkout@v3
+ - uses: vmactions/cf-tunnel@v0
id: tunnel
with:
protocol: http
@@ -48,14 +60,15 @@ jobs:
- name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest
- run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- - uses: vmactions/openbsd-vm@v0.0.4
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ - uses: vmactions/openbsd-vm@v0
with:
- envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
+ envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: |
"8080": "80"
- prepare: pkg_add socat curl
+ prepare: pkg_add socat curl wget
usesh: true
+ copyback: false
run: |
cd ../acmetest \
&& ./letest.sh
diff --git a/.github/workflows/PebbleStrict.yml b/.github/workflows/PebbleStrict.yml
index c1ea1cd2..9f3a98ce 100644
--- a/.github/workflows/PebbleStrict.yml
+++ b/.github/workflows/PebbleStrict.yml
@@ -13,6 +13,13 @@ on:
- '*.sh'
- '.github/workflows/PebbleStrict.yml'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+
+
jobs:
PebbleStrict:
runs-on: ubuntu-latest
@@ -26,7 +33,7 @@ jobs:
TEST_CA: "Pebble Intermediate CA"
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Install tools
run: sudo apt-get install -y socat
- name: Run Pebble
@@ -34,15 +41,15 @@ jobs:
- name: Set up Pebble
run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4
- name: Clone acmetest
- run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
run: cd ../acmetest && ./letest.sh
PebbleStrict_IPCert:
runs-on: ubuntu-latest
env:
- TestingDomain: 10.30.50.1
- ACME_DIRECTORY: https://localhost:14000/dir
+ TestingDomain: 1.23.45.67
+ TEST_ACME_Server: https://localhost:14000/dir
HTTPS_INSECURE: 1
Le_HTTPPort: 5002
Le_TLSPort: 5001
@@ -51,12 +58,15 @@ jobs:
TEST_IPCERT: 1
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Install tools
run: sudo apt-get install -y socat
- name: Run Pebble
- run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d
+ run: |
+ docker run --rm -itd --name=pebble \
+ -e PEBBLE_VA_ALWAYS_VALID=1 \
+ -p 14000:14000 -p 15000:15000 letsencrypt/pebble:latest pebble -config /test/config/pebble-config.json -strict
- name: Clone acmetest
- run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
run: cd ../acmetest && ./letest.sh
\ No newline at end of file
diff --git a/.github/workflows/Solaris.yml b/.github/workflows/Solaris.yml
index 6ba0e414..34d31a59 100644
--- a/.github/workflows/Solaris.yml
+++ b/.github/workflows/Solaris.yml
@@ -15,6 +15,11 @@ on:
- '.github/workflows/Solaris.yml'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
jobs:
Solaris:
strategy:
@@ -25,6 +30,12 @@ jobs:
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
+ - TEST_ACME_Server: "LetsEncrypt.org_test"
+ CA_ECDSA: ""
+ CA: ""
+ CA_EMAIL: ""
+ TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
+ ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA"
@@ -38,9 +49,10 @@ jobs:
CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
+ ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
steps:
- - uses: actions/checkout@v2
- - uses: vmactions/cf-tunnel@v0.0.3
+ - uses: actions/checkout@v3
+ - uses: vmactions/cf-tunnel@v0
id: tunnel
with:
protocol: http
@@ -48,13 +60,14 @@ jobs:
- name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest
- run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- - uses: vmactions/solaris-vm@v0.0.5
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ - uses: vmactions/solaris-vm@v0
with:
- envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
+ envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
+ copyback: "false"
nat: |
"8080": "80"
- prepare: pkgutil -y -i socat curl
+ prepare: pkgutil -y -i socat curl wget
run: |
cd ../acmetest \
&& ./letest.sh
diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml
index 4540580c..a6ec714c 100644
--- a/.github/workflows/Ubuntu.yml
+++ b/.github/workflows/Ubuntu.yml
@@ -14,6 +14,11 @@ on:
- '*.sh'
- '.github/workflows/Ubuntu.yml'
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+
jobs:
Ubuntu:
@@ -25,6 +30,12 @@ jobs:
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
+ - TEST_ACME_Server: "LetsEncrypt.org_test"
+ CA_ECDSA: ""
+ CA: ""
+ CA_EMAIL: ""
+ TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
+ ACME_USE_WGET: 1
- TEST_ACME_Server: "ZeroSSL.com"
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
CA: "ZeroSSL RSA Domain Secure Site CA"
@@ -57,10 +68,11 @@ jobs:
NO_REVOKE: ${{ matrix.NO_REVOKE }}
TEST_IPCERT: ${{ matrix.TEST_IPCERT }}
TestingDomain: ${{ matrix.TestingDomain }}
+ ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Install tools
- run: sudo apt-get install -y socat
+ run: sudo apt-get install -y socat wget
- name: Start StepCA
if: ${{ matrix.TEST_ACME_Server=='https://localhost:9000/acme/acme/directory' }}
run: |
@@ -76,7 +88,7 @@ jobs:
- name: Clone acmetest
run: |
cd .. \
- && git clone https://github.com/acmesh-official/acmetest.git \
+ && git clone --depth=1 https://github.com/acmesh-official/acmetest.git \
&& cp -r acme.sh acmetest/
- name: Run acmetest
run: |
diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml
index 55d32519..c02e2f77 100644
--- a/.github/workflows/Windows.yml
+++ b/.github/workflows/Windows.yml
@@ -15,6 +15,11 @@ on:
- '.github/workflows/Windows.yml'
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+
jobs:
Windows:
strategy:
@@ -44,7 +49,7 @@ jobs:
- name: Set git to use LF
run: |
git config --global core.autocrlf false
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Install cygwin base packages with chocolatey
run: |
choco config get cacheLocation
@@ -52,7 +57,7 @@ jobs:
shell: cmd
- name: Install cygwin additional packages
run: |
- C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git,xxd
+ C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s https://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git,xxd
shell: cmd
- name: Set ENV
shell: cmd
@@ -64,7 +69,7 @@ jobs:
echo "PATH=%PATH%"
- name: Clone acmetest
shell: cmd
- run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
+ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
shell: cmd
run: cd ../acmetest && bash.exe -c ./letest.sh
diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml
index 0c3aec0a..bd2c01aa 100644
--- a/.github/workflows/dockerhub.yml
+++ b/.github/workflows/dockerhub.yml
@@ -11,7 +11,11 @@ on:
- "Dockerfile"
- '.github/workflows/dockerhub.yml'
-
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+
jobs:
CheckToken:
runs-on: ubuntu-latest
@@ -37,7 +41,7 @@ jobs:
if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
steps:
- name: checkout code
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml
new file mode 100644
index 00000000..e92b0411
--- /dev/null
+++ b/.github/workflows/issue.yml
@@ -0,0 +1,19 @@
+name: "Update issues"
+on:
+ issues:
+ types: [opened]
+
+jobs:
+ comment:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/github-script@v6
+ with:
+ script: |
+ github.rest.issues.createComment({
+ issue_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ body: "Please upgrade to the latest code and try again first. Maybe it's already fixed. ```acme.sh --upgrade``` If it's still not working, please provide the log with `--debug 2`, otherwise, nobody can help you."
+
+ })
\ No newline at end of file
diff --git a/.github/workflows/pr_dns.yml b/.github/workflows/pr_dns.yml
new file mode 100644
index 00000000..5faa9105
--- /dev/null
+++ b/.github/workflows/pr_dns.yml
@@ -0,0 +1,30 @@
+name: Check dns api
+
+on:
+ pull_request_target:
+ types:
+ - opened
+ branches:
+ - 'dev'
+ paths:
+ - 'dnsapi/*.sh'
+
+
+jobs:
+ welcome:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/github-script@v6
+ with:
+ script: |
+ await github.rest.issues.createComment({
+ issue_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ body: `**Welcome**
+ Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test).
+ Then reply on this message, otherwise, your code will not be reviewed or merged.
+ We look forward to reviewing your Pull request shortly ✨
+ `
+ })
+
diff --git a/.github/workflows/pr_notify.yml b/.github/workflows/pr_notify.yml
new file mode 100644
index 00000000..4844e297
--- /dev/null
+++ b/.github/workflows/pr_notify.yml
@@ -0,0 +1,30 @@
+name: Check dns api
+
+on:
+ pull_request_target:
+ types:
+ - opened
+ branches:
+ - 'dev'
+ paths:
+ - 'notify/*.sh'
+
+
+jobs:
+ welcome:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/github-script@v6
+ with:
+ script: |
+ await github.rest.issues.createComment({
+ issue_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ body: `**Welcome**
+ Please make sure you're read our [Code-of-conduct](../wiki/Code-of-conduct) and add the usage here: [notify](../wiki/notify).
+ Then reply on this message, otherwise, your code will not be reviewed or merged.
+ We look forward to reviewing your Pull request shortly ✨
+ `
+ })
+
diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml
index 940a187d..a5a08bbf 100644
--- a/.github/workflows/shellcheck.yml
+++ b/.github/workflows/shellcheck.yml
@@ -13,20 +13,25 @@ on:
- '**.sh'
- '.github/workflows/shellcheck.yml'
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+
jobs:
ShellCheck:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Install Shellcheck
run: sudo apt-get install -y shellcheck
- name: DoShellcheck
- run: shellcheck -V && shellcheck -e SC2181 **/*.sh && echo "shellcheck OK"
+ run: shellcheck -V && shellcheck -e SC2181 -e SC2089 **/*.sh && echo "shellcheck OK"
shfmt:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Install shfmt
run: curl -sSL https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 -o ~/shfmt && chmod +x ~/shfmt
- name: shfmt
diff --git a/Dockerfile b/Dockerfile
index 049649f6..79fd1d89 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM alpine:3.15
+FROM alpine:3.16.3
RUN apk --no-cache add -f \
openssl \
diff --git a/README.md b/README.md
index 836664cd..15bc4089 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,8 @@
[![Ubuntu](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml)
[![Windows](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml)
[![Solaris](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml)
+[![DragonFlyBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml)
+
![Shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg)
![PebbleStrict](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg)
@@ -72,20 +74,21 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
|6|NA|pfsense
|7|[![OpenBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/OpenBSD.yml)|OpenBSD
|8|[![NetBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml)|NetBSD
-|9|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian
-|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS
-|11|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE
-|12|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl)
-|13|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Archlinux
-|14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora
-|15|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux
-|16|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux
-|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia
-|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux
-|19|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux
-|10|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111
-|21|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT)
-|22|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management)
+|9|[![DragonFlyBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml)|DragonFlyBSD
+|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian
+|11|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS
+|12|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE
+|13|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl)
+|14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Archlinux
+|15|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora
+|16|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux
+|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux
+|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia
+|19|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux
+|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux
+|11|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111
+|22|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT)
+|23|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management)
Check our [testing project](https://github.com/acmesh-official/acmetest):
@@ -358,10 +361,6 @@ Ok, it's done.
# 10. Issue ECC certificates
-`Let's Encrypt` can now issue **ECDSA** certificates.
-
-And we support them too!
-
Just set the `keylength` parameter with a prefix `ec-`.
For example:
@@ -382,10 +381,12 @@ Please look at the `keylength` parameter above.
Valid values are:
-1. **ec-256 (prime256v1, "ECDSA P-256")**
+1. **ec-256 (prime256v1, "ECDSA P-256", which is the default key type)**
2. **ec-384 (secp384r1, "ECDSA P-384")**
3. **ec-521 (secp521r1, "ECDSA P-521", which is not supported by Let's Encrypt yet.)**
-
+4. **2048 (RSA2048)**
+5. **3072 (RSA3072)**
+6. **4096 (RSA4096)**
# 11. Issue Wildcard certificates
@@ -506,6 +507,12 @@ Support this project with your organization. Your logo will show up here with a
+
+#### Sponsors
+
+[![quantumca-acmesh-logo](https://user-images.githubusercontent.com/8305679/183255712-634ee1db-bb61-4c03-bca0-bacce99e078c.svg)](https://www.quantumca.com.cn/?__utm_source=acmesh-donation)
+
+
# 19. License & Others
License is GPLv3
diff --git a/acme.sh b/acme.sh
index 3d65612f..c1a576a5 100755
--- a/acme.sh
+++ b/acme.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env sh
-VER=3.0.5
+VER=3.0.6
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_ACCOUNT_KEY_LENGTH=2048
-DEFAULT_DOMAIN_KEY_LENGTH=2048
+DEFAULT_ACCOUNT_KEY_LENGTH=ec-256
+DEFAULT_DOMAIN_KEY_LENGTH=ec-256
DEFAULT_OPENSSL_BIN="openssl"
@@ -436,24 +436,14 @@ _secure_debug3() {
fi
}
-__USE_TR_RAW="$([ "$(echo "abc" | tr a-z A-Z 2>/dev/null)" = "ABC" ] && echo 1 || echo 0)"
-
_upper_case() {
- if [ "$__USE_TR_RAW" = "0" ]; then
- tr '[:lower:]' '[:upper:]'
- else
- # shellcheck disable=SC2018,SC2019
- tr 'a-z' 'A-Z'
- fi
+ # shellcheck disable=SC2018,SC2019
+ tr '[a-z]' '[A-Z]'
}
_lower_case() {
- if [ "$__USE_TR_RAW" = "0" ]; then
- tr '[:upper:]' '[:lower:]'
- else
- # shellcheck disable=SC2018,SC2019
- tr 'A-Z' 'a-z'
- fi
+ # shellcheck disable=SC2018,SC2019
+ tr '[A-Z]' '[a-z]'
}
_startswith() {
@@ -1196,7 +1186,7 @@ _createkey() {
_is_idn() {
_is_idn_d="$1"
_debug2 _is_idn_d "$_is_idn_d"
- _idn_temp=$(printf "%s" "$_is_idn_d" | tr -d '0-9' | tr -d 'a-z' | tr -d 'A-Z' | tr -d '*.,-_')
+ _idn_temp=$(printf "%s" "$_is_idn_d" | tr -d '[0-9]' | tr -d '[a-z]' | tr -d '[A-Z]' | tr -d '*.,-_')
_debug2 _idn_temp "$_idn_temp"
[ "$_idn_temp" ]
}
@@ -1245,7 +1235,7 @@ _createcsr() {
_debug2 csr "$csr"
_debug2 csrconf "$csrconf"
- printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]\n\n" >"$csrconf"
+ printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]\nextendedKeyUsage=serverAuth,clientAuth\n" >"$csrconf"
if [ "$acmeValidationv1" ]; then
domainlist="$(_idn "$domainlist")"
@@ -2009,7 +1999,13 @@ _post() {
if [ "$_ret" != "0" ]; then
_err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret"
fi
- _sed_i "s/^ *//g" "$HTTP_HEADER"
+ if _contains "$_WGET" " -d "; then
+ # Demultiplex wget debug output
+ cat "$HTTP_HEADER" >&2
+ _sed_i '/^[^ ][^ ]/d; /^ *$/d' "$HTTP_HEADER"
+ fi
+ # remove leading whitespaces from header to match curl format
+ _sed_i 's/^ //g' "$HTTP_HEADER"
else
_ret="$?"
_err "Neither curl nor wget is found, can not do $httpmethod."
@@ -2062,9 +2058,21 @@ _get() {
fi
_debug "_WGET" "$_WGET"
if [ "$onlyheader" ]; then
- $_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O /dev/null "$url" 2>&1 | sed 's/^[ ]*//g'
+ _wget_out = "$($_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O /dev/null "$url" 2>&1)"
+ if _contains "$_WGET" " -d "; then
+ # Demultiplex wget debug output
+ echo "$_wget_out" >&2
+ echo "$_wget_out" | sed '/^[^ ][^ ]/d; /^ *$/d; s/^ //g' -
+ fi
else
- $_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -O - "$url"
+ $_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O - "$url" 2>"$HTTP_HEADER"
+ if _contains "$_WGET" " -d "; then
+ # Demultiplex wget debug output
+ cat "$HTTP_HEADER" >&2
+ _sed_i '/^[^ ][^ ]/d; /^ *$/d' "$HTTP_HEADER"
+ fi
+ # remove leading whitespaces from header to match curl format
+ _sed_i 's/^ //g' "$HTTP_HEADER"
fi
ret=$?
if [ "$ret" = "8" ]; then
@@ -2249,12 +2257,18 @@ _setopt() {
if [ ! -f "$__conf" ]; then
touch "$__conf"
fi
+ if [ -n "$(tail -c 1 <"$__conf")" ]; then
+ echo >>"$__conf"
+ fi
if grep -n "^$__opt$__sep" "$__conf" >/dev/null; then
_debug3 OK
if _contains "$__val" "&"; then
__val="$(echo "$__val" | sed 's/&/\\&/g')"
fi
+ if _contains "$__val" "|"; then
+ __val="$(echo "$__val" | sed 's/|/\\|/g')"
+ fi
text="$(cat "$__conf")"
printf -- "%s\n" "$text" | sed "s|^$__opt$__sep.*$|$__opt$__sep$__val$__end|" >"$__conf"
@@ -2262,6 +2276,9 @@ _setopt() {
if _contains "$__val" "&"; then
__val="$(echo "$__val" | sed 's/&/\\&/g')"
fi
+ if _contains "$__val" "|"; then
+ __val="$(echo "$__val" | sed 's/|/\\|/g')"
+ fi
text="$(cat "$__conf")"
printf -- "%s\n" "$text" | sed "s|^#$__opt$__sep.*$|$__opt$__sep$__val$__end|" >"$__conf"
@@ -2571,7 +2588,7 @@ __initHome() {
_script_home="$(dirname "$_script")"
_debug "_script_home" "$_script_home"
if [ -d "$_script_home" ]; then
- _SCRIPT_HOME="$_script_home"
+ export _SCRIPT_HOME="$_script_home"
else
_err "It seems the script home is not correct:$_script_home"
fi
@@ -4033,8 +4050,7 @@ _ns_lookup_dp() {
_ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type"
}
-#domain, type
-_ns_lookup() {
+_ns_select_doh() {
if [ -z "$DOH_USE" ]; then
_debug "Detect dns server first."
if _ns_is_available_cf; then
@@ -4053,7 +4069,11 @@ _ns_lookup() {
_err "No doh"
fi
fi
+}
+#domain, type
+_ns_lookup() {
+ _ns_select_doh
if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then
_ns_lookup_cf "$@"
elif [ "$DOH_USE" = "$DOH_GOOGLE" ]; then
@@ -4076,6 +4096,7 @@ __check_txt() {
_debug "_c_txtdomain" "$_c_txtdomain"
_debug "_c_aliasdomain" "$_c_aliasdomain"
_debug "_c_txt" "$_c_txt"
+ _ns_select_doh
_answers="$(_ns_lookup "$_c_aliasdomain" TXT)"
_contains "$_answers" "$_c_txt"
@@ -4205,7 +4226,7 @@ _match_issuer() {
_isIPv4() {
for seg in $(echo "$1" | tr '.' ' '); do
_debug2 seg "$seg"
- if [ "$(echo "$seg" | tr -d [0-9])" ]; then
+ if [ "$(echo "$seg" | tr -d '[0-9]')" ]; then
#not all number
return 1
fi
@@ -4406,6 +4427,7 @@ issue() {
_debug "_saved_account_key_hash is not changed, skip register account."
fi
+ export Le_Next_Domain_Key="$CERT_KEY_PATH.next"
if [ -f "$CSR_PATH" ] && [ ! -f "$CERT_KEY_PATH" ]; then
_info "Signing from existing CSR."
else
@@ -4418,14 +4440,30 @@ issue() {
fi
_debug "Read key length:$_key"
if [ ! -f "$CERT_KEY_PATH" ] || [ "$_key_length" != "$_key" ] || [ "$Le_ForceNewDomainKey" = "1" ]; then
- if ! createDomainKey "$_main_domain" "$_key_length"; then
- _err "Create domain key error."
- _clearup
- _on_issue_err "$_post_hook"
+ if [ "$Le_ForceNewDomainKey" = "1" ] && [ -f "$Le_Next_Domain_Key" ]; then
+ _info "Using pre generated key: $Le_Next_Domain_Key"
+ cat "$Le_Next_Domain_Key" >"$CERT_KEY_PATH"
+ echo "" >"$Le_Next_Domain_Key"
+ else
+ if ! createDomainKey "$_main_domain" "$_key_length"; then
+ _err "Create domain key error."
+ _clearup
+ _on_issue_err "$_post_hook"
+ return 1
+ fi
+ fi
+ fi
+ if [ "$Le_ForceNewDomainKey" ]; then
+ _info "Generate next pre-generate key."
+ if [ ! -e "$Le_Next_Domain_Key" ]; then
+ touch "$Le_Next_Domain_Key"
+ chmod 600 "$Le_Next_Domain_Key"
+ fi
+ if ! _createkey "$_key_length" "$Le_Next_Domain_Key"; then
+ _err "Can not pre generate domain key"
return 1
fi
fi
-
if ! _createcsr "$_main_domain" "$_alt_domains" "$CERT_KEY_PATH" "$CSR_PATH" "$DOMAIN_SSL_CONF"; then
_err "Create CSR error."
_clearup
@@ -4876,7 +4914,9 @@ $_authorizations_map"
_on_issue_err "$_post_hook" "$vlist"
return 1
fi
-
+ if ! chmod a+r "$wellknown_path/$token"; then
+ _debug "chmod failed, but we just continue."
+ fi
if [ ! "$usingApache" ]; then
if webroot_owner=$(_stat "$_currentRoot"); then
_debug "Changing owner/group of .well-known to $webroot_owner"
@@ -5159,6 +5199,9 @@ $_authorizations_map"
[ -f "$CA_CERT_PATH" ] && _info "The intermediate CA cert is in: $(__green "$CA_CERT_PATH")"
[ -f "$CERT_FULLCHAIN_PATH" ] && _info "And the full chain certs is there: $(__green "$CERT_FULLCHAIN_PATH")"
+ if [ "$Le_ForceNewDomainKey" ] && [ -e "$Le_Next_Domain_Key" ]; then
+ _info "Your pre-generated next key for future cert key change is in: $(__green "$Le_Next_Domain_Key")"
+ fi
Le_CertCreateTime=$(_time)
_savedomainconf "Le_CertCreateTime" "$Le_CertCreateTime"
@@ -5210,11 +5253,25 @@ $_authorizations_map"
_info "The domain is set to be valid to: $_valid_to"
_info "It can not be renewed automatically"
_info "See: $_VALIDITY_WIKI"
+ else
+ _now=$(_time)
+ _debug2 "_now" "$_now"
+ _lifetime=$(_math $Le_NextRenewTime - $_now)
+ _debug2 "_lifetime" "$_lifetime"
+ if [ $_lifetime -gt 86400 ]; then
+ #if lifetime is logner than one day, it will renew one day before
+ Le_NextRenewTime=$(_math $Le_NextRenewTime - 86400)
+ Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime")
+ else
+ #if lifetime is less than 24 hours, it will renew one hour before
+ Le_NextRenewTime=$(_math $Le_NextRenewTime - 3600)
+ Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime")
+ fi
fi
else
Le_NextRenewTime=$(_math "$Le_CertCreateTime" + "$Le_RenewalDays" \* 24 \* 60 \* 60)
- Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime")
Le_NextRenewTime=$(_math "$Le_NextRenewTime" - 86400)
+ Le_NextRenewTimeStr=$(_time2str "$Le_NextRenewTime")
fi
_savedomainconf "Le_NextRenewTimeStr" "$Le_NextRenewTimeStr"
_savedomainconf "Le_NextRenewTime" "$Le_NextRenewTime"
@@ -5719,7 +5776,8 @@ installcert() {
_savedomainconf "Le_RealKeyPath" "$_real_key"
_savedomainconf "Le_ReloadCmd" "$_reload_cmd" "base64"
_savedomainconf "Le_RealFullChainPath" "$_real_fullchain"
-
+ export Le_ForceNewDomainKey="$(_readdomainconf Le_ForceNewDomainKey)"
+ export Le_Next_Domain_Key
_installcert "$_main_domain" "$_real_cert" "$_real_key" "$_real_ca" "$_real_fullchain" "$_reload_cmd"
}
@@ -5811,6 +5869,8 @@ _installcert() {
export CA_CERT_PATH
export CERT_FULLCHAIN_PATH
export Le_Domain="$_main_domain"
+ export Le_ForceNewDomainKey
+ export Le_Next_Domain_Key
cd "$DOMAIN_PATH" && eval "$_reload_cmd"
); then
_info "$(__green "Reload success")"
@@ -6048,6 +6108,8 @@ revoke() {
if [ -z "$response" ]; then
_info "Revoke success."
rm -f "$CERT_PATH"
+ cat "$CERT_KEY_PATH" >"$CERT_KEY_PATH.revoked"
+ cat "$CSR_PATH" >"$CSR_PATH.revoked"
return 0
else
_err "Revoke error by domain key."
@@ -6064,6 +6126,8 @@ revoke() {
if [ -z "$response" ]; then
_info "Revoke success."
rm -f "$CERT_PATH"
+ cat "$CERT_KEY_PATH" >"$CERT_KEY_PATH.revoked"
+ cat "$CSR_PATH" >"$CSR_PATH.revoked"
return 0
else
_err "Revoke error."
@@ -6549,7 +6613,7 @@ install() {
if [ "$_accountemail" ]; then
_saveaccountconf "ACCOUNT_EMAIL" "$_accountemail"
fi
-
+ _saveaccountconf "UPGRADE_HASH" "$(_getUpgradeHash)"
_info OK
}
@@ -6780,37 +6844,37 @@ Commands:
Parameters:
-d, --domain Specifies a domain, used to issue, renew or revoke etc.
--challenge-alias The challenge domain alias for DNS alias mode.
- See: $_DNS_ALIAS_WIKI
+ See: $_DNS_ALIAS_WIKI
--domain-alias The domain alias for DNS alias mode.
- See: $_DNS_ALIAS_WIKI
+ See: $_DNS_ALIAS_WIKI
--preferred-chain If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name.
- If no match, the default offered chain will be used. (default: empty)
- See: $_PREFERRED_CHAIN_WIKI
+ If no match, the default offered chain will be used. (default: empty)
+ See: $_PREFERRED_CHAIN_WIKI
--valid-to Request the NotAfter field of the cert.
- See: $_VALIDITY_WIKI
+ See: $_VALIDITY_WIKI
--valid-from Request the NotBefore field of the cert.
- See: $_VALIDITY_WIKI
+ See: $_VALIDITY_WIKI
-f, --force Force install, force cert renewal or override sudo restrictions.
--staging, --test Use staging server, for testing.
--debug [0|1|2|3] Output debug info. Defaults to 1 if argument is omitted.
--output-insecure Output all the sensitive messages.
- By default all the credentials/sensitive messages are hidden from the output/debug/log for security.
+ By default all the credentials/sensitive messages are hidden from the output/debug/log for security.
-w, --webroot Specifies the web root folder for web root mode.
--standalone Use standalone mode.
--alpn Use standalone alpn mode.
--stateless Use stateless mode.
- See: $_STATELESS_WIKI
+ See: $_STATELESS_WIKI
--apache Use apache mode.
--dns [dns_hook] Use dns manual mode or dns api. Defaults to manual mode when argument is omitted.
- See: $_DNS_API_WIKI
+ See: $_DNS_API_WIKI
--dnssleep 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 Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521.
-ak, --accountkeylength Specifies the account key length: 2048, 3072, 4096
--log [file] Specifies the log file. Defaults to \"$DEFAULT_LOG_FILE\" if argument is omitted.
@@ -6829,7 +6893,7 @@ Parameters:
--reloadcmd Command to execute after issue/renew to reload the server.
--server ACME Directory Resource URI. (default: $DEFAULT_CA)
- See: $_SERVER_WIKI
+ See: $_SERVER_WIKI
--accountconf Specifies a customized account config file.
--home Specifies the home dir for $PROJECT_NAME.
@@ -6848,7 +6912,7 @@ Parameters:
--ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate.
--ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl.
--no-cron Only valid for '--install' command, which means: do not install the default cron job.
- In this case, the certs will not be renewed automatically.
+ In this case, the certs will not be renewed automatically.
--no-profile Only valid for '--install' command, which means: do not install aliases to user profile.
--no-color Do not output color text.
--force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails.
@@ -6866,20 +6930,20 @@ Parameters:
--openssl-bin Specifies a custom openssl bin location.
--use-wget Force to use wget, if you have both curl and wget installed.
--yes-I-know-dns-manual-mode-enough-go-ahead-please Force use of dns manual mode.
- See: $_DNS_MANUAL_WIKI
+ See: $_DNS_MANUAL_WIKI
-b, --branch Only valid for '--upgrade' command, specifies the branch name to upgrade to.
--notify-level <0|1|2|3> Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT.
- 0: disabled, no notification will be sent.
- 1: send notifications only when there is an error.
- 2: send notifications when a cert is successfully renewed, or there is an error.
- 3: send notifications when a cert is skipped, renewed, or error.
+ 0: disabled, no notification will be sent.
+ 1: send notifications only when there is an error.
+ 2: send notifications when a cert is successfully renewed, or there is an error.
+ 3: send notifications when a cert is skipped, renewed, or error.
--notify-mode <0|1> Set notification mode. Default value is $NOTIFY_MODE_DEFAULT.
- 0: Bulk mode. Send all the domain's notifications in one message(mail).
- 1: Cert mode. Send a message for every single cert.
+ 0: Bulk mode. Send all the domain's notifications in one message(mail).
+ 1: Cert mode. Send a message for every single cert.
--notify-hook Set the notify hook
--revoke-reason <0-10> The reason for revocation, can be used in conjunction with the '--revoke' command.
- See: $_REVOKE_WIKI
+ See: $_REVOKE_WIKI
--password Add a password to exported pfx file. Use with --to-pkcs12.
@@ -6913,8 +6977,6 @@ installOnline() {
chmod +x $PROJECT_ENTRY
if ./$PROJECT_ENTRY --install "$@"; then
_info "Install success!"
- _initpath
- _saveaccountconf "UPGRADE_HASH" "$(_getUpgradeHash)"
fi
cd ..
@@ -7434,17 +7496,17 @@ _process() {
shift
;;
--home)
- LE_WORKING_DIR="$2"
+ export LE_WORKING_DIR="$2"
shift
;;
--cert-home | --certhome)
_certhome="$2"
- CERT_HOME="$_certhome"
+ export CERT_HOME="$_certhome"
shift
;;
--config-home)
_confighome="$2"
- LE_CONFIG_HOME="$_confighome"
+ export LE_CONFIG_HOME="$_confighome"
shift
;;
--useragent)
diff --git a/deploy/cpanel_uapi.sh b/deploy/cpanel_uapi.sh
index 44844f79..e5381b61 100644
--- a/deploy/cpanel_uapi.sh
+++ b/deploy/cpanel_uapi.sh
@@ -3,18 +3,29 @@
# Uses command line uapi. --user option is needed only if run as root.
# Returns 0 when success.
#
+# Configure DEPLOY_CPANEL_AUTO_<...> options to enable or restrict automatic
+# detection of deployment targets through UAPI (if not set, defaults below are used.)
+# - ENABLED : 'true' for multi-site / wildcard capability; otherwise single-site mode.
+# - NOMATCH : 'true' to allow deployment to sites that do not match the certificate.
+# - INCLUDE : Comma-separated list - sites must match this field.
+# - EXCLUDE : Comma-separated list - sites must NOT match this field.
+# INCLUDE/EXCLUDE both support non-lexical, glob-style matches using '*'
+#
# Please note that I am no longer using Github. If you want to report an issue
# or contact me, visit https://forum.webseodesigners.com/web-design-seo-and-hosting-f16/
#
# Written by Santeri Kannisto
# Public domain, 2017-2018
-
-#export DEPLOY_CPANEL_USER=myusername
+#
+# export DEPLOY_CPANEL_USER=myusername
+# export DEPLOY_CPANEL_AUTO_ENABLED='true'
+# export DEPLOY_CPANEL_AUTO_NOMATCH='false'
+# export DEPLOY_CPANEL_AUTO_INCLUDE='*'
+# export DEPLOY_CPANEL_AUTO_EXCLUDE=''
######## Public functions #####################
#domain keyfile certfile cafile fullchain
-
cpanel_uapi_deploy() {
_cdomain="$1"
_ckey="$2"
@@ -22,6 +33,9 @@ cpanel_uapi_deploy() {
_cca="$4"
_cfullchain="$5"
+ # re-declare vars inherited from acme.sh but not passed to make ShellCheck happy
+ : "${Le_Alt:=""}"
+
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
@@ -32,31 +46,166 @@ cpanel_uapi_deploy() {
_err "The command uapi is not found."
return 1
fi
+
+ # declare useful constants
+ uapi_error_response='status: 0'
+
# read cert and key files and urlencode both
_cert=$(_url_encode <"$_ccert")
_key=$(_url_encode <"$_ckey")
- _debug _cert "$_cert"
- _debug _key "$_key"
+ _debug2 _cert "$_cert"
+ _debug2 _key "$_key"
if [ "$(id -u)" = 0 ]; then
- if [ -z "$DEPLOY_CPANEL_USER" ]; then
+ _getdeployconf DEPLOY_CPANEL_USER
+ # fallback to _readdomainconf for old installs
+ if [ -z "${DEPLOY_CPANEL_USER:=$(_readdomainconf DEPLOY_CPANEL_USER)}" ]; then
_err "It seems that you are root, please define the target user name: export DEPLOY_CPANEL_USER=username"
return 1
fi
- _savedomainconf DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER"
- _response=$(uapi --user="$DEPLOY_CPANEL_USER" SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
- else
- _response=$(uapi SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
+ _debug DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER"
+ _savedeployconf DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER"
+
+ _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
+
+ # Load all AUTO envars and set defaults - see above for usage
+ __cpanel_initautoparam ENABLED 'true'
+ __cpanel_initautoparam NOMATCH 'false'
+ __cpanel_initautoparam INCLUDE '*'
+ __cpanel_initautoparam EXCLUDE ''
+
+ # Auto mode
+ if [ "$DEPLOY_CPANEL_AUTO_ENABLED" = "true" ]; then
+ # call API for site config
+ _response=$(uapi DomainInfo list_domains)
+ # exit if error in response
+ if [ -z "$_response" ] || [ "${_response#*"$uapi_error_response"}" != "$_response" ]; then
+ _err "Error in deploying certificate - cannot retrieve sitelist:"
+ _err "\n$_response"
+ return 1
+ fi
+
+ # parse response to create site list
+ sitelist=$(__cpanel_parse_response "$_response")
+ _debug "UAPI sites found: $sitelist"
+
+ # filter sitelist using configured domains
+ # skip if NOMATCH is "true"
+ if [ "$DEPLOY_CPANEL_AUTO_NOMATCH" = "true" ]; then
+ _debug "DEPLOY_CPANEL_AUTO_NOMATCH is true"
+ _info "UAPI nomatch mode is enabled - Will not validate sites are valid for the certificate"
+ else
+ _debug "DEPLOY_CPANEL_AUTO_NOMATCH is false"
+ d="$(echo "${Le_Alt}," | sed -e "s/^$_cdomain,//" -e "s/,$_cdomain,/,/")"
+ d="$(echo "$_cdomain,$d" | tr ',' '\n' | sed -e 's/\./\\./g' -e 's/\*/\[\^\.\]\*/g')"
+ sitelist="$(echo "$sitelist" | grep -ix "$d")"
+ _debug2 "Matched UAPI sites: $sitelist"
+ fi
+
+ # filter sites that do not match $DEPLOY_CPANEL_AUTO_INCLUDE
+ _info "Applying sitelist filter DEPLOY_CPANEL_AUTO_INCLUDE: $DEPLOY_CPANEL_AUTO_INCLUDE"
+ sitelist="$(echo "$sitelist" | grep -ix "$(echo "$DEPLOY_CPANEL_AUTO_INCLUDE" | tr ',' '\n' | sed -e 's/\./\\./g' -e 's/\*/\.\*/g')")"
+ _debug2 "Remaining sites: $sitelist"
+
+ # filter sites that match $DEPLOY_CPANEL_AUTO_EXCLUDE
+ _info "Applying sitelist filter DEPLOY_CPANEL_AUTO_EXCLUDE: $DEPLOY_CPANEL_AUTO_EXCLUDE"
+ sitelist="$(echo "$sitelist" | grep -vix "$(echo "$DEPLOY_CPANEL_AUTO_EXCLUDE" | tr ',' '\n' | sed -e 's/\./\\./g' -e 's/\*/\.\*/g')")"
+ _debug2 "Remaining sites: $sitelist"
+
+ # counter for success / failure check
+ successes=0
+ if [ -n "$sitelist" ]; then
+ sitetotal="$(echo "$sitelist" | wc -l)"
+ _debug "$sitetotal sites to deploy"
+ else
+ sitetotal=0
+ _debug "No sites to deploy"
+ fi
+
+ # for each site: call uapi to publish cert and log result. Only return failure if all fail
+ for site in $sitelist; do
+ # call uapi to publish cert, check response for errors and log them.
+ if [ -n "$_uapi_user" ]; then
+ _response=$(uapi --user="$_uapi_user" SSL install_ssl domain="$site" cert="$_cert" key="$_key")
+ else
+ _response=$(uapi SSL install_ssl domain="$site" cert="$_cert" key="$_key")
+ fi
+ if [ "${_response#*"$uapi_error_response"}" != "$_response" ]; then
+ _err "Error in deploying certificate to $site:"
+ _err "$_response"
+ else
+ successes=$((successes + 1))
+ _debug "$_response"
+ _info "Succcessfully deployed to $site"
+ fi
+ done
+
+ # Raise error if all updates fail
+ if [ "$sitetotal" -gt 0 ] && [ "$successes" -eq 0 ]; then
+ _err "Could not deploy to any of $sitetotal sites via UAPI"
+ _debug "successes: $successes, sitetotal: $sitetotal"
+ return 1
+ fi
+
+ _info "Successfully deployed certificate to $successes of $sitetotal sites via UAPI"
+ return 0
+ else
+ # "classic" mode - will only try to deploy to the primary domain; will not check UAPI first
+ if [ -n "$_uapi_user" ]; then
+ _response=$(uapi --user="$_uapi_user" SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
+ else
+ _response=$(uapi SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
+ fi
+
+ if [ "${_response#*"$uapi_error_response"}" != "$_response" ]; then
+ _err "Error in deploying certificate:"
+ _err "$_response"
+ return 1
+ fi
+
+ _debug response "$_response"
+ _info "Certificate successfully deployed"
+ return 0
fi
+}
+
+######## Private functions #####################
+
+# Internal utility to process YML from UAPI - looks at main_domain, sub_domains, addon domains and parked domains
+#[response]
+__cpanel_parse_response() {
+ if [ $# -gt 0 ]; then resp="$*"; else resp="$(cat)"; fi
+
+ echo "$resp" |
+ sed -En \
+ -e 's/\r$//' \
+ -e 's/^( *)([_.[:alnum:]]+) *: *(.*)/\1,\2,\3/p' \
+ -e 's/^( *)- (.*)/\1,-,\2/p' |
+ awk -F, '{
+ level = length($1)/2;
+ section[level] = $2;
+ for (i in section) {if (i > level) {delete section[i]}}
+ if (length($3) > 0) {
+ prefix="";
+ for (i=0; i < level; i++)
+ { prefix = (prefix)(section[i])("/") }
+ printf("%s%s=%s\n", prefix, $2, $3);
+ }
+ }' |
+ sed -En -e 's/^result\/data\/(main_domain|sub_domains\/-|addon_domains\/-|parked_domains\/-)=(.*)$/\2/p'
+}
+
+# Load parameter by prefix+name - fallback to default if not set, and save to config
+#pname pdefault
+__cpanel_initautoparam() {
+ pname="$1"
+ pdefault="$2"
+ pkey="DEPLOY_CPANEL_AUTO_$pname"
- _debug response "$_response"
- _info "Certificate successfully deployed"
- return 0
+ _getdeployconf "$pkey"
+ [ -n "$(eval echo "\"\$$pkey\"")" ] || eval "$pkey=\"$pdefault\""
+ _debug2 "$pkey" "$(eval echo "\"\$$pkey\"")"
+ _savedeployconf "$pkey" "$(eval echo "\"\$$pkey\"")"
}
diff --git a/deploy/gitlab.sh b/deploy/gitlab.sh
index ba2d3122..595b6d20 100644
--- a/deploy/gitlab.sh
+++ b/deploy/gitlab.sh
@@ -67,7 +67,7 @@ gitlab_deploy() {
error_response="error"
- if test "${_response#*$error_response}" != "$_response"; then
+ if test "${_response#*"$error_response"}" != "$_response"; then
_err "Error in deploying certificate:"
_err "$_response"
return 1
diff --git a/deploy/synology_dsm.sh b/deploy/synology_dsm.sh
index f30f82c0..c31a5df0 100644
--- a/deploy/synology_dsm.sh
+++ b/deploy/synology_dsm.sh
@@ -108,7 +108,7 @@ synology_dsm_deploy() {
_debug3 H1 "${_H1}"
fi
- response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$otp_code" "$_base_url/webapi/auth.cgi?enable_syno_token=yes")
+ response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$otp_code&device_name=certrenewal&device_id=$SYNO_DID" "$_base_url/webapi/auth.cgi?enable_syno_token=yes")
token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p')
_debug3 response "$response"
_debug token "$token"
diff --git a/dnsapi/dns_acmeproxy.sh b/dnsapi/dns_acmeproxy.sh
index d4a0e172..9d5533f9 100644
--- a/dnsapi/dns_acmeproxy.sh
+++ b/dnsapi/dns_acmeproxy.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env sh
-## Acmeproxy DNS provider to be used with acmeproxy (http://github.com/mdbraber/acmeproxy)
+## Acmeproxy DNS provider to be used with acmeproxy (https://github.com/mdbraber/acmeproxy)
## API integration by Maarten den Braber
##
## Report any bugs via https://github.com/mdbraber/acme.sh
diff --git a/dnsapi/dns_bunny.sh b/dnsapi/dns_bunny.sh
new file mode 100644
index 00000000..a9b1ea5a
--- /dev/null
+++ b/dnsapi/dns_bunny.sh
@@ -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
+## 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
+}
diff --git a/dnsapi/dns_cpanel.sh b/dnsapi/dns_cpanel.sh
index f91725a4..f6126bcb 100755
--- a/dnsapi/dns_cpanel.sh
+++ b/dnsapi/dns_cpanel.sh
@@ -13,6 +13,7 @@
# cPanel_Hostname=hostname
#
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+
# Used to add txt record
dns_cpanel_add() {
fulldomain=$1
@@ -120,7 +121,7 @@ _myget() {
_get_root() {
_myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones'
- _domains=$(echo "$_result" | sed 's/.*\(zones.*\[\).*/\1/' | cut -d':' -f2 | sed 's/"//g' | sed 's/{//g')
+ _domains=$(echo "$_result" | _egrep_o '"[a-z0-9\.\-]*":\["; cPanel first' | cut -d':' -f1 | sed 's/"//g' | sed 's/{//g')
_debug "_result is: $_result"
_debug "_domains is: $_domains"
if [ -z "$_domains" ]; then
@@ -138,15 +139,15 @@ _get_root() {
}
_successful_update() {
- if (echo "$_result" | grep -q 'newserial'); then return 0; fi
- return 1
+ if (echo "$_result" | _egrep_o 'data":\[[^]]*]' | grep -q '"newserial":null'); then return 1; fi
+ return 0
}
_findentry() {
_debug "In _findentry"
#returns id of dns entry, if it exists
_myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&domain=$_domain"
- _id=$(echo "$_result" | sed "s/.*\(line.*$fulldomain.*$txtvalue\).*/\1/" | cut -d ':' -f 2 | cut -d ',' -f 1)
+ _id=$(echo "$_result" | sed -e "s/},{/},\n{/g" | grep "$fulldomain" | grep "$txtvalue" | _egrep_o 'line":[0-9]+' | cut -d ':' -f 2)
_debug "_result is: $_result"
_debug "fulldomain. is $fulldomain."
_debug "txtvalue is $txtvalue"
diff --git a/dnsapi/dns_dgon.sh b/dnsapi/dns_dgon.sh
index ac14da48..afe1b32e 100755
--- a/dnsapi/dns_dgon.sh
+++ b/dnsapi/dns_dgon.sh
@@ -192,6 +192,7 @@ _get_base_domain() {
## get URL for the list of domains
## may get: "links":{"pages":{"last":".../v2/domains/DOM/records?page=2","next":".../v2/domains/DOM/records?page=2"}}
DOMURL="https://api.digitalocean.com/v2/domains"
+ found=""
## while we dont have a matching domain we keep going
while [ -z "$found" ]; do
@@ -205,9 +206,7 @@ _get_base_domain() {
fi
_debug2 domain_list "$domain_list"
- ## for each shortening of our $fulldomain, check if it exists in the $domain_list
- ## can never start on 1 (aka whole $fulldomain) as $fulldomain starts with "_acme-challenge"
- i=2
+ i=1
while [ $i -gt 0 ]; do
## get next longest domain
_domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM")
diff --git a/dnsapi/dns_dnsservices.sh b/dnsapi/dns_dnsservices.sh
index 9f2220fe..008153a4 100755
--- a/dnsapi/dns_dnsservices.sh
+++ b/dnsapi/dns_dnsservices.sh
@@ -13,8 +13,8 @@ DNSServices_API=https://dns.services/api
#Usage: dns_dnsservices_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_dnsservices_add() {
- fulldomain=$1
- txtvalue=$2
+ fulldomain="$1"
+ txtvalue="$2"
_info "Using dns.services to create ACME DNS challenge"
_debug2 add_fulldomain "$fulldomain"
@@ -61,8 +61,8 @@ dns_dnsservices_add() {
#Usage: fulldomain txtvalue
#Description: Remove the txt record after validation.
dns_dnsservices_rm() {
- fulldomain=$1
- txtvalue=$2
+ fulldomain="$1"
+ txtvalue="$2"
_info "Using dns.services to remove DNS record $fulldomain TXT $txtvalue"
_debug rm_fulldomain "$fulldomain"
@@ -117,36 +117,40 @@ _setup_headers() {
}
_get_root() {
- domain=$1
+ domain="$1"
_debug2 _get_root "Get the root domain of ${domain} for DNS API"
# Setup _get() and _post() headers
#_setup_headers
result=$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/dns")
+ result2="$(printf "%s\n" "$result" | tr '[' '\n' | grep '"name"')"
+ result3="$(printf "%s\n" "$result2" | tr '}' '\n' | grep '"name"' | sed "s,^\,,,g" | sed "s,$,},g")"
+ useResult=""
_debug2 _get_root "Got the following root domain(s) $result"
_debug2 _get_root "- JSON: $result"
- if [ "$(echo "$result" | grep -c '"name"')" -gt "1" ]; then
+ if [ "$(printf "%s\n" "$result" | tr '}' '\n' | grep -c '"name"')" -gt "1" ]; then
checkMultiZones="true"
_debug2 _get_root "- multiple zones found"
else
checkMultiZones="false"
-
+ _debug2 _get_root "- single zone found"
fi
# Find/isolate the root zone to work with in createRecord() and deleteRecord()
rootZone=""
if [ "$checkMultiZones" = "true" ]; then
- rootZone=$(for zone in $(echo "$result" | tr -d '\n' ' '); do
- if [ "$(echo "$domain" | grep "$zone")" != "" ]; then
- _debug2 _get_root "- trying to figure out if $zone is in $domain"
- echo "$zone"
- break
- fi
- done)
+ #rootZone=$(for x in $(printf "%s" "${result3}" | tr ',' '\n' | sed -n 's/.*"name":"\(.*\)",.*/\1/p'); do if [ "$(echo "$domain" | grep "$x")" != "" ]; then echo "$x"; fi; done)
+ rootZone=$(for x in $(printf "%s\n" "${result3}" | tr ',' '\n' | grep name | cut -d'"' -f4); do if [ "$(echo "$domain" | grep "$x")" != "" ]; then echo "$x"; fi; done)
+ if [ "$rootZone" != "" ]; then
+ _debug2 _rootZone "- root zone for $domain is $rootZone"
+ else
+ _err "Could not find root zone for $domain, is it correctly typed?"
+ return 1
+ fi
else
- rootZone=$(echo "$result" | _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"
fi
@@ -155,14 +159,18 @@ _get_root() {
return 1
fi
+ # Make sure we use the correct API zone data
+ useResult="$(printf "%s\n" "${result3}" tr ',' '\n' | grep "$rootZone")"
+ _debug2 _useResult "useResult=$useResult"
+
# Setup variables used by other functions to communicate with DNS.Services API
- #zoneInfo=$(echo "$result" | sed "s,\"zones,\n&,g" | grep zones | cut -d'[' -f2 | cut -d']' -f1 | tr '}' '\n' | grep "\"$rootZone\"")
- zoneInfo=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g' | grep "\"$rootZone\"")
+ #zoneInfo=$(printf "%s\n" "$useResult" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g')
+ zoneInfo=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep '"name"' | cut -d'"' -f4)
rootZoneName="$rootZone"
- subDomainName="$(echo "$domain" | sed "s,\.$rootZone,,g")"
- subDomainNameClean="$(echo "$domain" | sed "s,_acme-challenge.,,g")"
- rootZoneDomainID=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"domain_id":")([^"]*)"(.*)$,\2,g')
- rootZoneServiceID=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"service_id":")([^"]*)"(.*)$,\2,g')
+ subDomainName="$(printf "%s\n" "$domain" | sed "s,\.$rootZone,,g")"
+ subDomainNameClean="$(printf "%s\n" "$domain" | sed "s,_acme-challenge.,,g")"
+ rootZoneDomainID=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep domain_id | cut -d'"' -f4)
+ rootZoneServiceID=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep service_id | cut -d'"' -f4)
_debug2 _zoneInfo "Zone info from API : $zoneInfo"
_debug2 _get_root "Root zone name : $rootZoneName"
@@ -175,13 +183,17 @@ _get_root() {
}
createRecord() {
- fulldomain=$1
+ fulldomain="$1"
txtvalue="$2"
# Get root domain information - needed for DNS.Services API communication
if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
_get_root "$fulldomain"
fi
+ if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
+ _err "Something happend - could not get the API zone information"
+ return 1
+ fi
_debug2 createRecord "CNAME TXT value is: $txtvalue"
@@ -203,8 +215,8 @@ createRecord() {
}
deleteRecord() {
- fulldomain=$1
- txtvalue=$2
+ fulldomain="$1"
+ txtvalue="$2"
_log deleteRecord "Deleting $fulldomain TXT $txtvalue record"
@@ -213,8 +225,10 @@ deleteRecord() {
fi
result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")"
- recordInfo="$(echo "$result" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}")"
- recordID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"id":")([^"]*)"(.*)$,\2,g')"
+ #recordInfo="$(echo "$result" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}")"
+ #recordID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"id":")([^"]*)"(.*)$,\2,g')"
+ recordID="$(printf "%s\n" "$result" | tr '}' '\n' | grep -- "$txtvalue" | tr ',' '\n' | grep '"id"' | cut -d'"' -f4)"
+ _debug2 _recordID "recordID used for deletion of record: $recordID"
if [ -z "$recordID" ]; then
_info "Record $fulldomain TXT $txtvalue not found or already deleted"
diff --git a/dnsapi/dns_dynv6.sh b/dnsapi/dns_dynv6.sh
index 9efc9aeb..90814b1b 100644
--- a/dnsapi/dns_dynv6.sh
+++ b/dnsapi/dns_dynv6.sh
@@ -94,8 +94,8 @@ _get_domain() {
_your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')"
for l in $_your_hosts; do
#echo "host: $l"
- if test "${_full_domain#*$l}" != "$_full_domain"; then
- _record="${_full_domain%.$l}"
+ if test "${_full_domain#*"$l"}" != "$_full_domain"; then
+ _record=${_full_domain%."$l"}
_host=$l
_debug "The host is $_host and the record $_record"
return 0
@@ -143,7 +143,7 @@ _dns_dynv6_add_http() {
return 1
fi
_get_zone_name "$_zone_id"
- record="${fulldomain%%.$_zone_name}"
+ record=${fulldomain%%."$_zone_name"}
_set_record TXT "$record" "$txtvalue"
if _contains "$response" "$txtvalue"; then
_info "Successfully added record"
@@ -161,7 +161,7 @@ _dns_dynv6_rm_http() {
return 1
fi
_get_zone_name "$_zone_id"
- record="${fulldomain%%.$_zone_name}"
+ record=${fulldomain%%."$_zone_name"}
_get_record_id "$_zone_id" "$record" "$txtvalue"
_del_record "$_zone_id" "$_record_id"
if [ -z "$response" ]; then
diff --git a/dnsapi/dns_edgedns.sh b/dnsapi/dns_edgedns.sh
index 11c132fa..27650eb1 100755
--- a/dnsapi/dns_edgedns.sh
+++ b/dnsapi/dns_edgedns.sh
@@ -418,7 +418,7 @@ _edgedns_make_data_to_sign() {
_secure_debug2 "hdr" "$hdr"
_edgedns_make_content_hash
path="$(echo "$_request_url_path" | tr -d "\n\r" | sed 's/https\?:\/\///')"
- path="${path#*$AKAMAI_HOST}"
+ path=${path#*"$AKAMAI_HOST"}
_debug "hier path" "$path"
# dont expose headers to sign so use MT string
_mdata="$(printf "%s\thttps\t%s\t%s\t%s\t%s\t%s" "$_request_method" "$AKAMAI_HOST" "$path" "" "$_hash" "$hdr")"
diff --git a/dnsapi/dns_gandi_livedns.sh b/dnsapi/dns_gandi_livedns.sh
index 87119521..931da883 100644
--- a/dnsapi/dns_gandi_livedns.sh
+++ b/dnsapi/dns_gandi_livedns.sh
@@ -1,7 +1,7 @@
#!/usr/bin/env sh
# Gandi LiveDNS v5 API
-# http://doc.livedns.gandi.net/
+# https://doc.livedns.gandi.net/
# currently under beta
#
# Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable
diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh
index bda5cbd7..2788ad59 100755
--- a/dnsapi/dns_gcloud.sh
+++ b/dnsapi/dns_gcloud.sh
@@ -39,7 +39,7 @@ dns_gcloud_rm() {
_dns_gcloud_start_tr || return $?
_dns_gcloud_get_rrdatas || return $?
echo "$rrdatas" | _dns_gcloud_remove_rrs || return $?
- echo "$rrdatas" | grep -F -v "\"$txtvalue\"" | _dns_gcloud_add_rrs || return $?
+ echo "$rrdatas" | grep -F -v -- "\"$txtvalue\"" | _dns_gcloud_add_rrs || return $?
_dns_gcloud_execute_tr || return $?
_info "$fulldomain record added"
diff --git a/dnsapi/dns_gd.sh b/dnsapi/dns_gd.sh
index 7f8efca9..44c3d279 100755
--- a/dnsapi/dns_gd.sh
+++ b/dnsapi/dns_gd.sh
@@ -1,10 +1,12 @@
#!/usr/bin/env sh
#Godaddy domain api
+# Get API key and secret from https://developer.godaddy.com/
#
-#GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
+# GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
+# GD_Secret="asdfsdfsfsdfsdfdfsdf"
#
-#GD_Secret="asdfsdfsfsdfsdfdfsdf"
+# Ex.: acme.sh --issue --staging --dns dns_gd -d "*.s.example.com" -d "s.example.com"
GD_Api="https://api.godaddy.com/v1"
@@ -51,7 +53,8 @@ dns_gd_add() {
_add_data="{\"data\":\"$txtvalue\"}"
for t in $(echo "$response" | tr '{' "\n" | grep "\"name\":\"$_sub_domain\"" | tr ',' "\n" | grep '"data"' | cut -d : -f 2); do
_debug2 t "$t"
- if [ "$t" ]; then
+ # ignore empty (previously removed) records, to prevent useless _acme-challenge TXT entries
+ if [ "$t" ] && [ "$t" != '""' ]; then
_add_data="$_add_data,{\"data\":$t}"
fi
done
@@ -59,13 +62,25 @@ dns_gd_add() {
_info "Adding record"
if _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"; then
- _info "Added, sleeping 10 seconds"
- _sleep 10
- #todo: check if the record takes effect
- return 0
+ _debug "Checking updated records of '${fulldomain}'"
+
+ if ! _gd_rest GET "domains/$_domain/records/TXT/$_sub_domain"; then
+ _err "Validating TXT record for '${fulldomain}' with rest error [$?]." "$response"
+ return 1
+ fi
+
+ if ! _contains "$response" "$txtvalue"; then
+ _err "TXT record '${txtvalue}' for '${fulldomain}', value wasn't set!"
+ return 1
+ fi
+ else
+ _err "Add txt record error, value '${txtvalue}' for '${fulldomain}' was not set."
+ return 1
fi
- _err "Add txt record error."
- return 1
+
+ _sleep 10
+ _info "Added TXT record '${txtvalue}' for '${fulldomain}'."
+ return 0
}
#fulldomain
@@ -107,11 +122,20 @@ dns_gd_rm() {
fi
done
if [ -z "$_add_data" ]; then
- _add_data="{\"data\":\"\"}"
+ # delete empty record
+ _debug "Delete last record for '${fulldomain}'"
+ if ! _gd_rest DELETE "domains/$_domain/records/TXT/$_sub_domain"; then
+ _err "Cannot delete empty TXT record for '$fulldomain'"
+ return 1
+ fi
+ else
+ # remove specific TXT value, keeping other entries
+ _debug2 _add_data "$_add_data"
+ if ! _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"; then
+ _err "Cannot update TXT record for '$fulldomain'"
+ return 1
+ fi
fi
- _debug2 _add_data "$_add_data"
-
- _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"
}
#################### Private functions below ##################################
@@ -156,15 +180,15 @@ _gd_rest() {
export _H1="Authorization: sso-key $GD_Key:$GD_Secret"
export _H2="Content-Type: application/json"
- if [ "$data" ]; then
- _debug data "$data"
+ if [ "$data" ] || [ "$m" = "DELETE" ]; then
+ _debug "data ($m): " "$data"
response="$(_post "$data" "$GD_Api/$ep" "" "$m")"
else
response="$(_get "$GD_Api/$ep")"
fi
if [ "$?" != "0" ]; then
- _err "error $ep"
+ _err "error on rest call ($m): $ep"
return 1
fi
_debug2 response "$response"
diff --git a/dnsapi/dns_infomaniak.sh b/dnsapi/dns_infomaniak.sh
index 765cf39d..a005132c 100755
--- a/dnsapi/dns_infomaniak.sh
+++ b/dnsapi/dns_infomaniak.sh
@@ -76,7 +76,7 @@ dns_infomaniak_add() {
domain_id=${zone_and_id#* }
# extract first part of domain
- key=${fulldomain%.$zone}
+ key=${fulldomain%."$zone"}
_debug "zone:$zone id:$domain_id key:$key"
@@ -149,7 +149,7 @@ dns_infomaniak_rm() {
domain_id=${zone_and_id#* }
# extract first part of domain
- key=${fulldomain%.$zone}
+ key=${fulldomain%."$zone"}
_debug "zone:$zone id:$domain_id key:$key"
diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh
index 6f0e920f..560f073e 100755
--- a/dnsapi/dns_ispconfig.sh
+++ b/dnsapi/dns_ispconfig.sh
@@ -32,6 +32,10 @@ dns_ispconfig_rm() {
#################### Private functions below ##################################
_ISPC_credentials() {
+ ISPC_User="${ISPC_User:-$(_readaccountconf_mutable ISPC_User)}"
+ ISPC_Password="${ISPC_Password:-$(_readaccountconf_mutable ISPC_Password)}"
+ ISPC_Api="${ISPC_Api:-$(_readaccountconf_mutable ISPC_Api)}"
+ ISPC_Api_Insecure="${ISPC_Api_Insecure:-$(_readaccountconf_mutable ISPC_Api_Insecure)}"
if [ -z "${ISPC_User}" ] || [ -z "${ISPC_Password}" ] || [ -z "${ISPC_Api}" ] || [ -z "${ISPC_Api_Insecure}" ]; then
ISPC_User=""
ISPC_Password=""
@@ -40,10 +44,10 @@ _ISPC_credentials() {
_err "You haven't specified the ISPConfig Login data, URL and whether you want check the ISPC SSL cert. Please try again."
return 1
else
- _saveaccountconf ISPC_User "${ISPC_User}"
- _saveaccountconf ISPC_Password "${ISPC_Password}"
- _saveaccountconf ISPC_Api "${ISPC_Api}"
- _saveaccountconf ISPC_Api_Insecure "${ISPC_Api_Insecure}"
+ _saveaccountconf_mutable ISPC_User "${ISPC_User}"
+ _saveaccountconf_mutable ISPC_Password "${ISPC_Password}"
+ _saveaccountconf_mutable ISPC_Api "${ISPC_Api}"
+ _saveaccountconf_mutable ISPC_Api_Insecure "${ISPC_Api_Insecure}"
# Set whether curl should use secure or insecure mode
export HTTPS_INSECURE="${ISPC_Api_Insecure}"
fi
diff --git a/dnsapi/dns_kas.sh b/dnsapi/dns_kas.sh
index 2cb0b439..053abd21 100755
--- a/dnsapi/dns_kas.sh
+++ b/dnsapi/dns_kas.sh
@@ -5,51 +5,81 @@
# Environment variables:
#
# - $KAS_Login (Kasserver API login name)
-# - $KAS_Authtype (Kasserver API auth type. Default: sha1)
+# - $KAS_Authtype (Kasserver API auth type. Default: plain)
# - $KAS_Authdata (Kasserver API auth data.)
#
-# Author: Martin Kammerlander, Phlegx Systems OG
-# Updated by: Marc-Oliver Lange
-# Credits: Inspired by dns_he.sh. Thanks a lot man!
-# Git repo: https://github.com/phlegx/acme.sh
-# TODO: Better Error handling
+# Last update: squared GmbH
+# Credits:
+# - dns_he.sh. Thanks a lot man!
+# - Martin Kammerlander, Phlegx Systems OG
+# - Marc-Oliver Lange
+# - https://github.com/o1oo11oo/kasapi.sh
########################################################################
-KAS_Api="https://kasapi.kasserver.com/dokumentation/formular.php"
+KAS_Api_GET="$(_get "https://kasapi.kasserver.com/soap/wsdl/KasApi.wsdl")"
+KAS_Api="$(echo "$KAS_Api_GET" | tr -d ' ' | grep -i "//g")"
+_info "[KAS] -> API URL $KAS_Api"
+
+KAS_Auth_GET="$(_get "https://kasapi.kasserver.com/soap/wsdl/KasAuth.wsdl")"
+KAS_Auth="$(echo "$KAS_Auth_GET" | tr -d ' ' | grep -i "//g")"
+_info "[KAS] -> AUTH URL $KAS_Auth"
+
+KAS_default_ratelimit=5 # TODO - Every response delivers a ratelimit (seconds) where KASAPI is blocking a request.
+
######## Public functions #####################
dns_kas_add() {
_fulldomain=$1
_txtvalue=$2
- _info "Using DNS-01 All-inkl/Kasserver hook"
- _info "Adding $_fulldomain DNS TXT entry on All-inkl/Kasserver"
- _info "Check and Save Props"
+
+ _info "[KAS] -> Using DNS-01 All-inkl/Kasserver hook"
+ _info "[KAS] -> Check and Save Props"
_check_and_save
- _info "Checking Zone and Record_Name"
+
+ _info "[KAS] -> Adding $_fulldomain DNS TXT entry on all-inkl.com/Kasserver"
+ _info "[KAS] -> Retriving Credential Token"
+ _get_credential_token
+
+ _info "[KAS] -> Checking Zone and Record_Name"
_get_zone_and_record_name "$_fulldomain"
- _info "Getting Record ID"
+
+ _info "[KAS] -> Checking for existing Record entries"
_get_record_id
- _info "Creating TXT DNS record"
- params="?kas_login=$KAS_Login"
- params="$params&kas_auth_type=$KAS_Authtype"
- params="$params&kas_auth_data=$KAS_Authdata"
- params="$params&var1=record_name"
- params="$params&wert1=$_record_name"
- params="$params&var2=record_type"
- params="$params&wert2=TXT"
- params="$params&var3=record_data"
- params="$params&wert3=$_txtvalue"
- params="$params&var4=record_aux"
- params="$params&wert4=0"
- params="$params&kas_action=add_dns_settings"
- params="$params&var5=zone_host"
- params="$params&wert5=$_zone"
- _debug2 "Wait for 10 seconds by default before calling KAS API."
- _sleep 10
- response="$(_get "$KAS_Api$params")"
- _debug2 "response" "$response"
-
- if ! _contains "$response" "TRUE"; then
- _err "An unkown error occurred, please check manually."
+ # If there is a record_id, delete the entry
+ if [ -n "$_record_id" ]; then
+ _info "[KAS] -> Existing records found. Now deleting old entries"
+ for i in $_record_id; do
+ _delete_RecordByID "$i"
+ done
+ else
+ _info "[KAS] -> No record found."
+ fi
+
+ _info "[KAS] -> Creating TXT DNS record"
+ action="add_dns_settings"
+ kasReqParam="\"record_name\":\"$_record_name\""
+ kasReqParam="$kasReqParam,\"record_type\":\"TXT\""
+ kasReqParam="$kasReqParam,\"record_data\":\"$_txtvalue\""
+ kasReqParam="$kasReqParam,\"record_aux\":\"0\""
+ kasReqParam="$kasReqParam,\"zone_host\":\"$_zone\""
+ response="$(_callAPI "$action" "$kasReqParam")"
+ _debug2 "[KAS] -> Response" "$response"
+
+ if [ -z "$response" ]; then
+ _info "[KAS] -> Response was empty, please check manually."
+ return 1
+ elif _contains "$response" ""; then
+ faultstring="$(echo "$response" | tr -d '\n\r' | sed "s//\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
+ case "${faultstring}" in
+ "record_already_exists")
+ _info "[KAS] -> The record already exists, which must not be a problem. Please check manually."
+ ;;
+ *)
+ _err "[KAS] -> An error =>$faultstring<= occurred, please check manually."
+ return 1
+ ;;
+ esac
+ elif ! _contains "$response" "- ReturnStringTRUE
"; then
+ _err "[KAS] -> An unknown error occurred, please check manually."
return 1
fi
return 0
@@ -58,45 +88,62 @@ dns_kas_add() {
dns_kas_rm() {
_fulldomain=$1
_txtvalue=$2
- _info "Using DNS-01 All-inkl/Kasserver hook"
- _info "Cleaning up after All-inkl/Kasserver hook"
- _info "Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver"
- _info "Check and Save Props"
+ _info "[KAS] -> Using DNS-01 All-inkl/Kasserver hook"
+ _info "[KAS] -> Check and Save Props"
_check_and_save
- _info "Checking Zone and Record_Name"
+
+ _info "[KAS] -> Cleaning up after All-inkl/Kasserver hook"
+ _info "[KAS] -> Removing $_fulldomain DNS TXT entry on All-inkl/Kasserver"
+ _info "[KAS] -> Retriving Credential Token"
+ _get_credential_token
+
+ _info "[KAS] -> Checking Zone and Record_Name"
_get_zone_and_record_name "$_fulldomain"
- _info "Getting Record ID"
+
+ _info "[KAS] -> Getting Record ID"
_get_record_id
+ _info "[KAS] -> Removing entries with ID: $_record_id"
# If there is a record_id, delete the entry
if [ -n "$_record_id" ]; then
- params="?kas_login=$KAS_Login"
- params="$params&kas_auth_type=$KAS_Authtype"
- params="$params&kas_auth_data=$KAS_Authdata"
- params="$params&kas_action=delete_dns_settings"
-
for i in $_record_id; do
- params2="$params&var1=record_id"
- params2="$params2&wert1=$i"
- _debug2 "Wait for 10 seconds by default before calling KAS API."
- _sleep 10
- response="$(_get "$KAS_Api$params2")"
- _debug2 "response" "$response"
- if ! _contains "$response" "TRUE"; then
- _err "Either the txt record is not found or another error occurred, please check manually."
- return 1
- fi
+ _delete_RecordByID "$i"
done
else # Cannot delete or unkown error
- _err "No record_id found that can be deleted. Please check manually."
- return 1
+ _info "[KAS] -> No record_id found that can be deleted. Please check manually."
fi
return 0
}
########################## PRIVATE FUNCTIONS ###########################
+# Delete Record ID
+_delete_RecordByID() {
+ recId=$1
+ action="delete_dns_settings"
+ kasReqParam="\"record_id\":\"$recId\""
+ response="$(_callAPI "$action" "$kasReqParam")"
+ _debug2 "[KAS] -> Response" "$response"
+ if [ -z "$response" ]; then
+ _info "[KAS] -> Response was empty, please check manually."
+ return 1
+ elif _contains "$response" ""; then
+ faultstring="$(echo "$response" | tr -d '\n\r' | sed "s//\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
+ case "${faultstring}" in
+ "record_id_not_found")
+ _info "[KAS] -> The record was not found, which perhaps is not a problem. Please check manually."
+ ;;
+ *)
+ _err "[KAS] -> An error =>$faultstring<= occurred, please check manually."
+ return 1
+ ;;
+ esac
+ elif ! _contains "$response" "- ReturnStringTRUE
"; then
+ _err "[KAS] -> An unknown error occurred, please check manually."
+ return 1
+ fi
+}
# Checks for the ENV variables and saves them
_check_and_save() {
KAS_Login="${KAS_Login:-$(_readaccountconf_mutable KAS_Login)}"
@@ -107,7 +154,7 @@ _check_and_save() {
KAS_Login=
KAS_Authtype=
KAS_Authdata=
- _err "No auth details provided. Please set user credentials using the \$KAS_Login, \$KAS_Authtype, and \$KAS_Authdata environment variables."
+ _err "[KAS] -> No auth details provided. Please set user credentials using the \$KAS_Login, \$KAS_Authtype, and \$KAS_Authdata environment variables."
return 1
fi
_saveaccountconf_mutable KAS_Login "$KAS_Login"
@@ -119,50 +166,116 @@ _check_and_save() {
# Gets back the base domain/zone and record name.
# See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide
_get_zone_and_record_name() {
- params="?kas_login=$KAS_Login"
- params="?kas_login=$KAS_Login"
- params="$params&kas_auth_type=$KAS_Authtype"
- params="$params&kas_auth_data=$KAS_Authdata"
- params="$params&kas_action=get_domains"
-
- _debug2 "Wait for 10 seconds by default before calling KAS API."
- _sleep 10
- response="$(_get "$KAS_Api$params")"
- _debug2 "response" "$response"
- _zonen="$(echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "domain_name" | tr '<' '\n' | grep "domain_name" | sed "s/domain_name>=>//g")"
- _domain="$1"
- _temp_domain="$(echo "$1" | sed 's/\.$//')"
- _rootzone="$_domain"
- for i in $_zonen; do
- l1=${#_rootzone}
+ action="get_domains"
+ response="$(_callAPI "$action")"
+ _debug2 "[KAS] -> Response" "$response"
+
+ if [ -z "$response" ]; then
+ _info "[KAS] -> Response was empty, please check manually."
+ return 1
+ elif _contains "$response" ""; then
+ faultstring="$(echo "$response" | tr -d '\n\r' | sed "s//\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
+ _err "[KAS] -> Either no domains were found or another error =>$faultstring<= occurred, please check manually."
+ return 1
+ fi
+
+ zonen="$(echo "$response" | sed 's/- /\n/g' | sed -r 's/(.*domain_name<\/key>)(.*)(<\/value.*)/\2/' | sed '/^ Zone:" "$_zone"
+ _debug "[KAS] -> Domain:" "$domain"
+ _debug "[KAS] -> Record_Name:" "$_record_name"
return 0
}
# Retrieve the DNS record ID
_get_record_id() {
- params="?kas_login=$KAS_Login"
- params="$params&kas_auth_type=$KAS_Authtype"
- params="$params&kas_auth_data=$KAS_Authdata"
- params="$params&kas_action=get_dns_settings"
- params="$params&var1=zone_host"
- params="$params&wert1=$_zone"
-
- _debug2 "Wait for 10 seconds by default before calling KAS API."
- _sleep 10
- response="$(_get "$KAS_Api$params")"
- _debug2 "response" "$response"
- _record_id="$(echo "$response" | tr -d "\n\r" | tr -d " " | tr '[]' '<>' | sed "s/=>Array/\n=> Array/g" | tr ' ' '\n' | grep "=>$_record_name<" | grep '>TXT<' | tr '<' '\n' | grep record_id | sed "s/record_id>=>//g")"
- _debug2 _record_id "$_record_id"
+ action="get_dns_settings"
+ kasReqParam="\"zone_host\":\"$_zone\""
+ response="$(_callAPI "$action" "$kasReqParam")"
+ _debug2 "[KAS] -> Response" "$response"
+
+ if [ -z "$response" ]; then
+ _info "[KAS] -> Response was empty, please check manually."
+ return 1
+ elif _contains "$response" ""; then
+ faultstring="$(echo "$response" | tr -d '\n\r' | sed "s//\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
+ _err "[KAS] -> Either no domains were found or another error =>$faultstring<= occurred, please check manually."
+ return 1
+ fi
+
+ _record_id="$(echo "$response" | tr -d '\n\r' | sed "s/
- /\n/g" | grep -i "$_record_name" | grep -i ">TXT<" | sed "s/
- record_id<\/key>/=>/g" | sed "s/<\/value><\/item>/\n/g" | grep "=>" | sed "s/=>//g")"
+ _debug "[KAS] -> Record Id: " "$_record_id"
+ return 0
+}
+
+# Retrieve credential token
+_get_credential_token() {
+ baseParamAuth="\"kas_login\":\"$KAS_Login\""
+ baseParamAuth="$baseParamAuth,\"kas_auth_type\":\"$KAS_Authtype\""
+ baseParamAuth="$baseParamAuth,\"kas_auth_data\":\"$KAS_Authdata\""
+ baseParamAuth="$baseParamAuth,\"session_lifetime\":600"
+ baseParamAuth="$baseParamAuth,\"session_update_lifetime\":\"Y\""
+
+ data='{'
+ data="$data$baseParamAuth}"
+
+ _debug "[KAS] -> Be friendly and wait $KAS_default_ratelimit seconds by default before calling KAS API."
+ _sleep $KAS_default_ratelimit
+
+ contentType="text/xml"
+ export _H1="SOAPAction: urn:xmethodsKasApiAuthentication#KasAuth"
+ response="$(_post "$data" "$KAS_Auth" "" "POST" "$contentType")"
+ _debug2 "[KAS] -> Response" "$response"
+
+ if [ -z "$response" ]; then
+ _info "[KAS] -> Response was empty, please check manually."
+ return 1
+ elif _contains "$response" ""; then
+ faultstring="$(echo "$response" | tr -d '\n\r' | sed "s//\n=> /g" | sed "s/<\/faultstring>/\n/g" | grep "=>" | sed "s/=> //g")"
+ _err "[KAS] -> Could not retrieve login token or antoher error =>$faultstring<= occurred, please check manually."
+ return 1
+ fi
+
+ _credential_token="$(echo "$response" | tr '\n' ' ' | sed 's/.*return xsi:type="xsd:string">\(.*\)<\/return>/\1/' | sed 's/<\/ns1:KasAuthResponse\(.*\)Envelope>.*//')"
+ _debug "[KAS] -> Credential Token: " "$_credential_token"
return 0
}
+
+_callAPI() {
+ kasaction=$1
+ kasReqParams=$2
+
+ baseParamAuth="\"kas_login\":\"$KAS_Login\""
+ baseParamAuth="$baseParamAuth,\"kas_auth_type\":\"session\""
+ baseParamAuth="$baseParamAuth,\"kas_auth_data\":\"$_credential_token\""
+
+ data='{'
+ data="$data$baseParamAuth,\"kas_action\":\"$kasaction\""
+ if [ -n "$kasReqParams" ]; then
+ data="$data,\"KasRequestParams\":{$kasReqParams}"
+ fi
+ data="$data}"
+
+ _debug2 "[KAS] -> Request" "$data"
+
+ _debug "[KAS] -> Be friendly and wait $KAS_default_ratelimit seconds by default before calling KAS API."
+ _sleep $KAS_default_ratelimit
+
+ contentType="text/xml"
+ export _H1="SOAPAction: urn:xmethodsKasApi#KasApi"
+ response="$(_post "$data" "$KAS_Api" "" "POST" "$contentType")"
+ _debug2 "[KAS] -> Response" "$response"
+ echo "$response"
+}
diff --git a/dnsapi/dns_kinghost.sh b/dnsapi/dns_kinghost.sh
index 6253c71d..f640242f 100644
--- a/dnsapi/dns_kinghost.sh
+++ b/dnsapi/dns_kinghost.sh
@@ -2,7 +2,7 @@
############################################################
# KingHost API support #
-# http://api.kinghost.net/doc/ #
+# https://api.kinghost.net/doc/ #
# #
# Author: Felipe Keller Braz #
# Report Bugs here: https://github.com/kinghost/acme.sh #
diff --git a/dnsapi/dns_la.sh b/dnsapi/dns_la.sh
new file mode 100644
index 00000000..674df410
--- /dev/null
+++ b/dnsapi/dns_la.sh
@@ -0,0 +1,147 @@
+#!/usr/bin/env sh
+
+#LA_Id="test123"
+#LA_Key="d1j2fdo4dee3948"
+
+LA_Api="https://api.dns.la/api"
+
+######## Public functions #####################
+
+#Usage: dns_la_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+dns_la_add() {
+ fulldomain=$1
+ txtvalue=$2
+
+ LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}"
+ LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}"
+
+ if [ -z "$LA_Id" ] || [ -z "$LA_Key" ]; then
+ LA_Id=""
+ LA_Key=""
+ _err "You didn't specify a dnsla api id and key yet."
+ return 1
+ fi
+
+ #save the api key and email to the account conf file.
+ _saveaccountconf_mutable LA_Id "$LA_Id"
+ _saveaccountconf_mutable LA_Key "$LA_Key"
+
+ _debug "First detect the root zone"
+ if ! _get_root "$fulldomain"; then
+ _err "invalid domain"
+ return 1
+ fi
+ _debug _domain_id "$_domain_id"
+ _debug _sub_domain "$_sub_domain"
+ _debug _domain "$_domain"
+
+ _info "Adding record"
+ if _la_rest "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then
+ if _contains "$response" '"resultid":'; then
+ _info "Added, OK"
+ return 0
+ elif _contains "$response" '"code":532'; then
+ _info "Already exists, OK"
+ return 0
+ else
+ _err "Add txt record error."
+ return 1
+ fi
+ fi
+ _err "Add txt record error."
+ return 1
+
+}
+
+#fulldomain txtvalue
+dns_la_rm() {
+ fulldomain=$1
+ txtvalue=$2
+
+ LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}"
+ LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}"
+
+ _debug "First detect the root zone"
+ if ! _get_root "$fulldomain"; then
+ _err "invalid domain"
+ return 1
+ fi
+ _debug _domain_id "$_domain_id"
+ _debug _sub_domain "$_sub_domain"
+ _debug _domain "$_domain"
+
+ _debug "Getting txt records"
+ if ! _la_rest "record.ashx?cmd=listn&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue"; then
+ _err "Error"
+ return 1
+ fi
+
+ if ! _contains "$response" '"recordid":'; then
+ _info "Don't need to remove."
+ return 0
+ fi
+
+ record_id=$(printf "%s" "$response" | grep '"recordid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n')
+ _debug "record_id" "$record_id"
+ if [ -z "$record_id" ]; then
+ _err "Can not get record id to remove."
+ return 1
+ fi
+ if ! _la_rest "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$record_id"; then
+ _err "Delete record error."
+ return 1
+ fi
+ _contains "$response" '"code":300'
+
+}
+
+#################### Private functions below ##################################
+#_acme-challenge.www.domain.com
+#returns
+# _sub_domain=_acme-challenge.www
+# _domain=domain.com
+# _domain_id=sdjkglgdfewsdfg
+_get_root() {
+ domain=$1
+ i=1
+ p=1
+
+ while true; do
+ h=$(printf "%s" "$domain" | cut -d . -f $i-100)
+ if [ -z "$h" ]; then
+ #not valid
+ return 1
+ fi
+
+ if ! _la_rest "domain.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domain=$h"; then
+ return 1
+ fi
+
+ if _contains "$response" '"domainid":'; then
+ _domain_id=$(printf "%s" "$response" | grep '"domainid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n')
+ if [ "$_domain_id" ]; then
+ _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
+ _domain="$h"
+ return 0
+ fi
+ return 1
+ fi
+ p="$i"
+ i=$(_math "$i" + 1)
+ done
+ return 1
+}
+
+#Usage: URI
+_la_rest() {
+ url="$LA_Api/$1"
+ _debug "$url"
+
+ if ! response="$(_get "$url" | tr -d ' ' | tr "}" ",")"; then
+ _err "Error: $url"
+ return 1
+ fi
+
+ _debug2 response "$response"
+ return 0
+}
diff --git a/dnsapi/dns_leaseweb.sh b/dnsapi/dns_leaseweb.sh
index a1d9e749..63f81869 100644
--- a/dnsapi/dns_leaseweb.sh
+++ b/dnsapi/dns_leaseweb.sh
@@ -3,7 +3,7 @@
#Author: Rolph Haspers
#Utilize leaseweb.com API to finish dns-01 verifications.
#Requires a Leaseweb API Key (export LSW_Key="Your Key")
-#See http://developer.leaseweb.com for more information.
+#See https://developer.leaseweb.com for more information.
######## Public functions #####################
LSW_API="https://api.leaseweb.com/hosting/v2/domains/"
diff --git a/dnsapi/dns_miab.sh b/dnsapi/dns_miab.sh
index 7e697704..dad69bde 100644
--- a/dnsapi/dns_miab.sh
+++ b/dnsapi/dns_miab.sh
@@ -163,6 +163,7 @@ _retrieve_miab_env() {
_saveaccountconf_mutable MIAB_Username "$MIAB_Username"
_saveaccountconf_mutable MIAB_Password "$MIAB_Password"
_saveaccountconf_mutable MIAB_Server "$MIAB_Server"
+ return 0
}
#Useage: _miab_rest "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" "custom/_acme-challenge.www.domain.com/txt "POST"
diff --git a/dnsapi/dns_mydnsjp.sh b/dnsapi/dns_mydnsjp.sh
index aab2aabf..13866f70 100755
--- a/dnsapi/dns_mydnsjp.sh
+++ b/dnsapi/dns_mydnsjp.sh
@@ -150,7 +150,7 @@ _get_root() {
_mydnsjp_retrieve_domain() {
_debug "Login to MyDNS.JP"
- response="$(_post "masterid=$MYDNSJP_MasterID&masterpwd=$MYDNSJP_Password" "$MYDNSJP_API/?MENU=100")"
+ response="$(_post "MENU=100&masterid=$MYDNSJP_MasterID&masterpwd=$MYDNSJP_Password" "$MYDNSJP_API/members/")"
cookie="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2)"
# If cookies is not empty then logon successful
@@ -159,22 +159,8 @@ _mydnsjp_retrieve_domain() {
return 1
fi
- _debug "Retrieve DOMAIN INFO page"
-
- export _H1="Cookie:${cookie}"
-
- response="$(_get "$MYDNSJP_API/?MENU=300")"
-
- if [ "$?" != "0" ]; then
- _err "Fail to retrieve DOMAIN INFO."
- return 1
- fi
-
_root_domain=$(echo "$response" | grep "DNSINFO\[domainname\]" | sed 's/^.*value="\([^"]*\)".*/\1/')
- # Logout
- response="$(_get "$MYDNSJP_API/?MENU=090")"
-
_debug _root_domain "$_root_domain"
if [ -z "$_root_domain" ]; then
diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh
index dcd87723..a5f667a9 100755
--- a/dnsapi/dns_namecheap.sh
+++ b/dnsapi/dns_namecheap.sh
@@ -82,7 +82,7 @@ _get_root() {
_debug "Failed domain lookup via domains.getList api call. Trying domain lookup via domains.dns.getHosts api."
# The above "getList" api will only return hosts *owned* by the calling user. However, if the calling
# user is not the owner, but still has administrative rights, we must query the getHosts api directly.
- # See this comment and the official namecheap response: http://disq.us/p/1q6v9x9
+ # See this comment and the official namecheap response: https://disq.us/p/1q6v9x9
if ! _get_root_by_getHosts "$fulldomain"; then
return 1
fi
diff --git a/dnsapi/dns_namesilo.sh b/dnsapi/dns_namesilo.sh
index 0b87b7f7..f961d0bd 100755
--- a/dnsapi/dns_namesilo.sh
+++ b/dnsapi/dns_namesilo.sh
@@ -110,7 +110,7 @@ _get_root() {
return 1
fi
- if _contains "$response" "$host"; then
+ if _contains "$response" ">$host"; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$host"
return 0
diff --git a/dnsapi/dns_netlify.sh b/dnsapi/dns_netlify.sh
index 65e803c5..0e5dc327 100644
--- a/dnsapi/dns_netlify.sh
+++ b/dnsapi/dns_netlify.sh
@@ -18,15 +18,15 @@ dns_netlify_add() {
NETLIFY_ACCESS_TOKEN=""
_err "Please specify your Netlify Access Token and try again."
return 1
+ else
+ _saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN"
fi
_info "Using Netlify"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
- _saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN"
-
- if ! _get_root "$fulldomain" "$accesstoken"; then
+ if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
@@ -62,9 +62,9 @@ dns_netlify_rm() {
_debug txtdomain "$txtdomain"
_debug txt "$txt"
- _saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN"
+ NETLIFY_ACCESS_TOKEN="${NETLIFY_ACCESS_TOKEN:-$(_readaccountconf_mutable NETLIFY_ACCESS_TOKEN)}"
- if ! _get_root "$txtdomain" "$accesstoken"; then
+ if ! _get_root "$txtdomain"; then
_err "invalid domain"
return 1
fi
diff --git a/dnsapi/dns_oci.sh b/dnsapi/dns_oci.sh
index 18d74410..3b81143f 100644
--- a/dnsapi/dns_oci.sh
+++ b/dnsapi/dns_oci.sh
@@ -265,6 +265,7 @@ _signed_request() {
_response="$(_get "https://${_sig_host}${_sig_target}")"
elif [ "$_curl_method" = "PATCH" ]; then
export _H1="$_date_header"
+ # shellcheck disable=SC2090
export _H2="$_sig_body_sha256"
export _H3="$_sig_body_type"
export _H4="$_sig_body_length"
diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh
index eb95902f..c2806a1b 100755
--- a/dnsapi/dns_opnsense.sh
+++ b/dnsapi/dns_opnsense.sh
@@ -137,7 +137,7 @@ _get_root() {
domain=$1
i=2
p=1
- if _opns_rest "GET" "/domain/get"; then
+ if _opns_rest "GET" "/domain/searchMasterDomain"; then
_domain_response="$response"
else
return 1
@@ -150,7 +150,7 @@ _get_root() {
return 1
fi
_debug h "$h"
- id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":{\"[^\"]*\":{[^}]*}},\"transferkeyalgo\":{[^{]*{[^{]*{[^{]*{[^{]*{[^{]*{[^{]*{[^{]*{[^}]*}},\"transferkey\":\"[^\"]*\"(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2)
+ id=$(echo "$_domain_response" | _egrep_o "\"uuid\":\"[a-z0-9\-]*\",\"enabled\":\"1\",\"type\":\"master\",\"domainname\":\"${h}\"" | cut -d ':' -f 2 | cut -d '"' -f 2)
if [ -n "$id" ]; then
_debug id "$id"
_host=$(printf "%s" "$domain" | cut -d . -f 1-$p)
diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh
index 2252f03a..5e35011b 100755
--- a/dnsapi/dns_ovh.sh
+++ b/dnsapi/dns_ovh.sh
@@ -92,7 +92,7 @@ _initAuth() {
if [ "$OVH_AK" != "$(_readaccountconf OVH_AK)" ]; then
_info "It seems that your ovh key is changed, let's clear consumer key first."
- _clearaccountconf OVH_CK
+ _clearaccountconf_mutable OVH_CK
fi
_saveaccountconf_mutable OVH_AK "$OVH_AK"
_saveaccountconf_mutable OVH_AS "$OVH_AS"
@@ -118,14 +118,14 @@ _initAuth() {
#return and wait for retry.
return 1
fi
- _saveaccountconf OVH_CK "$OVH_CK"
+ _saveaccountconf_mutable OVH_CK "$OVH_CK"
_info "Checking authentication"
if ! _ovh_rest GET "domain" || _contains "$response" "INVALID_CREDENTIAL" || _contains "$response" "NOT_CREDENTIAL"; then
_err "The consumer key is invalid: $OVH_CK"
_err "Please retry to create a new one."
- _clearaccountconf OVH_CK
+ _clearaccountconf_mutable OVH_CK
return 1
fi
_info "Consumer key is ok."
@@ -236,7 +236,7 @@ _ovh_authentication() {
_secure_debug consumerKey "$consumerKey"
OVH_CK="$consumerKey"
-
+ _saveaccountconf_mutable OVH_CK "$OVH_CK"
_info "Please open this link to do authentication: $(__green "$validationUrl")"
_info "Here is a guide for you: $(__green "$wiki")"
diff --git a/dnsapi/dns_rage4.sh b/dnsapi/dns_rage4.sh
new file mode 100755
index 00000000..4af4541d
--- /dev/null
+++ b/dnsapi/dns_rage4.sh
@@ -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
+}
diff --git a/dnsapi/dns_regru.sh b/dnsapi/dns_regru.sh
index 2a1ebaa5..8ff380f0 100644
--- a/dnsapi/dns_regru.sh
+++ b/dnsapi/dns_regru.sh
@@ -92,10 +92,10 @@ _get_root() {
domains_list=$(echo "${response}" | grep dname | sed -r "s/.*dname=\"([^\"]+)\".*/\\1/g")
for ITEM in ${domains_list}; do
- IDN_ITEM="$(_idn "${ITEM}")"
+ IDN_ITEM=${ITEM}
case "${domain}" in
*${IDN_ITEM}*)
- _domain=${IDN_ITEM}
+ _domain="$(_idn "${ITEM}")"
_debug _domain "${_domain}"
return 0
;;
diff --git a/dnsapi/dns_selfhost.sh b/dnsapi/dns_selfhost.sh
new file mode 100644
index 00000000..a6ef1f94
--- /dev/null
+++ b/dnsapi/dns_selfhost.sh
@@ -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."
+}
diff --git a/dnsapi/dns_servercow.sh b/dnsapi/dns_servercow.sh
index f70a2294..52137905 100755
--- a/dnsapi/dns_servercow.sh
+++ b/dnsapi/dns_servercow.sh
@@ -53,7 +53,7 @@ dns_servercow_add() {
if printf -- "%s" "$response" | grep "{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\"" >/dev/null; then
_info "A txt record with the same name already exists."
# trim the string on the left
- txtvalue_old=${response#*{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"}
+ txtvalue_old=${response#*{\"name\":\""$_sub_domain"\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"}
# trim the string on the right
txtvalue_old=${txtvalue_old%%\"*}
diff --git a/dnsapi/dns_transip.sh b/dnsapi/dns_transip.sh
index 23debe0d..64a256ec 100644
--- a/dnsapi/dns_transip.sh
+++ b/dnsapi/dns_transip.sh
@@ -1,7 +1,6 @@
#!/usr/bin/env sh
TRANSIP_Api_Url="https://api.transip.nl/v6"
TRANSIP_Token_Read_Only="false"
-TRANSIP_Token_Global_Key="false"
TRANSIP_Token_Expiration="30 minutes"
# You can't reuse a label token, so we leave this empty normally
TRANSIP_Token_Label=""
@@ -96,7 +95,11 @@ _transip_get_token() {
nonce=$(echo "TRANSIP$(_time)" | _digest sha1 hex | cut -c 1-32)
_debug nonce "$nonce"
- data="{\"login\":\"${TRANSIP_Username}\",\"nonce\":\"${nonce}\",\"read_only\":\"${TRANSIP_Token_Read_Only}\",\"expiration_time\":\"${TRANSIP_Token_Expiration}\",\"label\":\"${TRANSIP_Token_Label}\",\"global_key\":\"${TRANSIP_Token_Global_Key}\"}"
+ # make IP whitelisting configurable
+ TRANSIP_Token_Global_Key="${TRANSIP_Token_Global_Key:-$(_readaccountconf_mutable TRANSIP_Token_Global_Key)}"
+ _saveaccountconf_mutable TRANSIP_Token_Global_Key "$TRANSIP_Token_Global_Key"
+
+ data="{\"login\":\"${TRANSIP_Username}\",\"nonce\":\"${nonce}\",\"read_only\":\"${TRANSIP_Token_Read_Only}\",\"expiration_time\":\"${TRANSIP_Token_Expiration}\",\"label\":\"${TRANSIP_Token_Label}\",\"global_key\":\"${TRANSIP_Token_Global_Key:-false}\"}"
_debug data "$data"
#_signature=$(printf "%s" "$data" | openssl dgst -sha512 -sign "$TRANSIP_Key_File" | _base64)
@@ -139,6 +142,18 @@ _transip_setup() {
_saveaccountconf_mutable TRANSIP_Username "$TRANSIP_Username"
_saveaccountconf_mutable TRANSIP_Key_File "$TRANSIP_Key_File"
+ # download key file if it's an URL
+ if _startswith "$TRANSIP_Key_File" "http"; then
+ _debug "download transip key file"
+ TRANSIP_Key_URL=$TRANSIP_Key_File
+ TRANSIP_Key_File="$(_mktemp)"
+ chmod 600 "$TRANSIP_Key_File"
+ if ! _get "$TRANSIP_Key_URL" >"$TRANSIP_Key_File"; then
+ _err "Error getting key file from : $TRANSIP_Key_URL"
+ return 1
+ fi
+ fi
+
if [ -f "$TRANSIP_Key_File" ]; then
if ! grep "BEGIN PRIVATE KEY" "$TRANSIP_Key_File" >/dev/null 2>&1; then
_err "Key file doesn't seem to be a valid key: ${TRANSIP_Key_File}"
@@ -156,6 +171,12 @@ _transip_setup() {
fi
fi
+ if [ -n "${TRANSIP_Key_URL}" ]; then
+ _debug "delete transip key file"
+ rm "${TRANSIP_Key_File}"
+ TRANSIP_Key_File=$TRANSIP_Key_URL
+ fi
+
_get_root "$fulldomain" || return 1
return 0
diff --git a/dnsapi/dns_vultr.sh b/dnsapi/dns_vultr.sh
index 84857966..58f14be1 100644
--- a/dnsapi/dns_vultr.sh
+++ b/dnsapi/dns_vultr.sh
@@ -3,10 +3,10 @@
#
#VULTR_API_KEY=000011112222333344445555666677778888
-VULTR_Api="https://api.vultr.com/v1"
+VULTR_Api="https://api.vultr.com/v2"
######## Public functions #####################
-
+#
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_vultr_add() {
fulldomain=$1
@@ -31,14 +31,14 @@ dns_vultr_add() {
_debug _domain "$_domain"
_debug 'Getting txt records'
- _vultr_rest GET "dns/records?domain=$_domain"
+ _vultr_rest GET "domains/$_domain/records"
if printf "%s\n" "$response" | grep -- "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then
_err 'Error'
return 1
fi
- if ! _vultr_rest POST 'dns/create_record' "domain=$_domain&name=$_sub_domain&data=\"$txtvalue\"&type=TXT"; then
+ if ! _vultr_rest POST "domains/$_domain/records" "{\"name\":\"$_sub_domain\",\"data\":\"$txtvalue\",\"type\":\"TXT\"}"; then
_err "$response"
return 1
fi
@@ -71,14 +71,14 @@ dns_vultr_rm() {
_debug _domain "$_domain"
_debug 'Getting txt records'
- _vultr_rest GET "dns/records?domain=$_domain"
+ _vultr_rest GET "domains/$_domain/records"
if printf "%s\n" "$response" | grep -- "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then
_err 'Error'
return 1
fi
- _record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'RECORDID' | cut -d : -f 2)"
+ _record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'id' | cut -d : -f 2)"
_debug _record_id "$_record_id"
if [ "$_record_id" ]; then
_info "Successfully retrieved the record id for ACME challenge."
@@ -87,7 +87,7 @@ dns_vultr_rm() {
return 0
fi
- if ! _vultr_rest POST 'dns/delete_record' "domain=$_domain&RECORDID=$_record_id"; then
+ if ! _vultr_rest DELETE "domains/$_domain/records/$_record_id"; then
_err "$response"
return 1
fi
@@ -112,11 +112,11 @@ _get_root() {
return 1
fi
- if ! _vultr_rest GET "dns/list"; then
+ if ! _vultr_rest GET "domains"; then
return 1
fi
- if printf "%s\n" "$response" | grep '^\[.*\]' >/dev/null; then
+ if printf "%s\n" "$response" | grep '^\{.*\}' >/dev/null; then
if _contains "$response" "\"domain\":\"$_domain\""; then
_sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")"
return 0
@@ -139,10 +139,10 @@ _vultr_rest() {
data="$3"
_debug "$ep"
- api_key_trimmed=$(echo $VULTR_API_KEY | tr -d '"')
+ api_key_trimmed=$(echo "$VULTR_API_KEY" | tr -d '"')
- export _H1="Api-Key: $api_key_trimmed"
- export _H2='Content-Type: application/x-www-form-urlencoded'
+ export _H1="Authorization: Bearer $api_key_trimmed"
+ export _H2='Content-Type: application/json'
if [ "$m" != "GET" ]; then
_debug data "$data"
diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh
index a0a83c37..dfda4efd 100644
--- a/dnsapi/dns_world4you.sh
+++ b/dnsapi/dns_world4you.sh
@@ -195,7 +195,7 @@ _get_paketnr() {
fqdn="$1"
form="$2"
- domains=$(echo "$form" | grep 'header-paket-domain' | sed 's/<[^>]*>//g' | sed 's/^.*>\([^>]*\)$/\1/')
+ domains=$(echo "$form" | grep '