自从家里的设备全部支持ipv6后(如何支持见上文), 怎么说呢,就一发不可收拾了。总想着尽可能的利用起来ipv6。想起来自己还有个域名,就尝试着试试看能不能让自己的域名仅支持ipv6。
试了之后发现还是挺简单的,虽然不能直接在域名解析上添加A记录,但是腾讯云还是很友好的发现的想添加的是一个ipv6的地址,于是就指引我去添加AAAA的记录过去了。添加完之后,就等着解析了。很快家里的网络就可以正常解析我只添加了AAAA记录的新地址blog.jiangbo.space。我的博客流程的打开了。
这里有一点比较坑的是,如果你使用了代理工具,特别是clash,这个是亲测可能会有影响的。我目前使用机场的配置文件中默认是不支持ipv6的,导致我走了很多弯路。如果使用这种不支持ipv6的配置,又使用了clash的代理,那么很不幸,即使你本地网络支持ipv6你也不能正常访问仅提供ipv6支持的网站。clash的配置要支持ipv6倒是也简单,添加ipv6:true即可。还望广大机场能尽快跟进,默认配置中就加上这句话。
域名解析添加以后,开始几天倒是还是正常使用的。我一致以为ipv6那么多,运营商现在肯定是给每个用户一个固定的ipv6地址。后来才发现我多想了,现在依旧是动态的,而且是动态的前缀,这就导致我配置一次AAAA记录是不行的。等到路由器断线重连之后,家里网络的ipv6地址就换了个边。这种情况就需要DDNS登场了。
我用的腾讯云解析的dns,这个可能比较小众,反正是没有找到现成的代码。这个时候就发现程序员的主观能动性了,自己主动撸一个了。写起来倒是比较简单,腾讯云还可以主动生成大部分代码,剩下的就是拼拼凑凑了。放在ubuntun上跑起来也简单,直接定时任务没5分钟刷一次好了。具体代码如下:
package main
import (
"fmt"
"net"
"regexp"
"strings"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
dnspod "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod/v20210323"
)
const dnsPodDomain = "dnspod.tencentcloudapi.com"
// 主域名,不包含www
const domain = ""
// 腾讯云secretId
const secretId = ""
// 腾讯云secretKey
const secretKey = ""
func main() {
// 目标子域名
subDomains := []string{"ipv6"}
// 密钥
credential := common.NewCredential(
secretId,
secretKey,
)
ipv6 := getMyIPV6()
fmt.Printf("ipv6地址: %s\n", ipv6)
cpf := profile.NewClientProfile()
cpf.HttpProfile.Endpoint = dnsPodDomain
client, _ := dnspod.NewClient(credential, "", cpf)
request := dnspod.NewDescribeRecordListRequest()
request.Domain = common.StringPtr(domain)
response, err := client.DescribeRecordList(request)
if _, ok := err.(*errors.TencentCloudSDKError); ok {
fmt.Printf("An API error has returned: %s", err)
return
}
if err != nil {
panic(err)
}
for _, subDomain := range subDomains {
for _, record := range response.Response.RecordList {
if *record.Value == ipv6 {
continue
}
if *record.Name == subDomain {
fmt.Printf("%d\n", *record.RecordId)
updateDomain(credential, subDomain, *record.RecordId, ipv6)
}
}
}
var name string
fmt.Scanln(&name)
}
func updateDomain(credential *common.Credential, subDomain string, recordId uint64, ipv6Str string) {
cpf := profile.NewClientProfile()
cpf.HttpProfile.Endpoint = dnsPodDomain
client, _ := dnspod.NewClient(credential, "", cpf)
request := dnspod.NewModifyRecordRequest()
request.Domain = common.StringPtr(domain)
request.SubDomain = common.StringPtr(subDomain)
request.RecordType = common.StringPtr("AAAA")
request.RecordLine = common.StringPtr("默认")
request.Value = common.StringPtr(ipv6Str)
request.RecordId = common.Uint64Ptr(recordId)
response, err := client.ModifyRecord(request)
if _, ok := err.(*errors.TencentCloudSDKError); ok {
fmt.Printf("An API error has returned: %s", err)
return
}
if err != nil {
panic(err)
}
fmt.Printf("%s\n", response.ToJsonString())
}
func getMyIPV6() string {
s, err := net.InterfaceAddrs()
if err != nil {
fmt.Printf("get ipv6 err %s", err)
return ""
}
for _, a := range s {
i := regexp.MustCompile(`(\w+:){7}\w+`).FindString(a.String())
if strings.Count(i, ":") == 7 {
return i
}
}
fmt.Printf("not get ipv6 address")
return ""
}
上面脚本ubuntun上跑问题不大,但是在我的群晖上不大好搞。群晖上不大想装个go环境,暂时也没想把它编译成可执行文件的想法。后面想到可以放到群晖的docker上跑,docker选择跟主机同样的网络就好。这样定时任务或开机时就可以获取到群晖主机所有的ipv6地址,剩下的就都一样了。