基于阿里云 DNS API 实现的 DDNS 工具
0.簡要介紹
0.1 思路說明
AliDDNSNet 是基于 .NET Core 開發的動態 DNS 解析工具,借助于阿里云的 DNS API 來實現域名與動態 IP 的綁定功能。工具核心就是調用了阿里云 DNS 的兩個 API ,一個 API 獲取指定域名的所有解析記錄,然后通過比對與當前公網 IP 是否一致,一致則不進行更改,不一致則通過另外一個修改 API 來修改指定子域名的修改記錄。
0.2 使用說明
使用時請更改同目錄下的?settings.json.example?為?settings.json?文件,同時也可以顯示通過?-f?參數來制定配置文件路徑。例如:
dotnet ./AliDDNSNet.dll -f ./settings.json2./AliDDNSNet -f ./settings.json3NAS 運行效果圖:
0.3.配置說明
通過更改?settings.json/settings.json.example?的內容來實現 DDNS 更新。
{// 阿里云的 Access Id"access_id": "",// 阿里云的 Access Key"access_key": "",// TTL 時間"interval": 600,// 主域名"domain": "example.com",// 子域名前綴"sub_domain": "test",// 記錄類型"type": "A"}其中 Access Id 與 Access Key 可以登錄阿里云之后在右上角可以得到。
回到頂部
1.代碼說明
1.1 主程序流程
主要流程代碼在 Program.cs 文件當中編寫,這里依次講解一下。
首先加載配置文件,如果用戶傳入了?-f?參數,則使用用戶傳入的配置文件路徑,否則的話直接使用當前目錄的默認?settings.json?配置文件,讀取成功之后存放到 Utils.config 屬性當中以便 Utils 使用。
之后通過?Utils.GetCurentPublicIP()?方法獲取到當前設備的公網 IP,再判斷指定的二級域名解析是否存在,如果不存在的話,則直接返回,這里并沒有做新增解析操作,后續版本可能會加上。
如果找到了對應二級域名的解析,則輸出當前解析的記錄值,然后進行比較,如果當前主機的公網 IP 與記錄值一樣則無需進行變更。
當阿里云 DNS 解析記錄與當前主機公網 IP 不一致的時候調用更新 API,傳入之前的域名的 rrId 去進行變更,完成即退出。
1.2 Utils 詳解
Utils.cs 主要存放一些功能性方法,比如說將?SortedDictionary?字典轉為請求字符串,還有就是加密方法,請求方法等。
1.2.1 生成通用參數字典
因為 API 請求的時候有很多共有參數,所以這里單獨用了一個靜態方法來生成這個公有請求參數的字典。
/// <summary>/// 生成通用參數字典/// </summary>public static SortedDictionary<string, string> GenerateGenericParameters() { ? ?var dict = new SortedDictionary<string, string>(StringComparer.Ordinal){{"Format", "json"},{"AccessKeyId", config.access_id},{"SignatureMethod", "HMAC-SHA1"},{"SignatureNonce", Guid.NewGuid().ToString()},{"Version", "2015-01-09"},{"SignatureVersion", "1.0"},{"Timestamp", DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")}}; ? ?return dict; }可以看到這里使用了?SortedDictionary<string,string>?來處理,這是因為阿里云 API 必須要求按大小寫敏感來排序請求參數,所以這里直接使用了 ```SortedDictionary?來處理這種情況。
1.2.2 根據字典構建請求字符串
因為阿里云 DNS 的 API 基本上都是 GET 請求,所以通過這個方法可以將之前的?SortedDictionary<string,string>?字典構建成請求字符串。
核心就是遍歷這個字典,通過?StringBuilder?來構建這個請求字符串。
1.2.3 生成請求簽名
這一步也是最重要的一步,因為阿里云所有的 API 接口都需要傳遞簽名參數,這個簽名參數是根據你提交的參數集合 AccessKey 來進行計算的。
這里之前我是按照阿里云 API 來進行開發的,不過有一點需要注意的是,返回的 Signature 值是不需要進行 URL 編碼的。就因為這一點,我白白浪費了 3 個小時來排查問題,看看官方 API 文檔說的:
說需要將簽名值編碼之后再提交,扯淡,如果編碼之后再提交的話,接口會一直返回:
Specified signature is not matched with our calculation.
這里直接返回 HMACSHA1 加密結果的 Base64 字符串即可。
1.2.4 發送請求
構建好一切之后我們就需要發送請求了,這里統一是使用的?SendRequest()?方法來進行處理,可以看到我們先獲得簽名,然后將獲取到的簽名追加到請求體內部,一起進行請求。
這里傳入的?IRequest?接口,是有具體實現的,可以轉到 Main 方法里面看一下:
await Utils.SendGetRequest(new DescribeDomainRecordsRequest(config.domain));await Utils.SendGetRequest(new UpdateDomainRecordRequest(rrId, config.sub_domain, config.type, currentIP, config.interval.ToString()));
這里的?DescribeDomainRecordsRequest?與?UpdateDomainRecordRequest?就是具體的請求體,定義很簡單,就是實現了?IRequest?接口而已,然后在各自的內部添加一些特殊的參數。
1.3 異步 Main 方法
異步的 Main 方法需要 C# 7.1 以上版本才能支持,你只需要右鍵你的項目選擇屬性,左側欄選擇生成,找到高級按鈕,更改當前 C# 語言版本即可。
效果如下:
static async Task<int> Main(string[] args){ ? ?// 代碼....return await Task.FromResult(0); }1.4 好用的 CommandLine 庫
編寫控制臺程序,最主要的是接受參數然后處理,而?Microsoft.Extensions.CommandLineUtils?庫提供了方便快捷的方式來為我們處理用戶輸入的參數。
使用方法如下:
2.GITHUB 開源地址
https://github.com/GameBelial/AliDDNSNet
有興趣的朋友可以 star 關注一下。
3.二進制程序下載地址
程序打包了 Linux-x64 與 Linux arm 環境的二進制可執行文件,你可以直接下載對應的壓縮包解壓到你的路由器或者 NAS 里面進行運行。
如果你的設備支持 Docker 環境,建議通過 Docker 運行 .NET Core 2.1 環境來執行本程序。
原文地址:https://www.cnblogs.com/myzony/p/9349578.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com 
總結
以上是生活随笔為你收集整理的基于阿里云 DNS API 实现的 DDNS 工具的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 基于.net standard 的动态编
- 下一篇: ASP.NET Core Web API
