当前位置: 首页 > news >正文

C#调用阿里云接口实现动态域名解析,支持IPv6(Windows系统下载可用)

电信宽带一般能申请到公网IP,但是是动态的,基本上每天都要变,所以想到做一个定时任务,随系统启动,网上看了不少博文很多都支持IPv4,自己动手写了一个。

(私信可全程指导)

部署步骤:

1、下载软件包,修改配置文件

下载地址:私信获取

下载压缩包,解压后修改配置文件AliDDNS.exe.config中的阿里云帐号和自己的域名。

2、修改脚本,并运行脚本

将“安装服务.bat”和“卸载服务.bat”脚本中的可执行文件路径,改为自己的软件包所在路径,然后右键“安装服务.bat”进行安装服务。

执行脚本后会将定时服务添加到系统服务中。

3、启动服务

右键“此电脑”,点击“管理”进入计算机管理窗口,在服务列表中找到上一步新增的服务,然后启动。即可定时更新阿里云解析记录,实现动态IP的DDNS。

源代码:


/// <summary>
/// 刷新阿里云域名解析记录
/// </summary>
private void RefreshAliRecord()
{string recordTypes = ConfigurationManager.AppSettings["RecordTypes"];if (string.IsNullOrWhiteSpace(recordTypes)){NLogHelper.WriteLog(typeof(AliDDNS), "配置文件中的“待解析的协议类型”不能为空。", NLogLevel.Warn);return;}string regionId = ConfigurationManager.AppSettings["RegionId"];string accessKeyID = ConfigurationManager.AppSettings["AccessKeyID"];string accessKeySecret = ConfigurationManager.AppSettings["AccessKeySecret"];string domainName = ConfigurationManager.AppSettings["DomainName"];string rR = ConfigurationManager.AppSettings["RR"];string[] rRTypes = rR.Split('|');// regionId:地区节点// accessKeyID:阿里云Key// accessKeySecret:阿里云密钥AlibabaCloudCredentialsProvider provider = new AccessKeyCredentialProvider(accessKeyID, accessKeySecret);IClientProfile profile = DefaultProfile.GetProfile(regionId);DefaultAcsClient client = new DefaultAcsClient(profile, provider);List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> recordList = DescribeDomainRecords(client, domainName);string[] recordTypeArray = recordTypes.Split('|');foreach (string recordType in recordTypeArray){if (recordType == "A"){#region IPv4解析记录try{string urls = ConfigurationManager.AppSettings["GetIPFromUrl"];string ipv4 = CommonHelper.GetExtranetIP(urls.Split('|').ToList());if (string.IsNullOrWhiteSpace(ipv4)){NLogHelper.WriteLog(typeof(AliDDNS), "未获取到外网IPv4地址!", NLogLevel.Warn);return;}if (IsAddSuccessLog){NLogHelper.WriteLog(typeof(AliDDNS), "获取到的外网IPv4地址为:" + ipv4, NLogLevel.Info);}foreach (string rRItem in rRTypes){if (string.IsNullOrWhiteSpace(rRItem)){continue;}List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> ipv4Records = recordList.Where(r => r.Type == recordType && r.RR == rRItem).ToList();if (ipv4Records == null || ipv4Records.Count() == 0){AddDNSRecord(client, domainName, rRItem, recordType, ipv4);}else{#region 更新解析记录// 非ipv4记录List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> otherRecords = ipv4Records.Where(r => r._Value != ipv4).ToList();// ipv4记录List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> tempList = ipv4Records.Where(r => r._Value == ipv4).ToList();if (tempList == null || tempList.Count == 0){// 如果不存在该IPv4的记录,则删除所有记录ipv4Records,并新增记录AddDNSRecord(client, domainName, rRItem, recordType, ipv4);DeleteDNSRecord(client, ipv4Records);}else if (tempList.Count == 1)  // 如果只存在一条该IPv4记录,则记录日志,如果有其他记录则删除{NLogHelper.WriteLog(typeof(AliDDNS), string.Format("同类型(“{0}”类型)的解析记录(IPv4:{1})已存在,无需更新!", rRItem, ipv4), NLogLevel.Info);if (ipv4Records.Count != tempList.Count){// 存在其他记录,则删除其他记录otherRecordsDeleteDNSRecord(client, otherRecords);}}else{// 如果存在多条该IPv4记录,则取第一条,其他的记录都删除tempList.RemoveRange(0, 1);otherRecords.AddRange(tempList);DeleteDNSRecord(client, otherRecords);}#endregion}}}catch (Exception ex){NLogHelper.WriteLog(typeof(AliDDNS), "查询并更新IPv4解析记录时异常:" + ex.ToString(), NLogLevel.Warn);}#endregion}else if (recordType == "AAAA"){#region IPv6解析记录try{List<string> ipv6List = CommonHelper.GetLocalIPv6();if (ipv6List == null || ipv6List.Count() == 0){NLogHelper.WriteLog(typeof(AliDDNS), "未获取到本机IPv6地址!", NLogLevel.Warn);return;}if (IsAddSuccessLog){NLogHelper.WriteLog(typeof(AliDDNS), "获取到的本地IPv6地址为:" + string.Join(",", ipv6List), NLogLevel.Info);}string defaultIPv6 = ipv6List[0];  // 默认只添加第一个IPv6地址foreach (string rRItem in rRTypes){if (string.IsNullOrWhiteSpace(rRItem)){continue;}List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> ipv6Records = recordList.Where(r => r.Type == recordType && r.RR == rRItem).ToList();if (ipv6Records == null || ipv6Records.Count() == 0){AddDNSRecord(client, domainName, rRItem, recordType, defaultIPv6);}else{#region 更新解析记录// 非ipv6记录List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> otherRecords = ipv6Records.Where(r => r._Value != defaultIPv6).ToList();// ipv6记录List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> tempList = ipv6Records.Where(r => r._Value == defaultIPv6).ToList();if (tempList == null || tempList.Count == 0){// 如果不存在该IPv6的记录,则删除所有记录ipv6Records,并新增记录AddDNSRecord(client, domainName, rRItem, recordType, defaultIPv6);DeleteDNSRecord(client, ipv6Records);}else if (tempList.Count == 1)  // 如果只存在一条该IPv6记录,则记录日志,如果有其他记录则删除{NLogHelper.WriteLog(typeof(AliDDNS), string.Format("同类型(“{0}”类型)的解析记录(IPv6:{1})已存在,无需更新!", rRItem, defaultIPv6), NLogLevel.Info);if (ipv6Records.Count != tempList.Count){// 存在其他记录,则删除其他记录otherRecordsDeleteDNSRecord(client, otherRecords);}}else{// 如果存在多条该IPv6记录,则取第一条,其他的记录都删除tempList.RemoveRange(0, 1);otherRecords.AddRange(tempList);DeleteDNSRecord(client, otherRecords);}#endregion}}}catch (Exception ex){NLogHelper.WriteLog(typeof(AliDDNS), "查询并更新IPv6解析记录时异常:" + ex.ToString(), NLogLevel.Warn);}#endregion}}
}// 获取指定主域名的所有解析记录列表
public List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> DescribeDomainRecords(DefaultAcsClient client, string domainName)
{List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> records = new List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record>();try{DescribeDomainRecordsRequest request = new DescribeDomainRecordsRequest();request.DomainName = domainName;记录类型 官网支持A/CNAME/MX/AAA/TXT/NS/SRV/CAA/URL隐性(显性)转发如果有需要可将该值配置为参数传入//request.Type = recordType;try{DescribeDomainRecordsResponse response = client.GetAcsResponse(request);if (IsAddSuccessLog){NLogHelper.WriteLog(typeof(AliDDNS), "查询到的解析记录:" + System.Text.Encoding.Default.GetString(response.HttpResponse.Content), NLogLevel.Info);}if (response.DomainRecords != null){records = response.DomainRecords;}}catch (Exception ex){NLogHelper.WriteLog(typeof(AliDDNS), "调用DescribeDomainRecords接口时发生异常:" + ex.ToString(), NLogLevel.Error);}}catch (Exception ex){NLogHelper.WriteLog(typeof(AliDDNS), "创建DescribeDomainRecords接口调用对象时发生异常:" + ex.ToString(), NLogLevel.Error);}return records;
}// 新增解析记录
public void AddDNSRecord(DefaultAcsClient client, string domainName, string rRItem, string recordType, string ipValue)
{#region 新增解析记录string recordStr = string.Format("(RR:{0},Type:{1},Value:{2})", rRItem, recordType, ipValue);try{var request = new AddDomainRecordRequest();request.DomainName = domainName;request.RR = rRItem;request.Type = recordType;request._Value = ipValue;request.TTL = 600;  // 免费版,默认600秒,10分钟var response = client.GetAcsResponse(request);if (IsAddSuccessLog){NLogHelper.WriteLog(typeof(AliDDNS), string.Format("新增解析记录{0}时接口返回内容:{1}", recordStr, Encoding.Default.GetString(response.HttpResponse.Content)), NLogLevel.Info);}}catch (Exception ex){NLogHelper.WriteLog(typeof(AliDDNS), string.Format("新增解析记录{0}时发生异常:{1}", recordStr, ex.ToString()), NLogLevel.Error);}#endregion
}// 删除解析记录
public void DeleteDNSRecord(DefaultAcsClient client, List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> deleteList)
{#region 删除解析记录foreach (DescribeDomainRecordsResponse.DescribeDomainRecords_Record record in deleteList){string recordStr = string.Format("(RR:{0},Type:{1},Value:{2})", record.RR, record.Type, record._Value);try{DeleteDomainRecordRequest request = new DeleteDomainRecordRequest();request.RecordId = record.RecordId;DeleteDomainRecordResponse response = client.GetAcsResponse(request);if (IsAddSuccessLog){NLogHelper.WriteLog(typeof(AliDDNS), string.Format("删除解析记录{0}时接口返回内容:{1}", recordStr, Encoding.Default.GetString(response.HttpResponse.Content)), NLogLevel.Info);}}catch (Exception ex){NLogHelper.WriteLog(typeof(AliDDNS), string.Format("删除解析记录{0}时发生异常:{1}", recordStr, ex.ToString()), NLogLevel.Error);}}#endregion
}

相关文章:

  • 【计算机网络】—— 详解码元,传输速率的计算|网络奇缘系列|计算机网络
  • 【Spark精讲】Spark RDD弹性体现在哪些方面?
  • python多版本共存
  • PyTorch官网demo解读——第一个神经网络(2)
  • C++:类和对象(1)
  • 亿发零售云引领新零售时代:智能收银系统助力连锁门店多业态发展
  • Flink CDC 3.0 正式发布,详细解读新一代实时数据集成框架
  • Linux 使用 Anaconda+Uwsgi 部署 Django项目和前端项目
  • 13、Kafka副本机制详解
  • 在 Cray Linux 上配置 LSF 集成
  • 全面掌握XSS漏洞攻击,实战案例从Self-XSS到账户接管,以及通过参数污染的XSS实现攻击
  • 设计模式——组合模式(结构型)
  • 如何提升数据结构方面的算法能力?
  • Leetcode 376 摆动序列
  • 计算机论文写作助手
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • 77. Combinations
  • angular2开源库收集
  • angular组件开发
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • Django 博客开发教程 8 - 博客文章详情页
  • Javascript 原型链
  • JS字符串转数字方法总结
  • Nodejs和JavaWeb协助开发
  • nodejs实现webservice问题总结
  • SpringCloud集成分布式事务LCN (一)
  • vue-router 实现分析
  • Webpack 4x 之路 ( 四 )
  • Zsh 开发指南(第十四篇 文件读写)
  • 阿里研究院入选中国企业智库系统影响力榜
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 给第三方使用接口的 URL 签名实现
  • 坑!为什么View.startAnimation不起作用?
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 那些被忽略的 JavaScript 数组方法细节
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 时间复杂度与空间复杂度分析
  • 使用API自动生成工具优化前端工作流
  • 回归生活:清理微信公众号
  • #传输# #传输数据判断#
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (备忘)Java Map 遍历
  • (笔试题)合法字符串
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • .gitignore文件—git忽略文件
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .NET Core中Emit的使用
  • .net framework4与其client profile版本的区别
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .net中调用windows performance记录性能信息
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • @EnableWebMvc介绍和使用详细demo
  • @开发者,一文搞懂什么是 C# 计时器!