Compare commits

..
0 Commits
187 changed files with 2569 additions and 6828 deletions

No files matched your search

+55 -105
View File
@@ -1,6 +1,5 @@
name: DNS name: DNS
on: on:
workflow_dispatch:
push: push:
paths: paths:
- 'dnsapi/*.sh' - 'dnsapi/*.sh'
@@ -66,7 +65,7 @@ jobs:
TokenName4: ${{ secrets.TokenName4}} TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}} TokenName5: ${{ secrets.TokenName5}}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Clone acmetest - name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Set env file - name: Set env file
@@ -114,7 +113,7 @@ jobs:
TokenName4: ${{ secrets.TokenName4}} TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}} TokenName5: ${{ secrets.TokenName5}}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install tools - name: Install tools
run: brew install socat run: brew install socat
- name: Clone acmetest - name: Clone acmetest
@@ -122,19 +121,19 @@ jobs:
- name: Run acmetest - name: Run acmetest
run: | run: |
if [ "${{ secrets.TokenName1}}" ] ; then if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
fi fi
if [ "${{ secrets.TokenName2}}" ] ; then if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
fi fi
if [ "${{ secrets.TokenName3}}" ] ; then if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
fi fi
if [ "${{ secrets.TokenName4}}" ] ; then if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
fi fi
if [ "${{ secrets.TokenName5}}" ] ; then if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
fi fi
cd ../acmetest cd ../acmetest
./letest.sh ./letest.sh
@@ -165,7 +164,7 @@ jobs:
- name: Set git to use LF - name: Set git to use LF
run: | run: |
git config --global core.autocrlf false git config --global core.autocrlf false
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install cygwin base packages with chocolatey - name: Install cygwin base packages with chocolatey
run: | run: |
choco config get cacheLocation choco config get cacheLocation
@@ -185,19 +184,19 @@ jobs:
shell: bash shell: bash
run: | run: |
if [ "${{ secrets.TokenName1}}" ] ; then if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
fi fi
if [ "${{ secrets.TokenName2}}" ] ; then if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
fi fi
if [ "${{ secrets.TokenName3}}" ] ; then if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
fi fi
if [ "${{ secrets.TokenName4}}" ] ; then if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
fi fi
if [ "${{ secrets.TokenName5}}" ] ; then if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
fi fi
cd ../acmetest cd ../acmetest
./letest.sh ./letest.sh
@@ -205,7 +204,7 @@ jobs:
FreeBSD: FreeBSD:
runs-on: ubuntu-latest runs-on: macos-12
needs: Windows needs: Windows
env: env:
TEST_DNS : ${{ secrets.TEST_DNS }} TEST_DNS : ${{ secrets.TEST_DNS }}
@@ -224,10 +223,10 @@ jobs:
TokenName4: ${{ secrets.TokenName4}} TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}} TokenName5: ${{ secrets.TokenName5}}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Clone acmetest - name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/freebsd-vm@v1 - uses: vmactions/freebsd-vm@v0
with: with:
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
prepare: pkg install -y socat curl prepare: pkg install -y socat curl
@@ -235,19 +234,19 @@ jobs:
copyback: false copyback: false
run: | run: |
if [ "${{ secrets.TokenName1}}" ] ; then if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
fi fi
if [ "${{ secrets.TokenName2}}" ] ; then if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
fi fi
if [ "${{ secrets.TokenName3}}" ] ; then if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
fi fi
if [ "${{ secrets.TokenName4}}" ] ; then if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
fi fi
if [ "${{ secrets.TokenName5}}" ] ; then if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
fi fi
cd ../acmetest cd ../acmetest
./letest.sh ./letest.sh
@@ -256,7 +255,7 @@ jobs:
OpenBSD: OpenBSD:
runs-on: ubuntu-latest runs-on: macos-12
needs: FreeBSD needs: FreeBSD
env: env:
TEST_DNS : ${{ secrets.TEST_DNS }} TEST_DNS : ${{ secrets.TEST_DNS }}
@@ -275,10 +274,10 @@ jobs:
TokenName4: ${{ secrets.TokenName4}} TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}} TokenName5: ${{ secrets.TokenName5}}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Clone acmetest - name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/openbsd-vm@v1 - uses: vmactions/openbsd-vm@v0
with: with:
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
prepare: pkg_add socat curl prepare: pkg_add socat curl
@@ -286,19 +285,19 @@ jobs:
copyback: false copyback: false
run: | run: |
if [ "${{ secrets.TokenName1}}" ] ; then if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
fi fi
if [ "${{ secrets.TokenName2}}" ] ; then if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
fi fi
if [ "${{ secrets.TokenName3}}" ] ; then if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
fi fi
if [ "${{ secrets.TokenName4}}" ] ; then if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
fi fi
if [ "${{ secrets.TokenName5}}" ] ; then if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
fi fi
cd ../acmetest cd ../acmetest
./letest.sh ./letest.sh
@@ -307,7 +306,7 @@ jobs:
NetBSD: NetBSD:
runs-on: ubuntu-latest runs-on: macos-12
needs: OpenBSD needs: OpenBSD
env: env:
TEST_DNS : ${{ secrets.TEST_DNS }} TEST_DNS : ${{ secrets.TEST_DNS }}
@@ -326,31 +325,31 @@ jobs:
TokenName4: ${{ secrets.TokenName4}} TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}} TokenName5: ${{ secrets.TokenName5}}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Clone acmetest - name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/netbsd-vm@v1 - uses: vmactions/netbsd-vm@v0
with: with:
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
prepare: | prepare: |
/usr/sbin/pkg_add curl socat pkg_add curl socat
usesh: true usesh: true
copyback: false copyback: false
run: | run: |
if [ "${{ secrets.TokenName1}}" ] ; then if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
fi fi
if [ "${{ secrets.TokenName2}}" ] ; then if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
fi fi
if [ "${{ secrets.TokenName3}}" ] ; then if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
fi fi
if [ "${{ secrets.TokenName4}}" ] ; then if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
fi fi
if [ "${{ secrets.TokenName5}}" ] ; then if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
fi fi
cd ../acmetest cd ../acmetest
./letest.sh ./letest.sh
@@ -359,7 +358,7 @@ jobs:
DragonFlyBSD: DragonFlyBSD:
runs-on: ubuntu-latest runs-on: macos-12
needs: NetBSD needs: NetBSD
env: env:
TEST_DNS : ${{ secrets.TEST_DNS }} TEST_DNS : ${{ secrets.TEST_DNS }}
@@ -378,31 +377,31 @@ jobs:
TokenName4: ${{ secrets.TokenName4}} TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}} TokenName5: ${{ secrets.TokenName5}}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Clone acmetest - name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/dragonflybsd-vm@v1 - uses: vmactions/dragonflybsd-vm@v0
with: with:
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
prepare: | prepare: |
pkg install -y curl socat libnghttp2 pkg install -y curl socat
usesh: true usesh: true
copyback: false copyback: false
run: | run: |
if [ "${{ secrets.TokenName1}}" ] ; then if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
fi fi
if [ "${{ secrets.TokenName2}}" ] ; then if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
fi fi
if [ "${{ secrets.TokenName3}}" ] ; then if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
fi fi
if [ "${{ secrets.TokenName4}}" ] ; then if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
fi fi
if [ "${{ secrets.TokenName5}}" ] ; then if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
fi fi
cd ../acmetest cd ../acmetest
./letest.sh ./letest.sh
@@ -414,7 +413,7 @@ jobs:
Solaris: Solaris:
runs-on: ubuntu-latest runs-on: macos-12
needs: DragonFlyBSD needs: DragonFlyBSD
env: env:
TEST_DNS : ${{ secrets.TEST_DNS }} TEST_DNS : ${{ secrets.TEST_DNS }}
@@ -434,10 +433,10 @@ jobs:
TokenName4: ${{ secrets.TokenName4}} TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}} TokenName5: ${{ secrets.TokenName5}}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Clone acmetest - name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/solaris-vm@v1 - uses: vmactions/solaris-vm@v0
with: with:
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy HTTPS_INSECURE TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy HTTPS_INSECURE TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
copyback: false copyback: false
@@ -446,68 +445,19 @@ jobs:
pkg set-mediator -v -I default@1.1 openssl pkg set-mediator -v -I default@1.1 openssl
export PATH=/usr/gnu/bin:$PATH export PATH=/usr/gnu/bin:$PATH
if [ "${{ secrets.TokenName1}}" ] ; then if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}" export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
fi fi
if [ "${{ secrets.TokenName2}}" ] ; then if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}" export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
fi fi
if [ "${{ secrets.TokenName3}}" ] ; then if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}" export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
fi fi
if [ "${{ secrets.TokenName4}}" ] ; then if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}" export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
fi fi
if [ "${{ secrets.TokenName5}}" ] ; then if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}" export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
fi
cd ../acmetest
./letest.sh
Omnios:
runs-on: ubuntu-latest
needs: Solaris
env:
TEST_DNS : ${{ secrets.TEST_DNS }}
TestingDomain: ${{ secrets.TestingDomain }}
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
TEST_DNS_NO_SUBDOMAIN: ${{ secrets.TEST_DNS_NO_SUBDOMAIN }}
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
CASE: le_test_dnsapi
TEST_LOCAL: 1
DEBUG: ${{ secrets.DEBUG }}
http_proxy: ${{ secrets.http_proxy }}
https_proxy: ${{ secrets.https_proxy }}
HTTPS_INSECURE: 1 # always set to 1 to ignore https error, since Omnios doesn't accept the expired ISRG X1 root
TokenName1: ${{ secrets.TokenName1}}
TokenName2: ${{ secrets.TokenName2}}
TokenName3: ${{ secrets.TokenName3}}
TokenName4: ${{ secrets.TokenName4}}
TokenName5: ${{ secrets.TokenName5}}
steps:
- uses: actions/checkout@v4
- name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/omnios-vm@v1
with:
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: pkg install socat
run: |
if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}="${{ secrets.TokenValue1}}"
fi
if [ "${{ secrets.TokenName2}}" ] ; then
export ${{ secrets.TokenName2}}="${{ secrets.TokenValue2}}"
fi
if [ "${{ secrets.TokenName3}}" ] ; then
export ${{ secrets.TokenName3}}="${{ secrets.TokenValue3}}"
fi
if [ "${{ secrets.TokenName4}}" ] ; then
export ${{ secrets.TokenName4}}="${{ secrets.TokenValue4}}"
fi
if [ "${{ secrets.TokenName5}}" ] ; then
export ${{ secrets.TokenName5}}="${{ secrets.TokenValue5}}"
fi fi
cd ../acmetest cd ../acmetest
./letest.sh ./letest.sh
+71 -71
View File
@@ -1,71 +1,71 @@
name: DragonFlyBSD name: DragonFlyBSD
on: on:
push: push:
branches: branches:
- '*' - '*'
paths: paths:
- '*.sh' - '*.sh'
- '.github/workflows/DragonFlyBSD.yml' - '.github/workflows/DragonFlyBSD.yml'
pull_request: pull_request:
branches: branches:
- dev - dev
paths: paths:
- '*.sh' - '*.sh'
- '.github/workflows/DragonFlyBSD.yml' - '.github/workflows/DragonFlyBSD.yml'
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
jobs:
DragonFlyBSD: jobs:
strategy: DragonFlyBSD:
matrix: strategy:
include: matrix:
- TEST_ACME_Server: "LetsEncrypt.org_test" include:
CA_ECDSA: "" - TEST_ACME_Server: "LetsEncrypt.org_test"
CA: "" CA_ECDSA: ""
CA_EMAIL: "" CA: ""
TEST_PREFERRED_CHAIN: (STAGING) CA_EMAIL: ""
#- TEST_ACME_Server: "ZeroSSL.com" TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" #- TEST_ACME_Server: "ZeroSSL.com"
# CA: "ZeroSSL RSA Domain Secure Site CA" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA_EMAIL: "githubtest@acme.sh" # CA: "ZeroSSL RSA Domain Secure Site CA"
# TEST_PREFERRED_CHAIN: "" # CA_EMAIL: "githubtest@acme.sh"
runs-on: ubuntu-latest # TEST_PREFERRED_CHAIN: ""
env: runs-on: macos-12
TEST_LOCAL: 1 env:
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} TEST_LOCAL: 1
CA_ECDSA: ${{ matrix.CA_ECDSA }} TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
CA: ${{ matrix.CA }} CA_ECDSA: ${{ matrix.CA_ECDSA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }} CA: ${{ matrix.CA }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} CA_EMAIL: ${{ matrix.CA_EMAIL }}
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: vmactions/cf-tunnel@v0 - uses: vmactions/cf-tunnel@v0
id: tunnel id: tunnel
with: with:
protocol: http protocol: http
port: 8080 port: 8080
- name: Set envs - name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest - name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/dragonflybsd-vm@v1 - uses: vmactions/dragonflybsd-vm@v0
with: with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
nat: | copyback: "false"
"8080": "80" nat: |
prepare: | "8080": "80"
pkg install -y curl socat libnghttp2 prepare: |
usesh: true pkg install -y curl socat
copyback: false usesh: true
run: | run: |
cd ../acmetest \ cd ../acmetest \
&& ./letest.sh && ./letest.sh
+5 -5
View File
@@ -29,19 +29,19 @@ jobs:
CA_ECDSA: "" CA_ECDSA: ""
CA: "" CA: ""
CA_EMAIL: "" CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "LetsEncrypt.org_test" - TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: "" CA_ECDSA: ""
CA: "" CA: ""
CA_EMAIL: "" CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
ACME_USE_WGET: 1 ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com" #- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA"
# CA_EMAIL: "githubtest@acme.sh" # CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: "" # TEST_PREFERRED_CHAIN: ""
runs-on: ubuntu-latest runs-on: macos-12
env: env:
TEST_LOCAL: 1 TEST_LOCAL: 1
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
@@ -51,7 +51,7 @@ jobs:
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: vmactions/cf-tunnel@v0 - uses: vmactions/cf-tunnel@v0
id: tunnel id: tunnel
with: with:
@@ -61,7 +61,7 @@ jobs:
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest - name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/freebsd-vm@v1 - uses: vmactions/freebsd-vm@v0
with: with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: | nat: |
+3 -3
View File
@@ -26,14 +26,14 @@ jobs:
Linux: Linux:
strategy: strategy:
matrix: matrix:
os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3"] os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:7", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3"]
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:
TEST_LOCAL: 1 TEST_LOCAL: 1
TEST_PREFERRED_CHAIN: (STAGING) TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
TEST_ACME_Server: "LetsEncrypt.org_test" TEST_ACME_Server: "LetsEncrypt.org_test"
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Clone acmetest - name: Clone acmetest
run: | run: |
cd .. \ cd .. \
+2 -2
View File
@@ -29,7 +29,7 @@ jobs:
CA_ECDSA: "" CA_ECDSA: ""
CA: "" CA: ""
CA_EMAIL: "" CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
#- TEST_ACME_Server: "ZeroSSL.com" #- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA"
@@ -44,7 +44,7 @@ jobs:
CA_EMAIL: ${{ matrix.CA_EMAIL }} CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install tools - name: Install tools
run: brew install socat run: brew install socat
- name: Clone acmetest - name: Clone acmetest
+72 -71
View File
@@ -1,71 +1,72 @@
name: NetBSD name: NetBSD
on: on:
push: push:
branches: branches:
- '*' - '*'
paths: paths:
- '*.sh' - '*.sh'
- '.github/workflows/NetBSD.yml' - '.github/workflows/NetBSD.yml'
pull_request: pull_request:
branches: branches:
- dev - dev
paths: paths:
- '*.sh' - '*.sh'
- '.github/workflows/NetBSD.yml' - '.github/workflows/NetBSD.yml'
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
jobs:
NetBSD: jobs:
strategy: NetBSD:
matrix: strategy:
include: matrix:
- TEST_ACME_Server: "LetsEncrypt.org_test" include:
CA_ECDSA: "" - TEST_ACME_Server: "LetsEncrypt.org_test"
CA: "" CA_ECDSA: ""
CA_EMAIL: "" CA: ""
TEST_PREFERRED_CHAIN: (STAGING) CA_EMAIL: ""
#- TEST_ACME_Server: "ZeroSSL.com" TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" #- TEST_ACME_Server: "ZeroSSL.com"
# CA: "ZeroSSL RSA Domain Secure Site CA" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA_EMAIL: "githubtest@acme.sh" # CA: "ZeroSSL RSA Domain Secure Site CA"
# TEST_PREFERRED_CHAIN: "" # CA_EMAIL: "githubtest@acme.sh"
runs-on: ubuntu-latest # TEST_PREFERRED_CHAIN: ""
env: runs-on: macos-12
TEST_LOCAL: 1 env:
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} TEST_LOCAL: 1
CA_ECDSA: ${{ matrix.CA_ECDSA }} TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
CA: ${{ matrix.CA }} CA_ECDSA: ${{ matrix.CA_ECDSA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }} CA: ${{ matrix.CA }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} CA_EMAIL: ${{ matrix.CA_EMAIL }}
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: vmactions/cf-tunnel@v0 - uses: vmactions/cf-tunnel@v0
id: tunnel id: tunnel
with: with:
protocol: http protocol: http
port: 8080 port: 8080
- name: Set envs - name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest - name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/netbsd-vm@v1 - uses: vmactions/netbsd-vm@v0
with: with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
nat: | nat: |
"8080": "80" "8080": "80"
prepare: | prepare: |
/usr/sbin/pkg_add curl socat export PKG_PATH="https://cdn.NetBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f '1 2' -d.)/All/"
usesh: true pkg_add curl socat
copyback: false usesh: true
run: | copyback: false
cd ../acmetest \ run: |
&& ./letest.sh cd ../acmetest \
&& ./letest.sh
-75
View File
@@ -1,75 +0,0 @@
name: Omnios
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/Omnios.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/Omnios.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
Omnios:
strategy:
matrix:
include:
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING)
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING)
ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA"
# CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: ""
runs-on: ubuntu-latest
env:
TEST_LOCAL: 1
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
CA_ECDSA: ${{ matrix.CA_ECDSA }}
CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
steps:
- uses: actions/checkout@v4
- 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/omnios-vm@v1
with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: |
"8080": "80"
prepare: pkg install socat wget
copyback: false
run: |
cd ../acmetest \
&& ./letest.sh
+6 -6
View File
@@ -29,19 +29,19 @@ jobs:
CA_ECDSA: "" CA_ECDSA: ""
CA: "" CA: ""
CA_EMAIL: "" CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "LetsEncrypt.org_test" - TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: "" CA_ECDSA: ""
CA: "" CA: ""
CA_EMAIL: "" CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
ACME_USE_WGET: 1 ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com" #- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA"
# CA_EMAIL: "githubtest@acme.sh" # CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: "" # TEST_PREFERRED_CHAIN: ""
runs-on: ubuntu-latest runs-on: macos-12
env: env:
TEST_LOCAL: 1 TEST_LOCAL: 1
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
@@ -51,7 +51,7 @@ jobs:
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: vmactions/cf-tunnel@v0 - uses: vmactions/cf-tunnel@v0
id: tunnel id: tunnel
with: with:
@@ -61,12 +61,12 @@ jobs:
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest - name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/openbsd-vm@v1 - uses: vmactions/openbsd-vm@v0
with: with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: | nat: |
"8080": "80" "8080": "80"
prepare: pkg_add socat curl wget libnghttp2 prepare: pkg_add socat curl wget
usesh: true usesh: true
copyback: false copyback: false
run: | run: |
+3 -3
View File
@@ -33,11 +33,11 @@ jobs:
TEST_CA: "Pebble Intermediate CA" TEST_CA: "Pebble Intermediate CA"
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install tools - name: Install tools
run: sudo apt-get install -y socat run: sudo apt-get install -y socat
- name: Run Pebble - name: Run Pebble
run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker compose up -d run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d
- name: Set up Pebble - name: Set up Pebble
run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4 run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4
- name: Clone acmetest - name: Clone acmetest
@@ -58,7 +58,7 @@ jobs:
TEST_IPCERT: 1 TEST_IPCERT: 1
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install tools - name: Install tools
run: sudo apt-get install -y socat run: sudo apt-get install -y socat
- name: Run Pebble - name: Run Pebble
+74 -75
View File
@@ -1,75 +1,74 @@
name: Solaris name: Solaris
on: on:
push: push:
branches: branches:
- '*' - '*'
paths: paths:
- '*.sh' - '*.sh'
- '.github/workflows/Solaris.yml' - '.github/workflows/Solaris.yml'
pull_request: pull_request:
branches: branches:
- dev - dev
paths: paths:
- '*.sh' - '*.sh'
- '.github/workflows/Solaris.yml' - '.github/workflows/Solaris.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
Solaris: Solaris:
strategy: strategy:
matrix: matrix:
include: include:
- TEST_ACME_Server: "LetsEncrypt.org_test" - TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: "" CA_ECDSA: ""
CA: "" CA: ""
CA_EMAIL: "" CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "LetsEncrypt.org_test" - TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: "" CA_ECDSA: ""
CA: "" CA: ""
CA_EMAIL: "" CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
ACME_USE_WGET: 1 ACME_USE_WGET: 1
#- TEST_ACME_Server: "ZeroSSL.com" #- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA"
# CA_EMAIL: "githubtest@acme.sh" # CA_EMAIL: "githubtest@acme.sh"
# TEST_PREFERRED_CHAIN: "" # TEST_PREFERRED_CHAIN: ""
runs-on: ubuntu-latest runs-on: macos-12
env: env:
TEST_LOCAL: 1 TEST_LOCAL: 1
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }} TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
CA_ECDSA: ${{ matrix.CA_ECDSA }} CA_ECDSA: ${{ matrix.CA_ECDSA }}
CA: ${{ matrix.CA }} CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }} CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }} TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: vmactions/cf-tunnel@v0 - uses: vmactions/cf-tunnel@v0
id: tunnel id: tunnel
with: with:
protocol: http protocol: http
port: 8080 port: 8080
- name: Set envs - name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest - name: Clone acmetest
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/solaris-vm@v1 - uses: vmactions/solaris-vm@v0
with: with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET' envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
nat: | copyback: "false"
"8080": "80" nat: |
prepare: pkgutil -y -i socat curl wget "8080": "80"
copyback: false prepare: pkgutil -y -i socat curl wget
run: | run: |
cd ../acmetest \ cd ../acmetest \
&& ./letest.sh && ./letest.sh
+5 -10
View File
@@ -29,12 +29,12 @@ jobs:
CA_ECDSA: "" CA_ECDSA: ""
CA: "" CA: ""
CA_EMAIL: "" CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "LetsEncrypt.org_test" - TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: "" CA_ECDSA: ""
CA: "" CA: ""
CA_EMAIL: "" CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
ACME_USE_WGET: 1 ACME_USE_WGET: 1
- TEST_ACME_Server: "ZeroSSL.com" - TEST_ACME_Server: "ZeroSSL.com"
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
@@ -70,7 +70,7 @@ jobs:
TestingDomain: ${{ matrix.TestingDomain }} TestingDomain: ${{ matrix.TestingDomain }}
ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }} ACME_USE_WGET: ${{ matrix.ACME_USE_WGET }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install tools - name: Install tools
run: sudo apt-get install -y socat wget run: sudo apt-get install -y socat wget
- name: Start StepCA - name: Start StepCA
@@ -80,14 +80,9 @@ jobs:
-p 9000:9000 \ -p 9000:9000 \
-e "DOCKER_STEPCA_INIT_NAME=Smallstep" \ -e "DOCKER_STEPCA_INIT_NAME=Smallstep" \
-e "DOCKER_STEPCA_INIT_DNS_NAMES=localhost,$(hostname -f)" \ -e "DOCKER_STEPCA_INIT_DNS_NAMES=localhost,$(hostname -f)" \
-e "DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT=true" \
-e "DOCKER_STEPCA_INIT_PASSWORD=test" \
--name stepca \ --name stepca \
smallstep/step-ca:0.23.1 smallstep/step-ca \
&& sleep 5 && docker exec stepca step ca provisioner add acme --type ACME \
sleep 5
docker exec stepca bash -c "echo test >test" \
&& docker exec stepca step ca provisioner add acme --type ACME --admin-subject step --admin-password-file=/home/step/test \
&& docker exec stepca kill -1 1 \ && docker exec stepca kill -1 1 \
&& docker exec stepca cat /home/step/certs/root_ca.crt | sudo bash -c "cat - >>/etc/ssl/certs/ca-certificates.crt" && docker exec stepca cat /home/step/certs/root_ca.crt | sudo bash -c "cat - >>/etc/ssl/certs/ca-certificates.crt"
- name: Clone acmetest - name: Clone acmetest
+2 -2
View File
@@ -29,7 +29,7 @@ jobs:
CA_ECDSA: "" CA_ECDSA: ""
CA: "" CA: ""
CA_EMAIL: "" CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
#- TEST_ACME_Server: "ZeroSSL.com" #- TEST_ACME_Server: "ZeroSSL.com"
# CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA" # CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
# CA: "ZeroSSL RSA Domain Secure Site CA" # CA: "ZeroSSL RSA Domain Secure Site CA"
@@ -49,7 +49,7 @@ jobs:
- name: Set git to use LF - name: Set git to use LF
run: | run: |
git config --global core.autocrlf false git config --global core.autocrlf false
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install cygwin base packages with chocolatey - name: Install cygwin base packages with chocolatey
run: | run: |
choco config get cacheLocation choco config get cacheLocation
+5 -5
View File
@@ -28,9 +28,9 @@ jobs:
id: step_one id: step_one
run: | run: |
if [ "$DOCKER_PASSWORD" ] ; then if [ "$DOCKER_PASSWORD" ] ; then
echo "hasToken=true" >>$GITHUB_OUTPUT echo "::set-output name=hasToken::true"
else else
echo "hasToken=false" >>$GITHUB_OUTPUT echo "::set-output name=hasToken::false"
fi fi
- name: Check the value - name: Check the value
run: echo ${{ steps.step_one.outputs.hasToken }} run: echo ${{ steps.step_one.outputs.hasToken }}
@@ -41,11 +41,11 @@ jobs:
if: "contains(needs.CheckToken.outputs.hasToken, 'true')" if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
steps: steps:
- name: checkout code - name: checkout code
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v2 uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v1
- name: login to docker hub - name: login to docker hub
run: | run: |
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
+3 -3
View File
@@ -4,6 +4,8 @@ on:
pull_request_target: pull_request_target:
types: types:
- opened - opened
branches:
- 'dev'
paths: paths:
- 'dnsapi/*.sh' - 'dnsapi/*.sh'
@@ -20,11 +22,9 @@ jobs:
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
body: `**Welcome** body: `**Welcome**
First thing: don't send PR to the master branch, please send to the dev branch instead. Please make sure you're read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test).
Please make sure you've 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. Then reply on this message, otherwise, your code will not be reviewed or merged.
We look forward to reviewing your Pull request shortly ✨ We look forward to reviewing your Pull request shortly ✨
注意: 必须通过了 [DNS-API-Test](../wiki/DNS-API-Test) 才会被 review. 无论是修改, 还是新加的 dns api, 都必须确保通过这个测试.
` `
}) })
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
body: `**Welcome** body: `**Welcome**
Please make sure you've read our [Code-of-conduct](../wiki/Code-of-conduct) and add the usage here: [notify](../wiki/notify). 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. Then reply on this message, otherwise, your code will not be reviewed or merged.
We look forward to reviewing your Pull request shortly ✨ We look forward to reviewing your Pull request shortly ✨
` `
+2 -2
View File
@@ -22,7 +22,7 @@ jobs:
ShellCheck: ShellCheck:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install Shellcheck - name: Install Shellcheck
run: sudo apt-get install -y shellcheck run: sudo apt-get install -y shellcheck
- name: DoShellcheck - name: DoShellcheck
@@ -31,7 +31,7 @@ jobs:
shfmt: shfmt:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Install shfmt - name: Install shfmt
run: curl -sSL https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 -o ~/shfmt && chmod +x ~/shfmt run: curl -sSL https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 -o ~/shfmt && chmod +x ~/shfmt
- name: shfmt - name: shfmt
+7 -6
View File
@@ -1,4 +1,4 @@
FROM alpine:3.17 FROM alpine:3.16.3
RUN apk --no-cache add -f \ RUN apk --no-cache add -f \
openssl \ openssl \
@@ -12,8 +12,7 @@ RUN apk --no-cache add -f \
oath-toolkit-oathtool \ oath-toolkit-oathtool \
tar \ tar \
libidn \ libidn \
jq \ jq
cronie
ENV LE_CONFIG_HOME /acme.sh ENV LE_CONFIG_HOME /acme.sh
@@ -26,7 +25,7 @@ COPY ./ /install_acme.sh/
RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/ RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/
RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh && crontab -l | grep acme.sh | sed 's#> /dev/null#> /proc/1/fd/1 2>/proc/1/fd/2#' | crontab - RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh && crontab -l | grep acme.sh | sed 's#> /dev/null##' | crontab -
RUN for verb in help \ RUN for verb in help \
version \ version \
@@ -65,10 +64,12 @@ RUN for verb in help \
RUN printf "%b" '#!'"/usr/bin/env sh\n \ RUN printf "%b" '#!'"/usr/bin/env sh\n \
if [ \"\$1\" = \"daemon\" ]; then \n \ if [ \"\$1\" = \"daemon\" ]; then \n \
exec crond -n -s -m off \n \ trap \"echo stop && killall crond && exit 0\" SIGTERM SIGINT \n \
crond && sleep infinity &\n \
wait \n \
else \n \ else \n \
exec -- \"\$@\"\n \ exec -- \"\$@\"\n \
fi\n" >/entry.sh && chmod +x /entry.sh fi" >/entry.sh && chmod +x /entry.sh
VOLUME /acme.sh VOLUME /acme.sh
+28 -21
View File
@@ -8,7 +8,7 @@
[![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) [![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) [![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) [![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)
[![Omnios](https://github.com/acmesh-official/acme.sh/actions/workflows/Omnios.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Omnios.yml)
![Shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg) ![Shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg)
![PebbleStrict](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) ![PebbleStrict](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg)
@@ -51,12 +51,14 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
- [ruby-china.org](https://ruby-china.org/topics/31983) - [ruby-china.org](https://ruby-china.org/topics/31983)
- [Proxmox](https://pve.proxmox.com/wiki/Certificate_Management) - [Proxmox](https://pve.proxmox.com/wiki/Certificate_Management)
- [pfsense](https://github.com/pfsense/FreeBSD-ports/pull/89) - [pfsense](https://github.com/pfsense/FreeBSD-ports/pull/89)
- [webfaction](https://community.webfaction.com/questions/19988/using-letsencrypt)
- [Loadbalancer.org](https://www.loadbalancer.org/blog/loadbalancer-org-with-lets-encrypt-quick-and-dirty) - [Loadbalancer.org](https://www.loadbalancer.org/blog/loadbalancer-org-with-lets-encrypt-quick-and-dirty)
- [discourse.org](https://meta.discourse.org/t/setting-up-lets-encrypt/40709) - [discourse.org](https://meta.discourse.org/t/setting-up-lets-encrypt/40709)
- [Centminmod](https://centminmod.com/letsencrypt-acmetool-https.html) - [Centminmod](https://centminmod.com/letsencrypt-acmetool-https.html)
- [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297) - [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297)
- [archlinux](https://www.archlinux.org/packages/community/any/acme.sh)
- [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient) - [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient)
- [CentOS Web Panel](https://control-webpanel.com) - [CentOS Web Panel](http://centos-webpanel.com/)
- [lnmp.org](https://lnmp.org/) - [lnmp.org](https://lnmp.org/)
- [more...](https://github.com/acmesh-official/acme.sh/wiki/Blogs-and-tutorials) - [more...](https://github.com/acmesh-official/acme.sh/wiki/Blogs-and-tutorials)
@@ -73,21 +75,20 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
|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 |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 |8|[![NetBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/NetBSD.yml)|NetBSD
|9|[![DragonFlyBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/DragonFlyBSD.yml)|DragonFlyBSD |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|[![Omnios](https://github.com/acmesh-official/acme.sh/actions/workflows/Omnios.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Omnios.yml)|Omnios |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)| 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)|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)|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)|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)|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)|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)|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)|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)|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)|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|[![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|-----| 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|-----| 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)
|24|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management)
Check our [testing project](https://github.com/acmesh-official/acmetest): Check our [testing project](https://github.com/acmesh-official/acmetest):
@@ -360,6 +361,10 @@ Ok, it's done.
# 10. Issue ECC certificates # 10. Issue ECC certificates
`Let's Encrypt` can now issue **ECDSA** certificates.
And we support them too!
Just set the `keylength` parameter with a prefix `ec-`. Just set the `keylength` parameter with a prefix `ec-`.
For example: For example:
@@ -380,12 +385,10 @@ Please look at the `keylength` parameter above.
Valid values are: Valid values are:
1. **ec-256 (prime256v1, "ECDSA P-256", which is the default key type)** 1. **ec-256 (prime256v1, "ECDSA P-256")**
2. **ec-384 (secp384r1, "ECDSA P-384")** 2. **ec-384 (secp384r1, "ECDSA P-384")**
3. **ec-521 (secp521r1, "ECDSA P-521", which is not supported by Let's Encrypt yet.)** 3. **ec-521 (secp521r1, "ECDSA P-521", which is not supported by Let's Encrypt yet.)**
4. **2048 (RSA2048)**
5. **3072 (RSA3072)**
6. **4096 (RSA4096)**
# 11. Issue Wildcard certificates # 11. Issue Wildcard certificates
@@ -507,6 +510,10 @@ Support this project with your organization. Your logo will show up here with a
<a href="https://opencollective.com/acmesh/organization/9/website"><img src="https://opencollective.com/acmesh/organization/9/avatar.svg"></a> <a href="https://opencollective.com/acmesh/organization/9/website"><img src="https://opencollective.com/acmesh/organization/9/avatar.svg"></a>
#### Sponsors
[![quantumca-acmesh-logo](https://user-images.githubusercontent.com/8305679/183255712-634ee1db-bb61-4c03-bca0-bacce99e078c.svg)](https://www.quantumca.com.cn/?__utm_source=acmesh-donation)
# 19. License & Others # 19. License & Others
+492 -606
View File
File diff suppressed because it is too large. Load diff
-157
View File
@@ -1,157 +0,0 @@
#!/usr/bin/env sh
# Script to create certificate to Alibaba Cloud CDN
#
# This deployment required following variables
# export Ali_Key="ALIACCESSKEY"
# export Ali_Secret="ALISECRETKEY"
# export DEPLOY_ALI_CDN_DOMAIN="cdn.example.com"
# If you have more than one domain, just
# export DEPLOY_ALI_CDN_DOMAIN="cdn1.example.com cdn2.example.com"
#
# The credentials are shared with all domains, also shared with dns_ali api
Ali_API="https://cdn.aliyuncs.com/"
ali_cdn_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}"
Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}"
if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then
Ali_Key=""
Ali_Secret=""
_err "You don't specify aliyun api key and secret yet."
return 1
fi
#save the api key and secret to the account conf file.
_saveaccountconf_mutable Ali_Key "$Ali_Key"
_saveaccountconf_mutable Ali_Secret "$Ali_Secret"
_getdeployconf DEPLOY_ALI_CDN_DOMAIN
if [ "$DEPLOY_ALI_CDN_DOMAIN" ]; then
_savedeployconf DEPLOY_ALI_CDN_DOMAIN "$DEPLOY_ALI_CDN_DOMAIN"
else
DEPLOY_ALI_CDN_DOMAIN="$_cdomain"
fi
# read cert and key files and urlencode both
_cert=$(_url_encode_upper <"$_cfullchain")
_key=$(_url_encode_upper <"$_ckey")
_debug2 _cert "$_cert"
_debug2 _key "$_key"
## update domain ssl config
for domain in $DEPLOY_ALI_CDN_DOMAIN; do
_set_cdn_domain_ssl_certificate_query "$domain" "$_cert" "$_key"
if _ali_rest "Set CDN domain SSL certificate for $domain" "" POST; then
_info "Domain $domain certificate has been deployed successfully"
fi
done
return 0
}
#################### Private functions below ##################################
# act ign mtd
_ali_rest() {
act="$1"
ign="$2"
mtd="$3"
signature=$(printf "%s" "$mtd&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64)
signature=$(_ali_urlencode "$signature")
url="$Ali_API?$query&Signature=$signature"
if [ "$mtd" = "GET" ]; then
response="$(_get "$url")"
else
# post payload is not supported yet because of signature
response="$(_post "" "$url")"
fi
_ret="$?"
_debug2 response "$response"
if [ "$_ret" != "0" ]; then
_err "Error <$act>"
return 1
fi
if [ -z "$ign" ]; then
message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")"
if [ "$message" ]; then
_err "$message"
return 1
fi
fi
}
_ali_urlencode() {
_str="$1"
_str_len=${#_str}
_u_i=1
while [ "$_u_i" -le "$_str_len" ]; do
_str_c="$(printf "%s" "$_str" | cut -c "$_u_i")"
case $_str_c in [a-zA-Z0-9.~_-])
printf "%s" "$_str_c"
;;
*)
printf "%%%02X" "'$_str_c"
;;
esac
_u_i="$(_math "$_u_i" + 1)"
done
}
_ali_nonce() {
#_head_n 1 </dev/urandom | _digest "sha256" hex | cut -c 1-31
#Not so good...
date +"%s%N" | sed 's/%N//g'
}
_timestamp() {
date -u +"%Y-%m-%dT%H%%3A%M%%3A%SZ"
}
# stdin stdout
_url_encode_upper() {
encoded=$(_url_encode)
for match in $(echo "$encoded" | _egrep_o '%..' | sort -u); do
upper=$(echo "$match" | _upper_case)
encoded=$(echo "$encoded" | sed "s/$match/$upper/g")
done
echo "$encoded"
}
# domain pub pri
_set_cdn_domain_ssl_certificate_query() {
query=''
query=$query'AccessKeyId='$Ali_Key
query=$query'&Action=SetCdnDomainSSLCertificate'
query=$query'&CertType=upload'
query=$query'&DomainName='$1
query=$query'&Format=json'
query=$query'&SSLPri='$3
query=$query'&SSLProtocol=on'
query=$query'&SSLPub='$2
query=$query'&SignatureMethod=HMAC-SHA1'
query=$query"&SignatureNonce=$(_ali_nonce)"
query=$query'&SignatureVersion=1.0'
query=$query'&Timestamp='$(_timestamp)
query=$query'&Version=2018-05-10'
}
+8 -19
View File
@@ -273,27 +273,16 @@ _check_curl_version() {
_minor="$(_getfield "$_cversion" 2 '.')" _minor="$(_getfield "$_cversion" 2 '.')"
_debug2 "_minor" "$_minor" _debug2 "_minor" "$_minor"
if [ "$_major" -ge "8" ]; then if [ "$_major$_minor" -lt "740" ]; then
#ok
return 0
fi
if [ "$_major" = "7" ]; then
if [ "$_minor" -lt "40" ]; then
_err "curl v$_cversion doesn't support unit socket"
_err "Please upgrade to curl 7.40 or later."
return 1
fi
if [ "$_minor" -lt "50" ]; then
_debug "Use short host name"
export _CURL_NO_HOST=1
else
export _CURL_NO_HOST=
fi
return 0
else
_err "curl v$_cversion doesn't support unit socket" _err "curl v$_cversion doesn't support unit socket"
_err "Please upgrade to curl 7.40 or later." _err "Please upgrade to curl 7.40 or later."
return 1 return 1
fi fi
if [ "$_major$_minor" -lt "750" ]; then
_debug "Use short host name"
export _CURL_NO_HOST=1
else
export _CURL_NO_HOST=
fi
return 0
} }
+7 -8
View File
@@ -1,11 +1,10 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# Here is the script to deploy the cert to G-Core CDN service (https://gcore.com/) using the G-Core Labs API (https://apidocs.gcore.com/cdn). # Here is the script to deploy the cert to G-Core CDN service (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/).
# Returns 0 when success. # Returns 0 when success.
# #
# Written by temoffey <temofffey@gmail.com> # Written by temoffey <temofffey@gmail.com>
# Public domain, 2019 # Public domain, 2019
# Update by DreamOfIce <admin@dreamofice.cn> in 2023
#export DEPLOY_GCORE_CDN_USERNAME=myusername #export DEPLOY_GCORE_CDN_USERNAME=myusername
#export DEPLOY_GCORE_CDN_PASSWORD=mypassword #export DEPLOY_GCORE_CDN_PASSWORD=mypassword
@@ -57,7 +56,7 @@ gcore_cdn_deploy() {
_request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}" _request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}"
_debug _request "$_request" _debug _request "$_request"
export _H1="Content-Type:application/json" export _H1="Content-Type:application/json"
_response=$(_post "$_request" "https://api.gcore.com/auth/jwt/login") _response=$(_post "$_request" "https://api.gcdn.co/auth/jwt/login")
_debug _response "$_response" _debug _response "$_response"
_regex=".*\"access\":\"\([-._0-9A-Za-z]*\)\".*$" _regex=".*\"access\":\"\([-._0-9A-Za-z]*\)\".*$"
_debug _regex "$_regex" _debug _regex "$_regex"
@@ -70,8 +69,8 @@ gcore_cdn_deploy() {
fi fi
_info "Find CDN resource with cname $_cdomain" _info "Find CDN resource with cname $_cdomain"
export _H2="Authorization:Bearer $_token" export _H2="Authorization:Token $_token"
_response=$(_get "https://api.gcore.com/cdn/resources") _response=$(_get "https://api.gcdn.co/resources")
_debug _response "$_response" _debug _response "$_response"
_regex="\"primary_resource\":null}," _regex="\"primary_resource\":null},"
_debug _regex "$_regex" _debug _regex "$_regex"
@@ -103,7 +102,7 @@ gcore_cdn_deploy() {
_date=$(date "+%d.%m.%Y %H:%M:%S") _date=$(date "+%d.%m.%Y %H:%M:%S")
_request="{\"name\":\"$_cdomain ($_date)\",\"sslCertificate\":\"$_fullchain\",\"sslPrivateKey\":\"$_key\"}" _request="{\"name\":\"$_cdomain ($_date)\",\"sslCertificate\":\"$_fullchain\",\"sslPrivateKey\":\"$_key\"}"
_debug _request "$_request" _debug _request "$_request"
_response=$(_post "$_request" "https://api.gcore.com/cdn/sslData") _response=$(_post "$_request" "https://api.gcdn.co/sslData")
_debug _response "$_response" _debug _response "$_response"
_regex=".*\"id\":\([0-9]*\).*$" _regex=".*\"id\":\([0-9]*\).*$"
_debug _regex "$_regex" _debug _regex "$_regex"
@@ -118,7 +117,7 @@ gcore_cdn_deploy() {
_info "Update CDN resource" _info "Update CDN resource"
_request="{\"originGroup\":$_originGroup,\"sslData\":$_sslDataAdd}" _request="{\"originGroup\":$_originGroup,\"sslData\":$_sslDataAdd}"
_debug _request "$_request" _debug _request "$_request"
_response=$(_post "$_request" "https://api.gcore.com/cdn/resources/$_resourceId" '' "PUT") _response=$(_post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT")
_debug _response "$_response" _debug _response "$_response"
_regex=".*\"sslData\":\([0-9]*\).*$" _regex=".*\"sslData\":\([0-9]*\).*$"
_debug _regex "$_regex" _debug _regex "$_regex"
@@ -134,7 +133,7 @@ gcore_cdn_deploy() {
_info "Not found old SSL certificate" _info "Not found old SSL certificate"
else else
_info "Delete old SSL certificate" _info "Delete old SSL certificate"
_response=$(_post '' "https://api.gcore.com/cdn/sslData/$_sslDataOld" '' "DELETE") _response=$(_post '' "https://api.gcdn.co/sslData/$_sslDataOld" '' "DELETE")
_debug _response "$_response" _debug _response "$_response"
fi fi
+9 -132
View File
@@ -36,19 +36,6 @@
# Note: This functionality requires HAProxy was compiled against # Note: This functionality requires HAProxy was compiled against
# a version of OpenSSL that supports this. # a version of OpenSSL that supports this.
# #
# export DEPLOY_HAPROXY_HOT_UPDATE="yes"
# export DEPLOY_HAPROXY_STATS_SOCKET="UNIX:/run/haproxy/admin.sock"
#
# OPTIONAL: Deploy the certificate over the HAProxy stats socket without
# needing to reload HAProxy. Default is "no".
#
# Require the socat binary. DEPLOY_HAPROXY_STATS_SOCKET variable uses the socat
# address format.
#
# export DEPLOY_HAPROXY_MASTER_CLI="UNIX:/run/haproxy-master.sock"
#
# OPTIONAL: To use the master CLI with DEPLOY_HAPROXY_HOT_UPDATE="yes" instead
# of a stats socket, use this variable.
######## Public functions ##################### ######## Public functions #####################
@@ -59,7 +46,6 @@ haproxy_deploy() {
_ccert="$3" _ccert="$3"
_cca="$4" _cca="$4"
_cfullchain="$5" _cfullchain="$5"
_cmdpfx=""
# Some defaults # Some defaults
DEPLOY_HAPROXY_PEM_PATH_DEFAULT="/etc/haproxy" DEPLOY_HAPROXY_PEM_PATH_DEFAULT="/etc/haproxy"
@@ -67,8 +53,6 @@ haproxy_deploy() {
DEPLOY_HAPROXY_BUNDLE_DEFAULT="no" DEPLOY_HAPROXY_BUNDLE_DEFAULT="no"
DEPLOY_HAPROXY_ISSUER_DEFAULT="no" DEPLOY_HAPROXY_ISSUER_DEFAULT="no"
DEPLOY_HAPROXY_RELOAD_DEFAULT="true" DEPLOY_HAPROXY_RELOAD_DEFAULT="true"
DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT="no"
DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT="UNIX:/run/haproxy/admin.sock"
_debug _cdomain "${_cdomain}" _debug _cdomain "${_cdomain}"
_debug _ckey "${_ckey}" _debug _ckey "${_ckey}"
@@ -102,11 +86,6 @@ haproxy_deploy() {
_savedomainconf Le_Deploy_haproxy_pem_name "${Le_Deploy_haproxy_pem_name}" _savedomainconf Le_Deploy_haproxy_pem_name "${Le_Deploy_haproxy_pem_name}"
elif [ -z "${Le_Deploy_haproxy_pem_name}" ]; then elif [ -z "${Le_Deploy_haproxy_pem_name}" ]; then
Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}" Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}"
# We better not have '*' as the first character
if [ "${Le_Deploy_haproxy_pem_name%%"${Le_Deploy_haproxy_pem_name#?}"}" = '*' ]; then
# removes the first characters and add a _ instead
Le_Deploy_haproxy_pem_name="_${Le_Deploy_haproxy_pem_name#?}"
fi
fi fi
# BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}" # BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}"
@@ -139,36 +118,6 @@ haproxy_deploy() {
Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD_DEFAULT}" Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD_DEFAULT}"
fi fi
# HOT_UPDATE is optional. If not provided then assume "${DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT}"
_getdeployconf DEPLOY_HAPROXY_HOT_UPDATE
_debug2 DEPLOY_HAPROXY_HOT_UPDATE "${DEPLOY_HAPROXY_HOT_UPDATE}"
if [ -n "${DEPLOY_HAPROXY_HOT_UPDATE}" ]; then
Le_Deploy_haproxy_hot_update="${DEPLOY_HAPROXY_HOT_UPDATE}"
_savedomainconf Le_Deploy_haproxy_hot_update "${Le_Deploy_haproxy_hot_update}"
elif [ -z "${Le_Deploy_haproxy_hot_update}" ]; then
Le_Deploy_haproxy_hot_update="${DEPLOY_HAPROXY_HOT_UPDATE_DEFAULT}"
fi
# STATS_SOCKET is optional. If not provided then assume "${DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT}"
_getdeployconf DEPLOY_HAPROXY_STATS_SOCKET
_debug2 DEPLOY_HAPROXY_STATS_SOCKET "${DEPLOY_HAPROXY_STATS_SOCKET}"
if [ -n "${DEPLOY_HAPROXY_STATS_SOCKET}" ]; then
Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_STATS_SOCKET}"
_savedomainconf Le_Deploy_haproxy_stats_socket "${Le_Deploy_haproxy_stats_socket}"
elif [ -z "${Le_Deploy_haproxy_stats_socket}" ]; then
Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_STATS_SOCKET_DEFAULT}"
fi
# MASTER_CLI is optional. No defaults are used. When the master CLI is used,
# all commands are sent with a prefix.
_getdeployconf DEPLOY_HAPROXY_MASTER_CLI
_debug2 DEPLOY_HAPROXY_MASTER_CLI "${DEPLOY_HAPROXY_MASTER_CLI}"
if [ -n "${DEPLOY_HAPROXY_MASTER_CLI}" ]; then
Le_Deploy_haproxy_stats_socket="${DEPLOY_HAPROXY_MASTER_CLI}"
_savedomainconf Le_Deploy_haproxy_stats_socket "${Le_Deploy_haproxy_stats_socket}"
_cmdpfx="@1 " # command prefix used for master CLI only.
fi
# Set the suffix depending if we are creating a bundle or not # Set the suffix depending if we are creating a bundle or not
if [ "${Le_Deploy_haproxy_bundle}" = "yes" ]; then if [ "${Le_Deploy_haproxy_bundle}" = "yes" ]; then
_info "Bundle creation requested" _info "Bundle creation requested"
@@ -193,13 +142,12 @@ haproxy_deploy() {
_issuer="${_pem}.issuer" _issuer="${_pem}.issuer"
_ocsp="${_pem}.ocsp" _ocsp="${_pem}.ocsp"
_reload="${Le_Deploy_haproxy_reload}" _reload="${Le_Deploy_haproxy_reload}"
_statssock="${Le_Deploy_haproxy_stats_socket}"
_info "Deploying PEM file" _info "Deploying PEM file"
# Create a temporary PEM file # Create a temporary PEM file
_temppem="$(_mktemp)" _temppem="$(_mktemp)"
_debug _temppem "${_temppem}" _debug _temppem "${_temppem}"
cat "${_ccert}" "${_cca}" "${_ckey}" | grep . >"${_temppem}" cat "${_ckey}" "${_ccert}" "${_cca}" >"${_temppem}"
_ret="$?" _ret="$?"
# Check that we could create the temporary file # Check that we could create the temporary file
@@ -317,86 +265,15 @@ haproxy_deploy() {
fi fi
fi fi
if [ "${Le_Deploy_haproxy_hot_update}" = "yes" ]; then # Reload HAProxy
# set the socket name for messages _debug _reload "${_reload}"
if [ -n "${_cmdpfx}" ]; then eval "${_reload}"
_socketname="master CLI" _ret=$?
else if [ "${_ret}" != "0" ]; then
_socketname="stats socket" _err "Error code ${_ret} during reload"
fi return ${_ret}
# Update certificate over HAProxy stats socket or master CLI.
if _exists socat; then
# look for the certificate on the stats socket, to chose between updating or creating one
_socat_cert_cmd="echo '${_cmdpfx}show ssl cert' | socat '${_statssock}' - | grep -q '^${_pem}$'"
_debug _socat_cert_cmd "${_socat_cert_cmd}"
eval "${_socat_cert_cmd}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_newcert="1"
_info "Creating new certificate '${_pem}' over HAProxy ${_socketname}."
# certificate wasn't found, it's a new one. We should check if the crt-list exists and creates/inserts the certificate.
_socat_crtlist_show_cmd="echo '${_cmdpfx}show ssl crt-list' | socat '${_statssock}' - | grep -q '^${Le_Deploy_haproxy_pem_path}$'"
_debug _socat_crtlist_show_cmd "${_socat_crtlist_show_cmd}"
eval "${_socat_crtlist_show_cmd}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_err "Couldn't find '${Le_Deploy_haproxy_pem_path}' in haproxy 'show ssl crt-list'"
return "${_ret}"
fi
# create a new certificate
_socat_new_cmd="echo '${_cmdpfx}new ssl cert ${_pem}' | socat '${_statssock}' - | grep -q 'New empty'"
_debug _socat_new_cmd "${_socat_new_cmd}"
eval "${_socat_new_cmd}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_err "Couldn't create '${_pem}' in haproxy"
return "${_ret}"
fi
else
_info "Update existing certificate '${_pem}' over HAProxy ${_socketname}."
fi
_socat_cert_set_cmd="echo -e '${_cmdpfx}set ssl cert ${_pem} <<\n$(cat "${_pem}")\n' | socat '${_statssock}' - | grep -q 'Transaction created'"
_debug _socat_cert_set_cmd "${_socat_cert_set_cmd}"
eval "${_socat_cert_set_cmd}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_err "Can't update '${_pem}' in haproxy"
return "${_ret}"
fi
_socat_cert_commit_cmd="echo '${_cmdpfx}commit ssl cert ${_pem}' | socat '${_statssock}' - | grep -q '^Success!$'"
_debug _socat_cert_commit_cmd "${_socat_cert_commit_cmd}"
eval "${_socat_cert_commit_cmd}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_err "Can't commit '${_pem}' in haproxy"
return ${_ret}
fi
if [ "${_newcert}" = "1" ]; then
# if this is a new certificate, it needs to be inserted into the crt-list`
_socat_cert_add_cmd="echo '${_cmdpfx}add ssl crt-list ${Le_Deploy_haproxy_pem_path} ${_pem}' | socat '${_statssock}' - | grep -q 'Success!'"
_debug _socat_cert_add_cmd "${_socat_cert_add_cmd}"
eval "${_socat_cert_add_cmd}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_err "Can't update '${_pem}' in haproxy"
return "${_ret}"
fi
fi
else
_err "'socat' is not available, couldn't update over ${_socketname}"
fi
else else
# Reload HAProxy _info "Reload successful"
_debug _reload "${_reload}"
eval "${_reload}"
_ret=$?
if [ "${_ret}" != "0" ]; then
_err "Error code ${_ret} during reload"
return ${_ret}
else
_info "Reload successful"
fi
fi fi
return 0 return 0
+44 -139
View File
@@ -7,18 +7,11 @@
# #
# Firewall admin with superuser and IP address is required. # Firewall admin with superuser and IP address is required.
# #
# REQURED: # export PANOS_USER="" # required
# export PANOS_HOST="" # export PANOS_PASS="" # required
# export PANOS_USER="" #User *MUST* have Commit and Import Permissions in XML API for Admin Role # export PANOS_HOST="" # required
# export PANOS_PASS=""
#
# OPTIONAL
# export PANOS_TEMPLATE="" #Template Name of panorama managed devices
#
# The script will automatically generate a new API key if
# no key is found, or if a saved key has expired or is invalid.
# This function is to parse the XML response from the firewall # This function is to parse the XML
parse_response() { parse_response() {
type=$2 type=$2
if [ "$type" = 'keygen' ]; then if [ "$type" = 'keygen' ]; then
@@ -30,46 +23,25 @@ parse_response() {
message="PAN-OS Key could not be set." message="PAN-OS Key could not be set."
fi fi
else else
status=$(echo "$1" | tr -d '\n' | sed 's/^.*"\([a-z]*\)".*/\1/g') status=$(echo "$1" | sed 's/^.*"\([a-z]*\)".*/\1/g')
message=$(echo "$1" | tr -d '\n' | sed 's/.*\(<result>\|<msg>\|<line>\)\([^<]*\).*/\2/g') message=$(echo "$1" | sed 's/^.*<result>\(.*\)<\/result.*/\1/g')
_debug "Firewall message: $message"
if [ "$type" = 'keytest' ] && [ "$status" != "success" ]; then
_debug "**** API Key has EXPIRED or is INVALID ****"
unset _panos_key
fi
fi fi
return 0 return 0
} }
#This function is used to deploy to the firewall
deployer() { deployer() {
content="" content=""
type=$1 # Types are keytest, keygen, cert, key, commit type=$1 # Types are keygen, cert, key, commit
_debug "**** Deploying $type *****"
panos_url="https://$_panos_host/api/" panos_url="https://$_panos_host/api/"
#Test API Key by performing a lookup
if [ "$type" = 'keytest' ]; then
_debug "**** Testing saved API Key ****"
_H1="Content-Type: application/x-www-form-urlencoded"
# Get Version Info to test key
content="type=version&key=$_panos_key"
## Exclude all scopes for the empty commit
#_exclude_scope="<policy-and-objects>exclude</policy-and-objects><device-and-network>exclude</device-and-network><shared-object>exclude</shared-object>"
#content="type=commit&action=partial&key=$_panos_key&cmd=<commit><partial>$_exclude_scope<admin><member>acmekeytest</member></admin></partial></commit>"
fi
# Generate API Key
if [ "$type" = 'keygen' ]; then if [ "$type" = 'keygen' ]; then
_debug "**** Generating new API Key ****"
_H1="Content-Type: application/x-www-form-urlencoded" _H1="Content-Type: application/x-www-form-urlencoded"
content="type=keygen&user=$_panos_user&password=$_panos_pass" content="type=keygen&user=$_panos_user&password=$_panos_pass"
# content="$content${nl}--$delim${nl}Content-Disposition: form-data; type=\"keygen\"; user=\"$_panos_user\"; password=\"$_panos_pass\"${nl}Content-Type: application/octet-stream${nl}${nl}" # content="$content${nl}--$delim${nl}Content-Disposition: form-data; type=\"keygen\"; user=\"$_panos_user\"; password=\"$_panos_pass\"${nl}Content-Type: application/octet-stream${nl}${nl}"
fi fi
# Deploy Cert or Key
if [ "$type" = 'cert' ] || [ "$type" = 'key' ]; then if [ "$type" = 'cert' ] || [ "$type" = 'key' ]; then
_debug "**** Deploying $type ****" #Generate DEIM
#Generate DELIM
delim="-----MultipartDelimiter$(date "+%s%N")" delim="-----MultipartDelimiter$(date "+%s%N")"
nl="\015\012" nl="\015\012"
#Set Header #Set Header
@@ -81,9 +53,6 @@ deployer() {
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")"
if [ "$_panos_template" ]; then
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n$_panos_template"
fi
fi fi
if [ "$type" = 'key' ]; then if [ "$type" = 'key' ]; then
panos_url="${panos_url}?type=import" panos_url="${panos_url}?type=import"
@@ -92,10 +61,7 @@ deployer() {
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n123456" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n123456"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cdomain.key")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")"
if [ "$_panos_template" ]; then
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n$_panos_template"
fi
fi fi
#Close multipart #Close multipart
content="$content${nl}--$delim--${nl}${nl}" content="$content${nl}--$delim--${nl}${nl}"
@@ -103,25 +69,16 @@ deployer() {
content=$(printf %b "$content") content=$(printf %b "$content")
fi fi
# Commit changes
if [ "$type" = 'commit' ]; then if [ "$type" = 'commit' ]; then
_debug "**** Committing changes ****"
export _H1="Content-Type: application/x-www-form-urlencoded" export _H1="Content-Type: application/x-www-form-urlencoded"
#Check for force commit - will commit ALL uncommited changes to the firewall. Use with caution! cmd=$(printf "%s" "<commit><partial><$_panos_user></$_panos_user></partial></commit>" | _url_encode)
if [ "$FORCE" ]; then content="type=commit&key=$_panos_key&cmd=$cmd"
_debug "Force switch detected. Committing ALL changes to the firewall."
cmd=$(printf "%s" "<commit><partial><force><admin><member>$_panos_user</member></admin></force></partial></commit>" | _url_encode)
else
_exclude_scope="<policy-and-objects>exclude</policy-and-objects><device-and-network>exclude</device-and-network>"
cmd=$(printf "%s" "<commit><partial>$_exclude_scope<admin><member>$_panos_user</member></admin></partial></commit>" | _url_encode)
fi
content="type=commit&action=partial&key=$_panos_key&cmd=$cmd"
fi fi
response=$(_post "$content" "$panos_url" "" "POST") response=$(_post "$content" "$panos_url" "" "POST")
parse_response "$response" "$type" parse_response "$response" "$type"
# Saving response to variables # Saving response to variables
response_status=$status response_status=$status
#DEBUG
_debug response_status "$response_status" _debug response_status "$response_status"
if [ "$response_status" = "success" ]; then if [ "$response_status" = "success" ]; then
_debug "Successfully deployed $type" _debug "Successfully deployed $type"
@@ -135,95 +92,43 @@ deployer() {
# This is the main function that will call the other functions to deploy everything. # This is the main function that will call the other functions to deploy everything.
panos_deploy() { panos_deploy() {
_cdomain=$(echo "$1" | sed 's/*/WILDCARD_/g') #Wildcard Safe Filename _cdomain="$1"
_ckey="$2" _ckey="$2"
_cfullchain="$5" _cfullchain="$5"
# PANOS ENV VAR check
# VALID FILE CHECK if [ -z "$PANOS_USER" ] || [ -z "$PANOS_PASS" ] || [ -z "$PANOS_HOST" ]; then
if [ ! -f "$_ckey" ] || [ ! -f "$_cfullchain" ]; then _debug "No ENV variables found lets check for saved variables"
_err "Unable to find a valid key and/or cert. If this is an ECDSA/ECC cert, use the --ecc flag when deploying."
return 1
fi
# PANOS_HOST
if [ "$PANOS_HOST" ]; then
_debug "Detected ENV variable PANOS_HOST. Saving to file."
_savedeployconf PANOS_HOST "$PANOS_HOST" 1
else
_debug "Attempting to load variable PANOS_HOST from file."
_getdeployconf PANOS_HOST
fi
# PANOS USER
if [ "$PANOS_USER" ]; then
_debug "Detected ENV variable PANOS_USER. Saving to file."
_savedeployconf PANOS_USER "$PANOS_USER" 1
else
_debug "Attempting to load variable PANOS_USER from file."
_getdeployconf PANOS_USER _getdeployconf PANOS_USER
fi
# PANOS_PASS
if [ "$PANOS_PASS" ]; then
_debug "Detected ENV variable PANOS_PASS. Saving to file."
_savedeployconf PANOS_PASS "$PANOS_PASS" 1
else
_debug "Attempting to load variable PANOS_PASS from file."
_getdeployconf PANOS_PASS _getdeployconf PANOS_PASS
fi _getdeployconf PANOS_HOST
_panos_user=$PANOS_USER
# PANOS_KEY _panos_pass=$PANOS_PASS
_getdeployconf PANOS_KEY _panos_host=$PANOS_HOST
if [ "$PANOS_KEY" ]; then if [ -z "$_panos_user" ] && [ -z "$_panos_pass" ] && [ -z "$_panos_host" ]; then
_debug "Detected saved key." _err "No host, user and pass found.. If this is the first time deploying please set PANOS_HOST, PANOS_USER and PANOS_PASS in environment variables. Delete them after you have succesfully deployed certs."
_panos_key=$PANOS_KEY return 1
else else
_debug "No key detected" _debug "Using saved env variables."
unset _panos_key
fi
# PANOS_TEMPLATE
if [ "$PANOS_TEMPLATE" ]; then
_debug "Detected ENV variable PANOS_TEMPLATE. Saving to file."
_savedeployconf PANOS_TEMPLATE "$PANOS_TEMPLATE" 1
else
_debug "Attempting to load variable PANOS_TEMPLATE from file."
_getdeployconf PANOS_TEMPLATE
fi
#Store variables
_panos_host=$PANOS_HOST
_panos_user=$PANOS_USER
_panos_pass=$PANOS_PASS
_panos_template=$PANOS_TEMPLATE
#Test API Key if found. If the key is invalid, the variable _panos_key will be unset.
if [ "$_panos_host" ] && [ "$_panos_key" ]; then
_debug "**** Testing API KEY ****"
deployer keytest
fi
# Check for valid variables
if [ -z "$_panos_host" ]; then
_err "No host found. If this is your first time deploying, please set PANOS_HOST in ENV variables. You can delete it after you have successfully deployed the certs."
return 1
elif [ -z "$_panos_user" ]; then
_err "No user found. If this is your first time deploying, please set PANOS_USER in ENV variables. You can delete it after you have successfully deployed the certs."
return 1
elif [ -z "$_panos_pass" ]; then
_err "No password found. If this is your first time deploying, please set PANOS_PASS in ENV variables. You can delete it after you have successfully deployed the certs."
return 1
else
# Generate a new API key if no valid API key is found
if [ -z "$_panos_key" ]; then
_debug "**** Generating new PANOS API KEY ****"
deployer keygen
_savedeployconf PANOS_KEY "$_panos_key" 1
fi fi
else
# Confirm that a valid key was generated _debug "Detected ENV variables to be saved to the deploy conf."
# Encrypt and save user
_savedeployconf PANOS_USER "$PANOS_USER" 1
_savedeployconf PANOS_PASS "$PANOS_PASS" 1
_savedeployconf PANOS_HOST "$PANOS_HOST" 1
_panos_user="$PANOS_USER"
_panos_pass="$PANOS_PASS"
_panos_host="$PANOS_HOST"
fi
_debug "Let's use username and pass to generate token."
if [ -z "$_panos_user" ] || [ -z "$_panos_pass" ] || [ -z "$_panos_host" ]; then
_err "Please pass username and password and host as env variables PANOS_USER, PANOS_PASS and PANOS_HOST"
return 1
else
_debug "Getting PANOS KEY"
deployer keygen
if [ -z "$_panos_key" ]; then if [ -z "$_panos_key" ]; then
_err "Unable to generate an API key. The user and pass may be invalid or not authorized to generate a new key. Please check the PANOS_USER and PANOS_PASS credentials and try again" _err "Missing apikey."
return 1 return 1
else else
deployer cert deployer cert
+4 -4
View File
@@ -99,11 +99,11 @@ proxmoxve_deploy() {
_proxmoxve_api_token_key="$DEPLOY_PROXMOXVE_API_TOKEN_KEY" _proxmoxve_api_token_key="$DEPLOY_PROXMOXVE_API_TOKEN_KEY"
_savedeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY "$DEPLOY_PROXMOXVE_API_TOKEN_KEY" _savedeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY "$DEPLOY_PROXMOXVE_API_TOKEN_KEY"
fi fi
_debug2 DEPLOY_PROXMOXVE_API_TOKEN_KEY "$_proxmoxve_api_token_key" _debug2 DEPLOY_PROXMOXVE_API_TOKEN_KEY _proxmoxve_api_token_key
# PVE API Token header value. Used in "Authorization: PVEAPIToken". # PVE API Token header value. Used in "Authorization: PVEAPIToken".
_proxmoxve_header_api_token="${_proxmoxve_user}@${_proxmoxve_user_realm}!${_proxmoxve_api_token_name}=${_proxmoxve_api_token_key}" _proxmoxve_header_api_token="${_proxmoxve_user}@${_proxmoxve_user_realm}!${_proxmoxve_api_token_name}=${_proxmoxve_api_token_key}"
_debug2 "Auth Header" "$_proxmoxve_header_api_token" _debug2 "Auth Header" _proxmoxve_header_api_token
# Ugly. I hate putting heredocs inside functions because heredocs don't # Ugly. I hate putting heredocs inside functions because heredocs don't
# account for whitespace correctly but it _does_ work and is several times # account for whitespace correctly but it _does_ work and is several times
@@ -124,8 +124,8 @@ HEREDOC
) )
_debug2 Payload "$_json_payload" _debug2 Payload "$_json_payload"
_info "Push certificates to server" # Push certificates to server.
export HTTPS_INSECURE=1 export _HTTPS_INSECURE=1
export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}" export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}"
_post "$_json_payload" "$_target_url" "" POST "application/json" _post "$_json_payload" "$_target_url" "" POST "application/json"
+5 -6
View File
@@ -137,8 +137,7 @@ routeros_deploy() {
return $_err_code return $_err_code
fi fi
DEPLOY_SCRIPT_CMD=":do {/system script remove \"LECertDeploy-$_cdomain\" } on-error={ }; \ DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=$ROUTER_OS_USERNAME \
/system script add name=\"LECertDeploy-$_cdomain\" owner=$ROUTER_OS_USERNAME \
comment=\"generated by routeros deploy script in acme.sh\" \ comment=\"generated by routeros deploy script in acme.sh\" \
source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\
\n/certificate remove [ find name=$_cdomain.cer_1 ];\ \n/certificate remove [ find name=$_cdomain.cer_1 ];\
@@ -147,8 +146,8 @@ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\
\n/certificate import file-name=$_cdomain.cer passphrase=\\\"\\\";\ \n/certificate import file-name=$_cdomain.cer passphrase=\\\"\\\";\
\n/certificate import file-name=$_cdomain.key passphrase=\\\"\\\";\ \n/certificate import file-name=$_cdomain.key passphrase=\\\"\\\";\
\ndelay 1;\ \ndelay 1;\
\n:do {/file remove $_cdomain.cer; } on-error={ }\ \n/file remove $_cdomain.cer;\
\n:do {/file remove $_cdomain.key; } on-error={ }\ \n/file remove $_cdomain.key;\
\ndelay 2;\ \ndelay 2;\
\n/ip service set www-ssl certificate=$_cdomain.cer_0;\ \n/ip service set www-ssl certificate=$_cdomain.cer_0;\
\n$ROUTER_OS_ADDITIONAL_SERVICES;\ \n$ROUTER_OS_ADDITIONAL_SERVICES;\
@@ -159,11 +158,11 @@ source=\"/certificate remove [ find name=$_cdomain.cer_0 ];\
return $_err_code return $_err_code
fi fi
if ! _ssh_remote_cmd "/system script run \"LECertDeploy-$_cdomain\""; then if ! _ssh_remote_cmd "/system script run \"LE Cert Deploy - $_cdomain\""; then
return $_err_code return $_err_code
fi fi
if ! _ssh_remote_cmd "/system script remove \"LECertDeploy-$_cdomain\""; then if ! _ssh_remote_cmd "/system script remove \"LE Cert Deploy - $_cdomain\""; then
return $_err_code return $_err_code
fi fi
+125 -284
View File
@@ -14,7 +14,7 @@
# The following examples are for QNAP NAS running QTS 4.2 # The following examples are for QNAP NAS running QTS 4.2
# export DEPLOY_SSH_CMD="" # defaults to "ssh -T" # export DEPLOY_SSH_CMD="" # defaults to "ssh -T"
# export DEPLOY_SSH_USER="admin" # required # export DEPLOY_SSH_USER="admin" # required
# export DEPLOY_SSH_SERVER="host1 host2:8022 192.168.0.1:9022" # defaults to domain name, support multiple servers with optional port # export DEPLOY_SSH_SERVER="qnap" # defaults to domain name
# export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem" # export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem"
# export DEPLOY_SSH_CERTFILE="/etc/stunnel/stunnel.pem" # export DEPLOY_SSH_CERTFILE="/etc/stunnel/stunnel.pem"
# export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem" # export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem"
@@ -23,8 +23,6 @@
# export DEPLOY_SSH_BACKUP="" # yes or no, default to yes or previously saved value # export DEPLOY_SSH_BACKUP="" # yes or no, default to yes or previously saved value
# export DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" # path on remote system. Defaults to .acme_ssh_deploy # export DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" # path on remote system. Defaults to .acme_ssh_deploy
# export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value # export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value
# export DEPLOY_SSH_USE_SCP="" yes or no, default to no
# export DEPLOY_SSH_SCP_CMD="" defaults to "scp -q"
# #
######## Public functions ##################### ######## Public functions #####################
@@ -44,134 +42,72 @@ ssh_deploy() {
_debug _cfullchain "$_cfullchain" _debug _cfullchain "$_cfullchain"
# USER is required to login by SSH to remote host. # USER is required to login by SSH to remote host.
_migratedeployconf Le_Deploy_ssh_user DEPLOY_SSH_USER
_getdeployconf DEPLOY_SSH_USER _getdeployconf DEPLOY_SSH_USER
_debug2 DEPLOY_SSH_USER "$DEPLOY_SSH_USER" _debug2 DEPLOY_SSH_USER "$DEPLOY_SSH_USER"
if [ -z "$DEPLOY_SSH_USER" ]; then if [ -z "$DEPLOY_SSH_USER" ]; then
_err "DEPLOY_SSH_USER not defined." if [ -z "$Le_Deploy_ssh_user" ]; then
return 1 _err "DEPLOY_SSH_USER not defined."
return 1
fi
else
Le_Deploy_ssh_user="$DEPLOY_SSH_USER"
_savedomainconf Le_Deploy_ssh_user "$Le_Deploy_ssh_user"
fi fi
_savedeployconf DEPLOY_SSH_USER "$DEPLOY_SSH_USER"
# SERVER is optional. If not provided then use _cdomain # SERVER is optional. If not provided then use _cdomain
_migratedeployconf Le_Deploy_ssh_server DEPLOY_SSH_SERVER
_getdeployconf DEPLOY_SSH_SERVER _getdeployconf DEPLOY_SSH_SERVER
_debug2 DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER" _debug2 DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER"
if [ -z "$DEPLOY_SSH_SERVER" ]; then if [ -n "$DEPLOY_SSH_SERVER" ]; then
DEPLOY_SSH_SERVER="$_cdomain" Le_Deploy_ssh_server="$DEPLOY_SSH_SERVER"
_savedomainconf Le_Deploy_ssh_server "$Le_Deploy_ssh_server"
elif [ -z "$Le_Deploy_ssh_server" ]; then
Le_Deploy_ssh_server="$_cdomain"
fi fi
_savedeployconf DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER"
# CMD is optional. If not provided then use ssh # CMD is optional. If not provided then use ssh
_migratedeployconf Le_Deploy_ssh_cmd DEPLOY_SSH_CMD
_getdeployconf DEPLOY_SSH_CMD _getdeployconf DEPLOY_SSH_CMD
_debug2 DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD" _debug2 DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD"
if [ -z "$DEPLOY_SSH_CMD" ]; then if [ -n "$DEPLOY_SSH_CMD" ]; then
DEPLOY_SSH_CMD="ssh -T" Le_Deploy_ssh_cmd="$DEPLOY_SSH_CMD"
_savedomainconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd"
elif [ -z "$Le_Deploy_ssh_cmd" ]; then
Le_Deploy_ssh_cmd="ssh -T"
fi fi
_savedeployconf DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD"
# BACKUP is optional. If not provided then default to previously saved value or yes. # BACKUP is optional. If not provided then default to previously saved value or yes.
_migratedeployconf Le_Deploy_ssh_backup DEPLOY_SSH_BACKUP
_getdeployconf DEPLOY_SSH_BACKUP _getdeployconf DEPLOY_SSH_BACKUP
_debug2 DEPLOY_SSH_BACKUP "$DEPLOY_SSH_BACKUP" _debug2 DEPLOY_SSH_BACKUP "$DEPLOY_SSH_BACKUP"
if [ -z "$DEPLOY_SSH_BACKUP" ]; then if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then
DEPLOY_SSH_BACKUP="yes" Le_Deploy_ssh_backup="no"
elif [ -z "$Le_Deploy_ssh_backup" ] || [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
Le_Deploy_ssh_backup="yes"
fi fi
_savedeployconf DEPLOY_SSH_BACKUP "$DEPLOY_SSH_BACKUP" _savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup"
# BACKUP_PATH is optional. If not provided then default to previously saved value or .acme_ssh_deploy # BACKUP_PATH is optional. If not provided then default to previously saved value or .acme_ssh_deploy
_migratedeployconf Le_Deploy_ssh_backup_path DEPLOY_SSH_BACKUP_PATH
_getdeployconf DEPLOY_SSH_BACKUP_PATH _getdeployconf DEPLOY_SSH_BACKUP_PATH
_debug2 DEPLOY_SSH_BACKUP_PATH "$DEPLOY_SSH_BACKUP_PATH" _debug2 DEPLOY_SSH_BACKUP_PATH "$DEPLOY_SSH_BACKUP_PATH"
if [ -z "$DEPLOY_SSH_BACKUP_PATH" ]; then if [ -n "$DEPLOY_SSH_BACKUP_PATH" ]; then
DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" Le_Deploy_ssh_backup_path="$DEPLOY_SSH_BACKUP_PATH"
elif [ -z "$Le_Deploy_ssh_backup_path" ]; then
Le_Deploy_ssh_backup_path=".acme_ssh_deploy"
fi fi
_savedeployconf DEPLOY_SSH_BACKUP_PATH "$DEPLOY_SSH_BACKUP_PATH" _savedomainconf Le_Deploy_ssh_backup_path "$Le_Deploy_ssh_backup_path"
# MULTI_CALL is optional. If not provided then default to previously saved # MULTI_CALL is optional. If not provided then default to previously saved
# value (which may be undefined... equivalent to "no"). # value (which may be undefined... equivalent to "no").
_migratedeployconf Le_Deploy_ssh_multi_call DEPLOY_SSH_MULTI_CALL
_getdeployconf DEPLOY_SSH_MULTI_CALL _getdeployconf DEPLOY_SSH_MULTI_CALL
_debug2 DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL" _debug2 DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL"
if [ -z "$DEPLOY_SSH_MULTI_CALL" ]; then if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
DEPLOY_SSH_MULTI_CALL="no" Le_Deploy_ssh_multi_call="yes"
fi _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call"
_savedeployconf DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL" elif [ "$DEPLOY_SSH_MULTI_CALL" = "no" ]; then
Le_Deploy_ssh_multi_call=""
# KEYFILE is optional. _cleardomainconf Le_Deploy_ssh_multi_call
# If provided then private key will be copied to provided filename.
_migratedeployconf Le_Deploy_ssh_keyfile DEPLOY_SSH_KEYFILE
_getdeployconf DEPLOY_SSH_KEYFILE
_debug2 DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE"
if [ -n "$DEPLOY_SSH_KEYFILE" ]; then
_savedeployconf DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE"
fi fi
# CERTFILE is optional. _deploy_ssh_servers=$Le_Deploy_ssh_server
# If provided then certificate will be copied or appended to provided filename. for Le_Deploy_ssh_server in $_deploy_ssh_servers; do
_migratedeployconf Le_Deploy_ssh_certfile DEPLOY_SSH_CERTFILE
_getdeployconf DEPLOY_SSH_CERTFILE
_debug2 DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE"
if [ -n "$DEPLOY_SSH_CERTFILE" ]; then
_savedeployconf DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE"
fi
# CAFILE is optional.
# If provided then CA intermediate certificate will be copied or appended to provided filename.
_migratedeployconf Le_Deploy_ssh_cafile DEPLOY_SSH_CAFILE
_getdeployconf DEPLOY_SSH_CAFILE
_debug2 DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE"
if [ -n "$DEPLOY_SSH_CAFILE" ]; then
_savedeployconf DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE"
fi
# FULLCHAIN is optional.
# If provided then fullchain certificate will be copied or appended to provided filename.
_migratedeployconf Le_Deploy_ssh_fullchain DEPLOY_SSH_FULLCHAIN
_getdeployconf DEPLOY_SSH_FULLCHAIN
_debug2 DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN"
if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then
_savedeployconf DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN"
fi
# REMOTE_CMD is optional.
# If provided then this command will be executed on remote host.
_migratedeployconf Le_Deploy_ssh_remote_cmd DEPLOY_SSH_REMOTE_CMD
_getdeployconf DEPLOY_SSH_REMOTE_CMD
_debug2 DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD"
if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then
_savedeployconf DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD"
fi
# USE_SCP is optional. If not provided then default to previously saved
# value (which may be undefined... equivalent to "no").
_getdeployconf DEPLOY_SSH_USE_SCP
_debug2 DEPLOY_SSH_USE_SCP "$DEPLOY_SSH_USE_SCP"
if [ -z "$DEPLOY_SSH_USE_SCP" ]; then
DEPLOY_SSH_USE_SCP="no"
fi
_savedeployconf DEPLOY_SSH_USE_SCP "$DEPLOY_SSH_USE_SCP"
# SCP_CMD is optional. If not provided then use scp
_getdeployconf DEPLOY_SSH_SCP_CMD
_debug2 DEPLOY_SSH_SCP_CMD "$DEPLOY_SSH_SCP_CMD"
if [ -z "$DEPLOY_SSH_SCP_CMD" ]; then
DEPLOY_SSH_SCP_CMD="scp -q"
fi
_savedeployconf DEPLOY_SSH_SCP_CMD "$DEPLOY_SSH_SCP_CMD"
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then
DEPLOY_SSH_MULTI_CALL="yes"
_info "Using scp as alternate method for copying files. Multicall Mode is implicit"
elif [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
_info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host"
else
_info "Required commands batched and sent in single call to remote host"
fi
_deploy_ssh_servers="$DEPLOY_SSH_SERVER"
for DEPLOY_SSH_SERVER in $_deploy_ssh_servers; do
_ssh_deploy _ssh_deploy
done done
} }
@@ -181,25 +117,16 @@ _ssh_deploy() {
_cmdstr="" _cmdstr=""
_backupprefix="" _backupprefix=""
_backupdir="" _backupdir=""
_local_cert_file=""
_local_ca_file=""
_local_full_file=""
case $DEPLOY_SSH_SERVER in _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server"
*:*) if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
_host=${DEPLOY_SSH_SERVER%:*} _info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host"
_port=${DEPLOY_SSH_SERVER##*:} else
;; _info "Required commands batched and sent in single call to remote host"
*) fi
_host=$DEPLOY_SSH_SERVER
_port=
;;
esac
_info "Deploy certificates to remote server $DEPLOY_SSH_USER@$_host:$_port" if [ "$Le_Deploy_ssh_backup" = "yes" ]; then
_backupprefix="$Le_Deploy_ssh_backup_path/$_cdomain-backup"
if [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
_backupprefix="$DEPLOY_SSH_BACKUP_PATH/$_cdomain-backup"
_backupdir="$_backupprefix-$(_utc_date | tr ' ' '-')" _backupdir="$_backupprefix-$(_utc_date | tr ' ' '-')"
# run cleanup on the backup directory, erase all older # run cleanup on the backup directory, erase all older
# than 180 days (15552000 seconds). # than 180 days (15552000 seconds).
@@ -211,7 +138,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
_cmdstr="mkdir -p $_backupdir; $_cmdstr" _cmdstr="mkdir -p $_backupdir; $_cmdstr"
_info "Backup of old certificate files will be placed in remote directory $_backupdir" _info "Backup of old certificate files will be placed in remote directory $_backupdir"
_info "Backup directories erased after 180 days." _info "Backup directories erased after 180 days."
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code return $_err_code
fi fi
@@ -219,184 +146,129 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
fi fi
fi fi
# KEYFILE is optional.
# If provided then private key will be copied to provided filename.
_getdeployconf DEPLOY_SSH_KEYFILE
_debug2 DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE"
if [ -n "$DEPLOY_SSH_KEYFILE" ]; then if [ -n "$DEPLOY_SSH_KEYFILE" ]; then
if [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then Le_Deploy_ssh_keyfile="$DEPLOY_SSH_KEYFILE"
_savedomainconf Le_Deploy_ssh_keyfile "$Le_Deploy_ssh_keyfile"
fi
if [ -n "$Le_Deploy_ssh_keyfile" ]; then
if [ "$Le_Deploy_ssh_backup" = "yes" ]; then
# backup file we are about to overwrite. # backup file we are about to overwrite.
_cmdstr="$_cmdstr cp $DEPLOY_SSH_KEYFILE $_backupdir >/dev/null;" _cmdstr="$_cmdstr cp $Le_Deploy_ssh_keyfile $_backupdir >/dev/null;"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi fi
# copy new certificate into file.
# copy new key into file. _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;"
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then _info "will copy private key to remote file $Le_Deploy_ssh_keyfile"
# scp the file if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
if ! _scp_remote_cmd "$_ckey" "$DEPLOY_SSH_KEYFILE"; then if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code return $_err_code
fi fi
else _cmdstr=""
# ssh echo to the file
_cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $DEPLOY_SSH_KEYFILE;"
_info "will copy private key to remote file $DEPLOY_SSH_KEYFILE"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi fi
fi fi
# CERTFILE is optional.
# If provided then certificate will be copied or appended to provided filename.
_getdeployconf DEPLOY_SSH_CERTFILE
_debug2 DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE"
if [ -n "$DEPLOY_SSH_CERTFILE" ]; then if [ -n "$DEPLOY_SSH_CERTFILE" ]; then
Le_Deploy_ssh_certfile="$DEPLOY_SSH_CERTFILE"
_savedomainconf Le_Deploy_ssh_certfile "$Le_Deploy_ssh_certfile"
fi
if [ -n "$Le_Deploy_ssh_certfile" ]; then
_pipe=">" _pipe=">"
if [ "$DEPLOY_SSH_CERTFILE" = "$DEPLOY_SSH_KEYFILE" ]; then if [ "$Le_Deploy_ssh_certfile" = "$Le_Deploy_ssh_keyfile" ]; then
# if filename is same as previous file then append. # if filename is same as previous file then append.
_pipe=">>" _pipe=">>"
elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
# backup file we are about to overwrite. # backup file we are about to overwrite.
_cmdstr="$_cmdstr cp $DEPLOY_SSH_CERTFILE $_backupdir >/dev/null;" _cmdstr="$_cmdstr cp $Le_Deploy_ssh_certfile $_backupdir >/dev/null;"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi fi
# copy new certificate into file. # copy new certificate into file.
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then _cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;"
# scp the file _info "will copy certificate to remote file $Le_Deploy_ssh_certfile"
_local_cert_file=$(_mktemp) if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
if [ "$DEPLOY_SSH_CERTFILE" = "$DEPLOY_SSH_KEYFILE" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then
cat "$_ckey" >>"$_local_cert_file"
fi
cat "$_ccert" >>"$_local_cert_file"
if ! _scp_remote_cmd "$_local_cert_file" "$DEPLOY_SSH_CERTFILE"; then
return $_err_code return $_err_code
fi fi
else _cmdstr=""
# ssh echo to the file
_cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $DEPLOY_SSH_CERTFILE;"
_info "will copy certificate to remote file $DEPLOY_SSH_CERTFILE"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi fi
fi fi
# CAFILE is optional.
# If provided then CA intermediate certificate will be copied or appended to provided filename.
_getdeployconf DEPLOY_SSH_CAFILE
_debug2 DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE"
if [ -n "$DEPLOY_SSH_CAFILE" ]; then if [ -n "$DEPLOY_SSH_CAFILE" ]; then
Le_Deploy_ssh_cafile="$DEPLOY_SSH_CAFILE"
_savedomainconf Le_Deploy_ssh_cafile "$Le_Deploy_ssh_cafile"
fi
if [ -n "$Le_Deploy_ssh_cafile" ]; then
_pipe=">" _pipe=">"
if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_KEYFILE" ] || if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] ||
[ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_CERTFILE" ]; then [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then
# if filename is same as previous file then append. # if filename is same as previous file then append.
_pipe=">>" _pipe=">>"
elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
# backup file we are about to overwrite. # backup file we are about to overwrite.
_cmdstr="$_cmdstr cp $DEPLOY_SSH_CAFILE $_backupdir >/dev/null;" _cmdstr="$_cmdstr cp $Le_Deploy_ssh_cafile $_backupdir >/dev/null;"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi fi
# copy new certificate into file. # copy new certificate into file.
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then _cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;"
# scp the file _info "will copy CA file to remote file $Le_Deploy_ssh_cafile"
_local_ca_file=$(_mktemp) if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_KEYFILE" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then
cat "$_ckey" >>"$_local_ca_file"
fi
if [ "$DEPLOY_SSH_CAFILE" = "$DEPLOY_SSH_CERTFILE" ]; then
cat "$_ccert" >>"$_local_ca_file"
fi
cat "$_cca" >>"$_local_ca_file"
if ! _scp_remote_cmd "$_local_ca_file" "$DEPLOY_SSH_CAFILE"; then
return $_err_code return $_err_code
fi fi
else _cmdstr=""
# ssh echo to the file
_cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $DEPLOY_SSH_CAFILE;"
_info "will copy CA file to remote file $DEPLOY_SSH_CAFILE"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi fi
fi fi
# FULLCHAIN is optional.
# If provided then fullchain certificate will be copied or appended to provided filename.
_getdeployconf DEPLOY_SSH_FULLCHAIN
_debug2 DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN"
if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then
Le_Deploy_ssh_fullchain="$DEPLOY_SSH_FULLCHAIN"
_savedomainconf Le_Deploy_ssh_fullchain "$Le_Deploy_ssh_fullchain"
fi
if [ -n "$Le_Deploy_ssh_fullchain" ]; then
_pipe=">" _pipe=">"
if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_KEYFILE" ] || if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] ||
[ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CERTFILE" ] || [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ] ||
[ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CAFILE" ]; then [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then
# if filename is same as previous file then append. # if filename is same as previous file then append.
_pipe=">>" _pipe=">>"
elif [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
# backup file we are about to overwrite. # backup file we are about to overwrite.
_cmdstr="$_cmdstr cp $DEPLOY_SSH_FULLCHAIN $_backupdir >/dev/null;" _cmdstr="$_cmdstr cp $Le_Deploy_ssh_fullchain $_backupdir >/dev/null;"
if [ "$DEPLOY_SSH_FULLCHAIN" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi fi
# copy new certificate into file. # copy new certificate into file.
if [ "$DEPLOY_SSH_USE_SCP" = "yes" ]; then _cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;"
# scp the file _info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain"
_local_full_file=$(_mktemp) if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_KEYFILE" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then
cat "$_ckey" >>"$_local_full_file"
fi
if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CERTFILE" ]; then
cat "$_ccert" >>"$_local_full_file"
fi
if [ "$DEPLOY_SSH_FULLCHAIN" = "$DEPLOY_SSH_CAFILE" ]; then
cat "$_cca" >>"$_local_full_file"
fi
cat "$_cfullchain" >>"$_local_full_file"
if ! _scp_remote_cmd "$_local_full_file" "$DEPLOY_SSH_FULLCHAIN"; then
return $_err_code return $_err_code
fi fi
else _cmdstr=""
# ssh echo to the file
_cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $DEPLOY_SSH_FULLCHAIN;"
_info "will copy fullchain to remote file $DEPLOY_SSH_FULLCHAIN"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code
fi
_cmdstr=""
fi
fi fi
fi fi
# cleanup local files if any # REMOTE_CMD is optional.
if [ -f "$_local_cert_file" ]; then # If provided then this command will be executed on remote host.
rm -f "$_local_cert_file" _getdeployconf DEPLOY_SSH_REMOTE_CMD
fi _debug2 DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD"
if [ -f "$_local_ca_file" ]; then
rm -f "$_local_ca_file"
fi
if [ -f "$_local_full_file" ]; then
rm -f "$_local_full_file"
fi
if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then
_cmdstr="$_cmdstr $DEPLOY_SSH_REMOTE_CMD;" Le_Deploy_ssh_remote_cmd="$DEPLOY_SSH_REMOTE_CMD"
_info "Will execute remote command $DEPLOY_SSH_REMOTE_CMD" _savedomainconf Le_Deploy_ssh_remote_cmd "$Le_Deploy_ssh_remote_cmd"
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then fi
if [ -n "$Le_Deploy_ssh_remote_cmd" ]; then
_cmdstr="$_cmdstr $Le_Deploy_ssh_remote_cmd;"
_info "Will execute remote command $Le_Deploy_ssh_remote_cmd"
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
if ! _ssh_remote_cmd "$_cmdstr"; then if ! _ssh_remote_cmd "$_cmdstr"; then
return $_err_code return $_err_code
fi fi
@@ -410,25 +282,17 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
return $_err_code return $_err_code
fi fi
fi fi
# cleanup in case all is ok
return 0 return 0
} }
#cmd #cmd
_ssh_remote_cmd() { _ssh_remote_cmd() {
_cmd="$1" _cmd="$1"
_ssh_cmd="$DEPLOY_SSH_CMD"
if [ -n "$_port" ]; then
_ssh_cmd="$_ssh_cmd -p $_port"
fi
_secure_debug "Remote commands to execute: $_cmd" _secure_debug "Remote commands to execute: $_cmd"
_info "Submitting sequence of commands to remote server by $_ssh_cmd" _info "Submitting sequence of commands to remote server by ssh"
# quotations in bash cmd below intended. Squash travis spellcheck error # quotations in bash cmd below intended. Squash travis spellcheck error
# shellcheck disable=SC2029 # shellcheck disable=SC2029
$_ssh_cmd "$DEPLOY_SSH_USER@$_host" sh -c "'$_cmd'" $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmd'"
_err_code="$?" _err_code="$?"
if [ "$_err_code" != "0" ]; then if [ "$_err_code" != "0" ]; then
@@ -437,26 +301,3 @@ _ssh_remote_cmd() {
return $_err_code return $_err_code
} }
# cmd scp
_scp_remote_cmd() {
_src=$1
_dest=$2
_scp_cmd="$DEPLOY_SSH_SCP_CMD"
if [ -n "$_port" ]; then
_scp_cmd="$_scp_cmd -P $_port"
fi
_secure_debug "Remote copy source $_src to destination $_dest"
_info "Submitting secure copy by $_scp_cmd"
$_scp_cmd "$_src" "$DEPLOY_SSH_USER"@"$_host":"$_dest"
_err_code="$?"
if [ "$_err_code" != "0" ]; then
_err "Error code $_err_code returned from scp"
fi
return $_err_code
}
+100 -362
View File
@@ -1,53 +1,34 @@
#!/bin/bash #!/usr/bin/env sh
################################################################################ # Here is a script to deploy cert to Synology DSM
# ACME.sh 3rd party deploy plugin for Synology DSM #
################################################################################ # It requires following environment variables:
# Authors: Brian Hartvigsen (creator), https://github.com/tresni #
# Martin Arndt (contributor), https://troublezone.net/ # SYNO_Username - Synology Username to login (must be an administrator)
# Updated: 2023-07-03 # SYNO_Password - Synology Password to login
# Issues: https://github.com/acmesh-official/acme.sh/issues/2727 # SYNO_Certificate - Certificate description to target for replacement
################################################################################ #
# Usage (shown values are the examples): # The following environmental variables may be set if you don't like their
# 1. Set required environment variables: # default values:
# - use automatically created temp admin user to authenticate #
# export SYNO_USE_TEMP_ADMIN=1 # SYNO_Scheme - defaults to http
# - or provide your own admin user credential to authenticate # SYNO_Hostname - defaults to localhost
# 1. export SYNO_USERNAME="adminUser" # SYNO_Port - defaults to 5000
# 2. export SYNO_PASSWORD="adminPassword" # SYNO_DID - device ID to skip OTP - defaults to empty
# 2. Set optional environment variables # SYNO_TOTP_SECRET - TOTP secret to generate OTP - defaults to empty
# - common optional variables #
# - export SYNO_SCHEME="http" - defaults to "http"
# - export SYNO_HOSTNAME="localhost" - defaults to "localhost"
# - export SYNO_PORT="5000" - defaults to "5000"
# - export SYNO_CREATE=1 - to allow creating the cert if it doesn't exist
# - export SYNO_CERTIFICATE="" - to replace a specific cert by its
# description
# - temp admin optional variables
# - export SYNO_LOCAL_HOSTNAME=1 - if set to 1, force to treat hostname is
# targeting current local machine (since
# this method only locally supported)
# - exsiting admin 2FA-OTP optional variables
# - export SYNO_OTP_CODE="XXXXXX" - if set, script won't require to
# interactive input the OTP code
# - export SYNO_DEVICE_NAME="CertRenewal" - if set, script won't require to
# interactive input the device name
# - export SYNO_DEVICE_ID="" - (deprecated, auth with OTP code instead)
# required for omitting 2FA-OTP
# 3. Run command:
# acme.sh --deploy --deploy-hook synology_dsm -d example.com
################################################################################
# Dependencies: # Dependencies:
# - curl # -------------
# - synouser & synogroup & synosetkeyvalue (Required for SYNO_USE_TEMP_ADMIN=1) # - jq and curl
################################################################################ # - oathtool (When using 2 Factor Authentication and SYNO_TOTP_SECRET is set)
# Return value: #
# 0 means success, otherwise error. #returns 0 means success, otherwise error.
################################################################################
######## Public functions #####################
########## Public functions ####################################################
#domain keyfile certfile cafile fullchain #domain keyfile certfile cafile fullchain
synology_dsm_deploy() { synology_dsm_deploy() {
_cdomain="$1" _cdomain="$1"
_ckey="$2" _ckey="$2"
_ccert="$3" _ccert="$3"
@@ -55,391 +36,148 @@ synology_dsm_deploy() {
_debug _cdomain "$_cdomain" _debug _cdomain "$_cdomain"
# Get username and password, but don't save until we authenticated successfully # Get Username and Password, but don't save until we successfully authenticate
_migratedeployconf SYNO_Username SYNO_USERNAME _getdeployconf SYNO_Username
_migratedeployconf SYNO_Password SYNO_PASSWORD _getdeployconf SYNO_Password
_migratedeployconf SYNO_Device_ID SYNO_DEVICE_ID _getdeployconf SYNO_Create
_migratedeployconf SYNO_Device_Name SYNO_DEVICE_NAME _getdeployconf SYNO_DID
_getdeployconf SYNO_USERNAME _getdeployconf SYNO_TOTP_SECRET
_getdeployconf SYNO_PASSWORD if [ -z "${SYNO_Username:-}" ] || [ -z "${SYNO_Password:-}" ]; then
_getdeployconf SYNO_DEVICE_ID _err "SYNO_Username & SYNO_Password must be set"
_getdeployconf SYNO_DEVICE_NAME
# Prepare to use temp admin if SYNO_USE_TEMP_ADMIN is set
_getdeployconf SYNO_USE_TEMP_ADMIN
_check2cleardeployconfexp SYNO_USE_TEMP_ADMIN
_debug2 SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN"
if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then
if ! _exists synouser || ! _exists synogroup || ! _exists synosetkeyvalue; then
_err "Missing required tools to creat temp admin user, please set SYNO_USERNAME and SYNO_PASSWORD instead."
_err "Notice: temp admin user authorization method only supports local deployment on DSM."
return 1
fi
if synouser --help 2>&1 | grep -q 'Permission denied'; then
_err "For creating temp admin user, the deploy script must be run as root."
return 1
fi
[ -n "$SYNO_USERNAME" ] || _savedeployconf SYNO_USERNAME ""
[ -n "$SYNO_PASSWORD" ] || _savedeployconf SYNO_PASSWORD ""
_debug "Setting temp admin user credential..."
SYNO_USERNAME=sc-acmesh-tmp
SYNO_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16)
# Set 2FA-OTP settings to empty consider they won't be needed.
SYNO_DEVICE_ID=
SYNO_DEVICE_NAME=
SYNO_OTP_CODE=
else
_debug2 SYNO_USERNAME "$SYNO_USERNAME"
_secure_debug2 SYNO_PASSWORD "$SYNO_PASSWORD"
_debug2 SYNO_DEVICE_NAME "$SYNO_DEVICE_NAME"
_secure_debug2 SYNO_DEVICE_ID "$SYNO_DEVICE_ID"
fi
if [ -z "$SYNO_USERNAME" ] || [ -z "$SYNO_PASSWORD" ]; then
_err "You must set either SYNO_USE_TEMP_ADMIN, or set both SYNO_USERNAME and SYNO_PASSWORD."
return 1 return 1
fi fi
_debug2 SYNO_Username "$SYNO_Username"
_secure_debug2 SYNO_Password "$SYNO_Password"
# Optional scheme, hostname and port for Synology DSM # Optional scheme, hostname, and port for Synology DSM
_migratedeployconf SYNO_Scheme SYNO_SCHEME _getdeployconf SYNO_Scheme
_migratedeployconf SYNO_Hostname SYNO_HOSTNAME _getdeployconf SYNO_Hostname
_migratedeployconf SYNO_Port SYNO_PORT _getdeployconf SYNO_Port
_getdeployconf SYNO_SCHEME
_getdeployconf SYNO_HOSTNAME
_getdeployconf SYNO_PORT
# Default values for scheme, hostname and port # default vaules for scheme, hostname, and port
# Defaulting to localhost and http, because it's localhost… # defaulting to localhost and http because it's localhost...
[ -n "$SYNO_SCHEME" ] || SYNO_SCHEME="http" [ -n "${SYNO_Scheme}" ] || SYNO_Scheme="http"
[ -n "$SYNO_HOSTNAME" ] || SYNO_HOSTNAME="localhost" [ -n "${SYNO_Hostname}" ] || SYNO_Hostname="localhost"
[ -n "$SYNO_PORT" ] || SYNO_PORT="5000" [ -n "${SYNO_Port}" ] || SYNO_Port="5000"
_savedeployconf SYNO_SCHEME "$SYNO_SCHEME"
_savedeployconf SYNO_HOSTNAME "$SYNO_HOSTNAME"
_savedeployconf SYNO_PORT "$SYNO_PORT"
_debug2 SYNO_SCHEME "$SYNO_SCHEME"
_debug2 SYNO_HOSTNAME "$SYNO_HOSTNAME"
_debug2 SYNO_PORT "$SYNO_PORT"
# Get the certificate description, but don't save it until we verify it's real _savedeployconf SYNO_Scheme "$SYNO_Scheme"
_migratedeployconf SYNO_Certificate SYNO_CERTIFICATE "base64" _savedeployconf SYNO_Hostname "$SYNO_Hostname"
_getdeployconf SYNO_CERTIFICATE _savedeployconf SYNO_Port "$SYNO_Port"
_check2cleardeployconfexp SYNO_CERTIFICATE
_debug SYNO_CERTIFICATE "${SYNO_CERTIFICATE:-}" _debug2 SYNO_Scheme "$SYNO_Scheme"
_debug2 SYNO_Hostname "$SYNO_Hostname"
_debug2 SYNO_Port "$SYNO_Port"
# Get the certificate description, but don't save it until we verfiy it's real
_getdeployconf SYNO_Certificate
_debug SYNO_Certificate "${SYNO_Certificate:-}"
# shellcheck disable=SC1003 # We are not trying to escape a single quote # shellcheck disable=SC1003 # We are not trying to escape a single quote
if printf "%s" "$SYNO_CERTIFICATE" | grep '\\'; then if printf "%s" "$SYNO_Certificate" | grep '\\'; then
_err "Do not use a backslash (\) in your certificate description" _err "Do not use a backslash (\) in your certificate description"
return 1 return 1
fi fi
_debug "Getting API version..." _base_url="$SYNO_Scheme://$SYNO_Hostname:$SYNO_Port"
_base_url="$SYNO_SCHEME://$SYNO_HOSTNAME:$SYNO_PORT"
_debug _base_url "$_base_url" _debug _base_url "$_base_url"
_debug "Getting API version"
response=$(_get "$_base_url/webapi/query.cgi?api=SYNO.API.Info&version=1&method=query&query=SYNO.API.Auth") response=$(_get "$_base_url/webapi/query.cgi?api=SYNO.API.Info&version=1&method=query&query=SYNO.API.Auth")
api_path=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"path" *: *"\([^"]*\)".*/\1/p')
api_version=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"maxVersion" *: *\([0-9]*\).*/\1/p') api_version=$(echo "$response" | grep "SYNO.API.Auth" | sed -n 's/.*"maxVersion" *: *\([0-9]*\).*/\1/p')
_debug3 response "$response" _debug3 response "$response"
_debug3 api_path "$api_path"
_debug3 api_version "$api_version" _debug3 api_version "$api_version"
# Login, get the session ID and SynoToken from JSON # Login, get the token from JSON and session id from cookie
_info "Logging into $SYNO_HOSTNAME:$SYNO_PORT..." _info "Logging into $SYNO_Hostname:$SYNO_Port"
encoded_username="$(printf "%s" "$SYNO_USERNAME" | _url_encode)" encoded_username="$(printf "%s" "$SYNO_Username" | _url_encode)"
encoded_password="$(printf "%s" "$SYNO_PASSWORD" | _url_encode)" encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)"
# ## START ## - DEPRECATED, for backward compatibility
_getdeployconf SYNO_TOTP_SECRET
otp_code=""
if [ -n "$SYNO_TOTP_SECRET" ]; then if [ -n "$SYNO_TOTP_SECRET" ]; then
_info "WARNING: Usage of SYNO_TOTP_SECRET is deprecated!" if _exists oathtool; then
_info " See synology_dsm.sh script or ACME.sh Wiki page for details:" otp_code="$(oathtool --base32 --totp "${SYNO_TOTP_SECRET}" 2>/dev/null)"
_info " https://github.com/acmesh-official/acme.sh/wiki/Synology-NAS-Guide" else
if ! _exists oathtool; then
_err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET" _err "oathtool could not be found, install oathtool to use SYNO_TOTP_SECRET"
return 1 return 1
fi fi
DEPRECATED_otp_code="$(oathtool --base32 --totp "$SYNO_TOTP_SECRET" 2>/dev/null)"
if [ -z "$SYNO_DEVICE_ID" ]; then
_getdeployconf SYNO_DID
[ -n "$SYNO_DID" ] || SYNO_DEVICE_ID="$SYNO_DID"
fi
if [ -n "$SYNO_DEVICE_ID" ]; then
_H1="Cookie: did=$SYNO_DEVICE_ID"
export _H1
_debug3 H1 "${_H1}"
fi
response=$(_post "method=login&account=$encoded_username&passwd=$encoded_password&api=SYNO.API.Auth&version=$api_version&enable_syno_token=yes&otp_code=$DEPRECATED_otp_code&device_name=certrenewal&device_id=$SYNO_DEVICE_ID" "$_base_url/webapi/$api_path?enable_syno_token=yes")
_debug3 response "$response"
# ## END ## - DEPRECATED, for backward compatibility
# If SYNO_DEVICE_ID or SYNO_OTP_CODE is set, we treat current account enabled 2FA-OTP.
# Notice that if SYNO_USE_TEMP_ADMIN=1, both variables will be unset
else
if [ -n "$SYNO_DEVICE_ID" ] || [ -n "$SYNO_OTP_CODE" ]; then
response='{"error":{"code":403}}'
# Assume the current account disabled 2FA-OTP, try to log in right away.
else
if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then
_getdeployconf SYNO_LOCAL_HOSTNAME
_debug SYNO_LOCAL_HOSTNAME "${SYNO_LOCAL_HOSTNAME:-}"
if [ "$SYNO_LOCAL_HOSTNAME" != "1" ] && [ "$SYNO_LOCAL_HOSTNAME" == "$SYNO_HOSTNAME" ]; then
if [ "$SYNO_HOSTNAME" != "localhost" ] && [ "$SYNO_HOSTNAME" != "127.0.0.1" ]; then
_err "SYNO_USE_TEMP_ADMIN=1 only support local deployment, though if you are sure that the hostname $SYNO_HOSTNAME is targeting to your **current local machine**, execute 'export SYNO_LOCAL_HOSTNAME=1' then rerun."
return 1
fi
fi
_debug "Creating temp admin user in Synology DSM..."
if synogroup --help | grep -q '\-\-memberadd '; then
_temp_admin_create "$SYNO_USERNAME" "$SYNO_PASSWORD"
synogroup --memberadd administrators "$SYNO_USERNAME" >/dev/null
elif synogroup --help | grep -q '\-\-member '; then
# For supporting DSM 6.x which only has `--member` parameter.
cur_admins=$(synogroup --get administrators | awk -F '[][]' '/Group Members/,0{if(NF>1)printf "%s ", $2}')
if [ -n "$cur_admins" ]; then
_temp_admin_create "$SYNO_USERNAME" "$SYNO_PASSWORD"
_secure_debug3 admin_users "$cur_admins$SYNO_USERNAME"
# shellcheck disable=SC2086
synogroup --member administrators $cur_admins $SYNO_USERNAME >/dev/null
else
_err "The tool synogroup may be broken, please set SYNO_USERNAME and SYNO_PASSWORD instead."
return 1
fi
else
_err "Unsupported synogroup tool detected, please set SYNO_USERNAME and SYNO_PASSWORD instead."
return 1
fi
# havig a workaround to temporary disable enforce 2FA-OTP, will restore
# it soon (after a single request), though if any accident occurs like
# unexpected interruption, this setting can be easily reverted manually.
otp_enforce_option=$(synogetkeyvalue /etc/synoinfo.conf otp_enforce_option)
if [ -n "$otp_enforce_option" ] && [ "${otp_enforce_option:-"none"}" != "none" ]; then
synosetkeyvalue /etc/synoinfo.conf otp_enforce_option none
_info "Enforcing 2FA-OTP has been disabled to complete temp admin authentication."
_info "Notice: it will be restored soon, if not, you can restore it manually via Control Panel."
_info "previous_otp_enforce_option" "$otp_enforce_option"
else
otp_enforce_option=""
fi
fi
response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes")
if [ -n "$SYNO_USE_TEMP_ADMIN" ] && [ -n "$otp_enforce_option" ]; then
synosetkeyvalue /etc/synoinfo.conf otp_enforce_option "$otp_enforce_option"
_info "Restored previous enforce 2FA-OTP option."
fi
_debug3 response "$response"
fi
fi fi
error_code=$(echo "$response" | grep '"error":' | grep -o '"code":[0-9]*' | grep -o '[0-9]*') if [ -n "$SYNO_DID" ]; then
_debug2 error_code "$error_code" _H1="Cookie: did=$SYNO_DID"
# Account has 2FA-OTP enabled, since error 403 reported. export _H1
# https://global.download.synology.com/download/Document/Software/DeveloperGuide/Os/DSM/All/enu/DSM_Login_Web_API_Guide_enu.pdf _debug3 H1 "${_H1}"
if [ "$error_code" == "403" ]; then
if [ -z "$SYNO_DEVICE_NAME" ]; then
printf "Enter device name or leave empty for default (CertRenewal): "
read -r SYNO_DEVICE_NAME
[ -n "$SYNO_DEVICE_NAME" ] || SYNO_DEVICE_NAME="CertRenewal"
fi
if [ -n "$SYNO_DEVICE_ID" ]; then
# Omit OTP code with SYNO_DEVICE_ID.
response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_name=$SYNO_DEVICE_NAME&device_id=$SYNO_DEVICE_ID")
_secure_debug3 response "$response"
else
# Require the OTP code if still unset.
if [ -z "$SYNO_OTP_CODE" ]; then
printf "Enter OTP code for user '%s': " "$SYNO_USERNAME"
read -r SYNO_OTP_CODE
fi
_secure_debug SYNO_OTP_CODE "${SYNO_OTP_CODE:-}"
if [ -z "$SYNO_OTP_CODE" ]; then
response='{"error":{"code":404}}'
else
response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=login&format=sid&account=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&enable_device_token=yes&device_name=$SYNO_DEVICE_NAME&otp_code=$SYNO_OTP_CODE")
_secure_debug3 response "$response"
id_property='device_id'
[ "${api_version}" -gt '6' ] || id_property='did'
SYNO_DEVICE_ID=$(echo "$response" | grep "$id_property" | sed -n 's/.*"'$id_property'" *: *"\([^"]*\).*/\1/p')
_secure_debug2 SYNO_DEVICE_ID "$SYNO_DEVICE_ID"
fi
fi
error_code=$(echo "$response" | grep '"error":' | grep -o '"code":[0-9]*' | grep -o '[0-9]*')
_debug2 error_code "$error_code"
fi fi
if [ -n "$error_code" ]; then 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")
if [ "$error_code" == "403" ] && [ -n "$SYNO_DEVICE_ID" ]; then
_cleardeployconf SYNO_DEVICE_ID
_err "Failed to authenticate with SYNO_DEVICE_ID (may expired or invalid), please try again in a new terminal window."
elif [ "$error_code" == "404" ]; then
_err "Failed to authenticate with provided 2FA-OTP code, please try again in a new terminal window."
elif [ "$error_code" == "406" ]; then
if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then
_err "Failed with unexcepted error, please report this by providing full log with '--debug 3'."
else
_err "Enforce auth with 2FA-OTP enabled, please configure the user to enable 2FA-OTP to continue."
fi
elif [ "$error_code" == "400" ]; then
_err "Failed to authenticate, no such account or incorrect password."
elif [ "$error_code" == "401" ]; then
_err "Failed to authenticate with a non-existent account."
elif [ "$error_code" == "408" ] || [ "$error_code" == "409" ] || [ "$error_code" == "410" ]; then
_err "Failed to authenticate, the account password has expired or must be changed."
else
_err "Failed to authenticate with error: $error_code."
fi
_temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME"
return 1
fi
sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p')
token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p') token=$(echo "$response" | grep "synotoken" | sed -n 's/.*"synotoken" *: *"\([^"]*\).*/\1/p')
_debug "Session ID" "$sid" _debug3 response "$response"
_debug SynoToken "$token" _debug token "$token"
if [ -z "$sid" ] || [ -z "$token" ]; then
# Still can't get necessary info even got no errors, may Synology have API updated? if [ -z "$token" ]; then
_err "Unable to authenticate to $_base_url, you may report this by providing full log with '--debug 3'." _err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme."
_temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME" _err "Check your username and password."
_err "If two-factor authentication is enabled for the user, set SYNO_TOTP_SECRET."
return 1 return 1
fi fi
sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p')
_H1="X-SYNO-TOKEN: $token" _H1="X-SYNO-TOKEN: $token"
export _H1 export _H1
_debug2 H1 "${_H1}" _debug2 H1 "${_H1}"
# Now that we know the username and password are good, save them if not in temp admin mode. # Now that we know the username and password are good, save them
if [ -n "$SYNO_USE_TEMP_ADMIN" ]; then _savedeployconf SYNO_Username "$SYNO_Username"
_cleardeployconf SYNO_USERNAME _savedeployconf SYNO_Password "$SYNO_Password"
_cleardeployconf SYNO_PASSWORD _savedeployconf SYNO_DID "$SYNO_DID"
_cleardeployconf SYNO_DEVICE_ID _savedeployconf SYNO_TOTP_SECRET "$SYNO_TOTP_SECRET"
_cleardeployconf SYNO_DEVICE_NAME
_savedeployconf SYNO_USE_TEMP_ADMIN "$SYNO_USE_TEMP_ADMIN"
_savedeployconf SYNO_LOCAL_HOSTNAME "$SYNO_HOSTNAME"
else
_savedeployconf SYNO_USERNAME "$SYNO_USERNAME"
_savedeployconf SYNO_PASSWORD "$SYNO_PASSWORD"
_savedeployconf SYNO_DEVICE_ID "$SYNO_DEVICE_ID"
_savedeployconf SYNO_DEVICE_NAME "$SYNO_DEVICE_NAME"
fi
_info "Getting certificates in Synology DSM..." _info "Getting certificates in Synology DSM"
response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi") response=$(_post "api=SYNO.Core.Certificate.CRT&method=list&version=1&_sid=$sid" "$_base_url/webapi/entry.cgi")
_debug3 response "$response" _debug3 response "$response"
escaped_certificate="$(printf "%s" "$SYNO_CERTIFICATE" | sed 's/\([].*^$[]\)/\\\1/g;s/"/\\\\"/g')" escaped_certificate="$(printf "%s" "$SYNO_Certificate" | sed 's/\([].*^$[]\)/\\\1/g;s/"/\\\\"/g')"
_debug escaped_certificate "$escaped_certificate" _debug escaped_certificate "$escaped_certificate"
id=$(echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\"id\":\"\([^\"]*\).*/\1/p") id=$(echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\"id\":\"\([^\"]*\).*/\1/p")
_debug2 id "$id" _debug2 id "$id"
error_code=$(echo "$response" | grep '"error":' | grep -o '"code":[0-9]*' | grep -o '[0-9]*') if [ -z "$id" ] && [ -z "${SYNO_Create:-}" ]; then
_debug2 error_code "$error_code" _err "Unable to find certificate: $SYNO_Certificate and \$SYNO_Create is not set"
if [ -n "$error_code" ]; then
if [ "$error_code" -eq 105 ]; then
_err "Current user is not administrator and does not have sufficient permission for deploying."
else
_err "Failed to fetch certificate info: $error_code, please try again or contact Synology to learn more."
fi
_temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME"
return 1 return 1
fi fi
_migratedeployconf SYNO_Create SYNO_CREATE # we've verified this certificate description is a thing, so save it
_getdeployconf SYNO_CREATE _savedeployconf SYNO_Certificate "$SYNO_Certificate" "base64"
_debug2 SYNO_CREATE "$SYNO_CREATE"
if [ -z "$id" ] && [ -z "$SYNO_CREATE" ]; then _info "Generate form POST request"
_err "Unable to find certificate: $SYNO_CERTIFICATE and $SYNO_CREATE is not set."
_temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME"
return 1
fi
# We've verified this certificate description is a thing, so save it
_savedeployconf SYNO_CERTIFICATE "$SYNO_CERTIFICATE" "base64"
_info "Generating form POST request..."
nl="\0015\0012" nl="\0015\0012"
delim="--------------------------$(_utc_date | tr -d -- '-: ')" delim="--------------------------$(_utc_date | tr -d -- '-: ')"
content="--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")\0012" content="--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")\0012"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"cert\"; filename=\"$(basename "$_ccert")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ccert")\0012" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"cert\"; filename=\"$(basename "$_ccert")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ccert")\0012"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"inter_cert\"; filename=\"$(basename "$_cca")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cca")\0012" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"inter_cert\"; filename=\"$(basename "$_cca")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cca")\0012"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"id\"${nl}${nl}$id" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"id\"${nl}${nl}$id"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_CERTIFICATE}" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"desc\"${nl}${nl}${SYNO_Certificate}"
if echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then if echo "$response" | sed -n "s/.*\"desc\":\"$escaped_certificate\",\([^{]*\).*/\1/p" | grep -- 'is_default":true' >/dev/null; then
_debug2 default "This is the default certificate" _debug2 default "this is the default certificate"
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"as_default\"${nl}${nl}true" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"as_default\"${nl}${nl}true"
else else
_debug2 default "This is NOT the default certificate" _debug2 default "this is NOT the default certificate"
fi fi
content="$content${nl}--$delim--${nl}" content="$content${nl}--$delim--${nl}"
content="$(printf "%b_" "$content")" content="$(printf "%b_" "$content")"
content="${content%_}" # protect trailing \n content="${content%_}" # protect trailing \n
_info "Upload certificate to the Synology DSM." _info "Upload certificate to the Synology DSM"
response=$(_post "$content" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token&_sid=$sid" "" "POST" "multipart/form-data; boundary=${delim}") response=$(_post "$content" "$_base_url/webapi/entry.cgi?api=SYNO.Core.Certificate&method=import&version=1&SynoToken=$token&_sid=$sid" "" "POST" "multipart/form-data; boundary=${delim}")
_debug3 response "$response" _debug3 response "$response"
if ! echo "$response" | grep '"error":' >/dev/null; then if ! echo "$response" | grep '"error":' >/dev/null; then
if echo "$response" | grep '"restart_httpd":true' >/dev/null; then if echo "$response" | grep '"restart_httpd":true' >/dev/null; then
_info "Restart HTTP services succeeded." _info "http services were restarted"
else else
_info "Restart HTTP services failed." _info "http services were NOT restarted"
fi fi
_temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME"
_logout
return 0 return 0
else else
_temp_admin_cleanup "$SYNO_USE_TEMP_ADMIN" "$SYNO_USERNAME" _err "Unable to update certificate, error code $response"
_err "Unable to update certificate, got error response: $response."
_logout
return 1 return 1
fi fi
} }
#################### Private functions below ##################################
_logout() {
# Logout CERT user only to not occupy a permanent session, e.g. in DSM's "Connected Users" widget (based on previous variables)
response=$(_get "$_base_url/webapi/$api_path?api=SYNO.API.Auth&version=$api_version&method=logout&_sid=$sid")
_debug3 response "$response"
}
_temp_admin_create() {
_username="$1"
_password="$2"
synouser --del "$_username" >/dev/null 2>/dev/null
synouser --add "$_username" "$_password" "" 0 "scruelt@hotmail.com" 0 >/dev/null
}
_temp_admin_cleanup() {
_flag=$1
_username=$2
if [ -n "${_flag}" ]; then
_debug "Cleanuping temp admin info..."
synouser --del "$_username" >/dev/null
fi
}
#_cleardeployconf key
_cleardeployconf() {
_cleardomainconf "SAVED_$1"
}
# key
_check2cleardeployconfexp() {
_key="$1"
_clear_key="CLEAR_$_key"
# Clear saved settings if explicitly requested
if [ -n "$(eval echo \$"$_clear_key")" ]; then
_debug2 "$_key: value cleared from config, exported value will be ignored."
_cleardeployconf "$_key"
eval "$_key"=
export "$_key"=
eval SAVED_"$_key"=
export SAVED_"$_key"=
fi
}
-21
View File
@@ -184,27 +184,6 @@ truenas_deploy() {
_info "S3 certificate is not configured or is not the same as TrueNAS web UI" _info "S3 certificate is not configured or is not the same as TrueNAS web UI"
fi fi
_info "Checking if any chart release Apps is using the same certificate as TrueNAS web UI. Tool 'jq' is required"
if _exists jq; then
_info "Query all chart release"
_release_list=$(_get "$_api_url/chart/release")
_related_name_list=$(printf "%s" "$_release_list" | jq -r "[.[] | {name,certId: .config.ingress?.main.tls[]?.scaleCert} | select(.certId==$_active_cert_id) | .name ] | unique")
_release_length=$(printf "%s" "$_related_name_list" | jq -r "length")
_info "Found $_release_length related chart release in list: $_related_name_list"
for i in $(seq 0 $((_release_length - 1))); do
_release_name=$(echo "$_related_name_list" | jq -r ".[$i]")
_info "Updating certificate from $_active_cert_id to $_cert_id for chart release: $_release_name"
#Read the chart release configuration
_chart_config=$(printf "%s" "$_release_list" | jq -r ".[] | select(.name==\"$_release_name\")")
#Replace the old certificate id with the new one in path .config.ingress.main.tls[].scaleCert. Then update .config.ingress
_updated_chart_config=$(printf "%s" "$_chart_config" | jq "(.config.ingress?.main.tls[]? | select(.scaleCert==$_active_cert_id) | .scaleCert ) |= $_cert_id | .config.ingress ")
_update_chart_result="$(_post "{\"values\" : { \"ingress\" : $_updated_chart_config } }" "$_api_url/chart/release/id/$_release_name" "" "PUT" "application/json")"
_debug3 _update_chart_result "$_update_chart_result"
done
else
_info "Tool 'jq' does not exists, skip chart release checking"
fi
_info "Deleting old certificate" _info "Deleting old certificate"
_delete_result="$(_post "" "$_api_url/certificate/id/$_active_cert_id" "" "DELETE" "application/json")" _delete_result="$(_post "" "$_api_url/certificate/id/$_active_cert_id" "" "DELETE" "application/json")"
+17 -70
View File
@@ -7,16 +7,13 @@
# #
# VAULT_PREFIX - this contains the prefix path in vault # VAULT_PREFIX - this contains the prefix path in vault
# VAULT_ADDR - vault requires this to find your vault server # VAULT_ADDR - vault requires this to find your vault server
# VAULT_SAVE_TOKEN - set to anything if you want to save the token
# VAULT_RENEW_TOKEN - set to anything if you want to renew the token to default TTL before deploying
# VAULT_KV_V2 - set to anything if you are using v2 of the kv engine
# #
# additionally, you need to ensure that VAULT_TOKEN is avialable # additionally, you need to ensure that VAULT_TOKEN is avialable
# to access the vault server # to access the vault server
#returns 0 means success, otherwise error. #returns 0 means success, otherwise error.
######## Public functions ##################### ######## Public functions #####################
#domain keyfile certfile cafile fullchain #domain keyfile certfile cafile fullchain
vault_deploy() { vault_deploy() {
@@ -48,83 +45,33 @@ vault_deploy() {
fi fi
_savedeployconf VAULT_ADDR "$VAULT_ADDR" _savedeployconf VAULT_ADDR "$VAULT_ADDR"
_getdeployconf VAULT_SAVE_TOKEN
_savedeployconf VAULT_SAVE_TOKEN "$VAULT_SAVE_TOKEN"
_getdeployconf VAULT_RENEW_TOKEN
_savedeployconf VAULT_RENEW_TOKEN "$VAULT_RENEW_TOKEN"
_getdeployconf VAULT_KV_V2
_savedeployconf VAULT_KV_V2 "$VAULT_KV_V2"
_getdeployconf VAULT_TOKEN
if [ -z "$VAULT_TOKEN" ]; then
_err "VAULT_TOKEN needs to be defined"
return 1
fi
if [ -n "$VAULT_SAVE_TOKEN" ]; then
_savedeployconf VAULT_TOKEN "$VAULT_TOKEN"
fi
_migratedeployconf FABIO VAULT_FABIO_MODE
# JSON does not allow multiline strings. # JSON does not allow multiline strings.
# So replacing new-lines with "\n" here # So replacing new-lines with "\n" here
_ckey=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$2") _ckey=$(sed -z 's/\n/\\n/g' <"$2")
_ccert=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$3") _ccert=$(sed -z 's/\n/\\n/g' <"$3")
_cca=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$4") _cca=$(sed -z 's/\n/\\n/g' <"$4")
_cfullchain=$(sed -e ':a' -e N -e '$ ! ba' -e 's/\n/\\n/g' <"$5") _cfullchain=$(sed -z 's/\n/\\n/g' <"$5")
export _H1="X-Vault-Token: $VAULT_TOKEN"
if [ -n "$VAULT_RENEW_TOKEN" ]; then
URL="$VAULT_ADDR/v1/auth/token/renew-self"
_info "Renew the Vault token to default TTL"
if ! _post "" "$URL" >/dev/null; then
_err "Failed to renew the Vault token"
return 1
fi
fi
URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain" URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain"
export _H1="X-Vault-Token: $VAULT_TOKEN"
if [ -n "$VAULT_FABIO_MODE" ]; then if [ -n "$FABIO" ]; then
_info "Writing certificate and key to $URL in Fabio mode"
if [ -n "$VAULT_KV_V2" ]; then if [ -n "$VAULT_KV_V2" ]; then
_post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL" >/dev/null || return 1 _post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL"
else else
_post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" >/dev/null || return 1 _post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL"
fi fi
else else
if [ -n "$VAULT_KV_V2" ]; then if [ -n "$VAULT_KV_V2" ]; then
_info "Writing certificate to $URL/cert.pem" _post "{\"data\": {\"value\": \"$_ccert\"}}" "$URL/cert.pem"
_post "{\"data\": {\"value\": \"$_ccert\"}}" "$URL/cert.pem" >/dev/null || return 1 _post "{\"data\": {\"value\": \"$_ckey\"}}" "$URL/cert.key"
_info "Writing key to $URL/cert.key" _post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/chain.pem"
_post "{\"data\": {\"value\": \"$_ckey\"}}" "$URL/cert.key" >/dev/null || return 1 _post "{\"data\": {\"value\": \"$_cfullchain\"}}" "$URL/fullchain.pem"
_info "Writing CA certificate to $URL/ca.pem"
_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/ca.pem" >/dev/null || return 1
_info "Writing full-chain certificate to $URL/fullchain.pem"
_post "{\"data\": {\"value\": \"$_cfullchain\"}}" "$URL/fullchain.pem" >/dev/null || return 1
else else
_info "Writing certificate to $URL/cert.pem" _post "{\"value\": \"$_ccert\"}" "$URL/cert.pem"
_post "{\"value\": \"$_ccert\"}" "$URL/cert.pem" >/dev/null || return 1 _post "{\"value\": \"$_ckey\"}" "$URL/cert.key"
_info "Writing key to $URL/cert.key" _post "{\"value\": \"$_cca\"}" "$URL/chain.pem"
_post "{\"value\": \"$_ckey\"}" "$URL/cert.key" >/dev/null || return 1 _post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem"
_info "Writing CA certificate to $URL/ca.pem"
_post "{\"value\": \"$_cca\"}" "$URL/ca.pem" >/dev/null || return 1
_info "Writing full-chain certificate to $URL/fullchain.pem"
_post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" >/dev/null || return 1
fi
# To make it compatible with the wrong ca path `chain.pem` which was used in former versions
if _contains "$(_get "$URL/chain.pem")" "-----BEGIN CERTIFICATE-----"; then
_err "The CA certificate has moved from chain.pem to ca.pem, if you don't depend on chain.pem anymore, you can delete it to avoid this warning"
_info "Updating CA certificate to $URL/chain.pem for backward compatibility"
if [ -n "$VAULT_KV_V2" ]; then
_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/chain.pem" >/dev/null || return 1
else
_post "{\"value\": \"$_cca\"}" "$URL/chain.pem" >/dev/null || return 1
fi
fi fi
fi fi
+2 -45
View File
@@ -8,8 +8,6 @@
# #
# VAULT_PREFIX - this contains the prefix path in vault # VAULT_PREFIX - this contains the prefix path in vault
# VAULT_ADDR - vault requires this to find your vault server # VAULT_ADDR - vault requires this to find your vault server
# VAULT_SAVE_TOKEN - set to anything if you want to save the token
# VAULT_RENEW_TOKEN - set to anything if you want to renew the token to default TTL before deploying
# #
# additionally, you need to ensure that VAULT_TOKEN is avialable or # additionally, you need to ensure that VAULT_TOKEN is avialable or
# `vault auth` has applied the appropriate authorization for the vault binary # `vault auth` has applied the appropriate authorization for the vault binary
@@ -35,36 +33,15 @@ vault_cli_deploy() {
_debug _cfullchain "$_cfullchain" _debug _cfullchain "$_cfullchain"
# validate required env vars # validate required env vars
_getdeployconf VAULT_PREFIX
if [ -z "$VAULT_PREFIX" ]; then if [ -z "$VAULT_PREFIX" ]; then
_err "VAULT_PREFIX needs to be defined (contains prefix path in vault)" _err "VAULT_PREFIX needs to be defined (contains prefix path in vault)"
return 1 return 1
fi fi
_savedeployconf VAULT_PREFIX "$VAULT_PREFIX"
_getdeployconf VAULT_ADDR
if [ -z "$VAULT_ADDR" ]; then if [ -z "$VAULT_ADDR" ]; then
_err "VAULT_ADDR needs to be defined (contains vault connection address)" _err "VAULT_ADDR needs to be defined (contains vault connection address)"
return 1 return 1
fi fi
_savedeployconf VAULT_ADDR "$VAULT_ADDR"
_getdeployconf VAULT_SAVE_TOKEN
_savedeployconf VAULT_SAVE_TOKEN "$VAULT_SAVE_TOKEN"
_getdeployconf VAULT_RENEW_TOKEN
_savedeployconf VAULT_RENEW_TOKEN "$VAULT_RENEW_TOKEN"
_getdeployconf VAULT_TOKEN
if [ -z "$VAULT_TOKEN" ]; then
_err "VAULT_TOKEN needs to be defined"
return 1
fi
if [ -n "$VAULT_SAVE_TOKEN" ]; then
_savedeployconf VAULT_TOKEN "$VAULT_TOKEN"
fi
_migratedeployconf FABIO VAULT_FABIO_MODE
VAULT_CMD=$(command -v vault) VAULT_CMD=$(command -v vault)
if [ ! $? ]; then if [ ! $? ]; then
@@ -72,33 +49,13 @@ vault_cli_deploy() {
return 1 return 1
fi fi
if [ -n "$VAULT_RENEW_TOKEN" ]; then if [ -n "$FABIO" ]; then
_info "Renew the Vault token to default TTL"
if ! $VAULT_CMD token renew; then
_err "Failed to renew the Vault token"
return 1
fi
fi
if [ -n "$VAULT_FABIO_MODE" ]; then
_info "Writing certificate and key to ${VAULT_PREFIX}/${_cdomain} in Fabio mode"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1 $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1
else else
_info "Writing certificate to ${VAULT_PREFIX}/${_cdomain}/cert.pem"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1 $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1
_info "Writing key to ${VAULT_PREFIX}/${_cdomain}/cert.key"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1 $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1
_info "Writing CA certificate to ${VAULT_PREFIX}/${_cdomain}/ca.pem" $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/ca.pem" value=@"$_cca" || return 1
_info "Writing full-chain certificate to ${VAULT_PREFIX}/${_cdomain}/fullchain.pem"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1 $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1
# To make it compatible with the wrong ca path `chain.pem` which was used in former versions
if $VAULT_CMD kv get "${VAULT_PREFIX}/${_cdomain}/chain.pem" >/dev/null; then
_err "The CA certificate has moved from chain.pem to ca.pem, if you don't depend on chain.pem anymore, you can delete it to avoid this warning"
_info "Updating CA certificate to ${VAULT_PREFIX}/${_cdomain}/chain.pem for backward compatibility"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1
fi
fi fi
} }
+83 -90
View File
@@ -1,42 +1,46 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034 #This file name is "dns_1984hosting.sh"
dns_1984hosting_info='1984.hosting #So, here must be a method dns_1984hosting_add()
Domains: 1984.is #Which will be called by acme.sh to add the txt record to your api system.
Site: 1984.hosting #returns 0 means success, otherwise error.
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_1984hosting
Options:
One984HOSTING_Username Username
One984HOSTING_Password Password
Issues: github.com/acmesh-official/acme.sh/issues/2851
Author: Adrian Fedoreanu
'
######## Public functions ##################### #Author: Adrian Fedoreanu
#Report Bugs here: https://github.com/acmesh-official/acme.sh
# or here... https://github.com/acmesh-official/acme.sh/issues/2851
#
######## Public functions #####################
# Usage: dns_1984hosting_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" # Export 1984HOSTING username and password in following variables
# Add a text record. #
# One984HOSTING_Username=username
# One984HOSTING_Password=password
#
# sessionid cookie is saved in ~/.acme.sh/account.conf
# username/password need to be set only when changed.
#Usage: dns_1984hosting_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_1984hosting_add() { dns_1984hosting_add() {
fulldomain=$1 fulldomain=$1
txtvalue=$2 txtvalue=$2
_info "Add TXT record using 1984Hosting." _info "Add TXT record using 1984Hosting"
_debug fulldomain "$fulldomain" _debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue" _debug txtvalue "$txtvalue"
if ! _1984hosting_login; then if ! _1984hosting_login; then
_err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file." _err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file"
return 1 return 1
fi fi
_debug "First detect the root zone." _debug "First detect the root zone"
if ! _get_root "$fulldomain"; then if ! _get_root "$fulldomain"; then
_err "Invalid domain '$fulldomain'." _err "invalid domain" "$fulldomain"
return 1 return 1
fi fi
_debug _sub_domain "$_sub_domain" _debug _sub_domain "$_sub_domain"
_debug _domain "$_domain" _debug _domain "$_domain"
_debug "Add TXT record $fulldomain with value '$txtvalue'." _debug "Add TXT record $fulldomain with value '$txtvalue'"
value="$(printf '%s' "$txtvalue" | _url_encode)" value="$(printf '%s' "$txtvalue" | _url_encode)"
url="https://1984.hosting/domains/entry/" url="https://1984.hosting/domains/entry/"
@@ -49,96 +53,92 @@ dns_1984hosting_add() {
_debug2 postdata "$postdata" _debug2 postdata "$postdata"
_authpost "$postdata" "$url" _authpost "$postdata" "$url"
if _contains "$_response" '"haserrors": true'; then response="$(echo "$_response" | _normalizeJson)"
_err "1984Hosting failed to add TXT record for $_sub_domain bad RC from _post." _debug2 response "$response"
if _contains "$response" '"haserrors": true'; then
_err "1984Hosting failed to add TXT record for $_sub_domain bad RC from _post"
return 1 return 1
elif _contains "$_response" "html>"; then elif _contains "$response" "html>"; then
_err "1984Hosting failed to add TXT record for $_sub_domain. Check $HTTP_HEADER file." _err "1984Hosting failed to add TXT record for $_sub_domain. Check $HTTP_HEADER file"
return 1 return 1
elif _contains "$_response" '"auth": false'; then elif _contains "$response" '"auth": false'; then
_err "1984Hosting failed to add TXT record for $_sub_domain. Invalid or expired cookie." _err "1984Hosting failed to add TXT record for $_sub_domain. Invalid or expired cookie"
return 1 return 1
fi fi
_info "Added acme challenge TXT record for $fulldomain at 1984Hosting." _info "Added acme challenge TXT record for $fulldomain at 1984Hosting"
return 0 return 0
} }
# Usage: fulldomain txtvalue #Usage: fulldomain txtvalue
# Remove the txt record after validation. #Remove the txt record after validation.
dns_1984hosting_rm() { dns_1984hosting_rm() {
fulldomain=$1 fulldomain=$1
txtvalue=$2 txtvalue=$2
_info "Delete TXT record using 1984Hosting." _info "Delete TXT record using 1984Hosting"
_debug fulldomain "$fulldomain" _debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue" _debug txtvalue "$txtvalue"
if ! _1984hosting_login; then if ! _1984hosting_login; then
_err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file." _err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file"
return 1 return 1
fi fi
_debug "First detect the root zone." _debug "First detect the root zone"
if ! _get_root "$fulldomain"; then if ! _get_root "$fulldomain"; then
_err "Invalid domain '$fulldomain'." _err "invalid domain" "$fulldomain"
return 1 return 1
fi fi
_debug _sub_domain "$_sub_domain" _debug _sub_domain "$_sub_domain"
_debug _domain "$_domain" _debug _domain "$_domain"
_debug "Delete $fulldomain TXT record." _debug "Delete $fulldomain TXT record"
url="https://1984.hosting/domains" url="https://1984.hosting/domains"
if ! _get_zone_id "$url" "$_domain"; then if ! _get_zone_id "$url" "$_domain"; then
_err "Invalid zone '$_domain'." _err "invalid zone" "$_domain"
return 1 return 1
fi fi
_htmlget "$url/$_zone_id" "$txtvalue" _htmlget "$url/$_zone_id" "$txtvalue"
_debug2 _response "$_response"
entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')" entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')"
_debug2 entry_id "$entry_id" _debug2 entry_id "$entry_id"
if [ -z "$entry_id" ]; then if [ -z "$entry_id" ]; then
_err "Error getting TXT entry_id for $1." _err "Error getting TXT entry_id for $1"
return 1 return 1
fi fi
_authpost "entry=$entry_id" "$url/delentry/" _authpost "entry=$entry_id" "$url/delentry/"
if ! _contains "$_response" '"ok": true'; then response="$(echo "$_response" | _normalizeJson)"
_err "1984Hosting failed to delete TXT record for $entry_id bad RC from _post." _debug2 response "$response"
if ! _contains "$response" '"ok": true'; then
_err "1984Hosting failed to delete TXT record for $entry_id bad RC from _post"
return 1 return 1
fi fi
_info "Deleted acme challenge TXT record for $fulldomain at 1984Hosting." _info "Deleted acme challenge TXT record for $fulldomain at 1984Hosting"
return 0 return 0
} }
#################### Private functions below ################################## #################### Private functions below ##################################
# usage: _1984hosting_login username password
# returns 0 success
_1984hosting_login() { _1984hosting_login() {
if ! _check_credentials; then return 1; fi if ! _check_credentials; then return 1; fi
if _check_cookies; then if _check_cookies; then
_debug "Already logged in." _debug "Already logged in"
return 0 return 0
fi fi
_debug "Login to 1984Hosting as user $One984HOSTING_Username." _debug "Login to 1984Hosting as user $One984HOSTING_Username"
username=$(printf '%s' "$One984HOSTING_Username" | _url_encode) username=$(printf '%s' "$One984HOSTING_Username" | _url_encode)
password=$(printf '%s' "$One984HOSTING_Password" | _url_encode) password=$(printf '%s' "$One984HOSTING_Password" | _url_encode)
url="https://1984.hosting/api/auth/" url="https://1984.hosting/accounts/checkuserauth/"
_get "https://1984.hosting/accounts/login/" | grep "csrfmiddlewaretoken"
csrftoken="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'csrftoken=[^;]*;' | tr -d ';')"
sessionid="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'sessionid=[^;]*;' | tr -d ';')"
if [ -z "$csrftoken" ] || [ -z "$sessionid" ]; then
_err "One or more cookies are empty: '$csrftoken', '$sessionid'."
return 1
fi
export _H1="Cookie: $csrftoken; $sessionid"
export _H2="Referer: https://1984.hosting/accounts/login/"
csrf_header=$(echo "$csrftoken" | sed 's/csrftoken=//' | _head_n 1)
export _H3="X-CSRFToken: $csrf_header"
response="$(_post "username=$username&password=$password&otpkey=" $url)" response="$(_post "username=$username&password=$password&otpkey=" $url)"
response="$(echo "$response" | _normalizeJson)" response="$(echo "$response" | _normalizeJson)"
@@ -149,8 +149,6 @@ _1984hosting_login() {
One984HOSTING_CSRFTOKEN_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'csrftoken=[^;]*;' | tr -d ';')" One984HOSTING_CSRFTOKEN_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'csrftoken=[^;]*;' | tr -d ';')"
export One984HOSTING_SESSIONID_COOKIE export One984HOSTING_SESSIONID_COOKIE
export One984HOSTING_CSRFTOKEN_COOKIE export One984HOSTING_CSRFTOKEN_COOKIE
_saveaccountconf_mutable One984HOSTING_Username "$One984HOSTING_Username"
_saveaccountconf_mutable One984HOSTING_Password "$One984HOSTING_Password"
_saveaccountconf_mutable One984HOSTING_SESSIONID_COOKIE "$One984HOSTING_SESSIONID_COOKIE" _saveaccountconf_mutable One984HOSTING_SESSIONID_COOKIE "$One984HOSTING_SESSIONID_COOKIE"
_saveaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE "$One984HOSTING_CSRFTOKEN_COOKIE" _saveaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE "$One984HOSTING_CSRFTOKEN_COOKIE"
return 0 return 0
@@ -159,13 +157,9 @@ _1984hosting_login() {
} }
_check_credentials() { _check_credentials() {
One984HOSTING_Username="${One984HOSTING_Username:-$(_readaccountconf_mutable One984HOSTING_Username)}"
One984HOSTING_Password="${One984HOSTING_Password:-$(_readaccountconf_mutable One984HOSTING_Password)}"
if [ -z "$One984HOSTING_Username" ] || [ -z "$One984HOSTING_Password" ]; then if [ -z "$One984HOSTING_Username" ] || [ -z "$One984HOSTING_Password" ]; then
One984HOSTING_Username="" One984HOSTING_Username=""
One984HOSTING_Password="" One984HOSTING_Password=""
_clearaccountconf_mutable One984HOSTING_Username
_clearaccountconf_mutable One984HOSTING_Password
_err "You haven't specified 1984Hosting username or password yet." _err "You haven't specified 1984Hosting username or password yet."
_err "Please export as One984HOSTING_Username / One984HOSTING_Password and try again." _err "Please export as One984HOSTING_Username / One984HOSTING_Password and try again."
return 1 return 1
@@ -177,43 +171,42 @@ _check_cookies() {
One984HOSTING_SESSIONID_COOKIE="${One984HOSTING_SESSIONID_COOKIE:-$(_readaccountconf_mutable One984HOSTING_SESSIONID_COOKIE)}" One984HOSTING_SESSIONID_COOKIE="${One984HOSTING_SESSIONID_COOKIE:-$(_readaccountconf_mutable One984HOSTING_SESSIONID_COOKIE)}"
One984HOSTING_CSRFTOKEN_COOKIE="${One984HOSTING_CSRFTOKEN_COOKIE:-$(_readaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE)}" One984HOSTING_CSRFTOKEN_COOKIE="${One984HOSTING_CSRFTOKEN_COOKIE:-$(_readaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE)}"
if [ -z "$One984HOSTING_SESSIONID_COOKIE" ] || [ -z "$One984HOSTING_CSRFTOKEN_COOKIE" ]; then if [ -z "$One984HOSTING_SESSIONID_COOKIE" ] || [ -z "$One984HOSTING_CSRFTOKEN_COOKIE" ]; then
_debug "No cached cookie(s) found." _debug "No cached cookie(s) found"
return 1 return 1
fi fi
_authget "https://1984.hosting/api/auth/" _authget "https://1984.hosting/accounts/loginstatus/"
if _contains "$_response" '"ok": true'; then if _contains "$response" '"ok": true'; then
_debug "Cached cookies still valid." _debug "Cached cookies still valid"
return 0 return 0
fi fi
_debug "Cached cookies no longer valid"
_debug "Cached cookies no longer valid. Clearing cookies."
One984HOSTING_SESSIONID_COOKIE="" One984HOSTING_SESSIONID_COOKIE=""
One984HOSTING_CSRFTOKEN_COOKIE="" One984HOSTING_CSRFTOKEN_COOKIE=""
_clearaccountconf_mutable One984HOSTING_SESSIONID_COOKIE _saveaccountconf_mutable One984HOSTING_SESSIONID_COOKIE "$One984HOSTING_SESSIONID_COOKIE"
_clearaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE _saveaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE "$One984HOSTING_CSRFTOKEN_COOKIE"
return 1 return 1
} }
# _acme-challenge.www.domain.com #_acme-challenge.www.domain.com
# Returns #returns
# _sub_domain=_acme-challenge.www # _sub_domain=_acme-challenge.www
# _domain=domain.com # _domain=domain.com
_get_root() { _get_root() {
domain="$1" domain="$1"
i=1 i=1
p=1 p=1
while true; do while true; do
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) h=$(printf "%s" "$domain" | cut -d . -f $i-100)
# not valid
if [ -z "$h" ]; then if [ -z "$h" ]; then
#not valid
return 1 return 1
fi fi
_authget "https://1984.hosting/domains/zonestatus/$h/?cached=no" _authget "https://1984.hosting/domains/soacheck/?zone=$h&nameserver=ns0.1984.is."
if _contains "$_response" '"ok": true'; then if _contains "$_response" "serial" && ! _contains "$_response" "null"; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h" _domain="$h"
return 0 return 0
fi fi
@@ -223,46 +216,46 @@ _get_root() {
return 1 return 1
} }
# Usage: _get_zone_id url domain.com #usage: _get_zone_id url domain.com
# Returns zone id for domain.com #returns zone id for domain.com
_get_zone_id() { _get_zone_id() {
url=$1 url=$1
domain=$2 domain=$2
_htmlget "$url" "$domain" _htmlget "$url" "$domain"
_debug2 _response "$_response"
_zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+' | _head_n 1)" _zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+' | _head_n 1)"
_debug2 _zone_id "$_zone_id" _debug2 _zone_id "$_zone_id"
if [ -z "$_zone_id" ]; then if [ -z "$_zone_id" ]; then
_err "Error getting _zone_id for $2." _err "Error getting _zone_id for $2"
return 1 return 1
fi fi
return 0 return 0
} }
# Add extra headers to request # add extra headers to request
_authget() { _authget() {
export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE; $One984HOSTING_SESSIONID_COOKIE" export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE"
_response=$(_get "$1" | _normalizeJson) _response=$(_get "$1" | _normalizeJson)
_debug2 _response "$_response" _debug2 _response "$_response"
} }
# Truncate huge HTML response # truncate huge HTML response
# echo: Argument list too long
_htmlget() { _htmlget() {
export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE; $One984HOSTING_SESSIONID_COOKIE" export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE"
_response=$(_get "$1" | grep "$2") _response=$(_get "$1" | grep "$2")
if _contains "$_response" "@$2"; then if _contains "$_response" "@$2"; then
_response=$(echo "$_response" | grep -v "[@]" | _head_n 1) _response=$(echo "$_response" | grep -v "[@]" | _head_n 1)
fi fi
_debug2 _response "$_response"
} }
# Add extra headers to request # add extra headers to request
_authpost() { _authpost() {
url="https://1984.hosting/domains" url="https://1984.hosting/domains"
_get_zone_id "$url" "$_domain" _get_zone_id "$url" "$_domain"
csrf_header="$(echo "$One984HOSTING_CSRFTOKEN_COOKIE" | _egrep_o "=[^=][0-9a-zA-Z]*" | tr -d "=")" csrf_header="$(echo "$One984HOSTING_CSRFTOKEN_COOKIE" | _egrep_o "=[^=][0-9a-zA-Z]*" | tr -d "=")"
export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE; $One984HOSTING_SESSIONID_COOKIE" export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE"
export _H2="Referer: https://1984.hosting/domains/$_zone_id" export _H2="Referer: https://1984.hosting/domains/$_zone_id"
export _H3="X-CSRFToken: $csrf_header" export _H3="X-CSRFToken: $csrf_header"
_response="$(_post "$1" "$2" | _normalizeJson)" _response=$(_post "$1" "$2")
_debug2 _response "$_response"
} }
+14 -14
View File
@@ -1,18 +1,18 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034 #
dns_acmedns_info='acme-dns Server API #Author: Wolfgang Ebner
The acme-dns is a limited DNS server with RESTful API to handle ACME DNS challenges. #Author: Sven Neubuaer
Site: github.com/joohoi/acme-dns #Report Bugs here: https://github.com/dampfklon/acme.sh
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_acmedns #
Options: # Usage:
ACMEDNS_USERNAME Username. Optional. # export ACMEDNS_BASE_URL="https://auth.acme-dns.io"
ACMEDNS_PASSWORD Password. Optional. #
ACMEDNS_SUBDOMAIN Subdomain. Optional. # You can optionally define an already existing account:
ACMEDNS_BASE_URL API endpoint. Default: "https://auth.acme-dns.io". #
Issues: github.com/dampfklon/acme.sh # export ACMEDNS_USERNAME="<username>"
Author: Wolfgang Ebner, Sven Neubuaer # export ACMEDNS_PASSWORD="<password>"
' # export ACMEDNS_SUBDOMAIN="<subdomain>"
#
######## Public functions ##################### ######## Public functions #####################
#Usage: dns_acmedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" #Usage: dns_acmedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
Executable → Regular
+5 -13
View File
@@ -1,17 +1,9 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_acmeproxy_info='AcmeProxy Server API ## Acmeproxy DNS provider to be used with acmeproxy (https://github.com/mdbraber/acmeproxy)
AcmeProxy can be used to as a single host in your network to request certificates through a DNS API. ## API integration by Maarten den Braber
Clients can connect with the one AcmeProxy host so you do not need to store DNS API credentials on every single host. ##
Site: github.com/mdbraber/acmeproxy ## Report any bugs via https://github.com/mdbraber/acme.sh
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_acmeproxy
Options:
ACMEPROXY_ENDPOINT API Endpoint
ACMEPROXY_USERNAME Username
ACMEPROXY_PASSWORD Password
Issues: github.com/acmesh-official/acme.sh/issues/2251
Author: Maarten den Braber
'
dns_acmeproxy_add() { dns_acmeproxy_add() {
fulldomain="${1}" fulldomain="${1}"
+2 -9
View File
@@ -1,13 +1,6 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_active24_info='Active24.com #ACTIVE24_Token="sdfsdfsdfljlbjkljlkjsdfoiwje"
Site: Active24.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_active24
Options:
ACTIVE24_Token API Token
Issues: github.com/acmesh-official/acme.sh/issues/2059
Author: Milan Pála
'
ACTIVE24_Api="https://api.active24.com" ACTIVE24_Api="https://api.active24.com"
+8 -9
View File
@@ -1,13 +1,12 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_ad_info='AlwaysData.com #
Site: AlwaysData.com #AD_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje"
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ad
Options: #This is the Alwaysdata api wrapper for acme.sh
AD_API_KEY API Key #
Issues: github.com/acmesh-official/acme.sh/pull/503 #Author: Paul Koppen
Author: Paul Koppen #Report Bugs here: https://github.com/wpk-/acme.sh
'
AD_API_URL="https://$AD_API_KEY:@api.alwaysdata.com/v1" AD_API_URL="https://$AD_API_KEY:@api.alwaysdata.com/v1"
+4 -10
View File
@@ -1,16 +1,10 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_ali_info='AlibabaCloud.com
Domains: Aliyun.com
Site: AlibabaCloud.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ali
Options:
Ali_Key API Key
Ali_Secret API Secret
'
Ali_API="https://alidns.aliyuncs.com/" Ali_API="https://alidns.aliyuncs.com/"
#Ali_Key="LTqIA87hOKdjevsf5"
#Ali_Secret="0p5EYueFNq501xnCPzKNbx6K51qPH2"
#Usage: dns_ali_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" #Usage: dns_ali_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_ali_add() { dns_ali_add() {
fulldomain=$1 fulldomain=$1
@@ -123,7 +117,7 @@ _ali_urlencode() {
_ali_nonce() { _ali_nonce() {
#_head_n 1 </dev/urandom | _digest "sha256" hex | cut -c 1-31 #_head_n 1 </dev/urandom | _digest "sha256" hex | cut -c 1-31
#Not so good... #Not so good...
date +"%s%N" | sed 's/%N//g' date +"%s%N"
} }
_check_exist_query() { _check_exist_query() {
-184
View File
@@ -1,184 +0,0 @@
#!/usr/bin/env sh
# Alviy domain api
#
# Get API key and secret from https://cloud.alviy.com/token
#
# Alviy_token="some-secret-key"
#
# Ex.: acme.sh --issue --staging --dns dns_alviy -d "*.s.example.com" -d "s.example.com"
Alviy_Api="https://cloud.alviy.com/api/v1"
######## Public functions #####################
#Usage: dns_alviy_add _acme-challenge.www.domain.com "content"
dns_alviy_add() {
fulldomain=$1
txtvalue=$2
Alviy_token="${Alviy_token:-$(_readaccountconf_mutable Alviy_token)}"
if [ -z "$Alviy_token" ]; then
Alviy_token=""
_err "Please specify Alviy token."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf_mutable Alviy_token "$Alviy_token"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting existing records"
if _alviy_txt_exists "$_domain" "$fulldomain" "$txtvalue"; then
_info "This record already exists, skipping"
return 0
fi
_add_data="{\"content\":\"$txtvalue\",\"type\":\"TXT\"}"
_debug2 _add_data "$_add_data"
_info "Adding record"
if _alviy_rest POST "zone/$_domain/domain/$fulldomain/" "$_add_data"; then
_debug "Checking updated records of '${fulldomain}'"
if ! _alviy_txt_exists "$_domain" "$fulldomain" "$txtvalue"; then
_err "TXT record '${txtvalue}' for '${fulldomain}', value wasn't set!"
return 1
fi
else
_err "Add txt record error, value '${txtvalue}' for '${fulldomain}' was not set."
return 1
fi
_sleep 10
_info "Added TXT record '${txtvalue}' for '${fulldomain}'."
return 0
}
#fulldomain
dns_alviy_rm() {
fulldomain=$1
txtvalue=$2
Alviy_token="${Alviy_token:-$(_readaccountconf_mutable Alviy_token)}"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
if ! _alviy_txt_exists "$_domain" "$fulldomain" "$txtvalue"; then
_info "The record does not exist, skip"
return 0
fi
_add_data=""
uuid=$(echo "$response" | tr "{" "\n" | grep "$txtvalue" | tr "," "\n" | grep uuid | cut -d \" -f4)
# delete record
_debug "Delete TXT record for '${fulldomain}'"
if ! _alviy_rest DELETE "zone/$_domain/record/$uuid" "{\"confirm\":1}"; then
_err "Cannot delete empty TXT record for '$fulldomain'"
return 1
fi
_info "The record '$fulldomain'='$txtvalue' deleted"
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain=$1
i=3
a="init"
while [ -n "$a" ]; do
a=$(printf "%s" "$domain" | cut -d . -f $i-)
i=$((i + 1))
done
n=$((i - 3))
h=$(printf "%s" "$domain" | cut -d . -f $n-)
if [ -z "$h" ]; then
#not valid
_alviy_rest GET "zone/$domain/"
_debug "can't get host from $domain"
return 1
fi
if ! _alviy_rest GET "zone/$h/"; then
return 1
fi
if _contains "$response" '"code":"NOT_FOUND"'; then
_debug "$h not found"
else
s=$((n - 1))
_sub_domain=$(printf "%s" "$domain" | cut -d . -f -$s)
_domain="$h"
return 0
fi
return 1
}
_alviy_txt_exists() {
zone=$1
domain=$2
content_data=$3
_debug "Getting existing records"
if ! _alviy_rest GET "zone/$zone/domain/$domain/TXT/"; then
_info "The record does not exist"
return 1
fi
if ! _contains "$response" "$3"; then
_info "The record has other value"
return 1
fi
# GOOD code return - TRUE function
return 0
}
_alviy_rest() {
method=$1
path="$2"
content_data="$3"
_debug "$path"
export _H1="Authorization: Bearer $Alviy_token"
export _H2="Content-Type: application/json"
if [ "$content_data" ] || [ "$method" = "DELETE" ]; then
_debug "data ($method): " "$content_data"
response="$(_post "$content_data" "$Alviy_Api/$path" "" "$method")"
else
response="$(_get "$Alviy_Api/$path")"
fi
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
if [ "$_code" = "401" ]; then
_err "It seems that your api key or secret is not correct."
return 1
fi
if [ "$_code" != "200" ]; then
_err "API call error ($method): $path Response code $_code"
fi
if [ "$?" != "0" ]; then
_err "error on rest call ($method): $path. Response:"
_err "$response"
return 1
fi
_debug2 response "$response"
return 0
}
+7 -9
View File
@@ -1,12 +1,9 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_anx_info='Anexia.com CloudDNS # Anexia CloudDNS acme.sh hook
Site: Anexia.com # Author: MA
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_anx
Options: #ANX_Token="xxxx"
ANX_Token API Token
Issues: github.com/acmesh-official/acme.sh/issues/3238
'
ANX_API='https://engine.anexia-it.com/api/clouddns/v1' ANX_API='https://engine.anexia-it.com/api/clouddns/v1'
@@ -130,6 +127,8 @@ _get_root() {
i=1 i=1
p=1 p=1
_anx_rest GET "zone.json"
while true; do while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100) h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h" _debug h "$h"
@@ -138,7 +137,6 @@ _get_root() {
return 1 return 1
fi fi
_anx_rest GET "zone.json/${h}"
if _contains "$response" "\"name\":\"$h\""; then if _contains "$response" "\"name\":\"$h\""; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h _domain=$h
-177
View File
@@ -1,177 +0,0 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_artfiles_info='ArtFiles.de
Site: ArtFiles.de
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_artfiles
Options:
AF_API_USERNAME API Username
AF_API_PASSWORD API Password
Issues: github.com/acmesh-official/acme.sh/issues/4718
Author: Martin Arndt <https://troublezone.net/>
'
########## API configuration ###################################################
AF_API_SUCCESS='status":"OK'
AF_URL_DCP='https://dcp.c.artfiles.de/api/'
AF_URL_DNS=${AF_URL_DCP}'dns/{*}_dns.html?domain='
AF_URL_DOMAINS=${AF_URL_DCP}'domain/get_domains.html'
########## Public functions ####################################################
# Adds a new TXT record for given ACME challenge value & domain.
# Usage: dns_artfiles_add _acme-challenge.www.example.com "ACME challenge value"
dns_artfiles_add() {
domain="$1"
txtValue="$2"
_info 'Using ArtFiles.de DNS addition API…'
_debug 'Domain' "$domain"
_debug 'txtValue' "$txtValue"
_set_credentials
_saveaccountconf_mutable 'AF_API_USERNAME' "$AF_API_USERNAME"
_saveaccountconf_mutable 'AF_API_PASSWORD' "$AF_API_PASSWORD"
_set_headers
_get_zone "$domain"
_dns 'GET'
if ! _contains "$response" 'TXT'; then
_err 'Retrieving TXT records failed.'
return 1
fi
_clean_records
_dns 'SET' "$(printf -- '%s\n_acme-challenge "%s"' "$response" "$txtValue")"
if ! _contains "$response" "$AF_API_SUCCESS"; then
_err 'Adding ACME challenge value failed.'
return 1
fi
}
# Removes the existing TXT record for given ACME challenge value & domain.
# Usage: dns_artfiles_rm _acme-challenge.www.example.com "ACME challenge value"
dns_artfiles_rm() {
domain="$1"
txtValue="$2"
_info 'Using ArtFiles.de DNS removal API…'
_debug 'Domain' "$domain"
_debug 'txtValue' "$txtValue"
_set_credentials
_set_headers
_get_zone "$domain"
if ! _dns 'GET'; then
return 1
fi
if ! _contains "$response" "$txtValue"; then
_err 'Retrieved TXT records are missing given ACME challenge value.'
return 1
fi
_clean_records
response="$(printf -- '%s' "$response" | sed '/_acme-challenge "'"$txtValue"'"/d')"
_dns 'SET' "$response"
if ! _contains "$response" "$AF_API_SUCCESS"; then
_err 'Removing ACME challenge value failed.'
return 1
fi
}
########## Private functions ###################################################
# Cleans awful TXT records response of ArtFiles's API & pretty prints it.
# Usage: _clean_records
_clean_records() {
_info 'Cleaning TXT records…'
# Extract TXT part, strip trailing quote sign (ACME.sh API guidelines forbid
# usage of SED's GNU extensions, hence couldn't omit it via regex), strip '\'
# from '\"' & turn '\n' into real LF characters.
# Yup, awful API to use - but that's all we got to get this working, so… ;)
_debug2 'Raw ' "$response"
response="$(printf -- '%s' "$response" | sed 's/^.*TXT":"\([^}]*\).*$/\1/;s/,".*$//;s/.$//;s/\\"/"/g;s/\\n/\n/g')"
_debug2 'Clean' "$response"
}
# Executes an HTTP GET or POST request for getting or setting DNS records,
# containing given payload upon POST.
# Usage: _dns [GET | SET] [payload]
_dns() {
_info 'Executing HTTP request…'
action="$1"
payload="$(printf -- '%s' "$2" | _url_encode)"
url="$(printf -- '%s%s' "$AF_URL_DNS" "$domain" | sed 's/{\*}/'"$(printf -- '%s' "$action" | _lower_case)"'/')"
if [ "$action" = 'SET' ]; then
_debug2 'Payload' "$payload"
response="$(_post '' "$url&TXT=$payload" '' 'POST' 'application/x-www-form-urlencoded')"
else
response="$(_get "$url" '' 10)"
fi
if ! _contains "$response" "$AF_API_SUCCESS"; then
_err "DNS API error: $response"
return 1
fi
_debug 'Response' "$response"
return 0
}
# Gets the root domain zone for given domain.
# Usage: _get_zone _acme-challenge.www.example.com
_get_zone() {
fqdn="$1"
domains="$(_get "$AF_URL_DOMAINS" '' 10)"
_info 'Getting domain zone…'
_debug2 'FQDN' "$fqdn"
_debug2 'Domains' "$domains"
while _contains "$fqdn" "."; do
if _contains "$domains" "$fqdn"; then
domain="$fqdn"
_info "Found root domain zone: $domain"
break
else
fqdn="${fqdn#*.}"
_debug2 'FQDN' "$fqdn"
fi
done
if [ "$domain" = "$fqdn" ]; then
return 0
fi
_err 'Couldn'\''t find root domain zone.'
return 1
}
# Sets the credentials for accessing ArtFiles's API
# Usage: _set_credentials
_set_credentials() {
_info 'Setting credentials…'
AF_API_USERNAME="${AF_API_USERNAME:-$(_readaccountconf_mutable AF_API_USERNAME)}"
AF_API_PASSWORD="${AF_API_PASSWORD:-$(_readaccountconf_mutable AF_API_PASSWORD)}"
if [ -z "$AF_API_USERNAME" ] || [ -z "$AF_API_PASSWORD" ]; then
_err 'Missing ArtFiles.de username and/or password.'
_err 'Please ensure both are set via export command & try again.'
return 1
fi
}
# Adds the HTTP Authorization & Content-Type headers to a follow-up request.
# Usage: _set_headers
_set_headers() {
_info 'Setting headers…'
encoded="$(printf -- '%s:%s' "$AF_API_USERNAME" "$AF_API_PASSWORD" | _base64)"
export _H1="Authorization: Basic $encoded"
export _H2='Content-Type: application/json'
}
+7 -13
View File
@@ -1,16 +1,11 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_arvan_info='ArvanCloud.ir
Site: ArvanCloud.ir
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_arvan
Options:
Arvan_Token API Token
Issues: github.com/acmesh-official/acme.sh/issues/2796
Author: Vahid Fardi
'
ARVAN_API_URL="https://napi.arvancloud.ir/cdn/4.0/domains" #Arvan_Token="Apikey xxxx"
ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains"
#Author: Vahid Fardi
#Report Bugs here: https://github.com/Neilpang/acme.sh
#
######## Public functions ##################### ######## Public functions #####################
#Usage: dns_arvan_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" #Usage: dns_arvan_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
@@ -23,7 +18,7 @@ dns_arvan_add() {
if [ -z "$Arvan_Token" ]; then if [ -z "$Arvan_Token" ]; then
_err "You didn't specify \"Arvan_Token\" token yet." _err "You didn't specify \"Arvan_Token\" token yet."
_err "You can get yours from here https://npanel.arvancloud.ir/profile/api-keys" _err "You can get yours from here https://npanel.arvancloud.com/profile/api-keys"
return 1 return 1
fi fi
#save the api token to the account conf file. #save the api token to the account conf file.
@@ -45,7 +40,7 @@ dns_arvan_add() {
_info "response id is $response" _info "response id is $response"
_info "Added, OK" _info "Added, OK"
return 0 return 0
elif _contains "$response" "Record Data is duplicate"; then elif _contains "$response" "Record Data is Duplicated"; then
_info "Already exists, OK" _info "Already exists, OK"
return 0 return 0
else else
@@ -146,7 +141,6 @@ _arvan_rest() {
response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")"
elif [ "$mtd" = "POST" ]; then elif [ "$mtd" = "POST" ]; then
export _H2="Content-Type: application/json" export _H2="Content-Type: application/json"
export _H3="Accept: application/json"
_debug data "$data" _debug data "$data"
response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")"
else else
+5 -11
View File
@@ -1,15 +1,9 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_aurora_info='versio.nl AuroraDNS #
Domains: pcextreme.nl #AURORA_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
Site: versio.nl #
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_aurora #AURORA_Secret="sdfsdfsdfljlbjkljlkjsdfoiwje"
Options:
AURORA_Key API Key
AURORA_Secret API Secret
Issues: github.com/acmesh-official/acme.sh/issues/3459
Author: Jasper Zonneveld
'
AURORA_Api="https://api.auroradns.eu" AURORA_Api="https://api.auroradns.eu"
+12 -11
View File
@@ -1,15 +1,16 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034 # -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*-
dns_autodns_info='InternetX autoDNS
InternetX autoDNS XML API # This is the InternetX autoDNS xml api wrapper for acme.sh
Site: InternetX.com/autodns/ # Author: auerswald@gmail.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_autodns # Created: 2018-01-14
Options: #
AUTODNS_USER Username # export AUTODNS_USER="username"
AUTODNS_PASSWORD Password # export AUTODNS_PASSWORD="password"
AUTODNS_CONTEXT Context # export AUTODNS_CONTEXT="context"
Author: <auerswald@gmail.com> #
' # Usage:
# acme.sh --issue --dns dns_autodns -d example.com
AUTODNS_API="https://gateway.autodns.com" AUTODNS_API="https://gateway.autodns.com"
+17 -34
View File
@@ -1,15 +1,13 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_aws_info='Amazon AWS Route53 domain API
Site: docs.aws.amazon.com/route53/
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_aws
Options:
AWS_ACCESS_KEY_ID API Key ID
AWS_SECRET_ACCESS_KEY API Secret
'
# All `_sleep` commands are included to avoid Route53 throttling, see #
# https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html#limits-api-requests #AWS_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje"
#
#AWS_SECRET_ACCESS_KEY="xxxxxxx"
#This is the Amazon Route53 api wrapper for acme.sh
#All `_sleep` commands are included to avoid Route53 throttling, see
#https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html#limits-api-requests
AWS_HOST="route53.amazonaws.com" AWS_HOST="route53.amazonaws.com"
AWS_URL="https://$AWS_HOST" AWS_URL="https://$AWS_HOST"
@@ -147,6 +145,7 @@ dns_aws_rm() {
fi fi
_sleep 1 _sleep 1
return 1 return 1
} }
#################### Private functions below ################################## #################### Private functions below ##################################
@@ -158,7 +157,7 @@ _get_root() {
# iterate over names (a.b.c.d -> b.c.d -> c.d -> d) # iterate over names (a.b.c.d -> b.c.d -> c.d -> d)
while true; do while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100 | sed 's/\./\\./g') h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug "Checking domain: $h" _debug "Checking domain: $h"
if [ -z "$h" ]; then if [ -z "$h" ]; then
_error "invalid domain" _error "invalid domain"
@@ -208,40 +207,24 @@ _use_container_role() {
} }
_use_instance_role() { _use_instance_role() {
_instance_role_name_url="http://169.254.169.254/latest/meta-data/iam/security-credentials/" _url="http://169.254.169.254/latest/meta-data/iam/security-credentials/"
_debug "_url" "$_url"
if _get "$_instance_role_name_url" true 1 | _head_n 1 | grep -Fq 401; then if ! _get "$_url" true 1 | _head_n 1 | grep -Fq 200; then
_debug "Using IMDSv2"
_token_url="http://169.254.169.254/latest/api/token"
export _H1="X-aws-ec2-metadata-token-ttl-seconds: 21600"
_token="$(_post "" "$_token_url" "" "PUT")"
_secure_debug3 "_token" "$_token"
if [ -z "$_token" ]; then
_debug "Unable to fetch IMDSv2 token from instance metadata"
return 1
fi
export _H1="X-aws-ec2-metadata-token: $_token"
fi
if ! _get "$_instance_role_name_url" true 1 | _head_n 1 | grep -Fq 200; then
_debug "Unable to fetch IAM role from instance metadata" _debug "Unable to fetch IAM role from instance metadata"
return 1 return 1
fi fi
_aws_role=$(_get "$_url" "" 1)
_instance_role_name=$(_get "$_instance_role_name_url" "" 1) _debug "_aws_role" "$_aws_role"
_debug "_instance_role_name" "$_instance_role_name" _use_metadata "$_url$_aws_role"
_use_metadata "$_instance_role_name_url$_instance_role_name" "$_token"
} }
_use_metadata() { _use_metadata() {
export _H1="X-aws-ec2-metadata-token: $2"
_aws_creds="$( _aws_creds="$(
_get "$1" "" 1 | _get "$1" "" 1 |
_normalizeJson | _normalizeJson |
tr '{,}' '\n' | tr '{,}' '\n' |
while read -r _line; do while read -r _line; do
_key="$(echo "${_line%%:*}" | tr -d '\"')" _key="$(echo "${_line%%:*}" | tr -d '"')"
_value="${_line#*:}" _value="${_line#*:}"
_debug3 "_key" "$_key" _debug3 "_key" "$_key"
_secure_debug3 "_value" "$_value" _secure_debug3 "_value" "$_value"
+5 -9
View File
@@ -1,13 +1,9 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_azion_info='Azion.om #
Site: Azion.com #AZION_Email=""
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_azion #AZION_Password=""
Options: #
AZION_Email Email
AZION_Password Password
Issues: github.com/acmesh-official/acme.sh/issues/3555
'
AZION_Api="https://api.azionapi.net" AZION_Api="https://api.azionapi.net"
+2 -11
View File
@@ -1,15 +1,6 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_azure_info='Azure WIKI="https://github.com/acmesh-official/acme.sh/wiki/How-to-use-Azure-DNS"
Site: Azure.microsoft.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_azure
Options:
AZUREDNS_SUBSCRIPTIONID Subscription ID
AZUREDNS_TENANTID Tenant ID
AZUREDNS_APPID App ID. App ID of the service principal
AZUREDNS_CLIENTSECRET Client Secret. Secret from creating the service principal
AZUREDNS_MANAGEDIDENTITY Use Managed Identity. Use Managed Identity assigned to a resource instead of a service principal. "true"/"false"
'
######## Public functions ##################### ######## Public functions #####################
-88
View File
@@ -1,88 +0,0 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_bookmyname_info='BookMyName.com
Site: BookMyName.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_bookmyname
Options:
BOOKMYNAME_USERNAME Username
BOOKMYNAME_PASSWORD Password
Issues: github.com/acmesh-official/acme.sh/issues/3209
Author: Neilpang
'
######## Public functions #####################
# BookMyName urls:
# https://BOOKMYNAME_USERNAME:BOOKMYNAME_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=add&value="XXXXXXXX"'
# https://BOOKMYNAME_USERNAME:BOOKMYNAME_PASSWORD@www.bookmyname.com/dyndns/?hostname=_acme-challenge.domain.tld&type=txt&ttl=300&do=remove&value="XXXXXXXX"'
# Output:
#good: update done, cid 123456, domain id 456789, type txt, ip XXXXXXXX
#good: remove done 1, cid 123456, domain id 456789, ttl 300, type txt, ip XXXXXXXX
# Be careful, BMN DNS servers can be slow to pick up changes; using dnssleep is thus advised.
# Usage:
# export BOOKMYNAME_USERNAME="ABCDE-FREE"
# export BOOKMYNAME_PASSWORD="MyPassword"
# /usr/local/ssl/acme.sh/acme.sh --dns dns_bookmyname --dnssleep 600 --issue -d domain.tld
#Usage: dns_bookmyname_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_bookmyname_add() {
fulldomain=$1
txtvalue=$2
_info "Using bookmyname"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
BOOKMYNAME_USERNAME="${BOOKMYNAME_USERNAME:-$(_readaccountconf_mutable BOOKMYNAME_USERNAME)}"
BOOKMYNAME_PASSWORD="${BOOKMYNAME_PASSWORD:-$(_readaccountconf_mutable BOOKMYNAME_PASSWORD)}"
if [ -z "$BOOKMYNAME_USERNAME" ] || [ -z "$BOOKMYNAME_PASSWORD" ]; then
BOOKMYNAME_USERNAME=""
BOOKMYNAME_PASSWORD=""
_err "You didn't specify BookMyName username and password yet."
_err "Please specify them and try again."
return 1
fi
#save the credentials to the account conf file.
_saveaccountconf_mutable BOOKMYNAME_USERNAME "$BOOKMYNAME_USERNAME"
_saveaccountconf_mutable BOOKMYNAME_PASSWORD "$BOOKMYNAME_PASSWORD"
uri="https://${BOOKMYNAME_USERNAME}:${BOOKMYNAME_PASSWORD}@www.bookmyname.com/dyndns/"
data="?hostname=${fulldomain}&type=TXT&ttl=300&do=add&value=${txtvalue}"
result="$(_get "${uri}${data}")"
_debug "Result: $result"
if ! _startswith "$result" 'good: update done, cid '; then
_err "Can't add $fulldomain"
return 1
fi
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_bookmyname_rm() {
fulldomain=$1
txtvalue=$2
_info "Using bookmyname"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
BOOKMYNAME_USERNAME="${BOOKMYNAME_USERNAME:-$(_readaccountconf_mutable BOOKMYNAME_USERNAME)}"
BOOKMYNAME_PASSWORD="${BOOKMYNAME_PASSWORD:-$(_readaccountconf_mutable BOOKMYNAME_PASSWORD)}"
uri="https://${BOOKMYNAME_USERNAME}:${BOOKMYNAME_PASSWORD}@www.bookmyname.com/dyndns/"
data="?hostname=${fulldomain}&type=TXT&ttl=300&do=remove&value=${txtvalue}"
result="$(_get "${uri}${data}")"
_debug "Result: $result"
if ! _startswith "$result" 'good: remove done 1, cid '; then
_info "Can't remove $fulldomain"
fi
}
#################### Private functions below ##################################
+12 -9
View File
@@ -1,13 +1,16 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_bunny_info='Bunny.net ## Will be called by acme.sh to add the TXT record via the Bunny DNS API.
Site: Bunny.net/dns/ ## returns 0 means success, otherwise error.
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_bunny
Options: ## Author: nosilver4u <nosilver4u at ewww.io>
BUNNY_API_KEY API Key ## GitHub: https://github.com/nosilver4u/acme.sh
Issues: github.com/acmesh-official/acme.sh/issues/4296
Author: <nosilver4u@ewww.io> ##
' ## Environment Variables Required:
##
## BUNNY_API_KEY="75310dc4-ca77-9ac3-9a19-f6355db573b49ce92ae1-2655-3ebd-61ac-3a3ae34834cc"
##
##################### Public functions ##################### ##################### Public functions #####################
+9 -12
View File
@@ -1,16 +1,13 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_cf_info='CloudFlare #
Site: CloudFlare.com #CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cf #
Options: #CF_Email="xxxx@sss.com"
CF_Key API Key
CF_Email Your account email #CF_Token="xxxx"
OptionsAlt: #CF_Account_ID="xxxx"
CF_Token API Token #CF_Zone_ID="xxxx"
CF_Account_ID Account ID
CF_Zone_ID Zone ID. Optional.
'
CF_Api="https://api.cloudflare.com/client/v4" CF_Api="https://api.cloudflare.com/client/v4"
+6 -11
View File
@@ -1,15 +1,10 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_clouddns_info='vshosting.cz CloudDNS # Author: Radek Sprta <sprta@vshosting.cz>
Site: github.com/vshosting/clouddns
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_clouddns #CLOUDDNS_EMAIL=XXXXX
Options: #CLOUDDNS_PASSWORD="YYYYYYYYY"
CLOUDDNS_EMAIL Email #CLOUDDNS_CLIENT_ID=XXXXX
CLOUDDNS_PASSWORD Password
CLOUDDNS_CLIENT_ID Client ID
Issues: github.com/acmesh-official/acme.sh/issues/2699
Author: Radek Sprta <sprta@vshosting.cz>
'
CLOUDDNS_API='https://admin.vshosting.cloud/clouddns' CLOUDDNS_API='https://admin.vshosting.cloud/clouddns'
CLOUDDNS_LOGIN_API='https://admin.vshosting.cloud/api/public/auth/login' CLOUDDNS_LOGIN_API='https://admin.vshosting.cloud/api/public/auth/login'
+8 -11
View File
@@ -1,15 +1,12 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_cloudns_info='ClouDNS.net
Site: ClouDNS.net
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cloudns
Options:
CLOUDNS_AUTH_ID Regular auth ID
CLOUDNS_SUB_AUTH_ID Sub auth ID
CLOUDNS_AUTH_PASSWORD Auth Password
Author: Boyan Peychev <boyan@cloudns.net>
'
# Author: Boyan Peychev <boyan at cloudns dot net>
# Repository: https://github.com/ClouDNS/acme.sh/
# Editor: I Komang Suryadana
#CLOUDNS_AUTH_ID=XXXXX
#CLOUDNS_SUB_AUTH_ID=XXXXX
#CLOUDNS_AUTH_PASSWORD="YYYYYYYYY"
CLOUDNS_API="https://api.cloudns.net" CLOUDNS_API="https://api.cloudns.net"
DOMAIN_TYPE= DOMAIN_TYPE=
DOMAIN_MASTER= DOMAIN_MASTER=
@@ -81,7 +78,7 @@ dns_cloudns_rm() {
return 1 return 1
fi fi
for i in $(echo "$response" | tr '{' "\n" | grep -- "$record"); do for i in $(echo "$response" | tr '{' "\n" | grep "$record"); do
record_id=$(echo "$i" | tr ',' "\n" | grep -E '^"id"' | sed -re 's/^\"id\"\:\"([0-9]+)\"$/\1/g') record_id=$(echo "$i" | tr ',' "\n" | grep -E '^"id"' | sed -re 's/^\"id\"\:\"([0-9]+)\"$/\1/g')
if [ -n "$record_id" ]; then if [ -n "$record_id" ]; then
+3 -10
View File
@@ -1,14 +1,7 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_cn_info='Core-Networks.de # DNS API for acme.sh for Core-Networks (https://beta.api.core-networks.de/doc/).
Site: beta.api.Core-Networks.de/doc/ # created by 5ll and francis
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cn
Options:
CN_User User
CN_Password Password
Issues: github.com/acmesh-official/acme.sh/issues/2142
Author: 5ll, francis
'
CN_API="https://beta.api.core-networks.de" CN_API="https://beta.api.core-networks.de"
-11
View File
@@ -1,15 +1,4 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_conoha_info='ConoHa.jp
Domains: ConoHa.io
Site: ConoHa.jp
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_conoha
Options:
CONOHA_Username Username
CONOHA_Password Password
CONOHA_TenantId TenantId
CONOHA_IdentityServiceApi Identity Service API. E.g. "https://identity.xxxx.conoha.io/v2.0"
'
CONOHA_DNS_EP_PREFIX_REGEXP="https://dns-service\." CONOHA_DNS_EP_PREFIX_REGEXP="https://dns-service\."
+4 -10
View File
@@ -1,16 +1,10 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_constellix_info='Constellix.com # Author: Wout Decre <wout@canodus.be>
Site: Constellix.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_constellix
Options:
CONSTELLIX_Key API Key
CONSTELLIX_Secret API Secret
Issues: github.com/acmesh-official/acme.sh/issues/2724
Author: Wout Decre <wout@canodus.be>
'
CONSTELLIX_Api="https://api.dns.constellix.com/v1" CONSTELLIX_Api="https://api.dns.constellix.com/v1"
#CONSTELLIX_Key="XXX"
#CONSTELLIX_Secret="XXX"
######## Public functions ##################### ######## Public functions #####################
+13 -13
View File
@@ -1,18 +1,18 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034 #
dns_cpanel_info='cPanel Server API #Author: Bjarne Saltbaek
Manage DNS via cPanel Dashboard. #Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/3732
Site: cPanel.net #
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_cpanel #
Options:
cPanel_Username Username
cPanel_Apitoken API Token
cPanel_Hostname Server URL. E.g. "https://hostname:port"
Issues: github.com/acmesh-official/acme.sh/issues/3732
Author: Bjarne Saltbaek
'
######## Public functions ##################### ######## Public functions #####################
#
# Export CPANEL username,api token and hostname in the following variables
#
# cPanel_Username=username
# cPanel_Apitoken=apitoken
# cPanel_Hostname=hostname
#
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Used to add txt record # Used to add txt record
dns_cpanel_add() { dns_cpanel_add() {
+5 -11
View File
@@ -1,15 +1,9 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_curanet_info='Curanet.dk #Script to use with curanet.dk, scannet.dk, wannafind.dk, dandomain.dk DNS management.
Domains: scannet.dk wannafind.dk dandomain.dk #Requires api credentials with scope: dns
Site: Curanet.dk #Author: Peter L. Hansen <peter@r12.dk>
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_curanet #Version 1.0
Options:
CURANET_AUTHCLIENTID Auth ClientID. Requires scope dns
CURANET_AUTHSECRET Auth Secret
Issues: github.com/acmesh-official/acme.sh/issues/3933
Author: Peter L. Hansen <peter@r12.dk>
'
CURANET_REST_URL="https://api.curanet.dk/dns/v1/Domains" CURANET_REST_URL="https://api.curanet.dk/dns/v1/Domains"
CURANET_AUTH_URL="https://apiauth.dk.team.blue/auth/realms/Curanet/protocol/openid-connect/token" CURANET_AUTH_URL="https://apiauth.dk.team.blue/auth/realms/Curanet/protocol/openid-connect/token"
+17 -11
View File
@@ -1,15 +1,21 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_cyon_info='cyon.ch ########
Site: cyon.ch # Custom cyon.ch DNS API for use with [acme.sh](https://github.com/acmesh-official/acme.sh)
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cyon #
Options: # Usage: acme.sh --issue --dns dns_cyon -d www.domain.com
CY_Username Username #
CY_Password API Token # Dependencies:
CY_OTP_Secret OTP token. Only required if using 2FA # -------------
Issues: github.com/noplanman/cyon-api/issues # - oathtool (When using 2 Factor Authentication)
Author: Armando Lüscher <armando@noplanman.ch> #
' # Issues:
# -------
# Any issues / questions / suggestions can be posted here:
# https://github.com/noplanman/cyon-api/issues
#
# Author: Armando Lüscher <armando@noplanman.ch>
########
dns_cyon_add() { dns_cyon_add() {
_cyon_load_credentials && _cyon_load_credentials &&
+27 -10
View File
@@ -1,14 +1,31 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034 # -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*-
dns_da_info='DirectAdmin Server API # vim: et ts=2 sw=2
Site: DirectAdmin.com/api.php #
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_da # DirectAdmin 1.41.0 API
Options: # The DirectAdmin interface has it's own Let's encrypt functionality, but this
DA_Api API Server URL. E.g. "https://remoteUser:remotePassword@da.domain.tld:8443" # script can be used to generate certificates for names which are not hosted on
DA_Api_Insecure Insecure TLS. 0: check for cert validity, 1: always accept # DirectAdmin
Issues: github.com/TigerP/acme.sh/issues #
' # User must provide login data and URL to DirectAdmin incl. port.
# You can create login key, by using the Login Keys function
# ( https://da.example.com:8443/CMD_LOGIN_KEYS ), which only has access to
# - CMD_API_DNS_CONTROL
# - CMD_API_SHOW_DOMAINS
#
# See also https://www.directadmin.com/api.php and
# https://www.directadmin.com/features.php?id=1298
#
# Report bugs to https://github.com/TigerP/acme.sh/issues
#
# Values to export:
# export DA_Api="https://remoteUser:remotePassword@da.example.com:8443"
# export DA_Api_Insecure=1
#
# Set DA_Api_Insecure to 1 for insecure and 0 for secure -> difference is
# whether ssl cert is checked for validity (0) or whether it is just accepted
# (1)
#
######## Public functions ##################### ######## Public functions #####################
# Usage: dns_myapi_add _acme-challenge.www.example.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" # Usage: dns_myapi_add _acme-challenge.www.example.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+12 -9
View File
@@ -1,13 +1,16 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_ddnss_info='DDNSS.de #Created by RaidenII, to use DuckDNS's API to add/remove text records
Site: DDNSS.de #modified by helbgd @ 03/13/2018 to support ddnss.de
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ddnss #modified by mod242 @ 04/24/2018 to support different ddnss domains
Options: #Please note: the Wildcard Feature must be turned on for the Host record
DDNSS_Token API Token #and the checkbox for TXT needs to be enabled
Issues: github.com/acmesh-official/acme.sh/issues/2230
Author: RaidenII, helbgd, mod242 # Pass credentials before "acme.sh --issue --dns dns_ddnss ..."
' # --
# export DDNSS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
# --
#
DDNSS_DNS_API="https://ddnss.de/upd.php" DDNSS_DNS_API="https://ddnss.de/upd.php"
+7 -9
View File
@@ -1,13 +1,11 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034 #
dns_desec_info='deSEC.io # deSEC.io Domain API
Site: desec.readthedocs.io/en/latest/ #
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_desec # Author: Zheng Qian
Options: #
DDNSS_Token API Token # deSEC API doc
Issues: github.com/acmesh-official/acme.sh/issues/2180 # https://desec.readthedocs.io/en/latest/
Author: Zheng Qian
'
REST_API="https://desec.io/api/v1/domains" REST_API="https://desec.io/api/v1/domains"
+14 -11
View File
@@ -1,15 +1,18 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_df_info='DynDnsFree.de ########################################################################
Domains: dynup.de # https://dyndnsfree.de hook script for acme.sh
Site: DynDnsFree.de #
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_df # Environment variables:
Options: #
DF_user Username # - $DF_user (your dyndnsfree.de username)
DF_password Password # - $DF_password (your dyndnsfree.de password)
Issues: github.com/acmesh-official/acme.sh/issues/2897 #
Author: Thilo Gass <thilo.gass@gmail.com> # Author: Thilo Gass <thilo.gass@gmail.com>
' # Git repo: https://github.com/ThiloGa/acme.sh
#-- dns_df_add() - Add TXT record --------------------------------------
# Usage: dns_df_add _acme-challenge.subdomain.domain.com "XyZ123..."
dyndnsfree_api="https://dynup.de/acme.php" dyndnsfree_api="https://dynup.de/acme.php"
+12 -8
View File
@@ -1,12 +1,16 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_dgon_info='DigitalOcean.com ## Will be called by acme.sh to add the txt record to your api system.
Site: DigitalOcean.com/help/api/ ## returns 0 means success, otherwise error.
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dgon
Options: ## Author: thewer <github at thewer.com>
DO_API_KEY API Key ## GitHub: https://github.com/gitwer/acme.sh
Author: <github@thewer.com>
' ##
## Environment Variables Required:
##
## DO_API_KEY="75310dc4ca779ac39a19f6355db573b49ce92ae126553ebd61ac3a3ae34834cc"
##
##################### Public functions ##################### ##################### Public functions #####################
-188
View File
@@ -1,188 +0,0 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_dnsexit_info='DNSExit.com
Site: DNSExit.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_dnsexit
Options:
DNSEXIT_API_KEY API Key
DNSEXIT_AUTH_USER Username
DNSEXIT_AUTH_PASS Password
Issues: github.com/acmesh-official/acme.sh/issues/4719
Author: Samuel Jimenez
'
DNSEXIT_API_URL="https://api.dnsexit.com/dns/"
DNSEXIT_HOSTS_URL="https://update.dnsexit.com/ipupdate/hosts.jsp"
######## Public functions #####################
#Usage: dns_dnsexit_add _acme-challenge.*.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_dnsexit_add() {
fulldomain=$1
txtvalue=$2
_info "Using DNSExit.com"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_debug 'Load account auth'
if ! get_account_info; then
return 1
fi
_debug 'First detect the root zone'
if ! _get_root "$fulldomain"; then
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
if ! _dnsexit_rest "{\"domain\":\"$_domain\",\"add\":{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":0,\"overwrite\":false}}"; then
_err "$response"
return 1
fi
_debug2 _response "$response"
return 0
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_dnsexit_rm() {
fulldomain=$1
txtvalue=$2
_info "Using DNSExit.com"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_debug 'Load account auth'
if ! get_account_info; then
return 1
fi
_debug 'First detect the root zone'
if ! _get_root "$fulldomain"; then
_err "$response"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
if ! _dnsexit_rest "{\"domain\":\"$_domain\",\"delete\":{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\"}}"; then
_err "$response"
return 1
fi
_debug2 _response "$response"
return 0
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain=$1
i=1
while true; do
_domain=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$_domain"
if [ -z "$_domain" ]; then
return 1
fi
_debug login "$DNSEXIT_AUTH_USER"
_debug password "$DNSEXIT_AUTH_PASS"
_debug domain "$_domain"
_dnsexit_http "login=$DNSEXIT_AUTH_USER&password=$DNSEXIT_AUTH_PASS&domain=$_domain"
if _contains "$response" "0=$_domain"; then
_sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")"
return 0
else
_debug "Go to next level of $_domain"
fi
i=$(_math "$i" + 1)
done
return 1
}
_dnsexit_rest() {
m=POST
ep=""
data="$1"
_debug _dnsexit_rest "$ep"
_debug data "$data"
api_key_trimmed=$(echo "$DNSEXIT_API_KEY" | tr -d '"')
export _H1="apikey: $api_key_trimmed"
export _H2='Content-Type: application/json'
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$DNSEXIT_API_URL/$ep" "" "$m")"
else
response="$(_get "$DNSEXIT_API_URL/$ep")"
fi
if [ "$?" != "0" ]; then
_err "Error $ep"
return 1
fi
_debug2 response "$response"
return 0
}
_dnsexit_http() {
m=GET
param="$1"
_debug param "$param"
_debug get "$DNSEXIT_HOSTS_URL?$param"
response="$(_get "$DNSEXIT_HOSTS_URL?$param")"
_debug response "$response"
if [ "$?" != "0" ]; then
_err "Error $param"
return 1
fi
_debug2 response "$response"
return 0
}
get_account_info() {
DNSEXIT_API_KEY="${DNSEXIT_API_KEY:-$(_readaccountconf_mutable DNSEXIT_API_KEY)}"
if test -z "$DNSEXIT_API_KEY"; then
DNSEXIT_API_KEY=''
_err 'DNSEXIT_API_KEY was not exported'
return 1
fi
_saveaccountconf_mutable DNSEXIT_API_KEY "$DNSEXIT_API_KEY"
DNSEXIT_AUTH_USER="${DNSEXIT_AUTH_USER:-$(_readaccountconf_mutable DNSEXIT_AUTH_USER)}"
if test -z "$DNSEXIT_AUTH_USER"; then
DNSEXIT_AUTH_USER=""
_err 'DNSEXIT_AUTH_USER was not exported'
return 1
fi
_saveaccountconf_mutable DNSEXIT_AUTH_USER "$DNSEXIT_AUTH_USER"
DNSEXIT_AUTH_PASS="${DNSEXIT_AUTH_PASS:-$(_readaccountconf_mutable DNSEXIT_AUTH_PASS)}"
if test -z "$DNSEXIT_AUTH_PASS"; then
DNSEXIT_AUTH_PASS=""
_err 'DNSEXIT_AUTH_PASS was not exported'
return 1
fi
_saveaccountconf_mutable DNSEXIT_AUTH_PASS "$DNSEXIT_AUTH_PASS"
return 0
}
+11 -10
View File
@@ -1,14 +1,15 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_dnshome_info='dnsHome.de # dnsHome.de API for acme.sh
Site: dnsHome.de #
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_dnshome # This Script adds the necessary TXT record to a Subdomain
Options: #
DNSHOME_Subdomain Subdomain # Author dnsHome.de (https://github.com/dnsHome-de)
DNSHOME_SubdomainPassword Subdomain Password #
Issues: github.com/acmesh-official/acme.sh/issues/3819 # Report Bugs to https://github.com/acmesh-official/acme.sh/issues/3819
Author: dnsHome.de https://github.com/dnsHome-de #
' # export DNSHOME_Subdomain=""
# export DNSHOME_SubdomainPassword=""
# Usage: add subdomain.ddnsdomain.tld "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" # Usage: add subdomain.ddnsdomain.tld "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Used to add txt record # Used to add txt record
+8 -8
View File
@@ -1,12 +1,12 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_dnsimple_info='DNSimple.com # DNSimple domain api
Site: DNSimple.com # https://github.com/pho3nixf1re/acme.sh/issues
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dnsimple #
Options: # This is your oauth token which can be acquired on the account page. Please
DNSimple_OAUTH_TOKEN OAuth Token # note that this must be an _account_ token and not a _user_ token.
Issues: github.com/pho3nixf1re/acme.sh/issues # https://dnsimple.com/a/<your account id>/account/access_tokens
' # DNSimple_OAUTH_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje"
DNSimple_API="https://api.dnsimple.com/v2" DNSimple_API="https://api.dnsimple.com/v2"
+7 -10
View File
@@ -1,15 +1,12 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_dnsservices_info='DNS.Services
Site: DNS.Services
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_dnsservices
Options:
DnsServices_Username Username
DnsServices_Password Password
Issues: github.com/acmesh-official/acme.sh/issues/4152
Author: Bjarke Bruun <bbruun@gmail.com>
'
#This file name is "dns_dnsservices.sh"
#Script for Danish DNS registra and DNS hosting provider https://dns.services
#Author: Bjarke Bruun <bbruun@gmail.com>
#Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/4152
# Global variable to connect to the DNS.Services API
DNSServices_API=https://dns.services/api DNSServices_API=https://dns.services/api
######## Public functions ##################### ######## Public functions #####################
+148
View File
@@ -0,0 +1,148 @@
#!/usr/bin/env sh
# DNS API for Domain-Offensive / Resellerinterface / Domainrobot
# Report bugs at https://github.com/seidler2547/acme.sh/issues
# set these environment variables to match your customer ID and password:
# DO_PID="KD-1234567"
# DO_PW="cdfkjl3n2"
DO_URL="https://soap.resellerinterface.de/"
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_do_add() {
fulldomain=$1
txtvalue=$2
if _dns_do_authenticate; then
_info "Adding TXT record to ${_domain} as ${fulldomain}"
_dns_do_soap createRR origin "${_domain}" name "${fulldomain}" type TXT data "${txtvalue}" ttl 300
if _contains "${response}" '>success<'; then
return 0
fi
_err "Could not create resource record, check logs"
fi
return 1
}
#fulldomain
dns_do_rm() {
fulldomain=$1
if _dns_do_authenticate; then
if _dns_do_list_rrs; then
_dns_do_had_error=0
for _rrid in ${_rr_list}; do
_info "Deleting resource record $_rrid for $_domain"
_dns_do_soap deleteRR origin "${_domain}" rrid "${_rrid}"
if ! _contains "${response}" '>success<'; then
_dns_do_had_error=1
_err "Could not delete resource record for ${_domain}, id ${_rrid}"
fi
done
return $_dns_do_had_error
fi
fi
return 1
}
#################### Private functions below ##################################
_dns_do_authenticate() {
_info "Authenticating as ${DO_PID}"
_dns_do_soap authPartner partner "${DO_PID}" password "${DO_PW}"
if _contains "${response}" '>success<'; then
_get_root "$fulldomain"
_debug "_domain $_domain"
return 0
else
_err "Authentication failed, are DO_PID and DO_PW set correctly?"
fi
return 1
}
_dns_do_list_rrs() {
_dns_do_soap getRRList origin "${_domain}"
if ! _contains "${response}" 'SOAP-ENC:Array'; then
_err "getRRList origin ${_domain} failed"
return 1
fi
_rr_list="$(echo "${response}" |
tr -d "\n\r\t" |
sed -e 's/<item xsi:type="ns2:Map">/\n/g' |
grep ">$(_regexcape "$fulldomain")</value>" |
sed -e 's/<\/item>/\n/g' |
grep '>id</key><value' |
_egrep_o '>[0-9]{1,16}<' |
tr -d '><')"
[ "${_rr_list}" ]
}
_dns_do_soap() {
func="$1"
shift
# put the parameters to xml
body="<tns:${func} xmlns:tns=\"${DO_URL}\">"
while [ "$1" ]; do
_k="$1"
shift
_v="$1"
shift
body="$body<$_k>$_v</$_k>"
done
body="$body</tns:${func}>"
_debug2 "SOAP request ${body}"
# build SOAP XML
_xml='<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body>'"$body"'</env:Body>
</env:Envelope>'
# set SOAP headers
export _H1="SOAPAction: ${DO_URL}#${func}"
if ! response="$(_post "${_xml}" "${DO_URL}")"; then
_err "Error <$1>"
return 1
fi
_debug2 "SOAP response $response"
# retrieve cookie header
_H2="$(_egrep_o 'Cookie: [^;]+' <"$HTTP_HEADER" | _head_n 1)"
export _H2
return 0
}
_get_root() {
domain=$1
i=1
_dns_do_soap getDomainList
_all_domains="$(echo "${response}" |
tr -d "\n\r\t " |
_egrep_o 'domain</key><value[^>]+>[^<]+' |
sed -e 's/^domain<\/key><value[^>]*>//g')"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
return 1
fi
if _contains "${_all_domains}" "^$(_regexcape "$h")\$"; then
_domain="$h"
return 0
fi
i=$(_math $i + 1)
done
_debug "$domain not found"
return 1
}
_regexcape() {
echo "$1" | sed -e 's/\([]\.$*^[]\)/\\\1/g'
}
+8 -11
View File
@@ -1,15 +1,12 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_doapi_info='Domain-Offensive do.de # Official Let's Encrypt API for do.de / Domain-Offensive
Official LetsEncrypt API for do.de / Domain-Offensive. #
This is different from the dns_do adapter, because dns_do is only usable for enterprise customers. # This is different from the dns_do adapter, because dns_do is only usable for enterprise customers
This API is also available to private customers/individuals. # This API is also available to private customers/individuals
Site: do.de #
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_doapi # Provide the required LetsEncrypt token like this:
Options: # DO_LETOKEN="FmD408PdqT1E269gUK57"
DO_LETOKEN LetsEncrypt Token
Issues: github.com/acmesh-official/acme.sh/issues/2057
'
DO_API="https://www.do.de/api/letsencrypt" DO_API="https://www.do.de/api/letsencrypt"
-9
View File
@@ -1,13 +1,4 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_domeneshop_info='DomeneShop.no
Site: DomeneShop.no
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_domeneshop
Options:
DOMENESHOP_Token Token
DOMENESHOP_Secret Secret
Issues: github.com/acmesh-official/acme.sh/issues/2457
'
DOMENESHOP_Api_Endpoint="https://api.domeneshop.no/v0" DOMENESHOP_Api_Endpoint="https://api.domeneshop.no/v0"
+6 -8
View File
@@ -1,12 +1,10 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_dp_info='DNSPod.cn # Dnspod.cn Domain api
Site: DNSPod.cn #
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dp #DP_Id="1234"
Options: #
DP_Id Id #DP_Key="sADDsdasdgdsf"
DP_Key Key
'
REST_API="https://dnsapi.cn" REST_API="https://dnsapi.cn"
+6 -8
View File
@@ -1,12 +1,10 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_dpi_info='DNSPod.com # Dnspod.com Domain api
Site: DNSPod.com #
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dpi #DPI_Id="1234"
Options: #
DPI_Id Id #DPI_Key="sADDsdasdgdsf"
DPI_Key Key
'
REST_API="https://api.dnspod.com" REST_API="https://api.dnspod.com"
+5 -9
View File
@@ -1,14 +1,10 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_dreamhost_info='DreamHost.com
Site: DreamHost.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dreamhost
Options:
DH_API_KEY API Key
Issues: github.com/RhinoLance/acme.sh
Author: RhinoLance
'
#Author: RhinoLance
#Report Bugs here: https://github.com/RhinoLance/acme.sh
#
#define the api endpoint
DH_API_ENDPOINT="https://api.dreamhost.com/" DH_API_ENDPOINT="https://api.dreamhost.com/"
querystring="" querystring=""
+10 -8
View File
@@ -1,12 +1,14 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_duckdns_info='DuckDNS.org #Created by RaidenII, to use DuckDNS's API to add/remove text records
Site: www.DuckDNS.org #06/27/2017
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns
Options: # Pass credentials before "acme.sh --issue --dns dns_duckdns ..."
DuckDNS_Token API Token # --
Author: RaidenII # export DuckDNS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
' # --
#
# Due to the fact that DuckDNS uses StartSSL as cert provider, --insecure may need to be used with acme.sh
DuckDNS_API="https://www.duckdns.org/update" DuckDNS_API="https://www.duckdns.org/update"
+3 -9
View File
@@ -1,13 +1,7 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_durabledns_info='DurableDNS.com #DD_API_User="xxxxx"
Site: DurableDNS.com #DD_API_Key="xxxxxx"
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_durabledns
Options:
DD_API_User API User
DD_API_Key API Key
Issues: github.com/acmesh-official/acme.sh/issues/2281
'
_DD_BASE="https://durabledns.com/services/dns" _DD_BASE="https://durabledns.com/services/dns"
+13 -12
View File
@@ -1,16 +1,10 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034 #
dns_dyn_info='Dyn.com # Dyn.com Domain API
Domains: dynect.net #
Site: Dyn.com # Author: Gerd Naschenweng
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dyn # https://github.com/magicdude4eva
Options: #
DYN_Customer Customer
DYN_Username API Username
DYN_Password Secret
Author: Gerd Naschenweng <https://github.com/magicdude4eva>
'
# Dyn Managed DNS API # Dyn Managed DNS API
# https://help.dyn.com/dns-api-knowledge-base/ # https://help.dyn.com/dns-api-knowledge-base/
# #
@@ -26,6 +20,13 @@ Author: Gerd Naschenweng <https://github.com/magicdude4eva>
# ZoneRemoveNode # ZoneRemoveNode
# ZonePublish # ZonePublish
# -- # --
#
# Pass credentials before "acme.sh --issue --dns dns_dyn ..."
# --
# export DYN_Customer="customer"
# export DYN_Username="apiuser"
# export DYN_Password="secret"
# --
DYN_API="https://api.dynect.net/REST" DYN_API="https://api.dynect.net/REST"
+10 -11
View File
@@ -1,21 +1,20 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_dynu_info='Dynu.com
Site: Dynu.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dynu
Options:
Dynu_ClientId Client ID
Dynu_Secret Secret
Issues: github.com/shar0119/acme.sh
Author: Dynu Systems Inc
'
#Client ID
#Dynu_ClientId="0b71cae7-a099-4f6b-8ddf-94571cdb760d"
#
#Secret
#Dynu_Secret="aCUEY4BDCV45KI8CSIC3sp2LKQ9"
#
#Token #Token
Dynu_Token="" Dynu_Token=""
# #
#Endpoint #Endpoint
Dynu_EndPoint="https://api.dynu.com/v2" Dynu_EndPoint="https://api.dynu.com/v2"
#
#Author: Dynu Systems, Inc.
#Report Bugs here: https://github.com/shar0119/acme.sh
#
######## Public functions ##################### ######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+4 -11
View File
@@ -1,15 +1,8 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034 #Author StefanAbl
dns_dynv6_info='DynV6.com #Usage specify a private keyfile to use with dynv6 'export KEY="path/to/keyfile"'
Site: DynV6.com #or use the HTTP REST API by by specifying a token 'export DYNV6_TOKEN="value"
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_dynv6 #if no keyfile is specified, you will be asked if you want to create one in /home/$USER/.ssh/dynv6 and /home/$USER/.ssh/dynv6.pub
Options:
DYNV6_TOKEN REST API token. Get from https://DynV6.com/keys
OptionsAlt:
KEY Path to SSH private key file. E.g. "/root/.ssh/dynv6"
Issues: github.com/acmesh-official/acme.sh/issues/2702
Author: StefanAbl
'
dynv6_api="https://dynv6.com/api/v2" dynv6_api="https://dynv6.com/api/v2"
######## Public functions ##################### ######## Public functions #####################
+8 -11
View File
@@ -1,17 +1,14 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_easydns_info='easyDNS.net
Site: easyDNS.net
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_easydns
Options:
EASYDNS_Token API Token
EASYDNS_Key API Key
Issues: github.com/acmesh-official/acme.sh/issues/2647
Author: Neilpang, wurzelpanzer <wurzelpanzer@maximolider.net>
'
#######################################################
#
# easyDNS REST API for acme.sh by Neilpang based on dns_cf.sh
#
# API Documentation: https://sandbox.rest.easydns.net:3001/ # API Documentation: https://sandbox.rest.easydns.net:3001/
#
# Author: wurzelpanzer [wurzelpanzer@maximolider.net]
# Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/2647
#
#################### Public functions ################# #################### Public functions #################
#EASYDNS_Key="xxxxxxxxxxxxxxxxxxxxxxxx" #EASYDNS_Key="xxxxxxxxxxxxxxxxxxxxxxxx"
+11 -14
View File
@@ -1,15 +1,4 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_edgedns_info='Akamai.com Edge DNS
Site: techdocs.Akamai.com/edge-dns/reference/edge-dns-api
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_edgedns
Options: Specify individual credentials
AKAMAI_HOST Host
AKAMAI_ACCESS_TOKEN Access token
AKAMAI_CLIENT_TOKEN Client token
AKAMAI_CLIENT_SECRET Client secret
Issues: github.com/acmesh-official/acme.sh/issues/3157
'
# Akamai Edge DNS v2 API # Akamai Edge DNS v2 API
# User must provide Open Edgegrid API credentials to the EdgeDNS installation. The remote user in EdgeDNS must have CRUD access to # User must provide Open Edgegrid API credentials to the EdgeDNS installation. The remote user in EdgeDNS must have CRUD access to
@@ -17,10 +6,18 @@ Issues: github.com/acmesh-official/acme.sh/issues/3157
# Report bugs to https://control.akamai.com/apps/support-ui/#/contact-support # Report bugs to https://control.akamai.com/apps/support-ui/#/contact-support
# Values to export:
# --EITHER--
# *** TBD. NOT IMPLEMENTED YET *** # *** TBD. NOT IMPLEMENTED YET ***
# Specify Edgegrid credentials file and section. # specify Edgegrid credentials file and section
# AKAMAI_EDGERC Edge RC. Full file path # AKAMAI_EDGERC=<full file path>
# AKAMAI_EDGERC_SECTION Edge RC Section. E.g. "default" # AKAMAI_EDGERC_SECTION="default"
## --OR--
# specify indiviual credentials
# export AKAMAI_HOST = <host>
# export AKAMAI_ACCESS_TOKEN = <access token>
# export AKAMAI_CLIENT_TOKEN = <client token>
# export AKAMAI_CLIENT_SECRET = <client secret>
ACME_EDGEDNS_VERSION="0.1.0" ACME_EDGEDNS_VERSION="0.1.0"
+14 -10
View File
@@ -1,14 +1,18 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_euserv_info='EUserv.com #This is the euserv.eu api wrapper for acme.sh
Domains: EUserv.eu #
Site: EUserv.com #Author: Michael Brueckner
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_euserv #Report Bugs: https://www.github.com/initit/acme.sh or mbr@initit.de
Options:
EUSERV_Username Username #
EUSERV_Password Password #EUSERV_Username="username"
Author: Michael Brueckner #
' #EUSERV_Password="password"
#
# Dependencies:
# -------------
# - none -
EUSERV_Api="https://api.euserv.net" EUSERV_Api="https://api.euserv.net"
-8
View File
@@ -1,12 +1,4 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_exoscale_info='Exoscale.com
Site: Exoscale.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_exoscale
Options:
EXOSCALE_API_KEY API Key
EXOSCALE_SECRET_KEY API Secret key
'
EXOSCALE_API=https://api.exoscale.com/dns/v1 EXOSCALE_API=https://api.exoscale.com/dns/v1
+2 -9
View File
@@ -1,13 +1,6 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_fornex_info='Fornex.com #Author: Timur Umarov <inbox@tumarov.com>
Site: Fornex.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_fornex
Options:
FORNEX_API_KEY API Key
Issues: github.com/acmesh-official/acme.sh/issues/3998
Author: Timur Umarov <inbox@tumarov.com>
'
FORNEX_API_URL="https://fornex.com/api/dns/v0.1" FORNEX_API_URL="https://fornex.com/api/dns/v0.1"
+9 -10
View File
@@ -1,15 +1,14 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_freedns_info='FreeDNS
Site: FreeDNS.afraid.org
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_freedns
Options:
FREEDNS_User Username
FREEDNS_Password Password
Issues: github.com/acmesh-official/acme.sh/issues/2305
Author: David Kerr <https://github.com/dkerr64>
'
#This file name is "dns_freedns.sh"
#So, here must be a method dns_freedns_add()
#Which will be called by acme.sh to add the txt record to your api system.
#returns 0 means success, otherwise error.
#
#Author: David Kerr
#Report Bugs here: https://github.com/dkerr64/acme.sh
#or here... https://github.com/acmesh-official/acme.sh/issues/2305
#
######## Public functions ##################### ######## Public functions #####################
# Export FreeDNS userid and password in following variables... # Export FreeDNS userid and password in following variables...
+18 -34
View File
@@ -1,42 +1,31 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_gandi_livedns_info='Gandi.net LiveDNS
Site: Gandi.net/domain/dns
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_gandi_livedns
Options:
GANDI_LIVEDNS_KEY API Key
Issues: github.com/fcrozat/acme.sh
Author: Frédéric Crozat <fcrozat@suse.com>, Dominik Röttsches <drott@google.com>
'
# Gandi LiveDNS v5 API # Gandi LiveDNS v5 API
# https://api.gandi.net/docs/livedns/ # https://doc.livedns.gandi.net/
# https://api.gandi.net/docs/authentication/ for token + apikey (deprecated) authentication
# currently under beta # currently under beta
#
# Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable
#
#Author: Frédéric Crozat <fcrozat@suse.com>
# Dominik Röttsches <drott@google.com>
#Report Bugs here: https://github.com/fcrozat/acme.sh
#
######## Public functions ##################### ######## Public functions #####################
GANDI_LIVEDNS_API="https://api.gandi.net/v5/livedns" GANDI_LIVEDNS_API="https://dns.api.gandi.net/api/v5"
#Usage: dns_gandi_livedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" #Usage: dns_gandi_livedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_gandi_livedns_add() { dns_gandi_livedns_add() {
fulldomain=$1 fulldomain=$1
txtvalue=$2 txtvalue=$2
if [ -z "$GANDI_LIVEDNS_KEY" ] && [ -z "$GANDI_LIVEDNS_TOKEN" ]; then if [ -z "$GANDI_LIVEDNS_KEY" ]; then
_err "No Token or API key (deprecated) specified for Gandi LiveDNS." _err "No API key specified for Gandi LiveDNS."
_err "Create your token or key and export it as GANDI_LIVEDNS_KEY or GANDI_LIVEDNS_TOKEN respectively" _err "Create your key and export it as GANDI_LIVEDNS_KEY"
return 1 return 1
fi fi
# Keep only one secret in configuration _saveaccountconf GANDI_LIVEDNS_KEY "$GANDI_LIVEDNS_KEY"
if [ -n "$GANDI_LIVEDNS_TOKEN" ]; then
_saveaccountconf GANDI_LIVEDNS_TOKEN "$GANDI_LIVEDNS_TOKEN"
_clearaccountconf GANDI_LIVEDNS_KEY
elif [ -n "$GANDI_LIVEDNS_KEY" ]; then
_saveaccountconf GANDI_LIVEDNS_KEY "$GANDI_LIVEDNS_KEY"
_clearaccountconf GANDI_LIVEDNS_TOKEN
fi
_debug "First detect the root zone" _debug "First detect the root zone"
if ! _get_root "$fulldomain"; then if ! _get_root "$fulldomain"; then
@@ -81,7 +70,7 @@ dns_gandi_livedns_rm() {
_gandi_livedns_rest PUT \ _gandi_livedns_rest PUT \
"domains/$_domain/records/$_sub_domain/TXT" \ "domains/$_domain/records/$_sub_domain/TXT" \
"{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" && "{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" &&
_contains "$response" '{"message":"DNS Record Created"}' && _contains "$response" '{"message": "DNS Record Created"}' &&
_info "Removing record $(__green "success")" _info "Removing record $(__green "success")"
} }
@@ -137,7 +126,7 @@ _dns_gandi_append_record() {
_debug new_rrset_values "$_rrset_values" _debug new_rrset_values "$_rrset_values"
_gandi_livedns_rest PUT "domains/$_domain/records/$sub_domain/TXT" \ _gandi_livedns_rest PUT "domains/$_domain/records/$sub_domain/TXT" \
"{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" && "{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" &&
_contains "$response" '{"message":"DNS Record Created"}' && _contains "$response" '{"message": "DNS Record Created"}' &&
_info "Adding record $(__green "success")" _info "Adding record $(__green "success")"
} }
@@ -147,11 +136,11 @@ _dns_gandi_existing_rrset_values() {
if ! _gandi_livedns_rest GET "domains/$domain/records/$sub_domain"; then if ! _gandi_livedns_rest GET "domains/$domain/records/$sub_domain"; then
return 1 return 1
fi fi
if ! _contains "$response" '"rrset_type":"TXT"'; then if ! _contains "$response" '"rrset_type": "TXT"'; then
_debug "Does not have a _acme-challenge TXT record yet." _debug "Does not have a _acme-challenge TXT record yet."
return 1 return 1
fi fi
if _contains "$response" '"rrset_values":\[\]'; then if _contains "$response" '"rrset_values": \[\]'; then
_debug "Empty rrset_values for TXT record, no previous TXT record." _debug "Empty rrset_values for TXT record, no previous TXT record."
return 1 return 1
fi fi
@@ -168,12 +157,7 @@ _gandi_livedns_rest() {
_debug "$ep" _debug "$ep"
export _H1="Content-Type: application/json" export _H1="Content-Type: application/json"
export _H2="X-Api-Key: $GANDI_LIVEDNS_KEY"
if [ -n "$GANDI_LIVEDNS_TOKEN" ]; then
export _H2="Authorization: Bearer $GANDI_LIVEDNS_TOKEN"
else
export _H2="Authorization: Apikey $GANDI_LIVEDNS_KEY"
fi
if [ "$m" = "GET" ]; then if [ "$m" = "GET" ]; then
response="$(_get "$GANDI_LIVEDNS_API/$ep")" response="$(_get "$GANDI_LIVEDNS_API/$ep")"
+3 -9
View File
@@ -1,12 +1,6 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_gcloud_info='Google Cloud DNS # Author: Janos Lenart <janos@lenart.io>
Site: Cloud.Google.com/dns
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_gcloud
Options:
CLOUDSDK_ACTIVE_CONFIG_NAME Active config name. E.g. "default"
Author: Janos Lenart <janos@lenart.io>
'
######## Public functions ##################### ######## Public functions #####################
@@ -48,7 +42,7 @@ dns_gcloud_rm() {
echo "$rrdatas" | grep -F -v -- "\"$txtvalue\"" | _dns_gcloud_add_rrs || return $? echo "$rrdatas" | grep -F -v -- "\"$txtvalue\"" | _dns_gcloud_add_rrs || return $?
_dns_gcloud_execute_tr || return $? _dns_gcloud_execute_tr || return $?
_info "$fulldomain record removed" _info "$fulldomain record added"
} }
#################### Private functions below ################################## #################### Private functions below ##################################
-191
View File
@@ -1,191 +0,0 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_gcore_info='Gcore.com
Site: Gcore.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_gcore
Options:
GCORE_Key API Key
Issues: github.com/acmesh-official/acme.sh/issues/4460
'
GCORE_Api="https://api.gcore.com/dns/v2"
GCORE_Doc="https://api.gcore.com/docs/dns"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_gcore_add() {
fulldomain=$1
txtvalue=$2
GCORE_Key="${GCORE_Key:-$(_readaccountconf_mutable GCORE_Key)}"
if [ -z "$GCORE_Key" ]; then
GCORE_Key=""
_err "You didn't specify a Gcore api key yet."
_err "You can get yours from here $GCORE_Doc"
return 1
fi
#save the api key to the account conf file.
_saveaccountconf_mutable GCORE_Key "$GCORE_Key"
_debug "First detect the zone name"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _zone_name "$_zone_name"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_gcore_rest GET "zones/$_zone_name/$fulldomain/TXT"
payload=""
if echo "$response" | grep "record is not found" >/dev/null; then
_info "Record doesn't exists"
payload="{\"resource_records\":[{\"content\":[\"$txtvalue\"],\"enabled\":true}],\"ttl\":120}"
elif echo "$response" | grep "$txtvalue" >/dev/null; then
_info "Already exists, OK"
return 0
elif echo "$response" | tr -d " " | grep \"name\":\""$fulldomain"\",\"type\":\"TXT\" >/dev/null; then
_info "Record with mismatch txtvalue, try update it"
payload=$(echo "$response" | tr -d " " | sed 's/"updated_at":[0-9]\+,//g' | sed 's/"meta":{}}]}/"meta":{}},{"content":['\""$txtvalue"\"'],"enabled":true}]}/')
fi
# For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so
# we can not use updating anymore.
# count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2)
# _debug count "$count"
# if [ "$count" = "0" ]; then
_info "Adding record"
if _gcore_rest PUT "zones/$_zone_name/$fulldomain/TXT" "$payload"; then
if _contains "$response" "$txtvalue"; then
_info "Added, OK"
return 0
elif _contains "$response" "rrset is already exists"; then
_info "Already exists, OK"
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
return 1
}
#fulldomain txtvalue
dns_gcore_rm() {
fulldomain=$1
txtvalue=$2
GCORE_Key="${GCORE_Key:-$(_readaccountconf_mutable GCORE_Key)}"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _zone_name "$_zone_name"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_gcore_rest GET "zones/$_zone_name/$fulldomain/TXT"
if echo "$response" | grep "record is not found" >/dev/null; then
_info "No such txt recrod"
return 0
fi
if ! echo "$response" | tr -d " " | grep \"name\":\""$fulldomain"\",\"type\":\"TXT\" >/dev/null; then
_err "Error: $response"
return 1
fi
if ! echo "$response" | tr -d " " | grep \""$txtvalue"\" >/dev/null; then
_info "No such txt recrod"
return 0
fi
count="$(echo "$response" | grep -o "content" | wc -l)"
if [ "$count" = "1" ]; then
if ! _gcore_rest DELETE "zones/$_zone_name/$fulldomain/TXT"; then
_err "Delete record error. $response"
return 1
fi
return 0
fi
payload="$(echo "$response" | tr -d " " | sed 's/"updated_at":[0-9]\+,//g' | sed 's/{"id":[0-9]\+,"content":\["'"$txtvalue"'"\],"enabled":true,"meta":{}}//' | sed 's/\[,/\[/' | sed 's/,,/,/' | sed 's/,\]/\]/')"
if ! _gcore_rest PUT "zones/$_zone_name/$fulldomain/TXT" "$payload"; then
_err "Delete record error. $response"
fi
}
#################### Private functions below ##################################
#_acme-challenge.sub.domain.com
#returns
# _sub_domain=_acme-challenge.sub or _acme-challenge
# _domain=domain.com
# _zone_name=domain.com or sub.domain.com
_get_root() {
domain=$1
i=1
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
if ! _gcore_rest GET "zones/$h"; then
return 1
fi
if _contains "$response" "\"name\":\"$h\""; then
_zone_name=$h
if [ "$_zone_name" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
return 1
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_gcore_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
key_trimmed=$(echo "$GCORE_Key" | tr -d '"')
export _H1="Content-Type: application/json"
export _H2="Authorization: APIKey $key_trimmed"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$GCORE_Api/$ep" "" "$m")"
else
response="$(_get "$GCORE_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}
+11 -11
View File
@@ -1,12 +1,12 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_gd_info='GoDaddy.com #Godaddy domain api
Site: GoDaddy.com # Get API key and secret from https://developer.godaddy.com/
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_gd #
Options: # GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
GD_Key API Key # GD_Secret="asdfsdfsfsdfsdfdfsdf"
GD_Secret API Secret #
' # Ex.: acme.sh --issue --staging --dns dns_gd -d "*.s.example.com" -d "s.example.com"
GD_Api="https://api.godaddy.com/v1" GD_Api="https://api.godaddy.com/v1"
@@ -22,8 +22,8 @@ dns_gd_add() {
if [ -z "$GD_Key" ] || [ -z "$GD_Secret" ]; then if [ -z "$GD_Key" ] || [ -z "$GD_Secret" ]; then
GD_Key="" GD_Key=""
GD_Secret="" GD_Secret=""
_err "You didn't specify godaddy api key and secret yet." _err "You don't specify godaddy api key and secret yet."
_err "Please create your key and try again." _err "Please create you key and try again."
return 1 return 1
fi fi
@@ -46,7 +46,7 @@ dns_gd_add() {
fi fi
if _contains "$response" "$txtvalue"; then if _contains "$response" "$txtvalue"; then
_info "This record already exists, skipping" _info "The record is existing, skip"
return 0 return 0
fi fi
+8 -8
View File
@@ -1,12 +1,12 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_geoscaling_info='GeoScaling.com ########################################################################
Site: GeoScaling.com # Geoscaling hook script for acme.sh
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_geoscaling #
Options: # Environment variables:
GEOSCALING_Username Username. This is usually NOT an email address #
GEOSCALING_Password Password # - $GEOSCALING_Username (your Geoscaling username - this is usually NOT an amail address)
' # - $GEOSCALING_Password (your Geoscaling password)
#-- dns_geoscaling_add() - Add TXT record -------------------------------------- #-- dns_geoscaling_add() - Add TXT record --------------------------------------
# Usage: dns_geoscaling_add _acme-challenge.subdomain.domain.com "XyZ123..." # Usage: dns_geoscaling_add _acme-challenge.subdomain.domain.com "XyZ123..."
-178
View File
@@ -1,178 +0,0 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_googledomains_info='Google Domains
Site: Domains.Google.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_googledomains
Options:
GOOGLEDOMAINS_ACCESS_TOKEN API Access Token
GOOGLEDOMAINS_ZONE Zone
Issues: github.com/acmesh-official/acme.sh/issues/4545
Author: Alex Leigh <leigh@alexleigh.me>
'
GOOGLEDOMAINS_API="https://acmedns.googleapis.com/v1/acmeChallengeSets"
######## Public functions ########
#Usage: dns_googledomains_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_googledomains_add() {
fulldomain=$1
txtvalue=$2
_info "Invoking Google Domains ACME DNS API."
if ! _dns_googledomains_setup; then
return 1
fi
zone="$(_dns_googledomains_get_zone "$fulldomain")"
if [ -z "$zone" ]; then
_err "Could not find a Google Domains-managed zone containing the requested domain."
return 1
fi
_debug zone "$zone"
_debug txtvalue "$txtvalue"
_info "Adding TXT record for $fulldomain."
if _dns_googledomains_api "$zone" ":rotateChallenges" "{\"accessToken\":\"$GOOGLEDOMAINS_ACCESS_TOKEN\",\"recordsToAdd\":[{\"fqdn\":\"$fulldomain\",\"digest\":\"$txtvalue\"}],\"keepExpiredRecords\":true}"; then
if _contains "$response" "$txtvalue"; then
_info "TXT record added."
return 0
else
_err "Error adding TXT record."
return 1
fi
fi
_err "Error adding TXT record."
return 1
}
#Usage: dns_googledomains_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_googledomains_rm() {
fulldomain=$1
txtvalue=$2
_info "Invoking Google Domains ACME DNS API."
if ! _dns_googledomains_setup; then
return 1
fi
zone="$(_dns_googledomains_get_zone "$fulldomain")"
if [ -z "$zone" ]; then
_err "Could not find a Google Domains-managed domain based on request."
return 1
fi
_debug zone "$zone"
_debug txtvalue "$txtvalue"
_info "Removing TXT record for $fulldomain."
if _dns_googledomains_api "$zone" ":rotateChallenges" "{\"accessToken\":\"$GOOGLEDOMAINS_ACCESS_TOKEN\",\"recordsToRemove\":[{\"fqdn\":\"$fulldomain\",\"digest\":\"$txtvalue\"}],\"keepExpiredRecords\":true}"; then
if _contains "$response" "$txtvalue"; then
_err "Error removing TXT record."
return 1
else
_info "TXT record removed."
return 0
fi
fi
_err "Error removing TXT record."
return 1
}
######## Private functions ########
_dns_googledomains_setup() {
if [ -n "$GOOGLEDOMAINS_SETUP_COMPLETED" ]; then
return 0
fi
GOOGLEDOMAINS_ACCESS_TOKEN="${GOOGLEDOMAINS_ACCESS_TOKEN:-$(_readaccountconf_mutable GOOGLEDOMAINS_ACCESS_TOKEN)}"
GOOGLEDOMAINS_ZONE="${GOOGLEDOMAINS_ZONE:-$(_readaccountconf_mutable GOOGLEDOMAINS_ZONE)}"
if [ -z "$GOOGLEDOMAINS_ACCESS_TOKEN" ]; then
GOOGLEDOMAINS_ACCESS_TOKEN=""
_err "Google Domains access token was not specified."
_err "Please visit Google Domains Security settings to provision an ACME DNS API access token."
return 1
fi
if [ "$GOOGLEDOMAINS_ZONE" ]; then
_savedomainconf GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN"
_savedomainconf GOOGLEDOMAINS_ZONE "$GOOGLEDOMAINS_ZONE"
else
_saveaccountconf_mutable GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN"
_clearaccountconf_mutable GOOGLEDOMAINS_ZONE
_clearaccountconf GOOGLEDOMAINS_ZONE
fi
_debug GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN"
_debug GOOGLEDOMAINS_ZONE "$GOOGLEDOMAINS_ZONE"
GOOGLEDOMAINS_SETUP_COMPLETED=1
return 0
}
_dns_googledomains_get_zone() {
domain=$1
# Use zone directly if provided
if [ "$GOOGLEDOMAINS_ZONE" ]; then
if ! _dns_googledomains_api "$GOOGLEDOMAINS_ZONE"; then
return 1
fi
echo "$GOOGLEDOMAINS_ZONE"
return 0
fi
i=2
while true; do
curr=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug curr "$curr"
if [ -z "$curr" ]; then
return 1
fi
if _dns_googledomains_api "$curr"; then
echo "$curr"
return 0
fi
i=$(_math "$i" + 1)
done
return 1
}
_dns_googledomains_api() {
zone=$1
apimethod=$2
data="$3"
if [ -z "$data" ]; then
response="$(_get "$GOOGLEDOMAINS_API/$zone$apimethod")"
else
_debug data "$data"
export _H1="Content-Type: application/json"
response="$(_post "$data" "$GOOGLEDOMAINS_API/$zone$apimethod")"
fi
_debug response "$response"
if [ "$?" != "0" ]; then
_err "Error"
return 1
fi
if _contains "$response" "\"error\": {"; then
return 1
fi
return 0
}
+11 -10
View File
@@ -1,14 +1,15 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_he_info='Hurricane Electric HE.net ########################################################################
Site: dns.he.net # Hurricane Electric hook script for acme.sh
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_he #
Options: # Environment variables:
HE_Username Username #
HE_Password Password # - $HE_Username (your dns.he.net username)
Issues: github.com/angel333/acme.sh/issues/ # - $HE_Password (your dns.he.net password)
Author: Ondrej Simek <me@ondrejsimek.com> #
' # Author: Ondrej Simek <me@ondrejsimek.com>
# Git repo: https://github.com/angel333/acme.sh
#-- dns_he_add() - Add TXT record -------------------------------------- #-- dns_he_add() - Add TXT record --------------------------------------
# Usage: dns_he_add _acme-challenge.subdomain.domain.com "XyZ123..." # Usage: dns_he_add _acme-challenge.subdomain.domain.com "XyZ123..."
+4 -8
View File
@@ -1,12 +1,8 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_hetzner_info='Hetzner.com #
Site: Hetzner.com #HETZNER_Token="sdfsdfsdfljlbjkljlkjsdfoiwje"
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_hetzner #
Options:
HETZNER_Token API Token
Issues: github.com/acmesh-official/acme.sh/issues/2943
'
HETZNER_Api="https://dns.hetzner.com/api/v1" HETZNER_Api="https://dns.hetzner.com/api/v1"
+5 -9
View File
@@ -1,13 +1,9 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_hexonet_info='Hexonet.com #
Site: Hexonet.com # Hexonet_Login="username!roleId"
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_hexonet #
Options: # Hexonet_Password="rolePassword"
Hexonet_Login Login. E.g. "username!roleId"
Hexonet_Password Role Password
Issues: github.com/acmesh-official/acme.sh/issues/2389
'
Hexonet_Api="https://coreapi.1api.net/api/call.cgi" Hexonet_Api="https://coreapi.1api.net/api/call.cgi"
+6 -9
View File
@@ -1,13 +1,10 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_hostingde_info='Hosting.de # hosting.de API
Site: Hosting.de
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_hostingde # Values to export:
Options: # export HOSTINGDE_ENDPOINT='https://secure.hosting.de'
HOSTINGDE_ENDPOINT Endpoint. E.g. "https://secure.hosting.de" # export HOSTINGDE_APIKEY='xxxxx'
HOSTINGDE_APIKEY API Key
Issues: github.com/acmesh-official/acme.sh/issues/2058
'
######## Public functions ##################### ######## Public functions #####################
+30 -72
View File
@@ -1,14 +1,8 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_huaweicloud_info='HuaweiCloud.com # HUAWEICLOUD_Username
Site: HuaweiCloud.com # HUAWEICLOUD_Password
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_huaweicloud # HUAWEICLOUD_DomainName
Options:
HUAWEICLOUD_Username Username
HUAWEICLOUD_Password Password
HUAWEICLOUD_DomainName DomainName
Issues: github.com/acmesh-official/acme.sh/issues/3265
'
iam_api="https://iam.myhuaweicloud.com" iam_api="https://iam.myhuaweicloud.com"
dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work
@@ -29,7 +23,7 @@ dns_huaweicloud_add() {
HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_DomainName)}" HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
# Check information # Check information
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
@@ -80,7 +74,7 @@ dns_huaweicloud_rm() {
HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_DomainName)}" HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
# Check information # Check information
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
@@ -104,59 +98,19 @@ dns_huaweicloud_rm() {
fi fi
_debug "Zone ID is:" "${zoneid}" _debug "Zone ID is:" "${zoneid}"
record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" # Remove all records
_recursive_rm_record "${token}" "${fulldomain}" "${zoneid}" "${record_id}" # Therotically HuaweiCloud does not allow more than one record set
ret="$?" # But remove them recurringly to increase robusty
if [ "${ret}" != "0" ]; then while [ "${record_id}" != "0" ]; do
_err "dns_api(dns_huaweicloud): Error removing record." _debug "Removing Record"
return 1 _rm_record "${token}" "${zoneid}" "${record_id}"
fi record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")"
done
return 0 return 0
} }
################### Private functions below ################################## ################### Private functions below ##################################
# _recursive_rm_record
# remove all records from the record set
#
# _token=$1
# _domain=$2
# _zoneid=$3
# _record_id=$4
#
# Returns 0 on success
_recursive_rm_record() {
_token=$1
_domain=$2
_zoneid=$3
_record_id=$4
# Most likely to have problems will huaweicloud side if more than 50 attempts but still cannot fully remove the record set
# Maybe can be removed manually in the dashboard
_retry_cnt=50
# Remove all records
# Therotically HuaweiCloud does not allow more than one record set
# But remove them recurringly to increase robusty
while [ "${_record_id}" != "0" ] && [ "${_retry_cnt}" != "0" ]; do
_debug "Removing Record"
_retry_cnt=$((_retry_cnt - 1))
_rm_record "${_token}" "${_zoneid}" "${_record_id}"
_record_id="$(_get_recordset_id "${_token}" "${_domain}" "${_zoneid}")"
_debug2 "Checking record exists: record_id=${_record_id}"
done
# Check if retry count is reached
if [ "${_retry_cnt}" = "0" ]; then
_debug "Failed to remove record after 50 attempts, please try removing it manually in the dashboard"
return 1
fi
return 0
}
# _get_zoneid # _get_zoneid
# #
# _token=$1 # _token=$1
@@ -170,7 +124,7 @@ _get_zoneid() {
i=1 i=1
while true; do while true; do
h=$(printf "%s" "${_domain_string}" | cut -d . -f "$i"-100) h=$(printf "%s" "${_domain_string}" | cut -d . -f $i-100)
if [ -z "$h" ]; then if [ -z "$h" ]; then
#not valid #not valid
return 1 return 1
@@ -181,11 +135,11 @@ _get_zoneid() {
if _contains "${response}" '"id"'; then if _contains "${response}" '"id"'; then
zoneidlist=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ") zoneidlist=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
zonenamelist=$(echo "${response}" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ") zonenamelist=$(echo "${response}" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
_debug2 "Returned Zone ID(s):" "${zoneidlist}" _debug2 "Return Zone ID(s):" "${zoneidlist}"
_debug2 "Returned Zone Name(s):" "${zonenamelist}" _debug2 "Return Zone Name(s):" "${zonenamelist}"
zoneidnum=0 zoneidnum=0
zoneidcount=$(echo "${zoneidlist}" | grep -c '^') zoneidcount=$(echo "${zoneidlist}" | grep -c '^')
_debug "Returned Zone ID(s) Count:" "${zoneidcount}" _debug "Retund Zone ID(s) Count:" "${zoneidcount}"
while [ "${zoneidnum}" -lt "${zoneidcount}" ]; do while [ "${zoneidnum}" -lt "${zoneidcount}" ]; do
zoneidnum=$(_math "$zoneidnum" + 1) zoneidnum=$(_math "$zoneidnum" + 1)
_zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p") _zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p")
@@ -210,7 +164,7 @@ _get_recordset_id() {
_zoneid=$3 _zoneid=$3
export _H1="X-Auth-Token: ${_token}" export _H1="X-Auth-Token: ${_token}"
response=$(_get "${dns_api}/v2/zones/${_zoneid}/recordsets?name=${_domain}&status=ACTIVE") response=$(_get "${dns_api}/v2/zones/${_zoneid}/recordsets?name=${_domain}")
if _contains "${response}" '"id"'; then if _contains "${response}" '"id"'; then
_id="$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")" _id="$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")"
printf "%s" "${_id}" printf "%s" "${_id}"
@@ -227,7 +181,7 @@ _add_record() {
# Get Existing Records # Get Existing Records
export _H1="X-Auth-Token: ${_token}" export _H1="X-Auth-Token: ${_token}"
response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}&status=ACTIVE") response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}")
_debug2 "${response}" _debug2 "${response}"
_exist_record=$(echo "${response}" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') _exist_record=$(echo "${response}" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g')
@@ -252,7 +206,8 @@ _add_record() {
\"type\": \"TXT\", \"type\": \"TXT\",
\"ttl\": 1, \"ttl\": 1,
\"records\": [ \"records\": [
${_exist_record},\"\\\"${_txtvalue}\\\"\" ${_exist_record},
\"\\\"${_txtvalue}\\\"\"
] ]
}" }"
fi fi
@@ -260,16 +215,19 @@ _add_record() {
_record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")" _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")"
_debug "Record Set ID is:" "${_record_id}" _debug "Record Set ID is:" "${_record_id}"
# Remove all records
while [ "${_record_id}" != "0" ]; do
_debug "Removing Record"
_rm_record "${_token}" "${zoneid}" "${_record_id}"
_record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")"
done
# Add brand new records with all old and new records # Add brand new records with all old and new records
export _H2="Content-Type: application/json" export _H2="Content-Type: application/json"
export _H1="X-Auth-Token: ${_token}" export _H1="X-Auth-Token: ${_token}"
_debug2 "${_post_body}" _debug2 "${_post_body}"
if [ -z "${_exist_record}" ]; then _post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null
_post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null
else
_post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets/${_record_id}" false "PUT" >/dev/null
fi
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
if [ "$_code" != "202" ]; then if [ "$_code" != "202" ]; then
_err "dns_huaweicloud: http code ${_code}" _err "dns_huaweicloud: http code ${_code}"
+4 -10
View File
@@ -1,14 +1,8 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_infoblox_info='Infoblox.com ## Infoblox API integration by Jason Keller and Elijah Tenai
Site: Infoblox.com ##
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_infoblox ## Report any bugs via https://github.com/jasonkeller/acme.sh
Options:
Infoblox_Creds Credentials. E.g. "username:password"
Infoblox_Server Server hostname. IP or FQDN of infoblox appliance
Issues: github.com/jasonkeller/acme.sh
Author: Jason Keller, Elijah Tenai
'
dns_infoblox_add() { dns_infoblox_add() {
+7 -8
View File
@@ -1,20 +1,19 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_infomaniak_info='Infomaniak.com
Site: Infomaniak.com
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_infomaniak
Options:
INFOMANIAK_API_TOKEN API Token
Issues: github.com/acmesh-official/acme.sh/issues/3188
'
###############################################################################
# Infomaniak API integration
#
# To use this API you need visit the API dashboard of your account # To use this API you need visit the API dashboard of your account
# once logged into https://manager.infomaniak.com add /api/dashboard to the URL # once logged into https://manager.infomaniak.com add /api/dashboard to the URL
# #
# Please report bugs to
# https://github.com/acmesh-official/acme.sh/issues/3188
#
# Note: the URL looks like this: # Note: the URL looks like this:
# https://manager.infomaniak.com/v3/<account_id>/api/dashboard # https://manager.infomaniak.com/v3/<account_id>/api/dashboard
# Then generate a token with the scope Domain # Then generate a token with the scope Domain
# this is given as an environment variable INFOMANIAK_API_TOKEN # this is given as an environment variable INFOMANIAK_API_TOKEN
###############################################################################
# base variables # base variables
+8 -10
View File
@@ -1,14 +1,12 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_internetbs_info='InternetBS.net #This is the Internet.BS api wrapper for acme.sh
Site: InternetBS.net #
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_internetbs #Author: <alexey@nelexa.ru> Ne-Lexa
Options: #Report Bugs here: https://github.com/Ne-Lexa/acme.sh
INTERNETBS_API_KEY API Key
INTERNETBS_API_PASSWORD API Password #INTERNETBS_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje"
Issues: github.com/acmesh-official/acme.sh/issues/2261 #INTERNETBS_API_PASSWORD="sdfsdfsdfljlbjkljlkjsdfoiwje"
Author: Ne-Lexa <alexey@nelexa.ru>
'
INTERNETBS_API_URL="https://api.internet.bs" INTERNETBS_API_URL="https://api.internet.bs"
+6 -9
View File
@@ -1,13 +1,10 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_inwx_info='INWX.de
Site: INWX.de
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_inwx
Options:
INWX_User Username
INWX_Password Password
'
#
#INWX_User="username"
#
#INWX_Password="password"
#
# Dependencies: # Dependencies:
# ------------- # -------------
# - oathtool (When using 2 Factor Authentication) # - oathtool (When using 2 Factor Authentication)
@@ -197,7 +194,7 @@ _inwx_login() {
response="$(_post "$xml_content" "$INWX_Api" "" "POST")" response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
INWX_Cookie=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep -i "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')") INWX_Cookie=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')")
_H1=$INWX_Cookie _H1=$INWX_Cookie
export _H1 export _H1
export INWX_Cookie export INWX_Cookie
+10 -9
View File
@@ -1,13 +1,14 @@
#!/usr/bin/env sh #!/usr/bin/env sh
# shellcheck disable=SC2034
dns_ionos_info='IONOS.de # Supports IONOS DNS API v1.0.1
Site: IONOS.de #
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_ionos # Usage:
Options: # Export IONOS_PREFIX and IONOS_SECRET before calling acme.sh:
IONOS_PREFIX Prefix #
IONOS_SECRET Secret # $ export IONOS_PREFIX="..."
Issues: github.com/acmesh-official/acme.sh/issues/3379 # $ export IONOS_SECRET="..."
' #
# $ acme.sh --issue --dns dns_ionos ...
IONOS_API="https://api.hosting.ionos.com/dns" IONOS_API="https://api.hosting.ionos.com/dns"
IONOS_ROUTE_ZONES="/v1/zones" IONOS_ROUTE_ZONES="/v1/zones"
-145
View File
@@ -1,145 +0,0 @@
#!/usr/bin/env sh
# Supports IONOS Cloud DNS API v1.15.4
#
# Usage:
# Export IONOS_TOKEN before calling acme.sh:
# $ export IONOS_TOKEN="..."
#
# $ acme.sh --issue --dns dns_ionos_cloud ...
IONOS_CLOUD_API="https://dns.de-fra.ionos.com"
IONOS_CLOUD_ROUTE_ZONES="/zones"
dns_ionos_cloud_add() {
fulldomain=$1
txtvalue=$2
if ! _ionos_init; then
return 1
fi
_record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1)
_body="{\"properties\":{\"name\":\"$_record_name\", \"type\":\"TXT\", \"content\":\"$txtvalue\"}}"
if _ionos_cloud_rest POST "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "202" ]; then
_info "TXT record has been created successfully."
return 0
fi
return 1
}
dns_ionos_cloud_rm() {
fulldomain=$1
txtvalue=$2
if ! _ionos_init; then
return 1
fi
if ! _ionos_cloud_get_record "$_zone_id" "$txtvalue" "$fulldomain"; then
_err "Could not find _acme-challenge TXT record."
return 1
fi
if _ionos_cloud_rest DELETE "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "202" ]; then
_info "TXT record has been deleted successfully."
return 0
fi
return 1
}
_ionos_init() {
IONOS_TOKEN="${IONOS_TOKEN:-$(_readaccountconf_mutable IONOS_TOKEN)}"
if [ -z "$IONOS_TOKEN" ]; then
_err "You didn't specify an IONOS token yet."
_err "Read https://api.ionos.com/docs/authentication/v1/#tag/tokens/operation/tokensGenerate to learn how to get a token."
_err "You need to set it before calling acme.sh:"
_err "\$ export IONOS_TOKEN=\"...\""
_err "\$ acme.sh --issue -d ... --dns dns_ionos_cloud"
return 1
fi
_saveaccountconf_mutable IONOS_TOKEN "$IONOS_TOKEN"
if ! _get_cloud_zone "$fulldomain"; then
_err "Cannot find zone $zone in your IONOS account."
return 1
fi
return 0
}
_get_cloud_zone() {
domain=$1
zone=$(printf "%s" "$domain" | cut -d . -f 2-)
if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES?filter.zoneName=$zone"; then
_response="$(echo "$_response" | tr -d "\n")"
_zone_list_items=$(echo "$_response" | _egrep_o "\"items\":.*")
_zone_id=$(printf "%s\n" "$_zone_list_items" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"')
if [ "$_zone_id" ]; then
return 0
fi
fi
return 1
}
_ionos_cloud_get_record() {
zone_id=$1
txtrecord=$2
# this is to transform the domain to lower case
fulldomain=$(printf "%s" "$3" | _lower_case)
# this is to transform record name to lower case
# IONOS Cloud API transforms all record names to lower case
_record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1 | _lower_case)
if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES/$zone_id/records"; then
_response="$(echo "$_response" | tr -d "\n")"
pattern="\{\"id\":\"[a-fA-F0-9\-]*\",\"type\":\"record\",\"href\":\"/zones/$zone_id/records/[a-fA-F0-9\-]*\",\"metadata\":\{\"createdDate\":\"[A-Z0-9\:\.\-]*\",\"lastModifiedDate\":\"[A-Z0-9\:\.\-]*\",\"fqdn\":\"$fulldomain\",\"state\":\"AVAILABLE\",\"zoneId\":\"$zone_id\"\},\"properties\":\{\"content\":\"$txtrecord\",\"enabled\":true,\"name\":\"$_record_name\",\"priority\":[0-9]*,\"ttl\":[0-9]*,\"type\":\"TXT\"\}\}"
_record="$(echo "$_response" | _egrep_o "$pattern")"
if [ "$_record" ]; then
_record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"')
return 0
fi
fi
return 1
}
_ionos_cloud_rest() {
method="$1"
route="$2"
data="$3"
export _H1="Authorization: Bearer $IONOS_TOKEN"
# clear headers
: >"$HTTP_HEADER"
if [ "$method" != "GET" ]; then
_response="$(_post "$data" "$IONOS_CLOUD_API$route" "" "$method" "application/json")"
else
_response="$(_get "$IONOS_CLOUD_API$route")"
fi
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
if [ "$?" != "0" ]; then
_err "Error $route: $_response"
return 1
fi
_debug2 "_response" "$_response"
_debug2 "_code" "$_code"
return 0
}
Loaded 100 of 187 files, more files were not shown because too many files have changed in this diff. Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.