域名还能绑定动态IP(真是又涨见识了,再也不用购买固定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不一致时,新增或者更新域名解析记录
实现方案【域名还能绑定动态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-82,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:

    推荐阅读