1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Python 实现动态解析阿里云DNS记录

Python 实现动态解析阿里云DNS记录

时间:2018-12-22 21:56:22

相关推荐

Python 实现动态解析阿里云DNS记录

一、背景

最近有一个需求,公司内网的IP地址会发生变化,导致阿里云域名不能解析到新的IP地址,此时我们需要对阿里云的域名进行更新

二、实现

2.1 获取本地出口的公网IP

2.1.1 通过命令或网页 - 获取本地出口的公网IP**

获取本地IP的方式有很多,可以通过访问一些网站来获取本地的公网IP地址

1. curl ifconfig.me2. curl -L ip.tool.lu3. 以及一些在线查询网页然后解析内容来获取我们的公网IP地址

2.1.2 通过Nginx 获取我们的公网IP

我们通过在云端创建一个主机地址,然后通过nginx来获取访问者的公网IP,这样的好处是我们自己搭建的服务比较稳定可靠

1. 创建阿里云主机记录

在域名服务中通过访问域名列表点击解析

2. 新增获取访问者IP的主机记录

设置主机地址,记录值这里填写自己阿里云的IP地址,这是为了访问这个域名地址时,nginx返回访问者的IP地址。

3. 新增测试的主机记录

我们可以自己在新建一个记录,主机记录随意填写一个如dev,IP地址也可以随意填写一个。

4. Nginx 返回对应的域名时返回访问者的IP

新建一个nginx的配置文件,指定域名返回的内容

root@rion:/etc/nginx/conf.d# pwd/etc/nginx/conf.droot@rion:/etc/nginx/conf.d# lsremote_ip.confroot@rion:/etc/nginx/conf.d# cat remote_ip.confreal_ip_recursive on;server {listen 80;# 指定访问端口,如果不想用80端口,需要在阿里云开启对应的端口server_name ip.xxx.xx;# 省略其他配置....# nginx直接返回客户端IP到bodylocation /ip {default_type text/plain;return 200 "$remote_addr";}}root@rion:/etc/nginx/conf.d# nginx -s reload

访问对应的域名查看结果是否正确,返回的结果时正确的。

2.2 实现动态更新阿里云IP地址

2.2.1 获取AccessKey ID和AccessKey Secret

我们使用SDK时,需要使用到AccessKey ID和AccessKey Secret 。

参考链接: /document_detail/38738.html

2.2.2 代码实现

下载python包

aliyun-python-sdk-core-v3aliyun-python-sdk-alidns

代码

import requestsimport tracebackimport timefrom datetime import datetimeimport jsonimport sysfrom aliyunsdkcore.client import AcsClientfrom aliyunsdkalidns.request.v0109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequestfrom aliyunsdkalidns.request.v0109.UpdateDomainRecordRequest import UpdateDomainRecordRequestclass DNSRecord:json_data = None # json 配置文件内容client = None # 阿里云clientpublic_dic = {"time":None,"ip":None}dns_record_dic = {"time":None,"ip":None,"record_id":None}@classmethoddef init(cls):"""初始化阿里云 client"""try:cls.client = AcsClient(cls.json_data['id'], cls.json_data['secret'], cls.json_data['region'])print("Aliyun key 认证成功")return Trueexcept Exception as e:print("Aliyun key 认证失败")return False@classmethoddef reload_config(cls):"""加载配置文件"""with open('./config.json',mode='r',encoding='utf-8') as fp:cls.json_data = json.load(fp)@classmethoddef get_dns_record(cls):"""获取dns记录"""try:request = DescribeDomainRecordsRequest()request.set_accept_format('json')request.set_DomainName(cls.json_data['domain_name'])response = cls.client.do_action_with_exception(request)data = json.loads(str(response, encoding='utf-8'))for record in data['DomainRecords']['Record']:if cls.json_data['RR'] == record['RR']:cls.dns_record_dic['time'] = datetime.now()cls.dns_record_dic['ip'] = record['Value']cls.dns_record_dic['record_id'] = record['RecordId']return Trueexcept:traceback.print_exc()return False@classmethoddef get_public_ip(cls):"""获取公网IP"""for url in cls.json_data['public_url']:try:request_obj = requests.get(url,timeout=5)if request_obj.status_code == 200:cls.public_dic['time'] = datetime.now()cls.public_dic['ip'] = request_obj.textreturn Trueexcept:traceback.print_exc()return False@classmethoddef update_dns_record(cls,public_ip):update_time = datetime.now()update_time_str = update_time.strftime("%Y-%m-%d %H:%M:%S")try:request = UpdateDomainRecordRequest()request.set_accept_format('json')request.set_Value(public_ip)request.set_Type(cls.json_data['type'])request.set_RR(cls.json_data['RR'])request.set_RecordId(cls.dns_record_dic['record_id'])response = cls.client.do_action_with_exception(request)cls.public_dic['time'] = update_timecls.dns_record_dic['time'] = update_timeprint(f"[更新成功 {update_time_str}] 域名:{cls.json_data['domain_name']} + \主机:{cls.json_data['RR']} 记录类型:{cls.json_data['type']} + \IP地址:{cls.dns_record_dic['ip']}")return Trueexcept Exception as e:print(f"域名:{cls.json_data['domain_name']} 主机:{cls.json_data['RR']} 解析失败,错误:",e)return False@classmethoddef main(cls):cls.reload_config()cls.init()while True:public_time = cls.public_dic['time']dns_time = cls.dns_record_dic['time']if not dns_time:ret = cls.get_dns_record() # 更新云端的IP、时间、record_idif not ret:time.sleep(10)continuedns_time = cls.dns_record_dic['time']if not public_time: ret = cls.get_public_ip()# 更新本地公网的IP、时间if not ret:time.sleep(10)continuepublic_time = cls.public_dic['time']if (public_time - dns_time).total_seconds() < 300: # 本地时间和云端时间小于5分钟print("本地更新时间与云端更新时间差小于5分钟")time.sleep(10)continueelse:public_ret = cls.get_public_ip()# 更新本地公网的IP、时间if not public_ret:time.sleep(10)continuedns_ret = cls.get_dns_record() # 获取阿里云dns记录if not dns_ret:time.sleep(10)continuepublic_ip = cls.public_dic['ip']dns_ip = cls.dns_record_dic['ip']if public_ip != dns_ip: # 本地公网IP和云端IP不相等ret = cls.update_dns_record(public_ip)if not ret:time.sleep(10)else:time.sleep(10)if __name__ == "__main__":dns_r = DNSRecorddns_r.main()

Json配置文件

{"id":"xxxxxxxxxxxxxxxxxx","secret":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx","region":"cn-hangzhou","RR":"dev","type":"A","domain_name":"xxxxx.xx","public_url":["http://ip.xx.xx/ip","http://xx.xxx.xx:8899/ip"]}

这里获取本地公网IP的对象为列表,若一个获取地址的URL挂掉了,我们还可以从另一个地址获取本地公网的IP,保证了一定的稳定性。

参考链接: /document_detail/124923.html

以上是python实现动态更新阿里云DNS解析记录的代码,除了更新记录之外还可以增加记录,删除记录等。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。