-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
lankeo
committed
Jun 23, 2022
1 parent
d23b631
commit 53118f1
Showing
13 changed files
with
619 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# Go Namesilo DDNS | ||
动态解析本地 IPv6 地址到 namesilo.com 托管的域名 | ||
|
||
### 特性 | ||
- namesilo.com DNS 记录新增(批量新增)、删除、修改、批量查,已实现 | ||
- 获取本地公共 IPv6 地址,已实现 | ||
- 动态 IPv6 地址解析,已实现 | ||
- 域名批量解析,已实现 | ||
- 定时任务自动域名解析, 未实现 | ||
|
||
### 配置 | ||
程序根目录下 `config.yaml` 文件 | ||
```yaml | ||
# namesilo API 请求 url | ||
url: | ||
base: "https://www.namesilo.com/api/" | ||
get: "dnsListRecords" | ||
add: "dnsAddRecord" | ||
update: "dnsUpdateRecord" | ||
delete: "dnsDeleteRecord" | ||
|
||
# namesilo API 要求字段 | ||
version: "1" | ||
type: "xml" | ||
|
||
# 账户设定的 key | ||
key: "dd911ac49199bb691795a" | ||
|
||
# 需要解析的域名(目前每次仅支持单个域名) | ||
domain: "example.com" | ||
|
||
# 需要添加的 DNS 解析记录(不添加请忽略) | ||
records: | ||
- | ||
# 记录值类型,值为 "A"、"AAAA"、"CNAME"、"MX"、"TXT","AAAA" 支持 IPv6 | ||
type: "AAAA" | ||
|
||
# 主机名,修改时不用包含域名 | ||
host: "www" | ||
|
||
# 记录值,IPv4 或 IPv6 地址 | ||
value: "260e:3b7:3223:d50::1000" | ||
|
||
# DNS记录在DNS服务器上的缓存时间,最小可设置为 3600 秒, 默认 7200 秒 | ||
ttl: "3600" | ||
|
||
# 仅用于 MX 类型(如果未提供,则默认为 10),其他类型默认为 0 | ||
distance: "0" | ||
- | ||
type: "AAAA" | ||
host: "" | ||
value: "260e:3b7:3223:d50::1000" | ||
ttl: "3600" | ||
distance: "0" | ||
``` | ||
### Example | ||
动态解析本地 IPv6 地址到 namesilo,所有的解析记录使用同一个本地 IPv6 地址 | ||
```go | ||
# `main.go` 文件 | ||
package main | ||
|
||
func main() { | ||
for _, rr := range ResourceRecords { | ||
rr.GetUpdateHost() | ||
rr.LocalPublicIPv6DDNS() | ||
} | ||
} | ||
``` | ||
- ResourceRecords 为所有记录值列表 | ||
|
||
根据配置文件 `config.yml` 中配置的 `records` 添加 DNS 解析记录,已存在则忽略 | ||
```go | ||
# `main.go` 文件 | ||
package main | ||
|
||
func main() { | ||
for _, rr := range ResourceRecords { | ||
rr.GetUpdateHost() | ||
} | ||
|
||
InitAddDNSRecord() | ||
} | ||
``` | ||
> Tips: 程序默认会动态解析本地 IPv6 地址到 namesilo,并根据配置添加 DNS 解析记录 | ||
### API | ||
#### Variables | ||
- var IPs [ ]string | ||
- var TargetIP string | ||
- var ResourceRecords [ ]ResourceRecord | ||
#### func GetDNSRecords(result *DNSRecordsResult) | ||
#### type ResourceRecord | ||
- #### func (rr *ResourceRecord) GetUpdateHost() | ||
- #### func (rr *ResourceRecord) UpdateDNSRecord() | ||
- #### func (rr *ResourceRecord) AddDNSRecord() | ||
- #### func (rr *ResourceRecord) DeleteDNSRecord() | ||
- #### func (rr *ResourceRecord) DeleteDNSRecord() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/xml" | ||
"io" | ||
"log" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
// 获取 DNS 记录列表 | ||
func GetDNSRecords(result *DNSRecordsResult) { | ||
url := GlobalConfig.Url.Base + GlobalConfig.Url.Get | ||
req, err := http.NewRequest("GET", url, nil) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
q := req.URL.Query() | ||
q.Add("version", GlobalConfig.Version) | ||
q.Add("type", GlobalConfig.Type) | ||
q.Add("key", GlobalConfig.Key) | ||
q.Add("domain", GlobalConfig.Domain) | ||
req.URL.RawQuery = q.Encode() | ||
log.Println("【查询】", req.URL.String()) | ||
|
||
client := &http.Client{} | ||
resp, err := client.Do(req) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
defer resp.Body.Close() | ||
|
||
body, err := io.ReadAll(resp.Body) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
err = xml.Unmarshal(body, result) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
result.Reply.RecordFailedLog() | ||
} | ||
|
||
// 获取更新记录值时需要传的 host, 保持原 host 不变 | ||
func (rr *ResourceRecord) GetUpdateHost() { | ||
if rr.Host == GlobalConfig.Domain { | ||
rr.Host = "" | ||
} else { | ||
rr.Host = strings.Split(rr.Host, "."+GlobalConfig.Domain)[0] | ||
} | ||
} | ||
|
||
// 更新 DNS 记录 | ||
func (rr *ResourceRecord) UpdateDNSRecord() { | ||
url := GlobalConfig.Url.Base + GlobalConfig.Url.Update | ||
req, err := http.NewRequest("GET", url, nil) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
q := req.URL.Query() | ||
q.Add("version", GlobalConfig.Version) | ||
q.Add("type", GlobalConfig.Type) | ||
q.Add("key", GlobalConfig.Key) | ||
q.Add("domain", GlobalConfig.Domain) | ||
|
||
q.Add("rrid", rr.RecordId) | ||
q.Add("rrhost", rr.Host) | ||
q.Add("rrvalue", rr.Value) | ||
q.Add("rrttl", rr.Ttl) | ||
q.Add("rrdistance", rr.Distance) | ||
req.URL.RawQuery = q.Encode() | ||
log.Println("【更新】", req.URL.String()) | ||
|
||
client := &http.Client{} | ||
resp, err := client.Do(req) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
defer resp.Body.Close() | ||
|
||
body, err := io.ReadAll(resp.Body) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
result := &DNSRecordsOperateResult{} | ||
err = xml.Unmarshal(body, result) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
result.Reply.RecordFailedLog() | ||
|
||
result.RecordSuccessLog(rr.Value, "Update") | ||
} | ||
|
||
// 添加 DNS 记录 | ||
func (rr *ResourceRecord) AddDNSRecord() { | ||
url := GlobalConfig.Url.Base + GlobalConfig.Url.Add | ||
req, err := http.NewRequest("GET", url, nil) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
q := req.URL.Query() | ||
q.Add("version", GlobalConfig.Version) | ||
q.Add("type", GlobalConfig.Type) | ||
q.Add("key", GlobalConfig.Key) | ||
q.Add("domain", GlobalConfig.Domain) | ||
|
||
q.Add("rrtype", rr.Type) | ||
q.Add("rrhost", rr.Host) | ||
q.Add("rrvalue", rr.Value) | ||
q.Add("rrttl", rr.Ttl) | ||
q.Add("rrdistance", rr.Distance) | ||
req.URL.RawQuery = q.Encode() | ||
log.Println("【新增】", req.URL.String()) | ||
|
||
client := &http.Client{} | ||
resp, err := client.Do(req) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
defer resp.Body.Close() | ||
|
||
body, err := io.ReadAll(resp.Body) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
result := &DNSRecordsOperateResult{} | ||
err = xml.Unmarshal(body, result) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
result.Reply.RecordFailedLog() | ||
|
||
result.RecordSuccessLog(rr.Value, "Add") | ||
} | ||
|
||
// 删除 DNS 记录 | ||
func (rr *ResourceRecord) DeleteDNSRecord() { | ||
url := GlobalConfig.Url.Base + GlobalConfig.Url.Delete | ||
req, err := http.NewRequest("GET", url, nil) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
q := req.URL.Query() | ||
q.Add("version", GlobalConfig.Version) | ||
q.Add("type", GlobalConfig.Type) | ||
q.Add("key", GlobalConfig.Key) | ||
q.Add("domain", GlobalConfig.Domain) | ||
|
||
q.Add("rrid", rr.RecordId) | ||
|
||
req.URL.RawQuery = q.Encode() | ||
log.Println("【删除】", req.URL.String()) | ||
|
||
client := &http.Client{} | ||
resp, err := client.Do(req) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
defer resp.Body.Close() | ||
|
||
body, err := io.ReadAll(resp.Body) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
result := &DNSRecordsOperateResult{} | ||
err = xml.Unmarshal(body, result) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
result.Reply.RecordFailedLog() | ||
|
||
result.RecordSuccessLog(rr.Value, "Delete") | ||
} | ||
|
||
// 动态解析本地 IPv6 地址到 namesilo | ||
func (rr *ResourceRecord) LocalPublicIPv6DDNS() { | ||
// ip 变化则更新记录值 | ||
if isLatest := InList(IPs, rr.Value); isLatest { | ||
// 记录值已是最新 ip | ||
rr.RecordIsLatestLog() | ||
} else { | ||
// 更新记录值 | ||
rr.Value = TargetIP | ||
rr.UpdateDNSRecord() | ||
} | ||
} | ||
|
||
// 配置中需要初始化添加的记录值 | ||
func InitAddDNSRecord() { | ||
for _, record := range GlobalConfig.Records { | ||
if InList(ResourceRecordHosts, record.Host) { | ||
log.Printf(`【配置记录值初始化】Host: "%s" 已存在于记录值列表,将自动忽略`, record.Host) | ||
continue | ||
} | ||
if len(record.Type) == 0 || len(record.Value) == 0 || len(record.Distance) == 0 { | ||
log.Fatalln("ConfigError: record 中 type, value, ttl 为必填项") | ||
} | ||
r := ResourceRecord{} | ||
r.Type = record.Type | ||
r.Host = record.Host | ||
r.Value = record.Value | ||
r.Ttl = record.Ttl | ||
r.Distance = record.Distance | ||
r.AddDNSRecord() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# namesilo API 请求 url | ||
url: | ||
base: "https://www.namesilo.com/api/" | ||
get: "dnsListRecords" | ||
add: "dnsAddRecord" | ||
update: "dnsUpdateRecord" | ||
delete: "dnsDeleteRecord" | ||
|
||
# namesilo API 要求字段 | ||
version: "1" | ||
type: "xml" | ||
|
||
# 账户设定的 key | ||
key: "dd911ac49199bb691795a" | ||
|
||
# 需要解析的域名(目前每次仅支持单个域名) | ||
domain: "example.com" | ||
|
||
# 需要添加的 DNS 解析记录(不添加请忽略) | ||
records: | ||
- | ||
# 记录值类型,值为 "A"、"AAAA"、"CNAME"、"MX"、"TXT","AAAA" 支持 IPv6 | ||
type: "AAAA" | ||
|
||
# 主机名,修改时不用包含域名 | ||
host: "www" | ||
|
||
# 记录值,IPv4 或 IPv6 地址 | ||
value: "260e:3b7:3223:d50::1000" | ||
|
||
# DNS记录在DNS服务器上的缓存时间,最小可设置为 3600 秒, 默认 7200 秒 | ||
ttl: "3600" | ||
|
||
# 仅用于 MX 类型(如果未提供,则默认为 10),其他类型默认为 0 | ||
distance: "0" | ||
- | ||
type: "AAAA" | ||
host: "" | ||
value: "260e:3b7:3223:d50::1000" | ||
ttl: "3600" | ||
distance: "0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package main | ||
|
||
// func main() { | ||
// for _, rr := range ResourceRecords { | ||
// rr.LocalPublicIPv6DDNS() | ||
|
||
// // 更新单个记录值 | ||
// if rr.Host == "scpc.games."+GlobalConfig.Domain { | ||
// rr.Value = IPs[0] | ||
// rr.Host = "" | ||
// rr.UpdateDNSRecord() | ||
// } | ||
|
||
// // 删除单个记录 | ||
// if rr.Host == "bad."+GlobalConfig.Domain { | ||
// rr.DeleteDNSRecord() | ||
// } | ||
// } | ||
|
||
// // 添加记录值 | ||
// rr := &ResourceRecord{ | ||
// Type: "AAAA", | ||
// Host: "Bad3", | ||
// Value: "240e:3b7:3223:da50:881d:b582:8fae:1cbd", | ||
// Ttl: "3600", | ||
// } | ||
// rr.AddDNSRecord() | ||
// } |
Oops, something went wrong.