Browse Source
Create dns_cpanel.sh
Create dns_cpanel.sh
New DNS method used for DNS-01 verify requests against cPanel controlled domains.pull/1092/head
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 281 additions and 0 deletions
@ -0,0 +1,281 @@ |
|||
#!/usr/bin/env bash |
|||
|
|||
#This is a dns hook for cpanel |
|||
#This file name is "dns_cpanel.sh" |
|||
#This hook is compatible with cpdyndns from https://forums.cpanel.net/threads/can-cpanel-update-dynamic-ip-information-to-dns-records.261951/ |
|||
# cpdyndns is not required, but this was designed to update a domain on a dd-wrt router to a cpanel hosted public domain. It may work elsewhere |
|||
# test and use at your own peril. |
|||
#returns 0 means success, otherwise error. |
|||
# |
|||
#Author: smithec |
|||
#Report Bugs here: https://github.com/Neilpang/acme.sh |
|||
# |
|||
#Tested on DD-WRT, Linux Mint 18 |
|||
# |
|||
# This is released without ANY warranty or guarantee of use. USE THIS AT YOUR OWN RISK. |
|||
# Your use of this API signifies an agreement to hold blameless the developers for any results or damages that may occur to you or to others. |
|||
# Always backup your data files and cPanel zones prior to using any tool that you allow to make edits. |
|||
|
|||
######## Public functions ##################### |
|||
|
|||
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
|||
dns_cpanel_add() { |
|||
fulldomain="$1" |
|||
txtvalue="$2" |
|||
_info "Using cPanel add" |
|||
_debug fulldomain: "$fulldomain" |
|||
_debug txtvalue: "$txtvalue" |
|||
_get_root |
|||
_setup_vars |
|||
_setup_timeout |
|||
_load_config |
|||
_check_config |
|||
_generate_auth_string |
|||
|
|||
REQUEST="GET /xml-api/cpanel?cpanel_xmlapi_module=ZoneEdit&cpanel_xmlapi_func=add_zone_record&cpanel_xmlapi_apiversion=2&domain=$_domain&name=$_sub_domain&type=TXT&txtdata=$txtvalue&ttl=300 HTTP/1.0\r\nConnection: close\r\nAuthorization: Basic $AUTH_STRING\r\nUser-Agent: $USERAGENT $VERSION\r\n\r\n\r\n" |
|||
RESULT=`echo -e "$REQUEST" | openssl s_client -quiet -connect $CPANEL_SERVER:2083 2>&1` |
|||
_check_results_for_error "$RESULT" "$REQUEST" |
|||
_terminate |
|||
return 1 |
|||
} |
|||
|
|||
#Usage: fulldomain txtvalue |
|||
#Remove the txt record after validation. |
|||
dns_cpanel_rm() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
_info "Using cpanel rm" |
|||
_debug fulldomain "$fulldomain" |
|||
_debug txtvalue "$txtvalue" |
|||
_get_root |
|||
_setup_vars |
|||
_setup_timeout |
|||
_load_config |
|||
_check_config |
|||
_generate_auth_string |
|||
|
|||
_retreive_zone |
|||
_parse_zone_lines |
|||
} |
|||
|
|||
#################### Private functions below ################################## |
|||
|
|||
#_acme-challenge.www.domain.com |
|||
#returns |
|||
# _sub_domain=_acme-challenge.www |
|||
# _domain=domain.com |
|||
_get_root() { |
|||
_debug "IN _get_root()" |
|||
domain="$fulldomain" |
|||
i=3 |
|||
p=2 |
|||
_domain=$(printf "$domain" | cut -d . -f $i-100) |
|||
_sub_domain=$(printf "$domain" | cut -d . -f 1-$p) |
|||
_debug domain "$_domain" |
|||
_debug subdomain "$_sub_domain" |
|||
_debug "OUT _get_root()" |
|||
} |
|||
|
|||
# This loads a pre-existing config file from cpdyndns |
|||
# your config file should be located at ~/etc/cpdyndns.conf |
|||
# a proper file will contain: |
|||
#CONTACT_EMAIL="my_email_here@cpanel.net" |
|||
#CPANEL_SERVER="my_server_here.cpanel.net" |
|||
#DOMAIN="my_domain_here.tld" |
|||
#SUBDOMAIN="my_subdomain_here" |
|||
#CPANEL_USER="my_username_here" |
|||
#CPANEL_PASS="my_password_here" |
|||
_load_config () |
|||
{ |
|||
if [ -e "/etc/$BASEDIR.conf" ]; then |
|||
chmod 0600 /etc/$BASEDIR.conf |
|||
. /etc/$BASEDIR.conf |
|||
_debug "== /etc/$BASEDIR.conf is being used for configuration" |
|||
else |
|||
_debug "== /etc/$BASEDIR.conf does not exist" |
|||
fi |
|||
if [ -e "$HOMEDIR/etc/$BASEDIR.conf" ]; then |
|||
chmod 0600 $HOMEDIR/etc/$BASEDIR.conf |
|||
. $HOMEDIR/etc/$BASEDIR.conf |
|||
_debug "== $HOMEDIR/etc/$BASEDIR.conf is being used for configuration" |
|||
else |
|||
_debug "== $HOMEDIR/etc/$BASEDIR.conf does not exist" |
|||
fi |
|||
} |
|||
|
|||
#Prime needed Variables |
|||
#These are meant to be compatible with cpdyndns/cpanel-dynamic-dns.sh |
|||
#You can use the CPANEL Values here, but this is designed to use a config file see _load_config() |
|||
_setup_vars () |
|||
{ |
|||
USERAGENT="acme.sh/dns_cpanel.sh" |
|||
VERSION="0.1" |
|||
APINAME="" |
|||
PARENTPID=$$ |
|||
HOMEDIR=`echo ~` |
|||
TIMEOUT="300" |
|||
BASEDIR="cpdyndns" |
|||
CPANEL_SERVER="" |
|||
CPANEL_USER="" |
|||
CPANEL_PASS="" |
|||
} |
|||
|
|||
_exit_timeout () |
|||
{ |
|||
ALARMPID="" |
|||
_err "Timeout while connecting to $LAST_CONNECT_HOST" |
|||
exit |
|||
} |
|||
|
|||
_setup_timeout () |
|||
{ |
|||
(sleep $TIMEOUT; kill -ALRM $PARENTPID) & |
|||
ALARMPID=$! |
|||
trap exit_timeout SIGALRM |
|||
} |
|||
|
|||
#Generate an Authentication String for cPanel |
|||
_generate_auth_string () { |
|||
AUTH_STRING=`echo -n "$CPANEL_USER:$CPANEL_PASS" | openssl enc -base64` |
|||
} |
|||
|
|||
#verify our configuration |
|||
_check_config () { |
|||
if [ -z "$CPANEL_SERVER" ]; then |
|||
_err "= Error: CPANEL_SERVER must be set in a configuration file" |
|||
exit |
|||
fi |
|||
if [ -z "$CPANEL_USER" ]; then |
|||
_err "= Error: CPANEL_USER must be set in a configuration file" |
|||
exit |
|||
fi |
|||
if [ -z "$CPANEL_PASS" ]; then |
|||
_err "= Error: CPANEL_PASS must be set in a configuration file" |
|||
exit |
|||
fi |
|||
} |
|||
|
|||
_terminate () { |
|||
if [ -z "$ALARMPID" ]; then |
|||
kill $ALARMPID |
|||
fi |
|||
exit |
|||
} |
|||
|
|||
_retreive_zone(){ |
|||
_info "In _retreive_zone" |
|||
_debug "matching for: TXT $_sub_domain.$_domain." |
|||
REQUEST="GET /xml-api/cpanel?cpanel_xmlapi_module=ZoneEdit&cpanel_xmlapi_func=fetchzone&cpanel_xmlapi_apiversion=2&domain=$DOMAIN HTTP/1.0\r\nConnection: close\r\nAuthorization: Basic $AUTH_STRING\r\nUser-Agent: cpanel-dynamic-dns.sh $VERSION\r\n\r\n\r\n" |
|||
RECORD="" |
|||
LINES="" |
|||
INRECORD=0 |
|||
USETHISRECORD=0 |
|||
REQUEST_RESULTS=`echo -e "$REQUEST" | openssl s_client -quiet -connect $CPANEL_SERVER:2083 2>/dev/null` |
|||
|
|||
_check_results_for_error "$REQUEST_RESULTS" "$REQUEST" |
|||
for LINE in $REQUEST_RESULTS |
|||
do |
|||
#_debug "$LINE" |
|||
if [ "$LINE" == "<record>" ]; then |
|||
INRECORD=1 |
|||
continue |
|||
fi |
|||
if [ "$LINE" == "</record>" ]; then |
|||
INRECORD=0 |
|||
if [ "$USETHISRECORD" == "2" ]; then |
|||
LINENUM=`echo -e "$RECORD" | grep '<Line>' | awk -F'<' '{print \$2}' | awk -F'>' '{print \$2}'` |
|||
TXT=`echo -e "$RECORD" | grep -i '<txtdata>' | awk -F'<' '{print \$2}' | awk -F'>' '{print \$2}'` |
|||
LINES="$LINES\n$LINENUM=$TXT" |
|||
fi |
|||
USETHISRECORD=0 |
|||
RECORD="" |
|||
continue |
|||
fi |
|||
if [ "$LINE" == "<type>TXT</type>" ]; then |
|||
_debug "Match TXT" |
|||
USETHISRECORD=`expr $USETHISRECORD + 1` |
|||
fi |
|||
if [ "$LINE" == "<name>$_sub_domain.$_domain.</name>" ]; then |
|||
_debug "Match Domain" |
|||
USETHISRECORD=`expr $USETHISRECORD + 1` |
|||
fi |
|||
if [ "$INRECORD" == "1" ]; then |
|||
RECORD="$RECORD\n$LINE" |
|||
fi |
|||
done |
|||
} |
|||
|
|||
_parse_zone_lines(){ |
|||
#_info "In _parse_zone_lines" |
|||
#_debug "$LINES" |
|||
for LINE in `echo -e $LINES` |
|||
do |
|||
_debug "Removing Validation TXT" |
|||
LINENUM=`echo $LINE | awk -F= '{print $1}'` |
|||
REQUEST="GET /xml-api/cpanel?cpanel_xmlapi_module=ZoneEdit&cpanel_xmlapi_func=remove_zone_record&cpanel_xmlapi_apiversion=2&domain=$DOMAIN&line=$LINENUM HTTP/1.0\r\nConnection: close\r\nAuthorization: Basic $AUTH_STRING\r\nUser-Agent: cpanel-dynamic-dns.sh $VERSION\r\n\r\n\r\n" |
|||
RESULT=`echo -e "$REQUEST" | openssl s_client -quiet -connect $CPANEL_SERVER:2083 2>&1` |
|||
_check_results_for_error "$RESULT" "$REQUEST" |
|||
done |
|||
} |
|||
|
|||
_check_results_for_error () |
|||
{ |
|||
REQUEST_RESULTS="$1" |
|||
REQUEST="$2" |
|||
if [ "`echo $REQUEST_RESULTS | grep '<status>1</status>'`" ]; then |
|||
if [ "$QUIET" != "1" ]; then |
|||
echo -n "success..." |
|||
fi |
|||
else |
|||
INREASON=0 |
|||
INSTATUSMSG=0 |
|||
MSG="" |
|||
STATUSMSG="" |
|||
|
|||
for LINE in $REQUEST_RESULTS |
|||
do |
|||
if [ "`echo $LINE | grep '<reason>'`" != "" ]; then |
|||
INREASON=1 |
|||
INSTATUSMSG=0 |
|||
MSG=`echo $LINE | awk -F'>' '{print \$2}'` |
|||
continue |
|||
fi |
|||
if [ "`echo $LINE | grep '</reason>'`" != "" ]; then |
|||
INREASON=0 |
|||
MSGADD=`echo $LINE | awk -F'<' '{print \$1}'` |
|||
MSG="$MSG $MSGADD" |
|||
continue |
|||
fi |
|||
if [ "`echo $LINE | grep '<statusmsg>'`" != "" ]; then |
|||
INSTATUSMSG=1 |
|||
INREASON=0 |
|||
STATUSMSG=`echo $LINE | awk -F'>' '{print \$2}'` |
|||
continue |
|||
fi |
|||
if [ "`echo $LINE | grep '</statusmsg>'`" != "" ]; then |
|||
INSTATUSMSG=0 |
|||
MSGADD=`echo $LINE | awk -F'<' '{print \$1}'` |
|||
STATUSMSG="$STATUSMSG $MSGADD" |
|||
continue |
|||
fi |
|||
if [ "$INREASON" -eq "1" ]; then |
|||
MSG="$MSG $LINE" |
|||
fi |
|||
if [ "$INSTATUSMSG" -eq "1" ]; then |
|||
STATUSMSG="$STATUSMSG $LINE" |
|||
fi |
|||
|
|||
done |
|||
|
|||
if [ -z "$MSG" ]; then |
|||
MSG="Unknown Error" |
|||
if [ -z "$STATUSMSG" ]; then |
|||
STATUSMSG="Please make sure you have the zoneedit, or simplezone edit permission on your account." |
|||
fi |
|||
fi |
|||
|
|||
_err "Request failed with error: $MSG ($STATUSMSG)" |
|||
|
|||
_terminate |
|||
fi |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue