MENU

【日常Py】阿里云域名云解析简易SDK

October 7, 2018 • Read: 1207 • 程序源码

博客数据被清空,再发一次
阿里云域名解析官方开发文档:https://help.aliyun.com/document_detail/29739.html?spm=a2c4g.11186631.6.610.7ad349692ujA1D

前段时间玩树莓派,用来WEB服务器的时候内网渗透,阿里云域名做DDNS(动态域名绑定),根据官方文档写的;这个简易SDK只增加了解析的增删改部分,如需其他根据其修改即可。

AliDNS SDK实现源码

# -*- coding: utf-8 -*-

class AliDns:
    '''
    author:小珏
    update:2018-09-23
    博客地址:http://qzone.work
    密匙获取地址 https://usercenter.console.aliyun.com/#/manage/ak
    API官方文档 https://help.aliyun.com/document_detail/29772.html?spm=a2c4g.11186623.6.639.79b06e00Jyr2oG
    简单介绍:对阿里云DNS解析进行简单调用开发,目前添加了基础的增删改查记录功能,如需其它功能请自行删改。
    不得不吐槽的一点是,阿里官方文档对签名算法的描述真好,可能是我太笨,就这个算法花了80%时间...
    '''
    
    aliAPI='https://alidns.aliyuncs.com/?'
    AccessKeyId='LTAIUfi4VEfLbd8G'   
    AccessKeySecret='UYkkUyG8wI9AVmYg5bF7aGYVTXfjiN'   
    

    def __init__(self):
        self.paras=dict()
        self.paras['Format']='JSON'  #返回类型
        self.paras['Version']='2015-01-09'  #API版本
        self.paras['AccessKeyId']=AliDns.AccessKeyId
        self.paras['SignatureMethod']='HMAC-SHA1'  #签名方式
        self.paras['SignatureVersion']='1.0'  #签名算法版本
        
    def getDomainRecords(self,domain=''):#获取域名解析信息
        self.__init__()
        self.paras['Action']='DescribeDomainRecords'
        self.paras['DomainName']=domain
        self.paras['PageNumber']='1'
        self.paras['PageSize']='300'
        return self.getResult(self.paras)
    
    def addDomainRecord(self,Domain,RR,Type,Value,TTL='600',Priority='10',Line='default'):#添加域名解析
        self.__init__()
        self.paras['Action']='AddDomainRecord'
        self.paras['DomainName']=Domain 
        self.paras['RR']=RR   #主机记录
        self.paras['Type']=Type  #A 记录,CNAME记录  常用
        self.paras['Value']=Value  
        self.paras['TTL']=TTL
        self.paras['Priority']=Priority
        return self.getResult(self.paras)
    
    def delDomainRecord(self,RecordId):#删除域名解析
        self.__init__()
        self.paras['Action']='DeleteDomainRecord'
        self.paras['RecordId']=RecordId
        return self.getResult(self.paras)
    
    def upDomainRecord(self,RecordId,RR,Type,Value,TTL='600',Priority='10',Line='default'):#更新域名解析
        self.__init__()
        self.paras['Action']='UpdateDomainRecord'
        self.paras['RecordId']=RecordId
        self.paras['RR']=RR   
        self.paras['Type']=Type 
        self.paras['Value']=Value  
        self.paras['TTL']=TTL
        self.paras['Priority']=Priority
        return self.getResult(self.paras)
    
    def getResult(self,paras):
        import requests as re,json
        self.paras['Timestamp']=self.UTC_now()  #请求时间
        self.paras['SignatureNonce']=self.randstr(32)  #唯一随机值
        self.paras['Signature']=self.Signature(self.StringToSign(self.paras)) #签名
        #GET_URL=self.getAPI(self.paras)
        #ret=json.loads(re.get(GET_URL).text)   #get 
        ret=json.loads(re.post(AliDns.aliAPI,self.paras).text)   #post
        return ret
    
    def getAPI(self,paras):
        url=AliDns.aliAPI
        for x in paras:
            url+=((x)+'='+(paras.get(x))+'&')
        return url[:-1]
    
    def percentEncode(self,paras):
        from urllib.parse import quote as urlencode
        res=urlencode(paras)
        res=res.replace('+','%20')
        res=res.replace('*','%2A')
        res=res.replace('%7E','~')
        return res
        
    def StringToSign(self,paras):
        key=sorted(paras)
        for x in range(len(key)):
            key[x]=key[x]+'='+self.percentEncode(paras.get(key[x]))
        key='&'.join(key)
        ret='POST&%2F&'+str(self.percentEncode(key))
        return (ret)
    
    def Signature(self,paras):
        import base64,hmac
        key=(AliDns.AccessKeySecret+'&').encode('utf-8')
        paras=paras.encode('utf-8')
        h=hmac.new(key,paras,digestmod='sha1')
        ret=base64.b64encode(h.digest())
        return ret.decode('utf-8')
    
    def randstr(self,length=0):
        import random
        km=''
        s='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
        if length == 0:
            length=32
        for x in range(length):
            i=random.randint(0,len(s)-1)
            km+=s[i]
        return(km)
        
    def UTC_now(self):
        import datetime
        return datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')

树莓派调用实现代码,实例化之后直接调用即可:

# -*- coding: utf-8 -*-

import AliDns,time,requests

#监控周期 单位min
time_='60'

def main():
    #=========================
    domain='qzone.club' 
    get_ip='http://45.32.164.128/ip.php'
    RR='m'
    ret={'Code':'0','Msg':None}
    isSet=False #判断记录是否存在
    #=========================
    ip=requests.get(get_ip)
    if ip.status_code == requests.codes.ok:
        ip=ip.text.strip() #获取本机IP
        dns=AliDns.AliDns() #初始化DNS对象
        res=dns.getDomainRecords(domain) #获取域名解析记录
        if res.get('DomainRecords'):
            records_list=res.get('DomainRecords').get('Record')
            for x in records_list:
                if x.get('RR') ==RR:
                    isSet=True
                    RecordId=x.get('RecordId')
            if isSet:#已存在则修改
                dns.upDomainRecord(RecordId,RR,'A',ip)
                ret['Code']='1'
                ret['Msg']=('已存在则修改')
            else:    #不存在则添加
                dns.addDomainRecord(domain,RR,'A',ip)
                ret['Code']='1'
                ret['Msg']=('不存在则添加')
        else:
            ret['Msg']='域名解析记录获取失败'
    else:
        ret['Msg']='IP获取失败'
    return ret
if __name__ == '__main__':
    while True:
        try:
            res=main()
            date=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
            log=open('./log.txt','a')
            log.write(date+'----'+res.get('Msg')+'\r\n')
            log.close()
            time.sleep(time_)
        except:
            break