0 Star 0 Fork 0

张杳/ddns

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
main.go 5.05 KB
一键复制 编辑 原始数据 按行查看 历史
package main
import (
"errors"
"flag"
dns "github.com/alibabacloud-go/alidns-20150109/v2/client"
openapi "github.com/alibabacloud-go/darabonba-openapi/client"
"github.com/alibabacloud-go/tea/tea"
log "github.com/sirupsen/logrus"
"net"
"os"
"strings"
"time"
)
var client *dns.Client
func NewString(s string) *string {
return &s
}
func Init(accessKey, secretKey, logLevel string) {
log.SetFormatter(&log.TextFormatter{
FullTimestamp: true,
TimestampFormat: "2006-01-02 15:04:05.000",
})
var err error
level, err := log.ParseLevel(logLevel)
if err != nil {
log.Errorf("parse log level error:%v\n", err)
os.Exit(1)
}
log.SetLevel(level)
client, err = dns.NewClient(&openapi.Config{
AccessKeyId: NewString(accessKey),
AccessKeySecret: NewString(secretKey),
RegionId: NewString(""),
})
if err != nil {
log.Errorf("create client error:%v\n", err)
os.Exit(1)
}
}
func GetRecordId(DNS string) string {
info := strings.Split(DNS, ":")
if len(info) != 3 {
log.Errorf("DNS format error: %s. Need to be like domain:record:type\n", DNS)
os.Exit(1)
}
rsp, err := client.DescribeDomainRecords(&dns.DescribeDomainRecordsRequest{
DomainName: NewString(info[0]),
RRKeyWord: NewString(info[1]),
Type: NewString(info[2]),
})
if err != nil {
log.Errorf("DescribeDomainRecords error:%v\n", err)
os.Exit(1)
}
var record *dns.DescribeDomainRecordsResponseBodyDomainRecordsRecord
var recordId string
if rsp != nil && rsp.Body != nil && rsp.Body.DomainRecords != nil && len(rsp.Body.DomainRecords.Record) > 0 {
record = rsp.Body.DomainRecords.Record[0]
recordId = *record.RecordId
}
return recordId
}
func GetOSIPv6(interfaceName string) string {
ifaces, err := net.Interfaces()
if err != nil {
log.Error("Error getting interfaces:", err)
os.Exit(1)
}
var ifacesNames []string
for _, iface := range ifaces {
ifacesNames = append(ifacesNames, iface.Name)
if iface.Name == interfaceName {
addrs, err := iface.Addrs()
if err != nil {
log.Error("Error getting addresses:", err)
os.Exit(1)
}
var address []string
for _, addr := range addrs {
if ipNet, ok := addr.(*net.IPNet); ok && ipNet.IP.To16() != nil && ipNet.IP.To4() == nil {
address = append(address, ipNet.IP.String())
}
}
if len(address) > 0 {
log.Info("there are many address in interface: ", address)
for _, a := range address {
if strings.HasPrefix(a, "2409") {
return a
}
}
log.Errorf("can not find Global IPv6 address Prefix 2409 in interface: %s with addresss %v\n", interfaceName, address)
os.Exit(1)
}
}
}
log.Errorf("interface with name [%s] not found in system interface %v\n", interfaceName, ifacesNames)
os.Exit(1)
return ""
}
func UpdateDNS(DNS string) bool {
info := strings.Split(DNS, ":")
if len(info) != 3 {
log.Errorf("DNS format error: %s. Need to be like domain:record:type\n", DNS)
os.Exit(1)
}
rsp, err := client.UpdateDomainRecord(&dns.UpdateDomainRecordRequest{
RecordId: NewString(recordId),
RR: NewString(info[1]),
Type: NewString(info[2]),
Value: NewString(ipv6),
})
if err != nil {
sdkErr := &tea.SDKError{}
if errors.As(err, &sdkErr) {
if *sdkErr.Code == "DomainRecordDuplicate" {
log.Warnln("The DNS record already exists IP not change. no need to update")
return true
}
}
log.Errorf("DescribeDomainRecords error:%v\n", err)
return false
}
if rsp != nil && rsp.Body != nil {
return true
}
return false
}
var ipv6 string
var recordId string
func main() {
var (
accessKey string
secretKey string
interfaceName string
DNS string
duration int
logLevel string
)
flag.StringVar(&accessKey, "accessKey", "", "aliyun accessKey")
flag.StringVar(&secretKey, "secretKey", "", "aliyun secretKey")
flag.StringVar(&interfaceName, "interfaceName", "", "interface name")
flag.StringVar(&DNS, "DNS", "", "format like domain:record:type")
flag.IntVar(&duration, "duration", 10, "duration for check ipv6 address change")
flag.StringVar(&logLevel, "logLevel", "info", "log level")
flag.Parse()
// 参数校验
if accessKey == "" || secretKey == "" || interfaceName == "" || DNS == "" {
flag.Usage()
os.Exit(1)
}
// 最小间隔10s
if duration < 10 {
duration = 10
}
// 初始化
Init(accessKey, secretKey, logLevel)
// 获取recordID
if recordId == "" {
recordId = GetRecordId(DNS)
if recordId == "" {
log.Errorln("can not get dns record ID from aliyun ...")
os.Exit(1)
}
}
log.Infof("Auto update dns reslove for interface %s to DNS %s every %d seconds\n", interfaceName, DNS, duration)
// IPv6 地址检测及更新
for {
ip := GetOSIPv6(interfaceName)
if ip == "" {
log.Errorf("can not get IPv6 address from interface %s\n", interfaceName)
os.Exit(1)
}
if ip != ipv6 {
ipv6 = ip
log.Printf("IPv6 address change to %s\n", ipv6)
if UpdateDNS(DNS) {
log.Printf("Update DNS success\n")
} else {
log.Printf("Update DNS failed\n")
}
} else {
log.Printf("IPv6 address not change ...")
}
time.Sleep(time.Duration(duration) * time.Second)
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/guanjiayao/ddns.git
git@gitee.com:guanjiayao/ddns.git
guanjiayao
ddns
ddns
main

搜索帮助