diff options
| author | 段 百威 <[email protected]> | 2024-09-04 08:17:13 +0000 |
|---|---|---|
| committer | 段 百威 <[email protected]> | 2024-09-04 08:17:13 +0000 |
| commit | 4482705c9aa22f61fcc33b252a30ee505f906040 (patch) | |
| tree | f925aabb46f7b06b87ae89289c349e7c5d342427 | |
| parent | 022999021890b0a576910f104ebaf4c31fc052d6 (diff) | |
| parent | 2d96fec1c731a34c32bdb93bbfffe3ef4751833f (diff) | |
Merge branch 'master' into 'main'
添加更多代码,图片、ppt、录屏材料
See merge request Minato/coredns_dnsovertor!1
46 files changed, 1466 insertions, 0 deletions
diff --git a/dotor分享-段百威.pptx b/dotor分享-段百威.pptx Binary files differnew file mode 100644 index 0000000..c8fff19 --- /dev/null +++ b/dotor分享-段百威.pptx diff --git a/dotor视频ppt.pptx b/dotor视频ppt.pptx Binary files differnew file mode 100644 index 0000000..78cbb42 --- /dev/null +++ b/dotor视频ppt.pptx diff --git a/代码/dnsovertor0.1/dnsovertor.go b/代码/dnsovertor0.1/dnsovertor.go new file mode 100644 index 0000000..369a32e --- /dev/null +++ b/代码/dnsovertor0.1/dnsovertor.go @@ -0,0 +1,141 @@ +// Package dnsovertor implements a plugin. +package dnsovertor + +import ( + "context" + "crypto/tls" + "encoding/base64" + "fmt" + "io/ioutil" + "net/http" + "os" + "time" + + "github.com/coredns/coredns/request" + "github.com/miekg/dns" + "golang.org/x/net/proxy" + + "github.com/coredns/coredns/plugin" + + clog "github.com/coredns/coredns/plugin/pkg/log" +) + +var log = clog.NewWithPlugin("dnsovertor") + +// Dnsovertor is a plugin in CoreDNS。用于匿名解析网关。 +// 在启用cache插件的情况下,初次处理DNS请求后,本地留有缓存(一块儿储存结果的全局变量),第二次将不会调用到这个dnsovertor插件。 +// Next为固定格式。Hsaddr表示隐藏服务地址。以.onion结尾。 TorCtrlPort应配置为已经启动的tor进程中torrc配置的ControlPort。 +type Dnsovertor struct { + Next plugin.Handler + Hsaddr string + TorCtrlPort string +} + +// 未经特殊配置的默认tor control port is 9050 +func NewDnsovertorPlugin(next plugin.Handler, Hsaddr string, TorCtrlPort string) *Dnsovertor { + + log.Debugf( + "Creating dnsovertor plugin with %s", + Hsaddr, + ) + + p := &Dnsovertor{ + Hsaddr: Hsaddr, + Next: next, + TorCtrlPort: TorCtrlPort, + } + + return p +} + +// ServeDNS implements the plugin.Handler interface. +func (p Dnsovertor) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { + // 固定写法,获取请求信息 + state := request.Request{W: w, Req: r} + qname := state.Name() + // 标准输出中打印日志 + t0 := time.Now() + timeStr := time.Now().Format("2006-01-02 15:04:05") + fmt.Printf("dnsovertor解析\n接收请求时间:" + timeStr) + fmt.Printf("接收请求域名:" + qname + "\n") + + //创建HTTP客户端 + //创建socks5代理拨号器 + dialer, err := proxy.SOCKS5("tcp", "127.0.0.1:"+p.TorCtrlPort, nil, proxy.Direct) + if err != nil { + fmt.Fprintln(os.Stderr, "can't connect to the proxy:", err) + os.Exit(1) + } + //设置http client。禁用TLS验证。启用 HTTP Keep-Alive,允许连接重用。设置超时时间为 10 秒。 + httpTransport := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + httpTransport.DisableKeepAlives = false + httpClient := &http.Client{ + Transport: httpTransport, + Timeout: 10 * time.Second, + } + // 将socks5代理设置为 拨号方法,这样 HTTP 客户端就会通过 SOCKS5 代理发送请求。 + httpTransport.Dial = dialer.Dial + + //创建DNS查询请求,查询A记录(实际上应该查询原请求的记录类型) + query := dns.Msg{} + query.SetQuestion(qname, dns.TypeA) + timeStr1 := time.Now().Format("2006-01-02 15:04:05") + fmt.Printf("发送请求时间:" + timeStr1) + fmt.Printf("发送请求域名:" + qname + "\n") + msg, _ := query.Pack() + b64 := base64.RawURLEncoding.EncodeToString(msg) + + + // 发送HTTPS请求 + resp, err := httpClient.Get("https://" + p.Hsaddr + "/dns-query?dns=" + b64) + if err != nil { + fmt.Printf("Send query error, err:%v\n", err) + } + + defer resp.Body.Close()// 资源清理 + bodyBytes, _ := ioutil.ReadAll(resp.Body) + response := dns.Msg{} + response.Unpack(bodyBytes) + + timeStr2 := time.Now().Format("2006-01-02 15:04:05") + fmt.Println("接收响应时间:" + timeStr2) + fmt.Println("接收响应信息:") + for i := 0; i < len(response.Answer); i++ { + //a := response.Answer[i].Header() + b := response.Answer[i].String() + //fmt.Printf("Dns answer name is :" + a.Name + "\n") + fmt.Printf(b + "\t") + } + fmt.Printf("\n") + //fmt.Printf("Dns answer is :%v\n", response.String()) + + //m := new(dns.Msg) + response.SetReply(r) //m是r的reply + //m.Authoritative = true + //m.Answer = answers + var msg22 *dns.Msg + msg22 = &response + timeStr3 := time.Now().Format("2006-01-02 15:04:05") + fmt.Println("发送响应时间:" + timeStr3) + fmt.Printf("发送响应信息:") + for i := 0; i < len(response.Answer); i++ { + //a := response.Answer[i].Header() + b := response.Answer[i].String() + //fmt.Printf("Dns answer name is :" + a.Name + "\n") + fmt.Printf(b + "\t") + } + t1 := time.Now() + d := t1.Sub(t0) + fmt.Printf("处理时间:") + fmt.Println(d) + + w.WriteMsg(msg22) + return dns.RcodeSuccess, nil +} + +// Name implements the Handler interface. +func (p Dnsovertor) Name() string { return "dnsovertor" } + + diff --git a/代码/dnsovertor0.1/dotor代码说明.docx b/代码/dnsovertor0.1/dotor代码说明.docx Binary files differnew file mode 100644 index 0000000..57a8e5d --- /dev/null +++ b/代码/dnsovertor0.1/dotor代码说明.docx diff --git a/代码/dnsovertor0.1/metrics.go b/代码/dnsovertor0.1/metrics.go new file mode 100644 index 0000000..516c059 --- /dev/null +++ b/代码/dnsovertor0.1/metrics.go @@ -0,0 +1,17 @@ +package dnsovertor + +import ( + "github.com/coredns/coredns/plugin" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +// 向dns隐藏服务转发的请求的数量 +var dotorCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: "dnsovertor", + Name: "dnsovertor_hits_total", + Help: "Counter of the number of requests made to warnlisted domains.", +}, []string{"server", "requestor", "domain"}) + diff --git a/代码/dnsovertor0.1/readme.txt b/代码/dnsovertor0.1/readme.txt new file mode 100644 index 0000000..6af82bc --- /dev/null +++ b/代码/dnsovertor0.1/readme.txt @@ -0,0 +1 @@ +稳定版本
\ No newline at end of file diff --git a/代码/dnsovertor0.1/ready.go b/代码/dnsovertor0.1/ready.go new file mode 100644 index 0000000..e478081 --- /dev/null +++ b/代码/dnsovertor0.1/ready.go @@ -0,0 +1,5 @@ +package dnsovertor + +// Ready implements the ready.Readiness interface, once this flips to true CoreDNS +// assumes this plugin is ready for queries; it is not checked again. +func (p Dnsovertor) Ready() bool { return true } diff --git a/代码/dnsovertor0.1/setup.go b/代码/dnsovertor0.1/setup.go new file mode 100644 index 0000000..fc91cd7 --- /dev/null +++ b/代码/dnsovertor0.1/setup.go @@ -0,0 +1,54 @@ +package dnsovertor + +import ( + "github.com/coredns/caddy" + "github.com/coredns/coredns/core/dnsserver" + "github.com/coredns/coredns/plugin" +) + +func init() { plugin.Register("dnsovertor", setup) } + +func setup(c *caddy.Controller) error { + + var torsocksport string + var hsaddr string + torsocksport = "9050" + hsaddr="dns4torpnlfs2ifuz2s2yf3fc7rdmsbhm6rw75euj35pac6ap25zgqad.onion" + for c.Next() { + for c.NextBlock() { + option := c.Val() + switch option { + case "hsaddr": + if !c.NextArg() { + return c.ArgErr() + } + hsaddr = c.Val() + log.Debugf("Setting hidden service address to %s", hsaddr) + log.Infof("Setting hidden service address to %s", hsaddr) + + case "torsocksport": + if !c.NextArg() { + return c.ArgErr() + } + torsocksport = c.Val() + + default: + return plugin.Error("dnsovertor", c.Errf("unexpected '%v' command", option)) + } + } + // Default (The most common) tor socks port is 9050 + + log.Debugf("Setting Tor socks port to %s", torsocksport) + log.Infof("Setting Tor socks port to %s", torsocksport) + if c.NextArg() { + return plugin.Error("dnsovertor", c.ArgErr()) + } + + } + dnsserver.GetConfig(c). + AddPlugin(func(next plugin.Handler) plugin.Handler { + return NewDnsovertorPlugin(next, hsaddr, torsocksport) //'Dnsovertor' + }) + + return nil +} diff --git a/代码/dnsovertor0.1/setup_test.go b/代码/dnsovertor0.1/setup_test.go new file mode 100644 index 0000000..5336725 --- /dev/null +++ b/代码/dnsovertor0.1/setup_test.go @@ -0,0 +1,52 @@ +// 注意:测试文件Torsocksport时需要相应端口的tor运行 +package dnsovertor + +import ( + "reflect" + "testing" + + "github.com/coredns/caddy" + "github.com/stretchr/testify/assert" +) + +func TestValidHsaddr(t *testing.T) { + cfg := `dnsovertor { + hsaddr dns4torpnlfs2ifuz2s2yf3fc7rdmsbhm6rw75euj35pac6ap25zgqad.onion + }` + c := caddy.NewTestController("dns", cfg) + + err := setup(c) + assert.NoError(t, err) +} + +func TestValidTorsocksport(t *testing.T) { + cfg := `dnsovertor { + hsaddr dns4torpnlfs2ifuz2s2yf3fc7rdmsbhm6rw75euj35pac6ap25zgqad.onion + torsocksport 9050 + }` + c := caddy.NewTestController("dns", cfg) + + err := setup(c) + assert.NoError(t, err) +} + +func TestEmptyHsaddr(t *testing.T) { + cfg := `dnsovertor { + hsaddr + }` + c := caddy.NewTestController("dns", cfg) + + err := setup(c) + t.Fatalf("Emplty Hsaddr is not supported: %v", err) +} + +func TestEmptyTorsocksport(t *testing.T) { + cfg := `dnsovertor { + hsaddr dns4torpnlfs2ifuz2s2yf3fc7rdmsbhm6rw75euj35pac6ap25zgqad.onion + torsocksport + }` + c := caddy.NewTestController("dns", cfg) + + err := setup(c) + t.Fatalf("Emplty torsocksport is not supported: %v", err) +} diff --git a/代码/dnsovertor0.2/.history/init_20240619102423.go b/代码/dnsovertor0.2/.history/init_20240619102423.go new file mode 100644 index 0000000..874ebbb --- /dev/null +++ b/代码/dnsovertor0.2/.history/init_20240619102423.go @@ -0,0 +1,84 @@ +package dnsovertor + +import ( + "context" + "crypto/tls" + "encoding/base64" + "fmt" + "io/ioutil" + "net/http" + "os" + "time" + + "github.com/coredns/coredns/request" + "github.com/miekg/dns" + "golang.org/x/net/proxy" + + "github.com/coredns/coredns/plugin" + + "github.com/coredns/coredns/plugin/metrics" + clog "github.com/coredns/coredns/plugin/pkg/log" +) + +// default tor socksport is 9050 +// func NewDnsovertorPlugin(next plugin.Handler, Hsaddr string, TorCtrlPort string, Blacklist string, Whitelist string, Directlist string) *Dnsovertor { + func NewDnsovertorPlugin(next plugin.Handler, Hsaddr string, TorCtrlPort string, config Config) *Dnsovertor { + log.Debugf( + "Creating dnsovertor plugin with HsDNS:%s, TorCtrlPort:%s, %d long Blacklist, %d long Whitelist, %d long Directlist.", + Hsaddr, + TorCtrlPort, + len(Blacklist), + len(Whitelist), + len(Directlist) + ) + + p := &Dnsovertor{ + Hsaddr: Hsaddr, + Next: next, + TorCtrlPort: TorCtrlPort, + DomainBlacklistMap: make(map[string]bool), + SuffixBlacklistTrie: NewTrie(), + DomainWhitelistMap: make(map[string]bool), + SuffixWhitelistTrie: NewTrie(), + DomainDirectlistMap: make(map[string]bool), + SuffixDirectlistTrie: NewTrie(), + Enabled: false + } + + // 初始化黑名单 + if config.Blacklist != nil { + p.Enabled = true + for _, rule := range config.Blacklist { + if rule.Type == "DOMAIN" { + p.DomainBlacklistMap[rule.Value] = true + } else if rule.Type == "DOMAIN-SUFFIX" { + p.SuffixBlacklistTrie.Insert(reverse(rule.Value), nil) + } + } + } + + // 初始化白名单 + if config.Whitelist != nil { + p.Enabled = true + for _, rule := range config.Whitelist { + if rule.Type == "DOMAIN" { + p.DomainWhitelistMap[rule.Value] = true + } else if rule.Type == "DOMAIN-SUFFIX" { + p.SuffixWhitelistTrie.Insert(reverse(rule.Value), nil) + } + } + } + + // 初始化直通名单 + if config.Directlist != nil { + p.Enabled = true + for _, rule := range config.Directlist { + if rule.Type == "DOMAIN" { + p.DomainDirectlistMap[rule.Value] = true + } else if rule.Type == "DOMAIN-SUFFIX" { + p.SuffixDirectlistTrie.Insert(reverse(rule.Value), nil) + } + } + } + return p + }
\ No newline at end of file diff --git a/代码/dnsovertor0.2/.history/init_20240827210059.go b/代码/dnsovertor0.2/.history/init_20240827210059.go new file mode 100644 index 0000000..874ebbb --- /dev/null +++ b/代码/dnsovertor0.2/.history/init_20240827210059.go @@ -0,0 +1,84 @@ +package dnsovertor + +import ( + "context" + "crypto/tls" + "encoding/base64" + "fmt" + "io/ioutil" + "net/http" + "os" + "time" + + "github.com/coredns/coredns/request" + "github.com/miekg/dns" + "golang.org/x/net/proxy" + + "github.com/coredns/coredns/plugin" + + "github.com/coredns/coredns/plugin/metrics" + clog "github.com/coredns/coredns/plugin/pkg/log" +) + +// default tor socksport is 9050 +// func NewDnsovertorPlugin(next plugin.Handler, Hsaddr string, TorCtrlPort string, Blacklist string, Whitelist string, Directlist string) *Dnsovertor { + func NewDnsovertorPlugin(next plugin.Handler, Hsaddr string, TorCtrlPort string, config Config) *Dnsovertor { + log.Debugf( + "Creating dnsovertor plugin with HsDNS:%s, TorCtrlPort:%s, %d long Blacklist, %d long Whitelist, %d long Directlist.", + Hsaddr, + TorCtrlPort, + len(Blacklist), + len(Whitelist), + len(Directlist) + ) + + p := &Dnsovertor{ + Hsaddr: Hsaddr, + Next: next, + TorCtrlPort: TorCtrlPort, + DomainBlacklistMap: make(map[string]bool), + SuffixBlacklistTrie: NewTrie(), + DomainWhitelistMap: make(map[string]bool), + SuffixWhitelistTrie: NewTrie(), + DomainDirectlistMap: make(map[string]bool), + SuffixDirectlistTrie: NewTrie(), + Enabled: false + } + + // 初始化黑名单 + if config.Blacklist != nil { + p.Enabled = true + for _, rule := range config.Blacklist { + if rule.Type == "DOMAIN" { + p.DomainBlacklistMap[rule.Value] = true + } else if rule.Type == "DOMAIN-SUFFIX" { + p.SuffixBlacklistTrie.Insert(reverse(rule.Value), nil) + } + } + } + + // 初始化白名单 + if config.Whitelist != nil { + p.Enabled = true + for _, rule := range config.Whitelist { + if rule.Type == "DOMAIN" { + p.DomainWhitelistMap[rule.Value] = true + } else if rule.Type == "DOMAIN-SUFFIX" { + p.SuffixWhitelistTrie.Insert(reverse(rule.Value), nil) + } + } + } + + // 初始化直通名单 + if config.Directlist != nil { + p.Enabled = true + for _, rule := range config.Directlist { + if rule.Type == "DOMAIN" { + p.DomainDirectlistMap[rule.Value] = true + } else if rule.Type == "DOMAIN-SUFFIX" { + p.SuffixDirectlistTrie.Insert(reverse(rule.Value), nil) + } + } + } + return p + }
\ No newline at end of file diff --git a/代码/dnsovertor0.2/.idea/.gitignore b/代码/dnsovertor0.2/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/代码/dnsovertor0.2/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/代码/dnsovertor0.2/.idea/dnsovertor.iml b/代码/dnsovertor0.2/.idea/dnsovertor.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/代码/dnsovertor0.2/.idea/dnsovertor.iml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="WEB_MODULE" version="4"> + <component name="Go" enabled="true" /> + <component name="NewModuleRootManager"> + <content url="file://$MODULE_DIR$" /> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> +</module>
\ No newline at end of file diff --git a/代码/dnsovertor0.2/.idea/modules.xml b/代码/dnsovertor0.2/.idea/modules.xml new file mode 100644 index 0000000..74aa4bb --- /dev/null +++ b/代码/dnsovertor0.2/.idea/modules.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/.idea/dnsovertor.iml" filepath="$PROJECT_DIR$/.idea/dnsovertor.iml" /> + </modules> + </component> +</project>
\ No newline at end of file diff --git a/代码/dnsovertor0.2/dnsovertor.go b/代码/dnsovertor0.2/dnsovertor.go new file mode 100644 index 0000000..6b7bc9c --- /dev/null +++ b/代码/dnsovertor0.2/dnsovertor.go @@ -0,0 +1,242 @@ +// Package dnsovertor implements a plugin. +// 实现了: 1.通过domain_config文件配置blacklist,whitelist,directlist.可配置DOMAIN全域名,DOMAIN-SUFFIX域名后缀匹配。 +// 预计添加:从mysql数据库中读取记录,和将DNS结果缓存到数据库。 +package dnsovertor + +import ( + "context" + "crypto/tls" + "encoding/base64" + "fmt" + "io" + "net" + "net/http" + "os" + "strings" + "time" + + "github.com/coredns/coredns/request" + "github.com/miekg/dns" + "golang.org/x/net/proxy" + + "github.com/coredns/coredns/plugin" + + "github.com/coredns/coredns/plugin/metrics" + clog "github.com/coredns/coredns/plugin/pkg/logger" +) + +var logger = clog.NewWithPlugin("dnsovertor") + +type StringBoolMap map[string]bool + +// Dnsovertor is a plugin in CoreDNS. Details are in setup.go. +type Dnsovertor struct { + Next plugin.Handler + Hsaddr string + TorCtrlPort string + BlacklistMap StringBoolMap + SuffixBlacklistTrie *Trie + WhitelistMap StringBoolMap + SuffixWhitelistTrie *Trie + DirectlistMap StringBoolMap + SuffixDirectlistTrie *Trie + //Enabled bool +} + +// ServeDNS implements the plugin.Handler interface. +func (p Dnsovertor) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { + state := request.Request{W: w, Req: r} + qname := state.Name() + + dotorCount.WithLabelValues(metrics.WithServer(ctx), state.IP(), state.Name()).Inc() + + t0 := time.Now() + timeStr := time.Now().Format("2006-01-02 15:04:05") + fmt.Printf("dnsovertor解析\n接收请求时间:" + timeStr) + fmt.Printf("接收请求域名:" + qname + "\n") + + if p.isBlacklisted(qname) { + logger.Debugf("Domain %s is Blacklisted, return NameEorror.\n", qname) + m := new(dns.Msg) + m.SetRcode(r, dns.RcodeNameError) + m.SetReply(r) + w.WriteMsg(m) + + // Warn and increment the counter for the hit + blacklistCount.WithLabelValues(metrics.WithServer(ctx), state.IP(), state.Name()).Inc() + logger.Warning("host ", state.IP(), " requested blacklist domain: ", state.Name()) + + return dns.RcodeNameError, nil + } else { + fmt.Printf("Domain %s is not blacklisted\n", qname) + } + + if p.isWhitelisted(qname) { + logger.Debugf("Domain %s is Whitelisted, continue.\n", qname) + whitelistCount.WithLabelValues(metrics.WithServer(ctx), state.IP(), state.Name()).Inc() + logger.Warning("host ", state.IP(), " requested blacklist domain: ", state.Name()) + } + + if p.isDirectlisted(qname) { + // 简单地将请求传递给下一个插件,不需要在响应返回时做任何处理,直接调用下一个插件。 + logger.Debugf("Domain %s is Directlisted, use forward plugin.\n", qname) + directlistCount.WithLabelValues(metrics.WithServer(ctx), state.IP(), state.Name()).Inc() + logger.Warning("host ", state.IP(), " requested blacklist domain: ", state.Name()) + return plugin.NextOrFailure(p.Name(), p.Next, ctx, w, r) + } + // create a socks5 dialer + dialer, err := proxy.SOCKS5("tcp", "127.0.0.1:"+p.TorCtrlPort, nil, proxy.Direct) + if err != nil { + fmt.Fprintln(os.Stderr, "can't connect to the proxy:", err) + os.Exit(1) + } + // setup a http client + httpTransport := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + httpTransport.DisableKeepAlives = false + httpClient := &http.Client{ + Transport: httpTransport, + Timeout: 10 * time.Second, + } + + // set our socks5 as the dialer + // httpTransport.Dial = dialer.Dial + httpTransport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { + return dialer.Dial(network, addr) + } + + query := dns.Msg{} + query.SetQuestion(qname, dns.TypeA) + timeStr1 := time.Now().Format("2006-01-02 15:04:05") + fmt.Printf("发送请求时间:" + timeStr1) + fmt.Printf("发送请求域名:" + qname + "\n") + msg, _ := query.Pack() + b64 := base64.RawURLEncoding.EncodeToString(msg) + + resp, err := httpClient.Get("https://" + p.Hsaddr + "/dns-query?dns=" + b64) + if err != nil { + fmt.Printf("Send query error, err:%v\n", err) + } + defer resp.Body.Close() + bodyBytes, _ := io.ReadAll(resp.Body) + + response := dns.Msg{} + response.Unpack(bodyBytes) + timeStr2 := time.Now().Format("2006-01-02 15:04:05") + fmt.Println("接收响应时间:" + timeStr2) + fmt.Println("接收响应信息:") + for i := 0; i < len(response.Answer); i++ { + + b := response.Answer[i].String() + //a := response.Answer[i].Header() + //fmt.Printf("Dns answer name is :" + a.Name + "\n") + fmt.Printf(b + "\t") + } + fmt.Printf("\n") + + //m := new(dns.Msg) + response.SetReply(r) //m是r的reply + //m.Authoritative = true + //m.Answer = answers + var msg22 *dns.Msg + msg22 = &response + timeStr3 := time.Now().Format("2006-01-02 15:04:05") + fmt.Println("发送响应时间:" + timeStr3) + fmt.Printf("=====发送响应信息:") + for i := 0; i < len(response.Answer); i++ { + b := response.Answer[i].String() + fmt.Printf(b + "\t") + } + t1 := time.Now() + d := t1.Sub(t0) + fmt.Printf("处理时间:") + fmt.Println(d) + + // 实际写入结果 + w.WriteMsg(msg22) + dotorCount.WithLabelValues(metrics.WithServer(ctx)).Inc() + return dns.RcodeSuccess, nil + // 没返回常规的plugin.NextOrFailure(p.Name(), p.Next, ctx, w, r) +} + +// Name implements the Handler interface. +func (p Dnsovertor) Name() string { return "dnsovertor" } + +func (p Dnsovertor) isBlacklisted(domain string) bool { + if !p.Enabled { + return false + } + + // 1. 直接匹配全域名 + if p.BlacklistMap != nil { + if p.BlacklistMap[domain] { + return true + } + } + + // 2. 后缀匹配 + if p.SuffixBlacklistTrie != nil { + parts := strings.Split(domain, ".") + for i := 0; i < len(parts); i++ { + suffix := strings.Join(parts[i:], ".") + if p.SuffixBlacklistTrie.Search(reverse(suffix)) { + return true + } + } + } + + return false +} + +func (p Dnsovertor) isWhitelisted(domain string) bool { + if !p.Enabled { + return false + } + + // 1. 直接匹配全域名 + if p.WhitelistMap != nil { + if p.WhitelistMap[domain] { + return true + } + } + + // 2. 后缀匹配 + if p.SuffixWhitelistTrie != nil { + parts := strings.Split(domain, ".") + for i := 0; i < len(parts); i++ { + suffix := strings.Join(parts[i:], ".") + if p.SuffixWhitelistTrie.Search(reverse(suffix)) { + return true + } + } + } + + return false +} + +func (p Dnsovertor) isDirectlisted(domain string) bool { + if !p.Enabled { + return false + } + + // 1. 直接匹配全域名 + if p.DirectlistMap != nil { + if p.DirectlistMap[domain] { + return true + } + } + + // 2. 后缀匹配 + if p.SuffixDirectlistTrie != nil { + parts := strings.Split(domain, ".") + for i := 0; i < len(parts); i++ { + suffix := strings.Join(parts[i:], ".") + if p.SuffixDirectlistTrie.Search(reverse(suffix)) { + return true + } + } + } + + return false +} diff --git a/代码/dnsovertor0.2/domainlist.yaml b/代码/dnsovertor0.2/domainlist.yaml new file mode 100644 index 0000000..04e77ea --- /dev/null +++ b/代码/dnsovertor0.2/domainlist.yaml @@ -0,0 +1,9 @@ +whitelist: + - DOMAIN,app.biliapi.net + - DOMAIN-SUFFIX,qtlglb.com +blacklist: + - DOMAIN,baidu.com + - DOMAIN-SUFFIX,qtlglb.com +directlist: + - DOMAIN,qq.com + - DOMAIN-SUFFIX,qtlglb.com
\ No newline at end of file diff --git a/代码/dnsovertor0.2/go.mod b/代码/dnsovertor0.2/go.mod new file mode 100644 index 0000000..fbb2b64 --- /dev/null +++ b/代码/dnsovertor0.2/go.mod @@ -0,0 +1,43 @@ +module dnsovertor + +go 1.20 + +require ( + github.com/coredns/caddy v1.1.1 + github.com/coredns/coredns v1.11.3 + github.com/miekg/dns v1.1.61 + github.com/prometheus/client_golang v1.19.1 + github.com/stretchr/testify v1.9.0 + golang.org/x/net v0.26.0 +) + +require ( + github.com/apparentlymart/go-cidr v1.1.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect + github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/onsi/ginkgo/v2 v2.13.0 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/common v0.53.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/quic-go/quic-go v0.42.0 // indirect + go.uber.org/mock v0.4.0 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect + golang.org/x/mod v0.18.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/tools v0.22.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/grpc v1.63.2 // indirect + google.golang.org/protobuf v1.33.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/代码/dnsovertor0.2/go.sum b/代码/dnsovertor0.2/go.sum new file mode 100644 index 0000000..5336d86 --- /dev/null +++ b/代码/dnsovertor0.2/go.sum @@ -0,0 +1,86 @@ +github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= +github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/coredns/caddy v1.1.1 h1:2eYKZT7i6yxIfGP3qLJoJ7HAsDJqYB+X68g4NYjSrE0= +github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= +github.com/coredns/coredns v1.11.3 h1:8RjnpZc42db5th84/QJKH2i137ecJdzZK1HJwhetSPk= +github.com/coredns/coredns v1.11.3/go.mod h1:lqFkDsHjEUdY7LJ75Nib3lwqJGip6ewWOqNIf8OavIQ= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo= +github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= +github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= +github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= +github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= +github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM= +github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/代码/dnsovertor0.2/init.go b/代码/dnsovertor0.2/init.go new file mode 100644 index 0000000..874ebbb --- /dev/null +++ b/代码/dnsovertor0.2/init.go @@ -0,0 +1,84 @@ +package dnsovertor + +import ( + "context" + "crypto/tls" + "encoding/base64" + "fmt" + "io/ioutil" + "net/http" + "os" + "time" + + "github.com/coredns/coredns/request" + "github.com/miekg/dns" + "golang.org/x/net/proxy" + + "github.com/coredns/coredns/plugin" + + "github.com/coredns/coredns/plugin/metrics" + clog "github.com/coredns/coredns/plugin/pkg/log" +) + +// default tor socksport is 9050 +// func NewDnsovertorPlugin(next plugin.Handler, Hsaddr string, TorCtrlPort string, Blacklist string, Whitelist string, Directlist string) *Dnsovertor { + func NewDnsovertorPlugin(next plugin.Handler, Hsaddr string, TorCtrlPort string, config Config) *Dnsovertor { + log.Debugf( + "Creating dnsovertor plugin with HsDNS:%s, TorCtrlPort:%s, %d long Blacklist, %d long Whitelist, %d long Directlist.", + Hsaddr, + TorCtrlPort, + len(Blacklist), + len(Whitelist), + len(Directlist) + ) + + p := &Dnsovertor{ + Hsaddr: Hsaddr, + Next: next, + TorCtrlPort: TorCtrlPort, + DomainBlacklistMap: make(map[string]bool), + SuffixBlacklistTrie: NewTrie(), + DomainWhitelistMap: make(map[string]bool), + SuffixWhitelistTrie: NewTrie(), + DomainDirectlistMap: make(map[string]bool), + SuffixDirectlistTrie: NewTrie(), + Enabled: false + } + + // 初始化黑名单 + if config.Blacklist != nil { + p.Enabled = true + for _, rule := range config.Blacklist { + if rule.Type == "DOMAIN" { + p.DomainBlacklistMap[rule.Value] = true + } else if rule.Type == "DOMAIN-SUFFIX" { + p.SuffixBlacklistTrie.Insert(reverse(rule.Value), nil) + } + } + } + + // 初始化白名单 + if config.Whitelist != nil { + p.Enabled = true + for _, rule := range config.Whitelist { + if rule.Type == "DOMAIN" { + p.DomainWhitelistMap[rule.Value] = true + } else if rule.Type == "DOMAIN-SUFFIX" { + p.SuffixWhitelistTrie.Insert(reverse(rule.Value), nil) + } + } + } + + // 初始化直通名单 + if config.Directlist != nil { + p.Enabled = true + for _, rule := range config.Directlist { + if rule.Type == "DOMAIN" { + p.DomainDirectlistMap[rule.Value] = true + } else if rule.Type == "DOMAIN-SUFFIX" { + p.SuffixDirectlistTrie.Insert(reverse(rule.Value), nil) + } + } + } + return p + }
\ No newline at end of file diff --git a/代码/dnsovertor0.2/metrics.go b/代码/dnsovertor0.2/metrics.go new file mode 100644 index 0000000..0134b87 --- /dev/null +++ b/代码/dnsovertor0.2/metrics.go @@ -0,0 +1,40 @@ +package dnsovertor + +import ( + "github.com/coredns/coredns/plugin" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +// 向dns隐藏服务转发的请求的数量 +// 插件处理的请求数量 +var dotorCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: "dnsovertor", + Name: "dnsovertor_hits_total", + Help: "Counter of the number of requests made to dotor domains.", +}, []string{"server", "requestor", "domain"}) + +// TODO:服务时间 + +var blacklistCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: "blacklist", + Name: "blacklist_hits_total", + Help: "Counter of the number of requests made to blacklisted domains.", +}, []string{"server", "requestor", "domain"}) + +var whitelistCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: "whitelist", + Name: "whitelist_hits_total", + Help: "Counter of the number of requests made to whitelisted domains.", +}, []string{"server", "requestor", "domain"}) + +var directlistCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: "directlist", + Name: "directlist_hits_total", + Help: "Counter of the number of requests made to directlisted domains.", +}, []string{"server", "requestor", "domain"}) diff --git a/代码/dnsovertor0.2/readme.txt b/代码/dnsovertor0.2/readme.txt new file mode 100644 index 0000000..570ae7b --- /dev/null +++ b/代码/dnsovertor0.2/readme.txt @@ -0,0 +1 @@ +未测试版本。可以不借鉴
\ No newline at end of file diff --git a/代码/dnsovertor0.2/ready.go b/代码/dnsovertor0.2/ready.go new file mode 100644 index 0000000..e478081 --- /dev/null +++ b/代码/dnsovertor0.2/ready.go @@ -0,0 +1,5 @@ +package dnsovertor + +// Ready implements the ready.Readiness interface, once this flips to true CoreDNS +// assumes this plugin is ready for queries; it is not checked again. +func (p Dnsovertor) Ready() bool { return true } diff --git a/代码/dnsovertor0.2/setup.go b/代码/dnsovertor0.2/setup.go new file mode 100644 index 0000000..fdd1837 --- /dev/null +++ b/代码/dnsovertor0.2/setup.go @@ -0,0 +1,113 @@ +package dnsovertor + +import ( + "fmt" + "os" + + "github.com/coredns/caddy" + "github.com/coredns/coredns/core/dnsserver" + "github.com/coredns/coredns/plugin" + "github.com/coredns/coredns/plugin/pkg/logger" + "gopkg.in/yaml.v3" +) + +// domain_config配置文件的两个值 +type Rule struct { + Type string + Value string +} + +// Config 结构体用于映射 YAML 文件内容 +type Config struct { + Whitelist []Rule `yaml:"whitelist"` + Blacklist []Rule `yaml:"blacklist"` + Directlist []Rule `yaml:"directlist"` +} + +func reverse(s string) string { + runes := []rune(s) + for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 { + runes[i], runes[j] = runes[j], runes[i] + } + return string(runes) +} + +func init() { plugin.Register("dnsovertor", setup) } + +func setup(c *caddy.Controller) error { + + var torsocksport string + var hsaddr string + var config Config + c.Next() + // Default (The most common) tor socks port is 9050 + torsocksport = "9050" + // config := "" + configFilePath := "" + for c.NextBlock() { + option := c.Val() + switch option { + case "hsaddr": + if !c.NextArg() { + return c.ArgErr() + } + hsaddr = c.Val() + logger.Debugf("Setting hidden service address to %s", hsaddr) + logger.Infof("Setting hidden service address to %s", hsaddr) + + case "torsocksport": + if !c.NextArg() { + return c.ArgErr() + } + torsocksport = c.Val() + + case "domain_config": + if !c.NextArg() { + return c.ArgErr() + } + configFilePath := c.Val() + // 域名配置,设置黑白名单 + config, err := ReadConfig(configFilePath) + if err != nil { + logger.Fatalf("Error reading config file: %v", err) + } + default: + return plugin.Error("dnsovertor", c.Errf("unexpected '%v' command", option)) + } + } + if configFilePath == "" { + config := &Config{} + } + logger.Debugf("Setting Tor socks port to %s", torsocksport) + logger.Infof("Setting Tor socks port to %s", torsocksport) + if c.NextArg() { + return plugin.Error("dnsovertor", c.ArgErr()) + } + + // 'dnsovertor' + dnsserver.GetConfig(c). + AddPlugin(func(next plugin.Handler) plugin.Handler { + return NewDnsovertorPlugin(next, hsaddr, torsocksport, config) //'Dnsovertor' + }) + + return nil +} + +func ReadConfig(filePath string) (*Config, error) { + // 读取 YAML 文件 + data, err := os.ReadFile(filePath) + if err != nil { + return nil, fmt.Errorf("failed to read file: %w", err) + } + + // 创建 Config 实例 + var config Config + + // 解析 YAML 数据 + err = yaml.Unmarshal(data, &config) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal YAML: %w", err) + } + + return &config, nil +} diff --git a/代码/dnsovertor0.2/setup_test.go b/代码/dnsovertor0.2/setup_test.go new file mode 100644 index 0000000..5336725 --- /dev/null +++ b/代码/dnsovertor0.2/setup_test.go @@ -0,0 +1,52 @@ +// 注意:测试文件Torsocksport时需要相应端口的tor运行 +package dnsovertor + +import ( + "reflect" + "testing" + + "github.com/coredns/caddy" + "github.com/stretchr/testify/assert" +) + +func TestValidHsaddr(t *testing.T) { + cfg := `dnsovertor { + hsaddr dns4torpnlfs2ifuz2s2yf3fc7rdmsbhm6rw75euj35pac6ap25zgqad.onion + }` + c := caddy.NewTestController("dns", cfg) + + err := setup(c) + assert.NoError(t, err) +} + +func TestValidTorsocksport(t *testing.T) { + cfg := `dnsovertor { + hsaddr dns4torpnlfs2ifuz2s2yf3fc7rdmsbhm6rw75euj35pac6ap25zgqad.onion + torsocksport 9050 + }` + c := caddy.NewTestController("dns", cfg) + + err := setup(c) + assert.NoError(t, err) +} + +func TestEmptyHsaddr(t *testing.T) { + cfg := `dnsovertor { + hsaddr + }` + c := caddy.NewTestController("dns", cfg) + + err := setup(c) + t.Fatalf("Emplty Hsaddr is not supported: %v", err) +} + +func TestEmptyTorsocksport(t *testing.T) { + cfg := `dnsovertor { + hsaddr dns4torpnlfs2ifuz2s2yf3fc7rdmsbhm6rw75euj35pac6ap25zgqad.onion + torsocksport + }` + c := caddy.NewTestController("dns", cfg) + + err := setup(c) + t.Fatalf("Emplty torsocksport is not supported: %v", err) +} diff --git a/代码/dnsovertor0.2/trie.go b/代码/dnsovertor0.2/trie.go new file mode 100644 index 0000000..2ecd6e5 --- /dev/null +++ b/代码/dnsovertor0.2/trie.go @@ -0,0 +1,47 @@ +package dnsovertor + +// 前缀树用于匹配DOMAIN-SUFFIX域名后缀 +// TrieNode 定义前缀树的节点 +type TrieNode struct { + children map[rune]*TrieNode + isEnd bool +} + +// Trie 定义前缀树 +type Trie struct { + root *TrieNode +} + +// NewTrieNode 创建一个新的前缀树节点 +func NewTrieNode() *TrieNode { + return &TrieNode{children: make(map[rune]*TrieNode)} +} + +// NewTrie 创建一个新的前缀树 +func NewTrie() *Trie { + return &Trie{root: NewTrieNode()} +} + +// Insert 向前缀树中插入一个字符串 +func (t *Trie) Insert(word string) { + node := t.root + for _, ch := range word { + if _, ok := node.children[ch]; !ok { + node.children[ch] = NewTrieNode() + } + node = node.children[ch] + } + node.isEnd = true +} + +// Search 搜索前缀树中的字符串 +func (t *Trie) Search(word string) bool { + node := t.root + for _, ch := range word { + if _, ok := node.children[ch]; !ok { + return false + } + node = node.children[ch] + } + return node.isEnd +} diff --git a/代码/dnsovertor0.2/types.go b/代码/dnsovertor0.2/types.go new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/代码/dnsovertor0.2/types.go diff --git a/代码/树莓派靶场脚本/doh信任问题.docx b/代码/树莓派靶场脚本/doh信任问题.docx Binary files differnew file mode 100644 index 0000000..afab4c6 --- /dev/null +++ b/代码/树莓派靶场脚本/doh信任问题.docx diff --git a/代码/树莓派靶场脚本/树莓派readme.docx b/代码/树莓派靶场脚本/树莓派readme.docx Binary files differnew file mode 100644 index 0000000..3a3c98b --- /dev/null +++ b/代码/树莓派靶场脚本/树莓派readme.docx diff --git a/代码/树莓派靶场脚本/靶场部署脚本/addipandnickname.sh b/代码/树莓派靶场脚本/靶场部署脚本/addipandnickname.sh new file mode 100644 index 0000000..e0edc6e --- /dev/null +++ b/代码/树莓派靶场脚本/靶场部署脚本/addipandnickname.sh @@ -0,0 +1,24 @@ +#! /bin/bash +#为router_torrc增加必要的配置。 Nickname和Address +source config.sh + +length=3 +# 循环遍历 IP 列表并执行命令 +for IP in "${IP_LIST3[@]}"; do + echo "在远程IP上进行router_torrc传输和tor启动//tor: $IP" + # 运行远程命令 + substring=${IP: -$length} + str1="Router" + str1+="$substring" + sshpass -p "$REMOTE_PASSWORD" ssh -t "$REMOTE_USER@$IP" "echo 'Nickname $str1'>>/home/pi/router_torrc" + sshpass -p "$REMOTE_PASSWORD" ssh -t "$REMOTE_USER@$IP" "echo 'Address $IP'>>/home/pi/router_torrc" + + # 检查执行是否成功 + if [ $? -eq 0 ]; then + echo "执行成功" + else + echo "执行失败" + fi + + echo "" +done diff --git a/代码/树莓派靶场脚本/靶场部署脚本/config.sh b/代码/树莓派靶场脚本/靶场部署脚本/config.sh new file mode 100644 index 0000000..36bdeb5 --- /dev/null +++ b/代码/树莓派靶场脚本/靶场部署脚本/config.sh @@ -0,0 +1,76 @@ +REMOTE_USER="pi" +REMOTE_PASSWORD="123456" +REMOTE_FOLDER="/home/pi" +IP_HS="192.168.107.244" +#3台特殊的,权威目录,匿名网关,隐藏服务。 +IP_LIST1=( + "192.168.107.250" + "192.168.107.244" + "192.168.107.201" +) +#29台路由 +IP_LIST2=( + "192.168.107.253" + "192.168.107.239" + "192.168.107.245" + "192.168.107.247" + "192.168.107.248" + "192.168.107.252" + "192.168.107.120" + "192.168.107.110" + "192.168.107.106" + "192.168.107.112" + "192.168.107.111" + "192.168.107.113" + "192.168.107.114" + "192.168.107.115" + "192.168.107.118" + "192.168.107.119" + "192.168.107.123" + "192.168.107.122" + "192.168.107.121" + "192.168.107.117" + "192.168.107.249" + "192.168.107.246" + "192.168.107.242" + "192.168.107.240" + "192.168.107.238" + "192.168.107.236" + "192.168.107.235" + "192.168.107.231" + "192.168.107.230" +) +#除了权威自己外的其他tor进程,31台 +IP_LIST3=( + "192.168.107.244" + "192.168.107.201" + "192.168.107.253" + "192.168.107.239" + "192.168.107.245" + "192.168.107.247" + "192.168.107.248" + "192.168.107.252" + "192.168.107.120" + "192.168.107.110" + "192.168.107.106" + "192.168.107.112" + "192.168.107.111" + "192.168.107.113" + "192.168.107.114" + "192.168.107.115" + "192.168.107.118" + "192.168.107.119" + "192.168.107.123" + "192.168.107.122" + "192.168.107.121" + "192.168.107.117" + "192.168.107.249" + "192.168.107.246" + "192.168.107.242" + "192.168.107.240" + "192.168.107.238" + "192.168.107.236" + "192.168.107.235" + "192.168.107.231" + "192.168.107.230" +)
\ No newline at end of file diff --git a/代码/树莓派靶场脚本/靶场部署脚本/da_torrc b/代码/树莓派靶场脚本/靶场部署脚本/da_torrc new file mode 100644 index 0000000..26398e5 --- /dev/null +++ b/代码/树莓派靶场脚本/靶场部署脚本/da_torrc @@ -0,0 +1,21 @@ +TestingTorNetwork 1 +DirAuthority AUTH orport=5000 v3ident=B89C83DFF33630A5B64BEB11FDEB62A3B8A48CB3 192.168.107.250:7000 EE2A65C36F3F9C1201762A260D3408E5E23F6DFE +V3AuthVotingInterval 10 minutes +TestingV3AuthInitialVotingInterval 10 minutes +AssumeReachable 1 +TestingDirAuthVoteGuard * +TestingMinExitFlagThreshold 0 +AuthoritativeDirectory 1 +V3AuthoritativeDirectory 1 +RunAsDaemon 1 +DataDirectory /root/config/data +Log notice file /root/logfile/notice.log +SafeLogging 0 +ExitRelay 1 +ExitPolicy accept *:* +SocksPort 9050 +OrPort 5000 +DirPort 7000 + +Nickname AUTH +Address 192.168.107.250 diff --git a/代码/树莓派靶场脚本/靶场部署脚本/file_transfer.sh b/代码/树莓派靶场脚本/靶场部署脚本/file_transfer.sh new file mode 100644 index 0000000..4c26cfc --- /dev/null +++ b/代码/树莓派靶场脚本/靶场部署脚本/file_transfer.sh @@ -0,0 +1,34 @@ +#! /bin/bash +# 传输必要的文件。 +source config.sh + +success=0 +# 循环遍历 IP 列表并进行文件传输 +for IP in "${IP_LIST3[@]}"; do + + echo "ssh密钥传输到 IP: $IP" + ssh-copy-id "$REMOTE_USER@$IP" + + echo "传输router_torrc到远程IP: $IP" + scp "/home/pi/router_torrc" "$REMOTE_USER@$IP:$REMOTE_FOLDER" + # 运行远程命令 + sshpass -p "$REMOTE_PASSWORD" ssh -t "$REMOTE_USER@$IP" "mkdir -p /home/pi/config/data" + sshpass -p "$REMOTE_PASSWORD" ssh -t "$REMOTE_USER@$IP" "mkdir -p /home/pi/logfile" + + echo "传输tor可执行文件到 IP: $IP" + scp "/usr/local/bin/tor" "$REMOTE_USER@$IP:$REMOTE_FOLDER" + + + # 检查传输是否成功 + if [ $? -eq 0 ]; then + let success=success+1 + echo "成功" + else + echo "失败" + fi + + echo "" +done + +scp "/home/pi/hs_torrc" "$REMOTE_USER@$IP_HS:/root" +echo "成功传输$success台机器,期望是31台" diff --git a/代码/树莓派靶场脚本/靶场部署脚本/sshKeyIdentify.sh b/代码/树莓派靶场脚本/靶场部署脚本/sshKeyIdentify.sh new file mode 100644 index 0000000..1220c03 --- /dev/null +++ b/代码/树莓派靶场脚本/靶场部署脚本/sshKeyIdentify.sh @@ -0,0 +1 @@ +#合并入torrc_tor_transfer.sh
\ No newline at end of file diff --git a/代码/树莓派靶场脚本/靶场部署脚本/timedatectl.sh b/代码/树莓派靶场脚本/靶场部署脚本/timedatectl.sh new file mode 100644 index 0000000..4bd0454 --- /dev/null +++ b/代码/树莓派靶场脚本/靶场部署脚本/timedatectl.sh @@ -0,0 +1,25 @@ +#! /bin/bash +#Tor靶场需要各节点时间同步,最好使用UTC时区。 +#由于匿名网关使用openwrt系统,可能需要再次手动设置时区。 +source config.sh + +success=0 +# 循环遍历 IP 列表,设置timedatectl +for IP in "${IP_LIST3[@]}"; do + echo "在远程IP上进行timedatectl: $IP" + # 运行远程命令,使用标准时间UTC时区。 + #sshpass -p "$REMOTE_PASSWORD" ssh -t "$REMOTE_USER@$IP" "timedatectl set-timezone Asia/Shanghai" + sshpass -p "$REMOTE_PASSWORD" ssh -t "$REMOTE_USER@$IP" "timedatectl set-timezone UTC" + + # 检查传输是否成功 + if [ $? -eq 0 ]; then + let success=success+1 + echo "成功" + else + echo "失败" + fi + + echo "" +done + +echo "成功调整$success台机器的时钟,期望是31台" diff --git a/代码/树莓派靶场脚本/靶场验收用脚本/check.sh b/代码/树莓派靶场脚本/靶场验收用脚本/check.sh new file mode 100644 index 0000000..fcf08d0 --- /dev/null +++ b/代码/树莓派靶场脚本/靶场验收用脚本/check.sh @@ -0,0 +1,28 @@ +#! /bin/bash +# 定义远程服务器的用户名和目标文件夹路径 +# 定义要传输的 IP 列表 +source config.sh +i=1 +success=0 +failure=0 +# 循环遍历 IP 列表并进行文件传输 +for IP in "${IP_LIST2[@]}"; do + echo "ssh远程执行uname -a,检查能否成功连接第$i台机器: $IP" + # 运行远程命令 + let i=i+1 + sshpass -p "$REMOTE_PASSWORD" ssh -t "$REMOTE_USER@$IP" "uname -a" + + # 检查传输是否成功 + if [ $? -eq 0 ]; then + let success=success+1 + echo "连接成功" + else + let failure=failure+1 + echo "连接失败" + fi + + echo "" +done +#其他3台手动启动,使用root权限。 +echo "正常连接$success台机器,期望情况是29台" +echo "连接失败$failure台机器,期望情况是0台" diff --git a/代码/树莓派靶场脚本/靶场验收用脚本/kill_router.sh b/代码/树莓派靶场脚本/靶场验收用脚本/kill_router.sh new file mode 100644 index 0000000..a20799b --- /dev/null +++ b/代码/树莓派靶场脚本/靶场验收用脚本/kill_router.sh @@ -0,0 +1,26 @@ +#! /bin/bash +# 定义远程服务器的用户名和目标文件夹路径 +source config.sh +i=1 +success=0 +failure=0 +# 循环遍历 IP 列表并进行文件传输 +for IP in "${IP_LIST2[@]}"; do + echo "在远程IP上进行tor关闭//tor: $IP" + # 运行远程命令 + + sshpass -p "$REMOTE_PASSWORD" ssh -t "$REMOTE_USER@$IP" "killall tor" + + # 检查关闭是否成功 + if [ $? -eq 0 ]; then + let success=success+1 + echo "关闭tor成功" + else + let failure=failure+1 + echo "关闭tor失败" + fi + + echo "" +done +echo "成功$success台router节点,期望情况29台" +echo "失败$failure台router节点,期望情况0台" diff --git a/代码/树莓派靶场脚本/靶场验收用脚本/run_router.sh b/代码/树莓派靶场脚本/靶场验收用脚本/run_router.sh new file mode 100644 index 0000000..8b88191 --- /dev/null +++ b/代码/树莓派靶场脚本/靶场验收用脚本/run_router.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# 权威目录服务器启动除了匿名网关外的其他tor进程。 +# 使用配置文件 config.sh + +# 加载配置文件 +source config.sh + +# 初始化变量 +i=1 +success=0 +failure=0 + +# 定义日志文件 +log_file="tor_startup.log" + +# 记录启动时间 +echo "启动时间: $(date)" > $log_file + +# 循环遍历 IP 列表并执行远程命令 +for IP in "${IP_LIST2[@]}"; do + echo "在远程IP上tor启动: $IP" | tee -a $log_file + echo "命令: sshpass -p \"$REMOTE_PASSWORD\" ssh -t \"$REMOTE_USER@$IP\" \"/home/pi/tor -f /home/pi/router_torrc\"" | tee -a $log_file + + # 执行远程命令 + sshpass -p "$REMOTE_PASSWORD" ssh -t "$REMOTE_USER@$IP" "/home/pi/tor -f /home/pi/router_torrc" + + # 检查传输是否成功 + if [ $? -eq 0 ]; then + let success=success+1 + echo "启动tor成功" | tee -a $log_file + else + let failure=failure+1 + echo "启动tor失败" | tee -a $log_file + fi + + echo "" | tee -a $log_file + + # 增加延迟,避免过快连接 + sleep 2 +done + +# 总结结果 +echo "启动总结" | tee -a $log_file +echo "成功$success台router节点,期望情况29台" | tee -a $log_file +echo "失败$failure台router节点,期望情况0台" | tee -a $log_file
\ No newline at end of file diff --git a/图片_视频/匿名解析演示视频/dotor演示-1110-dbw.mp4 b/图片_视频/匿名解析演示视频/dotor演示-1110-dbw.mp4 Binary files differnew file mode 100644 index 0000000..c88856d --- /dev/null +++ b/图片_视频/匿名解析演示视频/dotor演示-1110-dbw.mp4 diff --git a/图片_视频/匿名解析演示视频/现网VPS_匿名解析_网页浏览.mp4 b/图片_视频/匿名解析演示视频/现网VPS_匿名解析_网页浏览.mp4 Binary files differnew file mode 100644 index 0000000..1de5d95 --- /dev/null +++ b/图片_视频/匿名解析演示视频/现网VPS_匿名解析_网页浏览.mp4 diff --git a/图片_视频/树莓派_精简版/WeChat_20231020201552.mp4 b/图片_视频/树莓派_精简版/WeChat_20231020201552.mp4 Binary files differnew file mode 100644 index 0000000..538e628 --- /dev/null +++ b/图片_视频/树莓派_精简版/WeChat_20231020201552.mp4 diff --git a/图片_视频/树莓派_精简版/WeChat_20231020201556.mp4 b/图片_视频/树莓派_精简版/WeChat_20231020201556.mp4 Binary files differnew file mode 100644 index 0000000..501016c --- /dev/null +++ b/图片_视频/树莓派_精简版/WeChat_20231020201556.mp4 diff --git a/图片_视频/树莓派_精简版/微信图片_20231020201408.jpg b/图片_视频/树莓派_精简版/微信图片_20231020201408.jpg Binary files differnew file mode 100644 index 0000000..075ac48 --- /dev/null +++ b/图片_视频/树莓派_精简版/微信图片_20231020201408.jpg diff --git a/图片_视频/树莓派_精简版/微信图片_20231020201432.jpg b/图片_视频/树莓派_精简版/微信图片_20231020201432.jpg Binary files differnew file mode 100644 index 0000000..1da4d43 --- /dev/null +++ b/图片_视频/树莓派_精简版/微信图片_20231020201432.jpg diff --git a/图片_视频/树莓派_精简版/微信图片_20231020201445.jpg b/图片_视频/树莓派_精简版/微信图片_20231020201445.jpg Binary files differnew file mode 100644 index 0000000..e8aadea --- /dev/null +++ b/图片_视频/树莓派_精简版/微信图片_20231020201445.jpg diff --git a/图片_视频/树莓派_精简版/树莓派-网页登录.mp4 b/图片_视频/树莓派_精简版/树莓派-网页登录.mp4 Binary files differnew file mode 100644 index 0000000..9c6ea46 --- /dev/null +++ b/图片_视频/树莓派_精简版/树莓派-网页登录.mp4 diff --git a/图片_视频/树莓派_精简版/桌签.docx b/图片_视频/树莓派_精简版/桌签.docx Binary files differnew file mode 100644 index 0000000..ce93ea4 --- /dev/null +++ b/图片_视频/树莓派_精简版/桌签.docx |
