浏览代码

Add whitelist support

tags/v2.1.3^2
9seconds 4 年前
父节点
当前提交
0ddaabb136
共有 6 个文件被更改,包括 84 次插入19 次删除
  1. 21
    0
      example.config.toml
  2. 18
    6
      internal/cli/run_proxy.go
  3. 20
    9
      internal/config/config.go
  4. 6
    0
      internal/config/parse.go
  5. 14
    4
      mtglib/proxy.go
  6. 5
    0
      mtglib/proxy_opts.go

+ 21
- 0
example.config.toml 查看文件

@@ -174,6 +174,27 @@ urls = [
174 174
 # How often do we need to update a blocklist set.
175 175
 update-each = "24h"
176 176
 
177
+# Allowlist is an opposite to a blocklist. Only those IPs that are coming from
178
+# subnets defined in these lists are allowed. All others will be rejected.
179
+#
180
+# If this feature is disabled, then there won't be any check performed by this
181
+# validator. It is possible to combine both blocklist and whitelist.
182
+[defense.allowlist]
183
+# You can enable/disable this feature.
184
+enabled = false
185
+# This is a limiter for concurrency. In order to protect website
186
+# from overloading, we download files in this number of threads.
187
+download-concurrency = 2
188
+# A list of URLs in FireHOL format (https://iplists.firehol.org/)
189
+# You can provider links here (starts with https:// or http://) or
190
+# path to a local file, but in this case it should be absolute.
191
+urls = [
192
+    # "https://iplists.firehol.org/files/firehol_level1.netset",
193
+    # "/local.file"
194
+
195
+]
196
+update-each = "24h"
197
+
177 198
 # statsd statistics integration.
178 199
 [stats.statsd]
179 200
 # enabled/disabled

+ 18
- 6
internal/cli/run_proxy.go 查看文件

@@ -86,15 +86,15 @@ func makeAntiReplayCache(conf *config.Config) mtglib.AntiReplayCache {
86 86
 	)
87 87
 }
88 88
 
