电信宽带可以通过10000号主动申请一个公网ip,但是这个ip是不固定的,每次重启路由器或者断电后,ip都会变,所以需要通过ddns来实现域名解析到公网ip,这样就可以通过域名访问家里的设备了。
之前华硕路由器是自带了ddns的,但是红米AX6000的固件没有自带的服务,有提供几个ddns的服务商,要不是国内的需要备案的,要不就是国外的免费的要每隔30天验证一次,都不怎么好用。
cloudflare是提供了修改域名的dns配置的api,所以可以通过定时脚本来实现ddns的功能。
配置dns api token
- 登录cloudflare,打开https://dash.cloudflare.com/profile/api-tokens
- 点击
Create Token
, 选择Edit zone DNS
template - Zone Resources, 选择
Specific Zone
, 选择你的域名 - 点击
continue to summary
- 创建完成,复制token
设置域名的dns记录
- 在cloudflare的域名管理页面,找到
DNS
标签 - 点击
Add Record
, 选择A
类型,输入你的域名,比如self.beyondkmp.com
, 然后加上ip - 关闭
Proxied
选项,DNS only的,保存
编辑脚本并保存
vim update_cloudflare_dns.sh
并粘贴以下内容,修改的地方有:
- zone: 域名, 改成你自己的域名
- dnsrecord: 域名记录, 改成你自己的域名记录
- cloudflare_auth_email: cloudflare的账号
- cloudflare_auth_key: cloudflare的api token
保存到/usr/local/bin/update_cloudflare_dns.sh
#!/bin/bash
# A bash script to update a Cloudflare DNS A record with the external IP of the source machine
# Used to provide DDNS service for my home
# Needs the DNS record pre-creating on Cloudflare
# Proxy - uncomment and provide details if using a proxy
#export https_proxy=http://<proxyuser>:<proxypassword>@<proxyip>:<proxyport>
# Cloudflare zone is the zone which holds the record
zone=beyondkmp.com
# dnsrecord is the A record which will be updated
dnsrecord=self.beyondkmp.com
## Cloudflare authentication details
## keep these private
cloudflare_auth_email=beyondkmp@gmail.com
cloudflare_auth_key=xxxxxxxxyyyyyyyxxzzzzzzzzzzzzzz
# Get the current external IP address
ip=$(curl -s -X GET https://checkip.amazonaws.com)
echo "Current IP is $ip"
if host $dnsrecord 114.114.114.114 | grep "has address" | grep "$ip"; then
echo "$dnsrecord is currently set to $ip; no changes needed"
exit
fi
# if here, the dns record needs updating
# get the zone id for the requested zone
zoneid=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$zone&status=active" \
-H "X-Auth-Email: $cloudflare_auth_email" \
-H "X-Auth-Key: $cloudflare_auth_key" \
-H "Content-Type: application/json" | jq -r '{"result"}[] | .[0] | .id')
echo "Zoneid for $zone is $zoneid"
# get the dns record id
dnsrecordid=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records?type=A&name=$dnsrecord" \
-H "X-Auth-Email: $cloudflare_auth_email" \
-H "X-Auth-Key: $cloudflare_auth_key" \
-H "Content-Type: application/json" | jq -r '{"result"}[] | .[0] | .id')
echo "DNSrecordid for $dnsrecord is $dnsrecordid"
# update the record
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records/$dnsrecordid" \
-H "X-Auth-Email: $cloudflare_auth_email" \
-H "X-Auth-Key: $cloudflare_auth_key" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$dnsrecord\",\"content\":\"$ip\",\"ttl\":1,\"proxied\":false}" | jq
安装依赖
- 上面的脚本是依赖
jq
来解析json的,所以需要安装jq
apt install jq
- 还依赖dns解析,所以需要安装
dnsutils
apt install dnsutils
设置定时任务
crontab -e
添加下面的内容,每隔3分钟更新一次
*/3 * * * * /usr/local/bin/update_cloudflare_dns.sh
测试
- 重新启动路由器,查看路由器的公网ip
- 隔三分钟后,ping下你的域名,看下公网ip是不是和路由器上面显示的一样