对IPv4进行动态解释
This commit is contained in:
commit
32010c77d1
|
|
@ -0,0 +1,7 @@
|
|||
*.exe
|
||||
.vscode/
|
||||
go.sum
|
||||
ddns6
|
||||
*.cmd
|
||||
.env
|
||||
ddns4
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
FROM harbor.ks.easyj.top/zt/alpine:0.1
|
||||
|
||||
ENV APP_DIR=/app \
|
||||
DOMAIN=myschools.me \
|
||||
RR=pi \
|
||||
REGIONID=cn-hangzhou \
|
||||
ACCESSKEYID=LTAI5tJV828nqSqGpkouh1FD \
|
||||
ACCESSSECRET=aiMEp37bHLOjtoJFTDTfpq1o37cGtA
|
||||
|
||||
COPY ddns4 ${APP_DIR}/ddns4
|
||||
|
||||
WORKDIR ${APP_DIR}
|
||||
|
||||
RUN chmod +x ddns4
|
||||
|
||||
CMD ["./ddns4"]
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
module myschools.me/suguo/ddns6
|
||||
|
||||
go 1.19
|
||||
|
||||
require github.com/aliyun/alibaba-cloud-sdk-go v1.62.676
|
||||
|
||||
require (
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
|
||||
github.com/json-iterator/go v1.1.10 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
|
||||
gopkg.in/ini.v1 v1.66.2 // indirect
|
||||
)
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# DDNS4
|
||||
|
||||
---
|
||||
|
||||
|
||||
一、概述
|
||||
|
||||
把当前主机的IPV4向阿里DNS进行注册,实现IPV4 DDNS功能。当二级域名没有创建时会自动创建,解释使用A类型,每10秒检测一次当前主机的IPV4地址,如果发生变化则自动更新到阿里DNS。如果存在多个IPV4地址,则只更新第一个IPV4地址。
|
||||
|
||||
二、组件
|
||||
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.62.676
|
||||
|
||||
三、配置
|
||||
|
||||
1. 阿里云配置RAM访问控制,权限如下:
|
||||
|
||||
AliyunDNSFullAccess
|
||||
AliyunHTTPDNSFullAccess
|
||||
|
||||
2. 环境变量
|
||||
DOMAIN 域名
|
||||
RR 二级域名
|
||||
REGIONID 地域,默认cn-hangzhou
|
||||
ACCESSKEYID 访问key
|
||||
ACCESSSECRET 访问私钥
|
||||
|
||||
四、 调试
|
||||
|
||||
Loading…
Reference in New Issue