89
-func makeIPBlocklist(conf *config.Config, logger mtglib.Logger, ntw mtglib.Network) (mtglib.IPBlocklist, error) {
90
-	if !conf.Defense.Blocklist.Enabled.Get(false) {
89
+func makeIPBlocklist(conf config.ListConfig, logger mtglib.Logger, ntw mtglib.Network) (mtglib.IPBlocklist, error) {
90
+	if !conf.Enabled.Get(false) {
91 91
 		return ipblocklist.NewNoop(), nil
92 92
 	}
93 93
 
94 94
 	remoteURLs := []string{}
95 95
 	localFiles := []string{}
96 96
 
97
-	for _, v := range conf.Defense.Blocklist.URLs {
97
+	for _, v := range conf.URLs {
98 98
 		if v.IsRemote() {
99 99
 			remoteURLs = append(remoteURLs, v.String())
100 100
 		} else {
@@ -104,7 +104,7 @@ func makeIPBlocklist(conf *config.Config, logger mtglib.Logger, ntw mtglib.Netwo
104 104
 
105 105
 	firehol, err := ipblocklist.NewFirehol(logger.Named("ipblockist"),
106 106
 		ntw,
107
-		conf.Defense.Blocklist.DownloadConcurrency.Get(1),
107
+		conf.DownloadConcurrency.Get(1),
108 108
 		remoteURLs,
109 109
 		localFiles)
110 110
 	if err != nil {
@@ -153,7 +153,7 @@ func makeEventStream(conf *config.Config, logger mtglib.Logger) (mtglib.EventStr
153 153
 	return events.NewNoopStream(), nil
154 154
 }
155 155
 
156
-func runProxy(conf *config.Config, version string) error {
156
+func runProxy(conf *config.Config, version string) error { // nolint: funlen
157 157
 	logger := makeLogger(conf)
158 158
 
159 159
 	logger.BindJSON("configuration", conf.String()).Debug("configuration")
@@ -163,11 +163,22 @@ func runProxy(conf *config.Config, version string) error {
163 163
 		return fmt.Errorf("cannot build network: %w", err)
164 164
 	}
165 165
 
166
-	blocklist, err := makeIPBlocklist(conf, logger, ntw)
166
+	blocklist, err := makeIPBlocklist(conf.Defense.Blocklist, logger, ntw)
167 167
 	if err != nil {
168 168
 		return fmt.Errorf("cannot build ip blocklist: %w", err)
169 169
 	}
170 170
 
171
+	var whitelist mtglib.IPBlocklist
172
+
173
+	if conf.Defense.Allowlist.Enabled.Get(false) {
174
+		whlist, err := makeIPBlocklist(conf.Defense.Allowlist, logger, ntw)
175
+		if err != nil {
176
+			return fmt.Errorf("cannot build ip blocklist: %w", err)
177
+		}
178
+
179
+		whitelist = whlist
180
+	}
181
+
171 182
 	eventStream, err := makeEventStream(conf, logger)
172 183
 	if err != nil {
173 184
 		return fmt.Errorf("cannot build event stream: %w", err)
@@ -178,6 +189,7 @@ func runProxy(conf *config.Config, version string) error {
178 189
 		Network:         ntw,
179 190
 		AntiReplayCache: makeAntiReplayCache(conf),
180 191
 		IPBlocklist:     blocklist,
192
+		IPWhitelist:     whitelist,
181 193
 		EventStream:     eventStream,
182 194
 
183 195
 		Secret:             conf.Secret,

+ 20
- 9
internal/config/config.go 查看文件

@@ -8,6 +8,18 @@ import (
8 8
 	"github.com/9seconds/mtg/v2/mtglib"
9 9
 )
10 10
 
11
+type Optional struct {
12
+	Enabled TypeBool `json:"enabled"`
13
+}
14
+
15
+type ListConfig struct {
16
+	Optional
17
+
18
+	DownloadConcurrency TypeConcurrency    `json:"downloadConcurrency"`
19
+	URLs                []TypeBlocklistURI `json:"urls"`
20
+	UpdateEach          TypeDuration       `json:"updateEach"`
21
+}
22
+
11 23
 type Config struct {
12 24
 	Debug                    TypeBool        `json:"debug"`
13 25
 	AllowFallbackOnUnknownDC TypeBool        `json:"allowFallbackOnUnknownDc"`
@@ -20,16 +32,13 @@ type Config struct {
20 32
 	Concurrency              TypeConcurrency `json:"concurrency"`
21 33
 	Defense                  struct {
22 34
 		AntiReplay struct {
23
-			Enabled   TypeBool      `json:"enabled"`
35
+			Optional
36
+
24 37
 			MaxSize   TypeBytes     `json:"maxSize"`
25 38
 			ErrorRate TypeErrorRate `json:"errorRate"`
26 39
 		} `json:"antiReplay"`
27
-		Blocklist struct {
28
-			Enabled             TypeBool           `json:"enabled"`
29
-			DownloadConcurrency TypeConcurrency    `json:"downloadConcurrency"`
30
-			URLs                []TypeBlocklistURI `json:"urls"`
31
-			UpdateEach          TypeDuration       `json:"updateEach"`
32
-		} `json:"blocklist"`
40
+		Blocklist ListConfig `json:"blocklist"`
41
+		Allowlist ListConfig `json:"allowlist"`
33 42
 	} `json:"defense"`
34 43
 	Network struct {
35 44
 		Timeout struct {
@@ -42,13 +51,15 @@ type Config struct {
42 51
 	} `json:"network"`
43 52
 	Stats struct {
44 53
 		StatsD struct {
45
-			Enabled      TypeBool            `json:"enabled"`
54
+			Optional
55
+
46 56
 			Address      TypeHostPort        `json:"address"`
47 57
 			MetricPrefix TypeMetricPrefix    `json:"metricPrefix"`
48 58
 			TagFormat    TypeStatsdTagFormat `json:"tagFormat"`
49 59
 		} `json:"statsd"`
50 60
 		Prometheus struct {
51
-			Enabled      TypeBool         `json:"enabled"`
61
+			Optional
62
+
52 63
 			BindTo       TypeHostPort     `json:"bindTo"`
53 64
 			HTTPPath     TypeHTTPPath     `json:"httpPath"`
54 65
 			MetricPrefix TypeMetricPrefix `json:"metricPrefix"`

+ 6
- 0
internal/config/parse.go 查看文件

@@ -30,6 +30,12 @@ type tomlConfig struct {
30 30
 			URLs                []string `toml:"urls" json:"urls,omitempty"`
31 31
 			UpdateEach          string   `toml:"update-each" json:"updateEach,omitempty"`
32 32
 		} `toml:"blocklist" json:"blocklist,omitempty"`
33
+		Allowlist struct {
34
+			Enabled             bool     `toml:"enabled" json:"enabled,omitempty"`
35
+			DownloadConcurrency uint     `toml:"download-concurrency" json:"downloadConcurrency,omitempty"`
36
+			URLs                []string `toml:"urls" json:"urls,omitempty"`
37
+			UpdateEach          string   `toml:"update-each" json:"updateEach,omitempty"`
38
+		} `toml:"allowlist" json:"allowlist,omitempty"`
33 39
 	} `toml:"defense" json:"defense,omitempty"`
34 40
 	Network struct {
35 41
 		Timeout struct {

+ 14
- 4
mtglib/proxy.go 查看文件

@@ -33,7 +33,8 @@ type Proxy struct {
33 33
 	secret          Secret
34 34
 	network         Network
35 35
 	antiReplayCache AntiReplayCache
36
-	ipBlocklist     IPBlocklist
36
+	blocklist       IPBlocklist
37
+	whitelist       IPBlocklist
37 38
 	eventStream     EventStream
38 39
 	logger          Logger
39 40
 }
@@ -91,7 +92,7 @@ func (p *Proxy) ServeConn(conn net.Conn) {
91 92
 }
92 93
 
93 94
 // Serve starts a proxy on a given listener.
94
-func (p *Proxy) Serve(listener net.Listener) error {
95
+func (p *Proxy) Serve(listener net.Listener) error { // nolint: cyclop
95 96
 	p.streamWaitGroup.Add(1)
96 97
 	defer p.streamWaitGroup.Done()
97 98
 
@@ -109,7 +110,15 @@ func (p *Proxy) Serve(listener net.Listener) error {
109 110
 		ipAddr := conn.RemoteAddr().(*net.TCPAddr).IP
110 111
 		logger := p.logger.BindStr("ip", ipAddr.String())
111 112
 
112
-		if p.ipBlocklist.Contains(ipAddr) {
113
+		if p.whitelist != nil && !p.whitelist.Contains(ipAddr) {
114
+			conn.Close()
115
+			logger.Info("ip was rejected by whitelist")
116
+			p.eventStream.Send(p.ctx, NewEventIPBlocklisted(ipAddr))
117
+
118
+			continue
119
+		}
120
+
121
+		if p.blocklist.Contains(ipAddr) {
113 122
 			conn.Close()
114 123
 			logger.Info("ip was blacklisted")
115 124
 			p.eventStream.Send(p.ctx, NewEventIPBlocklisted(ipAddr))
@@ -291,7 +300,8 @@ func NewProxy(opts ProxyOpts) (*Proxy, error) {
291 300
 		secret:                   opts.Secret,
292 301
 		network:                  opts.Network,
293 302
 		antiReplayCache:          opts.AntiReplayCache,
294
-		ipBlocklist:              opts.IPBlocklist,
303
+		blocklist:                opts.IPBlocklist,
304
+		whitelist:                opts.IPWhitelist,
295 305
 		eventStream:              opts.EventStream,
296 306
 		logger:                   opts.getLogger("proxy"),
297 307
 		domainFrontingPort:       opts.getDomainFrontingPort(),

+ 5
- 0
mtglib/proxy_opts.go 查看文件

@@ -28,6 +28,11 @@ type ProxyOpts struct {
28 28
 	// This is a mandatory setting.
29 29
 	IPBlocklist IPBlocklist
30 30
 
31
+	// IPWhitelist defines a whitelist of IPs to allow to use proxy.
32
+	//
33
+	// This is an optional setting, ignored by default (no restrictions).
34
+	IPWhitelist IPBlocklist
35
+
31 36
 	// EventStream defines an instance of event stream.
32 37
 	//
33 38
 	// This ia a mandatory setting.

正在加载...
取消
保存