阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

域名绑定动态IP实战案例

365次阅读
没有评论

共计 5051 个字符,预计需要花费 13 分钟才能阅读完成。

导读 一般家庭网络的公网 IP 都是不固定的,而我又想通过域名来访问自己服务器上的应用,也就是说:需要通过将域名绑定到动态 IP 上来实现这个需求。

域名绑定动态 IP 实战案例

一般家庭网络的公网 IP 都是不固定的,而我又想通过域名来访问自己服务器上的应用,也就是说:需要通过将域名绑定到动态 IP 上来实现这个需求。于是乎,我开始探索实现的技术方案。

通过在网上查阅一系列的资料后,发现阿里云可以做到实现动态域名解析 DDNS。于是乎,一顿操作下来,我实现了域名绑定动态 IP。这里,我们以 Python 为例实现。

好了,说干就干,我们开始吧,走起~~

阿里云 DDNS 前置条件
  • 域名是在阿里云购买的
  • 地址必须是公网地址,不然加了解析也没有用
  • 通过阿里云提供的 SDK,然后自己编写程序新增或者修改域名的解析,达到动态解析域名的目的; 主要应用于 pppoe 拨号的环境,比如家里设置了服务器,但是外网地址经常变化的场景; 再比如公司的 pppoe 网关,需要建立 vpn 的场景。

    安装阿里云 SDK

    需要安装两个 SDK 库,一个是阿里云核心 SDK 库,一个是阿里云域名 SDK 库;

    阿里云核心 SDK 库

    pip install aliyun-python-sdk-core

    阿里云域名 SDK 库

    pip install aliyun-python-sdk-domain

    阿里云 DNSSDK 库

    pip install aliyun-python-sdk-alidns
    设计思路
  • 获取阿里云的 accessKeyId 和 accessSecret
  • 获取外网 ip
  • 判断外网 ip 是否与之前一致
  • 外网 ip 不一致时,新增或者更新域名解析记录
  • 实现方案

    这里,我直接给出完整的 Python 代码,小伙伴们自行替换 AccessKey 和 AccessSecret。

    #!/usr/bin/env python
    #coding=utf-8
    
    # 加载核心 SDK
    from aliyunsdkcore.client import AcsClient
    from aliyunsdkcore.acs_exception.exceptions import ClientException
    from aliyunsdkcore.acs_exception.exceptions import ServerException
    
    # 加载获取、新增、更新、删除接口
    from aliyunsdkalidns.request.v20150109 import DescribeSubDomainRecordsRequest, AddDomainRecordRequest, UpdateDomainRecordRequest, DeleteDomainRecordRequest
    
    # 加载内置模块
    import json,urllib
    
    # AccessKey 和 Secret  建议使用 RAM 子账户的 KEY 和 SECRET 增加安全性
    ID = 'xxxxxxx'
    SECRET = 'xxxxxx'
    
    # 地区节点 可选地区取决于你的阿里云帐号等级,普通用户只有四个,分别是杭州、上海、深圳、河北,具体参考官网 API
    regionId = 'cn-hangzhou'
    
    # 配置认证信息
    client = AcsClient(ID, SECRET, regionId)
    
    # 设置主域名
    DomainName = 'binghe.com'
    
    # 子域名列表  列表参数可根据实际需求增加或减少值
    SubDomainList = ['a', 'b', 'c']
    
    # 获取外网 IP   三个地址返回的 ip 地址格式各不相同,3322 的是最纯净的格式,备选 1 为 json 格式  备选 2 为 curl 方式获取  两个备选地址都需要对获取值作进一步处理才能使用
    def getIp():
        # 备选地址:1,http://pv.sohu.com/cityjson?ie=utf-8    2,curl -L tool.lu/ip
        with urllib.request.urlopen('http://www.3322.org/dyndns/getip') as response:
            html = response.read()
            ip = str(html, encoding='utf-8').replace("\n", "")
        return ip
    
    # 查询记录
    def getDomainInfo(SubDomain):
        request = DescribeSubDomainRecordsRequest.DescribeSubDomainRecordsRequest()
        request.set_accept_format('json')
    
        # 设置要查询的记录类型为 A 记录   官网支持 A / CNAME / MX / AAAA / TXT / NS / SRV / CAA / URL 隐性(显性)转发  如果有需要可将该值配置为参数传入
        request.set_Type("A")
    
        # 指定查记的域名 格式为 'test.binghe.com'
        request.set_SubDomain(SubDomain)
    
        response = client.do_action_with_exception(request)
        response = str(response, encoding='utf-8')
    
        # 将获取到的记录转换成 json 对象并返回
        return json.loads(response)
    
    # 新增记录 (默认都设置为 A 记录,通过配置 set_Type 可设置为其他记录)
    def addDomainRecord(client,value,rr,domainname):
        request = AddDomainRecordRequest.AddDomainRecordRequest()
        request.set_accept_format('json')
    
        # request.set_Priority('1')  # MX 记录时的必选参数
        request.set_TTL('600')       # 可选值的范围取决于你的阿里云账户等级,免费版为 600 - 86400 单位为秒 
        request.set_Value(value)     # 新增的 ip 地址
        request.set_Type('A')        # 记录类型
        request.set_RR(rr)           # 子域名名称  
        request.set_DomainName(domainname) #主域名
    
        # 获取记录信息,返回信息中包含 TotalCount 字段,表示获取到的记录条数 0 表示没有记录,其他数字为多少表示有多少条相同记录,正常有记录的值应该为 1,如果值大于 1 则应该检查是不是重复添加了相同的记录
        response = client.do_action_with_exception(request)
        response = str(response, encoding='utf-8')
        relsult = json.loads(response)
        return relsult
    
    # 更新记录
    def updateDomainRecord(client,value,rr,record_id):
        request = UpdateDomainRecordRequest.UpdateDomainRecordRequest()
        request.set_accept_format('json')
    
        # request.set_Priority('1')
        request.set_TTL('600')
        request.set_Value(value) # 新的 ip 地址
        request.set_Type('A')
        request.set_RR(rr)
        request.set_RecordId(record_id)  # 更新记录需要指定 record_id,该字段为记录的唯一标识,可以在获取方法的返回信息中得到该字段的值
    
        response = client.do_action_with_exception(request)
        response = str(response, encoding='utf-8')
        return response
    
    # 删除记录
    def delDomainRecord(client,subdomain):
        info = getDomainInfo(subdomain)
        if info['TotalCount'] == 0:
            print('没有相关的记录信息,删除失败!')
        elif info["TotalCount"] == 1:
            print('准备删除记录')
            request = DeleteDomainRecordRequest.DeleteDomainRecordRequest()
            request.set_accept_format('json')
    
            record_id = info["DomainRecords"]["Record"][0]["RecordId"]
            request.set_RecordId(record_id) # 删除记录需要指定 record_id,该字段为记录的唯一标识,可以在获取方法的返回信息中得到该字段的值
            result = client.do_action_with_exception(request)
            print('删除成功,返回信息:')
            print(result)
        else:
            # 正常不应该有多条相同的记录,如果存在这种情况,应该手动去网站检查核实是否有操作失误
            print("存在多个相同子域名解析记录值,请核查后再操作!")
    
    # 有记录则更新,没有记录则新增
    def setDomainRecord(client,value,rr,domainname):
        info = getDomainInfo(rr + '.' + domainname)
        if info['TotalCount'] == 0:
            print('准备添加新记录')
            add_result = addDomainRecord(client,value,rr,domainname)
            print(add_result)
        elif info["TotalCount"] == 1:
            print('准备更新已有记录')
            record_id = info["DomainRecords"]["Record"][0]["RecordId"]
            cur_ip = getIp()
            old_ip = info["DomainRecords"]["Record"][0]["Value"]
            if cur_ip == old_ip:
                print ("新 ip 与原 ip 相同,不更新!")
            else:
                update_result = updateDomainRecord(client,value,rr,record_id)
                print('更新成功,返回信息:')
                print(update_result)
        else:
            # 正常不应该有多条相同的记录,如果存在这种情况,应该手动去网站检查核实是否有操作失误
            print("存在多个相同子域名解析记录值,请核查删除后再操作!")
    
    
    IP = getIp()
    
    # 循环子域名列表进行批量操作
    for x in SubDomainList:
        setDomainRecord(client,IP,x,DomainName)
    
    # 删除记录测试
    # delDomainRecord(client,'b.jsoner.com')
    
    # 新增或更新记录测试
    # setDomainRecord(client,'192.168.3.222','a',DomainName)
    
    # 获取记录测试
    # print (getDomainInfo(DomainName, 'y'))
    
    # 批量获取记录测试
    # for x in SubDomainList:
    #     print (getDomainInfo(DomainName, x))
    
    # 获取外网 ip 地址测试
    # print ('(' + getIp() + ')')

    Python 脚本的功能如下:

  • 获取外网 ip 地址。
  • 获取域名解析记录。
  • 新增域名解析记录。
  • 更新域名解析记录。
  • 删除域名解析记录 (并不建议将该功能添加在实际脚本中)。
  • 批量操作,如果记录不存在则添加记录,存在则更新记录。
  • 另外,有几点需要特别说明:

  • 建议不要将删除记录添加进实际使用的脚本当中。
  • 相同记录是同一个子域名的多条记录,比如 test.binghe.com。
  • 脚本并没有验证记录类型,所以同一子域名下的不同类型的记录也会认为是相同记录,比如:有两条记录分别是 test.binghe.com 的 A 记录 和 test.binghe.com 的 AAAA 记录,会被认为是两条相同的 test.binghe.com 记录. 如果需要判定为不同的记录,小伙伴们可以根据上述 Python 脚本自行实现。
  • 可以通过判断获取记录返回的 record_id 来实现精确匹配记录。
  • 最后,可以将以上脚本保存为文件之后,通过定时任务,来实现定期自动更新 ip 地址。

    正文完
    星哥玩云-微信公众号
    post-qrcode
     0
    星锅
    版权声明:本站原创文章,由 星锅 于2024-07-25发表,共计5051字。
    转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
    【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
    阿里云-最新活动爆款每日限量供应
    评论(没有评论)
    验证码
    【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

    星哥玩云

    星哥玩云
    星哥玩云
    分享互联网知识
    用户数
    4
    文章数
    19352
    评论数
    4
    阅读量
    8072892
    文章搜索
    热门文章
    星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

    星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

    星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
    星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

    星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

    星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
    再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

    再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

    再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
    飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

    飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

    飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
    免费领取huggingface的2核16G云服务器,超简单教程

    免费领取huggingface的2核16G云服务器,超简单教程

    免费领取 huggingface 的 2 核 16G 云服务器,超简单教程 前言 HuggingFace.co...
    阿里云CDN
    阿里云CDN-提高用户访问的响应速度和成功率
    随机文章
    再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

    再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

    再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
    免费领取huggingface的2核16G云服务器,超简单教程

    免费领取huggingface的2核16G云服务器,超简单教程

    免费领取 huggingface 的 2 核 16G 云服务器,超简单教程 前言 HuggingFace.co...
    恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击

    恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击

    恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击 PHP-FPM(FastCGl Process M...
    亚马逊云崩完,微软云崩!当全球第二大云“摔了一跤”:Azure 宕机背后的配置风险与警示

    亚马逊云崩完,微软云崩!当全球第二大云“摔了一跤”:Azure 宕机背后的配置风险与警示

    亚马逊云崩完,微软云崩!当全球第二大云“摔了一跤”:Azure 宕机背后的配置风险与警示 首先来回顾一下 10...
    2025年11月28日-Cloudflare史诗级事故:一次配置失误,引爆全球宕机

    2025年11月28日-Cloudflare史诗级事故:一次配置失误,引爆全球宕机

    2025 年 11 月 28 日 -Cloudflare 史诗级事故: 一次配置失误,引爆全球宕机 前言 继今...

    免费图片视频管理工具让灵感库告别混乱

    一言一句话
    -「
    手气不错
    让微信公众号成为 AI 智能体:从内容沉淀到智能问答的一次升级

    让微信公众号成为 AI 智能体:从内容沉淀到智能问答的一次升级

    让微信公众号成为 AI 智能体:从内容沉淀到智能问答的一次升级 大家好,我是星哥,之前写了一篇文章 自己手撸一...
    星哥带你玩飞牛 NAS-10:备份微信聊天记录、数据到你的NAS中!

    星哥带你玩飞牛 NAS-10:备份微信聊天记录、数据到你的NAS中!

    星哥带你玩飞牛 NAS-10:备份微信聊天记录、数据到你的 NAS 中! 大家对「数据安全感」的需求越来越高 ...
    支付宝、淘宝、闲鱼又双叕崩了,Cloudflare也瘫了连监控都挂,根因藏在哪?

    支付宝、淘宝、闲鱼又双叕崩了,Cloudflare也瘫了连监控都挂,根因藏在哪?

    支付宝、淘宝、闲鱼又双叕崩了,Cloudflare 也瘫了连监控都挂,根因藏在哪? 最近两天的互联网堪称“故障...
    每天一个好玩的网站-手机博物馆-CHAZ 3D Experience

    每天一个好玩的网站-手机博物馆-CHAZ 3D Experience

    每天一个好玩的网站 - 手机博物馆 -CHAZ 3D Experience 一句话介绍:一个用 3D 方式重温...
    欧洲无限速云盘免费10GB永久存储 + WebDAV部署+图床搭建,多平台联动一步到位!

    欧洲无限速云盘免费10GB永久存储 + WebDAV部署+图床搭建,多平台联动一步到位!

    欧洲无限速云盘免费 10GB 永久存储 + WebDAV 部署 + 图床搭建,多平台联动一步到位! 大家好,我...