大致思路

  • 有一个地方保存旧公网ip 可以是文件/redis等

  • 定时访问一些网站或者执行脚本获取最新的公网ip

    • 网站

      https://api.ipify.org
      http://myexternalip.com/raw
      
    • 脚本

      curl -s ifconfig.me
      curl ipv4.ip.sb
      
  • 新公网ip 与 旧公网ip不一致,则调用腾讯云golang sdk修改域名的ip解析

    • 正文有详细的demo代码
  • 循环定时执行巡检即可

获取最新公网ip

func getExternalIp1() string {
	// 使用http.Get函数请求外部服务
	resp, err := http.Get("https://api.ipify.org")
	if err != nil {
		log.Printf("请求失败: %s\n", err)
		return ""
	}
	defer resp.Body.Close() // 确保关闭响应体
	// 读取响应体内容
	ip, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Printf("读取响应失败: %s\n", err)
		return ""
	}
	return string(ip)
}
  • 为了兼容一些异常 校验下ip是否合法 不是一些errorcode之类的

    func IsValidIPv4(ip string) bool {
    	parsedIP := net.ParseIP(ip)
    	return parsedIP != nil && parsedIP.To4() != nil
    }
    

动态更新域名对应ip

腾讯云启用API密钥,记录自己的secertId和和secertKey

管理地址 https://console.cloud.tencent.com/cam/capi

引入腾讯云golangapi 其它也类似

import (
	"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"
)

查询域名下面的所有解析记录

  • 下面demo代码注意修改 你的SecertId/你的SecertKey/域名 会打印域名下面的所有的A记录解析情况
credential := common.NewCredential(
		"你的SecertId",
		"你的SecertKey",
	)
	// 实例化一个client选项,可选的,没有特殊需求可以跳过
	cpf := profile.NewClientProfile()
	cpf.HttpProfile.Endpoint = "dnspod.tencentcloudapi.com"
	// 实例化要请求产品的client对象,clientProfile是可选的
	client, _ := dnspod.NewClient(credential, "", cpf)
	// 实例化一个请求对象,每个接口都会对应一个request对象
	request := dnspod.NewDescribeRecordListRequest()
	var Domain string ="becool.vip"
	var RecordType string ="A"
	request.Domain =&Domain
	request.RecordType =&RecordType
	// 返回的resp是一个DescribeRecordListResponse的实例,与请求对象对应
	response, err := client.DescribeRecordList(request)
	if _, ok := err.(*errors.TencentCloudSDKError); ok {
		fmt.Printf("An API error has returned: %s\n", err)
		return ""
	}
	if err != nil {
		fmt.Println("getdnsrecord err:%s",err.Error())
		return ""
	}
	for i:=0;i<len(response.Response.RecordList);i++{
		item:=response.Response.RecordList[i]
fmt.Println(*item.Value,*item.RecordId,*item.Line,*item.LineId,*item.Remark,*item.MX,*item.Name,*item.UpdatedOn)
	}

更改域名对应ip解析

  • 建议指定var SubDomain string ="bereal" 具体主机记录 比如@/www/子域名
// 实例化一个认证对象,入参需要传入腾讯云账户secretIdsecretKey,此处还需注意密钥对的保密
	// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
	credential := common.NewCredential(
		"你的SecertId",
		"你的SecertKey",
	)
	// 实例化一个client选项,可选的,没有特殊需求可以跳过
	cpf := profile.NewClientProfile()
	cpf.HttpProfile.Endpoint = "dnspod.tencentcloudapi.com"
	// 实例化要请求产品的client对象,clientProfile是可选的
	client, _ := dnspod.NewClient(credential, "", cpf)
	// 实例化一个请求对象,每个接口都会对应一个request对象
	request := dnspod.NewModifyRecordRequest()
	var Domain string ="becool.vip"
	var SubDomain string ="blog" // 我这里指定子域名 对应全称就是blog.becool.vip
	var RecordType string = "A"
	var RecordLine string = "默认"
	var RecordLineId string ="0"
	var RecordId uint64 = 1811353533 // 对应上面的item.RecordId
	var Value string = extIp
	request.Domain =&Domain
	request.RecordType = &RecordType
	request.RecordLine = &RecordLine
	request.RecordLineId =&RecordLineId
	request.Value =&Value
	request.RecordId =&RecordId
	request.SubDomain=&SubDomain
	// 返回的resp是一个ModifyRecordResponse的实例,与请求对象对应
	_, err := client.ModifyRecord(request)
	if _, ok := err.(*errors.TencentCloudSDKError); ok {
		fmt.Printf("An API error has returned: %s", err)
		return false
	}
	if err != nil {
		fmt.Println("modify error",err.Error())
	}