大贤者
精华
|
战斗力 鹅
|
回帖 0
注册时间 2020-10-21
|
本帖最后由 冰箱研会长e-3M 于 2021-1-23 14:09 编辑
1. 精简版
使用脚本配合web api, 每隔一段时间就更新解析记录.
详情见下.
2. 购买域名
我所使用的域名购买于www.namesilo.com.
这家价格便宜, 有比较完整的web api, 文档说人话,
支付手段也算是丰富(好像有支付宝), 最重要的是我只用过这家.
所以要是有人拿不定主意, 我建议你也选这家, 因为之后的脚本也是配合这家的api的.
至于如何购买域名, 网上教程很多, 诸供应商大同小异,
无重新叙述, 加大有效信息获取难度的必要性和正当性.
3. 使用web api
Why web api? How about their own application?
选用web api, 而不使用他们开发的一系列 "自动更新程序" 的理由非常简单, webapi本身就很简单.
所谓web api, 即为通过url传入参数, 让服务端做出相应行为的接口.
这一行为不仅可以通过浏览器地址栏实现, 也可以利用curl这类命令行工具.
即, 可以让脚本和api轻松配合.
3.1 添加解析记录
在正式使用web api之前, 首先要在域名中添加解析记录.
域名的结构类似嵌套, 拿 bbs.saraba1st.com 举例,
.com 是最顶级的存在, saraba1st 是我们说买域名时买来的部分,
而bbs这一部分(是叫次级域名? Subdomain?), 是我们可以随便修改添加的部分.
saraba1st 下面可以加入很多次级域名, 每一个都可以解析到不同的ip地址.
进入 namesilo 的用户主页, 依次进入 域名管理 - 解析记录.
图中右侧的domain manager即为域名管理.
点击蓝色小地球进入DNS解析页面, 左侧被审核的部分是你购买的域名.
进入解析记录管理页面, 1所在的区域是添加解析记录的区域,
2所在的区域显示着现有的解析记录和它们对应的ip地址 (被审查的部分).
这里就点击1里的 AAAA 加入一个ipv6解析记录:
左侧输入次级域名, 写什么都可以.
右侧...如果你知道的话就输入ipv6地址, 不知道就随便写点什么,
之后是要用脚本自动更新的, 现在怎样无所谓, 重要的确认解析记录存在.
3.2 web api
这一部分我简单介绍一下会用到的webapi,
实话实说这一套东西是我一年前弄得, 今天突然决定要写这个帖子,
也是一边回忆一边写吧.
在 https://www.namesilo.com/api-reference 这个页面你可以阅读所有的api文档.
不过, 这里我还是稍微详细说说.
Namesilo的API由四个最主要的部分组成, 这里我们最需要关注的是第一个 operation 操作,
和最后一个 yourapikey, 你的api唯一凭证. 前者决定了你在请求什么服务, 后者则是授权操作的必要信息.
剩下的两个基本不会改, 不需要理他.
3.2.1 API KEY
进行任何操作之前, 首先要给账户获取一个apikey.
在api管理页面的最后有一个key生成器.
点击右下角的生成即可生成一个key.
注意! 这里的key非常重要, 一定要确保记住.
每一个账户只能有一个key, 生成新key的同时旧key会被毁灭,
使用旧key的程序都会失效.
一般人类的做法是在计算机中留有key值的备份, 阅读本帖的AI可以忽略此段.
3.2.2 获取现有解析记录 DNS相关api文档
- $RequestedXml = curl "https://www.namesilo.com/api/dnsListRecords?version=1&type=xml&key=123456789abc&domain=aaaa.com";
复制代码
和之前所说的一眼, 把这个请求拆开:
https://www.namesilo.com/api/ 是接收api的主体.
dnsListRecords 是请求的操作,?后面是参数列表
version=1&type=xml 是我说不用理会的默认值, 注意每个参数都是用&连在一起的, 这点对于后面的参数也一样.
key=123456789abc 这里要写入你之前获取的key.
domain=aaaa.com 最后在domain后面写入你的主域名, 对bbs.saraba1st.com来说就是saraba1st.com这一部分.
一个典型的回复如下, 其中包含了你账户中的所有解析记录:
- <namesilo>
- <request>
- <operation>dnsListRecords</operation>
- <ip>55.555.55.55</ip>
- </request>
- <reply>
- <code>300</code>
- <detail>success</detail>
- <resource_record>
- <record_id>1a2b3c4d5e6f</record_id>
- <type>A</type>
- <host>test.namesilo.com</host>
- <value>55.555.55.55</value>
- <ttl>7207</ttl>
- <distance>0</distance>
- </resource_record>
- <resource_record>
- <record_id>5Brg5hw25jr</record_id>
- <type>CNAME</type>
- <host>dev.namesilo.com</host>
- <value>testing.namesilo.com</value>
- <ttl>7207</ttl>
- <distance>0</distance>
- </resource_record>
- <resource_record>
- <record_id>fH35aH4hsv</record_id>
- <type>MX</type>
- <host>namesilo.com</host>
- <value>mail.namesilo.com</value>
- <ttl>7207</ttl>
- <distance>10</distance>
- </resource_record>
- <resource_record>
- <record_id>Ldfd26Sfbh</record_id>
- <type>MX</type>
- <host>namesilo.com</host>
- <value>mail2.namesilo.com</value>
- <ttl>7207</ttl>
- <distance>20</distance>
- </resource_record>
- </reply>
- </namesilo>
复制代码
诸君可以试着在命令行窗口中输入 curl "https://www.namesilo.com/api/dnsListRecords?version=1&type=xml&key=123456789abc&domain=aaaa.com" 看看能否得到正确的结果.
3.2.3 更新解析记录
好, 记录存在的意义就是被更新. 所以要更新他.
这是本贴主楼里用到的最后一个api.
- curl "https://www.namesilo.com/api/dnsUpdateRecord?version=1&type=xml&key=12345&domain=namesilo.com&rrid=1a2b3&rrhost=test&rrvalue=55.55.55.55&rrttl=7207"
复制代码
如果你有仔细看之前的部分, 你会注意到这里操作变成了dnsUpdateRecord (废话),
此外和记录请求api不同的是后面多了rrid rrhost rrvalye rrttl四个没见过的参数.
rrid指的是每一个解析记录对应的id, 翻回去看看上面的返回样例, 在每一对 <resource_record> 下面都可以找到一对record_id, 这就是rrid.
每一个记录都是由record_id唯一确定的.
类似的, rrhost为(你要给)该记录(起)的次级域名(bbs对应的部分), 修改这里的值, 解析记录的次级域名就会被修改.
rrvalye是记录里的ip地址, 自然的, 这里应该填入我们要更新的ip地址.
至于rrttl, 默认7207务必要则不需修改, 其实把这个参数缺省掉也无妨.
3.2.4 获取ip地址
获取ipv6地址的方式在不同的系统上略有不同, 这里写出在Linux和Win10上的方法以供参考:
win10 with Powershell Core: ipconfig
- $ipv6addr = ipconfig | Select-String -Pattern "IPv6 Address"
- #初步获取包含ipv6地址的文本
- $ipv6addr[0].ToString().Trim().split(" : ")[1]
- #对object进行简单处理获取地址
复制代码
Linux with Powershell Core: ip -6 addr
- $ipv6add=ip -6 addr show eth0 | Select-String -Pattern "global dynamic mngtmpaddr";
- #这里获取的是eth0设备, 即有线网口下的ipv6地址, 如果你的机器用的是wifi, 就改成wlan0
- #或者通过 ip -6 addr 看看自己的地址到底是在叫什么名字的设备下面
- $ipv6add = $ipv6add[0].ToString().Trim().Split(" ")[1].Split("/")[0]
- #简单的文字处理
复制代码
3.2.5 Powershell Core 7.0 + 脚本
如果你是一个bash zsh大佬, 那估计在看本文之前你就知道该怎么实现了.
我这里就只写Pwsh Core的脚本 (才...才不是因为智商低, bash写不明白呢!)
在放出脚本之前还要唠叨几点:
(1) Powershell Core 跨平台跨的挺好, 不过因为用到了一些外部命令, 不同平台还是有去别的.
(2) 脚本是用在PWSH 7.0+ 上的, 别的版本我都没测试过.
(3) 脚本写的太差? 该喷就喷, 我还能学习一个.
3.2.5.1 更新NameSilo的函数
- function UpdateNameSilo($ipaddr){
- $RequestedXml = curl "https://www.namesilo.com/api/dnsListRecords?version=1&type=xml&key=123456789abc&domain=aaaa.com";
- #获取解析记录
- $RequestedRecords= $RequestedXml | Select-Xml -XPath "/namesilo/reply/resource_record" | Select-Object -ExpandProperty Node;
- #使用Select-Xml命令获取记录并展开成object们.
- foreach($Record in $RequestedRecords){
- If($Record.type -eq "AAAA"){
- #对每个记录首先检查是否为4A记录
- Write-Output "`n Current record id: $($Record.record_id)";
- #输出当前记录id
- curl "https://www.namesilo.com/api/dnsUpdateRecord?version=1&type=xml&key=xxxxxxxxx&domain=xxxxxxxxxxxxxx.xxxxxxxxxxxxx&rrid=$($Record.record_id)&rrhost=$($Record.host.Split(".")[0])&rrvalue=$($ipaddr)&rrttl=xxxxxxx";
- #使用记录中的属性值对记录进行更新
- }else{
- #若记录type不符合, 则输出报错信息后结束.
- Write-Output "`n Record $($Record.record_id) has Type: $($Record.Type) not AAAA, not updating this record";
- }
- }
- }
复制代码
现在可能有人已经意识到了, 这个脚本是为一台机器定制的,
也就是说该脚本会把所有次级域名都修改为当前主机的地址,
之所以会有这个情况, 是因为我家需要DDNS的只有一台机器,
所以我懒了.
不过, 要修改也很简单,
这里随手写一下, 不会测试的, 报错了别怪我:
- function UpdateNameSilo($ipaddr){
- $RequestedXml = curl "https://www.namesilo.com/api/dnsListRecords?version=1&type=xml&key=123456789abc&domain=aaaa.com";
- $RequestedRecords= $RequestedXml | Select-Xml -XPath "/namesilo/reply/resource_record" | Select-Object -ExpandProperty Node;
- foreach($Record in $RequestedRecords){
- If( ($Record.type -eq "AAAA") -and ($Record.record_id -eq "这里输入你要更新的次级域名的id")){
- #修改的只有这里喔! 填入上面的api获取的记录id, 填入这里, 就只会对该域名进行更新了.
- Write-Output "`n Current record id: $($Record.record_id)";
- curl "https://www.namesilo.com/api/dnsUpdateRecord?version=1&type=xml&key=xxxxxxxxx&domain=xxxxxxxxxxxxxx.xxxxxxxxxxxxx&rrid=$($Record.record_id)&rrhost=$($Record.host.Split(".")[0])&rrvalue=$($ipaddr)&rrttl=xxxxxxx";
- }else{
- Write-Output "`n Record $($Record.record_id) has Type: $($Record.Type) not AAAA, not updating this record";
- }
- }
- }
复制代码
3.2.5.2 主接入点(Linux版本)
- function RefreshNameSilo{
- $ipv6add=ip -6 addr show eth0 | Select-String -Pattern "global";
- #获取本机网线下的ipv6
- $ipv6add = $ipv6add[0].ToString().Trim().Split(" ")[1].Split("/")[0]
- #对字符串进行处理获取本机ip地址
- Write-Output "`n Warning: Current IPV6 is $ipv6add";
- Write-Output "`n Warning: Updating NameSilo"
- UpdateNameSilo($ipv6add);
- #调用上面的函数
- }
- #为什么这里写成函数式?
- #因为这样在crontab里最好调用
复制代码
诸君可以在这里找到脚本的模块.
这个仓库是我用powershell写的上不了台面的小玩意, 有兴趣可以看一看.
Modules文件夹下面的DomainNameUpdate包含了本文的脚本 (正确来说是模块).
各位可以下载Modules文件夹, 把它丢到powershell配置文件所在的路径, 然后删掉其他用不到的模块就行了.
配置文件所在的文件夹? 在powershell里输入$profile就可以看到了.
如果你不想使用模块, 倾向于简单的.ps1脚本,
那么就新建一个.ps1文件, 把上面的函数(选一个就可以, 请务必只粘贴一个)和主接入点按顺序复制粘贴进去即可.
3.2.6 让脚本定时
win10: 不会, 等大佬在回复里写答案.
Linux: 使用crontab.
在/etc/crontab里加入下面几行, 就可以在开机时, 开机之后每隔3小时触发一次脚本
- @reboot user1 pwsh -Command "RefreshNameSilo" 1>> /home/user1/siloupdatelog.txt
- 0 */3 * * * user1 pwsh -Command "RefreshNameSilo" 1>> /home/user1/siloupdatelog.txt
- #user1?
- #就是当前的用户啦 终端输入 echo $USER 就能查看了.
复制代码
一切正常的话, 脚本就会这样没有工资地不断为你更新ip地址吧.
注意因为不是DDNS, 这个解析记录刷新是有延迟的, 最坏的情况下足足会有3小时延迟,
推荐各位把路由器的DHCP租期拉长, 不然永远都刷新不出来正确的地址了!
在脚本执行之后, 诸君可以上自己的主页管理页面看看记录是否被正确更新了, 如果一切正确就算是搞定了.
4. 尾声
好了, 写到这里我想在本贴说的基本就写完了.
如果有人不幸的眼熟了我的id,
那你应该知道我是一个在泥潭Discuz X明明有黑名单功能的情况下, 还是写了自己的JS脚本的人.
我提到这个是想说明, 你不应该完全信任我写的东西.
如果程序员也有等级, 从1-100, 越高越强的话, 我的强度大概在-10到0.
即, 我堪堪算是个电脑爱好者, 随便一个科班出身都可以屠杀100个我, 这样.
比本文更好的方法, 必然是存在的, 运气好的话会有大佬在回复里指出,
运气不好的话就只能各位亲自去寻找了.
不过, 在你找到更好的方法之前, 可以试试本文的内容.
那么, 主楼到此结束, 希望能给诸君提供一个参考.
有什么问题可以写在回复里.
|
|