Browse Source

Yandex DNS script added

pull/861/head
Maksim Gaidai 1 year ago
parent
commit
df38d77ce5
3 changed files with 196 additions and 2 deletions
  1. +45
    -0
      dns_scripts/Yandex-README.md
  2. +144
    -0
      dns_scripts/dns_yandex
  3. +7
    -2
      getssl

+ 45
- 0
dns_scripts/Yandex-README.md View File

@ -0,0 +1,45 @@
# Yandex DNS management via Yandex API
## Requrements
- [JQ](https://jqlang.github.io/jq/) command-line JSON processor needed
## Useful links
- [Yandex API Access](https://yandex.ru/dev/api360/doc/concepts/access.html)
- [Yandex DNS API](https://yandex.ru/dev/api360/doc/ref/DomainDNSService.html)
## Yandex Auth parameters in domain config file
0. Authorize in Your Yandex Account in web browser. You must have Administartor rights
1. Get `OrgId` from Your Comapny Profile - <https://admin.yandex.ru/company-profile> (You have Your first important variable `YANDEX_ORGID` now!)
2. Create Your new application for DNS management - <https://oauth.yandex.ru/client/new/id>
3. Get `ClientID` for this application on application page
4. Get `OAuthToken` for this application from URL <https://oauth.yandex.ru/authorize?response_type=token&client_id=ClientID> in authtorised browser where `ClientID` code from previous step. This is Your second secret variable `YANDEX_OAUTH`!
5. Define this variables in domain config file
```bash
# Use the following 3 variables if you want to validate via DNS
VALIDATE_VIA_DNS="true"
DNS_ADD_COMMAND="/usr/share/getssl/dns_scripts/dns_yandex add"
DNS_DEL_COMMAND="/usr/share/getssl/dns_scripts/dns_yandex del"
DNS_WAIT="600" # Waiting 10 minutes. Very-very-very slow distrbution
# Yandex base DNS
AUTH_DNS_SERVER="77.88.8.8"
# Yandex Authentication credintals
export YANDEX_ORGID="<OrgId>"
export YANDEX_OAUTH="<OAuthToken>"
```
## Manual run
- `/usr/share/getssl/dns_scripts/dns_yandex add domain.tld <token>` - add `<token> TXT _acme-challenge.domain.tld` record
- `/usr/share/getssl/dns_scripts/dns_yandex add subdomain.domain.tld <token>` - add `<token> TXT _acme-challenge.subdomain.domain.tld` record
- `/usr/share/getssl/dns_scripts/dns_yandex del domain.tld <token>` - delete `<token> TXT _acme-challenge.domain.tld` record
- `/usr/share/getssl/dns_scripts/dns_yandex del subdomain.domain.tld <token>` - delete `<token> TXT _acme-challenge.subdomain.domain.tld` record
- `/usr/share/getssl/dns_scripts/dns_yandex cleanup domain.tld` - cleanup all dangling `_acme-challenge` records from DNS for <domain.tld>
- `/usr/share/getssl/dns_scripts/dns_yandex cleanup subdomain.domain.tld` - cleanup all dangling `_acme-challenge.subdomain` records from DNS for <subdomain.domain.tld>
- `/usr/share/getssl/dns_scripts/dns_yandex cleanup [subdomain.]domain.tld <token>` - cleanup all dangling `_acme-challenge` domain or subdomain records with `<token>`

+ 144
- 0
dns_scripts/dns_yandex View File

@ -0,0 +1,144 @@
#!/bin/bash
### Functions
check() { # Verify that required parameters are set
IFS=$'\n'
for var in ${check_vars[@]}; do
var_name=$(echo $var | awk -F, '{ print $1 }')
err_msg=$( echo $var | awk -F, '{ print $2 }')
[ -z "${!var_name}" ] && error_exit "variable '${var_name}' empty. Error:$err_msg"
done
}
add() { # Add challenge domain to DNS
debug "create domain '$acme_domain'"
response=`curl --silent \
-X POST https://api360.yandex.net/directory/v1/org/${orgId}/domains/${domain}/dns \
-H "Authorization: OAuth ${OAuth}" \
-H "Content-Type: application/json" \
-d '{"name":"'"$acme_domain"'","type":"TXT","ttl":"3600","text":"'"$token"'"}'`
debug "Asked record: {\"name\":\"$acme_domain\",\"type\":\"TXT\",\"ttl\":\"3600\",\"text\":\"$token\"}"
debug "Recieved response: \"$response\""
recordId=$(echo $response | jq .recordId)
if [ "$recordId" != "null" ]; then
# Save recordId for cleanup later
mkdir -p -m 0700 $(dirname $recordIdFile)
echo $response >> $recordIdFile
debug "File '$recordIdFile' created/updated:\n$(sed -E '/^#/d;/^\s*$/d' $recordIdFile)"
else
err_code=$(echo $response | jq .code)
err_message=$(echo $response | jq .message)
error_exit "error code: $err_code -- $err_message"
fi
}
del() { # Delete all or specific challenge domains from DNS
if [[ "$1" == "cleanup" ]]; then # Cleanup records for specific domain
if [ -z "$subdomain" ]; then # Delete all records for domain if 'domain.tld' specimied
# Get ALL recordIDs from file
debug "all '$domain' domain records will be removed"
recordIds=`sed -E '/^#/d;/^\s*$/d' $recordIdFile | jq .recordId`
else # Delete all records for specific subdomain only if 'subdomain.domain.tld' specified
# Get ALL recordIDs from file for specific domain
debug "all '$acme_domain' domain records will be removed"
recordIds=`sed -E '/^#/d;/^\s*$/d' $recordIdFile | jq "select(.name == \"$acme_domain\") | .recordId"`
fi
else # Delete specific records for specific domain or subdomain specified challenge token
# Get specific combinations of domain and token
debug "'$acme_domain' domain records with token '$token' will be removed"
recordIds=`sed -E '/^#/d;/^\s*$/d' $recordIdFile | jq "select(.name == \"$acme_domain\" and .text == \"$token\") | .recordId"`
fi
# Check selected exist records
[ -z "$recordIds" ] && error_exit "can't parse '$recordIdFile' file or matched recordIds not found"
# Delete selected records if exist
unset not_removed
for recordId in $recordIds; do
debug "removeing record '$recordId'"
del_result=`curl -H "Authorization: OAuth ${OAuth}" --silent \
-X DELETE https://api360.yandex.net/directory/v1/org/${orgId}/domains/${domain}/dns/${recordId}`
if [ "$del_result" == "{}" ]; then
sed -i "/$recordId/d" $recordIdFile # Remove record from file if it was removed from DNS
unset del_msg
else
not_removed=${not_removed:+$not_removed, }$recordId
del_msg=' NOT'
fi
debug "'$recordId' was$rm_msg removed from DNS and file '$recordIdFile'"
done
[ -n "$not_removed" ] && error_exit "Something went wrong. Server says: '$del_result' This records was NOT removed: '$not_removed'"
}
### Requires
requires jq
### Presets
# Yandex Authentication credintals
orgId=${YANDEX_ORGID:-''}
OAuth=${YANDEX_OAUTH:-''}
# Let's Encrypt DNS validtaion token
token=$3
# Split FQDN to domain and subdomain. Specific for Yandex API
fqdn=`echo $2 | grep -Po '^(?:(?!-)[a-z0-9-]{0,62}[a-z0-9]\.)+[a-z]{2,}$'`
domain=`echo $fqdn | grep -Po '(?!-)[a-z0-9-]{0,62}[a-z0-9]\.[a-z]{2,}$'`
subdomain=`echo $fqdn | sed -E 's/(\.?[^.]+){2}$//'`
acme_domain="_acme-challenge${subdomain:+.$subdomain}"
recordIdFile=${WORKING_DIR:-/tmp}/getssl_yandex_dns_records
debug "FQDN: '$fqdn'
Validation token: '$token'
Asked domain: '$domain'
Asked subdomain: '$subdomain'
Record ID file: '$recordIdFile'"
# Yandex API returns JSON with recordId as successful result
# It's required for remove this record later. Yandex API cant't remove records by names, by recordId only
[ -f "$recordIdFile" ] || echo -n "
# DON'T EDIT! DON'T DELETE!
# This is active Yandex DNS challenge records
# Don't remove manually
# Just run \`$(cd "$(dirname "$0")" || exit; pwd -P;) cleanup [subdomain.]domain.tld\`
" > "$recordIdFile"
### Main process
case "$1" in
"add" )
check_vars=(
"fqdn, No or invalid FQDN"
"domain, No or invalid DOMAIN"
"token, No challenge token"
"orgId, No Yandex OrgID"
"OAuth, No Yandex OAuth"
)
check
add
;;
"del" )
check_vars=(
"domain, No or invalid DOMAIN"
"token, No challenge token"
"orgId, No Yandex OrgID"
"OAuth, No Yandex OAuth"
)
check
del
;;
"cleanup" )
check_vars=(
"domain, No or invalid DOMAIN"
"orgId, No Yandex OrgID"
"OAuth, No Yandex OAuth"
)
check
del cleanup
;;
* )
echo "Unknown command '$1'. Valid commands: (add|del|cleanup)"
;;
esac

