生活随笔
收集整理的這篇文章主要介紹了
                                
Python 实现动态解析阿里云DNS记录
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
 
                                
                            
                            
                            一、背景
 
最近有一個需求,公司內網的IP地址會發生變化,導致阿里云域名不能解析到新的IP地址,此時我們需要對阿里云的域名進行更新
 
二、實現
 
2.1 獲取本地出口的公網IP
 
2.1.1 通過命令或網頁 - 獲取本地出口的公網IP**
 
獲取本地IP的方式有很多,可以通過訪問一些網站來獲取本地的公網IP地址
 
1. curl ifconfig.me
2. curl -L ip.tool.lu
3. 以及一些在線查詢網頁然后解析內容來獲取我們的公網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.d
root@rion:/etc/nginx/conf.d# ls
remote_ip.conf
root@rion:/etc/nginx/conf.d# cat remote_ip.conf
real_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 。
 
 參考鏈接: https://help.aliyun.com/document_detail/38738.html
 
 
2.2.2 代碼實現
 
-  下載python包 aliyun-python-sdk-core-v3
aliyun-python-sdk-alidns
-  代碼 
import requests
import traceback
import time
from datetime 
import datetime
import json
import sys
from aliyunsdkcore
.client 
import AcsClient
from aliyunsdkalidns
.request
.v20150109
.DescribeDomainRecordsRequest 
import DescribeDomainRecordsRequest
from aliyunsdkalidns
.request
.v20150109
.UpdateDomainRecordRequest 
import UpdateDomainRecordRequest
class DNSRecord:json_data 
= None        client 
= None           public_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@classmethod     def 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
.text
return 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_time
print(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
()              if not ret
:time
.sleep
(10)continuedns_time 
= cls
.dns_record_dic
['time']if not public_time
:             ret 
= cls
.get_public_ip
()               if not ret
:time
.sleep
(10)continuepublic_time 
= cls
.public_dic
['time']if (public_time 
- dns_time
).total_seconds
() < 300:  print("本地更新時間與云端更新時間差小于5分鐘")time
.sleep
(10)continueelse:public_ret 
= cls
.get_public_ip
()               if not public_ret
:time
.sleep
(10)continuedns_ret 
= cls
.get_dns_record
()                 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
:                     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
()
 
 
{"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,保證了一定的穩定性。
 
 參考鏈接: https://help.aliyun.com/document_detail/124923.html
 
 
以上是python實現動態更新阿里云DNS解析記錄的代碼,除了更新記錄之外還可以增加記錄,刪除記錄等。
                            總結
                            
                                以上是生活随笔為你收集整理的Python 实现动态解析阿里云DNS记录的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。