fix: more bug fix
This commit is contained in:
parent
0dfd04005d
commit
c0208cb947
|
@ -0,0 +1,10 @@
|
|||
curl www.odboy.cn
|
||||
|
||||
{"www.odboy.cn.springboot-standard-demo.svc.cluster.local", "A", 2}
|
||||
{"www.odboy.cn.springboot-standard-demo.svc.cluster.local", "AAAA", 2}
|
||||
{"www.odboy.cn.cluster.local", "A", 2}
|
||||
{"www.odboy.cn.cluster.local", "AAAA", 2}
|
||||
{"www.odboy.cn.io.local", "A", 2}
|
||||
{"www.odboy.cn.io.local", "AAAA", 2}
|
||||
{"www.odboy.cn", "A", 2}
|
||||
{"www.odboy.cn", "AAAA", 2}
|
35
README.md
35
README.md
|
@ -131,6 +131,41 @@ DNS服务所在的ip地址为 192.168.43.130
|
|||
![rollback1](https://oss.odboy.cn/blog/files/onlinedoc/kenaito-dns/rollback_func.png)
|
||||
![rollback2](https://oss.odboy.cn/blog/files/onlinedoc/kenaito-dns/rollback_func2.png)
|
||||
|
||||
## k8s集群中使用
|
||||
|
||||
```shell
|
||||
# 使用的是CoreDNS,并且配置上游DNS服务器
|
||||
kubectl edit configmap coredns -n kube-system
|
||||
# ---------------------------------------------------
|
||||
apiVersion: v1
|
||||
data:
|
||||
Corefile: |
|
||||
.:53 {
|
||||
errors
|
||||
health
|
||||
lameduck 5s
|
||||
ready
|
||||
kubernetes cluster.local in-addr.arpa ip6.arpa {
|
||||
pods insecure
|
||||
upstream 192.168.1.103
|
||||
fallthrough in-addr.arpa ip6.arpa cluster.local io.local
|
||||
ttl 30
|
||||
}
|
||||
prometheus :9153
|
||||
cache 30
|
||||
loop
|
||||
reload
|
||||
loadbalance
|
||||
}
|
||||
kind: ConfigMap
|
||||
# ---------------------------------------------------
|
||||
|
||||
# 逐个重启 coredns pod
|
||||
kubectl get pod -A|grep coredns|awk '{print $2}'|xargs -I{} kubectl delete pod {} -n kube-system
|
||||
|
||||
# 进入容器验证
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
#### nslookup 命令不存在解决
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
package cache
|
||||
|
||||
/*
|
||||
* @Description 缓存
|
||||
* @Author www.odboy.cn
|
||||
* @Date 20241107
|
||||
*/
|
||||
import (
|
||||
"fmt"
|
||||
"kenaito-dns/common"
|
||||
"kenaito-dns/config"
|
||||
"kenaito-dns/dao"
|
||||
"sync"
|
||||
|
@ -10,11 +16,13 @@ import (
|
|||
|
||||
var KeyResolveRecordMap sync.Map
|
||||
var IdResolveRecordMap sync.Map
|
||||
var NameSet *common.Set
|
||||
|
||||
func ReloadCache() {
|
||||
fmt.Println("[app] [info] " + time.Now().Format(config.AppTimeFormat) + " [Cache] Reload cache start")
|
||||
KeyResolveRecordMap.Range(cleanKeyCache)
|
||||
IdResolveRecordMap.Range(cleanIdCache)
|
||||
NameSet = common.NewSet()
|
||||
resolveRecords := dao.FindResolveRecordByVersion(dao.GetResolveVersion(), false)
|
||||
for _, record := range resolveRecords {
|
||||
// id -> resolveRecord
|
||||
|
@ -31,6 +39,7 @@ func ReloadCache() {
|
|||
records = append(newRecords, record)
|
||||
KeyResolveRecordMap.Store(cacheKey, records)
|
||||
}
|
||||
NameSet.Add(record.Name)
|
||||
}
|
||||
fmt.Println("[app] [info] " + time.Now().Format(config.AppTimeFormat) + " [Cache] Reload cache end")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package common
|
||||
|
||||
/*
|
||||
* @Description 自定义Set结构
|
||||
* @Author www.odboy.cn
|
||||
* @Date 20241112
|
||||
*/
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Set struct {
|
||||
m map[string]struct{}
|
||||
}
|
||||
|
||||
func NewSet() *Set {
|
||||
return &Set{m: make(map[string]struct{})}
|
||||
}
|
||||
|
||||
func (s *Set) Add(val string) {
|
||||
s.m[val] = struct{}{}
|
||||
}
|
||||
|
||||
func (s *Set) Remove(val string) {
|
||||
delete(s.m, val)
|
||||
}
|
||||
|
||||
func (s *Set) Contains(val string) bool {
|
||||
_, exists := s.m[val]
|
||||
return exists
|
||||
}
|
||||
|
||||
func (s *Set) Size() int {
|
||||
return len(s.m)
|
||||
}
|
||||
|
||||
func (s *Set) GetSimilarityValue(text string) string {
|
||||
for key := range s.m {
|
||||
if strings.HasPrefix(text, key+".") {
|
||||
return key
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func main() {
|
||||
set := NewSet()
|
||||
set.Add("bad")
|
||||
set.Add("man")
|
||||
fmt.Println(set.Contains("man")) // 输出: true
|
||||
fmt.Println(set.Size()) // 输出: 2
|
||||
}
|
|
@ -6,5 +6,6 @@ package config
|
|||
* @Date 20241108
|
||||
*/
|
||||
const (
|
||||
DnsServerPort = ":53"
|
||||
DNSServerPort = ":53"
|
||||
ForwardDNServer = "8.8.8.8:53" // Google的公共DNS服务器
|
||||
)
|
||||
|
|
|
@ -27,19 +27,34 @@ func HandleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
|||
for _, question := range r.Question {
|
||||
switch question.Qtype {
|
||||
case dns.TypeA:
|
||||
handleARecord(question, msg)
|
||||
isFound := handleARecord(question, msg)
|
||||
if !isFound {
|
||||
forwardGlobalServer(question.Name, dns.TypeA, msg)
|
||||
}
|
||||
break
|
||||
case dns.TypeAAAA:
|
||||
handleAAAARecord(question, msg)
|
||||
isFound := handleAAAARecord(question, msg)
|
||||
if !isFound {
|
||||
forwardGlobalServer(question.Name, dns.TypeAAAA, msg)
|
||||
}
|
||||
break
|
||||
case dns.TypeCNAME:
|
||||
handleCNAMERecord(question, msg)
|
||||
isFound := handleCNAMERecord(question, msg)
|
||||
if !isFound {
|
||||
forwardGlobalServer(question.Name, dns.TypeCNAME, msg)
|
||||
}
|
||||
break
|
||||
case dns.TypeMX:
|
||||
handleMXRecord(question, msg)
|
||||
isFound := handleMXRecord(question, msg)
|
||||
if !isFound {
|
||||
forwardGlobalServer(question.Name, dns.TypeMX, msg)
|
||||
}
|
||||
break
|
||||
case dns.TypeTXT:
|
||||
handleTXTRecord(question, msg)
|
||||
isFound := handleTXTRecord(question, msg)
|
||||
if !isFound {
|
||||
forwardGlobalServer(question.Name, dns.TypeTXT, msg)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -50,8 +65,43 @@ func HandleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
|||
}
|
||||
}
|
||||
|
||||
// 发送DNS请求到公共DNS服务器
|
||||
func forwardGlobalServer(name string, rrType uint16, msg *dns.Msg) {
|
||||
m := new(dns.Msg)
|
||||
m.Authoritative = true
|
||||
m.RecursionAvailable = true
|
||||
m.SetQuestion(name, rrType)
|
||||
c := new(dns.Client)
|
||||
r, _, err := c.Exchange(m, config.ForwardDNServer)
|
||||
if err != nil {
|
||||
fmt.Printf("[dns] [error] "+time.Now().Format(config.AppTimeFormat)+" [DNS] Lookup Failed: %s\n", err.Error())
|
||||
}
|
||||
if r.Rcode != dns.RcodeSuccess {
|
||||
fmt.Printf("[dns] [error] " + time.Now().Format(config.AppTimeFormat) + " [DNS] Lookup Failed \n")
|
||||
}
|
||||
for _, record := range r.Answer {
|
||||
switch r := record.(type) {
|
||||
case *dns.A:
|
||||
msg.Answer = append(msg.Answer, r)
|
||||
break
|
||||
case *dns.AAAA:
|
||||
msg.Answer = append(msg.Answer, r)
|
||||
break
|
||||
case *dns.MX:
|
||||
msg.Answer = append(msg.Answer, r)
|
||||
break
|
||||
case *dns.TXT:
|
||||
msg.Answer = append(msg.Answer, r)
|
||||
break
|
||||
case *dns.CNAME:
|
||||
msg.Answer = append(msg.Answer, r)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 构建 A 记录 IPV4
|
||||
func handleARecord(q dns.Question, msg *dns.Msg) {
|
||||
func handleARecord(q dns.Question, msg *dns.Msg) bool {
|
||||
name := q.Name
|
||||
queryName := name[0 : len(name)-1]
|
||||
var records []dao.ResolveRecord
|
||||
|
@ -62,7 +112,13 @@ func handleARecord(q dns.Question, msg *dns.Msg) {
|
|||
records = value.([]dao.ResolveRecord)
|
||||
fmt.Println("[app] [info] " + time.Now().Format(config.AppTimeFormat) + " [Cache] Query cache end")
|
||||
} else {
|
||||
//// 支持pod内置域名解析
|
||||
//similarityValue := cache.NameSet.GetSimilarityValue(queryName)
|
||||
//if similarityValue != "" {
|
||||
// records = dao.FindResolveRecordByNameType(similarityValue, constant.R_A)
|
||||
//} else {
|
||||
records = dao.FindResolveRecordByNameType(queryName, constant.R_A)
|
||||
//}
|
||||
}
|
||||
if len(records) > 0 {
|
||||
for _, record := range records {
|
||||
|
@ -79,11 +135,13 @@ func handleARecord(q dns.Question, msg *dns.Msg) {
|
|||
}
|
||||
msg.Answer = append(msg.Answer, rr)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 构建 AAAA 记录 IPV6
|
||||
func handleAAAARecord(q dns.Question, msg *dns.Msg) {
|
||||
func handleAAAARecord(q dns.Question, msg *dns.Msg) bool {
|
||||
name := q.Name
|
||||
queryName := name[0 : len(name)-1]
|
||||
var records []dao.ResolveRecord
|
||||
|
@ -94,7 +152,13 @@ func handleAAAARecord(q dns.Question, msg *dns.Msg) {
|
|||
records = value.([]dao.ResolveRecord)
|
||||
fmt.Println("[app] [info] " + time.Now().Format(config.AppTimeFormat) + " [Cache] Query cache end")
|
||||
} else {
|
||||
//// 支持pod内置域名解析
|
||||
//similarityValue := cache.NameSet.GetSimilarityValue(queryName)
|
||||
//if similarityValue != "" {
|
||||
// records = dao.FindResolveRecordByNameType(similarityValue, constant.R_AAAA)
|
||||
//} else {
|
||||
records = dao.FindResolveRecordByNameType(queryName, constant.R_AAAA)
|
||||
//}
|
||||
}
|
||||
if len(records) > 0 {
|
||||
for _, record := range records {
|
||||
|
@ -111,11 +175,13 @@ func handleAAAARecord(q dns.Question, msg *dns.Msg) {
|
|||
}
|
||||
msg.Answer = append(msg.Answer, rr)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 构建 CNAME 记录
|
||||
func handleCNAMERecord(q dns.Question, msg *dns.Msg) {
|
||||
func handleCNAMERecord(q dns.Question, msg *dns.Msg) bool {
|
||||
name := q.Name
|
||||
queryName := name[0 : len(name)-1]
|
||||
var records []dao.ResolveRecord
|
||||
|
@ -142,11 +208,13 @@ func handleCNAMERecord(q dns.Question, msg *dns.Msg) {
|
|||
}
|
||||
msg.Answer = append(msg.Answer, rr)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 构建 MX 记录
|
||||
func handleMXRecord(q dns.Question, msg *dns.Msg) {
|
||||
func handleMXRecord(q dns.Question, msg *dns.Msg) bool {
|
||||
name := q.Name
|
||||
queryName := name[0 : len(name)-1]
|
||||
var records []dao.ResolveRecord
|
||||
|
@ -174,11 +242,13 @@ func handleMXRecord(q dns.Question, msg *dns.Msg) {
|
|||
}
|
||||
msg.Answer = append(msg.Answer, rr)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 构建 TXT 记录
|
||||
func handleTXTRecord(q dns.Question, msg *dns.Msg) {
|
||||
func handleTXTRecord(q dns.Question, msg *dns.Msg) bool {
|
||||
name := q.Name
|
||||
queryName := name[0 : len(name)-1]
|
||||
var records []dao.ResolveRecord
|
||||
|
@ -205,5 +275,7 @@ func handleTXTRecord(q dns.Question, msg *dns.Msg) {
|
|||
}
|
||||
msg.Answer = append(msg.Answer, rr)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
|
@ -71,7 +71,7 @@ func FindResolveRecordByVersion(version int, isAll bool) []ResolveRecord {
|
|||
|
||||
func FindResolveRecordByNameType(name string, recordType string) []ResolveRecord {
|
||||
var records []ResolveRecord
|
||||
err := Engine.Table("resolve_record").Where("`name` = ? and `record_type` = ? and `version` = ?", name, recordType, GetResolveVersion()).Find(&records)
|
||||
err := Engine.Table("resolve_record").Where("`name` = ? and `record_type` = ? and `version` = ? and `enabled` = ?", name, recordType, GetResolveVersion(), 1).Find(&records)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
|
2
main.go
2
main.go
|
@ -28,7 +28,7 @@ func initDNSServer() {
|
|||
// 注册 DNS 请求处理函数
|
||||
dns.HandleFunc(".", core.HandleDNSRequest)
|
||||
// 设置服务器地址和协议
|
||||
server := &dns.Server{Addr: config.DnsServerPort, Net: "udp"}
|
||||
server := &dns.Server{Addr: config.DNSServerPort, Net: "udp"}
|
||||
// 开始监听
|
||||
fmt.Printf("[dns] [info] "+time.Now().Format(config.AppTimeFormat)+" Starting DNS server on %s\n", server.Addr)
|
||||
if err := server.ListenAndServe(); err != nil {
|
||||
|
|
Loading…
Reference in New Issue