DnsPod 被腾讯收购以后进行了升级,原先的 API 相对简单,后续将会停止服务,应当尽早过渡到新的接口,DnsPod 3.0 分两种签名方法,分别是 V1 和 V3,V1 虽然比原 DnsPod 认证复杂,但比起 V3 仍然不算复杂,目前腾讯云推荐的是 V3 签名算法,安全性更高,但算法比较复杂,腾讯官方提供了 Python、Java、PHP、Go、NodeJS、.NET、C++、Ruby 的 SDK,可以直接下载配置使用,但这些 SDK 都依赖于指定的程序,需要额外安装软件,Powershell 是 Windows 内置组件,不需要安装,但腾讯云没有提供 DnsPod Powershell 程序 SDK 或示例,而普通人使用 Powershell 编程又会困难重重,并不是因为 Powershell 难学,而是设计 Powershell 的人不是正常人,Powershell 的坑太多,脑残的设计和莫名其妙的数据自动转换贯穿始终,一不小心就掉进坑里。
以下代码使用 Powershell DnsPod 3.0 接口实现了 Ddns 动态更新域名解析记录。支持 Powershell 5.1 - 7.4,其中 7.4 是编写代码时 Powershell 的最高版本。
代码有可能被编辑器改变,建议下载附件使用。- <#
- .Description Powershell DnsPod API 3.0 接口程序 动态更新域名解析 实现 Ddns
- .Link wuxiancheng.cn
- .Notes 本程序由吴先成编写
- .Notes 请修改 Make-ApiRequest 中的 $SecretId $SecretKey 为自己的腾讯云 API 密钥信息
- #>
- <#
- .Description 计算字符串的哈希值
- .Link wuxiancheng.cn
- .Notes 本程序由吴先成编写
- .Parameter [String] $Algorithm 哈希算法 支持 SHA256
- .Parameter [String] $Message 要计算哈希值的字符串
- .Outputs [String] 返回计算得到的哈希值
- #>
- Function Compute-Hash{
- [CmdletBinding(PositionalBinding=$False)]
- Param(
- [String][ValidateSet("SHA256")]$Algorithm="SHA256",
- [String]$Message
- )
- $SHA256 = Invoke-Expression -Command "[System.Security.Cryptography.$Algorithm]::Create()"
- $MessageBytes = [System.Text.Encoding]::UTF8.GetBytes($Message)
- $HashBytes = $SHA256.ComputeHash($MessageBytes)
- $Hash = [System.BitConverter]::ToString($HashBytes).Replace("-", "").ToLower()
- Return $Hash
- }
- <#
- .Description 计算 HMAC 哈希值
- .Link wuxiancheng.cn
- .Notes 本程序由吴先成编写
- .Parameter [String] $Algorithm 哈希算法 支持 SHA256
- .Parameter [String] $Message 要计算哈希值的字符串
- .Parameter [String]|[Byte[]] $Key 密钥 字符串或字节数组
- .Parameter [Switch] $Binary 是否返回原始二进制数据
- .Outputs [String]|[Byte[]] 使用 $Binary 时返回字节数组 否则返回字符串
- #>
- Function Compute-HmacHash{
- [CmdletBinding(PositionalBinding=$False)]
- Param(
- [String][ValidateSet("SHA256")]$Algorithm="SHA256",
- [String]$Message,
- [Object][ValidateScript({$_ -is [String] -or $_ -is [Byte]})]$Key,
- [Switch]$Binary
- )
- $Utf8Encoding = [System.Text.Encoding]::UTF8
- $MessageBytes = $Utf8Encoding.GetBytes($Message)
- If($Key -is [String]){
- $KeyBytes = $Utf8Encoding.GetBytes($Key)
- }Else{
- $KeyBytes = $Key
- }
- $HMAC = New-Object -TypeName "System.Security.Cryptography.HMAC$Algorithm"
- $HMAC.Key = $KeyBytes
- $HashBytes = $HMAC.ComputeHash($MessageBytes)
- If($Binary){
- $Hash = $HashBytes
- }Else{
- $Hash = [System.BitConverter]::ToString($HashBytes).Replace("-", "").ToLower()
- }
- Return $Hash
- }
- <#
- .Description 将非 ASCII 字符转换为 JSON 安全字符
- .Link wuxiancheng.cn
- .Notes 本程序由吴先成编写
- .Parameter [String] $String 原字符串
- .Outputs [String] 转换后的字符串
- #>
- Function Escape-JsonString{
- Param(
- [String]$String
- )
- $EscapedString = $String.ToCharArray() | ForEach-Object{
- If($_ -match "[^\x00-\x7F]"){
- Return ("\u{0:x4}" -f [Int32][Char]$_)
- }Else{
- Return $_
- }
- }
- Return $EscapedString -join ""
- }
- <#
- .Description 向服务器发送接口请求 请求失败时输出错误信息
- .Link wuxiancheng.cn
- .Notes 本程序由吴先成编写
- .Parameter [String] $Action 需要请求的服务器接口名称
- .Parameter [Hashtable] $Fields 向服务器发送的 POST 数据字段
- .Outputs [Object] 返回请求响应对象 有 .Error 代表接口报错 .Error.Message 是接口提供的错误信息 .Error.Code 是接口提供的错误代码
- #>
- Function Make-ApiRequest{
- [CmdletBinding(PositionalBinding=$False)]
- Param(
- [String]$Action,
- [System.Collections.Hashtable]$Fields=@{}
- )
- $ResponseObject = New-Object -TypeName System.Object
- if("" -ne $Action){
- $ActionLowerCase = $Action.ToLower()
- $PsVersion = $PSVersionTable.PSVersion
- $SecretId = "wuxiancheng"
- $SecretKey = "wuxiancheng"
- $Service = "dnspod"
- $HostName = "dnspod.tencentcloudapi.com"
- $Version = "2021-03-23"
- $Endpoint = "https://$HostName"
- $HashAlgorithm = "SHA256"
- $SignatureAlgorithm = "TC3-HMAC-SHA256"
- $DateTime = Get-Date
- # Powershell 6.0 及更早版本 %s 返回值包含小数部分,并且有时区偏移量,需要修正。
- If($PsVersion -lt [System.Version]"6.1"){
- $Timestamp = [System.Math]::Round((Get-Date -Date $DateTime.ToUniversalTime() -UFormat "%s"))
- }Else{
- $Timestamp = Get-Date -Date $DateTime -UFormat "%s"
- }
- # Powershell 7.0 及更早版本不支持 Get-Date -AsUtc
- If($PsVersion -lt [System.Version]"7.1"){
- $UtcDate = [System.DateTime]::UtcNow.ToString("yyyy-MM-dd")
- }Else{
- $UtcDate = Get-Date -AsUtc -Date $DateTime -UFormat "%Y-%m-%d"
- }
-
- $RequestMethod = "POST"
- # Powershell 6.0 及更早版本不支持 JSON 非 ASCII 字符转码 会导致有汉字时接口请求出错
- If($PsVersion -lt [System.Version]"6.1"){
- $RequestPayload = ConvertTo-Json -InputObject $Fields -Compress
- $RequestPayload = Escape-JsonString -String $RequestPayload
- }Else{
- $RequestPayload = ConvertTo-Json -EscapeHandling "EscapeNonAscii" -InputObject $Fields -Compress
- }
- $CanonicalUri = "/"
- $CanonicalQueryString = ""
- $ContentType = "application/json; charset=utf-8"
- $CanonicalHeaders = "content-type:$ContentType`nhost:$HostName`nx-tc-action:$ActionLowerCase`n"
- $SignedHeaders = "content-type;host;x-tc-action"
- $HashedRequestPayload = Compute-Hash -Algorithm $HashAlgorithm -Message $RequestPayload
- $CanonicalRequest = "$RequestMethod`n$CanonicalUri`n$CanonicalQueryString`n$CanonicalHeaders`n$SignedHeaders`n$HashedRequestPayload"
-
- $CredentialScope = "$UtcDate/$Service/tc3_request"
- $HashedCanonicalRequest = Compute-Hash -Algorithm $HashAlgorithm -Message $CanonicalRequest
- $StringToSign = "$SignatureAlgorithm`n$Timestamp`n$CredentialScope`n$HashedCanonicalRequest"
-
- $SecretDate = Compute-HmacHash -Algorithm $HashAlgorithm -Message $UtcDate -Key "TC3$SecretKey" -Binary
- $SecretService = Compute-HmacHash -Algorithm $HashAlgorithm -Message $Service -Key $SecretDate -Binary
- $SecretSigning = Compute-HmacHash -Algorithm $HashAlgorithm -Message "tc3_request" -Key $SecretService -Binary
- $Signature = Compute-HmacHash -Algorithm $HashAlgorithm -Message $StringToSign -Key $SecretSigning
-
- $Authorization = "$SignatureAlgorithm Credential=$SecretId/$CredentialScope, SignedHeaders=$SignedHeaders, Signature=$Signature"
-
- $Headers = @{
- "Authorization" = $Authorization
- "Content-Type" = $ContentType
- "Host" = $HostName
- "X-TC-Action" = $Action
- "X-TC-Timestamp" = $Timestamp
- "X-TC-Version" = $Version
- }
-
- $InvokingArguments = @{
- "Uri" = $Endpoint
- "Method" = "POST"
- "Headers" = $Headers
- "Body" = $RequestPayload
- }
- # Powershell 6.0+ 支持 -SkipHeaderValidation 跳过请求头验证
- If($PsVersion -ge [System.Version]"6.0"){
- $InvokingArguments.SkipHeaderValidation = $True
- }
- $ResponseText = Invoke-WebRequest @InvokingArguments | Select-Object -ExpandProperty Content
- $ResponseObject = ConvertFrom-Json -InputObject $ResponseText
- If($ResponseObject -IsNot [System.Object]){
- $ResponseObject = New-Object -TypeName System.Object
- }ElseIf($ResponseObject.Response -Is [System.Object]){
- $ResponseObject = $ResponseObject.Response
- }
- If($ResponseObject.Error -and $ResponseObject.Error.Message){
- Write-Warning ($Action + ": " + $ResponseObject.Error.Message)
- }
- }
- Return $ResponseObject
- }
- <#
- .Description 调用接口更新域名解析记录值
- .Link wuxiancheng.cn
- .Notes 本程序由吴先成编写
- .Parameter [String] $Domain 域名 如 wuxiancheng.cn
- .Parameter [String] $Record 记录名 如 www
- .Parameter [String] $Type 记录类型 如 A AAAA
- .Parameter [String] $LineId 线路编号 0 代表默认线路
- .Outputs [Boolean] 成功时返回 $True 失败时返回 $False
- #>
- Function Update-RecordValue{
- [CmdletBinding(PositionalBinding=$False)]
- Param(
- [String]$Domain,
- [String]$Record,
- [String]$Type,
- [String]$Value,
- [String]$LineId="0"
- )
- $Response = Make-ApiRequest -Action DescribeRecordFilterList -Fields @{
- "Domain" = $Domain
- "SubDomain" = $Record
- "IsExactSubDomain" = $True
- "RecordType" = @($Type)
- "RecordLine" = @($LineId)
- }
- If($Response.RecordList -is [System.Array]){
- ForEach($RecordObject in $Response.RecordList){
- If($RecordObject.Value -eq $Value){
- Return $True
- }
- $Response = Make-ApiRequest -Action ModifyRecordFields -Fields @{
- "Domain" = $Domain
- "RecordId" = $RecordObject.RecordId
- "FieldList" = @(@{
- "Key" = "value"
- "Value" = $Value
- })
- }
- Return $Null -eq $Response.Error
- }
- }
- Return $False
- }
- Update-RecordValue -Domain "51-n.com" -Record "www" -Type A -Value "175.155.81.103"
- Update-RecordValue -Domain "51-n.com" -Record "www" -Type AAAA -Value "2408:8266:2b01:a6fd:54e2:d4af:3da6:184f"
复制代码 运行脚本前务必将 Make-ApiRequest 中的 $SecretId $SecretKey 修改为自己的密钥信息,如果没有腾讯云云 API 密钥,需要先申请。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?新建账号
×
|