万网注册的域名有福了,背靠阿里这个大金主,最近推出了不少有用的功能,甩出新网之类的域名注册商不止一条街了。朋友之前一直使用DNSPod和花生壳来构筑VPN内网的域名解析,可TPLINK自带的路由器花生壳功能太不稳定了,DNSPod也拒绝加入那些免费的二级域名了,只能想看看有没有办法在他已有的域名上实现DDNS的二级域名解析了。凑巧看见万网和阿里云推出的云解析功能支持API调用,既然API可以实现域名管理的基本全部功能,那实现一个DDNS的客户端就可以完美替代花生壳的解决方案了。可惜没有找到现成的阿里云解析客户端,参考的实现也只有JAVA实现,虽然有完备的API开发文档,但对认证签名一块用Python实现起来还是有些含糊不清的地方。这里我详细给出了针对阿里云解析API(2015-01-09)版的认证这一块的代码,完整DDNS客户端请前往github搜索aliyun-ddns-client
另外要能够调用云解析的API,用户需要从阿里云获取Access ID和Access Key,步骤如下:
- 登陆 阿里云官方网站
- 进入页面上方菜单【用户中心】
- 进入上方二级菜单【我的服务】
- 进入左侧菜单【安全认证】
- 页面所显示的Access Key ID和Access Key Secret则为所需ID和Key
完整云解析OpenAPI文档下载: 万网–帮助中心–域名–域名解析–OpenAPI文档下载
签名参考Python代码
import urllib
import hashlib
import hmac
import uuid
def getSignatureNonce(self):
"""
Unique random value
"""
return uuid.uuid4()
def getTimeStamp(self):
"""
ISO8601 standard: YYYY-MM-DDThh:mm:ssZ, e,g:2015-0109T12:00:00Z (UTC Timezone)
@return string
"""
return datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
def getCommonParams(self):
commonParams = {
'Format': 'json',
'Version': '2015-01-09',
# 这里accessKeyId是阿里云获取的Access Key ID
'AccessKeyId': self.accessKeyId,
'TimeStamp': self.getTimeStamp(),
'SignatureMethod': 'HMAC-SHA1',
'SignatureNonce': self.getSignatureNonce(),
'SignatureVersion': "1.0",
}
return commonParams
def getSignature(self, httpMethod, params):
"""
1. params = combine specific params and common params
2. sortedParams = sort params by key
3. queryString = urlencode sortedParams
4. signString = HTTPMethod + "&" + urlencode "/" + quote_plus queryString
5. hashValue = sha1 with hashKey against signString
6. base64HashValue = base64 encoding hashValue
7. signature = urlencode base64HashValue
@return string
"""
# 获取API文档中的公共参数, 并与每个不同方法中的特殊参数合并
params.update(self.getCommonParams())
# 对应API文档中的1.11-1.a)步骤: 按参数Key字母排序
sortedParams = sorted(params.items())
# 对应API文档中的1.11-1.b)步骤: 对参数key和value进行URL编码
canonString = urllib.urlencode(sortedParams)
# 对应API文档中的1.11-2步骤: 构造签名所要使用的规范化字符串
signString = httpMethod + "&" + urllib.quote_plus("/") + "&" + urllib.quote_plus(canonString)
# 对应API文档中的1.11-3步骤: 对签名字符串计算HMAC值, 这里self.hashKey=阿里云获取的Access Key Secret + "&"
hashValue = hmac.new(self.hashKey, signString, hashlib.sha1).digest()
# 对应API文档中的1.11-4步骤: 对HMAC值进行base64编码
# 注意: 有些第三方http库比如requests会在发送请求时自动对所有参数再进行一次URL编码, 所以这里忽略1.11-5步骤
signature=hashValue.encode("base64").rstrip('n')
return signature