mirror of
https://github.com/plantroon/acme.sh.git
synced 2024-12-22 13:11:41 +00:00
Merge branch 'acmesh-official:master' into master
This commit is contained in:
commit
71a32477e4
18
.github/workflows/DNS.yml
vendored
18
.github/workflows/DNS.yml
vendored
@ -61,22 +61,22 @@ jobs:
|
||||
run: |
|
||||
cd ../acmetest
|
||||
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||
echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> env.list
|
||||
echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> docker.env
|
||||
fi
|
||||
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||
echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> env.list
|
||||
echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> docker.env
|
||||
fi
|
||||
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||
echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> env.list
|
||||
echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> docker.env
|
||||
fi
|
||||
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||
echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> env.list
|
||||
echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> docker.env
|
||||
fi
|
||||
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||
echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> env.list
|
||||
echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env
|
||||
fi
|
||||
echo "TEST_DNS_NO_WILDCARD" >> env.list
|
||||
echo "TEST_DNS_SLEEP" >> env.list
|
||||
echo "TEST_DNS_NO_WILDCARD" >> docker.env
|
||||
echo "TEST_DNS_SLEEP" >> docker.env
|
||||
- name: Run acmetest
|
||||
run: cd ../acmetest && ./rundocker.sh testall
|
||||
|
||||
@ -170,7 +170,7 @@ jobs:
|
||||
./letest.sh
|
||||
|
||||
FreeBSD:
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-10.15
|
||||
needs: Windows
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
@ -209,7 +209,7 @@ jobs:
|
||||
./letest.sh
|
||||
|
||||
Solaris:
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-10.15
|
||||
needs: FreeBSD
|
||||
env:
|
||||
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||
|
11
.github/workflows/FreeBSD.yml
vendored
11
.github/workflows/FreeBSD.yml
vendored
@ -24,20 +24,23 @@ jobs:
|
||||
CA_ECDSA: ""
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
- TEST_ACME_Server: "ZeroSSL.com"
|
||||
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
|
||||
CA: "ZeroSSL RSA Domain Secure Site CA"
|
||||
CA_EMAIL: "githubtest@acme.sh"
|
||||
runs-on: macos-latest
|
||||
TEST_PREFERRED_CHAIN: ""
|
||||
runs-on: macos-10.15
|
||||
env:
|
||||
TEST_LOCAL: 1
|
||||
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
|
||||
CA_ECDSA: ${{ matrix.CA_ECDSA }}
|
||||
CA: ${{ matrix.CA }}
|
||||
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: vmactions/cf-tunnel@v0.0.2
|
||||
- uses: vmactions/cf-tunnel@v0.0.3
|
||||
id: tunnel
|
||||
with:
|
||||
protocol: http
|
||||
@ -46,9 +49,9 @@ jobs:
|
||||
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/freebsd-vm@v0.1.4
|
||||
- uses: vmactions/freebsd-vm@v0.1.5
|
||||
with:
|
||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL'
|
||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
|
||||
nat: |
|
||||
"8080": "80"
|
||||
prepare: pkg install -y socat curl
|
||||
|
3
.github/workflows/Linux.yml
vendored
3
.github/workflows/Linux.yml
vendored
@ -20,10 +20,11 @@ jobs:
|
||||
Linux:
|
||||
strategy:
|
||||
matrix:
|
||||
os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3-amd64", "clearlinux:latest"]
|
||||
os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3-amd64"]
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
TEST_LOCAL: 1
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Clone acmetest
|
||||
|
3
.github/workflows/MacOS.yml
vendored
3
.github/workflows/MacOS.yml
vendored
@ -24,10 +24,12 @@ jobs:
|
||||
CA_ECDSA: ""
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
- TEST_ACME_Server: "ZeroSSL.com"
|
||||
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
|
||||
CA: "ZeroSSL RSA Domain Secure Site CA"
|
||||
CA_EMAIL: "githubtest@acme.sh"
|
||||
TEST_PREFERRED_CHAIN: ""
|
||||
runs-on: macos-latest
|
||||
env:
|
||||
TEST_LOCAL: 1
|
||||
@ -35,6 +37,7 @@ jobs:
|
||||
CA_ECDSA: ${{ matrix.CA_ECDSA }}
|
||||
CA: ${{ matrix.CA }}
|
||||
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install tools
|
||||
|
23
.github/workflows/PebbleStrict.yml
vendored
23
.github/workflows/PebbleStrict.yml
vendored
@ -37,3 +37,26 @@ jobs:
|
||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- name: Run acmetest
|
||||
run: cd ../acmetest && ./letest.sh
|
||||
|
||||
PebbleStrict_IPCert:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
TestingDomain: 10.30.50.1
|
||||
ACME_DIRECTORY: https://localhost:14000/dir
|
||||
HTTPS_INSECURE: 1
|
||||
Le_HTTPPort: 5002
|
||||
Le_TLSPort: 5001
|
||||
TEST_LOCAL: 1
|
||||
TEST_CA: "Pebble Intermediate CA"
|
||||
TEST_IPCERT: 1
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install tools
|
||||
run: sudo apt-get install -y socat
|
||||
- name: Run Pebble
|
||||
run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- name: Run acmetest
|
||||
run: cd ../acmetest && ./letest.sh
|
9
.github/workflows/Solaris.yml
vendored
9
.github/workflows/Solaris.yml
vendored
@ -24,20 +24,23 @@ jobs:
|
||||
CA_ECDSA: ""
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
- TEST_ACME_Server: "ZeroSSL.com"
|
||||
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
|
||||
CA: "ZeroSSL RSA Domain Secure Site CA"
|
||||
CA_EMAIL: "githubtest@acme.sh"
|
||||
runs-on: macos-latest
|
||||
TEST_PREFERRED_CHAIN: ""
|
||||
runs-on: macos-10.15
|
||||
env:
|
||||
TEST_LOCAL: 1
|
||||
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
|
||||
CA_ECDSA: ${{ matrix.CA_ECDSA }}
|
||||
CA: ${{ matrix.CA }}
|
||||
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: vmactions/cf-tunnel@v0.0.2
|
||||
- uses: vmactions/cf-tunnel@v0.0.3
|
||||
id: tunnel
|
||||
with:
|
||||
protocol: http
|
||||
@ -48,7 +51,7 @@ jobs:
|
||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/solaris-vm@v0.0.3
|
||||
with:
|
||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL'
|
||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
|
||||
nat: |
|
||||
"8080": "80"
|
||||
prepare: pkgutil -y -i socat curl
|
||||
|
3
.github/workflows/Ubuntu.yml
vendored
3
.github/workflows/Ubuntu.yml
vendored
@ -24,10 +24,12 @@ jobs:
|
||||
CA_ECDSA: ""
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
- TEST_ACME_Server: "ZeroSSL.com"
|
||||
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
|
||||
CA: "ZeroSSL RSA Domain Secure Site CA"
|
||||
CA_EMAIL: "githubtest@acme.sh"
|
||||
TEST_PREFERRED_CHAIN: ""
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
@ -37,6 +39,7 @@ jobs:
|
||||
CA: ${{ matrix.CA }}
|
||||
CA_EMAIL: ${{ matrix.CA_EMAIL }}
|
||||
NO_ECC_384: ${{ matrix.NO_ECC_384 }}
|
||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install tools
|
||||
|
7
.github/workflows/Windows.yml
vendored
7
.github/workflows/Windows.yml
vendored
@ -24,10 +24,12 @@ jobs:
|
||||
CA_ECDSA: ""
|
||||
CA: ""
|
||||
CA_EMAIL: ""
|
||||
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
|
||||
- TEST_ACME_Server: "ZeroSSL.com"
|
||||
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
|
||||
CA: "ZeroSSL RSA Domain Secure Site CA"
|
||||
CA_EMAIL: "githubtest@acme.sh"
|
||||
TEST_PREFERRED_CHAIN: ""
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
|
||||
@ -37,6 +39,7 @@ jobs:
|
||||
TEST_LOCAL: 1
|
||||
#The 80 port is used by Windows server, we have to use a custom port, tunnel will also use this port.
|
||||
Le_HTTPPort: 8888
|
||||
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
|
||||
steps:
|
||||
- name: Set git to use LF
|
||||
run: |
|
||||
@ -49,12 +52,12 @@ jobs:
|
||||
shell: cmd
|
||||
- name: Install cygwin additional packages
|
||||
run: |
|
||||
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git
|
||||
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git,xxd
|
||||
shell: cmd
|
||||
- name: Set ENV
|
||||
shell: cmd
|
||||
run: |
|
||||
echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV%
|
||||
echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin;%PATH% >> %GITHUB_ENV%
|
||||
- name: Check ENV
|
||||
shell: cmd
|
||||
run: |
|
||||
|
@ -55,6 +55,7 @@ RUN for verb in help \
|
||||
deactivate-account \
|
||||
set-notify \
|
||||
set-default-ca \
|
||||
set-default-chain \
|
||||
; do \
|
||||
printf -- "%b" "#!/usr/bin/env sh\n/root/.acme.sh/acme.sh --${verb} --config-home /acme.sh \"\$@\"" >/usr/local/bin/--${verb} && chmod +x /usr/local/bin/--${verb} \
|
||||
; done
|
||||
|
145
acme.sh
145
acme.sh
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
VER=3.0.1
|
||||
VER=3.0.2
|
||||
|
||||
PROJECT_NAME="acme.sh"
|
||||
|
||||
@ -20,6 +20,8 @@ _SUB_FOLDER_DEPLOY="deploy"
|
||||
|
||||
_SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY"
|
||||
|
||||
CA_LETSENCRYPT_V1="https://acme-v01.api.letsencrypt.org/directory"
|
||||
|
||||
CA_LETSENCRYPT_V2="https://acme-v02.api.letsencrypt.org/directory"
|
||||
CA_LETSENCRYPT_V2_TEST="https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
|
||||
@ -57,6 +59,9 @@ VTYPE_HTTP="http-01"
|
||||
VTYPE_DNS="dns-01"
|
||||
VTYPE_ALPN="tls-alpn-01"
|
||||
|
||||
ID_TYPE_DNS="dns"
|
||||
ID_TYPE_IP="ip"
|
||||
|
||||
LOCAL_ANY_ADDRESS="0.0.0.0"
|
||||
|
||||
DEFAULT_RENEW=60
|
||||
@ -424,19 +429,27 @@ _secure_debug3() {
|
||||
}
|
||||
|
||||
_upper_case() {
|
||||
# shellcheck disable=SC2018,SC2019
|
||||
tr 'a-z' 'A-Z'
|
||||
if _is_solaris; then
|
||||
tr '[:lower:]' '[:upper:]'
|
||||
else
|
||||
# shellcheck disable=SC2018,SC2019
|
||||
tr 'a-z' 'A-Z'
|
||||
fi
|
||||
}
|
||||
|
||||
_lower_case() {
|
||||
# shellcheck disable=SC2018,SC2019
|
||||
tr 'A-Z' 'a-z'
|
||||
if _is_solaris; then
|
||||
tr '[:upper:]' '[:lower:]'
|
||||
else
|
||||
# shellcheck disable=SC2018,SC2019
|
||||
tr 'A-Z' 'a-z'
|
||||
fi
|
||||
}
|
||||
|
||||
_startswith() {
|
||||
_str="$1"
|
||||
_sub="$2"
|
||||
echo "$_str" | grep "^$_sub" >/dev/null 2>&1
|
||||
echo "$_str" | grep -- "^$_sub" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
_endswith() {
|
||||
@ -1220,19 +1233,27 @@ _createcsr() {
|
||||
|
||||
if [ "$acmeValidationv1" ]; then
|
||||
domainlist="$(_idn "$domainlist")"
|
||||
printf -- "\nsubjectAltName=DNS:$domainlist" >>"$csrconf"
|
||||
_debug2 domainlist "$domainlist"
|
||||
alt=""
|
||||
for dl in $(echo "$domainlist" | tr "," ' '); do
|
||||
if [ "$alt" ]; then
|
||||
alt="$alt,$(_getIdType "$dl" | _upper_case):$dl"
|
||||
else
|
||||
alt="$(_getIdType "$dl" | _upper_case):$dl"
|
||||
fi
|
||||
done
|
||||
printf -- "\nsubjectAltName=$alt" >>"$csrconf"
|
||||
elif [ -z "$domainlist" ] || [ "$domainlist" = "$NO_VALUE" ]; then
|
||||
#single domain
|
||||
_info "Single domain" "$domain"
|
||||
printf -- "\nsubjectAltName=DNS:$(_idn "$domain")" >>"$csrconf"
|
||||
printf -- "\nsubjectAltName=$(_getIdType "$domain" | _upper_case):$(_idn "$domain")" >>"$csrconf"
|
||||
else
|
||||
domainlist="$(_idn "$domainlist")"
|
||||
_debug2 domainlist "$domainlist"
|
||||
if _contains "$domainlist" ","; then
|
||||
alt="DNS:$(_idn "$domain"),DNS:$(echo "$domainlist" | sed "s/,,/,/g" | sed "s/,/,DNS:/g")"
|
||||
else
|
||||
alt="DNS:$(_idn "$domain"),DNS:$domainlist"
|
||||
fi
|
||||
alt="$(_getIdType "$domain" | _upper_case):$domain"
|
||||
for dl in $(echo "$domainlist" | tr "," ' '); do
|
||||
alt="$alt,$(_getIdType "$dl" | _upper_case):$dl"
|
||||
done
|
||||
#multi
|
||||
_info "Multi domain" "$alt"
|
||||
printf -- "\nsubjectAltName=$alt" >>"$csrconf"
|
||||
@ -3161,12 +3182,12 @@ _checkConf() {
|
||||
FOUND_REAL_NGINX_CONF="$2"
|
||||
return 0
|
||||
fi
|
||||
if cat "$2" | tr "\t" " " | grep "^ *include +.*;" >/dev/null; then
|
||||
if cat "$2" | tr "\t" " " | grep "^ *include *.*;" >/dev/null; then
|
||||
_debug "Try include files"
|
||||
for included in $(cat "$2" | tr "\t" " " | grep "^ *include +.*;" | sed "s/include //" | tr -d " ;"); do
|
||||
for included in $(cat "$2" | tr "\t" " " | grep "^ *include *.*;" | sed "s/include //" | tr -d " ;"); do
|
||||
_debug "check included $included"
|
||||
if ! _startswith "$included" "/" && _exists dirname; then
|
||||
_relpath="$(dirname "$_c_file")"
|
||||
_relpath="$(dirname "$2")"
|
||||
_debug "_relpath" "$_relpath"
|
||||
included="$_relpath/$included"
|
||||
fi
|
||||
@ -3380,6 +3401,8 @@ _on_before_issue() {
|
||||
if [ "$_chk_pre_hook" ]; then
|
||||
_info "Run pre hook:'$_chk_pre_hook'"
|
||||
if ! (
|
||||
export Le_Domain="$_chk_main_domain"
|
||||
export Le_Alt="$_chk_alt_domains"
|
||||
cd "$DOMAIN_PATH" && eval "$_chk_pre_hook"
|
||||
); then
|
||||
_err "Error when run pre hook."
|
||||
@ -4170,6 +4193,36 @@ _match_issuer() {
|
||||
_contains "$_rootissuer" "$_missuer"
|
||||
}
|
||||
|
||||
#ip
|
||||
_isIPv4() {
|
||||
for seg in $(echo "$1" | tr '.' ' '); do
|
||||
if [ $seg -ge 0 ] 2>/dev/null && [ $seg -le 255 ] 2>/dev/null; then
|
||||
continue
|
||||
fi
|
||||
return 1
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
#ip6
|
||||
_isIPv6() {
|
||||
_contains "$1" ":"
|
||||
}
|
||||
|
||||
#ip
|
||||
_isIP() {
|
||||
_isIPv4 "$1" || _isIPv6 "$1"
|
||||
}
|
||||
|
||||
#identifier
|
||||
_getIdType() {
|
||||
if _isIP "$1"; then
|
||||
echo "$ID_TYPE_IP"
|
||||
else
|
||||
echo "$ID_TYPE_DNS"
|
||||
fi
|
||||
}
|
||||
|
||||
#webroot, domain domainlist keylength
|
||||
issue() {
|
||||
if [ -z "$2" ]; then
|
||||
@ -4218,12 +4271,6 @@ issue() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "Using ACME_DIRECTORY: $ACME_DIRECTORY"
|
||||
|
||||
if ! _initAPI; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -f "$DOMAIN_CONF" ]; then
|
||||
Le_NextRenewTime=$(_readdomainconf Le_NextRenewTime)
|
||||
_debug Le_NextRenewTime "$Le_NextRenewTime"
|
||||
@ -4243,6 +4290,11 @@ issue() {
|
||||
fi
|
||||
fi
|
||||
|
||||
_debug "Using ACME_DIRECTORY: $ACME_DIRECTORY"
|
||||
if ! _initAPI; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
_savedomainconf "Le_Domain" "$_main_domain"
|
||||
_savedomainconf "Le_Alt" "$_alt_domains"
|
||||
_savedomainconf "Le_Webroot" "$_web_roots"
|
||||
@ -4327,7 +4379,7 @@ issue() {
|
||||
dvsep=','
|
||||
if [ -z "$vlist" ]; then
|
||||
#make new order request
|
||||
_identifiers="{\"type\":\"dns\",\"value\":\"$(_idn "$_main_domain")\"}"
|
||||
_identifiers="{\"type\":\"$(_getIdType "$_main_domain")\",\"value\":\"$(_idn "$_main_domain")\"}"
|
||||
_w_index=1
|
||||
while true; do
|
||||
d="$(echo "$_alt_domains," | cut -d , -f "$_w_index")"
|
||||
@ -4336,7 +4388,7 @@ issue() {
|
||||
if [ -z "$d" ]; then
|
||||
break
|
||||
fi
|
||||
_identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$(_idn "$d")\"}"
|
||||
_identifiers="$_identifiers,{\"type\":\"$(_getIdType "$d")\",\"value\":\"$(_idn "$d")\"}"
|
||||
done
|
||||
_debug2 _identifiers "$_identifiers"
|
||||
if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then
|
||||
@ -4930,7 +4982,9 @@ $_authorizations_map"
|
||||
|
||||
echo "$response" >"$CERT_PATH"
|
||||
_split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH"
|
||||
|
||||
if [ -z "$_preferred_chain" ]; then
|
||||
_preferred_chain=$(_readcaconf DEFAULT_PREFERRED_CHAIN)
|
||||
fi
|
||||
if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then
|
||||
if [ "$DEBUG" ]; then
|
||||
_debug "default chain issuers: " "$(_get_chain_issuers "$CERT_FULLCHAIN_PATH")"
|
||||
@ -5108,7 +5162,7 @@ renew() {
|
||||
|
||||
. "$DOMAIN_CONF"
|
||||
_debug Le_API "$Le_API"
|
||||
if [ -z "$Le_API" ]; then
|
||||
if [ -z "$Le_API" ] || [ "$CA_LETSENCRYPT_V1" = "$Le_API" ]; then
|
||||
#if this is from an old version, Le_API is empty,
|
||||
#so, we force to use letsencrypt server
|
||||
Le_API="$CA_LETSENCRYPT_V2"
|
||||
@ -5125,7 +5179,6 @@ renew() {
|
||||
CA_CONF=""
|
||||
_debug3 "initpath again."
|
||||
_initpath "$Le_Domain" "$_isEcc"
|
||||
_initAPI
|
||||
fi
|
||||
|
||||
if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then
|
||||
@ -5670,8 +5723,16 @@ installcronjob() {
|
||||
if [ -f "$LE_WORKING_DIR/$PROJECT_ENTRY" ]; then
|
||||
lesh="\"$LE_WORKING_DIR\"/$PROJECT_ENTRY"
|
||||
else
|
||||
_err "Can not install cronjob, $PROJECT_ENTRY not found."
|
||||
return 1
|
||||
_debug "_SCRIPT_" "$_SCRIPT_"
|
||||
_script="$(_readlink "$_SCRIPT_")"
|
||||
_debug _script "$_script"
|
||||
if [ -f "$_script" ]; then
|
||||
_info "Using the current script from: $_script"
|
||||
lesh="$_script"
|
||||
else
|
||||
_err "Can not install cronjob, $PROJECT_ENTRY not found."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
if [ "$_c_home" ]; then
|
||||
_c_entry="--config-home \"$_c_home\" "
|
||||
@ -5743,7 +5804,7 @@ uninstallcronjob() {
|
||||
_info "Removing cron job"
|
||||
cr="$($_CRONTAB -l | grep "$PROJECT_ENTRY --cron")"
|
||||
if [ "$cr" ]; then
|
||||
if _exists uname && uname -a | grep solaris >/dev/null; then
|
||||
if _exists uname && uname -a | grep SunOS >/dev/null; then
|
||||
$_CRONTAB -l | sed "/$PROJECT_ENTRY --cron/d" | $_CRONTAB --
|
||||
else
|
||||
$_CRONTAB -l | sed "/$PROJECT_ENTRY --cron/d" | $_CRONTAB -
|
||||
@ -5898,7 +5959,7 @@ _deactivate() {
|
||||
_initAPI
|
||||
fi
|
||||
|
||||
_identifiers="{\"type\":\"dns\",\"value\":\"$_d_domain\"}"
|
||||
_identifiers="{\"type\":\"$(_getIdType "$_d_domain")\",\"value\":\"$_d_domain\"}"
|
||||
if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then
|
||||
_err "Can not get domain new order."
|
||||
return 1
|
||||
@ -5934,7 +5995,7 @@ _deactivate() {
|
||||
thumbprint="$(__calc_account_thumbprint)"
|
||||
fi
|
||||
_debug "Trigger validation."
|
||||
vtype="$VTYPE_DNS"
|
||||
vtype="$(_getIdType "$_d_domain")"
|
||||
entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')"
|
||||
_debug entry "$entry"
|
||||
if [ -z "$entry" ]; then
|
||||
@ -6543,6 +6604,8 @@ Commands:
|
||||
--deactivate Deactivate the domain authz, professional use.
|
||||
--set-default-ca Used with '--server', Set the default CA to use.
|
||||
See: $_SERVER_WIKI
|
||||
--set-default-chain Set the default preferred chain for a CA.
|
||||
See: $_PREFERRED_CHAIN_WIKI
|
||||
|
||||
|
||||
Parameters:
|
||||
@ -6829,6 +6892,18 @@ setdefaultca() {
|
||||
_info "Changed default CA to: $(__green "$ACME_DIRECTORY")"
|
||||
}
|
||||
|
||||
#preferred-chain
|
||||
setdefaultchain() {
|
||||
_initpath
|
||||
_preferred_chain="$1"
|
||||
if [ -z "$_preferred_chain" ]; then
|
||||
_err "Please give a '--preferred-chain value' value."
|
||||
return 1
|
||||
fi
|
||||
mkdir -p "$CA_DIR"
|
||||
_savecaconf "DEFAULT_PREFERRED_CHAIN" "$_preferred_chain"
|
||||
}
|
||||
|
||||
_process() {
|
||||
_CMD=""
|
||||
_domain=""
|
||||
@ -6980,6 +7055,9 @@ _process() {
|
||||
--set-default-ca)
|
||||
_CMD="setdefaultca"
|
||||
;;
|
||||
--set-default-chain)
|
||||
_CMD="setdefaultchain"
|
||||
;;
|
||||
-d | --domain)
|
||||
_dvalue="$2"
|
||||
|
||||
@ -7510,6 +7588,9 @@ _process() {
|
||||
setdefaultca)
|
||||
setdefaultca
|
||||
;;
|
||||
setdefaultchain)
|
||||
setdefaultchain "$_preferred_chain"
|
||||
;;
|
||||
*)
|
||||
if [ "$_CMD" ]; then
|
||||
_err "Invalid command: $_CMD"
|
||||
|
@ -54,11 +54,6 @@ haproxy_deploy() {
|
||||
DEPLOY_HAPROXY_ISSUER_DEFAULT="no"
|
||||
DEPLOY_HAPROXY_RELOAD_DEFAULT="true"
|
||||
|
||||
if [ -f "${DOMAIN_CONF}" ]; then
|
||||
# shellcheck disable=SC1090
|
||||
. "${DOMAIN_CONF}"
|
||||
fi
|
||||
|
||||
_debug _cdomain "${_cdomain}"
|
||||
_debug _ckey "${_ckey}"
|
||||
_debug _ccert "${_ccert}"
|
||||
@ -66,6 +61,8 @@ haproxy_deploy() {
|
||||
_debug _cfullchain "${_cfullchain}"
|
||||
|
||||
# PEM_PATH is optional. If not provided then assume "${DEPLOY_HAPROXY_PEM_PATH_DEFAULT}"
|
||||
_getdeployconf DEPLOY_HAPROXY_PEM_PATH
|
||||
_debug2 DEPLOY_HAPROXY_PEM_PATH "${DEPLOY_HAPROXY_PEM_PATH}"
|
||||
if [ -n "${DEPLOY_HAPROXY_PEM_PATH}" ]; then
|
||||
Le_Deploy_haproxy_pem_path="${DEPLOY_HAPROXY_PEM_PATH}"
|
||||
_savedomainconf Le_Deploy_haproxy_pem_path "${Le_Deploy_haproxy_pem_path}"
|
||||
@ -82,6 +79,8 @@ haproxy_deploy() {
|
||||
fi
|
||||
|
||||
# PEM_NAME is optional. If not provided then assume "${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}"
|
||||
_getdeployconf DEPLOY_HAPROXY_PEM_NAME
|
||||
_debug2 DEPLOY_HAPROXY_PEM_NAME "${DEPLOY_HAPROXY_PEM_NAME}"
|
||||
if [ -n "${DEPLOY_HAPROXY_PEM_NAME}" ]; then
|
||||
Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME}"
|
||||
_savedomainconf Le_Deploy_haproxy_pem_name "${Le_Deploy_haproxy_pem_name}"
|
||||
@ -90,6 +89,8 @@ haproxy_deploy() {
|
||||
fi
|
||||
|
||||
# BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}"
|
||||
_getdeployconf DEPLOY_HAPROXY_BUNDLE
|
||||
_debug2 DEPLOY_HAPROXY_BUNDLE "${DEPLOY_HAPROXY_BUNDLE}"
|
||||
if [ -n "${DEPLOY_HAPROXY_BUNDLE}" ]; then
|
||||
Le_Deploy_haproxy_bundle="${DEPLOY_HAPROXY_BUNDLE}"
|
||||
_savedomainconf Le_Deploy_haproxy_bundle "${Le_Deploy_haproxy_bundle}"
|
||||
@ -98,6 +99,8 @@ haproxy_deploy() {
|
||||
fi
|
||||
|
||||
# ISSUER is optional. If not provided then assume "${DEPLOY_HAPROXY_ISSUER_DEFAULT}"
|
||||
_getdeployconf DEPLOY_HAPROXY_ISSUER
|
||||
_debug2 DEPLOY_HAPROXY_ISSUER "${DEPLOY_HAPROXY_ISSUER}"
|
||||
if [ -n "${DEPLOY_HAPROXY_ISSUER}" ]; then
|
||||
Le_Deploy_haproxy_issuer="${DEPLOY_HAPROXY_ISSUER}"
|
||||
_savedomainconf Le_Deploy_haproxy_issuer "${Le_Deploy_haproxy_issuer}"
|
||||
@ -106,6 +109,8 @@ haproxy_deploy() {
|
||||
fi
|
||||
|
||||
# RELOAD is optional. If not provided then assume "${DEPLOY_HAPROXY_RELOAD_DEFAULT}"
|
||||
_getdeployconf DEPLOY_HAPROXY_RELOAD
|
||||
_debug2 DEPLOY_HAPROXY_RELOAD "${DEPLOY_HAPROXY_RELOAD}"
|
||||
if [ -n "${DEPLOY_HAPROXY_RELOAD}" ]; then
|
||||
Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD}"
|
||||
_savedomainconf Le_Deploy_haproxy_reload "${Le_Deploy_haproxy_reload}"
|
||||
@ -190,7 +195,7 @@ haproxy_deploy() {
|
||||
_info "Updating OCSP stapling info"
|
||||
_debug _ocsp "${_ocsp}"
|
||||
_info "Extracting OCSP URL"
|
||||
_ocsp_url=$(openssl x509 -noout -ocsp_uri -in "${_pem}")
|
||||
_ocsp_url=$(${ACME_OPENSSL_BIN:-openssl} x509 -noout -ocsp_uri -in "${_pem}")
|
||||
_debug _ocsp_url "${_ocsp_url}"
|
||||
|
||||
# Only process OCSP if URL was present
|
||||
@ -203,9 +208,9 @@ haproxy_deploy() {
|
||||
# Only process the certificate if we have a .issuer file
|
||||
if [ -r "${_issuer}" ]; then
|
||||
# Check if issuer cert is also a root CA cert
|
||||
_subjectdn=$(openssl x509 -in "${_issuer}" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)
|
||||
_subjectdn=$(${ACME_OPENSSL_BIN:-openssl} x509 -in "${_issuer}" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)
|
||||
_debug _subjectdn "${_subjectdn}"
|
||||
_issuerdn=$(openssl x509 -in "${_issuer}" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)
|
||||
_issuerdn=$(${ACME_OPENSSL_BIN:-openssl} x509 -in "${_issuer}" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)
|
||||
_debug _issuerdn "${_issuerdn}"
|
||||
_info "Requesting OCSP response"
|
||||
# If the issuer is a CA cert then our command line has "-CAfile" added
|
||||
@ -216,7 +221,7 @@ haproxy_deploy() {
|
||||
fi
|
||||
_debug _cafile_argument "${_cafile_argument}"
|
||||
# if OpenSSL/LibreSSL is v1.1 or above, the format for the -header option has changed
|
||||
_openssl_version=$(openssl version | cut -d' ' -f2)
|
||||
_openssl_version=$(${ACME_OPENSSL_BIN:-openssl} version | cut -d' ' -f2)
|
||||
_debug _openssl_version "${_openssl_version}"
|
||||
_openssl_major=$(echo "${_openssl_version}" | cut -d '.' -f1)
|
||||
_openssl_minor=$(echo "${_openssl_version}" | cut -d '.' -f2)
|
||||
@ -226,7 +231,7 @@ haproxy_deploy() {
|
||||
_header_sep=" "
|
||||
fi
|
||||
# Request the OCSP response from the issuer and store it
|
||||
_openssl_ocsp_cmd="openssl ocsp \
|
||||
_openssl_ocsp_cmd="${ACME_OPENSSL_BIN:-openssl} ocsp \
|
||||
-issuer \"${_issuer}\" \
|
||||
-cert \"${_pem}\" \
|
||||
-url \"${_ocsp_url}\" \
|
||||
|
@ -45,7 +45,7 @@ kong_deploy() {
|
||||
#Generate data for request (Multipart/form-data with mixed content)
|
||||
if [ -z "$ssl_uuid" ]; then
|
||||
#set sni to domain
|
||||
content="--$delim${nl}Content-Disposition: form-data; name=\"snis\"${nl}${nl}$_cdomain"
|
||||
content="--$delim${nl}Content-Disposition: form-data; name=\"snis[]\"${nl}${nl}$_cdomain"
|
||||
fi
|
||||
#add key
|
||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")"
|
||||
|
280
deploy/lighttpd.sh
Normal file
280
deploy/lighttpd.sh
Normal file
@ -0,0 +1,280 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Script for acme.sh to deploy certificates to lighttpd
|
||||
#
|
||||
# The following variables can be exported:
|
||||
#
|
||||
# export DEPLOY_LIGHTTPD_PEM_NAME="${domain}.pem"
|
||||
#
|
||||
# Defines the name of the PEM file.
|
||||
# Defaults to "<domain>.pem"
|
||||
#
|
||||
# export DEPLOY_LIGHTTPD_PEM_PATH="/etc/lighttpd"
|
||||
#
|
||||
# Defines location of PEM file for Lighttpd.
|
||||
# Defaults to /etc/lighttpd
|
||||
#
|
||||
# export DEPLOY_LIGHTTPD_RELOAD="systemctl reload lighttpd"
|
||||
#
|
||||
# OPTIONAL: Reload command used post deploy
|
||||
# This defaults to be a no-op (ie "true").
|
||||
# It is strongly recommended to set this something that makes sense
|
||||
# for your distro.
|
||||
#
|
||||
# export DEPLOY_LIGHTTPD_ISSUER="yes"
|
||||
#
|
||||
# OPTIONAL: Places CA file as "${DEPLOY_LIGHTTPD_PEM}.issuer"
|
||||
# Note: Required for OCSP stapling to work
|
||||
#
|
||||
# export DEPLOY_LIGHTTPD_BUNDLE="no"
|
||||
#
|
||||
# OPTIONAL: Deploy this certificate as part of a multi-cert bundle
|
||||
# This adds a suffix to the certificate based on the certificate type
|
||||
# eg RSA certificates will have .rsa as a suffix to the file name
|
||||
# Lighttpd will load all certificates and provide one or the other
|
||||
# depending on client capabilities
|
||||
# Note: This functionality requires Lighttpd was compiled against
|
||||
# a version of OpenSSL that supports this.
|
||||
#
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
lighttpd_deploy() {
|
||||
_cdomain="$1"
|
||||
_ckey="$2"
|
||||
_ccert="$3"
|
||||
_cca="$4"
|
||||
_cfullchain="$5"
|
||||
|
||||
# Some defaults
|
||||
DEPLOY_LIGHTTPD_PEM_PATH_DEFAULT="/etc/lighttpd"
|
||||
DEPLOY_LIGHTTPD_PEM_NAME_DEFAULT="${_cdomain}.pem"
|
||||
DEPLOY_LIGHTTPD_BUNDLE_DEFAULT="no"
|
||||
DEPLOY_LIGHTTPD_ISSUER_DEFAULT="yes"
|
||||
DEPLOY_LIGHTTPD_RELOAD_DEFAULT="true"
|
||||
|
||||
_debug _cdomain "${_cdomain}"
|
||||
_debug _ckey "${_ckey}"
|
||||
_debug _ccert "${_ccert}"
|
||||
_debug _cca "${_cca}"
|
||||
_debug _cfullchain "${_cfullchain}"
|
||||
|
||||
# PEM_PATH is optional. If not provided then assume "${DEPLOY_LIGHTTPD_PEM_PATH_DEFAULT}"
|
||||
_getdeployconf DEPLOY_LIGHTTPD_PEM_PATH
|
||||
_debug2 DEPLOY_LIGHTTPD_PEM_PATH "${DEPLOY_LIGHTTPD_PEM_PATH}"
|
||||
if [ -n "${DEPLOY_LIGHTTPD_PEM_PATH}" ]; then
|
||||
Le_Deploy_lighttpd_pem_path="${DEPLOY_LIGHTTPD_PEM_PATH}"
|
||||
_savedomainconf Le_Deploy_lighttpd_pem_path "${Le_Deploy_lighttpd_pem_path}"
|
||||
elif [ -z "${Le_Deploy_lighttpd_pem_path}" ]; then
|
||||
Le_Deploy_lighttpd_pem_path="${DEPLOY_LIGHTTPD_PEM_PATH_DEFAULT}"
|
||||
fi
|
||||
|
||||
# Ensure PEM_PATH exists
|
||||
if [ -d "${Le_Deploy_lighttpd_pem_path}" ]; then
|
||||
_debug "PEM_PATH ${Le_Deploy_lighttpd_pem_path} exists"
|
||||
else
|
||||
_err "PEM_PATH ${Le_Deploy_lighttpd_pem_path} does not exist"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# PEM_NAME is optional. If not provided then assume "${DEPLOY_LIGHTTPD_PEM_NAME_DEFAULT}"
|
||||
_getdeployconf DEPLOY_LIGHTTPD_PEM_NAME
|
||||
_debug2 DEPLOY_LIGHTTPD_PEM_NAME "${DEPLOY_LIGHTTPD_PEM_NAME}"
|
||||
if [ -n "${DEPLOY_LIGHTTPD_PEM_NAME}" ]; then
|
||||
Le_Deploy_lighttpd_pem_name="${DEPLOY_LIGHTTPD_PEM_NAME}"
|
||||
_savedomainconf Le_Deploy_lighttpd_pem_name "${Le_Deploy_lighttpd_pem_name}"
|
||||
elif [ -z "${Le_Deploy_lighttpd_pem_name}" ]; then
|
||||
Le_Deploy_lighttpd_pem_name="${DEPLOY_LIGHTTPD_PEM_NAME_DEFAULT}"
|
||||
fi
|
||||
|
||||
# BUNDLE is optional. If not provided then assume "${DEPLOY_LIGHTTPD_BUNDLE_DEFAULT}"
|
||||
_getdeployconf DEPLOY_LIGHTTPD_BUNDLE
|
||||
_debug2 DEPLOY_LIGHTTPD_BUNDLE "${DEPLOY_LIGHTTPD_BUNDLE}"
|
||||
if [ -n "${DEPLOY_LIGHTTPD_BUNDLE}" ]; then
|
||||
Le_Deploy_lighttpd_bundle="${DEPLOY_LIGHTTPD_BUNDLE}"
|
||||
_savedomainconf Le_Deploy_lighttpd_bundle "${Le_Deploy_lighttpd_bundle}"
|
||||
elif [ -z "${Le_Deploy_lighttpd_bundle}" ]; then
|
||||
Le_Deploy_lighttpd_bundle="${DEPLOY_LIGHTTPD_BUNDLE_DEFAULT}"
|
||||
fi
|
||||
|
||||
# ISSUER is optional. If not provided then assume "${DEPLOY_LIGHTTPD_ISSUER_DEFAULT}"
|
||||
_getdeployconf DEPLOY_LIGHTTPD_ISSUER
|
||||
_debug2 DEPLOY_LIGHTTPD_ISSUER "${DEPLOY_LIGHTTPD_ISSUER}"
|
||||
if [ -n "${DEPLOY_LIGHTTPD_ISSUER}" ]; then
|
||||
Le_Deploy_lighttpd_issuer="${DEPLOY_LIGHTTPD_ISSUER}"
|
||||
_savedomainconf Le_Deploy_lighttpd_issuer "${Le_Deploy_lighttpd_issuer}"
|
||||
elif [ -z "${Le_Deploy_lighttpd_issuer}" ]; then
|
||||
Le_Deploy_lighttpd_issuer="${DEPLOY_LIGHTTPD_ISSUER_DEFAULT}"
|
||||
fi
|
||||
|
||||
# RELOAD is optional. If not provided then assume "${DEPLOY_LIGHTTPD_RELOAD_DEFAULT}"
|
||||
_getdeployconf DEPLOY_LIGHTTPD_RELOAD
|
||||
_debug2 DEPLOY_LIGHTTPD_RELOAD "${DEPLOY_LIGHTTPD_RELOAD}"
|
||||
if [ -n "${DEPLOY_LIGHTTPD_RELOAD}" ]; then
|
||||
Le_Deploy_lighttpd_reload="${DEPLOY_LIGHTTPD_RELOAD}"
|
||||
_savedomainconf Le_Deploy_lighttpd_reload "${Le_Deploy_lighttpd_reload}"
|
||||
elif [ -z "${Le_Deploy_lighttpd_reload}" ]; then
|
||||
Le_Deploy_lighttpd_reload="${DEPLOY_LIGHTTPD_RELOAD_DEFAULT}"
|
||||
fi
|
||||
|
||||
# Set the suffix depending if we are creating a bundle or not
|
||||
if [ "${Le_Deploy_lighttpd_bundle}" = "yes" ]; then
|
||||
_info "Bundle creation requested"
|
||||
# Initialise $Le_Keylength if its not already set
|
||||
if [ -z "${Le_Keylength}" ]; then
|
||||
Le_Keylength=""
|
||||
fi
|
||||
if _isEccKey "${Le_Keylength}"; then
|
||||
_info "ECC key type detected"
|
||||
_suffix=".ecdsa"
|
||||
else
|
||||
_info "RSA key type detected"
|
||||
_suffix=".rsa"
|
||||
fi
|
||||
else
|
||||
_suffix=""
|
||||
fi
|
||||
_debug _suffix "${_suffix}"
|
||||
|
||||
# Set variables for later
|
||||
_pem="${Le_Deploy_lighttpd_pem_path}/${Le_Deploy_lighttpd_pem_name}${_suffix}"
|
||||
_issuer="${_pem}.issuer"
|
||||
_ocsp="${_pem}.ocsp"
|
||||
_reload="${Le_Deploy_lighttpd_reload}"
|
||||
|
||||
_info "Deploying PEM file"
|
||||
# Create a temporary PEM file
|
||||
_temppem="$(_mktemp)"
|
||||
_debug _temppem "${_temppem}"
|
||||
cat "${_ckey}" "${_ccert}" "${_cca}" >"${_temppem}"
|
||||
_ret="$?"
|
||||
|
||||
# Check that we could create the temporary file
|
||||
if [ "${_ret}" != "0" ]; then
|
||||
_err "Error code ${_ret} returned during PEM file creation"
|
||||
[ -f "${_temppem}" ] && rm -f "${_temppem}"
|
||||
return ${_ret}
|
||||
fi
|
||||
|
||||
# Move PEM file into place
|
||||
_info "Moving new certificate into place"
|
||||
_debug _pem "${_pem}"
|
||||
cat "${_temppem}" >"${_pem}"
|
||||
_ret=$?
|
||||
|
||||
# Clean up temp file
|
||||
[ -f "${_temppem}" ] && rm -f "${_temppem}"
|
||||
|
||||
# Deal with any failure of moving PEM file into place
|
||||
if [ "${_ret}" != "0" ]; then
|
||||
_err "Error code ${_ret} returned while moving new certificate into place"
|
||||
return ${_ret}
|
||||
fi
|
||||
|
||||
# Update .issuer file if requested
|
||||
if [ "${Le_Deploy_lighttpd_issuer}" = "yes" ]; then
|
||||
_info "Updating .issuer file"
|
||||
_debug _issuer "${_issuer}"
|
||||
cat "${_cca}" >"${_issuer}"
|
||||
_ret="$?"
|
||||
|
||||
if [ "${_ret}" != "0" ]; then
|
||||
_err "Error code ${_ret} returned while copying issuer/CA certificate into place"
|
||||
return ${_ret}
|
||||
fi
|
||||
else
|
||||
[ -f "${_issuer}" ] && _err "Issuer file update not requested but .issuer file exists"
|
||||
fi
|
||||
|
||||
# Update .ocsp file if certificate was requested with --ocsp/--ocsp-must-staple option
|
||||
if [ -z "${Le_OCSP_Staple}" ]; then
|
||||
Le_OCSP_Staple="0"
|
||||
fi
|
||||
if [ "${Le_OCSP_Staple}" = "1" ]; then
|
||||
_info "Updating OCSP stapling info"
|
||||
_debug _ocsp "${_ocsp}"
|
||||
_info "Extracting OCSP URL"
|
||||
_ocsp_url=$(${ACME_OPENSSL_BIN:-openssl} x509 -noout -ocsp_uri -in "${_pem}")
|
||||
_debug _ocsp_url "${_ocsp_url}"
|
||||
|
||||
# Only process OCSP if URL was present
|
||||
if [ "${_ocsp_url}" != "" ]; then
|
||||
# Extract the hostname from the OCSP URL
|
||||
_info "Extracting OCSP URL"
|
||||
_ocsp_host=$(echo "${_ocsp_url}" | cut -d/ -f3)
|
||||
_debug _ocsp_host "${_ocsp_host}"
|
||||
|
||||
# Only process the certificate if we have a .issuer file
|
||||
if [ -r "${_issuer}" ]; then
|
||||
# Check if issuer cert is also a root CA cert
|
||||
_subjectdn=$(${ACME_OPENSSL_BIN:-openssl} x509 -in "${_issuer}" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)
|
||||
_debug _subjectdn "${_subjectdn}"
|
||||
_issuerdn=$(${ACME_OPENSSL_BIN:-openssl} x509 -in "${_issuer}" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)
|
||||
_debug _issuerdn "${_issuerdn}"
|
||||
_info "Requesting OCSP response"
|
||||
# If the issuer is a CA cert then our command line has "-CAfile" added
|
||||
if [ "${_subjectdn}" = "${_issuerdn}" ]; then
|
||||
_cafile_argument="-CAfile \"${_issuer}\""
|
||||
else
|
||||
_cafile_argument=""
|
||||
fi
|
||||
_debug _cafile_argument "${_cafile_argument}"
|
||||
# if OpenSSL/LibreSSL is v1.1 or above, the format for the -header option has changed
|
||||
_openssl_version=$(${ACME_OPENSSL_BIN:-openssl} version | cut -d' ' -f2)
|
||||
_debug _openssl_version "${_openssl_version}"
|
||||
_openssl_major=$(echo "${_openssl_version}" | cut -d '.' -f1)
|
||||
_openssl_minor=$(echo "${_openssl_version}" | cut -d '.' -f2)
|
||||
if [ "${_openssl_major}" -eq "1" ] && [ "${_openssl_minor}" -ge "1" ] || [ "${_openssl_major}" -ge "2" ]; then
|
||||
_header_sep="="
|
||||
else
|
||||
_header_sep=" "
|
||||
fi
|
||||
# Request the OCSP response from the issuer and store it
|
||||
_openssl_ocsp_cmd="${ACME_OPENSSL_BIN:-openssl} ocsp \
|
||||
-issuer \"${_issuer}\" \
|
||||
-cert \"${_pem}\" \
|
||||
-url \"${_ocsp_url}\" \
|
||||
-header Host${_header_sep}\"${_ocsp_host}\" \
|
||||
-respout \"${_ocsp}\" \
|
||||
-verify_other \"${_issuer}\" \
|
||||
${_cafile_argument} \
|
||||
| grep -q \"${_pem}: good\""
|
||||
_debug _openssl_ocsp_cmd "${_openssl_ocsp_cmd}"
|
||||
eval "${_openssl_ocsp_cmd}"
|
||||
_ret=$?
|
||||
else
|
||||
# Non fatal: No issuer file was present so no OCSP stapling file created
|
||||
_err "OCSP stapling in use but no .issuer file was present"
|
||||
fi
|
||||
else
|
||||
# Non fatal: No OCSP url was found int the certificate
|
||||
_err "OCSP update requested but no OCSP URL was found in certificate"
|
||||
fi
|
||||
|
||||
# Non fatal: Check return code of openssl command
|
||||
if [ "${_ret}" != "0" ]; then
|
||||
_err "Updating OCSP stapling failed with return code ${_ret}"
|
||||
fi
|
||||
else
|
||||
# An OCSP file was already present but certificate did not have OCSP extension
|
||||
if [ -f "${_ocsp}" ]; then
|
||||
_err "OCSP was not requested but .ocsp file exists."
|
||||
# Could remove the file at this step, although Lighttpd just ignores it in this case
|
||||
# rm -f "${_ocsp}" || _err "Problem removing stale .ocsp file"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Reload Lighttpd
|
||||
_debug _reload "${_reload}"
|
||||
eval "${_reload}"
|
||||
_ret=$?
|
||||
if [ "${_ret}" != "0" ]; then
|
||||
_err "Error code ${_ret} during reload"
|
||||
return ${_ret}
|
||||
else
|
||||
_info "Reload successful"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
@ -37,11 +37,6 @@ ssh_deploy() {
|
||||
_cfullchain="$5"
|
||||
_deploy_ssh_servers=""
|
||||
|
||||
if [ -f "$DOMAIN_CONF" ]; then
|
||||
# shellcheck disable=SC1090
|
||||
. "$DOMAIN_CONF"
|
||||
fi
|
||||
|
||||
_debug _cdomain "$_cdomain"
|
||||
_debug _ckey "$_ckey"
|
||||
_debug _ccert "$_ccert"
|
||||
@ -49,6 +44,8 @@ ssh_deploy() {
|
||||
_debug _cfullchain "$_cfullchain"
|
||||
|
||||
# USER is required to login by SSH to remote host.
|
||||
_getdeployconf DEPLOY_SSH_USER
|
||||
_debug2 DEPLOY_SSH_USER "$DEPLOY_SSH_USER"
|
||||
if [ -z "$DEPLOY_SSH_USER" ]; then
|
||||
if [ -z "$Le_Deploy_ssh_user" ]; then
|
||||
_err "DEPLOY_SSH_USER not defined."
|
||||
@ -60,6 +57,8 @@ ssh_deploy() {
|
||||
fi
|
||||
|
||||
# SERVER is optional. If not provided then use _cdomain
|
||||
_getdeployconf DEPLOY_SSH_SERVER
|
||||
_debug2 DEPLOY_SSH_SERVER "$DEPLOY_SSH_SERVER"
|
||||
if [ -n "$DEPLOY_SSH_SERVER" ]; then
|
||||
Le_Deploy_ssh_server="$DEPLOY_SSH_SERVER"
|
||||
_savedomainconf Le_Deploy_ssh_server "$Le_Deploy_ssh_server"
|
||||
@ -68,6 +67,8 @@ ssh_deploy() {
|
||||
fi
|
||||
|
||||
# CMD is optional. If not provided then use ssh
|
||||
_getdeployconf DEPLOY_SSH_CMD
|
||||
_debug2 DEPLOY_SSH_CMD "$DEPLOY_SSH_CMD"
|
||||
if [ -n "$DEPLOY_SSH_CMD" ]; then
|
||||
Le_Deploy_ssh_cmd="$DEPLOY_SSH_CMD"
|
||||
_savedomainconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd"
|
||||
@ -94,6 +95,8 @@ ssh_deploy() {
|
||||
fi
|
||||
|
||||
# BACKUP is optional. If not provided then default to previously saved value or yes.
|
||||
_getdeployconf DEPLOY_SSH_BACKUP
|
||||
_debug2 DEPLOY_SSH_BACKUP "$DEPLOY_SSH_BACKUP"
|
||||
if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then
|
||||
Le_Deploy_ssh_backup="no"
|
||||
elif [ -z "$Le_Deploy_ssh_backup" ] || [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
|
||||
@ -102,6 +105,8 @@ ssh_deploy() {
|
||||
_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
|
||||
_getdeployconf DEPLOY_SSH_BACKUP_PATH
|
||||
_debug2 DEPLOY_SSH_BACKUP_PATH "$DEPLOY_SSH_BACKUP_PATH"
|
||||
if [ -n "$DEPLOY_SSH_BACKUP_PATH" ]; then
|
||||
Le_Deploy_ssh_backup_path="$DEPLOY_SSH_BACKUP_PATH"
|
||||
elif [ -z "$Le_Deploy_ssh_backup_path" ]; then
|
||||
@ -111,6 +116,8 @@ ssh_deploy() {
|
||||
|
||||
# MULTI_CALL is optional. If not provided then default to previously saved
|
||||
# value (which may be undefined... equivalent to "no").
|
||||
_getdeployconf DEPLOY_SSH_MULTI_CALL
|
||||
_debug2 DEPLOY_SSH_MULTI_CALL "$DEPLOY_SSH_MULTI_CALL"
|
||||
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
|
||||
Le_Deploy_ssh_multi_call="yes"
|
||||
_savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call"
|
||||
@ -189,6 +196,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
|
||||
|
||||
# KEYFILE is optional.
|
||||
# If provided then private key will be copied to provided filename.
|
||||
_getdeployconf DEPLOY_SSH_KEYFILE
|
||||
_debug2 DEPLOY_SSH_KEYFILE "$DEPLOY_SSH_KEYFILE"
|
||||
if [ -n "$DEPLOY_SSH_KEYFILE" ]; then
|
||||
Le_Deploy_ssh_keyfile="$DEPLOY_SSH_KEYFILE"
|
||||
_savedomainconf Le_Deploy_ssh_keyfile "$Le_Deploy_ssh_keyfile"
|
||||
@ -225,6 +234,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
|
||||
|
||||
# CERTFILE is optional.
|
||||
# If provided then certificate will be copied or appended to provided filename.
|
||||
_getdeployconf DEPLOY_SSH_CERTFILE
|
||||
_debug2 DEPLOY_SSH_CERTFILE "$DEPLOY_SSH_CERTFILE"
|
||||
if [ -n "$DEPLOY_SSH_CERTFILE" ]; then
|
||||
Le_Deploy_ssh_certfile="$DEPLOY_SSH_CERTFILE"
|
||||
_savedomainconf Le_Deploy_ssh_certfile "$Le_Deploy_ssh_certfile"
|
||||
@ -273,6 +284,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
|
||||
|
||||
# CAFILE is optional.
|
||||
# If provided then CA intermediate certificate will be copied or appended to provided filename.
|
||||
_getdeployconf DEPLOY_SSH_CAFILE
|
||||
_debug2 DEPLOY_SSH_CAFILE "$DEPLOY_SSH_CAFILE"
|
||||
if [ -n "$DEPLOY_SSH_CAFILE" ]; then
|
||||
Le_Deploy_ssh_cafile="$DEPLOY_SSH_CAFILE"
|
||||
_savedomainconf Le_Deploy_ssh_cafile "$Le_Deploy_ssh_cafile"
|
||||
@ -329,6 +342,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
|
||||
|
||||
# FULLCHAIN is optional.
|
||||
# If provided then fullchain certificate will be copied or appended to provided filename.
|
||||
_getdeployconf DEPLOY_SSH_FULLCHAIN
|
||||
_debug2 DEPLOY_SSH_FULLCHAIN "$DEPLOY_SSH_FULLCHAIN"
|
||||
if [ -n "$DEPLOY_SSH_FULLCHAIN" ]; then
|
||||
Le_Deploy_ssh_fullchain="$DEPLOY_SSH_FULLCHAIN"
|
||||
_savedomainconf Le_Deploy_ssh_fullchain "$Le_Deploy_ssh_fullchain"
|
||||
@ -399,6 +414,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
|
||||
|
||||
# REMOTE_CMD is optional.
|
||||
# If provided then this command will be executed on remote host.
|
||||
_getdeployconf DEPLOY_SSH_REMOTE_CMD
|
||||
_debug2 DEPLOY_SSH_REMOTE_CMD "$DEPLOY_SSH_REMOTE_CMD"
|
||||
if [ -n "$DEPLOY_SSH_REMOTE_CMD" ]; then
|
||||
Le_Deploy_ssh_remote_cmd="$DEPLOY_SSH_REMOTE_CMD"
|
||||
_savedomainconf Le_Deploy_ssh_remote_cmd "$Le_Deploy_ssh_remote_cmd"
|
||||
|
@ -100,6 +100,7 @@ synology_dsm_deploy() {
|
||||
if [ -z "$token" ]; then
|
||||
_err "Unable to authenticate to $SYNO_Hostname:$SYNO_Port using $SYNO_Scheme."
|
||||
_err "Check your username and password."
|
||||
_err "If two-factor authentication is enabled for the user, you have to choose another user."
|
||||
return 1
|
||||
fi
|
||||
sid=$(echo "$response" | grep "sid" | sed -n 's/.*"sid" *: *"\([^"]*\).*/\1/p')
|
||||
|
@ -46,7 +46,7 @@ dns_1984hosting_add() {
|
||||
|
||||
postdata="entry=new"
|
||||
postdata="$postdata&type=TXT"
|
||||
postdata="$postdata&ttl=3600"
|
||||
postdata="$postdata&ttl=900"
|
||||
postdata="$postdata&zone=$_domain"
|
||||
postdata="$postdata&host=$_sub_domain"
|
||||
postdata="$postdata&rdata=%22$value%22"
|
||||
@ -93,20 +93,15 @@ dns_1984hosting_rm() {
|
||||
fi
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug "Delete $fulldomain TXT record"
|
||||
url="https://management.1984hosting.com/domains"
|
||||
|
||||
_htmlget "$url" "$_domain"
|
||||
_debug2 _response "$_response"
|
||||
zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')"
|
||||
_debug2 zone_id "$zone_id"
|
||||
if [ -z "$zone_id" ]; then
|
||||
_err "Error getting zone_id for $1"
|
||||
url="https://management.1984hosting.com/domains"
|
||||
if ! _get_zone_id "$url" "$_domain"; then
|
||||
_err "invalid zone" "$_domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_htmlget "$url/$zone_id" "$_sub_domain"
|
||||
_htmlget "$url/$_zone_id" "$txtvalue"
|
||||
_debug2 _response "$_response"
|
||||
entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')"
|
||||
_debug2 entry_id "$entry_id"
|
||||
@ -135,7 +130,7 @@ dns_1984hosting_rm() {
|
||||
_1984hosting_login() {
|
||||
if ! _check_credentials; then return 1; fi
|
||||
|
||||
if _check_cookie; then
|
||||
if _check_cookies; then
|
||||
_debug "Already logged in"
|
||||
return 0
|
||||
fi
|
||||
@ -150,9 +145,12 @@ _1984hosting_login() {
|
||||
_debug2 response "$response"
|
||||
|
||||
if _contains "$response" '"loggedin": true'; then
|
||||
One984HOSTING_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _tail_n 1 | _egrep_o 'sessionid=[^;]*;' | tr -d ';')"
|
||||
export One984HOSTING_COOKIE
|
||||
_saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE"
|
||||
One984HOSTING_SESSIONID_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'sessionid=[^;]*;' | tr -d ';')"
|
||||
One984HOSTING_CSRFTOKEN_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _egrep_o 'csrftoken=[^;]*;' | tr -d ';')"
|
||||
export One984HOSTING_SESSIONID_COOKIE
|
||||
export One984HOSTING_CSRFTOKEN_COOKIE
|
||||
_saveaccountconf_mutable One984HOSTING_SESSIONID_COOKIE "$One984HOSTING_SESSIONID_COOKIE"
|
||||
_saveaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE "$One984HOSTING_CSRFTOKEN_COOKIE"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
@ -169,21 +167,24 @@ _check_credentials() {
|
||||
return 0
|
||||
}
|
||||
|
||||
_check_cookie() {
|
||||
One984HOSTING_COOKIE="${One984HOSTING_COOKIE:-$(_readaccountconf_mutable One984HOSTING_COOKIE)}"
|
||||
if [ -z "$One984HOSTING_COOKIE" ]; then
|
||||
_debug "No cached cookie found"
|
||||
_check_cookies() {
|
||||
One984HOSTING_SESSIONID_COOKIE="${One984HOSTING_SESSIONID_COOKIE:-$(_readaccountconf_mutable One984HOSTING_SESSIONID_COOKIE)}"
|
||||
One984HOSTING_CSRFTOKEN_COOKIE="${One984HOSTING_CSRFTOKEN_COOKIE:-$(_readaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE)}"
|
||||
if [ -z "$One984HOSTING_SESSIONID_COOKIE" ] || [ -z "$One984HOSTING_CSRFTOKEN_COOKIE" ]; then
|
||||
_debug "No cached cookie(s) found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_authget "https://management.1984hosting.com/accounts/loginstatus/"
|
||||
if _contains "$response" '"ok": true'; then
|
||||
_debug "Cached cookie still valid"
|
||||
_debug "Cached cookies still valid"
|
||||
return 0
|
||||
fi
|
||||
_debug "Cached cookie no longer valid"
|
||||
One984HOSTING_COOKIE=""
|
||||
_saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE"
|
||||
_debug "Cached cookies no longer valid"
|
||||
One984HOSTING_SESSIONID_COOKIE=""
|
||||
One984HOSTING_CSRFTOKEN_COOKIE=""
|
||||
_saveaccountconf_mutable One984HOSTING_SESSIONID_COOKIE "$One984HOSTING_SESSIONID_COOKIE"
|
||||
_saveaccountconf_mutable One984HOSTING_CSRFTOKEN_COOKIE "$One984HOSTING_CSRFTOKEN_COOKIE"
|
||||
return 1
|
||||
}
|
||||
|
||||
@ -215,9 +216,25 @@ _get_root() {
|
||||
return 1
|
||||
}
|
||||
|
||||
#usage: _get_zone_id url domain.com
|
||||
#returns zone id for domain.com
|
||||
_get_zone_id() {
|
||||
url=$1
|
||||
domain=$2
|
||||
_htmlget "$url" "$domain"
|
||||
_debug2 _response "$_response"
|
||||
_zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+' | _head_n 1)"
|
||||
_debug2 _zone_id "$_zone_id"
|
||||
if [ -z "$_zone_id" ]; then
|
||||
_err "Error getting _zone_id for $2"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# add extra headers to request
|
||||
_authget() {
|
||||
export _H1="Cookie: $One984HOSTING_COOKIE"
|
||||
export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE"
|
||||
_response=$(_get "$1" | _normalizeJson)
|
||||
_debug2 _response "$_response"
|
||||
}
|
||||
@ -225,12 +242,20 @@ _authget() {
|
||||
# truncate huge HTML response
|
||||
# echo: Argument list too long
|
||||
_htmlget() {
|
||||
export _H1="Cookie: $One984HOSTING_COOKIE"
|
||||
_response=$(_get "$1" | grep "$2" | _head_n 1)
|
||||
export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE"
|
||||
_response=$(_get "$1" | grep "$2")
|
||||
if _contains "$_response" "@$2"; then
|
||||
_response=$(echo "$_response" | grep -v "[@]" | _head_n 1)
|
||||
fi
|
||||
}
|
||||
|
||||
# add extra headers to request
|
||||
_authpost() {
|
||||
export _H1="Cookie: $One984HOSTING_COOKIE"
|
||||
url="https://management.1984hosting.com/domains"
|
||||
_get_zone_id "$url" "$_domain"
|
||||
csrf_header="$(echo "$One984HOSTING_CSRFTOKEN_COOKIE" | _egrep_o "=[^=][0-9a-zA-Z]*" | tr -d "=")"
|
||||
export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE"
|
||||
export _H2="Referer: https://management.1984hosting.com/domains/$_zone_id"
|
||||
export _H3="X-CSRFToken: $csrf_header"
|
||||
_response=$(_post "$1" "$2")
|
||||
}
|
||||
|
159
dnsapi/dns_cpanel.sh
Executable file
159
dnsapi/dns_cpanel.sh
Executable file
@ -0,0 +1,159 @@
|
||||
#!/usr/bin/env sh
|
||||
#
|
||||
#Author: Bjarne Saltbaek
|
||||
#Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/3732
|
||||
#
|
||||
#
|
||||
######## Public functions #####################
|
||||
#
|
||||
# Export CPANEL username,api token and hostname in the following variables
|
||||
#
|
||||
# cPanel_Username=username
|
||||
# cPanel_Apitoken=apitoken
|
||||
# cPanel_Hostname=hostname
|
||||
#
|
||||
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
# Used to add txt record
|
||||
dns_cpanel_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
_info "Adding TXT record to cPanel based system"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
_debug cPanel_Username "$cPanel_Username"
|
||||
_debug cPanel_Apitoken "$cPanel_Apitoken"
|
||||
_debug cPanel_Hostname "$cPanel_Hostname"
|
||||
|
||||
if ! _cpanel_login; then
|
||||
_err "cPanel Login failed for user $cPanel_Username. Check $HTTP_HEADER file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "No matching root domain for $fulldomain found"
|
||||
return 1
|
||||
fi
|
||||
# adding entry
|
||||
_info "Adding the entry"
|
||||
stripped_fulldomain=$(echo "$fulldomain" | sed "s/.$_domain//")
|
||||
_debug "Adding $stripped_fulldomain to $_domain zone"
|
||||
_myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=add_zone_record&domain=$_domain&name=$stripped_fulldomain&type=TXT&txtdata=$txtvalue&ttl=1"
|
||||
if _successful_update; then return 0; fi
|
||||
_err "Couldn't create entry!"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Usage: fulldomain txtvalue
|
||||
# Used to remove the txt record after validation
|
||||
dns_cpanel_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
_info "Using cPanel based system"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
if ! _cpanel_login; then
|
||||
_err "cPanel Login failed for user $cPanel_Username. Check $HTTP_HEADER file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _get_root; then
|
||||
_err "No matching root domain for $fulldomain found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_findentry "$fulldomain" "$txtvalue"
|
||||
if [ -z "$_id" ]; then
|
||||
_info "Entry doesn't exist, nothing to delete"
|
||||
return 0
|
||||
fi
|
||||
_debug "Deleting record..."
|
||||
_myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=remove_zone_record&domain=$_domain&line=$_id"
|
||||
# removing entry
|
||||
_debug "_result is: $_result"
|
||||
|
||||
if _successful_update; then return 0; fi
|
||||
_err "Couldn't delete entry!"
|
||||
return 1
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
|
||||
_checkcredentials() {
|
||||
cPanel_Username="${cPanel_Username:-$(_readaccountconf_mutable cPanel_Username)}"
|
||||
cPanel_Apitoken="${cPanel_Apitoken:-$(_readaccountconf_mutable cPanel_Apitoken)}"
|
||||
cPanel_Hostname="${cPanel_Hostname:-$(_readaccountconf_mutable cPanel_Hostname)}"
|
||||
|
||||
if [ -z "$cPanel_Username" ] || [ -z "$cPanel_Apitoken" ] || [ -z "$cPanel_Hostname" ]; then
|
||||
cPanel_Username=""
|
||||
cPanel_Apitoken=""
|
||||
cPanel_Hostname=""
|
||||
_err "You haven't specified cPanel username, apitoken and hostname yet."
|
||||
_err "Please add credentials and try again."
|
||||
return 1
|
||||
fi
|
||||
#save the credentials to the account conf file.
|
||||
_saveaccountconf_mutable cPanel_Username "$cPanel_Username"
|
||||
_saveaccountconf_mutable cPanel_Apitoken "$cPanel_Apitoken"
|
||||
_saveaccountconf_mutable cPanel_Hostname "$cPanel_Hostname"
|
||||
return 0
|
||||
}
|
||||
|
||||
_cpanel_login() {
|
||||
if ! _checkcredentials; then return 1; fi
|
||||
|
||||
if ! _myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=CustInfo&cpanel_jsonapi_func=displaycontactinfo"; then
|
||||
_err "cPanel login failed for user $cPanel_Username."
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
_myget() {
|
||||
#Adds auth header to request
|
||||
export _H1="Authorization: cpanel $cPanel_Username:$cPanel_Apitoken"
|
||||
_result=$(_get "$cPanel_Hostname/$1")
|
||||
}
|
||||
|
||||
_get_root() {
|
||||
_myget 'json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzones'
|
||||
_domains=$(echo "$_result" | sed 's/.*\(zones.*\[\).*/\1/' | cut -d':' -f2 | sed 's/"//g' | sed 's/{//g')
|
||||
_debug "_result is: $_result"
|
||||
_debug "_domains is: $_domains"
|
||||
if [ -z "$_domains" ]; then
|
||||
_err "Primary domain list not found!"
|
||||
return 1
|
||||
fi
|
||||
for _domain in $_domains; do
|
||||
_debug "Checking if $fulldomain ends with $_domain"
|
||||
if (_endswith "$fulldomain" "$_domain"); then
|
||||
_debug "Root domain: $_domain"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
_successful_update() {
|
||||
if (echo "$_result" | grep -q 'newserial'); then return 0; fi
|
||||
return 1
|
||||
}
|
||||
|
||||
_findentry() {
|
||||
_debug "In _findentry"
|
||||
#returns id of dns entry, if it exists
|
||||
_myget "json-api/cpanel?cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&domain=$_domain"
|
||||
_id=$(echo "$_result" | sed "s/.*\(line.*$fulldomain.*$txtvalue\).*/\1/" | cut -d ':' -f 2 | cut -d ',' -f 1)
|
||||
_debug "_result is: $_result"
|
||||
_debug "fulldomain. is $fulldomain."
|
||||
_debug "txtvalue is $txtvalue"
|
||||
_debug "_id is: $_id"
|
||||
if [ -n "$_id" ]; then
|
||||
_debug "Entry found with _id=$_id"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
@ -163,5 +163,8 @@ _dns_gcloud_get_rrdatas() {
|
||||
return 1
|
||||
fi
|
||||
ttl=$(echo "$rrdatas" | cut -f1)
|
||||
rrdatas=$(echo "$rrdatas" | cut -f2 | sed 's/","/"\n"/g')
|
||||
# starting with version 353.0.0 gcloud seems to
|
||||
# separate records with a semicolon instead of commas
|
||||
# see also https://cloud.google.com/sdk/docs/release-notes#35300_2021-08-17
|
||||
rrdatas=$(echo "$rrdatas" | cut -f2 | sed 's/"[,;]"/"\n"/g')
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ dns_he_rm() {
|
||||
_debug "The txt record is not found, just skip"
|
||||
return 0
|
||||
fi
|
||||
_record_id="$(echo "$response" | tr -d "#" | sed "s/<tr/#<tr/g" | tr -d "\n" | tr "#" "\n" | grep "$_full_domain" | grep '"dns_tr"' | grep "$_txt_value" | cut -d '"' -f 4)"
|
||||
_record_id="$(echo "$response" | tr -d "#" | sed "s/<tr/#<tr/g" | tr -d "\n" | tr "#" "\n" | grep "$_full_domain" | grep '"dns_tr"' | grep -- "$_txt_value" | cut -d '"' -f 4)"
|
||||
_debug2 _record_id "$_record_id"
|
||||
if [ -z "$_record_id" ]; then
|
||||
_err "Can not find record id"
|
||||
|
@ -119,16 +119,16 @@ login() {
|
||||
tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST")
|
||||
sid=$(echo "$tmp" | tr '{}' '\n' | grep apisessionid | cut -d '"' -f 4)
|
||||
_debug "$tmp"
|
||||
if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then
|
||||
_err "$msg"
|
||||
if [ "$(_getfield "$tmp" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then
|
||||
_err "$tmp"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
logout() {
|
||||
tmp=$(_post "{\"action\": \"logout\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST")
|
||||
_debug "$tmp"
|
||||
if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then
|
||||
_err "$msg"
|
||||
if [ "$(_getfield "$tmp" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then
|
||||
_err "$tmp"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
RACKSPACE_Endpoint="https://dns.api.rackspacecloud.com/v1.0"
|
||||
|
||||
# 20210923 - RS changed the fields in the API response; fix sed
|
||||
# 20190213 - The name & id fields swapped in the API response; fix sed
|
||||
# 20190101 - Duplicating file for new pull request to dev branch
|
||||
# Original - tcocca:rackspace_dnsapi https://github.com/acmesh-official/acme.sh/pull/1297
|
||||
@ -79,8 +80,8 @@ _get_root_zone() {
|
||||
_debug2 response "$response"
|
||||
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
|
||||
# Response looks like:
|
||||
# {"ttl":300,"accountId":12345,"id":1111111,"name":"example.com","emailAddress": ...<and so on>
|
||||
_domain_id=$(echo "$response" | sed -n "s/^.*\"id\":\([^,]*\),\"name\":\"$h\",.*/\1/p")
|
||||
# {"id":"12345","accountId":"1111111","name": "example.com","ttl":3600,"emailAddress": ... <and so on>
|
||||
_domain_id=$(echo "$response" | sed -n "s/^.*\"id\":\"\([^,]*\)\",\"accountId\":\"[0-9]*\",\"name\":\"$h\",.*/\1/p")
|
||||
_debug2 domain_id "$_domain_id"
|
||||
if [ -n "$_domain_id" ]; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
|
158
dnsapi/dns_veesp.sh
Normal file
158
dnsapi/dns_veesp.sh
Normal file
@ -0,0 +1,158 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# bug reports to stepan@plyask.in
|
||||
|
||||
#
|
||||
# export VEESP_User="username"
|
||||
# export VEESP_Password="password"
|
||||
|
||||
VEESP_Api="https://secure.veesp.com/api"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_veesp_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
VEESP_Password="${VEESP_Password:-$(_readaccountconf_mutable VEESP_Password)}"
|
||||
VEESP_User="${VEESP_User:-$(_readaccountconf_mutable VEESP_User)}"
|
||||
VEESP_auth=$(printf "%s" "$VEESP_User:$VEESP_Password" | _base64)
|
||||
|
||||
if [ -z "$VEESP_Password" ] || [ -z "$VEESP_User" ]; then
|
||||
VEESP_Password=""
|
||||
VEESP_User=""
|
||||
_err "You don't specify veesp api key and email yet."
|
||||
_err "Please create you key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
#save the api key and email to the account conf file.
|
||||
_saveaccountconf_mutable VEESP_Password "$VEESP_Password"
|
||||
_saveaccountconf_mutable VEESP_User "$VEESP_User"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
_debug _domain_id "$_domain_id"
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_info "Adding record"
|
||||
if VEESP_rest POST "service/$_service_id/dns/$_domain_id/records" "{\"name\":\"$fulldomain\",\"ttl\":1,\"priority\":0,\"type\":\"TXT\",\"content\":\"$txtvalue\"}"; then
|
||||
if _contains "$response" "\"success\":true"; then
|
||||
_info "Added"
|
||||
#todo: check if the record takes effect
|
||||
return 0
|
||||
else
|
||||
_err "Add txt record error."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Usage: fulldomain txtvalue
|
||||
# Used to remove the txt record after validation
|
||||
dns_veesp_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
VEESP_Password="${VEESP_Password:-$(_readaccountconf_mutable VEESP_Password)}"
|
||||
VEESP_User="${VEESP_User:-$(_readaccountconf_mutable VEESP_User)}"
|
||||
VEESP_auth=$(printf "%s" "$VEESP_User:$VEESP_Password" | _base64)
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
_debug _domain_id "$_domain_id"
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug "Getting txt records"
|
||||
VEESP_rest GET "service/$_service_id/dns/$_domain_id"
|
||||
|
||||
count=$(printf "%s\n" "$response" | _egrep_o "\"type\":\"TXT\",\"content\":\".\"$txtvalue.\"\"" | wc -l | tr -d " ")
|
||||
_debug count "$count"
|
||||
if [ "$count" = "0" ]; then
|
||||
_info "Don't need to remove."
|
||||
else
|
||||
record_id=$(printf "%s\n" "$response" | _egrep_o "{\"id\":[^}]*\"type\":\"TXT\",\"content\":\".\"$txtvalue.\"\"" | cut -d\" -f4)
|
||||
_debug "record_id" "$record_id"
|
||||
if [ -z "$record_id" ]; then
|
||||
_err "Can not get record id to remove."
|
||||
return 1
|
||||
fi
|
||||
if ! VEESP_rest DELETE "service/$_service_id/dns/$_domain_id/records/$record_id"; then
|
||||
_err "Delete record error."
|
||||
return 1
|
||||
fi
|
||||
_contains "$response" "\"success\":true"
|
||||
fi
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
#_acme-challenge.www.domain.com
|
||||
#returns
|
||||
# _sub_domain=_acme-challenge.www
|
||||
# _domain=domain.com
|
||||
# _domain_id=sdjkglgdfewsdfg
|
||||
_get_root() {
|
||||
domain=$1
|
||||
i=2
|
||||
p=1
|
||||
if ! VEESP_rest GET "dns"; then
|
||||
return 1
|
||||
fi
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
_debug h "$h"
|
||||
if [ -z "$h" ]; then
|
||||
#not valid
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "\"name\":\"$h\""; then
|
||||
_domain_id=$(printf "%s\n" "$response" | _egrep_o "\"domain_id\":[^,]*,\"name\":\"$h\"" | cut -d : -f 2 | cut -d , -f 1 | cut -d '"' -f 2)
|
||||
_debug _domain_id "$_domain_id"
|
||||
_service_id=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$h\",\"service_id\":[^}]*" | cut -d : -f 3 | cut -d '"' -f 2)
|
||||
_debug _service_id "$_service_id"
|
||||
if [ "$_domain_id" ]; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain="$h"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
p=$i
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
VEESP_rest() {
|
||||
m=$1
|
||||
ep="$2"
|
||||
data="$3"
|
||||
_debug "$ep"
|
||||
|
||||
export _H1="Accept: application/json"
|
||||
export _H2="Authorization: Basic $VEESP_auth"
|
||||
if [ "$m" != "GET" ]; then
|
||||
_debug data "$data"
|
||||
export _H3="Content-Type: application/json"
|
||||
response="$(_post "$data" "$VEESP_Api/$ep" "" "$m")"
|
||||
else
|
||||
response="$(_get "$VEESP_Api/$ep")"
|
||||
fi
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error $ep"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
@ -36,7 +36,6 @@ dns_world4you_add() {
|
||||
export _H1="Cookie: W4YSESSID=$sessid"
|
||||
form=$(_get "$WORLD4YOU_API/$paketnr/dns")
|
||||
formiddp=$(echo "$form" | grep 'AddDnsRecordForm\[uniqueFormIdDP\]' | sed 's/^.*name="AddDnsRecordForm\[uniqueFormIdDP\]" value="\([^"]*\)".*$/\1/')
|
||||
formidttl=$(echo "$form" | grep 'AddDnsRecordForm\[uniqueFormIdTTL\]' | sed 's/^.*name="AddDnsRecordForm\[uniqueFormIdTTL\]" value="\([^"]*\)".*$/\1/')
|
||||
form_token=$(echo "$form" | grep 'AddDnsRecordForm\[_token\]' | sed 's/^.*name="AddDnsRecordForm\[_token\]" value="\([^"]*\)".*$/\1/')
|
||||
if [ -z "$formiddp" ]; then
|
||||
_err "Unable to parse form"
|
||||
@ -45,9 +44,7 @@ dns_world4you_add() {
|
||||
|
||||
_resethttp
|
||||
export ACME_HTTP_NO_REDIRECTS=1
|
||||
body="AddDnsRecordForm[name]=$RECORD&AddDnsRecordForm[dnsType][type]=TXT&\
|
||||
AddDnsRecordForm[value]=$value&AddDnsRecordForm[aktivPaket]=$paketnr&AddDnsRecordForm[uniqueFormIdDP]=$formiddp&\
|
||||
AddDnsRecordForm[uniqueFormIdTTL]=$formidttl&AddDnsRecordForm[_token]=$form_token"
|
||||
body="AddDnsRecordForm[name]=$RECORD&AddDnsRecordForm[dnsType][type]=TXT&AddDnsRecordForm[value]=$value&AddDnsRecordForm[uniqueFormIdDP]=$formiddp&AddDnsRecordForm[_token]=$form_token"
|
||||
_info "Adding record..."
|
||||
ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns" '' POST 'application/x-www-form-urlencoded')
|
||||
_resethttp
|
||||
@ -101,7 +98,6 @@ dns_world4you_rm() {
|
||||
|
||||
form=$(_get "$WORLD4YOU_API/$paketnr/dns")
|
||||
formiddp=$(echo "$form" | grep 'DeleteDnsRecordForm\[uniqueFormIdDP\]' | sed 's/^.*name="DeleteDnsRecordForm\[uniqueFormIdDP\]" value="\([^"]*\)".*$/\1/')
|
||||
formidttl=$(echo "$form" | grep 'DeleteDnsRecordForm\[uniqueFormIdTTL\]' | sed 's/^.*name="DeleteDnsRecordForm\[uniqueFormIdTTL\]" value="\([^"]*\)".*$/\1/')
|
||||
form_token=$(echo "$form" | grep 'DeleteDnsRecordForm\[_token\]' | sed 's/^.*name="DeleteDnsRecordForm\[_token\]" value="\([^"]*\)".*$/\1/')
|
||||
if [ -z "$formiddp" ]; then
|
||||
_err "Unable to parse form"
|
||||
@ -113,11 +109,9 @@ dns_world4you_rm() {
|
||||
|
||||
_resethttp
|
||||
export ACME_HTTP_NO_REDIRECTS=1
|
||||
body="DeleteDnsRecordForm[recordId]=$recordid&DeleteDnsRecordForm[aktivPaket]=$paketnr&\
|
||||
DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[uniqueFormIdTTL]=$formidttl&\
|
||||
DeleteDnsRecordForm[_token]=$form_token"
|
||||
body="DeleteDnsRecordForm[recordId]=$recordid&DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[_token]=$form_token"
|
||||
_info "Removing record..."
|
||||
ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/deleteRecord" '' POST 'application/x-www-form-urlencoded')
|
||||
ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns/record/delete" '' POST 'application/x-www-form-urlencoded')
|
||||
_resethttp
|
||||
|
||||
if _contains "$(_head_n 3 <"$HTTP_HEADER")" '302'; then
|
||||
@ -190,7 +184,7 @@ _get_paketnr() {
|
||||
fqdn="$1"
|
||||
form="$2"
|
||||
|
||||
domains=$(echo "$form" | grep '^ *[A-Za-z0-9_\.-]*\.[A-Za-z0-9_-]*$' | sed 's/^\s*\(\S*\)$/\1/')
|
||||
domains=$(echo "$form" | grep '^ *[A-Za-z0-9_\.-]*\.[A-Za-z0-9_-]*$' | sed 's/^ *\(.*\)$/\1/')
|
||||
domain=''
|
||||
for domain in $domains; do
|
||||
if _contains "$fqdn" "$domain\$"; then
|
||||
|
51
notify/bark.sh
Normal file
51
notify/bark.sh
Normal file
@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Support iOS Bark Notification
|
||||
|
||||
#BARK_API_URL="https://api.day.app/xxxx"
|
||||
#BARK_SOUND="yyyy"
|
||||
#BARK_GROUP="zzzz"
|
||||
|
||||
# subject content statusCode
|
||||
bark_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_subject" "$_subject"
|
||||
_debug "_content" "$_content"
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
BARK_API_URL="${BARK_API_URL:-$(_readaccountconf_mutable BARK_API_URL)}"
|
||||
if [ -z "$BARK_API_URL" ]; then
|
||||
BARK_API_URL=""
|
||||
_err "You didn't specify a Bark API URL BARK_API_URL yet."
|
||||
_err "You can download Bark from App Store and get yours."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable BARK_API_URL "$BARK_API_URL"
|
||||
|
||||
BARK_SOUND="${BARK_SOUND:-$(_readaccountconf_mutable BARK_SOUND)}"
|
||||
_saveaccountconf_mutable BARK_SOUND "$BARK_SOUND"
|
||||
|
||||
BARK_GROUP="${BARK_GROUP:-$(_readaccountconf_mutable BARK_GROUP)}"
|
||||
if [ -z "$BARK_GROUP" ]; then
|
||||
BARK_GROUP="ACME"
|
||||
_info "The BARK_GROUP is not set, so use the default ACME as group name."
|
||||
else
|
||||
_saveaccountconf_mutable BARK_GROUP "$BARK_GROUP"
|
||||
fi
|
||||
|
||||
_content=$(echo "$_content" | _url_encode)
|
||||
_subject=$(echo "$_subject" | _url_encode)
|
||||
|
||||
response="$(_get "$BARK_API_URL/$_subject/$_content?sound=$BARK_SOUND&group=$BARK_GROUP")"
|
||||
|
||||
if [ "$?" = "0" ] && _contains "$response" "success"; then
|
||||
_info "Bark API fired success."
|
||||
return 0
|
||||
fi
|
||||
|
||||
_err "Bark API fired error."
|
||||
_err "$response"
|
||||
return 1
|
||||
}
|
48
notify/feishu.sh
Normal file
48
notify/feishu.sh
Normal file
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Support feishu webhooks api
|
||||
|
||||
#required
|
||||
#FEISHU_WEBHOOK="xxxx"
|
||||
|
||||
#optional
|
||||
#FEISHU_KEYWORD="yyyy"
|
||||
|
||||
# subject content statusCode
|
||||
feishu_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_subject" "$_subject"
|
||||
_debug "_content" "$_content"
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
FEISHU_WEBHOOK="${FEISHU_WEBHOOK:-$(_readaccountconf_mutable FEISHU_WEBHOOK)}"
|
||||
if [ -z "$FEISHU_WEBHOOK" ]; then
|
||||
FEISHU_WEBHOOK=""
|
||||
_err "You didn't specify a feishu webhooks FEISHU_WEBHOOK yet."
|
||||
_err "You can get yours from https://www.feishu.cn"
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable FEISHU_WEBHOOK "$FEISHU_WEBHOOK"
|
||||
|
||||
FEISHU_KEYWORD="${FEISHU_KEYWORD:-$(_readaccountconf_mutable FEISHU_KEYWORD)}"
|
||||
if [ "$FEISHU_KEYWORD" ]; then
|
||||
_saveaccountconf_mutable FEISHU_KEYWORD "$FEISHU_KEYWORD"
|
||||
fi
|
||||
|
||||
_content=$(echo "$_content" | _json_encode)
|
||||
_subject=$(echo "$_subject" | _json_encode)
|
||||
_data="{\"msg_type\": \"text\", \"content\": {\"text\": \"[$FEISHU_KEYWORD]\n$_subject\n$_content\"}}"
|
||||
|
||||
response="$(_post "$_data" "$FEISHU_WEBHOOK" "" "POST" "application/json")"
|
||||
|
||||
if [ "$?" = "0" ] && _contains "$response" "StatusCode\":0"; then
|
||||
_info "feishu webhooks event fired success."
|
||||
return 0
|
||||
fi
|
||||
|
||||
_err "feishu webhooks event fired error."
|
||||
_err "$response"
|
||||
return 1
|
||||
}
|
@ -62,7 +62,7 @@ mail_send() {
|
||||
fi
|
||||
|
||||
contenttype="text/plain; charset=utf-8"
|
||||
subject="=?UTF-8?B?$(echo "$_subject" | _base64)?="
|
||||
subject="=?UTF-8?B?$(printf -- "%b" "$_subject" | _base64)?="
|
||||
result=$({ _mail_body | eval "$(_mail_cmnd)"; } 2>&1)
|
||||
|
||||
# shellcheck disable=SC2181
|
||||
@ -131,6 +131,7 @@ _mail_body() {
|
||||
echo "To: $MAIL_TO"
|
||||
echo "Subject: $subject"
|
||||
echo "Content-Type: $contenttype"
|
||||
echo "MIME-Version: 1.0"
|
||||
echo
|
||||
;;
|
||||
esac
|
||||
|
44
notify/pushbullet.sh
Normal file
44
notify/pushbullet.sh
Normal file
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Support for pushbullet.com's api. Push notification, notification sync and message platform for multiple platforms
|
||||
#PUSHBULLET_TOKEN="" Required, pushbullet application token
|
||||
#PUSHBULLET_DEVICE="" Optional, Specific device, ignore to send to all devices
|
||||
|
||||
PUSHBULLET_URI="https://api.pushbullet.com/v2/pushes"
|
||||
pushbullet_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
PUSHBULLET_TOKEN="${PUSHBULLET_TOKEN:-$(_readaccountconf_mutable PUSHBULLET_TOKEN)}"
|
||||
if [ -z "$PUSHBULLET_TOKEN" ]; then
|
||||
PUSHBULLET_TOKEN=""
|
||||
_err "You didn't specify a Pushbullet application token yet."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable PUSHBULLET_TOKEN "$PUSHBULLET_TOKEN"
|
||||
|
||||
PUSHBULLET_DEVICE="${PUSHBULLET_DEVICE:-$(_readaccountconf_mutable PUSHBULLET_DEVICE)}"
|
||||
if [ -z "$PUSHBULLET_DEVICE" ]; then
|
||||
_clearaccountconf_mutable PUSHBULLET_DEVICE
|
||||
else
|
||||
_saveaccountconf_mutable PUSHBULLET_DEVICE "$PUSHBULLET_DEVICE"
|
||||
fi
|
||||
|
||||
export _H1="Content-Type: application/json"
|
||||
export _H2="Access-Token: ${PUSHBULLET_TOKEN}"
|
||||
_content="$(printf "*%s*\n" "$_content" | _json_encode)"
|
||||
_subject="$(printf "*%s*\n" "$_subject" | _json_encode)"
|
||||
_data="{\"type\": \"note\",\"title\": \"${_subject}\",\"body\": \"${_content}\",\"device_iden\": \"${PUSHBULLET_DEVICE}\"}"
|
||||
response="$(_post "$_data" "$PUSHBULLET_URI")"
|
||||
|
||||
if [ "$?" != "0" ] || _contains "$response" "\"error_code\""; then
|
||||
_err "PUSHBULLET send error."
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "PUSHBULLET send success."
|
||||
return 0
|
||||
}
|
Loading…
Reference in New Issue
Block a user