Explorar el Código

Add whitelist support

tags/v2.1.3^2
9seconds hace 4 años
padre
commit
0ddaabb136
Se han modificado 6 ficheros con 84 adiciones y 19 borrados
  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 Ver fichero

174
 # How often do we need to update a blocklist set.
174
 # How often do we need to update a blocklist set.
175
 update-each = "24h"
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
 # statsd statistics integration.
198
 # statsd statistics integration.
178
 [stats.statsd]
199
 [stats.statsd]
179
 # enabled/disabled
200
 # enabled/disabled

+ 18
- 6
internal/cli/run_proxy.go Ver fichero

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
 		return ipblocklist.NewNoop(), nil
91
 		return ipblocklist.NewNoop(), nil
92
 	}
92
 	}
93
 
93
 
94
 	remoteURLs := []string{}
94
 	remoteURLs := []string{}
95
 	localFiles := []string{}
95
 	localFiles := []string{}
96
 
96
 
97
-	for _, v := range conf.Defense.Blocklist.URLs {
97
+	for _, v := range conf.URLs {
98
 		if v.IsRemote() {
98
 		if v.IsRemote() {
99
 			remoteURLs = append(remoteURLs, v.String())
99
 			remoteURLs = append(remoteURLs, v.String())
100
 		} else {
100
 		} else {
104
 
104
 
105
 	firehol, err := ipblocklist.NewFirehol(logger.Named("ipblockist"),
105
 	firehol, err := ipblocklist.NewFirehol(logger.Named("ipblockist"),
106
 		ntw,
106
 		ntw,
107
-		conf.Defense.Blocklist.DownloadConcurrency.Get(1),
107
+		conf.DownloadConcurrency.Get(1),
108
 		remoteURLs,
108
 		remoteURLs,
109
 		localFiles)
109
 		localFiles)
110
 	if err != nil {
110
 	if err != nil {
153
 	return events.NewNoopStream(), nil
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
 	logger := makeLogger(conf)
157
 	logger := makeLogger(conf)
158
 
158
 
159
 	logger.BindJSON("configuration", conf.String()).Debug("configuration")
159
 	logger.BindJSON("configuration", conf.String()).Debug("configuration")
163
 		return fmt.Errorf("cannot build network: %w", err)
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
 	if err != nil {
167
 	if err != nil {
168
 		return fmt.Errorf("cannot build ip blocklist: %w", err)
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
 	eventStream, err := makeEventStream(conf, logger)
182
 	eventStream, err := makeEventStream(conf, logger)
172
 	if err != nil {
183
 	if err != nil {
173
 		return fmt.Errorf("cannot build event stream: %w", err)
184
 		return fmt.Errorf("cannot build event stream: %w", err)
178
 		Network:         ntw,
189
 		Network:         ntw,
179
 		AntiReplayCache: makeAntiReplayCache(conf),
190
 		AntiReplayCache: makeAntiReplayCache(conf),
180
 		IPBlocklist:     blocklist,
191
 		IPBlocklist:     blocklist,
192
+		IPWhitelist:     whitelist,
181
 		EventStream:     eventStream,
193
 		EventStream:     eventStream,
182
 
194
 
183
 		Secret:             conf.Secret,
195
 		Secret:             conf.Secret,

+ 20
- 9
internal/config/config.go Ver fichero

8
 	"github.com/9seconds/mtg/v2/mtglib"
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
 type Config struct {
23
 type Config struct {
12
 	Debug                    TypeBool        `json:"debug"`
24
 	Debug                    TypeBool        `json:"debug"`
13
 	AllowFallbackOnUnknownDC TypeBool        `json:"allowFallbackOnUnknownDc"`
25
 	AllowFallbackOnUnknownDC TypeBool        `json:"allowFallbackOnUnknownDc"`
20
 	Concurrency              TypeConcurrency `json:"concurrency"`
32
 	Concurrency              TypeConcurrency `json:"concurrency"`
21
 	Defense                  struct {
33
 	Defense                  struct {
22
 		AntiReplay struct {
34
 		AntiReplay struct {
23
-			Enabled   TypeBool      `json:"enabled"`
35
+			Optional
36
+
24
 			MaxSize   TypeBytes     `json:"maxSize"`
37
 			MaxSize   TypeBytes     `json:"maxSize"`
25
 			ErrorRate TypeErrorRate `json:"errorRate"`
38
 			ErrorRate TypeErrorRate `json:"errorRate"`
26
 		} `json:"antiReplay"`
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
 	} `json:"defense"`
42
 	} `json:"defense"`
34
 	Network struct {
43
 	Network struct {
35
 		Timeout struct {
44
 		Timeout struct {
42
 	} `json:"network"`
51
 	} `json:"network"`
43
 	Stats struct {
52
 	Stats struct {
44
 		StatsD struct {
53
 		StatsD struct {
45
-			Enabled      TypeBool            `json:"enabled"`
54
+			Optional
55
+
46
 			Address      TypeHostPort        `json:"address"`
56
 			Address      TypeHostPort        `json:"address"`
47
 			MetricPrefix TypeMetricPrefix    `json:"metricPrefix"`
57
 			MetricPrefix TypeMetricPrefix    `json:"metricPrefix"`
48
 			TagFormat    TypeStatsdTagFormat `json:"tagFormat"`
58
 			TagFormat    TypeStatsdTagFormat `json:"tagFormat"`
49
 		} `json:"statsd"`
59
 		} `json:"statsd"`
50
 		Prometheus struct {
60
 		Prometheus struct {
51
-			Enabled      TypeBool         `json:"enabled"`
61
+			Optional
62
+
52
 			BindTo       TypeHostPort     `json:"bindTo"`
63
 			BindTo       TypeHostPort     `json:"bindTo"`
53
 			HTTPPath     TypeHTTPPath     `json:"httpPath"`
64
 			HTTPPath     TypeHTTPPath     `json:"httpPath"`
54
 			MetricPrefix TypeMetricPrefix `json:"metricPrefix"`
65
 			MetricPrefix TypeMetricPrefix `json:"metricPrefix"`

+ 6
- 0
internal/config/parse.go Ver fichero

30
 			URLs                []string `toml:"urls" json:"urls,omitempty"`
30
 			URLs                []string `toml:"urls" json:"urls,omitempty"`
31
 			UpdateEach          string   `toml:"update-each" json:"updateEach,omitempty"`
31
 			UpdateEach          string   `toml:"update-each" json:"updateEach,omitempty"`
32
 		} `toml:"blocklist" json:"blocklist,omitempty"`
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
 	} `toml:"defense" json:"defense,omitempty"`
39
 	} `toml:"defense" json:"defense,omitempty"`
34
 	Network struct {
40
 	Network struct {
35
 		Timeout struct {
41
 		Timeout struct {

+ 14
- 4
mtglib/proxy.go Ver fichero

33
 	secret          Secret
33
 	secret          Secret
34
 	network         Network
34
 	network         Network
35
 	antiReplayCache AntiReplayCache
35
 	antiReplayCache AntiReplayCache
36
-	ipBlocklist     IPBlocklist
36
+	blocklist       IPBlocklist
37
+	whitelist       IPBlocklist
37
 	eventStream     EventStream
38
 	eventStream     EventStream
38
 	logger          Logger
39
 	logger          Logger
39
 }
40
 }
91
 }
92
 }
92
 
93
 
93
 // Serve starts a proxy on a given listener.
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
 	p.streamWaitGroup.Add(1)
96
 	p.streamWaitGroup.Add(1)
96
 	defer p.streamWaitGroup.Done()
97
 	defer p.streamWaitGroup.Done()
97
 
98
 
109
 		ipAddr := conn.RemoteAddr().(*net.TCPAddr).IP
110
 		ipAddr := conn.RemoteAddr().(*net.TCPAddr).IP
110
 		logger := p.logger.BindStr("ip", ipAddr.String())
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
 			conn.Close()
122
 			conn.Close()
114
 			logger.Info("ip was blacklisted")
123
 			logger.Info("ip was blacklisted")
115
 			p.eventStream.Send(p.ctx, NewEventIPBlocklisted(ipAddr))
124
 			p.eventStream.Send(p.ctx, NewEventIPBlocklisted(ipAddr))
291
 		secret:                   opts.Secret,
300
 		secret:                   opts.Secret,
292
 		network:                  opts.Network,
301
 		network:                  opts.Network,
293
 		antiReplayCache:          opts.AntiReplayCache,
302
 		antiReplayCache:          opts.AntiReplayCache,
294
-		ipBlocklist:              opts.IPBlocklist,
303
+		blocklist:                opts.IPBlocklist,
304
+		whitelist:                opts.IPWhitelist,
295
 		eventStream:              opts.EventStream,
305
 		eventStream:              opts.EventStream,
296
 		logger:                   opts.getLogger("proxy"),
306
 		logger:                   opts.getLogger("proxy"),
297
 		domainFrontingPort:       opts.getDomainFrontingPort(),
307
 		domainFrontingPort:       opts.getDomainFrontingPort(),

+ 5
- 0
mtglib/proxy_opts.go Ver fichero

28
 	// This is a mandatory setting.
28
 	// This is a mandatory setting.
29
 	IPBlocklist IPBlocklist
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
 	// EventStream defines an instance of event stream.
36
 	// EventStream defines an instance of event stream.
32
 	//
37
 	//
33
 	// This ia a mandatory setting.
38
 	// This ia a mandatory setting.

Loading…
Cancelar
Guardar