Bazen dışarıdayken ev bilgisayarıma SSH bağlamam gerekiyor, bu yüzden işleri kolaylaştırmak için ev ağıma işaret edecek bir DNS girişi ayarlıyorum. Yönlendiricim, çoğu yönlendirici gibi, yönlendiricinin İSS’mden yeni bir IP aldığını fark ettiğinde bir DNS girişini düzenli aralıklarla güncellediği “dinamik DNS” adı verilen bir hizmeti destekliyor. Ve işe yarıyor: Bu hizmet dyndns.org olduğu sürece. DynDNS’e aşina iseniz, bu yılın başlarında ücretsiz katmanlarını kapattıklarını ve ücretli katmanlarına katılmaya kesinlikle ilgim (veya ihtiyacım) olmadığından, onsuz yapıyorum.
Bunu yeniden başlatmak istiyorum, bu yüzden CPanel’in kendi API’sine sahip olup olmadığına dair biraz araştırma yapmaya karar verdim. İlk araştırmamı yaptığımda resmi belgeler kapalıydı (tamamen çevrimdışı olduğunu varsaydım), ama görünüşe göre şimdi tekrar çalışıyor. Her durumda, Bölge Düzenleme özelliğini bulmak için Google Önbelleğini kullanabildim. Daha sonra yapmanız gereken tek şey, bu betiği ağ içindeki bir sunucuya yerleştirmek ve cron/Windows Scheduler’a kaydetmektir; DNS girişiniz, genel IP adresinizle periyodik olarak güncellenecektir.
Her zamanki gibi aşağıdaki kodu LINQPad’de “C# Program” diliyle test edebilirsiniz:
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();
}