ddns4/main.go

146 lines
2.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"fmt"
"io"
"log"
"net"
"net/http"
"os"
"strings"
"time"
"github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
)
// getPublicIP 通过外部 API 获取公网 IPv4 地址
func getPublicIP() (string, error) {
// 使用多个 IP 查询服务作为备选
apis := []string{
"https://api.ipify.org",
"https://ifconfig.me/ip",
"https://ipecho.net/plain",
}
for _, api := range apis {
resp, err := http.Get(api)
if err != nil {
log.Printf("Error fetching IP from %s: %v", api, err)
continue
}
body, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
log.Printf("Error reading response from %s: %v", api, err)
continue
}
ip := strings.TrimSpace(string(body))
if net.ParseIP(ip) != nil {
return ip, nil
}
}
return "", fmt.Errorf("failed to get public IP from all APIs")
}
func main() {
domain := os.Getenv("DOMAIN")
rr := os.Getenv("RR")
regionID := os.Getenv("REGIONID")
if regionID == "" {
regionID = "cn-hangzhou"
}
accessKeyID := os.Getenv("ACCESSKEYID")
accessSecret := os.Getenv("ACCESSSECRET")
ip4 := ""
for {
time.Sleep(10 * time.Second)
currentIPV4, err := getPublicIP()
if err != nil {
log.Println("Error getting public IP:", err)
continue
}
if currentIPV4 == "" || currentIPV4 == ip4 {
continue
}
client, err := alidns.NewClientWithAccessKey(regionID, accessKeyID, accessSecret)
if err != nil {
log.Println(err.Error())
continue
}
drRequest := alidns.CreateDescribeDomainRecordsRequest()
drRequest.KeyWord = rr
drRequest.DomainName = domain
drRequest.TypeKeyWord = "A"
drResponse, err := client.DescribeDomainRecords(drRequest)
if err != nil {
log.Println(err)
continue
}
if !drResponse.IsSuccess() {
continue
}
rid := ""
for _, r := range drResponse.DomainRecords.Record {
rid = r.RecordId
if r.Value == currentIPV4 {
ip4 = currentIPV4
rid = ""
}
break
}
if rid == "" {
continue
}
//修改域名对应的IP修改成功后continue
req := alidns.CreateUpdateDomainRecordRequest()
req.Scheme = "https"
req.RR = rr
req.RecordId = rid
req.Value = currentIPV4
req.Type = "A"
resp, err := client.UpdateDomainRecord(req)
if err != nil {
log.Println(err.Error())
if !strings.Contains(err.Error(), fmt.Sprintf("not %s", domain)) {
continue
}
}
if resp.IsSuccess() {
ip4 = currentIPV4
log.Println("update success: ", ip4)
continue
}
//当域名修改失败时判断是否是没有对应的记录,不存在时创建新的域名记录
request := alidns.CreateAddDomainRecordRequest()
request.Scheme = "https"
request.Value = currentIPV4
request.Type = "A"
request.RR = rr
request.DomainName = domain
response, err := client.AddDomainRecord(request)
if err != nil {
fmt.Print(err.Error())
continue
}
if !response.IsSuccess() {
fmt.Print(response.GetHttpContentString())
ip4 = currentIPV4
}
}
}