Skip to content

Commit b067b4e

Browse files
committed
update
1 parent 09721e0 commit b067b4e

27 files changed

+2582
-25
lines changed

Corefile

+9-20
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,14 @@
11
. {
2-
dnssrc locals.conf {
3-
expire 30s
4-
path_reload 3s
5-
max_fails 0
6-
health_check 30s
7-
to 114.114.114.114 223.5.5.5
8-
policy round_robin
9-
bootstrap 172.21.66.1
2+
datahub {
103
debug
4+
geoip_path data/geoip.dat
5+
geosite_path data/geosite.dat
6+
geoip_cache cn hk jp google apple
7+
geosite_cache cn hk jp private apple
8+
geodat_upgrade_url http://xxxx.com
9+
geodat_upgrade_cron 0 30 0 * * *
10+
keyword_table cn data/keyword_cn.txt
11+
reload @every 3s
1112
}
1213

13-
dnssrc 172.21.66.137 192.168.0.1/24 {
14-
expire 1s
15-
path_reload 3s
16-
max_fails 0
17-
health_check 30s
18-
to json-doh://dns.google/resolve
19-
to 1.1.1.1
20-
to 9.9.9.9
21-
policy round_robin
22-
bootstrap 172.21.66.1
23-
debug
24-
}
2514
}

data/keyword_cn.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cn:baidu

go.mod

+6-3
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@ module github.com/ca17/datahub
33
go 1.16
44

55
require (
6+
github.com/allegro/bigcache v1.2.1
67
github.com/c-robinson/iplib v1.0.3
8+
github.com/ca17/dnssrc v0.0.2
79
github.com/coredns/caddy v1.1.1
810
github.com/coredns/coredns v1.8.6
9-
github.com/m13253/dns-over-https/v2 v2.3.0
10-
github.com/mdlayher/netlink v1.4.2
11+
github.com/digineo/go-ipset/v2 v2.2.1 // indirect
12+
github.com/golang/protobuf v1.5.2
1113
github.com/miekg/dns v1.1.43
12-
github.com/prometheus/client_golang v1.11.0
14+
github.com/robfig/cron/v3 v3.0.1
15+
google.golang.org/protobuf v1.27.1
1316
)

go.sum

+992
Large diffs are not rendered by default.

main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package main
22

33
import (
4-
_ "github.com/ca17/dnssrc/plugin/dnssrc"
4+
_ "github.com/ca17/datahub/plugin/datahub"
55
"github.com/coredns/coredns/core/dnsserver"
66
_ "github.com/coredns/coredns/core/plugin"
77
"github.com/coredns/coredns/coremain"

plugin/datahub/dataapi.go

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package datahub
2+
3+
import (
4+
"net"
5+
"strings"
6+
7+
"github.com/c-robinson/iplib"
8+
"github.com/ca17/datahub/plugin/pkg/loader"
9+
"github.com/ca17/datahub/plugin/pkg/v2data"
10+
)
11+
12+
// LoadGeoIPFromDAT 载入 GEOIP 数据表
13+
func (dh *Datahub) LoadGeoIPFromDAT(tag string) (*v2data.GeoIP, error) {
14+
return loader.LoadGeoIPFromDAT(dh.geoipPath, tag)
15+
}
16+
17+
// LoadGeoSiteFromDAT 载入 GEOSITE 表
18+
func (dh *Datahub) LoadGeoSiteFromDAT(country string) (*v2data.GeoSite, error) {
19+
return loader.LoadGeoSiteFromDAT(dh.geositePath, country)
20+
}
21+
22+
func (dh *Datahub) MatchGeoip(tag string, ip net.IP) bool {
23+
tag = strings.ToUpper(tag)
24+
dh.nlmLock.RLock()
25+
defer dh.nlmLock.RUnlock()
26+
inet := iplib.NewNet(ip, 32)
27+
if list, ok := dh.geoipNetListMap[tag]; ok {
28+
return list.MatchNet(inet)
29+
}
30+
return false
31+
}
32+
33+
func (dh *Datahub) MatchGeoNet(tag string, net iplib.Net) bool {
34+
tag = strings.ToUpper(tag)
35+
dh.nlmLock.RLock()
36+
defer dh.nlmLock.RUnlock()
37+
if list, ok := dh.geoipNetListMap[tag]; ok {
38+
return list.MatchNet(net)
39+
}
40+
return false
41+
}
42+
43+
// MatchGeosite 匹配 Geosite 域名
44+
func (dh *Datahub) MatchGeosite(matchType, tag string, name string) bool {
45+
tag = strings.ToUpper(tag)
46+
dh.dlmLock.RLock()
47+
defer dh.dlmLock.RUnlock()
48+
if list, ok := dh.geositeDoaminListMap[tag]; ok {
49+
return list.Match(matchType, name)
50+
}
51+
return false
52+
}
53+
54+
func (dh *Datahub) MatchKeyword(tag string, name string) bool {
55+
tag = strings.ToUpper(tag)
56+
dh.ktLock.RLock()
57+
defer dh.ktLock.RUnlock()
58+
if list := dh.getKeywordTableByTag(tag); list!=nil {
59+
return list.Match(name)
60+
}
61+
return false
62+
}
63+
64+
// MixMatch 混合模式匹配域名
65+
func (dh *Datahub) MixMatch(tag string, name string) bool {
66+
tag = strings.ToUpper(tag)
67+
68+
if list := dh.getDomainListByTag(tag); list!=nil {
69+
if list.MixMatch(name) {
70+
return true
71+
}
72+
}
73+
74+
if list := dh.getKeywordTableByTag(tag); list!=nil {
75+
if list.Match(name) {
76+
return true
77+
}
78+
}
79+
80+
return false
81+
}

plugin/datahub/datahub.go

+174
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
package datahub
2+
3+
import (
4+
"context"
5+
"strings"
6+
"sync"
7+
"time"
8+
9+
"github.com/allegro/bigcache"
10+
"github.com/c-robinson/iplib"
11+
"github.com/ca17/datahub/plugin/pkg/datatable"
12+
"github.com/ca17/datahub/plugin/pkg/loader"
13+
"github.com/ca17/datahub/plugin/pkg/netutils"
14+
"github.com/ca17/datahub/plugin/pkg/v2data"
15+
"github.com/coredns/coredns/plugin"
16+
"github.com/miekg/dns"
17+
"github.com/robfig/cron/v3"
18+
)
19+
20+
var cronParser = cron.NewParser(
21+
cron.SecondOptional | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor,
22+
)
23+
24+
type Datahub struct {
25+
nlmLock sync.RWMutex
26+
dlmLock sync.RWMutex
27+
ktLock sync.RWMutex
28+
Next plugin.Handler
29+
geoipCacheTags []string
30+
geositeCacheTags []string
31+
geoipNetListMap map[string]*netutils.NetList
32+
geositeDoaminListMap map[string]*netutils.DomainList
33+
keywordTableMap map[string]*datatable.DataTable
34+
geoipPath string
35+
geositePath string
36+
geodatUpgradeUrl string
37+
geodatUpgradeCron string
38+
sched *cron.Cron
39+
matchCache *bigcache.BigCache
40+
reloadCron string
41+
debug bool
42+
}
43+
44+
func (dh *Datahub) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
45+
return plugin.NextOrFailure(dh.Name(), dh.Next, ctx, w, r)
46+
}
47+
48+
func (dh *Datahub) Name() string { return "datahub" }
49+
50+
func NewDatahub() *Datahub {
51+
mc, _ := bigcache.NewBigCache(bigcache.DefaultConfig(time.Second * 3600))
52+
return &Datahub{
53+
nlmLock: sync.RWMutex{},
54+
dlmLock: sync.RWMutex{},
55+
geoipNetListMap: make(map[string]*netutils.NetList),
56+
geositeDoaminListMap: make(map[string]*netutils.DomainList),
57+
keywordTableMap: make(map[string]*datatable.DataTable),
58+
matchCache: mc,
59+
sched: cron.New(cron.WithParser(cronParser)),
60+
}
61+
}
62+
63+
func (dh *Datahub) getDomainListByTag(tag string) *netutils.DomainList{
64+
dh.dlmLock.RLock()
65+
defer dh.dlmLock.RUnlock()
66+
return dh.geositeDoaminListMap[tag]
67+
}
68+
69+
func (dh *Datahub) getNetListByTag(tag string) *netutils.NetList{
70+
dh.nlmLock.RLock()
71+
defer dh.nlmLock.RUnlock()
72+
return dh.geoipNetListMap[tag]
73+
}
74+
75+
func (dh *Datahub) getKeywordTableByTag(tag string) *datatable.DataTable{
76+
dh.ktLock.RLock()
77+
defer dh.ktLock.RUnlock()
78+
return dh.keywordTableMap[tag]
79+
}
80+
81+
// 根据 tag 从 geoip.dat 加载 geoip 数据
82+
func (dh *Datahub) reloadGeoipNetListByTag(tags []string, cache bool) error {
83+
if !cache {
84+
loader.RemoveCache(dh.geoipPath)
85+
}
86+
tagitems, err := loader.LoadGeoIPFromDATByTags(dh.geoipPath, tags)
87+
if err != nil {
88+
return err
89+
}
90+
dh.nlmLock.Lock()
91+
defer dh.nlmLock.Unlock()
92+
for _, dataitems := range tagitems {
93+
var nets []iplib.Net
94+
for _, data := range dataitems.GetCidr() {
95+
_net := iplib.NewNet(data.GetIp(), int(data.GetPrefix()))
96+
nets = append(nets, _net)
97+
}
98+
99+
dh.geoipNetListMap[dataitems.GetCountryCode()] = netutils.NewNetList(nets)
100+
101+
}
102+
return nil
103+
}
104+
105+
// 根据 tag 从 geosite.dat 加载 geosite 数据
106+
func (dh *Datahub) reloadGeositeDmoainListByTag(tags []string, cache bool) error {
107+
if !cache {
108+
loader.RemoveCache(dh.geositePath)
109+
}
110+
tagitems, err := loader.LoadGeoSiteFromDATByTags(dh.geositePath, tags)
111+
if err != nil {
112+
return err
113+
}
114+
dh.dlmLock.Lock()
115+
defer dh.dlmLock.Unlock()
116+
for _, dataitems := range tagitems {
117+
var sites []string
118+
var regexs []string
119+
for _, data := range dataitems.GetDomain() {
120+
switch data.Type {
121+
case v2data.Domain_Full, v2data.Domain_Domain:
122+
sites = append(sites, data.GetValue())
123+
case v2data.Domain_Regex:
124+
regexs = append(regexs, data.GetValue())
125+
}
126+
}
127+
dmlist := netutils.NewDomainList()
128+
dmlist.InitDomainData(netutils.MatchFullType, sites)
129+
dmlist.InitDomainData(netutils.MatchRegexType, regexs)
130+
dh.geositeDoaminListMap[dataitems.GetCountryCode()] = dmlist
131+
}
132+
return nil
133+
}
134+
135+
func (dh *Datahub) parseKeywordTableByTag(tag string, from string) error {
136+
tag = strings.ToUpper(tag)
137+
table, err := datatable.NewFromArgs(datatable.DateTypeKeywordTable, tag, from )
138+
if err != nil {
139+
return err
140+
}
141+
table.LoadAll()
142+
dh.ktLock.Lock()
143+
defer dh.ktLock.Unlock()
144+
dh.keywordTableMap[tag] = table
145+
return nil
146+
}
147+
148+
func (dh *Datahub) OnStartup() error {
149+
dh.startSched()
150+
return nil
151+
}
152+
153+
func (dh *Datahub) OnShutdown() error {
154+
dh.stopSched()
155+
return nil
156+
}
157+
158+
func (dh *Datahub) debugPrint() {
159+
log.Info("geoip_path ", dh.geositePath)
160+
log.Info("geosite_path ", dh.geositePath)
161+
log.Info("geoip_cache ", dh.geoipCacheTags)
162+
log.Info("geosite_cache ", dh.geositeCacheTags)
163+
log.Info("geodat_upgrade_url ", dh.geodatUpgradeUrl)
164+
log.Info("geodat_upgrade_cron ", dh.geodatUpgradeCron)
165+
for k, v := range dh.geoipNetListMap {
166+
log.Infof("geoip_cache %s total %d", k, v.Len())
167+
}
168+
for k, v := range dh.geositeDoaminListMap {
169+
log.Infof("geosite_cache %s full_domain:%d regex_domain:%d", k, v.FullLen(), v.RegexLen())
170+
}
171+
for k, v := range dh.keywordTableMap {
172+
log.Infof("keyword_table %s total %d",k, v.Len())
173+
}
174+
}

0 commit comments

Comments
 (0)