fradev
3 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 1205 additions and 252 deletions
-
13.github/workflows/DNS.yml
-
2.github/workflows/Linux.yml
-
2.github/workflows/Solaris.yml
-
29.github/workflows/Ubuntu.yml
-
6Dockerfile
-
210acme.sh
-
46deploy/fritzbox.sh
-
156deploy/openmediavault.sh
-
10deploy/routeros.sh
-
20deploy/synology_dsm.sh
-
180deploy/truenas.sh
-
21deploy/vault.sh
-
63dnsapi/dns_acmedns.sh
-
182dnsapi/dns_azure.sh
-
24dnsapi/dns_cloudns.sh
-
4dnsapi/dns_ddnss.sh
-
87dnsapi/dns_dnshome.sh
-
42dnsapi/dns_huaweicloud.sh
-
2dnsapi/dns_ispconfig.sh
-
6dnsapi/dns_knot.sh
-
261dnsapi/dns_mythic_beasts.sh
-
2dnsapi/dns_opnsense.sh
-
5dnsapi/dns_regru.sh
-
22dnsapi/dns_simply.sh
-
62notify/gotify.sh
@ -0,0 +1,156 @@ |
|||
#!/usr/bin/env sh |
|||
|
|||
# This deploy hook is tested on OpenMediaVault 5.x. It supports both local and remote deployment. |
|||
# The way it works is that if a cert with the matching domain name is not found, it will firstly create a dummy cert to get its uuid, and then replace it with your cert. |
|||
# |
|||
# DEPLOY_OMV_WEBUI_ADMIN - This is OMV web gui admin account. Default value is admin. It's required as the user parameter (-u) for the omv-rpc command. |
|||
# DEPLOY_OMV_HOST and DEPLOY_OMV_SSH_USER are optional. They are used for remote deployment through ssh (support public key authentication only). Per design, OMV web gui admin doesn't have ssh permission, so another account is needed for ssh. |
|||
# |
|||
# returns 0 means success, otherwise error. |
|||
|
|||
######## Public functions ##################### |
|||
|
|||
#domain keyfile certfile cafile fullchain |
|||
openmediavault_deploy() { |
|||
_cdomain="$1" |
|||
_ckey="$2" |
|||
_ccert="$3" |
|||
_cca="$4" |
|||
_cfullchain="$5" |
|||
|
|||
_debug _cdomain "$_cdomain" |
|||
_debug _ckey "$_ckey" |
|||
_debug _ccert "$_ccert" |
|||
_debug _cca "$_cca" |
|||
_debug _cfullchain "$_cfullchain" |
|||
|
|||
_getdeployconf DEPLOY_OMV_WEBUI_ADMIN |
|||
|
|||
if [ -z "$DEPLOY_OMV_WEBUI_ADMIN" ]; then |
|||
DEPLOY_OMV_WEBUI_ADMIN="admin" |
|||
fi |
|||
|
|||
_savedeployconf DEPLOY_OMV_WEBUI_ADMIN "$DEPLOY_OMV_WEBUI_ADMIN" |
|||
|
|||
_getdeployconf DEPLOY_OMV_HOST |
|||
_getdeployconf DEPLOY_OMV_SSH_USER |
|||
|
|||
if [ -n "$DEPLOY_OMV_HOST" ] && [ -n "$DEPLOY_OMV_SSH_USER" ]; then |
|||
_info "[OMV deploy-hook] Deploy certificate remotely through ssh." |
|||
_savedeployconf DEPLOY_OMV_HOST "$DEPLOY_OMV_HOST" |
|||
_savedeployconf DEPLOY_OMV_SSH_USER "$DEPLOY_OMV_SSH_USER" |
|||
else |
|||
_info "[OMV deploy-hook] Deploy certificate locally." |
|||
fi |
|||
|
|||
if [ -n "$DEPLOY_OMV_HOST" ] && [ -n "$DEPLOY_OMV_SSH_USER" ]; then |
|||
|
|||
_command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'getList' '{\"start\": 0, \"limit\": -1}' | jq -r '.data[] | select(.name==\"/CN='$_cdomain'\") | .uuid'" |
|||
# shellcheck disable=SC2029 |
|||
_uuid=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") |
|||
_debug _command "$_command" |
|||
|
|||
if [ -z "$_uuid" ]; then |
|||
_info "[OMV deploy-hook] Domain $_cdomain has no certificate in openmediavault, creating it!" |
|||
_command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'create' '{\"cn\": \"test.example.com\", \"size\": 4096, \"days\": 3650, \"c\": \"\", \"st\": \"\", \"l\": \"\", \"o\": \"\", \"ou\": \"\", \"email\": \"\"}' | jq -r '.uuid'" |
|||
# shellcheck disable=SC2029 |
|||
_uuid=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") |
|||
_debug _command "$_command" |
|||
|
|||
if [ -z "$_uuid" ]; then |
|||
_err "[OMV deploy-hook] An error occured while creating the certificate" |
|||
return 1 |
|||
fi |
|||
fi |
|||
|
|||
_info "[OMV deploy-hook] Domain $_cdomain has uuid: $_uuid" |
|||
_fullchain=$(jq <"$_cfullchain" -aRs .) |
|||
_key=$(jq <"$_ckey" -aRs .) |
|||
|
|||
_debug _fullchain "$_fullchain" |
|||
_debug _key "$_key" |
|||
|
|||
_info "[OMV deploy-hook] Updating key and certificate in openmediavault" |
|||
_command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'set' '{\"uuid\":\"$_uuid\", \"certificate\":$_fullchain, \"privatekey\":$_key, \"comment\":\"acme.sh deployed $(date)\"}'" |
|||
# shellcheck disable=SC2029 |
|||
_result=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") |
|||
|
|||
_debug _command "$_command" |
|||
_debug _result "$_result" |
|||
|
|||
_command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'WebGui' 'setSettings' \$(omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'WebGui' 'getSettings' | jq -c '.sslcertificateref=\"$_uuid\"')" |
|||
# shellcheck disable=SC2029 |
|||
_result=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") |
|||
|
|||
_debug _command "$_command" |
|||
_debug _result "$_result" |
|||
|
|||
_info "[OMV deploy-hook] Asking openmediavault to apply changes... (this could take some time, hang in there)" |
|||
_command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'Config' 'applyChanges' '{\"modules\":[], \"force\": false}'" |
|||
# shellcheck disable=SC2029 |
|||
_result=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") |
|||
|
|||
_debug _command "$_command" |
|||
_debug _result "$_result" |
|||
|
|||
_info "[OMV deploy-hook] Asking nginx to reload" |
|||
_command="nginx -s reload" |
|||
# shellcheck disable=SC2029 |
|||
_result=$(ssh "$DEPLOY_OMV_SSH_USER@$DEPLOY_OMV_HOST" "$_command") |
|||
|
|||
_debug _command "$_command" |
|||
_debug _result "$_result" |
|||
|
|||
else |
|||
|
|||
# shellcheck disable=SC2086 |
|||
_uuid=$(omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'getList' '{"start": 0, "limit": -1}' | jq -r '.data[] | select(.name=="/CN='$_cdomain'") | .uuid') |
|||
if [ -z "$_uuid" ]; then |
|||
_info "[OMV deploy-hook] Domain $_cdomain has no certificate in openmediavault, creating it!" |
|||
# shellcheck disable=SC2086 |
|||
_uuid=$(omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'create' '{"cn": "test.example.com", "size": 4096, "days": 3650, "c": "", "st": "", "l": "", "o": "", "ou": "", "email": ""}' | jq -r '.uuid') |
|||
|
|||
if [ -z "$_uuid" ]; then |
|||
_err "[OMB deploy-hook] An error occured while creating the certificate" |
|||
return 1 |
|||
fi |
|||
fi |
|||
|
|||
_info "[OMV deploy-hook] Domain $_cdomain has uuid: $_uuid" |
|||
_fullchain=$(jq <"$_cfullchain" -aRs .) |
|||
_key=$(jq <"$_ckey" -aRs .) |
|||
|
|||
_debug _fullchain "$_fullchain" |
|||
_debug _key "$_key" |
|||
|
|||
_info "[OMV deploy-hook] Updating key and certificate in openmediavault" |
|||
_command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'CertificateMgmt' 'set' '{\"uuid\":\"$_uuid\", \"certificate\":$_fullchain, \"privatekey\":$_key, \"comment\":\"acme.sh deployed $(date)\"}'" |
|||
_result=$(eval "$_command") |
|||
|
|||
_debug _command "$_command" |
|||
_debug _result "$_result" |
|||
|
|||
_command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'WebGui' 'setSettings' \$(omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'WebGui' 'getSettings' | jq -c '.sslcertificateref=\"$_uuid\"')" |
|||
_result=$(eval "$_command") |
|||
|
|||
_debug _command "$_command" |
|||
_debug _result "$_result" |
|||
|
|||
_info "[OMV deploy-hook] Asking openmediavault to apply changes... (this could take some time, hang in there)" |
|||
_command="omv-rpc -u $DEPLOY_OMV_WEBUI_ADMIN 'Config' 'applyChanges' '{\"modules\":[], \"force\": false}'" |
|||
_result=$(eval "$_command") |
|||
|
|||
_debug _command "$_command" |
|||
_debug _result "$_result" |
|||
|
|||
_info "[OMV deploy-hook] Asking nginx to reload" |
|||
_command="nginx -s reload" |
|||
_result=$(eval "$_command") |
|||
|
|||
_debug _command "$_command" |
|||
_debug _result "$_result" |
|||
|
|||
fi |
|||
|
|||
return 0 |
|||
} |
@ -0,0 +1,180 @@ |
|||
#!/usr/bin/env sh |
|||
|
|||
# Here is a scipt to deploy the cert to your TrueNAS using the REST API. |
|||
# https://www.truenas.com/docs/hub/additional-topics/api/rest_api.html |
|||
# |
|||
# Written by Frank Plass github@f-plass.de |
|||
# https://github.com/danb35/deploy-freenas/blob/master/deploy_freenas.py |
|||
# Thanks to danb35 for your template! |
|||
# |
|||
# Following environment variables must be set: |
|||
# |
|||
# export DEPLOY_TRUENAS_APIKEY="<API_KEY_GENERATED_IN_THE_WEB_UI" |
|||
# |
|||
# The following environmental variables may be set if you don't like their |
|||
# default values: |
|||
# |
|||
# DEPLOY_TRUENAS_HOSTNAME - defaults to localhost |
|||
# DEPLOY_TRUENAS_SCHEME - defaults to http, set alternatively to https |
|||
# |
|||
#returns 0 means success, otherwise error. |
|||
|
|||
######## Public functions ##################### |
|||
|
|||
#domain keyfile certfile cafile fullchain |
|||
truenas_deploy() { |
|||
_cdomain="$1" |
|||
_ckey="$2" |
|||
_ccert="$3" |
|||
_cca="$4" |
|||
_cfullchain="$5" |
|||
|
|||
_debug _cdomain "$_cdomain" |
|||
_debug _ckey "$_ckey" |
|||
_debug _ccert "$_ccert" |
|||
_debug _cca "$_cca" |
|||
_debug _cfullchain "$_cfullchain" |
|||
|
|||
_getdeployconf DEPLOY_TRUENAS_APIKEY |
|||
|
|||
if [ -z "$DEPLOY_TRUENAS_APIKEY" ]; then |
|||
_err "TrueNAS Api Key is not found, please define DEPLOY_TRUENAS_APIKEY." |
|||
return 1 |
|||
fi |
|||
_secure_debug2 DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY" |
|||
|
|||
# Optional hostname, scheme for TrueNAS |
|||
_getdeployconf DEPLOY_TRUENAS_HOSTNAME |
|||
_getdeployconf DEPLOY_TRUENAS_SCHEME |
|||
|
|||
# default values for hostname and scheme |
|||
[ -n "${DEPLOY_TRUENAS_HOSTNAME}" ] || DEPLOY_TRUENAS_HOSTNAME="localhost" |
|||
[ -n "${DEPLOY_TRUENAS_SCHEME}" ] || DEPLOY_TRUENAS_SCHEME="http" |
|||
|
|||
_debug2 DEPLOY_TRUENAS_HOSTNAME "$DEPLOY_TRUENAS_HOSTNAME" |
|||
_debug2 DEPLOY_TRUENAS_SCHEME "$DEPLOY_TRUENAS_SCHEME" |
|||
|
|||
_api_url="$DEPLOY_TRUENAS_SCHEME://$DEPLOY_TRUENAS_HOSTNAME/api/v2.0" |
|||
_debug _api_url "$_api_url" |
|||
|
|||
_H1="Authorization: Bearer $DEPLOY_TRUENAS_APIKEY" |
|||
_secure_debug3 _H1 "$_H1" |
|||
|
|||
_info "Testing Connection TrueNAS" |
|||
_response=$(_get "$_api_url/system/state") |
|||
_info "TrueNAS System State: $_response." |
|||
|
|||
if [ -z "$_response" ]; then |
|||
_err "Unable to authenticate to $_api_url." |
|||
_err 'Check your Connection and set DEPLOY_TRUENAS_HOSTNAME="192.168.178.x".' |
|||
_err 'or' |
|||
_err 'set DEPLOY_TRUENAS_HOSTNAME="<truenas_dnsname>".' |
|||
_err 'Check your Connection and set DEPLOY_TRUENAS_SCHEME="https".' |
|||
_err "Check your Api Key." |
|||
return 1 |
|||
fi |
|||
|
|||
_savedeployconf DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY" |
|||
_savedeployconf DEPLOY_TRUENAS_HOSTNAME "$DEPLOY_TRUENAS_HOSTNAME" |
|||
_savedeployconf DEPLOY_TRUENAS_SCHEME "$DEPLOY_TRUENAS_SCHEME" |
|||
|
|||
_info "Getting active certificate from TrueNAS" |
|||
_response=$(_get "$_api_url/system/general") |
|||
_active_cert_id=$(echo "$_response" | grep -B2 '"name":' | grep 'id' | tr -d -- '"id: ,') |
|||
_active_cert_name=$(echo "$_response" | grep '"name":' | sed -n 's/.*: "\(.\{1,\}\)",$/\1/p') |
|||
_param_httpsredirect=$(echo "$_response" | grep '"ui_httpsredirect":' | sed -n 's/.*": \(.\{1,\}\),$/\1/p') |
|||
_debug Active_UI_Certificate_ID "$_active_cert_id" |
|||
_debug Active_UI_Certificate_Name "$_active_cert_name" |
|||
_debug Active_UI_http_redirect "$_param_httpsredirect" |
|||
|
|||
if [ "$DEPLOY_TRUENAS_SCHEME" = "http" ] && [ "$_param_httpsredirect" = "true" ]; then |
|||
_info "http Redirect active" |
|||
_info "Setting DEPLOY_TRUENAS_SCHEME to 'https'" |
|||
DEPLOY_TRUENAS_SCHEME="https" |
|||
_api_url="$DEPLOY_TRUENAS_SCHEME://$DEPLOY_TRUENAS_HOSTNAME/api/v2.0" |
|||
_savedeployconf DEPLOY_TRUENAS_SCHEME "$DEPLOY_TRUENAS_SCHEME" |
|||
fi |
|||
|
|||
_info "Upload new certifikate to TrueNAS" |
|||
_certname="Letsencrypt_$(_utc_date | tr ' ' '_' | tr -d -- ':')" |
|||
_debug3 _certname "$_certname" |
|||
|
|||
_certData="{\"create_type\": \"CERTIFICATE_CREATE_IMPORTED\", \"name\": \"${_certname}\", \"certificate\": \"$(_json_encode <"$_cfullchain")\", \"privatekey\": \"$(_json_encode <"$_ckey")\"}" |
|||
_add_cert_result="$(_post "$_certData" "$_api_url/certificate" "" "POST" "application/json")" |
|||
|
|||
_debug3 _add_cert_result "$_add_cert_result" |
|||
|
|||
_info "Getting Certificate list to get new Cert ID" |
|||
_cert_list=$(_get "$_api_url/system/general/ui_certificate_choices") |
|||
_cert_id=$(echo "$_cert_list" | grep "$_certname" | sed -n 's/.*"\([0-9]\{1,\}\)".*$/\1/p') |
|||
|
|||
_debug3 _cert_id "$_cert_id" |
|||
|
|||
_info "Activate Certificate ID: $_cert_id" |
|||
_activateData="{\"ui_certificate\": \"${_cert_id}\"}" |
|||
_activate_result="$(_post "$_activateData" "$_api_url/system/general" "" "PUT" "application/json")" |
|||
|
|||
_debug3 _activate_result "$_activate_result" |
|||
|
|||
_info "Check if WebDAV certificate is the same as the WEB UI" |
|||
_webdav_list=$(_get "$_api_url/webdav") |
|||
_webdav_cert_id=$(echo "$_webdav_list" | grep '"certssl":' | tr -d -- '"certsl: ,') |
|||
|
|||
if [ "$_webdav_cert_id" = "$_active_cert_id" ]; then |
|||
_info "Update the WebDAV Certificate" |
|||
_debug _webdav_cert_id "$_webdav_cert_id" |
|||
_webdav_data="{\"certssl\": \"${_cert_id}\"}" |
|||
_activate_webdav_cert="$(_post "$_webdav_data" "$_api_url/webdav" "" "PUT" "application/json")" |
|||
_webdav_new_cert_id=$(echo "$_activate_webdav_cert" | _json_decode | sed -n 's/.*: \([0-9]\{1,\}\) }$/\1/p') |
|||
if [ "$_webdav_new_cert_id" -eq "$_cert_id" ]; then |
|||
_info "WebDAV Certificate update successfully" |
|||
else |
|||
_err "Unable to set WebDAV certificate" |
|||
_debug3 _activate_webdav_cert "$_activate_webdav_cert" |
|||
_debug3 _webdav_new_cert_id "$_webdav_new_cert_id" |
|||
return 1 |
|||
fi |
|||
_debug3 _webdav_new_cert_id "$_webdav_new_cert_id" |
|||
else |
|||
_info "WebDAV certificate not set or not the same as Web UI" |
|||
fi |
|||
|
|||
_info "Check if FTP certificate is the same as the WEB UI" |
|||
_ftp_list=$(_get "$_api_url/ftp") |
|||
_ftp_cert_id=$(echo "$_ftp_list" | grep '"ssltls_certificate":' | tr -d -- '"certislfa:_ ,') |
|||
|
|||
if [ "$_ftp_cert_id" = "$_active_cert_id" ]; then |
|||
_info "Update the FTP Certificate" |
|||
_debug _ftp_cert_id "$_ftp_cert_id" |
|||
_ftp_data="{\"ssltls_certificate\": \"${_cert_id}\"}" |
|||
_activate_ftp_cert="$(_post "$_ftp_data" "$_api_url/ftp" "" "PUT" "application/json")" |
|||
_ftp_new_cert_id=$(echo "$_activate_ftp_cert" | _json_decode | sed -n 's/.*: \([0-9]\{1,\}\) }$/\1/p') |
|||
if [ "$_ftp_new_cert_id" -eq "$_cert_id" ]; then |
|||
_info "FTP Certificate update successfully" |
|||
else |
|||
_err "Unable to set FTP certificate" |
|||
_debug3 _activate_ftp_cert "$_activate_ftp_cert" |
|||
_debug3 _ftp_new_cert_id "$_ftp_new_cert_id" |
|||
return 1 |
|||
fi |
|||
_debug3 _activate_ftp_cert "$_activate_ftp_cert" |
|||
else |
|||
_info "FTP certificate not set or not the same as Web UI" |
|||
fi |
|||
|
|||
_info "Delete old Certificate" |
|||
_delete_result="$(_post "" "$_api_url/certificate/id/$_active_cert_id" "" "DELETE" "application/json")" |
|||
|
|||
_debug3 _delete_result "$_delete_result" |
|||
|
|||
_info "Reload WebUI from TrueNAS" |
|||
_restart_UI=$(_get "$_api_url/system/general/ui_restart") |
|||
_debug2 _restart_UI "$_restart_UI" |
|||
|
|||
if [ -n "$_add_cert_result" ] && [ -n "$_activate_result" ]; then |
|||
return 0 |
|||
else |
|||
_err "Certupdate was not succesfull, please use --debug" |
|||
return 1 |
|||
fi |
|||
} |
@ -0,0 +1,87 @@ |
|||
#!/usr/bin/env sh |
|||
|
|||
# dnsHome.de API for acme.sh |
|||
# |
|||
# This Script adds the necessary TXT record to a Subdomain |
|||
# |
|||
# Author dnsHome.de (https://github.com/dnsHome-de) |
|||
# |
|||
# Report Bugs to https://github.com/acmesh-official/acme.sh/issues/3819 |
|||
# |
|||
# export DNSHOME_Subdomain="" |
|||
# export DNSHOME_SubdomainPassword="" |
|||
|
|||
# Usage: add subdomain.ddnsdomain.tld "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
|||
# Used to add txt record |
|||
dns_dnshome_add() { |
|||
txtvalue=$2 |
|||
|
|||
DNSHOME_Subdomain="${DNSHOME_Subdomain:-$(_readdomainconf DNSHOME_Subdomain)}" |
|||
DNSHOME_SubdomainPassword="${DNSHOME_SubdomainPassword:-$(_readdomainconf DNSHOME_SubdomainPassword)}" |
|||
|
|||
if [ -z "$DNSHOME_Subdomain" ] || [ -z "$DNSHOME_SubdomainPassword" ]; then |
|||
DNSHOME_Subdomain="" |
|||
DNSHOME_SubdomainPassword="" |
|||
_err "Please specify/export your dnsHome.de Subdomain and Password" |
|||
return 1 |
|||
fi |
|||
|
|||
#save the credentials to the account conf file. |
|||
_savedomainconf DNSHOME_Subdomain "$DNSHOME_Subdomain" |
|||
_savedomainconf DNSHOME_SubdomainPassword "$DNSHOME_SubdomainPassword" |
|||
|
|||
DNSHOME_Api="https://$DNSHOME_Subdomain:$DNSHOME_SubdomainPassword@www.dnshome.de/dyndns.php" |
|||
|
|||
_DNSHOME_rest POST "acme=add&txt=$txtvalue" |
|||
if ! echo "$response" | grep 'successfully' >/dev/null; then |
|||
_err "Error" |
|||
_err "$response" |
|||
return 1 |
|||
fi |
|||
|
|||
return 0 |
|||
} |
|||
|
|||
# Usage: txtvalue |
|||
# Used to remove the txt record after validation |
|||
dns_dnshome_rm() { |
|||
txtvalue=$2 |
|||
|
|||
DNSHOME_Subdomain="${DNSHOME_Subdomain:-$(_readdomainconf DNSHOME_Subdomain)}" |
|||
DNSHOME_SubdomainPassword="${DNSHOME_SubdomainPassword:-$(_readdomainconf DNSHOME_SubdomainPassword)}" |
|||
|
|||
DNSHOME_Api="https://$DNSHOME_Subdomain:$DNSHOME_SubdomainPassword@www.dnshome.de/dyndns.php" |
|||
|
|||
if [ -z "$DNSHOME_Subdomain" ] || [ -z "$DNSHOME_SubdomainPassword" ]; then |
|||
DNSHOME_Subdomain="" |
|||
DNSHOME_SubdomainPassword="" |
|||
_err "Please specify/export your dnsHome.de Subdomain and Password" |
|||
return 1 |
|||
fi |
|||
|
|||
_DNSHOME_rest POST "acme=rm&txt=$txtvalue" |
|||
if ! echo "$response" | grep 'successfully' >/dev/null; then |
|||
_err "Error" |
|||
_err "$response" |
|||
return 1 |
|||
fi |
|||
|
|||
return 0 |
|||
} |
|||
|
|||
#################### Private functions below ################################## |
|||
_DNSHOME_rest() { |
|||
method=$1 |
|||
data="$2" |
|||
_debug "$data" |
|||
|
|||
_debug data "$data" |
|||
response="$(_post "$data" "$DNSHOME_Api" "" "$method")" |
|||
|
|||
if [ "$?" != "0" ]; then |
|||
_err "error $data" |
|||
return 1 |
|||
fi |
|||
_debug2 response "$response" |
|||
return 0 |
|||
} |
@ -0,0 +1,261 @@ |
|||
#!/usr/bin/env sh |
|||
# Mythic Beasts is a long-standing UK service provider using standards-based OAuth2 authentication |
|||
# To test: ./acme.sh --dns dns_mythic_beasts --test --debug 1 --output-insecure --issue --domain domain.com |
|||
# Cannot retest once cert is issued |
|||
# OAuth2 tokens only valid for 300 seconds so we do not store |
|||
# NOTE: This will remove all TXT records matching the fulldomain, not just the added ones (_acme-challenge.www.domain.com) |
|||
|
|||
# Test OAuth2 credentials |
|||
#MB_AK="aaaaaaaaaaaaaaaa" |
|||
#MB_AS="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" |
|||
|
|||
# URLs |
|||
MB_API='https://api.mythic-beasts.com/dns/v2/zones' |
|||
MB_AUTH='https://auth.mythic-beasts.com/login' |
|||
|
|||
######## Public functions ##################### |
|||
|
|||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
|||
dns_mythic_beasts_add() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
|
|||
_info "MYTHIC BEASTS Adding record $fulldomain = $txtvalue" |
|||
if ! _initAuth; then |
|||
return 1 |
|||
fi |
|||
|
|||
if ! _get_root "$fulldomain"; then |
|||
return 1 |
|||
fi |
|||
|
|||
# method path body_data |
|||
if _mb_rest POST "$_domain/records/$_sub_domain/TXT" "$txtvalue"; then |
|||
|
|||
if _contains "$response" "1 records added"; then |
|||
_info "Added, verifying..." |
|||
# Max 120 seconds to publish |
|||
for i in $(seq 1 6); do |
|||
# Retry on error |
|||
if ! _mb_rest GET "$_domain/records/$_sub_domain/TXT?verify"; then |
|||
_sleep 20 |
|||
else |
|||
_info "Record published!" |
|||
return 0 |
|||
fi |
|||
done |
|||
|
|||
else |
|||
_err "\n$response" |
|||
fi |
|||
|
|||
fi |
|||
_err "Add txt record error." |
|||
return 1 |
|||
} |
|||
|
|||
#Usage: rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
|||
dns_mythic_beasts_rm() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
|
|||
_info "MYTHIC BEASTS Removing record $fulldomain = $txtvalue" |
|||
if ! _initAuth; then |
|||
return 1 |
|||
fi |
|||
|
|||
if ! _get_root "$fulldomain"; then |
|||
return 1 |
|||
fi |
|||
|
|||
# method path body_data |
|||
if _mb_rest DELETE "$_domain/records/$_sub_domain/TXT" "$txtvalue"; then |
|||
_info "Record removed" |
|||
return 0 |
|||
fi |
|||
_err "Remove txt record error." |
|||
return 1 |
|||
} |
|||
|
|||
#################### Private functions below ################################## |
|||
|
|||
#Possible formats: |
|||
# _acme-challenge.www.example.com |
|||
# _acme-challenge.example.com |
|||
# _acme-challenge.example.co.uk |
|||
# _acme-challenge.www.example.co.uk |
|||
# _acme-challenge.sub1.sub2.www.example.co.uk |
|||
# sub1.sub2.example.co.uk |
|||
# example.com |
|||
# example.co.uk |
|||
#returns |
|||
# _sub_domain=_acme-challenge.www |
|||
# _domain=domain.com |
|||
_get_root() { |
|||
domain=$1 |
|||
i=1 |
|||
p=1 |
|||
|
|||
_debug "Detect the root zone" |
|||
while true; do |
|||
h=$(printf "%s" "$domain" | cut -d . -f $i-100) |
|||
if [ -z "$h" ]; then |
|||
_err "Domain exhausted" |
|||
return 1 |
|||
fi |
|||
|
|||
# Use the status errors to find the domain, continue on 403 Access denied |
|||
# method path body_data |
|||
_mb_rest GET "$h/records" |
|||
ret="$?" |
|||
if [ "$ret" -eq 0 ]; then |
|||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) |
|||
_domain="$h" |
|||
_debug _sub_domain "$_sub_domain" |
|||
_debug _domain "$_domain" |
|||
return 0 |
|||
elif [ "$ret" -eq 1 ]; then |
|||
return 1 |
|||
fi |
|||
|
|||
p=$i |
|||
i=$(_math "$i" + 1) |
|||
|
|||
if [ "$i" -gt 50 ]; then |
|||
break |
|||
fi |
|||
done |
|||
_err "Domain too long" |
|||
return 1 |
|||
} |
|||
|
|||
_initAuth() { |
|||
MB_AK="${MB_AK:-$(_readaccountconf_mutable MB_AK)}" |
|||
MB_AS="${MB_AS:-$(_readaccountconf_mutable MB_AS)}" |
|||
|
|||
if [ -z "$MB_AK" ] || [ -z "$MB_AS" ]; then |
|||
MB_AK="" |
|||
MB_AS="" |
|||
_err "Please specify an OAuth2 Key & Secret" |
|||
return 1 |
|||
fi |
|||
|
|||
_saveaccountconf_mutable MB_AK "$MB_AK" |
|||
_saveaccountconf_mutable MB_AS "$MB_AS" |
|||
|
|||
if ! _oauth2; then |
|||
return 1 |
|||
fi |
|||
|
|||
_info "Checking authentication" |
|||
_secure_debug access_token "$MB_TK" |
|||
_sleep 1 |
|||
|
|||
# GET a list of zones |
|||
# method path body_data |
|||
if ! _mb_rest GET ""; then |
|||
_err "The token is invalid" |
|||
return 1 |
|||
fi |
|||
_info "Token OK" |
|||
return 0 |
|||
} |
|||
|
|||
# Github appears to use an outbound proxy for requests which means subsequent requests may not have the same |
|||
# source IP. The standard Mythic Beasts OAuth2 tokens are tied to an IP, meaning github test requests fail |
|||
# authentication. This is a work around using an undocumented MB API to obtain a token not tied to an |
|||
# IP just for the github tests. |
|||
_oauth2() { |
|||
if [ "$GITHUB_ACTIONS" = "true" ]; then |
|||
_oauth2_github |
|||
else |
|||
_oauth2_std |
|||
fi |
|||
return $? |
|||
} |
|||
|
|||
_oauth2_std() { |
|||
# HTTP Basic Authentication |
|||
_H1="Authorization: Basic $(echo "$MB_AK:$MB_AS" | _base64)" |
|||
_H2="Accepts: application/json" |
|||
export _H1 _H2 |
|||
body="grant_type=client_credentials" |
|||
|
|||
_info "Getting OAuth2 token..." |
|||
# body url [needbase64] [POST|PUT|DELETE] [ContentType] |
|||
response="$(_post "$body" "$MB_AUTH" "" "POST" "application/x-www-form-urlencoded")" |
|||
if _contains "$response" "\"token_type\":\"bearer\""; then |
|||
MB_TK="$(echo "$response" | _egrep_o "access_token\":\"[^\"]*\"" | cut -d : -f 2 | tr -d '"')" |
|||
if [ -z "$MB_TK" ]; then |
|||
_err "Unable to get access_token" |
|||
_err "\n$response" |
|||
return 1 |
|||
fi |
|||
else |
|||
_err "OAuth2 token_type not Bearer" |
|||
_err "\n$response" |
|||
return 1 |
|||
fi |
|||
_debug2 response "$response" |
|||
return 0 |
|||
} |
|||
|
|||
_oauth2_github() { |
|||
_H1="Accepts: application/json" |
|||
export _H1 |
|||
body="{\"login\":{\"handle\":\"$MB_AK\",\"pass\":\"$MB_AS\",\"floating\":1}}" |
|||
|
|||
_info "Getting Floating token..." |
|||
# body url [needbase64] [POST|PUT|DELETE] [ContentType] |
|||
response="$(_post "$body" "$MB_AUTH" "" "POST" "application/json")" |
|||
MB_TK="$(echo "$response" | _egrep_o "\"token\":\"[^\"]*\"" | cut -d : -f 2 | tr -d '"')" |
|||
if [ -z "$MB_TK" ]; then |
|||
_err "Unable to get token" |
|||
_err "\n$response" |
|||
return 1 |
|||
fi |
|||
_debug2 response "$response" |
|||
return 0 |
|||
} |
|||
|
|||
# method path body_data |
|||
_mb_rest() { |
|||
# URL encoded body for single API operations |
|||
m="$1" |
|||
ep="$2" |
|||
data="$3" |
|||
|
|||
if [ -z "$ep" ]; then |
|||
_mb_url="$MB_API" |
|||
else |
|||
_mb_url="$MB_API/$ep" |
|||
fi |
|||
|
|||
_H1="Authorization: Bearer $MB_TK" |
|||
_H2="Accepts: application/json" |
|||
export _H1 _H2 |
|||
if [ "$data" ] || [ "$m" = "POST" ] || [ "$m" = "PUT" ] || [ "$m" = "DELETE" ]; then |
|||
# body url [needbase64] [POST|PUT|DELETE] [ContentType] |
|||
response="$(_post "data=$data" "$_mb_url" "" "$m" "application/x-www-form-urlencoded")" |
|||
else |
|||
response="$(_get "$_mb_url")" |
|||
fi |
|||
|
|||
if [ "$?" != "0" ]; then |
|||
_err "Request error" |
|||
return 1 |
|||
fi |
|||
|
|||
header="$(cat "$HTTP_HEADER")" |
|||
status="$(echo "$header" | _egrep_o "^HTTP[^ ]* .*$" | cut -d " " -f 2-100 | tr -d "\f\n")" |
|||
code="$(echo "$status" | _egrep_o "^[0-9]*")" |
|||
if [ "$code" -ge 400 ] || _contains "$response" "\"error\"" || _contains "$response" "invalid_client"; then |
|||
_err "error $status" |
|||
_err "\n$response" |
|||
_debug "\n$header" |
|||
return 2 |
|||
fi |
|||
|
|||
_debug2 response "$response" |
|||
return 0 |
|||
} |
@ -0,0 +1,62 @@ |
|||
#!/usr/bin/env sh |
|||
|
|||
#Support Gotify |
|||
|
|||
#GOTIFY_URL="https://gotify.example.com" |
|||
#GOTIFY_TOKEN="123456789ABCDEF" |
|||
|
|||
#optional |
|||
#GOTIFY_PRIORITY=0 |
|||
|
|||
# subject content statusCode |
|||
gotify_send() { |
|||
_subject="$1" |
|||
_content="$2" |
|||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped |
|||
_debug "_subject" "$_subject" |
|||
_debug "_content" "$_content" |
|||
_debug "_statusCode" "$_statusCode" |
|||
|
|||
GOTIFY_URL="${GOTIFY_URL:-$(_readaccountconf_mutable GOTIFY_URL)}" |
|||
if [ -z "$GOTIFY_URL" ]; then |
|||
GOTIFY_URL="" |
|||
_err "You didn't specify the gotify server url GOTIFY_URL." |
|||
return 1 |
|||
fi |
|||
_saveaccountconf_mutable GOTIFY_URL "$GOTIFY_URL" |
|||
|
|||
GOTIFY_TOKEN="${GOTIFY_TOKEN:-$(_readaccountconf_mutable GOTIFY_TOKEN)}" |
|||
if [ -z "$GOTIFY_TOKEN" ]; then |
|||
GOTIFY_TOKEN="" |
|||
_err "You didn't specify the gotify token GOTIFY_TOKEN." |
|||
return 1 |
|||
fi |
|||
_saveaccountconf_mutable GOTIFY_TOKEN "$GOTIFY_TOKEN" |
|||
|
|||
GOTIFY_PRIORITY="${GOTIFY_PRIORITY:-$(_readaccountconf_mutable GOTIFY_PRIORITY)}" |
|||
if [ -z "$GOTIFY_PRIORITY" ]; then |
|||
GOTIFY_PRIORITY=0 |
|||
else |
|||
_saveaccountconf_mutable GOTIFY_PRIORITY "$GOTIFY_PRIORITY" |
|||
fi |
|||
|
|||
export _H1="X-Gotify-Key: ${GOTIFY_TOKEN}" |
|||
export _H2="Content-Type: application/json" |
|||
|
|||
_content=$(echo "$_content" | _json_encode) |
|||
_subject=$(echo "$_subject" | _json_encode) |
|||
|
|||
_data="{\"title\": \"${_subject}\", \"message\": \"${_content}\", \"priority\": ${GOTIFY_PRIORITY}}" |
|||
|
|||
response="$(_post "${_data}" "${GOTIFY_URL}/message" "" "POST" "application/json")" |
|||
|
|||
if [ "$?" != "0" ]; then |
|||
_err "Failed to send message" |
|||
_err "$response" |
|||
return 1 |
|||
fi |
|||
|
|||
_debug2 response "$response" |
|||
|
|||
return 0 |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue