├── .gitignore ├── README.md ├── aimijia.py └── key.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 该项目为使用aliyun动态解析域名脚本,采用python编写,主要适用于在家里自己捣腾服务器的朋友们。由于家用宽带没有固定ip,所以一旦家里的路由器重新拨号了会分配到新的公网ip地址,这会导致在外网无法访问到服务器。东西很简单,一般有点编程知识的人都能看懂,不过在使用前最好再了解下以下几个注意点: 2 | 3 | 1.请记得保管好你的Access Key,所以我没有在我的代码里直接写Access Key Id和Access Key Secret,我把他们单独放在一个key.json文件中,同时将这个文件排除出git,保证只有我自己知道,因为一旦这两个值泄露了那别人就可以直接修改你的域名了。 4 | 5 | 2.阿里云通过RecordId来区分每条域名解析记录,但是他们之前文档上对于这个参数的描述只写了“解析记录的ID”,没有写如何获取这条解析记录ID,我去我的阿里云控制台上找了好久都没找到,到后来我突然想到sdk上有获取域名信息的api,我试着用这个果然返回的信息里有这个字段,后来联系了他们客服,他们也说在控制台上没办法找到,也只有通过api获取域名信息才能找到,后来他们也在文档中注明了这个字段的获取方式。 6 | 7 | 3.更新域名解析主要用到的是阿里云sdk包里aliyun/api/rest/Dns20150109UpdateDomainRecordRequest.py 方法,我为了偷懒直接在这个方法里写死了一些需要固定传入的参数,如果你要对自己的域名做解析的话记得去修改这些参数值。 8 | 9 | ## 20230304 update: 10 | 1.更新为使用阿里云python3接口,弃用原先下载sdk包调用形式 11 | 12 | 2.新增日志输出 13 | 14 | 参考文档:https://next.api.aliyun.com/api-tools/sdk/Alidns?version=2015-01-09&language=python-tea , https://next.api.aliyun.com/api-tools/demo/Alidns/87dd2c5a-bb87-4269-8bb1-6e021be52123 15 | -------------------------------------------------------------------------------- /aimijia.py: -------------------------------------------------------------------------------- 1 | import json 2 | import time 3 | import urllib.request 4 | 5 | from alibabacloud_tea_openapi import models as open_api_models 6 | from alibabacloud_alidns20150109 import models as alidns_models 7 | from alibabacloud_alidns20150109.client import Client as Client 8 | 9 | 10 | class DNS: 11 | 12 | def __init__(self): 13 | pass 14 | 15 | @staticmethod 16 | def init(id: str, secret: str): 17 | config = open_api_models.Config(id, secret) 18 | # 访问的域名 19 | config.endpoint = 'alidns.cn-hangzhou.aliyuncs.com' 20 | client = Client(config) 21 | return client 22 | 23 | # 获取当前ip地址 24 | @staticmethod 25 | def getMyIp(): 26 | try: 27 | response = urllib.request.urlopen("http://members.3322.org/dyndns/getip") 28 | resp = response.read().decode('utf-8') 29 | return resp.strip('\n') 30 | except Exception as e: 31 | DNS.print_log('getMyIp' + '|' + str(e)) 32 | return None 33 | 34 | # 获取域名已经配置解析的ip地址 35 | @staticmethod 36 | def getDNSIp(client: Client, record_id: str): 37 | requests = alidns_models.DescribeDomainRecordInfoRequest() 38 | requests.record_id = record_id 39 | try: 40 | resp = client.describe_domain_record_info(requests) 41 | # print(resp.body) 42 | return resp.body.value 43 | except Exception as e: 44 | DNS.print_log('getDNSIp' + record_id + '|' + str(e)) 45 | return None 46 | 47 | # 查询域名解析记录,主要用于查询解析记录的recordId 48 | @staticmethod 49 | def get_domain_info(client: Client, domain_name): 50 | 51 | req = alidns_models.DescribeDomainRecordsRequest() 52 | req.domain_name = domain_name 53 | try: 54 | resp = client.describe_domain_records(req) 55 | print(resp.body) 56 | except Exception as e: 57 | DNS.print_log('get_domain_info' + domain_name + '|' + str(e)) 58 | 59 | # 更新域名解析记录 60 | @staticmethod 61 | def update_domain(client: Client, newIp, recordId, rr): 62 | req = alidns_models.UpdateDomainRecordRequest() 63 | req.record_id = recordId 64 | req.rr = rr 65 | req.type = 'A' 66 | req.value = newIp 67 | try: 68 | resp = client.update_domain_record(req) 69 | # print(resp.body) 70 | return resp 71 | except Exception as e: 72 | DNS.print_log('update_domain' + newIp + '|' + str(e)) 73 | 74 | @staticmethod 75 | def print_log(log): 76 | log = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) + '|' + log + '\n' 77 | # print(log) 78 | with open('./result.log', 'a') as f: 79 | f.write(log) 80 | 81 | 82 | if __name__ == '__main__': 83 | # 加载配置文件 84 | jsonfile = open('key.json') 85 | s = json.load(jsonfile) 86 | 87 | client = DNS.init(s['id'], s['secret']) 88 | 89 | # DNS.get_domain_info(client, s['domain']) 90 | 91 | newip = DNS.getMyIp() 92 | oldip = DNS.getDNSIp(client, s['recordId']) 93 | if oldip != newip and newip is not None: 94 | resp = DNS.update_domain(client, newip, s['recordId'], s['rr']) 95 | DNS.print_log(newip + '|' + oldip + '|' + resp.body.request_id) 96 | -------------------------------------------------------------------------------- /key.json: -------------------------------------------------------------------------------- 1 | { 2 | "id":"aliyun-api-id", 3 | "secret":"aliyun-api-secret", 4 | "domain": "域名", 5 | "rr": "解析名", 6 | "recordId": "现有解析id" 7 | } 8 | --------------------------------------------------------------------------------