使用he.net的动态域名服务
- IT
- 2023-11-12
- 475热度
- 1评论
我的ipv6动态域名(DDNS)服务之前托管在dynv6上。dynv6是一家专注于ipv6 DDNS的网站,它有一个别家不具备的优点:即可以手动配置ipv6地址的后64位。在局域网内,诸如NAS、软路由等,默认情况下,会将自己的Mac地址作为ipv6地址的后64位,而Windows出于安全原因会默认会关闭这项功能。这样一来,局域网内的N台设备,只需要其中1台向dynv6“汇报”ipv6地址,dynv6即可取得前64位前缀,与手动设置的后64位(实际上是设备的Mac地址)拼合成其他设备的ipv6。
原先的方案中,我使用openwrt自动汇报公网ipv6,其余设备均采用这种方式“半指定”ipv6地址,其中Windows设备关闭隐藏硬件地址功能。一开始运行不错,但过了一段时间发现,dynv6似乎对免费用户不太友好,如果一段时间不用,ipv6 DDNS就会失效,需要登陆上去,手动删除并重新添加。
这怎么行?只能更换服务。
一直听说鼎鼎大名的HE(HERRICANE ELECTRIC),之前曾经研究过它家的IPv6 Tunnel Broker,而它也具备ipv4、ipv6的DDNS功能。它上古设计的网站风格让人望而却步,但不妨碍它是业内最老牌的网络服务商之一。
由于它过分“精简”的页面设计,在使用它的DDNS过程中不免有一番探索和折腾。记录一下以备忘。
一、在你的域名托管商处设置NS(NameServer)解析
假设我们的域名是domain.sample.com。在托管域名的DNS解析管理页面,将之前domain.sample.com的DNS解析全部删除,并添加5个NS:ns1.he.net、ns2.he.net……ns5.he.net。
NS(NameServer)解析的意思是,对这个域名具体解析到哪里,你别管了,交给我设置的这些(nsx.he.net)来负责吧。添加5个原因是为了DNS解析的健壮性,确保全球不同地区均可以稳定地解析domain.sample.com的NS设置。注意,5个NS无法写到同一行中,这是由DNS规范确定的。
此外,经测试发现,阿里云的DNS解析,不支持将NS设置为he.net,设置之后始终无效。猜测是因为国内的DNS解析如果使用CNAME,它会首先检测你CNAME的指向域名有没有备案,如果没有备案,直接就不让你使用这条CNAME。而NS设定可能可以绕过这一点,因此当阿里云检测到NS的目标是一个“境外网站”时,它就不生效,急死你。
实测在cloudflare上对域名DNS进行操作就没有这些猫腻。添加之后,可能需要5分钟左右时间令它生效。
二、在dns.he.net上添加域名解析
首先注册dns.he.net。这个页面既包括手动的静态DNS,也包括动态DNS,每个免费用户可以设置50个域名。
第一步,添加域名,点击左侧“Add a new domain”。属于domain.sample.com。它会对这个域名进行一番检查,确保它已经正确设置了NS,除了NS之外的其他设置已经清空。
添加成功后,domain.sample.com就出现在了Active domains for this account表格中。点击域名前面编辑图标(Edit zone),进入Managing zone页面,可以看到,之前添加过的5个NS已经罗列在其中。除此之外,还有一个SOA,它标记了5个NS中具体哪一个是主域名解析器。这些都不用管它。
点击表格顶部的“New AAAA”(添加的是ipv6解析,如果是ipv4则为New A),在弹出的窗口中,Name可以再次输入域名,IPv6 Address留空(因为我们想要的是动态域名),TTL默认,然后勾选最下方的“Enable entry for dynamic dns”,这时候IPv6中可能会自动填上::1,或者上一个设置的ipv6地址,不用在意(因为它会被动态域名机制自动更新)。点击Submit提交。
之后可以看到DNS解析表格的最后一行是刚刚添加的AAAA记录。蓝色的四个AAAA表示这是一个动态域名。注意,后面有一个DDNS列,其中有一个类似“刷新”的图标,它不是刷新!它的功能鼠标移上去可以发现:“Generate a DDNS key.”
这个KEY对于DDNS来说至关重要,DDNS的原理就是任意一台设备,只要能报出域名和对应的KEY,就可以更新域名对应的IP为当前设备的IP。点击这个“Generate a DDNS key”,单击“Generate”,它会生成一个密码(DDNS key),妥善保存它,然后务必记得,再次点击Submit,让这个刚刚生成的key生效。
好了,dns.he.net这边的设置已经完成,下面的问题就是,如何让你的设备们,向dns.he.net报告自己的IP了。
dns.he.net没有像dynv6那样的手动设置Mac地址作为ipv6后缀的功能,所以只好在每台设备上进行客户端设置。
三、Openwrt的DDNS客户端设置
对于Openwrt,相对简单,在任务计划中添加一行即可:
*/5 * * * * curl -6 "https://domain.sample.com:DDNS_KEY@dyn.dns.he.net/nic/update?hostname=domain.sample.com"
四、Windows的DDNS客户端设置
实际上DDNS只需要向一个特定地址报告域名和密码,对于dns.he.net同样如此。这个地址和linux系统里curl的地址是一样的:
https://domain.sample.com:DDNS_KEY@dyn.dns.he.net/nic/update?hostname=domain.sample.com
如果Windows当前处于ipv6环境,那么,直接用浏览器访问上述地址,就可以看到返回结果,如果显示good [ipv6-address]说明DNS已经成功刷新;如果显示nochg [ipv6-address]说明成功握手,但DNS解析没变。
但是仍然有几个问题需要解决。
a)如果Windows当前环境下既有ipv4,又有ipv6,而因为某种原因,ipv6没有设置为优先时,上述网址可能就会返回“noipv4”。这是因为域名设置为AAAA,它只接受ipv6地址,如果本机报告的是ipv4地址,就会失败。
这种情况下,我们可以强行先对dyn.dns.he.net域名进行AAAA解析,将解析结果塞到一个变量中,然后用这个ipv6地址变量来构建后面的地址,这样,浏览器就明确知道“这是一个ipv6地址”,就不会傻乎乎地还用ipv4网络去访问它了。
b)powershell的Invoke-WebRequest方法,并不直接支持基本认证(也就是在URL地址中嵌入用户名、密码),因此,我们还需要手动构造。
c)Windows 10经过更新之后,默认禁止powershell执行任何脚本,因此,需要在powershell的执行参数中加上-ExecutionPolicy Bypass,以在“本次执行中”绕过执行权限限制。
d)我们希望执行的结果可以保存到一个log文件中。
创建一个后缀名为ps1的文本文件,例如dns-update.ps1,假设该文件位于c:\ddns。内容如下:
#----------- 配置区 -------------
$hostName = "HOSTNAME"
$ddnsKey = "DDNS_KEY"
$logPath = "C:\ddns\dns_update.log"
#----------- 认证头 -------------
$plain = "$hostName`:$ddnsKey"
$base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($plain))
#----------- 执行 curl ----------
$curlExe = Join-Path $Env:SystemRoot 'System32\curl.exe' # 保证是真·curl.exe
$uri = "https://dyn.dns.he.net/nic/update?hostname=$hostName"
try {
# 把每个参数分开放进数组,再用 & 调用
$result = & $curlExe -g -6 `
-H "Authorization: Basic $base64" `
$uri
$result | Out-File -Append -FilePath $logPath
}
catch {
"Error: $($_.Exception.Message)" | Out-File -Append -FilePath $logPath
}
#----------- 保留最新的1000行 -------------
$maxLines = 1000
if (Test-Path $logPath) {
$lines = Get-Content $logPath -Tail $maxLines
$lines | Set-Content $logPath
}
接下来,只需要手动创建一个任务计划,设定5分钟或者10分钟的时间间隔,程序选择powershell.exe(注意它一般在这里:C:\Windows\System32\WindowsPowerShell\v1.0),参数如下(路径修改为实际路径):
-ExecutionPolicy Bypass -File "c:\ddns\dns-update.ps1"
五、NAS的DDNS客户端设置
对于群晖,也比较简单,群晖无论是DSM6.2还是DSM7.2,控制面板中均自带任务计划功能,创建一个任务计划,配置为5分钟运行一次,脚本为:
curl -6 "https://domain.sample.com:DDNS_KEY@dyn.dns.he.net/nic/update?hostname=domain.sample.com"
注意这里不需要在脚本中添加定时设定,因为任务计划本身已经包含了定时执行的设置了。
对于西数NAS,这个恶心的设备,自带的DDNS功能只支持两家(不包含he.net),虽然可以SSH进去,但用户无法自定义cron任务,必须手动修改其系统级的cron任务,非常麻烦,不推荐。
[…] 家庭宽带通常可以轻松获得公网IPv6地址。因此,通过一台IPv4/IPv6双栈VPS来做端口转发实现家庭设备的访问是常见的需求。之前曾经提过可以用socat来实现(11 用nginx和socat实现ipv4与ipv6的转换),但socat有一个局限性:它对域名的解析只在启动时执行一次。由于家庭宽带的公网IPv6是典型的动态域名(使用he.net的动态域名服务),如果socat启动后,家庭设备的动态域名解析IP发生了变化,那么socat的端口转发就失效了。 […]