上一期我们已经在m401a中安装并搭建好了Pandora-cloud,并且获取了Access Token从而实现本地无障碍访问ChatGPT服务,和GPT 3.5 Turbo进行对话了。那么,我们的终极目标Anywhere如何实现呢?
内网穿透?2023年了,还在“内网穿透”,还在NAT over NAT?运营商表示很不爽!
纵观国内几大运营商提供的光宽带网络服务,公网IPv4不说,IPv6是早就开始推广应用了,近两年新装的宽带,附送的光猫无一例外都自带路由且支持DHCPv6,而且,要知道家庭宽带分配到的IP(v4 or v6)都是最干净的地址。查看盒子接口信息,应该都是“2409”开头的,这个“2409”开头的IPv6地址就是公网地址,是可以在外网访问的。
当然,也可能会有“fe80”开头的,那就需要致电运营商换光猫或者改桥接、手动加路由,因为“fe80”开头的不是公网地址,类似于IPv4的“10”网段了。当然,端口映射、内网穿透等在此情景下就有了用武之地。本文不会讨论这类方案或其他实现,越简单越好。
第四部分 域名绑定并获取API接口
我们找一个已注册的域名,最好是泊靠在Cloudflare,这样不用再做迁移。登录Cloudflare,选择我们打算绑定的域名,老E随便选了个刚注册的一个.eu.org域名。
进入该域的dns设置后,我们增加一条A或者AAAA记录,A是32bit IPv4、AAAA是128bit IPv6。这里,我添加了一条IPv6记录,具体地址只要合法就行,不用纠结,如果是添加A记录,IPv4地址完全可以用1.1.1.1。
记得关闭小黄云(不开启代理),TTL可以设为最小1分钟,确定后保存该记录。这样,ai.xxxxx.eu.org就是指向armbian m401a盒子的主机名。域名绑定完成。
这个IPv6地址如果设成当前盒子的IPv6地址的话,当然是可以从公网访问盒子的(80、443端口除外),但是,我们盒子的IPv6地址是动态分配的,所以需要绑定一个域名并实时更新记录,这就需要用到DDNS。多数名称服务提供机构都有DNS API支持,国内腾讯、阿里也有,Cloudflare自然也不例外,不过,从去年开始Cloudflare对于.tk/.ga/.gq等freenom注册的免费域名不再提供api支持。
使用CF的API,我们需要事先确定下来几个令牌(Token),不仅是DNS记录更新,包括证书申请、workers代理计算等都需要/可以使用API。
打开xxxxx.eu.org域的管理面板,右侧就是区域ID、令牌的标识,复制Zone/区域 ID。账户ID在本例中并不需要,但获取账户ID、Global令牌,基于Cloudflare API,几乎可以抛弃后台完成所有业务配置。
这里,点选“获取您的API令牌”,来到令牌创建页面。
老E的配置页面显示的是针对另一个区域(yyyy.eu.org)创建好的令牌,点选最右侧的"..."可以查看摘要信息。这里点选创建令牌即可。
选择第1项,使用编辑区域DNS模板。一般常用的就是该类令牌和“编辑Cloudflare Workers”以及“Wordpress”令牌。
区域资源点开"Select..."选择我们增加了AAAA记录的域xxxx.eu.org。选择“继续以显示摘要”,在摘要页点选“创建令牌”即可。
把创建的Token拷贝下来,和区域ID等一起保存好。给出的测试命令也可以一并拷贝下来保存。
至此,针对ddns配置任务目标,我们在cloudflare后台需要进行的操作全部完成。后期,如果要验证记录更新的话,也不必登录后台,没有套CDN的情况下,ping ai.xxxx.eu.org即可。
shell或cmd输入以下命令即可查询到刚才设定的AAAA记录ID:
curl --request GET \ --url https://api.cloudflare.com/client/v4/zones/{Zone-id}/dns_records \ --header 'Content-Type: application/json' \ --header 'X-Auth-Email: {Email}' \ --header 'Authorization: Bearer {Token}' \ | python3 -m json.tool
以上就是通过Cloudflare API Token读取DNS记录的 命令,需要替换(包括花括弧)给定的内容包括:ZoneID、账户邮箱、API Token。参考官方文档,我们可以了解详细API关键字和使用方法。务必注意,Token不是Key,官方文档没有描述清楚,网上很多教程把Token写在Key的地方,或者header定义是X-Auth-Key,后面写的是Token,完全不清楚是怎么跑通的或者说有没有真正测试过。
Result中的第一条就是Record ID,记录下来,在写入、更新新的IPv6地址的时候,需要指定。
首先,确认一下需要记下保存的4项信息:ZoneID、Token、Mail/Account、RecordID。
DDNS实现的核心就两点:
1.监测(被动)或检测(主动)IPv6地址的变化
2.基于变化进行DNS记录的更新
被动监测,是需要基于系统network管理进程,利用hooks机制,仅当接口分配到的IPv6地址发生变化时触发记录更新;主动检测,就是按一定时间周期(cron,如120s)进行轮询,一旦检测到接口的IPv6地址发生变化则进行记录更新。
被动监测轻巧、灵活,但受限于dhcp客户端的繁杂和稳定性、发行版的变化,不够鲁棒且有适应范围限制。主动检测可以很非常强健,但会消耗少量的系统资源,不同运营商环境下的最佳cron周期设置以及检测脚本(py或sh)性能都需要考虑,永久运行的定时任务也并不受推荐。
1.DNS记录更新脚本
无论主动检测或者被动监测,都需要在分配的IPv6地址发生变化时,通过Cloudflare API更新DNS记录,运行以下代码可以自动创建/bin/cf-ddns.sh脚本。
#!/bin/sh cat << EOF > /bin/cf-ddns6.sh #!/bin/sh sleep 10 IP6=\$(ip -6 addr show dev {Interface} | awk '/global/ {print \$2}' | awk -F "/" '{print \$1}') if [ -z "\$IP6" ]; then exit fi response=\$(curl -s -o /dev/null -w %{http_code} --request PUT \ --url "https://api.cloudflare.com/client/v4/zones/{ZoneID}/dns_records/{RecordID}" \ --header "Content-Type: application/json" \ --header "X-Auth-Email: {Email}" \ --header "Authorization: Bearer {Token}" \ --data '{ "type": "AAAA", "name": "{Fullname}", "content": "'"\$IP6"'", "proxied": false }') if [ "\$response" = "200" ]; then echo "DNS记录更新成功" else echo "DNS记录更新失败,HTTP状态码: \$response" fi EOF chmod +x /bin/cf-ddns6.sh
可通过执行以下命令下载脚本生成代码,会自动生成/bin/cf-ddns6.sh,务必在替换{interface}、{ZoneID}、{RecordID}、{Email}、{Token}、{Domainname}并保存果后执行。
curl -sSL -o ddns6.sh https://raw.githubusercontent.com/evanawn65/appscross/main/generate-cf-ddns6.sh && chmod +x ./ddns6.sh && ./ddns6.sh &&vim /bin/cf-ddns6.sh
-
- {interface}: 替换为监测的网络接口,例如 eth0。
- {ZoneID}: 替换为 Cloudflare 域名所在的区域 ID。
- {RecordID}: 替换为要更新的 DNS 记录的 ID。
- {Email}: 替换为你的 Cloudflare 帐户的注册电子邮件地址。
- {Token}: 替换为你获取的 Cloudflare API Token。
- {Fullname}: 替换为要更新的完整主机域名,如ai.xxxx.eu.org。
验证部署一下,先后台或者命令行查阅当前ai.xxxx.eu.org的IPv6地址。
运行/bin/cf-ddns.sh,除了最后的“成功”或“失败”返回码,静默运行不会有任何中间输出。
我们看到记录更新成功,回到Cloudflare DNS设置后台进行验证。
2.被动监测
对于使用 NetworkManager 的 Debian Bullseye,通过 NetworkManager 的 dispatcher.d 功能来监测到 IP 地址变化。这是一种类似于 dhcpcd以及dhclient 客户端 hooks 的机制,可以在 IP 地址变化时执行/bin/cf-ddns6.sh。
创建一个脚本文件,用于处理 IP 地址变化的操作。
sudo nano /etc/NetworkManager/dispatcher.d/99-ip6-address-change
脚本文件内容如下:
#!/bin/bash IFACE="$1" REASON="$2" if [ "$REASON" = "dhcp6-change" ] || [ "$REASON" = "connectivity-change" ] || [ "$REASON" = "up" ]; then # 调用 DNS 记录更新脚本 /bin/cf-ddns6.sh fi
记得文件赋权并确保脚本属主、属组为root。到此就完成了被动监测的DDNS本地设置,可以手动执行一次/bin/cf-ddns6.sh。当 NetworkManager 检测到 eth0 接口的 IP 地址变化并重新连接时,它将自动调用 /etc/NetworkManager/dispatcher.d/99-ip6-address-change 脚本。这个脚本可以将/bin/cf-ddns6.sh内容合并进来,但考虑到可能存在的“玄学”问题,这里进行分离处理。
curl -sSL -o /etc/NetworkManager/dispatcher.d/99-ip6-address-change https://github.com/evanawn65/appscross/raw/main/99-ip6-address-change
sudo chown root:root /etc/NetworkManager/dispatcher.d/99-ip6-address-change
sudo chmod +x /etc/NetworkManager/dispatcher.d/99-ip6-address-change
3.主动检测
如果被动监测无法实现,我们可以将/bin/cf-ddns6.sh作为定时任务,使用crontab -e编辑cron表,在其中增加如下一行内容,每2分钟执行一次。
*/2 * * * * /bin/sh /bin/cf-ddns6.sh >> /bin/cf-ddns6.log 2>&1
好了,至此我们就通过IPv6配置完成了基于Cloudflare API的DDNS,抓紧试试吧。通过DDNS的搭建与实现,我们不仅可以通过公网访问m401a服务器上的Pandora服务,还可以在m401a上部署Jellyfin server、HA等若干应用服务,从目前我的m401a运行情况来看,两个字:够用。
最后,需要提示一下:运营商屏蔽了80、443端口,需要重新编辑下pandora-cloud.service文件,监听端口改成非443、80端口,如此一来,公网访问也需要加端口号,譬如我的就是ai.xxxx.eu.org:8091。
文章评论