阿里云域名(解决服务器动态IP)

环境

python3

安装SDK

pip install pyyaml
pip install aliyun-python-sdk-core-v3
pip install aliyun-python-sdk-alidns==2.0.6

文件里面其实还有 sys、os、re、socket包,但是大多数都是自带的 如果说有没安装的就自己用pip安装

脚本python代码


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import json #使用 Python 语言来编码和解码 JSON 对象
import yaml #python中读取yaml文件
import sys #sys 是和Python解释器打交道的
import os #操作系统接口模块
import re #python正则匹配
import socket #python内置模块socket模块可解决基于tcp和ucp协议的网络传输
from aliyunsdkcore.client import AcsClient
from aliyunsdkalidns.request.v20150109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest
#++++++++++++++++++++
#文件更多详细使用方法
# 请访问:http://darker.hellosmile.xin/2020/09/24/
#++++++++++++++++++++
# 通过ifconfig命令获取所有网卡的IP然后进行正则匹配获取外网IP
def getwaiwang():
    # 使用os.popen()函数执行ifconfig命令,结果为file对象,将其传入cmd_file保存
    cmd_file = os.popen('ifconfig')
    # 使用file对象的read()方法获取cmd_file的内容
    cmd_result = cmd_file.read()
    # 构造用于匹配IP的匹配模式
    pattern = re.compile(r'(inet )(106.\d{1,3}.\d{1,3}.\d{1,3})')
    # 使用re模块的findall函数匹配
    ip_list = re.findall(pattern, cmd_result)
    # 返回外网IP地址
    # 至于为什么是[0][1]要根据实际情况而定修改时最好打印一下
    return (ip_list[0][1])

#获取域名解析的IP值
# 使用socket是python自带的方便一些
def getIP(domain):
    #domain为传入的域名string
    myaddr = socket.getaddrinfo(domain, 'http')
    return myaddr[0][4][0]

#验证AliAccessKey相关参数是否正确
def AliAccessKey(id,Secret,region):
    try:
        client = AcsClient(id, Secret, region)
        return client
    except Exception as e:
        print("验证aliyun key失败")
        print(e)
        sys.exit(-1)

#读取配置文件获取相关配置信息
def read_yaml(filename):
    try:
        yaml_file = open(filename,"rb")
        yaml_data = yaml.safe_load(yaml_file)
        yaml_file.close()
        return yaml_data
    except Exception as e:
        print("读取配置文件错误")
        print(e)
        sys.exit(-1)

#获取RecordId,因为这个是修改解析值必要值
#如何检测ID是否正常,可以在阿里云域名控制台f12并修改域名解析地址,在网络层可以看到RecordId的值
def GetDNSRecordId(yaml_data,client,DomainName):
    try:
        request = DescribeDomainRecordsRequest()
        request.set_accept_format('json')
        request.set_DomainName(DomainName)
        response = client.do_action_with_exception(request)
        json_data = json.loads(str(response, encoding='utf-8'))

        for RecordId in json_data['DomainRecords']['Record']:
            if yaml_data['UserData']['RR'] == RecordId['RR']:
                return RecordId['RecordId']

    except Exception as e:
        print("获取RecordId失败")
        print(e)
        sys.exit(-1)

#更新域名解析值
def UpdateDomainRecord(client,yaml_data,RecordId):
    #在这里输出主要是日志方面好隔开
    print('---------------')
    #判断域名指向的IP和本机外网IP是否一致,如果一致则不做请求
    if str(getIP("max.hellosmile.xin")) != str(getwaiwang()):
        print("域名IP"+getIP("max.hellosmile.xin"))
        print("本机外网IP"+getwaiwang())
        #更改域名解析值
        try:
            request = UpdateDomainRecordRequest()
            request.set_accept_format('json')
            #如果配置文件中UpdateDomain为Auto_Lines则解析地址为本机外网IP地址
            #否则解析值就直接为 UpdateDomain的值
            if 'Auto_Lines' == yaml_data['UserData']['UpdateDomain']:
                DomainValue = getwaiwang()
            else:
                DomainValue = yaml_data['UserData']['UpdateDomain']
            request.set_Value(DomainValue)
            request.set_Type(yaml_data['UserData']['DomainType'])
            request.set_RR(yaml_data['UserData']['RR'])
            request.set_RecordId(RecordId)
            response = client.do_action_with_exception(request)
            print("更新域名解析成功")
            print("域名:" + yaml_data['UserData']['DomainName'] + " 主机:" + yaml_data['UserData']['RR'] + " 记录类型:" +
                  yaml_data['UserData']['DomainType'] + " 记录值:" + DomainValue)
        except Exception as e:
            print("更新域名解析失败")
            print(e)
    else:
        print("域名IP:"+getIP('max.hellosmile.xin')+"本机IP:"+getwaiwang()+"《IP一致无需更改》")

def main():
    #加载配置文件(注意文件路径是否正确)
    yaml_data = read_yaml('./conf.yaml')
    #检测AliAccessKey值是否正确
    client = AliAccessKey(yaml_data['AliyunData']['AccessKey_ID'],yaml_data['AliyunData']['Access_Key_Secret'],yaml_data['AliyunData']['region_id'])
    #获取域名的RecordId
    RecordId = GetDNSRecordId(yaml_data,client,yaml_data['UserData']['DomainName'])
    #更新域名解析值
    UpdateDomainRecord(client,yaml_data,RecordId)

if __name__ == "__main__" :
    main()

脚本配置文件


# 阿里云信息,从阿里云获取填写即可
AliyunData:
  # 阿里云的AccessKey_ID , Access_Key_Secret , region_id
  # 获取方法,参考文档: https://help.aliyun.com/knowledge_detail/38738.html
  AccessKey_ID: 'XXXXX'
  Access_Key_Secret: 'XXXXX'
  region_id: "cn-hangzhou"

# DNS解析信息
UserData:
  # 需要修改的域名
  DomainName: 'hellosmile.xin'
  # 解析的主机
  RR: 'max'
  # 解析的记录
  DomainType: 'A'
  # 解析更新的值,如果填写 Auto_Lines ,则从调用python文件里面的的socket方法
  UpdateDomain: 'Auto_Lines'

使用方法

将脚本配置文件和python文件存放在一个文件夹中
使用python运行python脚本即可 (python3)

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注