dbm 5 tahun lalu
melakukan
6ac8fafb72
2 mengubah file dengan 438 tambahan dan 0 penghapusan
  1. 0 0
      README.md
  2. 438 0
      ddns.php

+ 0 - 0
README.md


+ 438 - 0
ddns.php

@@ -0,0 +1,438 @@
+<?php
+
+namespace DDNS;
+
+if (!is_callable('curl_init'))
+	die('ERROR: This PHP script requires cURL to be installed.');
+
+/* 
+ *  
+ *  CUSTOM DYNAMIC DNS SOLUTION FOR USE WITH CLOUDFLARE
+ *  ===============================================================================================
+ *  ===============================================================================================
+ *  
+ *  Christopher Pei
+ *  ------------------------------------------
+ *  	September	05, 2018			R1
+ * 		November	27, 2018 			R2
+ * 		November	28, 2018 			R3
+ *  ===============================================================================================
+ *  
+ */
+
+
+//	-------------------------------------------------------------------------------------------
+//	SETTINGS
+//	-------------------------------------------------------------------------------------------
+
+//	API Credential Setup Instructions
+//	===========================================================================================
+//
+//	Settings or organized in a tabular format with SETTING NAME on the left and VLUE on the right.
+//	Please only edit the VALUE data/columns. When editing, please keep values inside the quotation-
+//	marks ("") and do not remove any parentheses (()) or semi-colons (;).
+//
+//	------------------ Set Basic Options
+//
+//	Since this script may be publicly accessible on your web server, you can use the "DDNS_PASSWORD"
+//	setting so that this string must be provided in order to access this script.
+//
+//	To access the script with the password, you use a web browser and access it as follows:
+//
+//		/ddns.php?psswd=56789
+//
+//	replacing "56789" with your DDNS Password. For example, if this script is located
+//	on your webserver at "https://www.google.com/ddns.php" and your DDNS Password is
+//	"4392", you would use your browser to access it as follows:
+//
+//				https://www.google.com/ddns.php?passwd=4392
+//
+//	Alternatively, if you wish to disable this security feature, leave the VALUE empty
+//	(nothing between the quotation marks). Then you can access the script just via the
+//	name itself. In the example above but without a DDNS Password, you would access it
+//	as follows:
+//
+//				https://www.google.com/ddns.php
+//
+//
+//	-------------------------------------------------------------------------------------------
+//	------------------ SETTING NAME -------------------- VALUE --------------------------------
+//	-------------------------------------------------------------------------------------------
+define(__NAMESPACE__ . '\DDNS_PASSWORD',				'56789'									);
+//
+//
+//
+//	------------------ Set Your API Credentials
+//
+//	For many of these settings, you will have access to your CloudFlare account to acquire the
+//	appropriate information.
+//
+//		1). Login to your CloudFlare account at:	https://dash.cloudflare.com/login
+//
+//		2). If applicable, select your account.
+//
+//		3). If applicable, select the domain you wish to use.
+//
+//		4). Under the "Domain Summary" section, locate the "Zone ID". Copy this value and paste
+//			this into the VALUE for the "CF_ZONE_ID" setting.
+//
+//		5). In the same section, click "Get your API Key". Scroll down the page and under the
+//			"API Keys" locate the "Global API Key" and click "View". Copy this value and paste
+//			this into the VALUE for the "CF_API_KEY" setting.
+//
+//		6). The e-mail address you use to login to CloudFlare is your API username. Provide
+//			this into the VALUE for the "CF_API_USERNAME" setting.
+//
+//	-------------------------------------------------------------------------------------------
+//	------------------ SETTING NAME -------------------- VALUE --------------------------------
+//	-------------------------------------------------------------------------------------------
+define(__NAMESPACE__ . "\CF_ZONE_ID",					"s40v9w8fbn0w49r84r8gw04954852784"		);
+define(__NAMESPACE__ . "\CF_API_USERNAME",				"your_email@domain.com"					);
+define(__NAMESPACE__ . "\CF_API_KEY",					"xk59gs4jg90d893i8560fg8wejdnci4869vvy"	);
+//
+//	------------------ Create The DNS Record
+//
+//		Now, if you have not already done so, it is time to create a subdomain on the domain
+//		that you wish to use for the custom dynamic DNS:
+//
+//		1). Navigate to https://dash.cloudflare.com/websites and select the domain you wish to
+//			use for the custom dynamic DNS service.
+//
+//		2). Go to the "DNS" section, and under the "Search" box, select "A" from the drop-down
+//			menu, enter your desired subdomain in the "Name" field.
+//
+//		3).	Copy and past the value of the "Name" field into the VALUE for the "FQDN" setting.
+//			Do not include ANY trailing slashes and do NOT include either "http://" or "https://"
+//			in the setting value.
+//
+//		4). Enter any IP address into the "IPv4 address" field (even "1.2.3.4" is okay; this will
+//			be updated by the script automatically later, so its current value is not relevant).
+//
+//		5). If this dynamic DNS is going to be used for HTTP traffic (such as a website), then you
+//			can leave the "Automatic TTL" and orange cloud enabled to benefit from CloudFlare's
+//			reverse proxy security. However, if this will be used for something else (such as FTP,
+//			SSH, Remote Desktop, etc) then modify the TTL to "2 minutes" and DISABLE the orange
+//			cloud. Disabling the orange cloud will disable CloudFlare's reverse proxy, which is
+//			required for non-HTTP protocols.
+//
+//		6).	When finished, click the "Add Record" button.
+//
+//	-------------------------------------------------------------------------------------------
+//	------------------ SETTING NAME -------------------- VALUE --------------------------------
+//	-------------------------------------------------------------------------------------------
+define(__NAMESPACE__ . "\FQDN",							"something.example.com"					);
+//
+//	------------------ Get The DNS Record ID
+//
+//	This is where it might seem funky. CloudFlare is somewhat "stupid" in the sense that it
+//	provides no NORMAL way to get the ID of a DNS record, which is a unique ID that identifies
+//	a particular DNS record for your website. The only way to do this is programmatically, via
+//	their API.
+//
+//	For simplicity, I have programmed this ability directly into this script:
+//
+//		1). Please be sure that all other settings are already provided--- otherwise this script
+//			cannot authenticate with the CloudFlare API to find the ID of your DNS record. The
+//			VALUE of CF_ZONE_ID, CF_API_KEY, and CF_API_USERNAME must be provided. (Please see
+//			the [Set Your API Credentials] section above for help).
+//
+//		2). Using a web browser of your choice, access this PHP script in the URL as follows:
+//
+//				/ddns.php?psswd=12345&dump=1
+//
+//			replacing "12345" with your DDNS Password. For example, if this script is located
+//			on your webserver at "https://www.google.com/ddns.php" and your DDNS Password is
+//			"4392", you would use your browser to access it as follows:
+//
+//				https://www.google.com/ddns.php?passwd=4392&dump=1
+//
+//			If your DDNS Password is disabled, access this PHP script in the URL as follows:
+//
+//				/ddns.php?dump=1
+//
+//			For example:
+//
+//				https://www.google.com/ddns.php?dump=1
+//
+//
+//		3).	If successful, the script will output a long string. Please carefully copy and paste
+//			the string into the VALUE for the "CF_DNS_RECORD_ID" setting.
+
+
+//	-------------------------------------------------------------------------------------------
+//	------------------ SETTING NAME -------------------- VALUE --------------------------------
+//	-------------------------------------------------------------------------------------------
+define(__NAMESPACE__ . "\CF_DNS_RECORD_ID",				"e67898768a9859c859845898b7897f09"		);
+//
+//
+//	------------------ Miscellaneous Settings
+//
+//	If you wish to use CloudFlare's reverse proxy security, which will mask your your IP, set this
+//	value to "true" (without quotations). Otherwise, set it to "false" (without quotations). Note
+//	that the CloudFlare reverse proxy feature is currently for HTTP services only, and will not
+//	work for other services, such as FTP, SSH, Remote Desktop, etc. A value of "true" is equivalent
+//	to the "orange-cloud" DNS setting on your CloudFlare control panel, while a value of "false"
+//	is equivalent of the "grey-cloud" DNS setting.
+//	-------------------------------------------------------------------------------------------
+//	------------------ SETTING NAME -------------------- VALUE --------------------------------
+//	-------------------------------------------------------------------------------------------
+define(__NAMESPACE__ . "\USE_CF_REV_PROXY", false );
+
+
+
+
+
+//	--------------------------------------------------------------------------------------------
+//	--------------------------------------------------------------------------------------------
+//	--------------------------------------------------------------------------------------------
+//	--------------------------------------------------------------------------------------------
+//	------------- END OF SETTINGS - BE CAREFUL CHANGING ANYTHING BEYOND THIS POINT -------------
+//	--------------------------------------------------------------------------------------------
+//	--------------------------------------------------------------------------------------------
+//	--------------------------------------------------------------------------------------------
+//	--------------------------------------------------------------------------------------------
+
+
+
+
+
+
+
+//	VARS
+
+$visitor_ip			= $_SERVER['HTTP_CF_CONNECTING_IP']??$_SERVER['REMOTE_ADDR'];
+$j 					= new \stdClass();
+
+//	FUNCTIONS
+
+//	@BRIEF		Creates and outputs the JSON response.
+//	@RETURNS	Does not return a value.
+function CREATE_JSON_RESPONSE(&$r){
+	
+	header('Content-Type: application/json');
+	echo json_encode($r, JSON_FORCE_OBJECT);
+}
+
+//	@BRIEF		Checks DDNS Password with provided password.
+//	@RETURNS	Returns true if correct or disabled, and false if incorrect.
+function CHECK_PASSWORD(){
+	
+	if (defined('DDNS\\DDNS_PASSWORD')){
+		
+		if (empty(DDNS_PASSWORD))
+			return true;
+		if (!strcmp($_REQUEST['passwd'], DDNS_PASSWORD))
+			return true;
+		return false;
+	}
+	
+	return true;
+}
+
+//	@BRIEF		Checks if script is being called with a DUMP request.
+//	@RETURNS	Returns true if it is or false otherwise.
+function IS_DUMP_REQUEST(){
+	
+if (isset($_REQUEST['dump']) &&
+	!empty($_REQUEST['dump']) &&
+	($_REQUEST['dump'] == 1 ||
+	$_REQUEST['dump'] == "1")
+	){
+	
+		if (!strcmp(FQDN, "something.example.com")){
+			
+			$j->success = false;
+			$j->message = 'You must provide the domain you wish to use for the "FQDN" setting.';
+			
+			CREATE_JSON_RESPONSE($j);
+			
+			exit(0);
+		}
+		
+		else return true;
+	}
+	
+	return false;
+}
+
+//	@BRIEF		Creates and DUMP of the DNS data to output the DNS Record ID.
+//	@RETURNS	Does not return a value.
+function DUMP(){
+	
+	try{
+		
+		//	Send the request.
+		$ch = curl_init();
+
+		curl_setopt($ch, CURLOPT_URL, "https://api.cloudflare.com/client/v4/zones/" . CF_ZONE_ID . "/dns_records?type=A&name=" . FQDN . "&match=all");
+		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
+
+
+		$headers = array();
+		$headers[] = "X-Auth-Email: " . CF_API_USERNAME;
+		$headers[] = "X-Auth-Key: " . CF_API_KEY;
+		$headers[] = "Content-Type: application/json";
+		curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+
+		$response = curl_exec($ch);
+		if (curl_errno($ch)){
+			
+			$j->success = false;
+			$j->message = 'cURL encountered a problem.';
+			$j->cURL_err = curl_error($ch);
+			
+			curl_close ($ch);
+			CREATE_JSON_RESPONSE($j);
+			
+			exit(0);
+		}
+		
+		curl_close ($ch);
+		
+		//	Parse the DNS Record ID.
+		$r = json_decode($response, true);
+		if (isset($r['result'][0]['id'])){
+			
+			$j->success = true;
+			$j->message = 'Please copy the "id" value below into the VALUE for the CF_DNS_RECORD_ID settings. Be sure to copy only the value below within the quotation marks.';
+			$j->id = $r['result'][0]['id'];
+			CREATE_JSON_RESPONSE($j);
+			
+			exit(0);
+		}
+		
+		else{
+			
+			$j->success = false;
+			$j->message = 'CloudFlare did not provide a valid response. Please ensure that you have provided correct details for all settings and try again.';
+			CREATE_JSON_RESPONSE($j);
+			exit(0);
+		}
+	}catch(Exception $e){
+		
+		$j->success = false;
+		$j->message = 'A fatal exception occurred.';
+		$j->exception = $e;
+		$j->cURL_err = curl_error($ch);
+		curl_close ($ch);
+	}
+
+}
+
+//	@BRIEF		Updates the DNS record with the visitor's IP.
+//	@RETURNS	Does not return a value.
+function DNS_UPDATE($new_ip){
+	
+	try{
+		
+		//	Send the request.
+		$ch = curl_init();
+		curl_setopt($ch, CURLOPT_URL, "https://api.cloudflare.com/client/v4/zones/" . CF_ZONE_ID . "/dns_records/" . CF_DNS_RECORD_ID);
+		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+		//	CloudFlare is fucking retarded and bitches about this as "malformed JSON, error 6007".
+		//curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"type\":\"A\",\"name\":\"" . FQDN . "\",\"content\":\"" . $new_ip . "\",\"ttl\":120,\"proxied\":" . USE_CF_REV_PROXY . "}");
+		if (USE_CF_REV_PROXY)
+			curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"type\":\"A\",\"name\":\"" . FQDN . "\",\"content\":\"" . $new_ip . "\",\"ttl\":120,\"proxied\":true}");
+		else
+			curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"type\":\"A\",\"name\":\"" . FQDN . "\",\"content\":\"" . $new_ip . "\",\"ttl\":120,\"proxied\":false}");
+		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
+
+
+		$headers = array();
+		$headers[] = "X-Auth-Email: " . CF_API_USERNAME;
+		$headers[] = "X-Auth-Key: " . CF_API_KEY;
+		$headers[] = "Content-Type: application/json";
+		curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+
+		$response = curl_exec($ch);
+		if (curl_errno($ch)){
+			
+			$j->success = false;
+			$j->message = 'cURL encountered a problem.';
+			$j->cURL_err = curl_error($ch);
+			
+			curl_close ($ch);
+			CREATE_JSON_RESPONSE($j);
+			
+			exit(0);
+		}
+		
+		curl_close ($ch);
+		
+		//	Parse the DNS Record ID.
+		$r = json_decode($response, true);
+		if (isset($r['success'])){
+			
+			//	Uncomment these lines for debugging.
+			// header('Content-Type: application/json');
+			// echo json_encode($r, JSON_FORCE_OBJECT);
+			// exit(0);
+			
+			if ($r['success'] == true){
+			
+				$j->success = true;
+				$j->message = 'The [' . FQDN . '] DNS record was successfully updated to point to [' . $new_ip . '].';
+				CREATE_JSON_RESPONSE($j);
+				
+				exit(0);
+			}
+			
+			$j->success = false;
+			$j->message = 'CloudFlare reported an error. Please ensure that you have provided correct details for all settings and try again.';
+			// $j->id = $r['result'][0]['id'];
+			CREATE_JSON_RESPONSE($j);
+			
+			exit(0);
+		}
+		
+		else{
+			
+			$j->success = false;
+			$j->message = 'CloudFlare did not provide a valid response. Please ensure that you have provided correct details for all settings and try again.';
+			CREATE_JSON_RESPONSE($j);
+			exit(0);
+		}
+	}catch(Exception $e){
+		
+		$j->success = false;
+		$j->message = 'A fatal exception occurred.';
+		$j->exception = $e;
+		$j->cURL_err = curl_error($ch);
+		curl_close ($ch);
+	}
+
+}
+
+
+
+
+
+//	SCRIPT
+
+//	---------------------------------------------------------
+
+if (CHECK_PASSWORD()){
+	
+	
+	if (IS_DUMP_REQUEST()){
+	
+		DUMP();
+		exit(0);
+	}
+	
+	DNS_UPDATE($visitor_ip);
+	
+	exit(0);
+}
+
+
+$j->success = false;
+$j->message = 'The DDNS Password is incorrect. Check the "passwd" value and try again.';
+CREATE_JSON_RESPONSE($j);
+
+exit(0);
+
+//	---------------------------------------------------------
+
+