fix: more bug fix

This commit is contained in:
骑着蜗牛追导弹 2024-11-12 20:34:02 +08:00
parent 0dfd04005d
commit c0208cb947
8 changed files with 193 additions and 13 deletions

10
PodCurlName.md Normal file
View File

@ -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}

View File

@ -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 命令不存在解决

View File

@ -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")
}

53
common/set.go Normal file
View File

@ -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
}

View File

@ -6,5 +6,6 @@ package config
* @Date 20241108
*/
const (
DnsServerPort = ":53"
DNSServerPort = ":53"
ForwardDNServer = "8.8.8.8:53" // Google的公共DNS服务器
)

View File

@ -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
}

View File

@ -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)
}

View File

@ -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 {