Unverified Commit a3f4cb15 authored by lufi42's avatar lufi42 Committed by GitHub
Browse files

Merge branch 'acmesh-official:dev' into dev

parents 2905edce b937665b
...@@ -121,19 +121,19 @@ jobs: ...@@ -121,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
...@@ -184,19 +184,19 @@ jobs: ...@@ -184,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
...@@ -234,19 +234,19 @@ jobs: ...@@ -234,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
...@@ -285,19 +285,19 @@ jobs: ...@@ -285,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
...@@ -337,19 +337,19 @@ jobs: ...@@ -337,19 +337,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
...@@ -389,19 +389,19 @@ jobs: ...@@ -389,19 +389,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
...@@ -445,19 +445,19 @@ jobs: ...@@ -445,19 +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 fi
cd ../acmetest cd ../acmetest
./letest.sh ./letest.sh
......
...@@ -61,7 +61,6 @@ jobs: ...@@ -61,7 +61,6 @@ jobs:
nat: | nat: |
"8080": "80" "8080": "80"
prepare: | prepare: |
export PKG_PATH="https://cdn.NetBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f '1 2' -d.)/All/"
pkg_add curl socat pkg_add curl socat
usesh: true usesh: true
copyback: false copyback: false
......
...@@ -80,9 +80,14 @@ jobs: ...@@ -80,9 +80,14 @@ jobs:
-p 9000:9000 \ -p 9000:9000 \
-e "DOCKER_STEPCA_INIT_NAME=Smallstep" \ -e "DOCKER_STEPCA_INIT_NAME=Smallstep" \
-e "DOCKER_STEPCA_INIT_DNS_NAMES=localhost,$(hostname -f)" \ -e "DOCKER_STEPCA_INIT_DNS_NAMES=localhost,$(hostname -f)" \
-e "DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT=true" \
-e "DOCKER_STEPCA_INIT_PASSWORD=test" \
--name stepca \ --name stepca \
smallstep/step-ca \ smallstep/step-ca:0.23.1
&& sleep 5 && docker exec stepca step ca provisioner add acme --type ACME \
sleep 5
docker exec stepca bash -c "echo test >test" \
&& docker exec stepca step ca provisioner add acme --type ACME --admin-subject step --admin-password-file=/home/step/test \
&& docker exec stepca kill -1 1 \ && docker exec stepca kill -1 1 \
&& docker exec stepca cat /home/step/certs/root_ca.crt | sudo bash -c "cat - >>/etc/ssl/certs/ca-certificates.crt" && docker exec stepca cat /home/step/certs/root_ca.crt | sudo bash -c "cat - >>/etc/ssl/certs/ca-certificates.crt"
- name: Clone acmetest - name: Clone acmetest
......
...@@ -28,9 +28,9 @@ jobs: ...@@ -28,9 +28,9 @@ jobs:
id: step_one id: step_one
run: | run: |
if [ "$DOCKER_PASSWORD" ] ; then if [ "$DOCKER_PASSWORD" ] ; then
echo "::set-output name=hasToken::true" echo "hasToken=true" >>$GITHUB_OUTPUT
else else
echo "::set-output name=hasToken::false" echo "hasToken=false" >>$GITHUB_OUTPUT
fi fi
- name: Check the value - name: Check the value
run: echo ${{ steps.step_one.outputs.hasToken }} run: echo ${{ steps.step_one.outputs.hasToken }}
...@@ -43,9 +43,9 @@ jobs: ...@@ -43,9 +43,9 @@ jobs:
- name: checkout code - name: checkout code
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- name: login to docker hub - name: login to docker hub
run: | run: |
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
......
FROM alpine:3.16.3 FROM alpine:3.17
RUN apk --no-cache add -f \ RUN apk --no-cache add -f \
openssl \ openssl \
...@@ -12,7 +12,8 @@ RUN apk --no-cache add -f \ ...@@ -12,7 +12,8 @@ RUN apk --no-cache add -f \
oath-toolkit-oathtool \ oath-toolkit-oathtool \
tar \ tar \
libidn \ libidn \
jq jq \
cronie
ENV LE_CONFIG_HOME /acme.sh ENV LE_CONFIG_HOME /acme.sh
...@@ -25,7 +26,7 @@ COPY ./ /install_acme.sh/ ...@@ -25,7 +26,7 @@ COPY ./ /install_acme.sh/
RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/ RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/
RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh && crontab -l | grep acme.sh | sed 's#> /dev/null##' | crontab - RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh && crontab -l | grep acme.sh | sed 's#> /dev/null#> /proc/1/fd/1 2>/proc/1/fd/2#' | crontab -
RUN for verb in help \ RUN for verb in help \
version \ version \
...@@ -64,12 +65,10 @@ RUN for verb in help \ ...@@ -64,12 +65,10 @@ RUN for verb in help \
RUN printf "%b" '#!'"/usr/bin/env sh\n \ RUN printf "%b" '#!'"/usr/bin/env sh\n \
if [ \"\$1\" = \"daemon\" ]; then \n \ if [ \"\$1\" = \"daemon\" ]; then \n \
trap \"echo stop && killall crond && exit 0\" SIGTERM SIGINT \n \ exec crond -n -s -m off \n \
crond && sleep infinity &\n \
wait \n \
else \n \ else \n \
exec -- \"\$@\"\n \ exec -- \"\$@\"\n \
fi" >/entry.sh && chmod +x /entry.sh fi\n" >/entry.sh && chmod +x /entry.sh
VOLUME /acme.sh VOLUME /acme.sh
......
...@@ -1637,7 +1637,7 @@ _stat() { ...@@ -1637,7 +1637,7 @@ _stat() {
#keyfile #keyfile
_isRSA() { _isRSA() {
keyfile=$1 keyfile=$1
if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || ${ACME_OPENSSL_BIN:-openssl} rsa -in "$keyfile" -noout -text | grep "^publicExponent:" >/dev/null 2>&1; then if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || ${ACME_OPENSSL_BIN:-openssl} rsa -in "$keyfile" -noout -text 2>&1 | grep "^publicExponent:" 2>&1 >/dev/null; then
return 0 return 0
fi fi
return 1 return 1
...@@ -1646,7 +1646,7 @@ _isRSA() { ...@@ -1646,7 +1646,7 @@ _isRSA() {
#keyfile #keyfile
_isEcc() { _isEcc() {
keyfile=$1 keyfile=$1
if grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || ${ACME_OPENSSL_BIN:-openssl} ec -in "$keyfile" -noout -text 2>/dev/null | grep "^NIST CURVE:" >/dev/null 2>&1; then if grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1 || ${ACME_OPENSSL_BIN:-openssl} ec -in "$keyfile" -noout -text 2>/dev/null | grep "^NIST CURVE:" 2>&1 >/dev/null; then
return 0 return 0
fi fi
return 1 return 1
...@@ -1744,7 +1744,7 @@ _calcjwk() { ...@@ -1744,7 +1744,7 @@ _calcjwk() {
_debug3 x64 "$x64" _debug3 x64 "$x64"
xend=$(_math "$xend" + 1) xend=$(_math "$xend" + 1)
y="$(printf "%s" "$pubtext" | cut -d : -f "$xend"-10000)" y="$(printf "%s" "$pubtext" | cut -d : -f "$xend"-2048)"
_debug3 y "$y" _debug3 y "$y"
y64="$(printf "%s" "$y" | tr -d : | _h2b | _base64 | _url_replace)" y64="$(printf "%s" "$y" | tr -d : | _h2b | _base64 | _url_replace)"
...@@ -1852,9 +1852,15 @@ _inithttp() { ...@@ -1852,9 +1852,15 @@ _inithttp() {
_ACME_CURL="$_ACME_CURL --cacert $CA_BUNDLE " _ACME_CURL="$_ACME_CURL --cacert $CA_BUNDLE "
fi fi
if _contains "$(curl --help 2>&1)" "--globoff"; then if _contains "$(curl --help 2>&1)" "--globoff" || _contains "$(curl --help curl 2>&1)" "--globoff"; then
_ACME_CURL="$_ACME_CURL -g " _ACME_CURL="$_ACME_CURL -g "
fi fi
#don't use --fail-with-body
##from curl 7.76: return fail on HTTP errors but keep the body
#if _contains "$(curl --help http 2>&1)" "--fail-with-body"; then
# _ACME_CURL="$_ACME_CURL --fail-with-body "
#fi
fi fi
if [ -z "$_ACME_WGET" ] && _exists "wget"; then if [ -z "$_ACME_WGET" ] && _exists "wget"; then
...@@ -1872,11 +1878,11 @@ _inithttp() { ...@@ -1872,11 +1878,11 @@ _inithttp() {
elif [ "$CA_BUNDLE" ]; then elif [ "$CA_BUNDLE" ]; then
_ACME_WGET="$_ACME_WGET --ca-certificate=$CA_BUNDLE " _ACME_WGET="$_ACME_WGET --ca-certificate=$CA_BUNDLE "
fi fi
fi
#from wget 1.14: do not skip body on 404 error #from wget 1.14: do not skip body on 404 error
if [ "$_ACME_WGET" ] && _contains "$($_ACME_WGET --help 2>&1)" "--content-on-error"; then if _contains "$(wget --help 2>&1)" "--content-on-error"; then
_ACME_WGET="$_ACME_WGET --content-on-error " _ACME_WGET="$_ACME_WGET --content-on-error "
fi
fi fi
__HTTP_INITIALIZED=1 __HTTP_INITIALIZED=1
...@@ -2058,7 +2064,7 @@ _get() { ...@@ -2058,7 +2064,7 @@ _get() {
fi fi
_debug "_WGET" "$_WGET" _debug "_WGET" "$_WGET"
if [ "$onlyheader" ]; then if [ "$onlyheader" ]; then
_wget_out = "$($_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O /dev/null "$url" 2>&1)" _wget_out="$($_WGET --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" -S -O /dev/null "$url" 2>&1)"
if _contains "$_WGET" " -d "; then if _contains "$_WGET" " -d "; then
# Demultiplex wget debug output # Demultiplex wget debug output
echo "$_wget_out" >&2 echo "$_wget_out" >&2
...@@ -2223,6 +2229,20 @@ _send_signed_request() { ...@@ -2223,6 +2229,20 @@ _send_signed_request() {
_debug3 _body "$_body" _debug3 _body "$_body"
fi fi
_retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *: *[0-9]\+ *" | cut -d : -f 2 | tr -d ' ' | tr -d '\r')
if [ "$code" = '503' ]; then
_sleep_overload_retry_sec=$_retryafter
if [ -z "$_sleep_overload_retry_sec" ]; then
_sleep_overload_retry_sec=5
fi
if [ $_sleep_overload_retry_sec -le 600 ]; then
_info "It seems the CA server is currently overloaded, let's wait and retry. Sleeping $_sleep_overload_retry_sec seconds."
_sleep $_sleep_overload_retry_sec
continue
else
_info "The retryafter=$_retryafter is too large > 600, not retry anymore."
fi
fi
if _contains "$_body" "JWS has invalid anti-replay nonce" || _contains "$_body" "JWS has an invalid anti-replay nonce"; then if _contains "$_body" "JWS has invalid anti-replay nonce" || _contains "$_body" "JWS has an invalid anti-replay nonce"; then
_info "It seems the CA server is busy now, let's wait and retry. Sleeping $_sleep_retry_sec seconds." _info "It seems the CA server is busy now, let's wait and retry. Sleeping $_sleep_retry_sec seconds."
_CACHED_NONCE="" _CACHED_NONCE=""
...@@ -2352,6 +2372,26 @@ _readdomainconf() { ...@@ -2352,6 +2372,26 @@ _readdomainconf() {
_read_conf "$DOMAIN_CONF" "$1" _read_conf "$DOMAIN_CONF" "$1"
} }
#_migratedomainconf oldkey newkey base64encode
_migratedomainconf() {
_old_key="$1"
_new_key="$2"
_b64encode="$3"
_value=$(_readdomainconf "$_old_key")
if [ -z "$_value" ]; then
return 1 # oldkey is not found
fi
_savedomainconf "$_new_key" "$_value" "$_b64encode"
_cleardomainconf "$_old_key"
_debug "Domain config $_old_key has been migrated to $_new_key"
}
#_migratedeployconf oldkey newkey base64encode
_migratedeployconf() {
_migratedomainconf "$1" "SAVED_$2" "$3" ||
_migratedomainconf "SAVED_$1" "SAVED_$2" "$3" # try only when oldkey itself is not found
}
#key value base64encode #key value base64encode
_savedeployconf() { _savedeployconf() {
_savedomainconf "SAVED_$1" "$2" "$3" _savedomainconf "SAVED_$1" "$2" "$3"
...@@ -2366,12 +2406,14 @@ _getdeployconf() { ...@@ -2366,12 +2406,14 @@ _getdeployconf() {
if [ "$_rac_value" ]; then if [ "$_rac_value" ]; then
if _startswith "$_rac_value" '"' && _endswith "$_rac_value" '"'; then if _startswith "$_rac_value" '"' && _endswith "$_rac_value" '"'; then
_debug2 "trim quotation marks" _debug2 "trim quotation marks"
eval "export $_rac_key=$_rac_value" eval $_rac_key=$_rac_value
export $_rac_key
fi fi
return 0 # do nothing return 0 # do nothing
fi fi
_saved=$(_readdomainconf "SAVED_$_rac_key") _saved="$(_readdomainconf "SAVED_$_rac_key")"
eval "export $_rac_key=\"\$_saved\"" eval $_rac_key=\$_saved
export $_rac_key
} }
#_saveaccountconf key value base64encode #_saveaccountconf key value base64encode
...@@ -2835,9 +2877,10 @@ _initpath() { ...@@ -2835,9 +2877,10 @@ _initpath() {
if _isEccKey "$_ilength"; then if _isEccKey "$_ilength"; then
DOMAIN_PATH="$domainhomeecc" DOMAIN_PATH="$domainhomeecc"
else elif [ -z "$__SELECTED_RSA_KEY" ]; then
if [ ! -d "$domainhome" ] && [ -d "$domainhomeecc" ]; then if [ ! -d "$domainhome" ] && [ -d "$domainhomeecc" ]; then
_info "The domain '$domain' seems to have a ECC cert already, please add '$(__red "--ecc")' parameter if you want to use that cert." _info "The domain '$domain' seems to have a ECC cert already, lets use ecc cert."
DOMAIN_PATH="$domainhomeecc"
fi fi
fi fi
_debug DOMAIN_PATH "$DOMAIN_PATH" _debug DOMAIN_PATH "$DOMAIN_PATH"
...@@ -3995,7 +4038,7 @@ _ns_purge_cf() { ...@@ -3995,7 +4038,7 @@ _ns_purge_cf() {
#checks if cf server is available #checks if cf server is available
_ns_is_available_cf() { _ns_is_available_cf() {
if _get "https://cloudflare-dns.com" "" 1 >/dev/null 2>&1; then if _get "https://cloudflare-dns.com" "" 10 >/dev/null; then
return 0 return 0
else else
return 1 return 1
...@@ -4003,7 +4046,7 @@ _ns_is_available_cf() { ...@@ -4003,7 +4046,7 @@ _ns_is_available_cf() {
} }
_ns_is_available_google() { _ns_is_available_google() {
if _get "https://dns.google" "" 1 >/dev/null 2>&1; then if _get "https://dns.google" "" 10 >/dev/null; then
return 0 return 0
else else
return 1 return 1
...@@ -4019,7 +4062,7 @@ _ns_lookup_google() { ...@@ -4019,7 +4062,7 @@ _ns_lookup_google() {
} }
_ns_is_available_ali() { _ns_is_available_ali() {
if _get "https://dns.alidns.com" "" 1 >/dev/null 2>&1; then if _get "https://dns.alidns.com" "" 10 >/dev/null; then
return 0 return 0
else else
return 1 return 1
...@@ -4035,7 +4078,7 @@ _ns_lookup_ali() { ...@@ -4035,7 +4078,7 @@ _ns_lookup_ali() {
} }
_ns_is_available_dp() { _ns_is_available_dp() {
if _get "https://doh.pub" "" 1 >/dev/null 2>&1; then if _get "https://doh.pub" "" 10 >/dev/null; then
return 0 return 0
else else
return 1 return 1
...@@ -5743,6 +5786,7 @@ deploy() { ...@@ -5743,6 +5786,7 @@ deploy() {
return 1 return 1
fi fi
_debug2 DOMAIN_CONF "$DOMAIN_CONF"
. "$DOMAIN_CONF" . "$DOMAIN_CONF"
_savedomainconf Le_DeployHook "$_hooks" _savedomainconf Le_DeployHook "$_hooks"
...@@ -6102,8 +6146,22 @@ revoke() { ...@@ -6102,8 +6146,22 @@ revoke() {
uri="${ACME_REVOKE_CERT}" uri="${ACME_REVOKE_CERT}"
_info "Try account key first."
if _send_signed_request "$uri" "$data" "" "$ACCOUNT_KEY_PATH"; then
if [ -z "$response" ]; then
_info "Revoke success."
rm -f "$CERT_PATH"
cat "$CERT_KEY_PATH" >"$CERT_KEY_PATH.revoked"
cat "$CSR_PATH" >"$CSR_PATH.revoked"
return 0
else
_err "Revoke error."
_debug "$response"
fi
fi
if [ -f "$CERT_KEY_PATH" ]; then if [ -f "$CERT_KEY_PATH" ]; then
_info "Try domain key first." _info "Try domain key."
if _send_signed_request "$uri" "$data" "" "$CERT_KEY_PATH"; then if _send_signed_request "$uri" "$data" "" "$CERT_KEY_PATH"; then
if [ -z "$response" ]; then if [ -z "$response" ]; then
_info "Revoke success." _info "Revoke success."
...@@ -6119,21 +6177,6 @@ revoke() { ...@@ -6119,21 +6177,6 @@ revoke() {
else else
_info "Domain key file doesn't exist." _info "Domain key file doesn't exist."
fi fi
_info "Try account key."
if _send_signed_request "$uri" "$data" "" "$ACCOUNT_KEY_PATH"; then
if [ -z "$response" ]; then
_info "Revoke success."
rm -f "$CERT_PATH"
cat "$CERT_KEY_PATH" >"$CERT_KEY_PATH.revoked"
cat "$CSR_PATH" >"$CSR_PATH.revoked"
return 0
else
_err "Revoke error."
_debug "$response"
fi
fi
return 1 return 1
} }
...@@ -6707,6 +6750,13 @@ _send_notify() { ...@@ -6707,6 +6750,13 @@ _send_notify() {
return 0 return 0
fi fi
_nsource="$NOTIFY_SOURCE"
if [ -z "$_nsource" ]; then
_nsource="$(hostname)"
fi
_nsubject="$_nsubject by $_nsource"
_send_err=0 _send_err=0
for _n_hook in $(echo "$_nhooks" | tr ',' " "); do for _n_hook in $(echo "$_nhooks" | tr ',' " "); do
_n_hook_file="$(_findHook "" $_SUB_FOLDER_NOTIFY "$_n_hook")" _n_hook_file="$(_findHook "" $_SUB_FOLDER_NOTIFY "$_n_hook")"
...@@ -6761,11 +6811,12 @@ setnotify() { ...@@ -6761,11 +6811,12 @@ setnotify() {
_nhook="$1" _nhook="$1"
_nlevel="$2" _nlevel="$2"
_nmode="$3" _nmode="$3"
_nsource="$4"
_initpath _initpath
if [ -z "$_nhook$_nlevel$_nmode" ]; then if [ -z "$_nhook$_nlevel$_nmode$_nsource" ]; then
_usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook <hookname>] [--notify-level <0|1|2|3>] [--notify-mode <0|1>]" _usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook <hookname>] [--notify-level <0|1|2|3>] [--notify-mode <0|1>] [--notify-source <hostname>]"
_usage "$_NOTIFY_WIKI" _usage "$_NOTIFY_WIKI"
return 1 return 1
fi fi
...@@ -6782,6 +6833,12 @@ setnotify() { ...@@ -6782,6 +6833,12 @@ setnotify() {
_saveaccountconf "NOTIFY_MODE" "$NOTIFY_MODE" _saveaccountconf "NOTIFY_MODE" "$NOTIFY_MODE"
fi fi
if [ "$_nsource" ]; then
_info "Set notify source to: $_nsource"
export "NOTIFY_SOURCE=$_nsource"
_saveaccountconf "NOTIFY_SOURCE" "$NOTIFY_SOURCE"
fi
if [ "$_nhook" ]; then if [ "$_nhook" ]; then
_info "Set notify hook to: $_nhook" _info "Set notify hook to: $_nhook"
if [ "$_nhook" = "$NO_VALUE" ]; then if [ "$_nhook" = "$NO_VALUE" ]; then
...@@ -6942,6 +6999,7 @@ Parameters: ...@@ -6942,6 +6999,7 @@ Parameters:
0: Bulk mode. Send all the domain's notifications in one message(mail). 0: Bulk mode. Send all the domain's notifications in one message(mail).
1: Cert mode. Send a message for every single cert. 1: Cert mode. Send a message for every single cert.
--notify-hook <hookname> Set the notify hook --notify-hook <hookname> Set the notify hook
--notify-source <server name> Set the server name in the notification message
--revoke-reason <0-10> The reason for revocation, can be used in conjunction with the '--revoke' command. --revoke-reason <0-10> The reason for revocation, can be used in conjunction with the '--revoke' command.
See: $_REVOKE_WIKI See: $_REVOKE_WIKI
...@@ -7099,7 +7157,9 @@ _selectServer() { ...@@ -7099,7 +7157,9 @@ _selectServer() {
_getCAShortName() { _getCAShortName() {
caurl="$1" caurl="$1"
if [ -z "$caurl" ]; then if [ -z "$caurl" ]; then
caurl="$DEFAULT_CA" #use letsencrypt as default value if the Le_API is empty
#this case can only come from the old upgrading.
caurl="$CA_LETSENCRYPT_V2"
fi fi
if [ "$CA_SSLCOM_ECC" = "$caurl" ]; then if [ "$CA_SSLCOM_ECC" = "$caurl" ]; then
caurl="$CA_SSLCOM_RSA" #just hack to get the short name caurl="$CA_SSLCOM_RSA" #just hack to get the short name
...@@ -7216,6 +7276,7 @@ _process() { ...@@ -7216,6 +7276,7 @@ _process() {
_notify_hook="" _notify_hook=""
_notify_level="" _notify_level=""
_notify_mode="" _notify_mode=""
_notify_source=""
_revoke_reason="" _revoke_reason=""
_eab_kid="" _eab_kid=""
_eab_hmac_key="" _eab_hmac_key=""
...@@ -7461,6 +7522,9 @@ _process() { ...@@ -7461,6 +7522,9 @@ _process() {
--keylength | -k) --keylength | -k)
_keylength="$2" _keylength="$2"
shift shift
if [ "$_keylength" ] && ! _isEccKey "$_keylength"; then
export __SELECTED_RSA_KEY=1
fi
;; ;;
-ak | --accountkeylength) -ak | --accountkeylength)
_accountkeylength="$2" _accountkeylength="$2"
...@@ -7496,7 +7560,7 @@ _process() { ...@@ -7496,7 +7560,7 @@ _process() {
shift shift
;; ;;
--home) --home)
export LE_WORKING_DIR="$2" export LE_WORKING_DIR="$(echo "$2" | sed 's|/$||')"
shift shift
;; ;;
--cert-home | --certhome) --cert-home | --certhome)
...@@ -7708,6 +7772,15 @@ _process() { ...@@ -7708,6 +7772,15 @@ _process() {
_notify_mode="$_nmode" _notify_mode="$_nmode"
shift shift
;; ;;
--notify-source)
_nsource="$2"
if _startswith "$_nsource" "-"; then
_err "'$_nsource' is not valid host name for '$1'"
return 1
fi
_notify_source="$_nsource"
shift
;;
--revoke-reason) --revoke-reason)
_revoke_reason="$2" _revoke_reason="$2"
if _startswith "$_revoke_reason" "-"; then if _startswith "$_revoke_reason" "-"; then
...@@ -7862,7 +7935,7 @@ _process() { ...@@ -7862,7 +7935,7 @@ _process() {
createCSR "$_domain" "$_altdomains" "$_ecc" createCSR "$_domain" "$_altdomains" "$_ecc"
;; ;;
setnotify) setnotify)
setnotify "$_notify_hook" "$_notify_level" "$_notify_mode" setnotify "$_notify_hook" "$_notify_level" "$_notify_mode" "$_notify_source"
;; ;;
setdefaultca) setdefaultca)
setdefaultca setdefaultca
......
...@@ -273,16 +273,27 @@ _check_curl_version() { ...@@ -273,16 +273,27 @@ _check_curl_version() {
_minor="$(_getfield "$_cversion" 2 '.')" _minor="$(_getfield "$_cversion" 2 '.')"
_debug2 "_minor" "$_minor" _debug2 "_minor" "$_minor"
if [ "$_major$_minor" -lt "740" ]; then if [ "$_major" -ge "8" ]; 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
} }
#!/usr/bin/env sh #!/usr/bin/env sh
# Here is the script to deploy the cert to G-Core CDN service (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/). # Here is the script to deploy the cert to G-Core CDN service (https://gcore.com/) using the G-Core Labs API (https://apidocs.gcore.com/cdn).
# Returns 0 when success. # Returns 0 when success.
# #
# Written by temoffey <temofffey@gmail.com> # Written by temoffey <temofffey@gmail.com>
# Public domain, 2019 # Public domain, 2019
# Update by DreamOfIce <admin@dreamofice.cn> in 2023
#export DEPLOY_GCORE_CDN_USERNAME=myusername #export DEPLOY_GCORE_CDN_USERNAME=myusername
#export DEPLOY_GCORE_CDN_PASSWORD=mypassword #export DEPLOY_GCORE_CDN_PASSWORD=mypassword
...@@ -56,7 +57,7 @@ gcore_cdn_deploy() { ...@@ -56,7 +57,7 @@ gcore_cdn_deploy() {
_request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}" _request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}"
_debug _request "$_request" _debug _request "$_request"
export _H1="Content-Type:application/json" export _H1="Content-Type:application/json"
_response=$(_post "$_request" "https://api.gcdn.co/auth/jwt/login") _response=$(_post "$_request" "https://api.gcore.com/auth/jwt/login")
_debug _response "$_response" _debug _response "$_response"
_regex=".*\"access\":\"\([-._0-9A-Za-z]*\)\".*$" _regex=".*\"access\":\"\([-._0-9A-Za-z]*\)\".*$"
_debug _regex "$_regex" _debug _regex "$_regex"
...@@ -69,8 +70,8 @@ gcore_cdn_deploy() { ...@@ -69,8 +70,8 @@ gcore_cdn_deploy() {
fi fi
_info "Find CDN resource with cname $_cdomain" _info "Find CDN resource with cname $_cdomain"
export _H2="Authorization:Token $_token" export _H2="Authorization:Bearer $_token"
_response=$(_get "https://api.gcdn.co/resources") _response=$(_get "https://api.gcore.com/cdn/resources")
_debug _response "$_response" _debug _response "$_response"
_regex="\"primary_resource\":null}," _regex="\"primary_resource\":null},"
_debug _regex "$_regex" _debug _regex "$_regex"
...@@ -102,7 +103,7 @@ gcore_cdn_deploy() { ...@@ -102,7 +103,7 @@ gcore_cdn_deploy() {
_date=$(date "+%d.%m.%Y %H:%M:%S") _date=$(date "+%d.%m.%Y %H:%M:%S")
_request="{\"name\":\"$_cdomain ($_date)\",\"sslCertificate\":\"$_fullchain\",\"sslPrivateKey\":\"$_key\"}" _request="{\"name\":\"$_cdomain ($_date)\",\"sslCertificate\":\"$_fullchain\",\"sslPrivateKey\":\"$_key\"}"
_debug _request "$_request" _debug _request "$_request"
_response=$(_post "$_request" "https://api.gcdn.co/sslData") _response=$(_post "$_request" "https://api.gcore.com/cdn/sslData")
_debug _response "$_response" _debug _response "$_response"
_regex=".*\"id\":\([0-9]*\).*$" _regex=".*\"id\":\([0-9]*\).*$"
_debug _regex "$_regex" _debug _regex "$_regex"
...@@ -117,7 +118,7 @@ gcore_cdn_deploy() { ...@@ -117,7 +118,7 @@ gcore_cdn_deploy() {
_info "Update CDN resource" _info "Update CDN resource"
_request="{\"originGroup\":$_originGroup,\"sslData\":$_sslDataAdd}" _request="{\"originGroup\":$_originGroup,\"sslData\":$_sslDataAdd}"
_debug _request "$_request" _debug _request "$_request"
_response=$(_post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT") _response=$(_post "$_request" "https://api.gcore.com/cdn/resources/$_resourceId" '' "PUT")
_debug _response "$_response" _debug _response "$_response"
_regex=".*\"sslData\":\([0-9]*\).*$" _regex=".*\"sslData\":\([0-9]*\).*$"
_debug _regex "$_regex" _debug _regex "$_regex"
...@@ -133,7 +134,7 @@ gcore_cdn_deploy() { ...@@ -133,7 +134,7 @@ gcore_cdn_deploy() {
_info "Not found old SSL certificate" _info "Not found old SSL certificate"
else else
_info "Delete old SSL certificate" _info "Delete old SSL certificate"
_response=$(_post '' "https://api.gcdn.co/sslData/$_sslDataOld" '' "DELETE") _response=$(_post '' "https://api.gcore.com/cdn/sslData/$_sslDataOld" '' "DELETE")
_debug _response "$_response" _debug _response "$_response"
fi fi
......
This diff is collapsed.
...@@ -184,6 +184,27 @@ truenas_deploy() { ...@@ -184,6 +184,27 @@ truenas_deploy() {
_info "S3 certificate is not configured or is not the same as TrueNAS web UI" _info "S3 certificate is not configured or is not the same as TrueNAS web UI"
fi fi
_info "Checking if any chart release Apps is using the same certificate as TrueNAS web UI. Tool 'jq' is required"
if _exists jq; then
_info "Query all chart release"
_release_list=$(_get "$_api_url/chart/release")
_related_name_list=$(printf "%s" "$_release_list" | jq -r "[.[] | {name,certId: .config.ingress?.main.tls[]?.scaleCert} | select(.certId==$_active_cert_id) | .name ] | unique")
_release_length=$(printf "%s" "$_related_name_list" | jq -r "length")
_info "Found $_release_length related chart release in list: $_related_name_list"
for i in $(seq 0 $((_release_length - 1))); do
_release_name=$(echo "$_related_name_list" | jq -r ".[$i]")
_info "Updating certificate from $_active_cert_id to $_cert_id for chart release: $_release_name"
#Read the chart release configuration
_chart_config=$(printf "%s" "$_release_list" | jq -r ".[] | select(.name==\"$_release_name\")")
#Replace the old certificate id with the new one in path .config.ingress.main.tls[].scaleCert. Then update .config.ingress
_updated_chart_config=$(printf "%s" "$_chart_config" | jq "(.config.ingress?.main.tls[]? | select(.scaleCert==$_active_cert_id) | .scaleCert ) |= $_cert_id | .config.ingress ")
_update_chart_result="$(_post "{\"values\" : { \"ingress\" : $_updated_chart_config } }" "$_api_url/chart/release/id/$_release_name" "" "PUT" "application/json")"
_debug3 _update_chart_result "$_update_chart_result"
done
else
_info "Tool 'jq' does not exists, skip chart release checking"
fi
_info "Deleting old certificate" _info "Deleting old certificate"
_delete_result="$(_post "" "$_api_url/certificate/id/$_active_cert_id" "" "DELETE" "application/json")" _delete_result="$(_post "" "$_api_url/certificate/id/$_active_cert_id" "" "DELETE" "application/json")"
......
...@@ -7,13 +7,16 @@ ...@@ -7,13 +7,16 @@
# #
# VAULT_PREFIX - this contains the prefix path in vault # VAULT_PREFIX - this contains the prefix path in vault
# VAULT_ADDR - vault requires this to find your vault server # VAULT_ADDR - vault requires this to find your vault server
# VAULT_SAVE_TOKEN - set to anything if you want to save the token
# VAULT_RENEW_TOKEN - set to anything if you want to renew the token to default TTL before deploying
# VAULT_KV_V2 - set to anything if you are using v2 of the kv engine
# #
# additionally, you need to ensure that VAULT_TOKEN is avialable # additionally, you need to ensure that VAULT_TOKEN is avialable
# to access the vault server # to access the vault server
#returns 0 means success, otherwise error. #returns 0 means success, otherwise error.
######## Public functions ##################### ######## Public functions #####################
#domain keyfile certfile cafile fullchain #domain keyfile certfile cafile fullchain
vault_deploy() { vault_deploy() {
...@@ -45,6 +48,26 @@ vault_deploy() { ...@@ -45,6 +48,26 @@ vault_deploy() {
fi fi
_savedeployconf VAULT_ADDR "$VAULT_ADDR" _savedeployconf VAULT_ADDR "$VAULT_ADDR"
_getdeployconf VAULT_SAVE_TOKEN
_savedeployconf VAULT_SAVE_TOKEN "$VAULT_SAVE_TOKEN"
_getdeployconf VAULT_RENEW_TOKEN
_savedeployconf VAULT_RENEW_TOKEN "$VAULT_RENEW_TOKEN"
_getdeployconf VAULT_KV_V2
_savedeployconf VAULT_KV_V2 "$VAULT_KV_V2"
_getdeployconf VAULT_TOKEN
if [ -z "$VAULT_TOKEN" ]; then
_err "VAULT_TOKEN needs to be defined"
return 1
fi
if [ -n "$VAULT_SAVE_TOKEN" ]; then
_savedeployconf VAULT_TOKEN "$VAULT_TOKEN"
fi
_migratedeployconf FABIO VAULT_FABIO_MODE
# JSON does not allow multiline strings. # JSON does not allow multiline strings.
# So replacing new-lines with "\n" here # So replacing new-lines with "\n" here
_ckey=$(sed -z 's/\n/\\n/g' <"$2") _ckey=$(sed -z 's/\n/\\n/g' <"$2")
...@@ -52,26 +75,56 @@ vault_deploy() { ...@@ -52,26 +75,56 @@ vault_deploy() {
_cca=$(sed -z 's/\n/\\n/g' <"$4") _cca=$(sed -z 's/\n/\\n/g' <"$4")
_cfullchain=$(sed -z 's/\n/\\n/g' <"$5") _cfullchain=$(sed -z 's/\n/\\n/g' <"$5")
URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain"
export _H1="X-Vault-Token: $VAULT_TOKEN" export _H1="X-Vault-Token: $VAULT_TOKEN"
if [ -n "$FABIO" ]; then if [ -n "$VAULT_RENEW_TOKEN" ]; then
URL="$VAULT_ADDR/v1/auth/token/renew-self"
_info "Renew the Vault token to default TTL"
if ! _post "" "$URL" >/dev/null; then
_err "Failed to renew the Vault token"
return 1
fi
fi
URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain"
if [ -n "$VAULT_FABIO_MODE" ]; then
_info "Writing certificate and key to $URL in Fabio mode"
if [ -n "$VAULT_KV_V2" ]; then if [ -n "$VAULT_KV_V2" ]; then
_post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL" _post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL" >/dev/null || return 1
else else
_post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" _post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" >/dev/null || return 1
fi fi
else else
if [ -n "$VAULT_KV_V2" ]; then if [ -n "$VAULT_KV_V2" ]; then
_post "{\"data\": {\"value\": \"$_ccert\"}}" "$URL/cert.pem" _info "Writing certificate to $URL/cert.pem"
_post "{\"data\": {\"value\": \"$_ckey\"}}" "$URL/cert.key" _post "{\"data\": {\"value\": \"$_ccert\"}}" "$URL/cert.pem" >/dev/null || return 1
_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/chain.pem" _info "Writing key to $URL/cert.key"
_post "{\"data\": {\"value\": \"$_cfullchain\"}}" "$URL/fullchain.pem" _post "{\"data\": {\"value\": \"$_ckey\"}}" "$URL/cert.key" >/dev/null || return 1
_info "Writing CA certificate to $URL/ca.pem"
_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/ca.pem" >/dev/null || return 1
_info "Writing full-chain certificate to $URL/fullchain.pem"
_post "{\"data\": {\"value\": \"$_cfullchain\"}}" "$URL/fullchain.pem" >/dev/null || return 1
else else
_post "{\"value\": \"$_ccert\"}" "$URL/cert.pem" _info "Writing certificate to $URL/cert.pem"
_post "{\"value\": \"$_ckey\"}" "$URL/cert.key" _post "{\"value\": \"$_ccert\"}" "$URL/cert.pem" >/dev/null || return 1
_post "{\"value\": \"$_cca\"}" "$URL/chain.pem" _info "Writing key to $URL/cert.key"
_post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" _post "{\"value\": \"$_ckey\"}" "$URL/cert.key" >/dev/null || return 1
_info "Writing CA certificate to $URL/ca.pem"
_post "{\"value\": \"$_cca\"}" "$URL/ca.pem" >/dev/null || return 1
_info "Writing full-chain certificate to $URL/fullchain.pem"
_post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" >/dev/null || return 1
fi
# To make it compatible with the wrong ca path `chain.pem` which was used in former versions
if _contains "$(_get "$URL/chain.pem")" "-----BEGIN CERTIFICATE-----"; then
_err "The CA certificate has moved from chain.pem to ca.pem, if you don't depend on chain.pem anymore, you can delete it to avoid this warning"
_info "Updating CA certificate to $URL/chain.pem for backward compatibility"
if [ -n "$VAULT_KV_V2" ]; then
_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/chain.pem" >/dev/null || return 1
else
_post "{\"value\": \"$_cca\"}" "$URL/chain.pem" >/dev/null || return 1
fi
fi fi
fi fi
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
# #
# VAULT_PREFIX - this contains the prefix path in vault # VAULT_PREFIX - this contains the prefix path in vault
# VAULT_ADDR - vault requires this to find your vault server # VAULT_ADDR - vault requires this to find your vault server
# VAULT_SAVE_TOKEN - set to anything if you want to save the token
# VAULT_RENEW_TOKEN - set to anything if you want to renew the token to default TTL before deploying
# #
# additionally, you need to ensure that VAULT_TOKEN is avialable or # additionally, you need to ensure that VAULT_TOKEN is avialable or
# `vault auth` has applied the appropriate authorization for the vault binary # `vault auth` has applied the appropriate authorization for the vault binary
...@@ -33,15 +35,36 @@ vault_cli_deploy() { ...@@ -33,15 +35,36 @@ vault_cli_deploy() {
_debug _cfullchain "$_cfullchain" _debug _cfullchain "$_cfullchain"
# validate required env vars # validate required env vars
_getdeployconf VAULT_PREFIX
if [ -z "$VAULT_PREFIX" ]; then if [ -z "$VAULT_PREFIX" ]; then
_err "VAULT_PREFIX needs to be defined (contains prefix path in vault)" _err "VAULT_PREFIX needs to be defined (contains prefix path in vault)"
return 1 return 1
fi fi
_savedeployconf VAULT_PREFIX "$VAULT_PREFIX"
_getdeployconf VAULT_ADDR
if [ -z "$VAULT_ADDR" ]; then if [ -z "$VAULT_ADDR" ]; then
_err "VAULT_ADDR needs to be defined (contains vault connection address)" _err "VAULT_ADDR needs to be defined (contains vault connection address)"
return 1 return 1
fi fi
_savedeployconf VAULT_ADDR "$VAULT_ADDR"
_getdeployconf VAULT_SAVE_TOKEN
_savedeployconf VAULT_SAVE_TOKEN "$VAULT_SAVE_TOKEN"
_getdeployconf VAULT_RENEW_TOKEN
_savedeployconf VAULT_RENEW_TOKEN "$VAULT_RENEW_TOKEN"
_getdeployconf VAULT_TOKEN
if [ -z "$VAULT_TOKEN" ]; then
_err "VAULT_TOKEN needs to be defined"
return 1
fi
if [ -n "$VAULT_SAVE_TOKEN" ]; then
_savedeployconf VAULT_TOKEN "$VAULT_TOKEN"
fi
_migratedeployconf FABIO VAULT_FABIO_MODE
VAULT_CMD=$(command -v vault) VAULT_CMD=$(command -v vault)
if [ ! $? ]; then if [ ! $? ]; then
...@@ -49,13 +72,33 @@ vault_cli_deploy() { ...@@ -49,13 +72,33 @@ vault_cli_deploy() {
return 1 return 1
fi fi
if [ -n "$FABIO" ]; then if [ -n "$VAULT_RENEW_TOKEN" ]; then
_info "Renew the Vault token to default TTL"
if ! $VAULT_CMD token renew; then
_err "Failed to renew the Vault token"
return 1
fi
fi
if [ -n "$VAULT_FABIO_MODE" ]; then
_info "Writing certificate and key to ${VAULT_PREFIX}/${_cdomain} in Fabio mode"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1 $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1
else else
_info "Writing certificate to ${VAULT_PREFIX}/${_cdomain}/cert.pem"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1 $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1
_info "Writing key to ${VAULT_PREFIX}/${_cdomain}/cert.key"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1 $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1 _info "Writing CA certificate to ${VAULT_PREFIX}/${_cdomain}/ca.pem"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/ca.pem" value=@"$_cca" || return 1
_info "Writing full-chain certificate to ${VAULT_PREFIX}/${_cdomain}/fullchain.pem"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1 $VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1
# To make it compatible with the wrong ca path `chain.pem` which was used in former versions
if $VAULT_CMD kv get "${VAULT_PREFIX}/${_cdomain}/chain.pem" >/dev/null; then
_err "The CA certificate has moved from chain.pem to ca.pem, if you don't depend on chain.pem anymore, you can delete it to avoid this warning"
_info "Updating CA certificate to ${VAULT_PREFIX}/${_cdomain}/chain.pem for backward compatibility"
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1
fi
fi fi
} }
#!/usr/bin/env sh #!/usr/bin/env sh
#Arvan_Token="Apikey xxxx" # Arvan_Token="Apikey xxxx"
ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" ARVAN_API_URL="https://napi.arvancloud.ir/cdn/4.0/domains"
#Author: Vahid Fardi # Author: Vahid Fardi
#Report Bugs here: https://github.com/Neilpang/acme.sh # Report Bugs here: https://github.com/Neilpang/acme.sh
# #
######## Public functions ##################### ######## Public functions #####################
...@@ -18,7 +18,7 @@ dns_arvan_add() { ...@@ -18,7 +18,7 @@ dns_arvan_add() {
if [ -z "$Arvan_Token" ]; then if [ -z "$Arvan_Token" ]; then
_err "You didn't specify \"Arvan_Token\" token yet." _err "You didn't specify \"Arvan_Token\" token yet."
_err "You can get yours from here https://npanel.arvancloud.com/profile/api-keys" _err "You can get yours from here https://npanel.arvancloud.ir/profile/api-keys"
return 1 return 1
fi fi
#save the api token to the account conf file. #save the api token to the account conf file.
...@@ -40,7 +40,7 @@ dns_arvan_add() { ...@@ -40,7 +40,7 @@ dns_arvan_add() {
_info "response id is $response" _info "response id is $response"
_info "Added, OK" _info "Added, OK"
return 0 return 0
elif _contains "$response" "Record Data is Duplicated"; then elif _contains "$response" "Record Data is duplicate"; then
_info "Already exists, OK" _info "Already exists, OK"
return 0 return 0
else else
...@@ -141,6 +141,7 @@ _arvan_rest() { ...@@ -141,6 +141,7 @@ _arvan_rest() {
response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")"
elif [ "$mtd" = "POST" ]; then elif [ "$mtd" = "POST" ]; then
export _H2="Content-Type: application/json" export _H2="Content-Type: application/json"
export _H3="Accept: application/json"
_debug data "$data" _debug data "$data"
response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")"
else else
......
...@@ -78,7 +78,7 @@ dns_cloudns_rm() { ...@@ -78,7 +78,7 @@ dns_cloudns_rm() {
return 1 return 1
fi fi
for i in $(echo "$response" | tr '{' "\n" | grep "$record"); do for i in $(echo "$response" | tr '{' "\n" | grep -- "$record"); do
record_id=$(echo "$i" | tr ',' "\n" | grep -E '^"id"' | sed -re 's/^\"id\"\:\"([0-9]+)\"$/\1/g') record_id=$(echo "$i" | tr ',' "\n" | grep -E '^"id"' | sed -re 's/^\"id\"\:\"([0-9]+)\"$/\1/g')
if [ -n "$record_id" ]; then if [ -n "$record_id" ]; then
......
#!/usr/bin/env sh
#
#GCORE_Key='773$7b7adaf2a2b32bfb1b83787b4ff32a67eb178e3ada1af733e47b1411f2461f7f4fa7ed7138e2772a46124377bad7384b3bb8d87748f87b3f23db4b8bbe41b2bb'
#
GCORE_Api="https://api.gcorelabs.com/dns/v2"
GCORE_Doc="https://apidocs.gcore.com/dns"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_gcore_add() {
fulldomain=$1
txtvalue=$2
GCORE_Key="${GCORE_Key:-$(_readaccountconf_mutable GCORE_Key)}"
if [ -z "$GCORE_Key" ]; then
GCORE_Key=""
_err "You didn't specify a Gcore api key yet."
_err "You can get yours from here $GCORE_Doc"
return 1
fi
#save the api key to the account conf file.
_saveaccountconf_mutable GCORE_Key "$GCORE_Key"
_debug "First detect the zone name"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _zone_name "$_zone_name"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_gcore_rest GET "zones/$_zone_name/$fulldomain/TXT"
payload=""
if echo "$response" | grep "record is not found" >/dev/null; then
_info "Record doesn't exists"
payload="{\"resource_records\":[{\"content\":[\"$txtvalue\"],\"enabled\":true}],\"ttl\":120}"
elif echo "$response" | grep "$txtvalue" >/dev/null; then
_info "Already exists, OK"
return 0
elif echo "$response" | tr -d " " | grep \"name\":\""$fulldomain"\",\"type\":\"TXT\" >/dev/null; then
_info "Record with mismatch txtvalue, try update it"
payload=$(echo "$response" | tr -d " " | sed 's/"updated_at":[0-9]\+,//g' | sed 's/"meta":{}}]}/"meta":{}},{"content":['\""$txtvalue"\"'],"enabled":true}]}/')
fi
# For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so
# we can not use updating anymore.
# count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2)
# _debug count "$count"
# if [ "$count" = "0" ]; then
_info "Adding record"
if _gcore_rest PUT "zones/$_zone_name/$fulldomain/TXT" "$payload"; then
if _contains "$response" "$txtvalue"; then
_info "Added, OK"
return 0
elif _contains "$response" "rrset is already exists"; then
_info "Already exists, OK"
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
return 1
}
#fulldomain txtvalue
dns_gcore_rm() {
fulldomain=$1
txtvalue=$2
GCORE_Key="${GCORE_Key:-$(_readaccountconf_mutable GCORE_Key)}"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _zone_name "$_zone_name"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_gcore_rest GET "zones/$_zone_name/$fulldomain/TXT"
if echo "$response" | grep "record is not found" >/dev/null; then
_info "No such txt recrod"
return 0
fi
if ! echo "$response" | tr -d " " | grep \"name\":\""$fulldomain"\",\"type\":\"TXT\" >/dev/null; then
_err "Error: $response"
return 1
fi
if ! echo "$response" | tr -d " " | grep \""$txtvalue"\" >/dev/null; then
_info "No such txt recrod"
return 0
fi
count="$(echo "$response" | grep -o "content" | wc -l)"
if [ "$count" = "1" ]; then
if ! _gcore_rest DELETE "zones/$_zone_name/$fulldomain/TXT"; then
_err "Delete record error. $response"
return 1
fi
return 0
fi
payload="$(echo "$response" | tr -d " " | sed 's/"updated_at":[0-9]\+,//g' | sed 's/{"id":[0-9]\+,"content":\["'"$txtvalue"'"\],"enabled":true,"meta":{}}//' | sed 's/\[,/\[/' | sed 's/,,/,/' | sed 's/,\]/\]/')"
if ! _gcore_rest PUT "zones/$_zone_name/$fulldomain/TXT" "$payload"; then
_err "Delete record error. $response"
fi
}
#################### Private functions below ##################################
#_acme-challenge.sub.domain.com
#returns
# _sub_domain=_acme-challenge.sub or _acme-challenge
# _domain=domain.com
# _zone_name=domain.com or sub.domain.com
_get_root() {
domain=$1
i=1
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
if ! _gcore_rest GET "zones/$h"; then
return 1
fi
if _contains "$response" "\"name\":\"$h\""; then
_zone_name=$h
if [ "$_zone_name" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
return 1
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_gcore_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
key_trimmed=$(echo "$GCORE_Key" | tr -d '"')
export _H1="Content-Type: application/json"
export _H2="Authorization: APIKey $key_trimmed"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$GCORE_Api/$ep" "" "$m")"
else
response="$(_get "$GCORE_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}
...@@ -22,8 +22,8 @@ dns_gd_add() { ...@@ -22,8 +22,8 @@ dns_gd_add() {
if [ -z "$GD_Key" ] || [ -z "$GD_Secret" ]; then if [ -z "$GD_Key" ] || [ -z "$GD_Secret" ]; then
GD_Key="" GD_Key=""
GD_Secret="" GD_Secret=""
_err "You don't specify godaddy api key and secret yet." _err "You didn't specify godaddy api key and secret yet."
_err "Please create you key and try again." _err "Please create your key and try again."
return 1 return 1
fi fi
...@@ -46,7 +46,7 @@ dns_gd_add() { ...@@ -46,7 +46,7 @@ dns_gd_add() {
fi fi
if _contains "$response" "$txtvalue"; then if _contains "$response" "$txtvalue"; then
_info "The record is existing, skip" _info "This record already exists, skipping"
return 0 return 0
fi fi
......
#!/usr/bin/env sh
# Author: Alex Leigh <leigh at alexleigh dot me>
# Created: 2023-03-02
#GOOGLEDOMAINS_ACCESS_TOKEN="xxxx"
#GOOGLEDOMAINS_ZONE="xxxx"
GOOGLEDOMAINS_API="https://acmedns.googleapis.com/v1/acmeChallengeSets"
######## Public functions ########
#Usage: dns_googledomains_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_googledomains_add() {
fulldomain=$1
txtvalue=$2
_info "Invoking Google Domains ACME DNS API."
if ! _dns_googledomains_setup; then
return 1
fi
zone="$(_dns_googledomains_get_zone "$fulldomain")"
if [ -z "$zone" ]; then
_err "Could not find a Google Domains-managed zone containing the requested domain."
return 1
fi
_debug zone "$zone"
_debug txtvalue "$txtvalue"
_info "Adding TXT record for $fulldomain."
if _dns_googledomains_api "$zone" ":rotateChallenges" "{\"accessToken\":\"$GOOGLEDOMAINS_ACCESS_TOKEN\",\"recordsToAdd\":[{\"fqdn\":\"$fulldomain\",\"digest\":\"$txtvalue\"}],\"keepExpiredRecords\":true}"; then
if _contains "$response" "$txtvalue"; then
_info "TXT record added."
return 0
else
_err "Error adding TXT record."
return 1
fi
fi
_err "Error adding TXT record."
return 1
}
#Usage: dns_googledomains_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_googledomains_rm() {
fulldomain=$1
txtvalue=$2
_info "Invoking Google Domains ACME DNS API."
if ! _dns_googledomains_setup; then
return 1
fi
zone="$(_dns_googledomains_get_zone "$fulldomain")"
if [ -z "$zone" ]; then
_err "Could not find a Google Domains-managed domain based on request."
return 1
fi
_debug zone "$zone"
_debug txtvalue "$txtvalue"
_info "Removing TXT record for $fulldomain."
if _dns_googledomains_api "$zone" ":rotateChallenges" "{\"accessToken\":\"$GOOGLEDOMAINS_ACCESS_TOKEN\",\"recordsToRemove\":[{\"fqdn\":\"$fulldomain\",\"digest\":\"$txtvalue\"}],\"keepExpiredRecords\":true}"; then
if _contains "$response" "$txtvalue"; then
_err "Error removing TXT record."
return 1
else
_info "TXT record removed."
return 0
fi
fi
_err "Error removing TXT record."
return 1
}
######## Private functions ########
_dns_googledomains_setup() {
if [ -n "$GOOGLEDOMAINS_SETUP_COMPLETED" ]; then
return 0
fi
GOOGLEDOMAINS_ACCESS_TOKEN="${GOOGLEDOMAINS_ACCESS_TOKEN:-$(_readaccountconf_mutable GOOGLEDOMAINS_ACCESS_TOKEN)}"
GOOGLEDOMAINS_ZONE="${GOOGLEDOMAINS_ZONE:-$(_readaccountconf_mutable GOOGLEDOMAINS_ZONE)}"
if [ -z "$GOOGLEDOMAINS_ACCESS_TOKEN" ]; then
GOOGLEDOMAINS_ACCESS_TOKEN=""
_err "Google Domains access token was not specified."
_err "Please visit Google Domains Security settings to provision an ACME DNS API access token."
return 1
fi
if [ "$GOOGLEDOMAINS_ZONE" ]; then
_savedomainconf GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN"
_savedomainconf GOOGLEDOMAINS_ZONE "$GOOGLEDOMAINS_ZONE"
else
_saveaccountconf_mutable GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN"
_clearaccountconf_mutable GOOGLEDOMAINS_ZONE
_clearaccountconf GOOGLEDOMAINS_ZONE
fi
_debug GOOGLEDOMAINS_ACCESS_TOKEN "$GOOGLEDOMAINS_ACCESS_TOKEN"
_debug GOOGLEDOMAINS_ZONE "$GOOGLEDOMAINS_ZONE"
GOOGLEDOMAINS_SETUP_COMPLETED=1
return 0
}
_dns_googledomains_get_zone() {
domain=$1
# Use zone directly if provided
if [ "$GOOGLEDOMAINS_ZONE" ]; then
if ! _dns_googledomains_api "$GOOGLEDOMAINS_ZONE"; then
return 1
fi
echo "$GOOGLEDOMAINS_ZONE"
return 0
fi
i=2
while true; do
curr=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug curr "$curr"
if [ -z "$curr" ]; then
return 1
fi
if _dns_googledomains_api "$curr"; then
echo "$curr"
return 0
fi
i=$(_math "$i" + 1)
done
return 1
}
_dns_googledomains_api() {
zone=$1
apimethod=$2
data="$3"
if [ -z "$data" ]; then
response="$(_get "$GOOGLEDOMAINS_API/$zone$apimethod")"
else
_debug data "$data"
export _H1="Content-Type: application/json"
response="$(_post "$data" "$GOOGLEDOMAINS_API/$zone$apimethod")"
fi
_debug response "$response"
if [ "$?" != "0" ]; then
_err "Error"
return 1
fi
if _contains "$response" "\"error\": {"; then
return 1
fi
return 0
}
...@@ -23,7 +23,7 @@ dns_huaweicloud_add() { ...@@ -23,7 +23,7 @@ dns_huaweicloud_add() {
HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_DomainName)}"
# Check information # Check information
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
...@@ -74,7 +74,7 @@ dns_huaweicloud_rm() { ...@@ -74,7 +74,7 @@ dns_huaweicloud_rm() {
HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_DomainName)}"
# Check information # Check information
if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
...@@ -98,19 +98,59 @@ dns_huaweicloud_rm() { ...@@ -98,19 +98,59 @@ dns_huaweicloud_rm() {
fi fi
_debug "Zone ID is:" "${zoneid}" _debug "Zone ID is:" "${zoneid}"
record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")"
_recursive_rm_record "${token}" "${fulldomain}" "${zoneid}" "${record_id}"
ret="$?"
if [ "${ret}" != "0" ]; then
_err "dns_api(dns_huaweicloud): Error removing record."
return 1
fi
return 0
}
################### 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 # Remove all records
# Therotically HuaweiCloud does not allow more than one record set # Therotically HuaweiCloud does not allow more than one record set
# But remove them recurringly to increase robusty # But remove them recurringly to increase robusty
while [ "${record_id}" != "0" ]; do
while [ "${_record_id}" != "0" ] && [ "${_retry_cnt}" != "0" ]; do
_debug "Removing Record" _debug "Removing Record"
_rm_record "${token}" "${zoneid}" "${record_id}" _retry_cnt=$((_retry_cnt - 1))
record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" _rm_record "${_token}" "${_zoneid}" "${_record_id}"
_record_id="$(_get_recordset_id "${_token}" "${_domain}" "${_zoneid}")"
_debug2 "Checking record exists: record_id=${_record_id}"
done 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 return 0
} }
################### Private functions below ##################################
# _get_zoneid # _get_zoneid
# #
# _token=$1 # _token=$1
...@@ -124,7 +164,7 @@ _get_zoneid() { ...@@ -124,7 +164,7 @@ _get_zoneid() {
i=1 i=1
while true; do while true; do
h=$(printf "%s" "${_domain_string}" | cut -d . -f $i-100) h=$(printf "%s" "${_domain_string}" | cut -d . -f "$i"-100)
if [ -z "$h" ]; then if [ -z "$h" ]; then
#not valid #not valid
return 1 return 1
...@@ -135,11 +175,11 @@ _get_zoneid() { ...@@ -135,11 +175,11 @@ _get_zoneid() {
if _contains "${response}" '"id"'; then if _contains "${response}" '"id"'; then
zoneidlist=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ") zoneidlist=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
zonenamelist=$(echo "${response}" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ") zonenamelist=$(echo "${response}" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
_debug2 "Return Zone ID(s):" "${zoneidlist}" _debug2 "Returned Zone ID(s):" "${zoneidlist}"
_debug2 "Return Zone Name(s):" "${zonenamelist}" _debug2 "Returned Zone Name(s):" "${zonenamelist}"
zoneidnum=0 zoneidnum=0
zoneidcount=$(echo "${zoneidlist}" | grep -c '^') zoneidcount=$(echo "${zoneidlist}" | grep -c '^')
_debug "Retund Zone ID(s) Count:" "${zoneidcount}" _debug "Returned Zone ID(s) Count:" "${zoneidcount}"
while [ "${zoneidnum}" -lt "${zoneidcount}" ]; do while [ "${zoneidnum}" -lt "${zoneidcount}" ]; do
zoneidnum=$(_math "$zoneidnum" + 1) zoneidnum=$(_math "$zoneidnum" + 1)
_zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p") _zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p")
...@@ -206,8 +246,7 @@ _add_record() { ...@@ -206,8 +246,7 @@ _add_record() {
\"type\": \"TXT\", \"type\": \"TXT\",
\"ttl\": 1, \"ttl\": 1,
\"records\": [ \"records\": [
${_exist_record}, ${_exist_record},\"\\\"${_txtvalue}\\\"\"
\"\\\"${_txtvalue}\\\"\"
] ]
}" }"
fi fi
...@@ -215,19 +254,16 @@ _add_record() { ...@@ -215,19 +254,16 @@ _add_record() {
_record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")" _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")"
_debug "Record Set ID is:" "${_record_id}" _debug "Record Set ID is:" "${_record_id}"
# Remove all records
while [ "${_record_id}" != "0" ]; do
_debug "Removing Record"
_rm_record "${_token}" "${zoneid}" "${_record_id}"
_record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")"
done
# Add brand new records with all old and new records # Add brand new records with all old and new records
export _H2="Content-Type: application/json" export _H2="Content-Type: application/json"
export _H1="X-Auth-Token: ${_token}" export _H1="X-Auth-Token: ${_token}"
_debug2 "${_post_body}" _debug2 "${_post_body}"
_post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null if [ -z "${_exist_record}" ]; then
_post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null
else
_post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets/${_record_id}" false "PUT" >/dev/null
fi
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
if [ "$_code" != "202" ]; then if [ "$_code" != "202" ]; then
_err "dns_huaweicloud: http code ${_code}" _err "dns_huaweicloud: http code ${_code}"
......
#!/usr/bin/env sh
#Created by Roman Lumetsberger, to use ipv64.net's API to add/remove text records
#2022/11/29
# Pass credentials before "acme.sh --issue --dns dns_ipv64 ..."
# --
# export IPv64_Token="aaaaaaaaaaaaaaaaaaaaaaaaaa"
# --
#
IPv64_API="https://ipv64.net/api"
######## Public functions ######################
#Usage: dns_ipv64_add _acme-challenge.domain.ipv64.net "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_ipv64_add() {
fulldomain=$1
txtvalue=$2
IPv64_Token="${IPv64_Token:-$(_readaccountconf_mutable IPv64_Token)}"
if [ -z "$IPv64_Token" ]; then
_err "You must export variable: IPv64_Token"
_err "The API Key for your IPv64 account is necessary."
_err "You can look it up in your IPv64 account."
return 1
fi
# Now save the credentials.
_saveaccountconf_mutable IPv64_Token "$IPv64_Token"
if ! _get_root "$fulldomain"; then
_err "invalid domain" "$fulldomain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
# convert to lower case
_domain="$(echo "$_domain" | _lower_case)"
_sub_domain="$(echo "$_sub_domain" | _lower_case)"
# Now add the TXT record
_info "Trying to add TXT record"
if _ipv64_rest "POST" "add_record=$_domain&praefix=$_sub_domain&type=TXT&content=$txtvalue"; then
_info "TXT record has been successfully added."
return 0
else
_err "Errors happened during adding the TXT record, response=$_response"
return 1
fi
}
#Usage: fulldomain txtvalue
#Usage: dns_ipv64_rm _acme-challenge.domain.ipv64.net "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
#Remove the txt record after validation.
dns_ipv64_rm() {
fulldomain=$1
txtvalue=$2
IPv64_Token="${IPv64_Token:-$(_readaccountconf_mutable IPv64_Token)}"
if [ -z "$IPv64_Token" ]; then
_err "You must export variable: IPv64_Token"
_err "The API Key for your IPv64 account is necessary."
_err "You can look it up in your IPv64 account."
return 1
fi
if ! _get_root "$fulldomain"; then
_err "invalid domain" "$fulldomain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
# convert to lower case
_domain="$(echo "$_domain" | _lower_case)"
_sub_domain="$(echo "$_sub_domain" | _lower_case)"
# Now delete the TXT record
_info "Trying to delete TXT record"
if _ipv64_rest "DELETE" "del_record=$_domain&praefix=$_sub_domain&type=TXT&content=$txtvalue"; then
_info "TXT record has been successfully deleted."
return 0
else
_err "Errors happened during deleting the TXT record, response=$_response"
return 1
fi
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain="$1"
i=1
p=1
_ipv64_get "get_domains"
domain_data=$_response
while true; do
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
if [ -z "$h" ]; then
#not valid
return 1
fi
#if _contains "$domain_data" "\""$h"\"\:"; then
if _contains "$domain_data" "\"""$h""\"\:"; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_domain="$h"
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
#send get request to api
# $1 has to set the api-function
_ipv64_get() {
url="$IPv64_API?$1"
export _H1="Authorization: Bearer $IPv64_Token"
_response=$(_get "$url")
_response="$(echo "$_response" | _normalizeJson)"
if _contains "$_response" "429 Too Many Requests"; then
_info "API throttled, sleeping to reset the limit"
_sleep 10
_response=$(_get "$url")
_response="$(echo "$_response" | _normalizeJson)"
fi
}
_ipv64_rest() {
url="$IPv64_API"
export _H1="Authorization: Bearer $IPv64_Token"
export _H2="Content-Type: application/x-www-form-urlencoded"
_response=$(_post "$2" "$url" "" "$1")
if _contains "$_response" "429 Too Many Requests"; then
_info "API throttled, sleeping to reset the limit"
_sleep 10
_response=$(_post "$2" "$url" "" "$1")
fi
if ! _contains "$_response" "\"info\":\"success\""; then
return 1
fi
_debug2 response "$_response"
return 0
}
...@@ -215,7 +215,7 @@ _get_record_id() { ...@@ -215,7 +215,7 @@ _get_record_id() {
return 1 return 1
fi fi
_record_id="$(echo "$response" | tr -d '\n\r' | sed "s/<item xsi:type=\"ns2:Map\">/\n/g" | grep -i "$_record_name" | grep -i ">TXT<" | sed "s/<item><key xsi:type=\"xsd:string\">record_id<\/key><value xsi:type=\"xsd:string\">/=>/g" | sed "s/<\/value><\/item>/\n/g" | grep "=>" | sed "s/=>//g")" _record_id="$(echo "$response" | tr -d '\n\r' | sed "s/<item xsi:type=\"ns2:Map\">/\n/g" | grep -i "$_record_name" | grep -i ">TXT<" | sed "s/<item><key xsi:type=\"xsd:string\">record_id<\/key><value xsi:type=\"xsd:string\">/=>/g" | grep -i "$_txtvalue" | sed "s/<\/value><\/item>/\n/g" | grep "=>" | sed "s/=>//g")"
_debug "[KAS] -> Record Id: " "$_record_id" _debug "[KAS] -> Record Id: " "$_record_id"
return 0 return 0
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment