Просмотр исходного кода

More elegant management of ip allowlists

tags/v2.1.6^2
9seconds 4 лет назад
Родитель
Сommit
a27facaa16
6 измененных файлов: 92 добавлений и 32 удалений
  1. 51
    19
      internal/cli/run_proxy.go
  2. 2
    2
      ipblocklist/files/mem.go
  3. 4
    0
      mtglib/init.go
  4. 6
    9
      mtglib/proxy.go
  5. 4
    2
      mtglib/proxy_opts.go
  6. 25
    0
      mtglib/proxy_test.go

+ 51
- 19
internal/cli/run_proxy.go Просмотреть файл

12
 	"github.com/9seconds/mtg/v2/internal/config"
12
 	"github.com/9seconds/mtg/v2/internal/config"
13
 	"github.com/9seconds/mtg/v2/internal/utils"
13
 	"github.com/9seconds/mtg/v2/internal/utils"
14
 	"github.com/9seconds/mtg/v2/ipblocklist"
14
 	"github.com/9seconds/mtg/v2/ipblocklist"
15
+	"github.com/9seconds/mtg/v2/ipblocklist/files"
15
 	"github.com/9seconds/mtg/v2/logger"
16
 	"github.com/9seconds/mtg/v2/logger"
16
 	"github.com/9seconds/mtg/v2/mtglib"
17
 	"github.com/9seconds/mtg/v2/mtglib"
17
 	"github.com/9seconds/mtg/v2/network"
18
 	"github.com/9seconds/mtg/v2/network"
18
 	"github.com/9seconds/mtg/v2/stats"
19
 	"github.com/9seconds/mtg/v2/stats"
19
 	"github.com/rs/zerolog"
20
 	"github.com/rs/zerolog"
21
+	"github.com/yl2chen/cidranger"
20
 )
22
 )
21
 
23
 
22
 func makeLogger(conf *config.Config) mtglib.Logger {
24
 func makeLogger(conf *config.Config) mtglib.Logger {
106
 		}
108
 		}
107
 	}
109
 	}
108
 
110
 
109
-	firehol, err := ipblocklist.NewFirehol(logger.Named("ipblockist"),
111
+	blocklist, err := ipblocklist.NewFirehol(logger.Named("ipblockist"),
110
 		ntw,
112
 		ntw,
111
 		conf.DownloadConcurrency.Get(1),
113
 		conf.DownloadConcurrency.Get(1),
112
 		remoteURLs,
114
 		remoteURLs,
116
 		return nil, fmt.Errorf("incorrect parameters for firehol: %w", err)
118
 		return nil, fmt.Errorf("incorrect parameters for firehol: %w", err)
117
 	}
119
 	}
118
 
120
 
119
-	go firehol.Run(conf.UpdateEach.Get(ipblocklist.DefaultFireholUpdateEach))
121
+	go blocklist.Run(conf.UpdateEach.Get(ipblocklist.DefaultFireholUpdateEach))
120
 
122
 
121
-	return firehol, nil
123
+	return blocklist, nil
124
+}
125
+
126
+func makeIPAllowlist(conf config.ListConfig,
127
+	logger mtglib.Logger,
128
+	ntw mtglib.Network,
129
+	updateCallback ipblocklist.FireholUpdateCallback,
130
+) (allowlist mtglib.IPBlocklist, err error) {
131
+	if !conf.Enabled.Get(false) {
132
+		allowlist, err = ipblocklist.NewFireholFromFiles(
133
+			logger.Named("ipblocklist"),
134
+			1,
135
+			[]files.File{
136
+				files.NewMem([]*net.IPNet{
137
+					cidranger.AllIPv4,
138
+					cidranger.AllIPv6,
139
+				}),
140
+			},
141
+			updateCallback,
142
+		)
143
+
144
+		go allowlist.Run(conf.UpdateEach.Get(ipblocklist.DefaultFireholUpdateEach))
145
+	} else {
146
+		allowlist, err = makeIPBlocklist(
147
+			conf,
148
+			logger,
149
+			ntw,
150
+			updateCallback,
151
+		)
152
+	}
153
+
154
+	if err != nil {
155
+		return nil, fmt.Errorf("cannot build allowlist: %w", err)
156
+	}
157
+
158
+	return allowlist, nil
122
 }
159
 }
123
 
160
 
124
 func makeEventStream(conf *config.Config, logger mtglib.Logger) (mtglib.EventStream, error) {
161
 func makeEventStream(conf *config.Config, logger mtglib.Logger) (mtglib.EventStream, error) {
186
 		return fmt.Errorf("cannot build ip blocklist: %w", err)
223
 		return fmt.Errorf("cannot build ip blocklist: %w", err)
187
 	}
224
 	}
188
 
225
 
189
-	var whitelist mtglib.IPBlocklist
190
-
191
-	if conf.Defense.Allowlist.Enabled.Get(false) {
192
-		whlist, err := makeIPBlocklist(
193
-			conf.Defense.Allowlist,
194
-			logger.Named("allowlist"),
195
-			ntw,
196
-			func(ctx context.Context, size int) {
197
-				eventStream.Send(ctx, mtglib.NewEventIPListSize(size, false))
198
-			})
199
-		if err != nil {
200
-			return fmt.Errorf("cannot build ip allowlist: %w", err)
201
-		}
202
-
203
-		whitelist = whlist
226
+	allowlist, err := makeIPAllowlist(
227
+		conf.Defense.Allowlist,
228
+		logger.Named("allowlist"),
229
+		ntw,
230
+		func(ctx context.Context, size int) {
231
+			eventStream.Send(ctx, mtglib.NewEventIPListSize(size, false))
232
+		},
233
+	)
234
+	if err != nil {
235
+		return fmt.Errorf("cannot build ip allowlist: %w", err)
204
 	}
236
 	}
205
 
237
 
206
 	opts := mtglib.ProxyOpts{
238
 	opts := mtglib.ProxyOpts{
208
 		Network:         ntw,
240
 		Network:         ntw,
209
 		AntiReplayCache: makeAntiReplayCache(conf),
241
 		AntiReplayCache: makeAntiReplayCache(conf),
210
 		IPBlocklist:     blocklist,
242
 		IPBlocklist:     blocklist,
211
-		IPWhitelist:     whitelist,
243
+		IPAllowlist:     allowlist,
212
 		EventStream:     eventStream,
244
 		EventStream:     eventStream,
213
 
245
 
214
 		Secret:             conf.Secret,
246
 		Secret:             conf.Secret,

+ 2
- 2
ipblocklist/files/mem.go Просмотреть файл

19
 	return "mem"
19
 	return "mem"
20
 }
20
 }
21
 
21
 
22
-func NewMem(networks []*net.IPNet) (File) {
22
+func NewMem(networks []*net.IPNet) File {
23
 	builder := strings.Builder{}
23
 	builder := strings.Builder{}
24
 
24
 
25
 	if len(networks) > 0 {
25
 	if len(networks) > 0 {
32
 	}
32
 	}
33
 
33
 
34
 	return memFile{
34
 	return memFile{
35
-		data:  builder.String(),
35
+		data: builder.String(),
36
 	}
36
 	}
37
 }
37
 }

+ 4
- 0
mtglib/init.go Просмотреть файл

48
 	// create a proxy but ip blocklist instance is not defined.
48
 	// create a proxy but ip blocklist instance is not defined.
49
 	ErrIPBlocklistIsNotDefined = errors.New("ip blocklist is not defined")
49
 	ErrIPBlocklistIsNotDefined = errors.New("ip blocklist is not defined")
50
 
50
 
51
+	// ErrIPAllowlistIsNotDefined is returned if you are trying to
52
+	// create a proxy but ip allowlist instance is not defined.
53
+	ErrIPAllowlistIsNotDefined = errors.New("ip allowlist is not defined")
54
+
51
 	// ErrEventStreamIsNotDefined is returned if you are trying to create a
55
 	// ErrEventStreamIsNotDefined is returned if you are trying to create a
52
 	// proxy but event stream instance is not defined.
56
 	// proxy but event stream instance is not defined.
53
 	ErrEventStreamIsNotDefined = errors.New("event stream is not defined")
57
 	ErrEventStreamIsNotDefined = errors.New("event stream is not defined")

+ 6
- 9
mtglib/proxy.go Просмотреть файл

34
 	network         Network
34
 	network         Network
35
 	antiReplayCache AntiReplayCache
35
 	antiReplayCache AntiReplayCache
36
 	blocklist       IPBlocklist
36
 	blocklist       IPBlocklist
37
-	whitelist       IPBlocklist
37
+	allowlist       IPBlocklist
38
 	eventStream     EventStream
38
 	eventStream     EventStream
39
 	logger          Logger
39
 	logger          Logger
40
 }
40
 }
91
 }
91
 }
92
 
92
 
93
 // Serve starts a proxy on a given listener.
93
 // Serve starts a proxy on a given listener.
94
-func (p *Proxy) Serve(listener net.Listener) error { // nolint: cyclop
94
+func (p *Proxy) Serve(listener net.Listener) error {
95
 	p.streamWaitGroup.Add(1)
95
 	p.streamWaitGroup.Add(1)
96
 	defer p.streamWaitGroup.Done()
96
 	defer p.streamWaitGroup.Done()
97
 
97
 
109
 		ipAddr := conn.RemoteAddr().(*net.TCPAddr).IP // nolint: forcetypeassert
109
 		ipAddr := conn.RemoteAddr().(*net.TCPAddr).IP // nolint: forcetypeassert
110
 		logger := p.logger.BindStr("ip", ipAddr.String())
110
 		logger := p.logger.BindStr("ip", ipAddr.String())
111
 
111
 
112
-		if p.whitelist != nil && !p.whitelist.Contains(ipAddr) {
112
+		if !p.allowlist.Contains(ipAddr) {
113
 			conn.Close()
113
 			conn.Close()
114
-			logger.Info("ip was rejected by whitelist")
114
+			logger.Info("ip was rejected by allowlist")
115
 			p.eventStream.Send(p.ctx, NewEventIPBlocklisted(ipAddr))
115
 			p.eventStream.Send(p.ctx, NewEventIPBlocklisted(ipAddr))
116
 
116
 
117
 			continue
117
 			continue
145
 	p.streamWaitGroup.Wait()
145
 	p.streamWaitGroup.Wait()
146
 	p.workerPool.Release()
146
 	p.workerPool.Release()
147
 
147
 
148
-	if p.whitelist != nil {
149
-		p.whitelist.Shutdown()
150
-	}
151
-
148
+	p.allowlist.Shutdown()
152
 	p.blocklist.Shutdown()
149
 	p.blocklist.Shutdown()
153
 }
150
 }
154
 
151
 
308
 		network:                  opts.Network,
305
 		network:                  opts.Network,
309
 		antiReplayCache:          opts.AntiReplayCache,
306
 		antiReplayCache:          opts.AntiReplayCache,
310
 		blocklist:                opts.IPBlocklist,
307
 		blocklist:                opts.IPBlocklist,
311
-		whitelist:                opts.IPWhitelist,
308
+		allowlist:                opts.IPAllowlist,
312
 		eventStream:              opts.EventStream,
309
 		eventStream:              opts.EventStream,
313
 		logger:                   opts.getLogger("proxy"),
310
 		logger:                   opts.getLogger("proxy"),
314
 		domainFrontingPort:       opts.getDomainFrontingPort(),
311
 		domainFrontingPort:       opts.getDomainFrontingPort(),

+ 4
- 2
mtglib/proxy_opts.go Просмотреть файл

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.
31
+	// IPAllowlist defines a whitelist of IPs to allow to use proxy.
32
 	//
32
 	//
33
 	// This is an optional setting, ignored by default (no restrictions).
33
 	// This is an optional setting, ignored by default (no restrictions).
34
-	IPWhitelist IPBlocklist
34
+	IPAllowlist IPBlocklist
35
 
35
 
36
 	// EventStream defines an instance of event stream.
36
 	// EventStream defines an instance of event stream.
37
 	//
37
 	//
125
 		return ErrAntiReplayCacheIsNotDefined
125
 		return ErrAntiReplayCacheIsNotDefined
126
 	case p.IPBlocklist == nil:
126
 	case p.IPBlocklist == nil:
127
 		return ErrIPBlocklistIsNotDefined
127
 		return ErrIPBlocklistIsNotDefined
128
+	case p.IPAllowlist == nil:
129
+		return ErrIPAllowlistIsNotDefined
128
 	case p.EventStream == nil:
130
 	case p.EventStream == nil:
129
 		return ErrEventStreamIsNotDefined
131
 		return ErrEventStreamIsNotDefined
130
 	case p.Logger == nil:
132
 	case p.Logger == nil:

+ 25
- 0
mtglib/proxy_test.go Просмотреть файл

15
 	"github.com/9seconds/mtg/v2/antireplay"
15
 	"github.com/9seconds/mtg/v2/antireplay"
16
 	"github.com/9seconds/mtg/v2/events"
16
 	"github.com/9seconds/mtg/v2/events"
17
 	"github.com/9seconds/mtg/v2/ipblocklist"
17
 	"github.com/9seconds/mtg/v2/ipblocklist"
18
+	"github.com/9seconds/mtg/v2/ipblocklist/files"
18
 	"github.com/9seconds/mtg/v2/logger"
19
 	"github.com/9seconds/mtg/v2/logger"
19
 	"github.com/9seconds/mtg/v2/mtglib"
20
 	"github.com/9seconds/mtg/v2/mtglib"
20
 	"github.com/9seconds/mtg/v2/network"
21
 	"github.com/9seconds/mtg/v2/network"
22
 	"github.com/gotd/td/telegram/dcs"
23
 	"github.com/gotd/td/telegram/dcs"
23
 	"github.com/gotd/td/tg"
24
 	"github.com/gotd/td/tg"
24
 	"github.com/stretchr/testify/suite"
25
 	"github.com/stretchr/testify/suite"
26
+	"github.com/yl2chen/cidranger"
25
 )
27
 )
26
 
28
 
27
 type ProxyTestSuite struct {
29
 type ProxyTestSuite struct {
49
 	ntw, err := network.NewNetwork(dialer, "mtgtest", "1.1.1.1", 0)
51
 	ntw, err := network.NewNetwork(dialer, "mtgtest", "1.1.1.1", 0)
50
 	suite.NoError(err)
52
 	suite.NoError(err)
51
 
53
 
54
+	allowlist, _ := ipblocklist.NewFireholFromFiles(
55
+		logger.NewNoopLogger(),
56
+		1,
57
+		[]files.File{
58
+			files.NewMem([]*net.IPNet{
59
+				cidranger.AllIPv4,
60
+				cidranger.AllIPv6,
61
+			}),
62
+		},
63
+		nil,
64
+	)
65
+
66
+	allowlist.Run(time.Second)
67
+
52
 	suite.opts = &mtglib.ProxyOpts{
68
 	suite.opts = &mtglib.ProxyOpts{
53
 		Secret:          mtglib.GenerateSecret("httpbin.org"),
69
 		Secret:          mtglib.GenerateSecret("httpbin.org"),
54
 		Network:         ntw,
70
 		Network:         ntw,
55
 		AntiReplayCache: antireplay.NewNoop(),
71
 		AntiReplayCache: antireplay.NewNoop(),
56
 		IPBlocklist:     ipblocklist.NewNoop(),
72
 		IPBlocklist:     ipblocklist.NewNoop(),
73
+		IPAllowlist:     allowlist,
57
 		EventStream:     events.NewNoopStream(),
74
 		EventStream:     events.NewNoopStream(),
58
 		Logger:          logger.NewNoopLogger(),
75
 		Logger:          logger.NewNoopLogger(),
59
 		UseTestDCs:      true,
76
 		UseTestDCs:      true,
114
 	suite.Error(err)
131
 	suite.Error(err)
115
 }
132
 }
116
 
133
 
134
+func (suite *ProxyTestSuite) TestCannotInitNoIPAllowlist() {
135
+	opts := *suite.opts
136
+	opts.IPAllowlist = nil
137
+
138
+	_, err := mtglib.NewProxy(opts)
139
+	suite.Error(err)
140
+}
141
+
117
 func (suite *ProxyTestSuite) TestCannotInitNoEventStream() {
142
 func (suite *ProxyTestSuite) TestCannotInitNoEventStream() {
118
 	opts := *suite.opts
143
 	opts := *suite.opts
119
 	opts.EventStream = nil
144
 	opts.EventStream = nil

Загрузка…
Отмена
Сохранить