700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 利用阿里云API为树莓派做DDNS

利用阿里云API为树莓派做DDNS

时间:2023-10-11 09:31:43

相关推荐

利用阿里云API为树莓派做DDNS

一直想利用树莓派亲手搭建几种服务器来加深了解,奈何电信光猫每次重启后都会重新分配公网IP。

只能先想办法解决这个最基本的问题,起初的时候没想到该怎么搞。当时手里有一个便宜买的海外虚拟主机,打算让树莓派每次开机后自动发送自己的IP到那个主机上,然后我需要外网访问的时候,从海外主机获取到ip然后在访问。。。。。后来想了想我图个啥。 最后从网络上找了这种通过阿里API去动态解析IP的方式,不过网上找到的虽然思路基本相同,但方法五花八门,而且调用api方法我至今没完全搞懂,只好摸索着用现在这个办法,记录一下。

思路:

1、树莓派利用api获取自己的公网ip

2、调用阿里云api将我的域名解析到当前树莓派的公网ip上,并且避免解析的地址相同(api会报错)

一、准备

1、树莓派、阿里云的域名(便宜的几块钱一年)、有公网ip且可以设置端口映射的路由

2、安装阿里云的python版本的sdk,我这个只用了核心库,里面有api的泛用型调用命令。

/tools/sdk?spm=5176.11122631.962077.5.d8f63801lb9te1#/python

我是直接用下面这个pip命令安装的,因为别的方法我不会,官方提供了一个httpdns的sdk。我估摸着应该是把方法都封装了更简便的样子。

3、得到你自己的AccessKey

在网页端阿里云控制台点击你的头像就能看到了,会生成一个AccessKey ID和Access Key Secret。这两个东西是过会调用api时验证你身份用的。

二、实施

1、获取树莓派当前的公网IP

调用网上找的获取IP地址的API,返回的就是自己访问公网的IP。我用的是这个: /tools/getip/

def getip():res=request.urlopen('/tools/getip/')return str(res.read(),'utf-8')

这个返回的就是自己公网的IP字符串。

2、构建客户端对象

构建一个包含你的AccessKey ID和Access Key Secret的客户段对象,后面会加到请求中

导入

from aliyunsdkcore.client import AcsClient

创建

client = AcsClient('你的AccessKey ID', '你的Access Key Secret', 'cn-hangzhou')

3、定义查询方法

导入

from aliyunsdkcore.request import CommonRequest

CommonRequest使用的介绍:

/document_detail/61476.html?spm=5176.10695662.1996646101.searchclickresult.61f2243bEt8PWL

def queryrecordid():request = CommonRequest()request.set_accept_format('json') #设置接收格式,有json和xml两种request.set_domain('') #请求地址request.set_method('POST')#请求方式,GET和POST两种request.set_version('-01-09') #版本信息request.set_action_name('DescribeDomainRecordInfo') #set_action_name这个是设置调用的方法request.add_query_param('RecordId', '解析记录的ID') #request.add_query_param添加参数response = client.do_action_with_exception(request) return json.loads(str(response,'utf-8'))['Value'] #只读取返回数据中的value也就是IP

图中调用的时候应该有异常处理,但我对python还不熟悉,所以当时没敢搞,回头再来解决。

基本调用api就是更改一下action参数和参数的变化,具体的参数信息也都能从api文档里找到

解析记录的id需要调用DescribeDomainRecords获取解析记录的方法,可以调用之后记下来,后面只需要对这条记录进行更改和查询就行了。

def querylist():request=CommonRequest()request.set_accept_format('json')request.set_domain('')request.set_method('POST')request.set_version('-01-09')request.set_action_name('DescribeDomainRecords')request.add_query_param('DomainName','你的域名')response=client.do_action_with_exception(request)print(str(response,'utf-8'))

4、定义更新方法

def updaterecordid(value):request = CommonRequest()request.set_accept_format('json')request.set_domain('')request.set_method('POST')request.set_version('-01-09')request.set_action_name('UpdateDomainRecord')request.add_query_param('RecordId', '解析记录ID')request.add_query_param('RR', '*')request.add_query_param('Type', 'A')request.add_query_param('Value', '解析到的IP地址') #上面三个值的解释都在api文档response = client.do_action_with_exception(request)

api地址:/document_detail/29774.html?spm=a2c4g.11186623.6.641.7b435eb4WHrsn4

5、防止解析到同一个地址

ip=getip()oldip=queryrecordid()if oldip!=ip:updaterecordid(ip)print('The new IP is',ip)else:print("IP address not updated")

网上有的方法是直接将上次解析的地址写入本地,这样就可以减少api的调用次数,不过我水平有限也不太喜欢在本地再生成一个文件,于是就直接用当前地址和解析记录中的地址对比了。

6、部署

因为我家的路由和派是在同一个插排上的,所以每次开启路由器时树莓派也一块启动,这样就可以把这个代码放到树莓派的开机执行里运行,不过路由器开机时间长,所以我设置树莓派开机3分钟后自动执行。

执行命令

vi /etc/rc.local

加一段代码到exit 0之前

sleep 3m && python3 ddns.py &

休眠三分钟之后执行这个python程序,不过好像在rc.local中会阻塞开机,所以最后加一个&放到新的线程中运行

三、其他

在手机或者pc访问的时候会优先使用本机储存的dns缓存,所以更新的ip同步不过来,需要刷新dns缓存。win是在cmd中执行ipconfig/flushdns,手机直接飞行模式貌似就可以。

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