+ 7
- 2
getssl View File

@ -972,6 +972,7 @@ clean_up() { # Perform pre-exit housekeeping
fi
fi
}
export -f clean_up # for use in DNS scripts
copy_file_to_location() { # copies a file, using scp, sftp or ftp if required.
cert=$1 # descriptive name, just used for display
@ -1297,6 +1298,7 @@ debug() { # write out debug info if the debug flag has been set
fi
fi
}
export -f debug # for use in DNS scripts
error_exit() { # give error message on error exit
echo -e "${PROGNAME}: ${1:-"Unknown Error"}" >&2
@ -1306,6 +1308,7 @@ error_exit() { # give error message on error exit
clean_up
exit 1
}
export -f error_exit # for use in DNS scripts
find_dns_utils() {
HAS_NSLOOKUP=false
@ -1365,7 +1368,7 @@ add_dns_rr() {
# shellcheck disable=SC2018,SC2019
lower_d=$(printf '%s' "${d#\*.}" | tr 'A-Z' 'a-z')
debug "adding DNS RR via command: ${DNS_ADD_COMMAND} ${lower_d} ${auth_key}"
eval "${DNS_ADD_COMMAND}" "${lower_d}" "${auth_key}"
eval "PROGNAME=$PROGNAME _USE_DEBUG=$_USE_DEBUG WORKING_DIR=$WORKING_DIR ${DNS_ADD_COMMAND}" "${lower_d}" "${auth_key}"
}
del_dns_rr() {
@ -1375,7 +1378,7 @@ del_dns_rr() {
# shellcheck disable=SC2018,SC2019
lower_d=$(printf '%s' "${d#\*.}" | tr 'A-Z' 'a-z')
debug "removing DNS RR via command: ${DNS_DEL_COMMAND} ${lower_d} ${auth_key}"
eval "${DNS_DEL_COMMAND}" "${lower_d}" "${auth_key}"
eval "PROGNAME=$PROGNAME _USE_DEBUG=$_USE_DEBUG WORKING_DIR=$WORKING_DIR ${DNS_DEL_COMMAND}" "${lower_d}" "${auth_key}"
}
fulfill_challenges() {
@ -2437,6 +2440,7 @@ requires() { # check if required function is available
fi
fi
}
export -f requires # for use in DNS scripts
set_server_type() { # uses SERVER_TYPE to set REMOTE_PORT and REMOTE_EXTRA
if [[ ${SERVER_TYPE} == "https" ]] || [[ ${SERVER_TYPE} == "webserver" ]]; then
@ -2679,6 +2683,7 @@ traceback() { # Print function traceback
done
return 0
}
export -f traceback # for use in DNS scripts
urlbase64() { # urlbase64: base64 encoded string with '+' replaced with '-' and '/' replaced with '_'
openssl base64 -e | tr -d '\n\r' | os_esed -e 's:=*$::g' -e 'y:+/:-_:'


Loading…
Cancel
Save