1. 程式人生 > >利用阿里雲的API實現動態域名解析

利用阿里雲的API實現動態域名解析

首先在實現動態域名解析之前要具備兩個條件:

第一、你必須有公網 IP,就是你的路由器撥號獲取到的 IP 必須是公網 IP (可以參考 ip138 獲取到的 IP)。長城寬頻沒有公公網 IP 所以就不用往下看了,用內網穿透的工具吧,那天在家搭伺服器時發現聯通給的也是內網IP,果斷投訴他們,讓他們換成公網的 IP。

第二、你必須有阿里雲的域名,API 是阿里雲提供的,阿里雲提供域名解析,所以沒有域名就沒法解析了。

進入正題,先說一下原理:

一個 windows 服務,定時獲取公網 IP ,然後呼叫 API 介面設定解析。

首先從阿里雲上把 SDK 下載下來,原始碼需要自己編譯,這裡我們只用到了 core 和 alidns 兩個專案,一個是核心元件,一個是 dns 介面元件。

其實我只用到了 3 個介面:

  • DescribeDomainRecords  獲取域名的解析列表
  • AddDomainRecord   新增一條新的解析記錄
  • UpdateDomainRecord  修改一條解析記錄

獲取域名的解析列表

CGlobalConfig.AccessKey 是獲取配置檔案裡配置的阿里雲的 AccessKey,這個需要去阿里雲申請(不花錢)。

CGlobalConfig.AccessKeySecret 是獲取配置檔案裡配置的阿里雲的 AccessKeySecret,這個跟 AccessKey 是一對。

domain 變數是域名

IClientProfile clientProfile = DefaultProfile.GetProfile("cn-hangzhou", CGlobalConfig.AccessKey, CGlobalConfig.AccessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(clientProfile);
DescribeDomainRecordsRequest request = new DescribeDomainRecordsRequest();
request.DomainName = domain;
DescribeDomainRecordsResponse response = client.GetAcsResponse(request);
List<DescribeDomainRecordsResponse.Record> list = response.DomainRecords;

獲取到的 list 就是這個域名的解析記錄。

DescribeDomainRecordsResponse.Record 物件有以下幾個屬性:

  • DomainName 域名
  • RecordId  記錄 ID ,唯一標識,是個 GUID
  • RR 主機記錄,如果要解析@.exmaple.com,主機記錄要填寫"@”,而不是空
  • Type  解析記錄型別,自己去看阿里雲的解析型別,我這裡只用了 A
  • Value  解析記錄的值,A 型別的記錄這裡就是 IP 地址了,每次修改的就是這個 Value

獲取到解析記錄後獲取當前的公網 IP 地址,我這裡是從 ip138 上獲取的,沒有時間找介面,就直接解析 HTML 了。

HttpWebRequest request = HttpWebRequest.Create(CGlobalConfig.IPUrl) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
	StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("GB2312"));
	string str = reader.ReadToEnd();
	reader.Close();
	reader.Dispose();
	int start = str.IndexOf("[");
	int end = str.IndexOf("]");
	if (start > -1 && end > -1 && end > start)
	{
		ip = str.Substring(start + 1, end - start - 1);
	}
}

ip 就是獲取到的 當前公網 IP 地址,然後判斷與當前解析是否一致,不一致時進行解析。

List<DescribeDomainRecordsResponse.Record> list = CDomainHelper.GetDomainRecords(CGlobalConfig.DomainName);
DescribeDomainRecordsResponse.Record record = list.Find(rec => rec.Type == "A" && rec.RR == "dev");
if (record != null)
{
	if (record.Value != ip)
	{
		CLogHelper.WriteInfo("當前 IP:" + ip + " 域名解析 IP:" + record.Value + " 開始修改解析記錄。 ");
		record.Value = ip;
		CDomainHelper.UpdateDomainRecords(record);
	}
    	else
    	{
        	CLogHelper.WriteInfo("當前 IP 與域名解析 IP 相同,不需要修改解析。");
    	}
}
else
{
	CLogHelper.WriteInfo("沒有找到解析需要新增解析記錄。");
	record = new DescribeDomainRecordsResponse.Record();
    	record.RR = "dev";
    	record.DomainName = CGlobalConfig.DomainName;
    	record.Type = "A";
    	record.Value = ip;
	CDomainHelper.AddDomainRecords(record);
}

CDomainHelper.AddDomainRecords 是新增解析記錄的方法:

IClientProfile clientProfile = DefaultProfile.GetProfile("cn-hangzhou", CGlobalConfig.AccessKey, CGlobalConfig.AccessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(clientProfile);
AddDomainRecordRequest request = new AddDomainRecordRequest();
request.DomainName = record.DomainName;
request.RR = record.RR;
request.Type = record.Type;
request.Value = record.Value;
AddDomainRecordResponse response = client.GetAcsResponse(request);

CDomainHelper.UpdateDomainRecords 是修改解析記錄的方法:

IClientProfile clientProfile = DefaultProfile.GetProfile("cn-hangzhou", CGlobalConfig.AccessKey, CGlobalConfig.AccessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(clientProfile);
UpdateDomainRecordRequest request = new UpdateDomainRecordRequest();
request.RecordId = record.RecordId;
request.RR = record.RR;
request.Type = record.Type;
request.Value = record.Value;
UpdateDomainRecordResponse response = client.GetAcsResponse(request);

好了,主要的邏輯完成了,然後我們建立一個 window 服務然後在  OnStart 裡啟動一個執行緒,每隔一段時間去解析就可以了。

大家可以下載原始碼進行參考,下載原始碼後需要更改配置檔案:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <!-- 阿里雲開發者的 AccessKey -->
    <add key="AccessKey" value="阿里雲開發者的AccessKey"/>
    <!-- 阿里雲開發者的 AccessKeySecret -->
    <add key="AccessKeySecret" value="阿里雲開發者的 AccessKeySecret"/>
    <!-- 阿里雲 API 的地址 -->
    <add key="APIUrl" value="http://ecs.aliyuncs.com/"/>
    <!-- 獲取外網 IP 的地址 -->
    <add key="IPUrl" value="http://1212.ip138.com/ic.asp"/>
    <!-- 要進行解析的域名 -->
    <add key="DomainName" value="要進行解析的域名"/>
  </appSettings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
  </startup>
</configuration>

需要修改的是 AccessKey,AccessKeySecret,DomainName 這三個配置項。

最後說一下,域名解析不是實時生效的,需要10分鐘的時間。

第一次寫部落格,寫的不好歡迎拍磚。