9

Dynamic DNS with CPanel

 3 years ago
source link: https://blog.nem.ec/2014/11/17/dyndns-cpanel/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Dynamic DNS with CPanel

By Dan Nemec

17 Nov 2014

Occasionally I need to SSH into my home computer while I’m out and about, so to make things easy I set up a DNS entry to point to my home network. My router, like most routers, supports a service called “dynamic DNS” where the router periodically updates a DNS entry when it notices that it has a new IP from my ISP. And it works: as long as that service is dyndns.org. If you’re familiar with DynDNS, you may know that they shut down their free tier earlier this year and since I have absolutely no interest (nor need) to join their paid tier, I’ve been doing without.

I’d like to get that up an running again, so I decided to do some digging into whether or not CPanel has its own API. The official documentation was down when I did my initial research (I assumed it was offline for good), but apparently it’s back up now. In any case, I was able to use Google Cache to find the Zone Edit feature. Next, all you have to do is place this script on a server within the network and register it with cron / Windows Scheduler and your DNS entry will be periodically updated with your public IP address.

As usual, you can test the following code in LINQPad with the “C# Program” language:

async void Main()
{
	var user = "";
	var pass = "";
	var cpanelDomain = "www.myhost.com";
	var baseDomain = "nem.ec";
	var domainToEdit = "example.nem.ec.";  // keep the trailing .
	var newAddress = await GetCurrentIpAddress();
	
	var baseUrl = String.Format(
        "https://{0}:2083/xml-api/cpanel?cpanel_xmlapi_module=ZoneEdit&domain={1}",
        cpanelDomain, 
        baseDomain);
	
	var client = new HttpClient();
	client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
        Convert.ToBase64String(
            Encoding.ASCII.GetBytes(String.Format("{0}:{1}", user, pass))));
	var url = baseUrl + "&cpanel_xmlapi_func=fetchzone";
	
	var resp = await client.GetAsync(url);
	resp.EnsureSuccessStatusCode();
	var stream = await resp.Content.ReadAsStreamAsync();
	
	var doc = XDocument.Load(stream);
	
    // Grab the first result where the domain name is the name
    // we're looking for.
	var record = doc
		.Element("cpanelresult")
		.Element("data")
		.Elements("record")
		.FirstOrDefault(r => 
			r.Elements("name").Any(e => 
				e.Value == domainToEdit));
	
	if(record != null)
	{
		Console.WriteLine("Replacing old address '{0}' with '{1}'", 
			record.Element("address").Value,
			newAddress);
		var lineNumber = record.Element("line").Value;
        
        // Line number is the "primary key" of the record,
        // at least as far as the API is concerned.
		var editUrl = baseUrl + String.Format(
			"&cpanel_xmlapi_func=edit_zone_record&line={0}&address={1}",
			lineNumber,
			newAddress);
		resp = await client.GetAsync(editUrl);
		resp.EnsureSuccessStatusCode();
		Console.WriteLine("Changed address.");
	}
	else
	{
		Console.WriteLine("No record available.");
	}
}

// Polls icanhazip for the current public IP address.
async Task<string> GetCurrentIpAddress()
{
	var client = new HttpClient();
	var resp = await client.GetAsync("https://icanhazip.com/");
	return await resp.Content.ReadAsStringAsync();
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK