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" |     CA_CERT_PATH="$WORKING_DIR/$domain/ca.cer" | ||||||
|   fi |   fi | ||||||
|    |    | ||||||
|    |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -619,12 +618,49 @@ issue() { | |||||||
|         _debug txt "$txt" |         _debug txt "$txt" | ||||||
|         #dns |         #dns | ||||||
|         #1. check use api |         #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 "Add the following TXT record:" | ||||||
|           _err "Domain: $txtdomain" |           _err "Domain: $txtdomain" | ||||||
|           _err "TXT value: $txt" |           _err "TXT value: $txt" | ||||||
|           _err "Please be aware that you prepend _acme-challenge. before your domain" |           _err "Please be aware that you prepend _acme-challenge. before your domain" | ||||||
|           _err "so the resulting subdomain will be: $txtdomain" |           _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 |       fi | ||||||
|     done |     done | ||||||
| 
 | 
 | ||||||
| @ -637,6 +673,10 @@ issue() { | |||||||
|      |      | ||||||
|   fi |   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" |   _debug "ok, let's start to verify" | ||||||
|   ventries=$(echo "$vlist" | sed "s/,/ /g") |   ventries=$(echo "$vlist" | sed "s/,/ /g") | ||||||
| @ -806,13 +846,17 @@ renew() { | |||||||
| 
 | 
 | ||||||
|   _initpath $Le_Domain |   _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" |   source "$DOMAIN_CONF" | ||||||
|   if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(date -u "+%s" )" -lt "$Le_NextRenewTime" ] ; then  |   if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(date -u "+%s" )" -lt "$Le_NextRenewTime" ] ; then  | ||||||
|     _info "Skip, Next renewal time is: $Le_NextRenewTimeStr" |     _info "Skip, Next renewal time is: $Le_NextRenewTimeStr" | ||||||
|     return 2 |     return 2 | ||||||
|   fi |   fi | ||||||
|   fi |    | ||||||
|   IS_RENEW="1" |   IS_RENEW="1" | ||||||
|   issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" |   issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" | ||||||
|   IS_RENEW="" |   IS_RENEW="" | ||||||
| @ -993,6 +1037,9 @@ install() { | |||||||
|   rm -f $WORKING_DIR/le |   rm -f $WORKING_DIR/le | ||||||
|   ln -s $WORKING_DIR/le.sh  $WORKING_DIR/le |   ln -s $WORKING_DIR/le.sh  $WORKING_DIR/le | ||||||
| 
 | 
 | ||||||
|  |   mkdir -p $WORKING_DIR/dnsapi | ||||||
|  |   cp  dnsapi/* $WORKING_DIR/dnsapi/ | ||||||
|  |    | ||||||
|   installcronjob |   installcronjob | ||||||
|    |    | ||||||
|   _info OK |   _info OK | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user