mirror of
				https://github.com/hiskang/acme.sh
				synced 2025-10-30 18:07:15 +00:00 
			
		
		
		
	Merge pull request #45 from Neilpang/dnsapi
support CloudFlare api for dns-01 challenge.
This commit is contained in:
		
						commit
						bda6909d53
					
				
							
								
								
									
										158
									
								
								dnsapi/dns-cf.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										158
									
								
								dnsapi/dns-cf.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,158 @@ | ||||
| #!/bin/bash | ||||
| 
 | ||||
| 
 | ||||
| # | ||||
| #CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" | ||||
| # | ||||
| #CF_Email="xxxx@sss.com" | ||||
| 
 | ||||
| 
 | ||||
| CF_Api="https://api.cloudflare.com/client/v4/" | ||||
| 
 | ||||
| ########  Public functions ##################### | ||||
| 
 | ||||
| #Usage: add  _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" | ||||
| dns-cf-add() { | ||||
|   fulldomain=$1 | ||||
|   txtvalue=$2 | ||||
|    | ||||
|   _debug "First detect the root zone" | ||||
|   if ! _get_root $fulldomain ; then | ||||
|     _err "invalid domain" | ||||
|     return 1 | ||||
|   fi | ||||
|    | ||||
|   _debug "Getting txt records" | ||||
|   _cf_rest GET "/zones/$_domain_id/dns_records?type=TXT&name=$fulldomain" | ||||
|    | ||||
|   if [ "$?" != "0" ] || ! printf $response | grep \"success\":true > /dev/null ; then | ||||
|     _err "Error" | ||||
|     return 1 | ||||
|   fi | ||||
|    | ||||
|   count=$(printf $response | grep -o \"count\":[^,]* | cut -d : -f 2) | ||||
|    | ||||
|   if [ "$count" == "0" ] ; then | ||||
|     _info "Adding record" | ||||
|     if _cf_rest POST "/zones/$_domain_id/dns_records"  "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then | ||||
|       if printf $response | grep $fulldomain > /dev/null ; then | ||||
|         _info "Added, sleeping 10 seconds" | ||||
|         sleep 10 | ||||
|         #todo: check if the record takes effect | ||||
|         return 0 | ||||
|       else | ||||
|         _err "Add txt record error." | ||||
|         return 1 | ||||
|       fi | ||||
|     fi | ||||
|     _err "Add txt record error." | ||||
|   else | ||||
|     _info "Updating record" | ||||
|     record_id=$(printf $response | grep -o \"id\":\"[^\"]*\" | cut -d : -f 2 | tr -d \") | ||||
|     _debug "record_id" $record_id | ||||
|      | ||||
|     _cf_rest PUT "/zones/$_domain_id/dns_records/$record_id"  "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"zone_name\":\"$_domain\"}" | ||||
|     if [ "$?" == "0" ]; then | ||||
|       _info "Updated, sleeping 10 seconds" | ||||
|       sleep 10 | ||||
|       #todo: check if the record takes effect | ||||
|       return 0; | ||||
|     fi | ||||
|     _err "Update error" | ||||
|     return 1 | ||||
|   fi | ||||
|    | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ####################  Private functions bellow ################################## | ||||
| #_acme-challenge.www.domain.com | ||||
| #returns | ||||
| # _sub_domain=_acme-challenge.www | ||||
| # _domain=domain.com | ||||
| # _domain_id=sdjkglgdfewsdfg | ||||
| _get_root() { | ||||
|   domain=$1 | ||||
|   i=2 | ||||
|   p=1 | ||||
|   while [ '1' ] ; do | ||||
|     h=$(printf $domain | cut -d . -f $i-100) | ||||
|     if [ -z "$h" ] ; then | ||||
|       #not valid | ||||
|       return 1; | ||||
|     fi | ||||
|      | ||||
|     if ! _cf_rest GET "zones?name=$h" ; then | ||||
|       return 1 | ||||
|     fi | ||||
|      | ||||
|     if printf $response | grep \"name\":\"$h\" ; then | ||||
|       _domain_id=$(printf $response | grep -o \"id\":\"[^\"]*\" | cut -d : -f 2 | tr -d \") | ||||
|       if [ "$_domain_id" ] ; then | ||||
|         _sub_domain=$(printf $domain | cut -d . -f 1-$p) | ||||
|         _domain=$h | ||||
|         return 0 | ||||
|       fi | ||||
|       return 1 | ||||
|     fi | ||||
|     p=$i | ||||
|     let "i+=1" | ||||
|   done | ||||
|   return 1 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| _cf_rest() { | ||||
|   m=$1 | ||||
|   ep="$2" | ||||
|   _debug $ep | ||||
|   if [ "$3" ] ; then | ||||
|     data="$3" | ||||
|     _debug data "$data" | ||||
|     response="$(curl --silent -X $m "$CF_Api/$ep" -H "X-Auth-Email: $CF_Email" -H "X-Auth-Key: $CF_Key" -H "Content-Type: application/json" --data $data)" | ||||
|   else | ||||
|     response="$(curl --silent -X $m "$CF_Api/$ep" -H "X-Auth-Email: $CF_Email" -H "X-Auth-Key: $CF_Key" -H "Content-Type: application/json")" | ||||
|   fi | ||||
|    | ||||
|   if [ "$?" != "0" ] ; then | ||||
|     _err "error $ep" | ||||
|     return 1 | ||||
|   fi | ||||
|   _debug response "$response" | ||||
|   return 0 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| _debug() { | ||||
| 
 | ||||
|   if [ -z "$DEBUG" ] ; then | ||||
|     return | ||||
|   fi | ||||
|    | ||||
|   if [ -z "$2" ] ; then | ||||
|     echo $1 | ||||
|   else | ||||
|     echo "$1"="$2" | ||||
|   fi | ||||
| } | ||||
| 
 | ||||
| _info() { | ||||
|   if [ -z "$2" ] ; then | ||||
|     echo "$1" | ||||
|   else | ||||
|     echo "$1"="$2" | ||||
|   fi | ||||
| } | ||||
| 
 | ||||
| _err() { | ||||
|   if [ -z "$2" ] ; then | ||||
|     echo "$1" >&2 | ||||
|   else | ||||
|     echo "$1"="$2" >&2 | ||||
|   fi | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										55
									
								
								le.sh
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								le.sh
									
									
									
									
									
								
							| @ -321,7 +321,6 @@ _initpath() { | ||||
|     CA_CERT_PATH="$WORKING_DIR/$domain/ca.cer" | ||||
|   fi | ||||
|    | ||||
|    | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| @ -619,12 +618,49 @@ issue() { | ||||
|         _debug txt "$txt" | ||||
|         #dns | ||||
|         #1. check use api | ||||
|         d_api="" | ||||
|         if [ -f "$WORKING_DIR/$d/$Le_Webroot" ] ; then | ||||
|           d_api="$WORKING_DIR/$d/$Le_Webroot" | ||||
|         elif [ -f "$WORKING_DIR/$d/$Le_Webroot.sh" ] ; then | ||||
|           d_api="$WORKING_DIR/$d/$Le_Webroot.sh" | ||||
|         elif [ -f "$WORKING_DIR/$Le_Webroot" ] ; then | ||||
|           d_api="$WORKING_DIR/$Le_Webroot" | ||||
|         elif [ -f "$WORKING_DIR/$Le_Webroot.sh" ] ; then | ||||
|           d_api="$WORKING_DIR/$Le_Webroot.sh" | ||||
|         elif [ -f "$WORKING_DIR/dnsapi/$Le_Webroot" ] ; then | ||||
|           d_api="$WORKING_DIR/dnsapi/$Le_Webroot" | ||||
|         elif [ -f "$WORKING_DIR/dnsapi/$Le_Webroot.sh" ] ; then | ||||
|           d_api="$WORKING_DIR/dnsapi/$Le_Webroot.sh" | ||||
|         fi | ||||
|         _debug d_api "$d_api" | ||||
|          | ||||
|         if [ "$d_api" ]; then | ||||
|           _info "Found domain api file: $d_api" | ||||
|         else | ||||
|           _err "Add the following TXT record:" | ||||
|           _err "Domain: $txtdomain" | ||||
|           _err "TXT value: $txt" | ||||
|           _err "Please be aware that you prepend _acme-challenge. before your domain" | ||||
|           _err "so the resulting subdomain will be: $txtdomain" | ||||
|         #dnsadded='1' | ||||
|           continue | ||||
|         fi | ||||
| 
 | ||||
|         if ! source $d_api ; then | ||||
|           _err "Load file $d_api error. Please check your api file and try again." | ||||
|           return 1 | ||||
|         fi | ||||
|          | ||||
|         addcommand="$Le_Webroot-add" | ||||
|         if ! command -v $addcommand ; then  | ||||
|           _err "It seems that your api file is not correct, it must have a function named: $Le_Webroot" | ||||
|           return 1 | ||||
|         fi | ||||
|          | ||||
|         if ! $addcommand $txtdomain $txt ; then | ||||
|           _err "Error add txt for domain:$txtdomain" | ||||
|           return 1 | ||||
|         fi | ||||
|         dnsadded='1' | ||||
|       fi | ||||
|     done | ||||
| 
 | ||||
| @ -637,6 +673,10 @@ issue() { | ||||
|      | ||||
|   fi | ||||
|    | ||||
|   if [ "$dnsadded" == '1' ] ; then | ||||
|     _info "Sleep 60 seconds for the txt records to take effect" | ||||
|     sleep 60 | ||||
|   fi | ||||
|    | ||||
|   _debug "ok, let's start to verify" | ||||
|   ventries=$(echo "$vlist" | sed "s/,/ /g") | ||||
| @ -806,13 +846,17 @@ renew() { | ||||
| 
 | ||||
|   _initpath $Le_Domain | ||||
| 
 | ||||
|   if [ -f "$DOMAIN_CONF" ] ; then | ||||
|   if [ ! -f "$DOMAIN_CONF" ] ; then | ||||
|     _err "$Le_Domain is not a issued domain, skip." | ||||
|     return 1; | ||||
|   fi | ||||
|    | ||||
|   source "$DOMAIN_CONF" | ||||
|   if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(date -u "+%s" )" -lt "$Le_NextRenewTime" ] ; then  | ||||
|     _info "Skip, Next renewal time is: $Le_NextRenewTimeStr" | ||||
|     return 2 | ||||
|   fi | ||||
|   fi | ||||
|    | ||||
|   IS_RENEW="1" | ||||
|   issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" | ||||
|   IS_RENEW="" | ||||
| @ -993,6 +1037,9 @@ install() { | ||||
|   rm -f $WORKING_DIR/le | ||||
|   ln -s $WORKING_DIR/le.sh  $WORKING_DIR/le | ||||
| 
 | ||||
|   mkdir -p $WORKING_DIR/dnsapi | ||||
|   cp  dnsapi/* $WORKING_DIR/dnsapi/ | ||||
|    | ||||
|   installcronjob | ||||
|    | ||||
|   _info OK | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user