mirror of
https://github.com/TeaOSLab/EdgeAPI.git
synced 2025-11-07 02:20:24 +08:00
实现DNS域名验证
This commit is contained in:
@@ -4,31 +4,35 @@ import "github.com/iwind/TeaGo/dbs"
|
|||||||
|
|
||||||
// NSDomain DNS域名
|
// NSDomain DNS域名
|
||||||
type NSDomain struct {
|
type NSDomain struct {
|
||||||
Id uint64 `field:"id"` // ID
|
Id uint64 `field:"id"` // ID
|
||||||
ClusterId uint32 `field:"clusterId"` // 集群ID
|
ClusterId uint32 `field:"clusterId"` // 集群ID
|
||||||
UserId uint32 `field:"userId"` // 用户ID
|
UserId uint32 `field:"userId"` // 用户ID
|
||||||
IsOn bool `field:"isOn"` // 是否启用
|
IsOn bool `field:"isOn"` // 是否启用
|
||||||
Name string `field:"name"` // 域名
|
Name string `field:"name"` // 域名
|
||||||
GroupIds dbs.JSON `field:"groupIds"` // 分组ID
|
GroupIds dbs.JSON `field:"groupIds"` // 分组ID
|
||||||
Tsig dbs.JSON `field:"tsig"` // TSIG配置
|
Tsig dbs.JSON `field:"tsig"` // TSIG配置
|
||||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
VerifyTXT string `field:"verifyTXT"` // 验证用的TXT
|
||||||
Version uint64 `field:"version"` // 版本号
|
VerifyExpiresAt uint64 `field:"verifyExpiresAt"` // 验证TXT过期时间
|
||||||
Status string `field:"status"` // 状态:none|verified
|
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||||
State uint8 `field:"state"` // 状态
|
Version uint64 `field:"version"` // 版本号
|
||||||
|
Status string `field:"status"` // 状态:none|verified
|
||||||
|
State uint8 `field:"state"` // 状态
|
||||||
}
|
}
|
||||||
|
|
||||||
type NSDomainOperator struct {
|
type NSDomainOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
ClusterId interface{} // 集群ID
|
ClusterId any // 集群ID
|
||||||
UserId interface{} // 用户ID
|
UserId any // 用户ID
|
||||||
IsOn interface{} // 是否启用
|
IsOn any // 是否启用
|
||||||
Name interface{} // 域名
|
Name any // 域名
|
||||||
GroupIds interface{} // 分组ID
|
GroupIds any // 分组ID
|
||||||
Tsig interface{} // TSIG配置
|
Tsig any // TSIG配置
|
||||||
CreatedAt interface{} // 创建时间
|
VerifyTXT any // 验证用的TXT
|
||||||
Version interface{} // 版本号
|
VerifyExpiresAt any // 验证TXT过期时间
|
||||||
Status interface{} // 状态:none|verified
|
CreatedAt any // 创建时间
|
||||||
State interface{} // 状态
|
Version any // 版本号
|
||||||
|
Status any // 状态:none|verified
|
||||||
|
State any // 状态
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNSDomainOperator() *NSDomainOperator {
|
func NewNSDomainOperator() *NSDomainOperator {
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
@@ -82,68 +78,6 @@ func (this *NSClusterDAO) FindEnabledNSClusterName(tx *dbs.Tx, id int64) (string
|
|||||||
FindStringCol("")
|
FindStringCol("")
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateCluster 创建集群
|
|
||||||
func (this *NSClusterDAO) CreateCluster(tx *dbs.Tx, name string, accessLogRefJSON []byte) (int64, error) {
|
|
||||||
var op = NewNSClusterOperator()
|
|
||||||
op.Name = name
|
|
||||||
|
|
||||||
if len(accessLogRefJSON) > 0 {
|
|
||||||
op.AccessLog = accessLogRefJSON
|
|
||||||
}
|
|
||||||
|
|
||||||
op.IsOn = true
|
|
||||||
op.State = NSClusterStateEnabled
|
|
||||||
|
|
||||||
// 默认端口
|
|
||||||
// TCP
|
|
||||||
{
|
|
||||||
var config = &serverconfigs.TCPProtocolConfig{}
|
|
||||||
config.IsOn = true
|
|
||||||
config.Listen = []*serverconfigs.NetworkAddressConfig{
|
|
||||||
{
|
|
||||||
Protocol: serverconfigs.ProtocolTCP,
|
|
||||||
PortRange: "53",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
configJSON, err := json.Marshal(config)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
op.Tcp = configJSON
|
|
||||||
}
|
|
||||||
|
|
||||||
// UDP
|
|
||||||
{
|
|
||||||
var config = &serverconfigs.UDPProtocolConfig{}
|
|
||||||
config.IsOn = true
|
|
||||||
config.Listen = []*serverconfigs.NetworkAddressConfig{
|
|
||||||
{
|
|
||||||
Protocol: serverconfigs.ProtocolUDP,
|
|
||||||
PortRange: "53",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
configJSON, err := json.Marshal(config)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
op.Udp = configJSON
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.SaveInt64(tx, op)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateCluster 修改集群
|
|
||||||
func (this *NSClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name string, isOn bool) error {
|
|
||||||
if clusterId <= 0 {
|
|
||||||
return errors.New("invalid clusterId")
|
|
||||||
}
|
|
||||||
var op = NewNSClusterOperator()
|
|
||||||
op.Id = clusterId
|
|
||||||
op.Name = name
|
|
||||||
op.IsOn = isOn
|
|
||||||
return this.Save(tx, op)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountAllEnabledClusters 计算可用集群数量
|
// CountAllEnabledClusters 计算可用集群数量
|
||||||
func (this *NSClusterDAO) CountAllEnabledClusters(tx *dbs.Tx) (int64, error) {
|
func (this *NSClusterDAO) CountAllEnabledClusters(tx *dbs.Tx) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
@@ -189,23 +123,6 @@ func (this *NSClusterDAO) FindAllEnabledClusterIds(tx *dbs.Tx) ([]int64, error)
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateClusterAccessLog 设置访问日志
|
|
||||||
func (this *NSClusterDAO) UpdateClusterAccessLog(tx *dbs.Tx, clusterId int64, accessLogJSON []byte) error {
|
|
||||||
return this.Query(tx).
|
|
||||||
Pk(clusterId).
|
|
||||||
Set("accessLog", accessLogJSON).
|
|
||||||
UpdateQuickly()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindClusterAccessLog 读取访问日志配置
|
|
||||||
func (this *NSClusterDAO) FindClusterAccessLog(tx *dbs.Tx, clusterId int64) ([]byte, error) {
|
|
||||||
accessLog, err := this.Query(tx).
|
|
||||||
Pk(clusterId).
|
|
||||||
Result("accessLog").
|
|
||||||
FindStringCol("")
|
|
||||||
return []byte(accessLog), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindClusterGrantId 查找集群的认证ID
|
// FindClusterGrantId 查找集群的认证ID
|
||||||
func (this *NSClusterDAO) FindClusterGrantId(tx *dbs.Tx, clusterId int64) (int64, error) {
|
func (this *NSClusterDAO) FindClusterGrantId(tx *dbs.Tx, clusterId int64) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
@@ -214,102 +131,6 @@ func (this *NSClusterDAO) FindClusterGrantId(tx *dbs.Tx, clusterId int64) (int64
|
|||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateRecursion 设置递归DNS
|
|
||||||
func (this *NSClusterDAO) UpdateRecursion(tx *dbs.Tx, clusterId int64, recursionJSON []byte) error {
|
|
||||||
err := this.Query(tx).
|
|
||||||
Pk(clusterId).
|
|
||||||
Set("recursion", recursionJSON).
|
|
||||||
UpdateQuickly()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return this.NotifyUpdate(tx, clusterId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindClusterRecursion 读取递归DNS配置
|
|
||||||
func (this *NSClusterDAO) FindClusterRecursion(tx *dbs.Tx, clusterId int64) ([]byte, error) {
|
|
||||||
recursion, err := this.Query(tx).
|
|
||||||
Result("recursion").
|
|
||||||
Pk(clusterId).
|
|
||||||
FindStringCol("")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return []byte(recursion), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindClusterTCP 查找集群的TCP设置
|
|
||||||
func (this *NSClusterDAO) FindClusterTCP(tx *dbs.Tx, clusterId int64) ([]byte, error) {
|
|
||||||
return this.Query(tx).
|
|
||||||
Pk(clusterId).
|
|
||||||
Result("tcp").
|
|
||||||
FindBytesCol()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateClusterTCP 修改集群的TCP设置
|
|
||||||
func (this *NSClusterDAO) UpdateClusterTCP(tx *dbs.Tx, clusterId int64, tcpConfig *serverconfigs.TCPProtocolConfig) error {
|
|
||||||
tcpJSON, err := json.Marshal(tcpConfig)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = this.Query(tx).
|
|
||||||
Pk(clusterId).
|
|
||||||
Set("tcp", tcpJSON).
|
|
||||||
UpdateQuickly()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return this.NotifyUpdate(tx, clusterId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindClusterTLS 查找集群的TLS设置
|
|
||||||
func (this *NSClusterDAO) FindClusterTLS(tx *dbs.Tx, clusterId int64) ([]byte, error) {
|
|
||||||
return this.Query(tx).
|
|
||||||
Pk(clusterId).
|
|
||||||
Result("tls").
|
|
||||||
FindBytesCol()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateClusterTLS 修改集群的TLS设置
|
|
||||||
func (this *NSClusterDAO) UpdateClusterTLS(tx *dbs.Tx, clusterId int64, tlsConfig *serverconfigs.TLSProtocolConfig) error {
|
|
||||||
tlsJSON, err := json.Marshal(tlsConfig)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = this.Query(tx).
|
|
||||||
Pk(clusterId).
|
|
||||||
Set("tls", tlsJSON).
|
|
||||||
UpdateQuickly()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return this.NotifyUpdate(tx, clusterId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindClusterUDP 查找集群的TCP设置
|
|
||||||
func (this *NSClusterDAO) FindClusterUDP(tx *dbs.Tx, clusterId int64) ([]byte, error) {
|
|
||||||
return this.Query(tx).
|
|
||||||
Pk(clusterId).
|
|
||||||
Result("udp").
|
|
||||||
FindBytesCol()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateClusterUDP 修改集群的UDP设置
|
|
||||||
func (this *NSClusterDAO) UpdateClusterUDP(tx *dbs.Tx, clusterId int64, udpConfig *serverconfigs.UDPProtocolConfig) error {
|
|
||||||
udpJSON, err := json.Marshal(udpConfig)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = this.Query(tx).
|
|
||||||
Pk(clusterId).
|
|
||||||
Set("udp", udpJSON).
|
|
||||||
UpdateQuickly()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return this.NotifyUpdate(tx, clusterId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountAllClustersWithSSLPolicyIds 计算使用SSL策略的所有NS集群数量
|
// CountAllClustersWithSSLPolicyIds 计算使用SSL策略的所有NS集群数量
|
||||||
func (this *NSClusterDAO) CountAllClustersWithSSLPolicyIds(tx *dbs.Tx, sslPolicyIds []int64) (count int64, err error) {
|
func (this *NSClusterDAO) CountAllClustersWithSSLPolicyIds(tx *dbs.Tx, sslPolicyIds []int64) (count int64, err error) {
|
||||||
if len(sslPolicyIds) == 0 {
|
if len(sslPolicyIds) == 0 {
|
||||||
@@ -326,45 +147,6 @@ func (this *NSClusterDAO) CountAllClustersWithSSLPolicyIds(tx *dbs.Tx, sslPolicy
|
|||||||
Count()
|
Count()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindClusterDDoSProtection 获取集群的DDoS设置
|
|
||||||
func (this *NSClusterDAO) FindClusterDDoSProtection(tx *dbs.Tx, clusterId int64) (*ddosconfigs.ProtectionConfig, error) {
|
|
||||||
one, err := this.Query(tx).
|
|
||||||
Result("ddosProtection").
|
|
||||||
Pk(clusterId).
|
|
||||||
Find()
|
|
||||||
if one == nil || err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return one.(*NSCluster).DecodeDDoSProtection(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateClusterDDoSProtection 设置集群的DDoS设置
|
|
||||||
func (this *NSClusterDAO) UpdateClusterDDoSProtection(tx *dbs.Tx, clusterId int64, ddosProtection *ddosconfigs.ProtectionConfig) error {
|
|
||||||
if clusterId <= 0 {
|
|
||||||
return ErrNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
var op = NewNSClusterOperator()
|
|
||||||
op.Id = clusterId
|
|
||||||
|
|
||||||
if ddosProtection == nil {
|
|
||||||
op.DdosProtection = "{}"
|
|
||||||
} else {
|
|
||||||
ddosProtectionJSON, err := json.Marshal(ddosProtection)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
op.DdosProtection = ddosProtectionJSON
|
|
||||||
}
|
|
||||||
|
|
||||||
err := this.Save(tx, op)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleDNS, clusterId, 0, NSNodeTaskTypeDDosProtectionChanged)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotifyUpdate 通知更改
|
// NotifyUpdate 通知更改
|
||||||
func (this *NSClusterDAO) NotifyUpdate(tx *dbs.Tx, clusterId int64) error {
|
func (this *NSClusterDAO) NotifyUpdate(tx *dbs.Tx, clusterId int64) error {
|
||||||
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleDNS, clusterId, 0, NSNodeTaskTypeConfigChanged)
|
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleDNS, clusterId, 0, NSNodeTaskTypeConfigChanged)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ type NSCluster struct {
|
|||||||
Tls dbs.JSON `field:"tls"` // TLS设置
|
Tls dbs.JSON `field:"tls"` // TLS设置
|
||||||
Udp dbs.JSON `field:"udp"` // UDP设置
|
Udp dbs.JSON `field:"udp"` // UDP设置
|
||||||
DdosProtection dbs.JSON `field:"ddosProtection"` // DDoS防护设置
|
DdosProtection dbs.JSON `field:"ddosProtection"` // DDoS防护设置
|
||||||
|
Hosts dbs.JSON `field:"hosts"` // DNS主机地址
|
||||||
}
|
}
|
||||||
|
|
||||||
type NSClusterOperator struct {
|
type NSClusterOperator struct {
|
||||||
@@ -31,6 +32,7 @@ type NSClusterOperator struct {
|
|||||||
Tls any // TLS设置
|
Tls any // TLS设置
|
||||||
Udp any // UDP设置
|
Udp any // UDP设置
|
||||||
DdosProtection any // DDoS防护设置
|
DdosProtection any // DDoS防护设置
|
||||||
|
Hosts any // DNS主机地址
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNSClusterOperator() *NSClusterOperator {
|
func NewNSClusterOperator() *NSClusterOperator {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package models
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,7 +15,7 @@ func (this *NSCluster) DecodeDDoSProtection() *ddosconfigs.ProtectionConfig {
|
|||||||
var result = &ddosconfigs.ProtectionConfig{}
|
var result = &ddosconfigs.ProtectionConfig{}
|
||||||
err := json.Unmarshal(this.DdosProtection, &result)
|
err := json.Unmarshal(this.DdosProtection, &result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// ignore err
|
remotelogs.Error("NSCluster.DecodeDDoSProtection", "decode failed: "+err.Error())
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@@ -26,4 +27,19 @@ func (this *NSCluster) HasDDoSProtection() bool {
|
|||||||
return config.IsOn()
|
return config.IsOn()
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecodeHosts 解析主机地址
|
||||||
|
func (this *NSCluster) DecodeHosts() []string {
|
||||||
|
if IsNull(this.Hosts) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var hosts = []string{}
|
||||||
|
err := json.Unmarshal(this.Hosts, &hosts)
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("NSCluster.DecodeHosts", "decode failed: "+err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return hosts
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
123
internal/utils/lookup.go
Normal file
123
internal/utils/lookup.go
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||||
|
"github.com/miekg/dns"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LookupCNAME 查询CNAME记录
|
||||||
|
// TODO 可以设置使用的DNS主机地址
|
||||||
|
func LookupCNAME(host string) (string, error) {
|
||||||
|
config, err := dns.ClientConfigFromFile("/etc/resolv.conf")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var c = new(dns.Client)
|
||||||
|
var m = new(dns.Msg)
|
||||||
|
|
||||||
|
m.SetQuestion(host+".", dns.TypeCNAME)
|
||||||
|
m.RecursionDesired = true
|
||||||
|
|
||||||
|
var lastErr error
|
||||||
|
for _, serverAddr := range config.Servers {
|
||||||
|
r, _, err := c.Exchange(m, configutils.QuoteIP(serverAddr)+":"+config.Port)
|
||||||
|
if err != nil {
|
||||||
|
lastErr = err
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(r.Answer) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.Answer[0].(*dns.CNAME).Target, nil
|
||||||
|
}
|
||||||
|
return "", lastErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupNS 查询NS记录
|
||||||
|
// TODO 可以设置使用的DNS主机地址
|
||||||
|
func LookupNS(host string) ([]string, error) {
|
||||||
|
config, err := dns.ClientConfigFromFile("/etc/resolv.conf")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var c = new(dns.Client)
|
||||||
|
var m = new(dns.Msg)
|
||||||
|
|
||||||
|
m.SetQuestion(host+".", dns.TypeNS)
|
||||||
|
m.RecursionDesired = true
|
||||||
|
|
||||||
|
var result = []string{}
|
||||||
|
|
||||||
|
var lastErr error
|
||||||
|
var hasValidServer = false
|
||||||
|
for _, serverAddr := range config.Servers {
|
||||||
|
r, _, err := c.Exchange(m, configutils.QuoteIP(serverAddr)+":"+config.Port)
|
||||||
|
if err != nil {
|
||||||
|
lastErr = err
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
hasValidServer = true
|
||||||
|
|
||||||
|
if len(r.Answer) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, answer := range r.Answer {
|
||||||
|
result = append(result, answer.(*dns.NS).Ns)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasValidServer {
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, lastErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupTXT 获取CNAME
|
||||||
|
// TODO 可以设置使用的DNS主机地址
|
||||||
|
func LookupTXT(host string) ([]string, error) {
|
||||||
|
config, err := dns.ClientConfigFromFile("/etc/resolv.conf")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var c = new(dns.Client)
|
||||||
|
var m = new(dns.Msg)
|
||||||
|
|
||||||
|
m.SetQuestion(host + ".", dns.TypeTXT)
|
||||||
|
m.RecursionDesired = true
|
||||||
|
|
||||||
|
var lastErr error
|
||||||
|
var result = []string{}
|
||||||
|
var hasValidServer = false
|
||||||
|
for _, serverAddr := range config.Servers {
|
||||||
|
r, _, err := c.Exchange(m, configutils.QuoteIP(serverAddr)+":"+config.Port)
|
||||||
|
if err != nil {
|
||||||
|
lastErr = err
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
hasValidServer = true
|
||||||
|
|
||||||
|
if len(r.Answer) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, answer := range r.Answer {
|
||||||
|
result = append(result, answer.(*dns.TXT).Txt...)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasValidServer {
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, lastErr
|
||||||
|
}
|
||||||
20
internal/utils/lookup_test.go
Normal file
20
internal/utils/lookup_test.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package utils_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLookupCNAME(t *testing.T) {
|
||||||
|
t.Log(utils.LookupCNAME("www.yun4s.cn"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLookupNS(t *testing.T) {
|
||||||
|
t.Log(utils.LookupNS("goedge.cn"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLookupTXT(t *testing.T) {
|
||||||
|
t.Log(utils.LookupTXT("yanzheng.goedge.cn"))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user