首先在实现动态域名解析之前要具备两个条件:
第一、你必须有公网 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分钟的时间。
源码的下载地址:http://download.csdn.net/detail/jiyuxian/9716699
第一次写博客,写的不好欢迎拍砖。
来源:CSDN
作者:败家子
链接:https://blog.csdn.net/jiyuxian/article/details/53762646