Skip to content

Commit 44c8cc6

Browse files
committed
add mmdb support for rest ip match
1 parent 025823c commit 44c8cc6

File tree

6 files changed

+181
-0
lines changed

6 files changed

+181
-0
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ require (
4545
github.com/mdlayher/socket v0.5.1 // indirect
4646
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
4747
github.com/onsi/ginkgo/v2 v2.20.0 // indirect
48+
github.com/oschwald/geoip2-golang v1.11.0 // indirect
49+
github.com/oschwald/maxminddb-golang v1.13.1 // indirect
4850
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
4951
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
5052
github.com/prometheus/client_model v0.6.1 // indirect

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw
5858
github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
5959
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
6060
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
61+
github.com/oschwald/geoip2-golang v1.11.0 h1:hNENhCn1Uyzhf9PTmquXENiWS6AlxAEnBII6r8krA3w=
62+
github.com/oschwald/geoip2-golang v1.11.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo=
63+
github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE=
64+
github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8=
6165
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
6266
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
6367
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=

plugin/data_provider/iface.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ package data_provider
2222
import (
2323
"github.com/IrineSistiana/mosdns/v5/pkg/matcher/domain"
2424
"github.com/IrineSistiana/mosdns/v5/pkg/matcher/netlist"
25+
"github.com/oschwald/geoip2-golang"
2526
)
2627

2728
type DomainMatcherProvider interface {
@@ -31,3 +32,7 @@ type DomainMatcherProvider interface {
3132
type IPMatcherProvider interface {
3233
GetIPMatcher() netlist.Matcher
3334
}
35+
36+
type MmdbMatcherProvider interface {
37+
GetMmdbMatcher() *geoip2.Reader
38+
}

plugin/data_provider/mmdb/mmdb.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright (C) 2020-2022, IrineSistiana
3+
*
4+
* This file is part of mosdns.
5+
*
6+
* mosdns is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* mosdns is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
package mmdb
21+
22+
import (
23+
"github.com/IrineSistiana/mosdns/v5/coremain"
24+
"github.com/IrineSistiana/mosdns/v5/plugin/data_provider"
25+
"github.com/oschwald/geoip2-golang"
26+
)
27+
28+
const PluginType = "mmdb"
29+
30+
func init() {
31+
coremain.RegNewPluginFunc(PluginType, Init, func() any { return new(Args) })
32+
}
33+
34+
func Init(bp *coremain.BP, args any) (any, error) {
35+
return NewMmdb(bp, args.(*Args))
36+
}
37+
38+
type Args struct {
39+
File string `yaml:"file"`
40+
}
41+
42+
var _ data_provider.MmdbMatcherProvider = (*Mmdb)(nil)
43+
44+
type Mmdb struct {
45+
mmdb *geoip2.Reader
46+
}
47+
48+
func (m *Mmdb) GetMmdbMatcher() *geoip2.Reader {
49+
return m.mmdb
50+
}
51+
52+
func NewMmdb(bp *coremain.BP, args *Args) (*Mmdb, error) {
53+
m := &Mmdb{}
54+
55+
db, err := geoip2.Open(args.File)
56+
if err == nil {
57+
m.mmdb = db
58+
}
59+
60+
return m, nil
61+
}

plugin/enabled_plugins.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
// data provider
2525
_ "github.com/IrineSistiana/mosdns/v5/plugin/data_provider/domain_set"
2626
_ "github.com/IrineSistiana/mosdns/v5/plugin/data_provider/ip_set"
27+
_ "github.com/IrineSistiana/mosdns/v5/plugin/data_provider/mmdb"
2728

2829
// matcher
2930
_ "github.com/IrineSistiana/mosdns/v5/plugin/matcher/client_ip"
@@ -38,6 +39,7 @@ import (
3839
_ "github.com/IrineSistiana/mosdns/v5/plugin/matcher/random"
3940
_ "github.com/IrineSistiana/mosdns/v5/plugin/matcher/rcode"
4041
_ "github.com/IrineSistiana/mosdns/v5/plugin/matcher/resp_ip"
42+
_ "github.com/IrineSistiana/mosdns/v5/plugin/matcher/resp_ip_mmdb"
4143
_ "github.com/IrineSistiana/mosdns/v5/plugin/matcher/string_exp"
4244

4345
// executable
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright (C) 2020-2022, IrineSistiana
3+
*
4+
* This file is part of mosdns.
5+
*
6+
* mosdns is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* mosdns is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
package resp_ip_mmdb
21+
22+
import (
23+
"context"
24+
"errors"
25+
"fmt"
26+
"github.com/IrineSistiana/mosdns/v5/pkg/query_context"
27+
"github.com/IrineSistiana/mosdns/v5/plugin/data_provider"
28+
"github.com/IrineSistiana/mosdns/v5/plugin/executable/sequence"
29+
"github.com/miekg/dns"
30+
"github.com/oschwald/geoip2-golang"
31+
"net"
32+
"strings"
33+
)
34+
35+
const PluginType = "resp_ip_mmdb"
36+
37+
func init() {
38+
sequence.MustRegMatchQuickSetup(PluginType, QuickSetup)
39+
}
40+
41+
func QuickSetup(bq sequence.BQ, s string) (sequence.Matcher, error) {
42+
if len(s) == 0 {
43+
return nil, errors.New("a iso code probability is required")
44+
}
45+
46+
args := strings.Fields(s)
47+
if len(args) != 2 {
48+
return nil, errors.New("probability error, must like: resp_ip_mmdb $plugin_name CN")
49+
}
50+
51+
mmdbName, _ := cutPrefix(args[0], "$")
52+
53+
p := bq.M().GetPlugin(mmdbName)
54+
provider, _ := p.(data_provider.MmdbMatcherProvider)
55+
if provider == nil {
56+
return nil, fmt.Errorf("cannot find mmdb %s", mmdbName)
57+
}
58+
m := provider.GetMmdbMatcher()
59+
60+
return &Matcher{args[1], m}, nil
61+
}
62+
63+
type Matcher struct {
64+
isoCode string
65+
mmdb *geoip2.Reader
66+
}
67+
68+
func (m *Matcher) Match(_ context.Context, qCtx *query_context.Context) (bool, error) {
69+
r := qCtx.R()
70+
if r == nil {
71+
return false, nil
72+
}
73+
74+
if m.mmdb == nil {
75+
return false, nil
76+
}
77+
78+
for _, rr := range r.Answer {
79+
var ip net.IP
80+
switch rr := rr.(type) {
81+
case *dns.A:
82+
ip = rr.A
83+
case *dns.AAAA:
84+
ip = rr.AAAA
85+
default:
86+
continue
87+
}
88+
89+
record, err := m.mmdb.Country(ip)
90+
if err != nil {
91+
continue
92+
}
93+
94+
if record.Country.IsoCode == m.isoCode {
95+
return true, nil
96+
}
97+
}
98+
99+
return false, nil
100+
}
101+
102+
func cutPrefix(s string, p string) (string, bool) {
103+
if strings.HasPrefix(s, p) {
104+
return strings.TrimPrefix(s, p), true
105+
}
106+
return s, false
107+
}

0 commit comments

Comments
 (0)