mirror of
https://github.com/plantroon/acme.sh.git
synced 2024-12-22 13:11:41 +00:00
commit
075e992fa0
10
.github/workflows/dockerhub.yml
vendored
10
.github/workflows/dockerhub.yml
vendored
@ -33,12 +33,10 @@ jobs:
|
||||
steps:
|
||||
- name: checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: install buildx
|
||||
id: buildx
|
||||
uses: crazy-max/ghaction-docker-buildx@v3
|
||||
with:
|
||||
buildx-version: latest
|
||||
qemu-version: latest
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
- name: login to docker hub
|
||||
run: |
|
||||
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
|
||||
|
@ -89,6 +89,7 @@ https://github.com/acmesh-official/acmetest
|
||||
- [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA)
|
||||
- [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA)
|
||||
- [Pebble strict Mode](https://github.com/letsencrypt/pebble)
|
||||
- Any other [RFC8555](https://tools.ietf.org/html/rfc8555)-compliant CA
|
||||
|
||||
# Supported modes
|
||||
|
||||
@ -109,13 +110,13 @@ https://github.com/acmesh-official/acmetest
|
||||
Check this project: https://github.com/acmesh-official/get.acme.sh
|
||||
|
||||
```bash
|
||||
curl https://get.acme.sh | sh
|
||||
curl https://get.acme.sh | sh -s email=my@example.com
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
```bash
|
||||
wget -O - https://get.acme.sh | sh
|
||||
wget -O - https://get.acme.sh | sh -s email=my@example.com
|
||||
```
|
||||
|
||||
|
||||
@ -126,7 +127,7 @@ Clone this project and launch installation:
|
||||
```bash
|
||||
git clone https://github.com/acmesh-official/acme.sh.git
|
||||
cd ./acme.sh
|
||||
./acme.sh --install
|
||||
./acme.sh --install -m my@example.com
|
||||
```
|
||||
|
||||
You `don't have to be root` then, although `it is recommended`.
|
||||
|
59
acme.sh
59
acme.sh
@ -6105,7 +6105,7 @@ _installalias() {
|
||||
|
||||
}
|
||||
|
||||
# nocron confighome noprofile
|
||||
# nocron confighome noprofile accountemail
|
||||
install() {
|
||||
|
||||
if [ -z "$LE_WORKING_DIR" ]; then
|
||||
@ -6115,6 +6115,8 @@ install() {
|
||||
_nocron="$1"
|
||||
_c_home="$2"
|
||||
_noprofile="$3"
|
||||
_accountemail="$4"
|
||||
|
||||
if ! _initpath; then
|
||||
_err "Install failed."
|
||||
return 1
|
||||
@ -6233,6 +6235,10 @@ install() {
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$_accountemail" ]; then
|
||||
_saveaccountconf "ACCOUNT_EMAIL" "$_accountemail"
|
||||
fi
|
||||
|
||||
_info OK
|
||||
}
|
||||
|
||||
@ -6511,7 +6517,7 @@ Parameters:
|
||||
--cert-home <directory> Specifies the home dir to save all the certs, only valid for '--install' command.
|
||||
--config-home <directory> Specifies the home dir to save all the configurations.
|
||||
--useragent <string> Specifies the user agent string. it will be saved for future use too.
|
||||
-m, --accountemail <email> Specifies the account email, only valid for the '--install' and '--update-account' command.
|
||||
-m, --email <email> Specifies the account email, only valid for the '--install' and '--update-account' command.
|
||||
--accountkey <file> Specifies the account key path, only valid for the '--install' command.
|
||||
--days <ndays> Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days.
|
||||
--httpport <port> Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer.
|
||||
@ -6522,9 +6528,9 @@ Parameters:
|
||||
--insecure Do not check the server certificate, in some devices, the api server's certificate may not be trusted.
|
||||
--ca-bundle <file> Specifies the path to the CA certificate bundle to verify api server's certificate.
|
||||
--ca-path <directory> Specifies directory containing CA certificates in PEM format, used by wget or curl.
|
||||
--nocron Only valid for '--install' command, which means: do not install the default cron job.
|
||||
--no-cron Only valid for '--install' command, which means: do not install the default cron job.
|
||||
In this case, the certs will not be renewed automatically.
|
||||
--noprofile Only valid for '--install' command, which means: do not install aliases to user profile.
|
||||
--no-profile Only valid for '--install' command, which means: do not install aliases to user profile.
|
||||
--no-color Do not output color text.
|
||||
--force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails.
|
||||
--ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--to-pkcs12' and '--create-csr'
|
||||
@ -6562,18 +6568,18 @@ Parameters:
|
||||
"
|
||||
}
|
||||
|
||||
# nocron noprofile
|
||||
_installOnline() {
|
||||
|
||||
installOnline() {
|
||||
_info "Installing from online archive."
|
||||
_nocron="$1"
|
||||
_noprofile="$2"
|
||||
if [ ! "$BRANCH" ]; then
|
||||
BRANCH="master"
|
||||
|
||||
_branch="$BRANCH"
|
||||
if [ -z "$_branch" ]; then
|
||||
_branch="master"
|
||||
fi
|
||||
|
||||
target="$PROJECT/archive/$BRANCH.tar.gz"
|
||||
target="$PROJECT/archive/$_branch.tar.gz"
|
||||
_info "Downloading $target"
|
||||
localname="$BRANCH.tar.gz"
|
||||
localname="$_branch.tar.gz"
|
||||
if ! _get "$target" >$localname; then
|
||||
_err "Download error."
|
||||
return 1
|
||||
@ -6585,9 +6591,9 @@ _installOnline() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$PROJECT_NAME-$BRANCH"
|
||||
cd "$PROJECT_NAME-$_branch"
|
||||
chmod +x $PROJECT_ENTRY
|
||||
if ./$PROJECT_ENTRY install "$_nocron" "" "$_noprofile"; then
|
||||
if ./$PROJECT_ENTRY --install "$@"; then
|
||||
_info "Install success!"
|
||||
_initpath
|
||||
_saveaccountconf "UPGRADE_HASH" "$(_getUpgradeHash)"
|
||||
@ -6595,7 +6601,7 @@ _installOnline() {
|
||||
|
||||
cd ..
|
||||
|
||||
rm -rf "$PROJECT_NAME-$BRANCH"
|
||||
rm -rf "$PROJECT_NAME-$_branch"
|
||||
rm -f "$localname"
|
||||
)
|
||||
}
|
||||
@ -6623,7 +6629,7 @@ upgrade() {
|
||||
[ -z "$FORCE" ] && [ "$(_getUpgradeHash)" = "$(_readaccountconf "UPGRADE_HASH")" ] && _info "Already uptodate!" && exit 0
|
||||
export LE_WORKING_DIR
|
||||
cd "$LE_WORKING_DIR"
|
||||
_installOnline "nocron" "noprofile"
|
||||
installOnline "--nocron" "--noprofile"
|
||||
); then
|
||||
_info "Upgrade success!"
|
||||
exit 0
|
||||
@ -6803,6 +6809,11 @@ _process() {
|
||||
--install)
|
||||
_CMD="install"
|
||||
;;
|
||||
--install-online)
|
||||
shift
|
||||
installOnline "$@"
|
||||
return
|
||||
;;
|
||||
--uninstall)
|
||||
_CMD="uninstall"
|
||||
;;
|
||||
@ -7077,9 +7088,9 @@ _process() {
|
||||
USER_AGENT="$_useragent"
|
||||
shift
|
||||
;;
|
||||
-m | --accountemail)
|
||||
-m | --email | --accountemail)
|
||||
_accountemail="$2"
|
||||
ACCOUNT_EMAIL="$_accountemail"
|
||||
export ACCOUNT_EMAIL="$_accountemail"
|
||||
shift
|
||||
;;
|
||||
--accountkey)
|
||||
@ -7122,10 +7133,10 @@ _process() {
|
||||
CA_PATH="$_ca_path"
|
||||
shift
|
||||
;;
|
||||
--nocron)
|
||||
--no-cron | --nocron)
|
||||
_nocron="1"
|
||||
;;
|
||||
--noprofile)
|
||||
--no-profile | --noprofile)
|
||||
_noprofile="1"
|
||||
;;
|
||||
--no-color)
|
||||
@ -7345,7 +7356,7 @@ _process() {
|
||||
fi
|
||||
_debug "Running cmd: ${_CMD}"
|
||||
case "${_CMD}" in
|
||||
install) install "$_nocron" "$_confighome" "$_noprofile" ;;
|
||||
install) install "$_nocron" "$_confighome" "$_noprofile" "$_accountemail" ;;
|
||||
uninstall) uninstall "$_nocron" ;;
|
||||
upgrade) upgrade ;;
|
||||
issue)
|
||||
@ -7458,12 +7469,6 @@ _process() {
|
||||
|
||||
}
|
||||
|
||||
if [ "$INSTALLONLINE" ]; then
|
||||
INSTALLONLINE=""
|
||||
_installOnline
|
||||
exit
|
||||
fi
|
||||
|
||||
main() {
|
||||
[ -z "$1" ] && showhelp && return
|
||||
if _startswith "$1" '-'; then _process "$@"; else "$@"; fi
|
||||
|
123
deploy/peplink.sh
Normal file
123
deploy/peplink.sh
Normal file
@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Script to deploy cert to Peplink Routers
|
||||
#
|
||||
# The following environment variables must be set:
|
||||
#
|
||||
# PEPLINK_Hostname - Peplink hostname
|
||||
# PEPLINK_Username - Peplink username to login
|
||||
# PEPLINK_Password - Peplink password to login
|
||||
#
|
||||
# The following environmental variables may be set if you don't like their
|
||||
# default values:
|
||||
#
|
||||
# PEPLINK_Certtype - Certificate type to target for replacement
|
||||
# defaults to "webadmin", can be one of:
|
||||
# * "chub" (ContentHub)
|
||||
# * "openvpn" (OpenVPN CA)
|
||||
# * "portal" (Captive Portal SSL)
|
||||
# * "webadmin" (Web Admin SSL)
|
||||
# * "webproxy" (Proxy Root CA)
|
||||
# * "wwan_ca" (Wi-Fi WAN CA)
|
||||
# * "wwan_client" (Wi-Fi WAN Client)
|
||||
# PEPLINK_Scheme - defaults to "https"
|
||||
# PEPLINK_Port - defaults to "443"
|
||||
#
|
||||
#returns 0 means success, otherwise error.
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
_peplink_get_cookie_data() {
|
||||
grep -i "\W$1=" | grep -i "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';'
|
||||
}
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
peplink_deploy() {
|
||||
|
||||
_cdomain="$1"
|
||||
_ckey="$2"
|
||||
_cfullchain="$5"
|
||||
|
||||
_debug _cdomain "$_cdomain"
|
||||
_debug _cfullchain "$_cfullchain"
|
||||
_debug _ckey "$_ckey"
|
||||
|
||||
# Get Hostname, Username and Password, but don't save until we successfully authenticate
|
||||
_getdeployconf PEPLINK_Hostname
|
||||
_getdeployconf PEPLINK_Username
|
||||
_getdeployconf PEPLINK_Password
|
||||
if [ -z "${PEPLINK_Hostname:-}" ] || [ -z "${PEPLINK_Username:-}" ] || [ -z "${PEPLINK_Password:-}" ]; then
|
||||
_err "PEPLINK_Hostname & PEPLINK_Username & PEPLINK_Password must be set"
|
||||
return 1
|
||||
fi
|
||||
_debug2 PEPLINK_Hostname "$PEPLINK_Hostname"
|
||||
_debug2 PEPLINK_Username "$PEPLINK_Username"
|
||||
_secure_debug2 PEPLINK_Password "$PEPLINK_Password"
|
||||
|
||||
# Optional certificate type, scheme, and port for Peplink
|
||||
_getdeployconf PEPLINK_Certtype
|
||||
_getdeployconf PEPLINK_Scheme
|
||||
_getdeployconf PEPLINK_Port
|
||||
|
||||
# Don't save the certificate type until we verify it exists and is supported
|
||||
_savedeployconf PEPLINK_Scheme "$PEPLINK_Scheme"
|
||||
_savedeployconf PEPLINK_Port "$PEPLINK_Port"
|
||||
|
||||
# Default vaules for certificate type, scheme, and port
|
||||
[ -n "${PEPLINK_Certtype}" ] || PEPLINK_Certtype="webadmin"
|
||||
[ -n "${PEPLINK_Scheme}" ] || PEPLINK_Scheme="https"
|
||||
[ -n "${PEPLINK_Port}" ] || PEPLINK_Port="443"
|
||||
|
||||
_debug2 PEPLINK_Certtype "$PEPLINK_Certtype"
|
||||
_debug2 PEPLINK_Scheme "$PEPLINK_Scheme"
|
||||
_debug2 PEPLINK_Port "$PEPLINK_Port"
|
||||
|
||||
_base_url="$PEPLINK_Scheme://$PEPLINK_Hostname:$PEPLINK_Port"
|
||||
_debug _base_url "$_base_url"
|
||||
|
||||
# Login, get the auth token from the cookie
|
||||
_info "Logging into $PEPLINK_Hostname:$PEPLINK_Port"
|
||||
encoded_username="$(printf "%s" "$PEPLINK_Username" | _url_encode)"
|
||||
encoded_password="$(printf "%s" "$PEPLINK_Password" | _url_encode)"
|
||||
response=$(_post "func=login&username=$encoded_username&password=$encoded_password" "$_base_url/cgi-bin/MANGA/api.cgi")
|
||||
auth_token=$(_peplink_get_cookie_data "bauth" <"$HTTP_HEADER")
|
||||
_debug3 response "$response"
|
||||
_debug auth_token "$auth_token"
|
||||
|
||||
if [ -z "$auth_token" ]; then
|
||||
_err "Unable to authenticate to $PEPLINK_Hostname:$PEPLINK_Port using $PEPLINK_Scheme."
|
||||
_err "Check your username and password."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_H1="Cookie: $auth_token"
|
||||
export _H1
|
||||
_debug2 H1 "${_H1}"
|
||||
|
||||
# Now that we know the hostnameusername and password are good, save them
|
||||
_savedeployconf PEPLINK_Hostname "$PEPLINK_Hostname"
|
||||
_savedeployconf PEPLINK_Username "$PEPLINK_Username"
|
||||
_savedeployconf PEPLINK_Password "$PEPLINK_Password"
|
||||
|
||||
_info "Generate form POST request"
|
||||
|
||||
encoded_key="$(_url_encode <"$_ckey")"
|
||||
encoded_fullchain="$(_url_encode <"$_cfullchain")"
|
||||
body="cert_type=$PEPLINK_Certtype&cert_uid=§ion=CERT_modify&key_pem=$encoded_key&key_pem_passphrase=&key_pem_passphrase_confirm=&cert_pem=$encoded_fullchain"
|
||||
_debug3 body "$body"
|
||||
|
||||
_info "Upload $PEPLINK_Certtype certificate to the Peplink"
|
||||
|
||||
response=$(_post "$body" "$_base_url/cgi-bin/MANGA/admin.cgi")
|
||||
_debug3 response "$response"
|
||||
|
||||
if echo "$response" | grep 'Success' >/dev/null; then
|
||||
# We've verified this certificate type is valid, so save it
|
||||
_savedeployconf PEPLINK_Certtype "$PEPLINK_Certtype"
|
||||
_info "Certificate was updated"
|
||||
return 0
|
||||
else
|
||||
_err "Unable to update certificate, error code $response"
|
||||
return 1
|
||||
fi
|
||||
}
|
@ -53,7 +53,7 @@ dns_dpi_rm() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _rest POST "Record.List" "user_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain"; then
|
||||
if ! _rest POST "Record.List" "login_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain"; then
|
||||
_err "Record.Lis error."
|
||||
return 1
|
||||
fi
|
||||
@ -63,14 +63,14 @@ dns_dpi_rm() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
record_id=$(echo "$response" | _egrep_o '{[^{]*"value":"'"$txtvalue"'"' | cut -d , -f 1 | cut -d : -f 2 | tr -d \")
|
||||
record_id=$(echo "$response" | tr "{" "\n" | grep -- "$txtvalue" | grep '^"id"' | cut -d : -f 2 | cut -d '"' -f 2)
|
||||
_debug record_id "$record_id"
|
||||
if [ -z "$record_id" ]; then
|
||||
_err "Can not get record id."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _rest POST "Record.Remove" "user_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&record_id=$record_id"; then
|
||||
if ! _rest POST "Record.Remove" "login_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&record_id=$record_id"; then
|
||||
_err "Record.Remove error."
|
||||
return 1
|
||||
fi
|
||||
@ -89,7 +89,7 @@ add_record() {
|
||||
|
||||
_info "Adding record"
|
||||
|
||||
if ! _rest POST "Record.Create" "user_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=default"; then
|
||||
if ! _rest POST "Record.Create" "login_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=default"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
@ -113,7 +113,7 @@ _get_root() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _rest POST "Domain.Info" "user_token=$DPI_Id,$DPI_Key&format=json&domain=$h"; then
|
||||
if ! _rest POST "Domain.Info" "login_token=$DPI_Id,$DPI_Key&format=json&domain=$h"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
184
dnsapi/dns_ionos.sh
Executable file
184
dnsapi/dns_ionos.sh
Executable file
@ -0,0 +1,184 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Supports IONOS DNS API Beta v1.0.0
|
||||
#
|
||||
# Usage:
|
||||
# Export IONOS_PREFIX and IONOS_SECRET before calling acme.sh:
|
||||
#
|
||||
# $ export IONOS_PREFIX="..."
|
||||
# $ export IONOS_SECRET="..."
|
||||
#
|
||||
# $ acme.sh --issue --dns dns_ionos ...
|
||||
|
||||
IONOS_API="https://api.hosting.ionos.com/dns"
|
||||
IONOS_ROUTE_ZONES="/v1/zones"
|
||||
|
||||
IONOS_TXT_TTL=60 # minimum accepted by API
|
||||
IONOS_TXT_PRIO=10
|
||||
|
||||
dns_ionos_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
if ! _ionos_init; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
_new_record="{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}"
|
||||
|
||||
# As no POST route is supported by the API, check for existing records and include them in the PATCH request in order not delete them.
|
||||
# This is required to support ACME v2 wildcard certificate creation, where two TXT records for the same domain name are created.
|
||||
|
||||
_ionos_get_existing_records "$fulldomain" "$_zone_id"
|
||||
|
||||
if [ "$_existing_records" ]; then
|
||||
_body="[$_new_record,$_existing_records]"
|
||||
else
|
||||
_body="[$_new_record]"
|
||||
fi
|
||||
|
||||
if _ionos_rest PATCH "$IONOS_ROUTE_ZONES/$_zone_id" "$_body" && [ -z "$response" ]; then
|
||||
_info "TXT record has been created successfully."
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
dns_ionos_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
if ! _ionos_init; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _ionos_get_record "$fulldomain" "$_zone_id" "$txtvalue"; then
|
||||
_err "Could not find _acme-challenge TXT record."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ -z "$response" ]; then
|
||||
_info "TXT record has been deleted successfully."
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
_ionos_init() {
|
||||
IONOS_PREFIX="${IONOS_PREFIX:-$(_readaccountconf_mutable IONOS_PREFIX)}"
|
||||
IONOS_SECRET="${IONOS_SECRET:-$(_readaccountconf_mutable IONOS_SECRET)}"
|
||||
|
||||
if [ -z "$IONOS_PREFIX" ] || [ -z "$IONOS_SECRET" ]; then
|
||||
_err "You didn't specify an IONOS api prefix and secret yet."
|
||||
_err "Read https://beta.developer.hosting.ionos.de/docs/getstarted to learn how to get a prefix and secret."
|
||||
_err ""
|
||||
_err "Then set them before calling acme.sh:"
|
||||
_err "\$ export IONOS_PREFIX=\"...\""
|
||||
_err "\$ export IONOS_SECRET=\"...\""
|
||||
_err "\$ acme.sh --issue -d ... --dns dns_ionos"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable IONOS_PREFIX "$IONOS_PREFIX"
|
||||
_saveaccountconf_mutable IONOS_SECRET "$IONOS_SECRET"
|
||||
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "Cannot find this domain in your IONOS account."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
_get_root() {
|
||||
domain=$1
|
||||
i=1
|
||||
p=1
|
||||
|
||||
if _ionos_rest GET "$IONOS_ROUTE_ZONES"; then
|
||||
response="$(echo "$response" | tr -d "\n")"
|
||||
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
if [ -z "$h" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
_zone="$(echo "$response" | _egrep_o "\"name\":\"$h\".*\}")"
|
||||
if [ "$_zone" ]; then
|
||||
_zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"')
|
||||
if [ "$_zone_id" ]; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain=$h
|
||||
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
fi
|
||||
|
||||
p=$i
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
_ionos_get_existing_records() {
|
||||
fulldomain=$1
|
||||
zone_id=$2
|
||||
|
||||
if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then
|
||||
response="$(echo "$response" | tr -d "\n")"
|
||||
|
||||
_existing_records="$(printf "%s\n" "$response" | _egrep_o "\"records\":\[.*\]" | _head_n 1 | cut -d '[' -f 2 | sed 's/]//')"
|
||||
fi
|
||||
}
|
||||
|
||||
_ionos_get_record() {
|
||||
fulldomain=$1
|
||||
zone_id=$2
|
||||
txtrecord=$3
|
||||
|
||||
if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then
|
||||
response="$(echo "$response" | tr -d "\n")"
|
||||
|
||||
_record="$(echo "$response" | _egrep_o "\"name\":\"$fulldomain\"[^\}]*\"type\":\"TXT\"[^\}]*\"content\":\"\\\\\"$txtrecord\\\\\"\".*\}")"
|
||||
if [ "$_record" ]; then
|
||||
_record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"')
|
||||
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
_ionos_rest() {
|
||||
method="$1"
|
||||
route="$2"
|
||||
data="$3"
|
||||
|
||||
IONOS_API_KEY="$(printf "%s.%s" "$IONOS_PREFIX" "$IONOS_SECRET")"
|
||||
|
||||
export _H1="X-API-Key: $IONOS_API_KEY"
|
||||
|
||||
if [ "$method" != "GET" ]; then
|
||||
export _H2="Accept: application/json"
|
||||
export _H3="Content-Type: application/json"
|
||||
|
||||
response="$(_post "$data" "$IONOS_API$route" "" "$method")"
|
||||
else
|
||||
export _H2="Accept: */*"
|
||||
|
||||
response="$(_get "$IONOS_API$route")"
|
||||
fi
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "Error $route"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
@ -75,7 +75,7 @@ _ISPC_getZoneInfo() {
|
||||
# suffix . needed for zone -> domain.tld.
|
||||
curData="{\"session_id\":\"${sessionID}\",\"primary_id\":{\"origin\":\"${curZone}.\"}}"
|
||||
curResult="$(_post "${curData}" "${ISPC_Api}?dns_zone_get")"
|
||||
_debug "Calling _ISPC_getZoneInfo: '${curData}' '${ISPC_Api}?login'"
|
||||
_debug "Calling _ISPC_getZoneInfo: '${curData}' '${ISPC_Api}?dns_zone_get'"
|
||||
_debug "Result of _ISPC_getZoneInfo: '$curResult'"
|
||||
if _contains "${curResult}" '"id":"'; then
|
||||
zoneFound=true
|
||||
@ -110,18 +110,32 @@ _ISPC_getZoneInfo() {
|
||||
;;
|
||||
*) _info "Retrieved Zone ID" ;;
|
||||
esac
|
||||
client_id=$(echo "${curResult}" | _egrep_o "sys_userid.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
|
||||
_debug "Client ID: '${client_id}'"
|
||||
case "${client_id}" in
|
||||
sys_userid=$(echo "${curResult}" | _egrep_o "sys_userid.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
|
||||
_debug "SYS User ID: '${sys_userid}'"
|
||||
case "${sys_userid}" in
|
||||
'' | *[!0-9]*)
|
||||
_err "Client ID is not numeric."
|
||||
_err "SYS User ID is not numeric."
|
||||
return 1
|
||||
;;
|
||||
*) _info "Retrieved Client ID." ;;
|
||||
*) _info "Retrieved SYS User ID." ;;
|
||||
esac
|
||||
zoneFound=""
|
||||
zoneEnd=""
|
||||
fi
|
||||
# Need to get client_id as it is different from sys_userid
|
||||
curData="{\"session_id\":\"${sessionID}\",\"sys_userid\":\"${sys_userid}\"}"
|
||||
curResult="$(_post "${curData}" "${ISPC_Api}?client_get_id")"
|
||||
_debug "Calling _ISPC_ClientGetID: '${curData}' '${ISPC_Api}?client_get_id'"
|
||||
_debug "Result of _ISPC_ClientGetID: '$curResult'"
|
||||
client_id=$(echo "${curResult}" | _egrep_o "response.*" | cut -d ':' -f 2 | cut -d '"' -f 2 | tr -d '{}')
|
||||
_debug "Client ID: '${client_id}'"
|
||||
case "${client_id}" in
|
||||
'' | *[!0-9]*)
|
||||
_err "Client ID is not numeric."
|
||||
return 1
|
||||
;;
|
||||
*) _info "Retrieved Client ID." ;;
|
||||
esac
|
||||
}
|
||||
|
||||
_ISPC_addTxt() {
|
||||
|
@ -106,6 +106,7 @@ dns_linode_v4_rm() {
|
||||
#################### Private functions below ##################################
|
||||
|
||||
_Linode_API() {
|
||||
LINODE_V4_API_KEY="${LINODE_V4_API_KEY:-$(_readaccountconf_mutable LINODE_V4_API_KEY)}"
|
||||
if [ -z "$LINODE_V4_API_KEY" ]; then
|
||||
LINODE_V4_API_KEY=""
|
||||
|
||||
@ -115,7 +116,7 @@ _Linode_API() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf LINODE_V4_API_KEY "$LINODE_V4_API_KEY"
|
||||
_saveaccountconf_mutable LINODE_V4_API_KEY "$LINODE_V4_API_KEY"
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
|
@ -157,7 +157,7 @@ _namecheap_set_publicip() {
|
||||
|
||||
if [ -z "$NAMECHEAP_SOURCEIP" ]; then
|
||||
_err "No Source IP specified for Namecheap API."
|
||||
_err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
|
||||
_err "Use your public ip address or an url to retrieve it (e.g. https://ifconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
|
||||
return 1
|
||||
else
|
||||
_saveaccountconf NAMECHEAP_SOURCEIP "$NAMECHEAP_SOURCEIP"
|
||||
@ -175,7 +175,7 @@ _namecheap_set_publicip() {
|
||||
_publicip=$(_get "$addr")
|
||||
else
|
||||
_err "No Source IP specified for Namecheap API."
|
||||
_err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
|
||||
_err "Use your public ip address or an url to retrieve it (e.g. https://ifconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
156
dnsapi/dns_rackcorp.sh
Normal file
156
dnsapi/dns_rackcorp.sh
Normal file
@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Provider: RackCorp (www.rackcorp.com)
|
||||
# Author: Stephen Dendtler (sdendtler@rackcorp.com)
|
||||
# Report Bugs here: https://github.com/senjoo/acme.sh
|
||||
# Alternate email contact: support@rackcorp.com
|
||||
#
|
||||
# You'll need an API key (Portal: ADMINISTRATION -> API)
|
||||
# Set the environment variables as below:
|
||||
#
|
||||
# export RACKCORP_APIUUID="UUIDHERE"
|
||||
# export RACKCORP_APISECRET="SECRETHERE"
|
||||
#
|
||||
|
||||
RACKCORP_API_ENDPOINT="https://api.rackcorp.net/api/rest/v2.4/json.php"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
dns_rackcorp_add() {
|
||||
fulldomain="$1"
|
||||
txtvalue="$2"
|
||||
|
||||
_debug fulldomain="$fulldomain"
|
||||
_debug txtvalue="$txtvalue"
|
||||
|
||||
if ! _rackcorp_validate; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "Searching for root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
return 1
|
||||
fi
|
||||
_debug _lookup "$_lookup"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_info "Creating TXT record."
|
||||
|
||||
if ! _rackcorp_api dns.record.create "\"name\":\"$_domain\",\"type\":\"TXT\",\"lookup\":\"$_lookup\",\"data\":\"$txtvalue\",\"ttl\":300"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#Usage: fulldomain txtvalue
|
||||
#Remove the txt record after validation.
|
||||
dns_rackcorp_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
_debug fulldomain="$fulldomain"
|
||||
_debug txtvalue="$txtvalue"
|
||||
|
||||
if ! _rackcorp_validate; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "Searching for root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
return 1
|
||||
fi
|
||||
_debug _lookup "$_lookup"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_info "Creating TXT record."
|
||||
|
||||
if ! _rackcorp_api dns.record.delete "\"name\":\"$_domain\",\"type\":\"TXT\",\"lookup\":\"$_lookup\",\"data\":\"$txtvalue\""; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
#_acme-challenge.domain.com
|
||||
#returns
|
||||
# _lookup=_acme-challenge
|
||||
# _domain=domain.com
|
||||
_get_root() {
|
||||
domain=$1
|
||||
i=1
|
||||
p=1
|
||||
if ! _rackcorp_api dns.domain.getall "\"name\":\"$domain\""; then
|
||||
return 1
|
||||
fi
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
_debug searchhost "$h"
|
||||
if [ -z "$h" ]; then
|
||||
_err "Could not find domain for record $domain in RackCorp using the provided credentials"
|
||||
#not valid
|
||||
return 1
|
||||
fi
|
||||
|
||||
_rackcorp_api dns.domain.getall "\"exactName\":\"$h\""
|
||||
|
||||
if _contains "$response" "\"matches\":1"; then
|
||||
if _contains "$response" "\"name\":\"$h\""; then
|
||||
_lookup=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain="$h"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
p=$i
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
_rackcorp_validate() {
|
||||
RACKCORP_APIUUID="${RACKCORP_APIUUID:-$(_readaccountconf_mutable RACKCORP_APIUUID)}"
|
||||
if [ -z "$RACKCORP_APIUUID" ]; then
|
||||
RACKCORP_APIUUID=""
|
||||
_err "You require a RackCorp API UUID (export RACKCORP_APIUUID=\"<api uuid>\")"
|
||||
_err "Please login to the portal and create an API key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable RACKCORP_APIUUID "$RACKCORP_APIUUID"
|
||||
|
||||
RACKCORP_APISECRET="${RACKCORP_APISECRET:-$(_readaccountconf_mutable RACKCORP_APISECRET)}"
|
||||
if [ -z "$RACKCORP_APISECRET" ]; then
|
||||
RACKCORP_APISECRET=""
|
||||
_err "You require a RackCorp API secret (export RACKCORP_APISECRET=\"<api secret>\")"
|
||||
_err "Please login to the portal and create an API key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable RACKCORP_APISECRET "$RACKCORP_APISECRET"
|
||||
|
||||
return 0
|
||||
}
|
||||
_rackcorp_api() {
|
||||
_rackcorpcmd=$1
|
||||
_rackcorpinputdata=$2
|
||||
_debug cmd "$_rackcorpcmd $_rackcorpinputdata"
|
||||
|
||||
export _H1="Accept: application/json"
|
||||
response="$(_post "{\"APIUUID\":\"$RACKCORP_APIUUID\",\"APISECRET\":\"$RACKCORP_APISECRET\",\"cmd\":\"$_rackcorpcmd\",$_rackcorpinputdata}" "$RACKCORP_API_ENDPOINT" "" "POST")"
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error $response"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
if _contains "$response" "\"code\":\"OK\""; then
|
||||
_debug code "OK"
|
||||
else
|
||||
_debug code "FAILED"
|
||||
response=""
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
49
notify/telegram.sh
Normal file
49
notify/telegram.sh
Normal file
@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Support Telegram Bots
|
||||
|
||||
#TELEGRAM_BOT_APITOKEN=""
|
||||
#TELEGRAM_BOT_CHATID=""
|
||||
|
||||
telegram_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
TELEGRAM_BOT_APITOKEN="${TELEGRAM_BOT_APITOKEN:-$(_readaccountconf_mutable TELEGRAM_BOT_APITOKEN)}"
|
||||
if [ -z "$TELEGRAM_BOT_APITOKEN" ]; then
|
||||
TELEGRAM_BOT_APITOKEN=""
|
||||
_err "You didn't specify a Telegram BOT API Token TELEGRAM_BOT_APITOKEN yet."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable TELEGRAM_BOT_APITOKEN "$TELEGRAM_BOT_APITOKEN"
|
||||
|
||||
TELEGRAM_BOT_CHATID="${TELEGRAM_BOT_CHATID:-$(_readaccountconf_mutable TELEGRAM_BOT_CHATID)}"
|
||||
if [ -z "$TELEGRAM_BOT_CHATID" ]; then
|
||||
TELEGRAM_BOT_CHATID=""
|
||||
_err "You didn't specify a Telegram Chat id TELEGRAM_BOT_CHATID yet."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable TELEGRAM_BOT_CHATID "$TELEGRAM_BOT_CHATID"
|
||||
|
||||
_content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)"
|
||||
_data="{\"text\": \"$_content\", "
|
||||
_data="$_data\"chat_id\": \"$TELEGRAM_BOT_CHATID\", "
|
||||
_data="$_data\"parse_mode\": \"markdown\", "
|
||||
_data="$_data\"disable_web_page_preview\": \"1\"}"
|
||||
|
||||
export _H1="Content-Type: application/json"
|
||||
_telegram_bot_url="https://api.telegram.org/bot${TELEGRAM_BOT_APITOKEN}/sendMessage"
|
||||
if _post "$_data" "$_telegram_bot_url"; then
|
||||
# shellcheck disable=SC2154
|
||||
_message=$(printf "%s\n" "$response" | sed -n 's/.*"ok":\([^,]*\).*/\1/p')
|
||||
if [ "$_message" = "true" ]; then
|
||||
_info "telegram send success."
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
_err "telegram send error."
|
||||
_err "$response"
|
||||
return 1
|
||||
}
|
Loading…
Reference in New Issue
Block a user