mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 12:04:03 +03:00
Add iplist_size metric
This commit is contained in:
@@ -383,6 +383,7 @@ Here goes a list of metrics with their types but without a prefix.
|
|||||||
| client_connections | gauge | `ip_family` | Count of processing client connections. |
|
| client_connections | gauge | `ip_family` | Count of processing client connections. |
|
||||||
| telegram_connections | gauge | `telegram_ip`, `dc` | Count of connections to Telegram servers. |
|
| telegram_connections | gauge | `telegram_ip`, `dc` | Count of connections to Telegram servers. |
|
||||||
| domain_fronting_connections | gauge | `ip_family` | Count of connections to fronting domain. |
|
| domain_fronting_connections | gauge | `ip_family` | Count of connections to fronting domain. |
|
||||||
|
| iplist_size | gauge | `ip_list` | A size of either allowlist or blocklist in use. |
|
||||||
| telegram_traffic | counter | `telegram_ip`, `dc`, `direction` | Count of bytes, transmitted to/from Telegram. |
|
| telegram_traffic | counter | `telegram_ip`, `dc`, `direction` | Count of bytes, transmitted to/from Telegram. |
|
||||||
| domain_fronting_traffic | counter | `direction` | Count of bytes, transmitted to/from fronting domain. |
|
| domain_fronting_traffic | counter | `direction` | Count of bytes, transmitted to/from fronting domain. |
|
||||||
| domain_fronting | counter | – | Count of domain fronting events. |
|
| domain_fronting | counter | – | Count of domain fronting events. |
|
||||||
@@ -398,3 +399,4 @@ Tag meaning:
|
|||||||
| dc | | A number of the Telegram DC for a connection. |
|
| dc | | A number of the Telegram DC for a connection. |
|
||||||
| telegram_ip | | IP address of the Telegram server. |
|
| telegram_ip | | IP address of the Telegram server. |
|
||||||
| direction | `to_client`, `from_client` | A direction of the traffic flow. |
|
| direction | `to_client`, `from_client` | A direction of the traffic flow. |
|
||||||
|
| ip_list | `allowlist`, `blocklist` | A type of the IP list. |
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ func eventStreamProcessor(ctx context.Context, eventChan <-chan mtglib.Event, ob
|
|||||||
observer.EventConcurrencyLimited(typedEvt)
|
observer.EventConcurrencyLimited(typedEvt)
|
||||||
case mtglib.EventReplayAttack:
|
case mtglib.EventReplayAttack:
|
||||||
observer.EventReplayAttack(typedEvt)
|
observer.EventReplayAttack(typedEvt)
|
||||||
|
case mtglib.EventIPListSize:
|
||||||
|
observer.EventIPListSize(typedEvt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,6 +204,27 @@ func (suite *EventStreamTestSuite) TestEventReplayAttack() {
|
|||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *EventStreamTestSuite) TestEventIPListSize() {
|
||||||
|
evt := mtglib.NewEventIPListSize(10, true)
|
||||||
|
|
||||||
|
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
||||||
|
v.
|
||||||
|
On("EventIPListSize", mock.Anything).
|
||||||
|
Once().
|
||||||
|
Run(func(args mock.Arguments) {
|
||||||
|
caught, ok := args.Get(0).(mtglib.EventIPListSize)
|
||||||
|
|
||||||
|
suite.True(ok)
|
||||||
|
suite.Equal(evt.Timestamp(), caught.Timestamp())
|
||||||
|
suite.Equal(evt.Size, caught.Size)
|
||||||
|
suite.Equal(evt.IsBlockList, caught.IsBlockList)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
suite.stream.Send(suite.ctx, evt)
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
func (suite *EventStreamTestSuite) TearDownTest() {
|
func (suite *EventStreamTestSuite) TearDownTest() {
|
||||||
suite.stream.Shutdown()
|
suite.stream.Shutdown()
|
||||||
suite.ctxCancel()
|
suite.ctxCancel()
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ type Observer interface {
|
|||||||
// EventReplayAttack reacts on incoming mtglib.EventReplayAttack event.
|
// EventReplayAttack reacts on incoming mtglib.EventReplayAttack event.
|
||||||
EventReplayAttack(mtglib.EventReplayAttack)
|
EventReplayAttack(mtglib.EventReplayAttack)
|
||||||
|
|
||||||
|
// EventIPListSize reacts on incoming mtglib.EventIPListSize
|
||||||
|
EventIPListSize(mtglib.EventIPListSize)
|
||||||
|
|
||||||
// Shutdown stop observer. Default event stream guarantees:
|
// Shutdown stop observer. Default event stream guarantees:
|
||||||
// 1. If shutdown is executed, it is executed only once
|
// 1. If shutdown is executed, it is executed only once
|
||||||
// 2. Observer won't receieve any new message after this
|
// 2. Observer won't receieve any new message after this
|
||||||
|
|||||||
@@ -41,6 +41,10 @@ func (o *ObserverMock) EventReplayAttack(evt mtglib.EventReplayAttack) {
|
|||||||
o.Called(evt)
|
o.Called(evt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *ObserverMock) EventIPListSize(evt mtglib.EventIPListSize) {
|
||||||
|
o.Called(evt)
|
||||||
|
}
|
||||||
|
|
||||||
func (o *ObserverMock) Shutdown() {
|
func (o *ObserverMock) Shutdown() {
|
||||||
o.Called()
|
o.Called()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,6 +130,21 @@ func (m multiObserver) EventReplayAttack(evt mtglib.EventReplayAttack) {
|
|||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m multiObserver) EventIPListSize(evt mtglib.EventIPListSize) {
|
||||||
|
wg := &sync.WaitGroup{}
|
||||||
|
wg.Add(len(m.observers))
|
||||||
|
|
||||||
|
for _, v := range m.observers {
|
||||||
|
go func(obs Observer) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
obs.EventIPListSize(evt)
|
||||||
|
}(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
func (m multiObserver) Shutdown() {
|
func (m multiObserver) Shutdown() {
|
||||||
for _, v := range m.observers {
|
for _, v := range m.observers {
|
||||||
v.Shutdown()
|
v.Shutdown()
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ func (n noopObserver) EventFinish(_ mtglib.EventFinish)
|
|||||||
func (n noopObserver) EventConcurrencyLimited(_ mtglib.EventConcurrencyLimited) {}
|
func (n noopObserver) EventConcurrencyLimited(_ mtglib.EventConcurrencyLimited) {}
|
||||||
func (n noopObserver) EventIPBlocklisted(_ mtglib.EventIPBlocklisted) {}
|
func (n noopObserver) EventIPBlocklisted(_ mtglib.EventIPBlocklisted) {}
|
||||||
func (n noopObserver) EventReplayAttack(_ mtglib.EventReplayAttack) {}
|
func (n noopObserver) EventReplayAttack(_ mtglib.EventReplayAttack) {}
|
||||||
|
func (n noopObserver) EventIPListSize(_ mtglib.EventIPListSize) {}
|
||||||
func (n noopObserver) Shutdown() {}
|
func (n noopObserver) Shutdown() {}
|
||||||
|
|
||||||
// NewNoopObserver creates an observer which discards each message.
|
// NewNoopObserver creates an observer which discards each message.
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ func (suite *NoopTestSuite) SetupSuite() {
|
|||||||
"concurrency-limited": mtglib.NewEventConcurrencyLimited(),
|
"concurrency-limited": mtglib.NewEventConcurrencyLimited(),
|
||||||
"ip-blacklisted": mtglib.NewEventIPBlocklisted(net.ParseIP("10.0.0.10")),
|
"ip-blacklisted": mtglib.NewEventIPBlocklisted(net.ParseIP("10.0.0.10")),
|
||||||
"replay-attack": mtglib.NewEventReplayAttack("connID"),
|
"replay-attack": mtglib.NewEventReplayAttack("connID"),
|
||||||
|
"ip-list-size": mtglib.NewEventIPListSize(10, true),
|
||||||
}
|
}
|
||||||
suite.ctx = context.Background()
|
suite.ctx = context.Background()
|
||||||
}
|
}
|
||||||
@@ -65,6 +66,8 @@ func (suite *NoopTestSuite) TestObserver() {
|
|||||||
observer.EventIPBlocklisted(typedEvt)
|
observer.EventIPBlocklisted(typedEvt)
|
||||||
case mtglib.EventReplayAttack:
|
case mtglib.EventReplayAttack:
|
||||||
observer.EventReplayAttack(typedEvt)
|
observer.EventReplayAttack(typedEvt)
|
||||||
|
case mtglib.EventIPListSize:
|
||||||
|
observer.EventIPListSize(typedEvt)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -170,7 +170,7 @@ download-concurrency = 2
|
|||||||
# You can provider links here (starts with https:// or http://) or
|
# You can provider links here (starts with https:// or http://) or
|
||||||
# path to a local file, but in this case it should be absolute.
|
# path to a local file, but in this case it should be absolute.
|
||||||
urls = [
|
urls = [
|
||||||
# "https://iplists.firehol.org/files/firehol_level1.netset",
|
"https://iplists.firehol.org/files/firehol_level1.netset",
|
||||||
# "/local.file"
|
# "/local.file"
|
||||||
]
|
]
|
||||||
# How often do we need to update a blocklist set.
|
# How often do we need to update a blocklist set.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -85,7 +86,10 @@ func makeAntiReplayCache(conf *config.Config) mtglib.AntiReplayCache {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeIPBlocklist(conf config.ListConfig, logger mtglib.Logger, ntw mtglib.Network) (mtglib.IPBlocklist, error) {
|
func makeIPBlocklist(conf config.ListConfig,
|
||||||
|
logger mtglib.Logger,
|
||||||
|
ntw mtglib.Network,
|
||||||
|
updateCallback ipblocklist.FireholUpdateCallback) (mtglib.IPBlocklist, error) {
|
||||||
if !conf.Enabled.Get(false) {
|
if !conf.Enabled.Get(false) {
|
||||||
return ipblocklist.NewNoop(), nil
|
return ipblocklist.NewNoop(), nil
|
||||||
}
|
}
|
||||||
@@ -105,7 +109,8 @@ func makeIPBlocklist(conf config.ListConfig, logger mtglib.Logger, ntw mtglib.Ne
|
|||||||
ntw,
|
ntw,
|
||||||
conf.DownloadConcurrency.Get(1),
|
conf.DownloadConcurrency.Get(1),
|
||||||
remoteURLs,
|
remoteURLs,
|
||||||
localFiles)
|
localFiles,
|
||||||
|
updateCallback)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("incorrect parameters for firehol: %w", err)
|
return nil, fmt.Errorf("incorrect parameters for firehol: %w", err)
|
||||||
}
|
}
|
||||||
@@ -159,12 +164,23 @@ func runProxy(conf *config.Config, version string) error { // nolint: funlen
|
|||||||
|
|
||||||
logger.BindJSON("configuration", conf.String()).Debug("configuration")
|
logger.BindJSON("configuration", conf.String()).Debug("configuration")
|
||||||
|
|
||||||
|
eventStream, err := makeEventStream(conf, logger)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot build event stream: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
ntw, err := makeNetwork(conf, version)
|
ntw, err := makeNetwork(conf, version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot build network: %w", err)
|
return fmt.Errorf("cannot build network: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
blocklist, err := makeIPBlocklist(conf.Defense.Blocklist, logger.Named("blocklist"), ntw)
|
blocklist, err := makeIPBlocklist(
|
||||||
|
conf.Defense.Blocklist,
|
||||||
|
logger.Named("blocklist"),
|
||||||
|
ntw,
|
||||||
|
func(ctx context.Context, size int) {
|
||||||
|
eventStream.Send(ctx, mtglib.NewEventIPListSize(size, true))
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot build ip blocklist: %w", err)
|
return fmt.Errorf("cannot build ip blocklist: %w", err)
|
||||||
}
|
}
|
||||||
@@ -172,7 +188,13 @@ func runProxy(conf *config.Config, version string) error { // nolint: funlen
|
|||||||
var whitelist mtglib.IPBlocklist
|
var whitelist mtglib.IPBlocklist
|
||||||
|
|
||||||
if conf.Defense.Allowlist.Enabled.Get(false) {
|
if conf.Defense.Allowlist.Enabled.Get(false) {
|
||||||
whlist, err := makeIPBlocklist(conf.Defense.Allowlist, logger.Named("allowlist"), ntw)
|
whlist, err := makeIPBlocklist(
|
||||||
|
conf.Defense.Allowlist,
|
||||||
|
logger.Named("allowlist"),
|
||||||
|
ntw,
|
||||||
|
func(ctx context.Context, size int) {
|
||||||
|
eventStream.Send(ctx, mtglib.NewEventIPListSize(size, false))
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot build ip allowlist: %w", err)
|
return fmt.Errorf("cannot build ip allowlist: %w", err)
|
||||||
}
|
}
|
||||||
@@ -180,11 +202,6 @@ func runProxy(conf *config.Config, version string) error { // nolint: funlen
|
|||||||
whitelist = whlist
|
whitelist = whlist
|
||||||
}
|
}
|
||||||
|
|
||||||
eventStream, err := makeEventStream(conf, logger)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot build event stream: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := mtglib.ProxyOpts{
|
opts := mtglib.ProxyOpts{
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
Network: ntw,
|
Network: ntw,
|
||||||
|
|||||||
+24
-12
@@ -23,6 +23,10 @@ var (
|
|||||||
fireholIPv6DefaultCIDR = net.CIDRMask(128, 128) // nolint: gomnd
|
fireholIPv6DefaultCIDR = net.CIDRMask(128, 128) // nolint: gomnd
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// FireholUpdateCallback defines a signature of the callback that has to be
|
||||||
|
// execute when ip list is updated.
|
||||||
|
type FireholUpdateCallback func(context.Context, int)
|
||||||
|
|
||||||
// Firehol is IPBlocklist which uses lists from FireHOL:
|
// Firehol is IPBlocklist which uses lists from FireHOL:
|
||||||
// https://iplists.firehol.org/
|
// https://iplists.firehol.org/
|
||||||
//
|
//
|
||||||
@@ -42,7 +46,8 @@ type Firehol struct {
|
|||||||
logger mtglib.Logger
|
logger mtglib.Logger
|
||||||
updateMutex sync.RWMutex
|
updateMutex sync.RWMutex
|
||||||
|
|
||||||
ranger cidranger.Ranger
|
updateCallback FireholUpdateCallback
|
||||||
|
ranger cidranger.Ranger
|
||||||
|
|
||||||
blocklists []files.File
|
blocklists []files.File
|
||||||
|
|
||||||
@@ -110,7 +115,7 @@ func (f *Firehol) update() {
|
|||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
wg.Add(len(f.blocklists))
|
wg.Add(len(f.blocklists))
|
||||||
|
|
||||||
treeMutex := &sync.Mutex{}
|
mutex := &sync.Mutex{}
|
||||||
ranger := cidranger.NewPCTrieRanger()
|
ranger := cidranger.NewPCTrieRanger()
|
||||||
|
|
||||||
for _, v := range f.blocklists {
|
for _, v := range f.blocklists {
|
||||||
@@ -128,7 +133,7 @@ func (f *Firehol) update() {
|
|||||||
|
|
||||||
defer fileContent.Close()
|
defer fileContent.Close()
|
||||||
|
|
||||||
if err := f.updateFromFile(treeMutex, ranger, bufio.NewScanner(fileContent)); err != nil {
|
if err := f.updateFromFile(mutex, ranger, bufio.NewScanner(fileContent)); err != nil {
|
||||||
logger.WarningError("update has failed", err)
|
logger.WarningError("update has failed", err)
|
||||||
}
|
}
|
||||||
}(v)
|
}(v)
|
||||||
@@ -141,6 +146,10 @@ func (f *Firehol) update() {
|
|||||||
|
|
||||||
f.ranger = ranger
|
f.ranger = ranger
|
||||||
|
|
||||||
|
if f.updateCallback != nil {
|
||||||
|
f.updateCallback(ctx, ranger.Len())
|
||||||
|
}
|
||||||
|
|
||||||
f.logger.Info("ip list was updated")
|
f.logger.Info("ip list was updated")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +215,8 @@ func (f *Firehol) updateParseLine(text string) (*net.IPNet, error) {
|
|||||||
func NewFirehol(logger mtglib.Logger, network mtglib.Network,
|
func NewFirehol(logger mtglib.Logger, network mtglib.Network,
|
||||||
downloadConcurrency uint,
|
downloadConcurrency uint,
|
||||||
urls []string,
|
urls []string,
|
||||||
localFiles []string) (*Firehol, error) {
|
localFiles []string,
|
||||||
|
updateCallback FireholUpdateCallback) (*Firehol, error) {
|
||||||
blocklists := []files.File{}
|
blocklists := []files.File{}
|
||||||
|
|
||||||
for _, v := range localFiles {
|
for _, v := range localFiles {
|
||||||
@@ -229,12 +239,13 @@ func NewFirehol(logger mtglib.Logger, network mtglib.Network,
|
|||||||
blocklists = append(blocklists, file)
|
blocklists = append(blocklists, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewFireholFromFiles(logger, downloadConcurrency, blocklists)
|
return NewFireholFromFiles(logger, downloadConcurrency, blocklists, updateCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFireholFromFiles(logger mtglib.Logger,
|
func NewFireholFromFiles(logger mtglib.Logger,
|
||||||
downloadConcurrency uint,
|
downloadConcurrency uint,
|
||||||
blocklists []files.File) (*Firehol, error) {
|
blocklists []files.File,
|
||||||
|
updateCallback FireholUpdateCallback) (*Firehol, error) {
|
||||||
if downloadConcurrency == 0 {
|
if downloadConcurrency == 0 {
|
||||||
downloadConcurrency = DefaultFireholDownloadConcurrency
|
downloadConcurrency = DefaultFireholDownloadConcurrency
|
||||||
}
|
}
|
||||||
@@ -243,11 +254,12 @@ func NewFireholFromFiles(logger mtglib.Logger,
|
|||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
return &Firehol{
|
return &Firehol{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
ctxCancel: cancel,
|
ctxCancel: cancel,
|
||||||
logger: logger.Named("firehol"),
|
logger: logger.Named("firehol"),
|
||||||
ranger: cidranger.NewPCTrieRanger(),
|
ranger: cidranger.NewPCTrieRanger(),
|
||||||
workerPool: workerPool,
|
workerPool: workerPool,
|
||||||
blocklists: blocklists,
|
blocklists: blocklists,
|
||||||
|
updateCallback: updateCallback,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,8 @@ func (suite *FireholTestSuite) TearDownSuite() {
|
|||||||
func (suite *FireholTestSuite) TestLocalFail() {
|
func (suite *FireholTestSuite) TestLocalFail() {
|
||||||
blocklist, err := ipblocklist.NewFirehol(logger.NewNoopLogger(),
|
blocklist, err := ipblocklist.NewFirehol(logger.NewNoopLogger(),
|
||||||
suite.networkMock, 2,
|
suite.networkMock, 2,
|
||||||
nil, []string{filepath.Join("testdata", "broken_ipset.ipset")})
|
nil, []string{filepath.Join("testdata", "broken_ipset.ipset")},
|
||||||
|
nil)
|
||||||
|
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
@@ -85,7 +86,8 @@ func (suite *FireholTestSuite) TestLocalFail() {
|
|||||||
func (suite *FireholTestSuite) TestLocalOk() {
|
func (suite *FireholTestSuite) TestLocalOk() {
|
||||||
blocklist, err := ipblocklist.NewFirehol(logger.NewNoopLogger(),
|
blocklist, err := ipblocklist.NewFirehol(logger.NewNoopLogger(),
|
||||||
suite.networkMock, 2,
|
suite.networkMock, 2,
|
||||||
nil, []string{filepath.Join("testdata", "good_ipset.ipset")})
|
nil, []string{filepath.Join("testdata", "good_ipset.ipset")},
|
||||||
|
nil)
|
||||||
|
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
@@ -103,7 +105,7 @@ func (suite *FireholTestSuite) TestLocalOk() {
|
|||||||
func (suite *FireholTestSuite) TestRemoteFail() {
|
func (suite *FireholTestSuite) TestRemoteFail() {
|
||||||
blocklist, err := ipblocklist.NewFirehol(logger.NewNoopLogger(),
|
blocklist, err := ipblocklist.NewFirehol(logger.NewNoopLogger(),
|
||||||
suite.networkMock, 2,
|
suite.networkMock, 2,
|
||||||
[]string{"https://google.com"}, nil)
|
[]string{"https://google.com"}, nil, nil)
|
||||||
|
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
@@ -127,7 +129,7 @@ func (suite *FireholTestSuite) TestMixed() {
|
|||||||
suite.httpServer.URL,
|
suite.httpServer.URL,
|
||||||
}, []string{
|
}, []string{
|
||||||
filepath.Join("testdata", "good_ipset.ipset"),
|
filepath.Join("testdata", "good_ipset.ipset"),
|
||||||
})
|
}, nil)
|
||||||
|
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,15 @@ type EventReplayAttack struct {
|
|||||||
eventBase
|
eventBase
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EventIPListSize is emitted when mtg updates a contents of the ip lists:
|
||||||
|
// allowlist or blocklist.
|
||||||
|
type EventIPListSize struct {
|
||||||
|
eventBase
|
||||||
|
|
||||||
|
Size int
|
||||||
|
IsBlockList bool
|
||||||
|
}
|
||||||
|
|
||||||
// NewEventStart creates a new EventStart event.
|
// NewEventStart creates a new EventStart event.
|
||||||
func NewEventStart(streamID string, remoteIP net.IP) EventStart {
|
func NewEventStart(streamID string, remoteIP net.IP) EventStart {
|
||||||
return EventStart{
|
return EventStart{
|
||||||
@@ -176,3 +185,14 @@ func NewEventReplayAttack(streamID string) EventReplayAttack {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewEventIPListSize creates a new EventIPListSize event.
|
||||||
|
func NewEventIPListSize(size int, isBlockList bool) EventIPListSize {
|
||||||
|
return EventIPListSize{
|
||||||
|
eventBase: eventBase{
|
||||||
|
timestamp: time.Now(),
|
||||||
|
},
|
||||||
|
Size: size,
|
||||||
|
IsBlockList: isBlockList,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -69,6 +69,15 @@ func (suite *EventsTestSuite) TestEventReplayAttack() {
|
|||||||
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *EventsTestSuite) TestEventIPListSize() {
|
||||||
|
evt := mtglib.NewEventIPListSize(10, false)
|
||||||
|
|
||||||
|
suite.Empty(evt.StreamID())
|
||||||
|
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
||||||
|
suite.Equal(10, evt.Size)
|
||||||
|
suite.False(evt.IsBlockList)
|
||||||
|
}
|
||||||
|
|
||||||
func TestEvents(t *testing.T) {
|
func TestEvents(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
suite.Run(t, &EventsTestSuite{})
|
suite.Run(t, &EventsTestSuite{})
|
||||||
|
|||||||
@@ -89,6 +89,13 @@ const (
|
|||||||
// Type: counter
|
// Type: counter
|
||||||
MetricReplayAttacks = "replay_attacks"
|
MetricReplayAttacks = "replay_attacks"
|
||||||
|
|
||||||
|
// MetricIPListSize defines a metric for the size of the the ip list.
|
||||||
|
//
|
||||||
|
// Type: gauge
|
||||||
|
// Tags:
|
||||||
|
// ip_list | 'allowlist' or 'blocklist'
|
||||||
|
MetricIPListSize = "iplist_size"
|
||||||
|
|
||||||
// TagIPFamily defines a name of the 'ip_family' tag and all values.
|
// TagIPFamily defines a name of the 'ip_family' tag and all values.
|
||||||
TagIPFamily = "ip_family"
|
TagIPFamily = "ip_family"
|
||||||
|
|
||||||
@@ -114,4 +121,13 @@ const (
|
|||||||
// TagDirectionFromClient defines that traffic is sent from a client to
|
// TagDirectionFromClient defines that traffic is sent from a client to
|
||||||
// Telegram.
|
// Telegram.
|
||||||
TagDirectionFromClient = "from_client"
|
TagDirectionFromClient = "from_client"
|
||||||
|
|
||||||
|
// TagIPList defines a name of the 'ip_list' and all values.
|
||||||
|
TagIPList = "ip_list"
|
||||||
|
|
||||||
|
// TagIPListAllow defines a value of 'ip_list' of allowlist.
|
||||||
|
TagIPListAllow = "allowlist"
|
||||||
|
|
||||||
|
// TagIPListBlock defines a value of 'ip_list' of blocklist.
|
||||||
|
TagIPListBlock = "blocklist"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -118,6 +118,15 @@ func (p prometheusProcessor) EventReplayAttack(_ mtglib.EventReplayAttack) {
|
|||||||
p.factory.metricReplayAttacks.Inc()
|
p.factory.metricReplayAttacks.Inc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p prometheusProcessor) EventIPListSize(evt mtglib.EventIPListSize) {
|
||||||
|
tag := TagIPListBlock
|
||||||
|
if !evt.IsBlockList {
|
||||||
|
tag = TagIPListAllow
|
||||||
|
}
|
||||||
|
|
||||||
|
p.factory.metricIPListSize.WithLabelValues(tag).Set(float64(evt.Size))
|
||||||
|
}
|
||||||
|
|
||||||
func (p prometheusProcessor) Shutdown() {
|
func (p prometheusProcessor) Shutdown() {
|
||||||
for k, v := range p.streams {
|
for k, v := range p.streams {
|
||||||
releaseStreamInfo(v)
|
releaseStreamInfo(v)
|
||||||
@@ -137,6 +146,7 @@ type PrometheusFactory struct {
|
|||||||
metricClientConnections *prometheus.GaugeVec
|
metricClientConnections *prometheus.GaugeVec
|
||||||
metricTelegramConnections *prometheus.GaugeVec
|
metricTelegramConnections *prometheus.GaugeVec
|
||||||
metricDomainFrontingConnections *prometheus.GaugeVec
|
metricDomainFrontingConnections *prometheus.GaugeVec
|
||||||
|
metricIPListSize *prometheus.GaugeVec
|
||||||
|
|
||||||
metricTelegramTraffic *prometheus.CounterVec
|
metricTelegramTraffic *prometheus.CounterVec
|
||||||
metricDomainFrontingTraffic *prometheus.CounterVec
|
metricDomainFrontingTraffic *prometheus.CounterVec
|
||||||
@@ -197,6 +207,11 @@ func NewPrometheus(metricPrefix, httpPath string) *PrometheusFactory { // nolint
|
|||||||
Name: MetricDomainFrontingConnections,
|
Name: MetricDomainFrontingConnections,
|
||||||
Help: "A number of connections which talk to front domain.",
|
Help: "A number of connections which talk to front domain.",
|
||||||
}, []string{TagIPFamily}),
|
}, []string{TagIPFamily}),
|
||||||
|
metricIPListSize: prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||||
|
Namespace: metricPrefix,
|
||||||
|
Name: MetricIPListSize,
|
||||||
|
Help: "A size of the ip list (blocklist or allowlist)",
|
||||||
|
}, []string{TagIPList}),
|
||||||
|
|
||||||
metricTelegramTraffic: prometheus.NewCounterVec(prometheus.CounterOpts{
|
metricTelegramTraffic: prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||||
Namespace: metricPrefix,
|
Namespace: metricPrefix,
|
||||||
@@ -234,6 +249,7 @@ func NewPrometheus(metricPrefix, httpPath string) *PrometheusFactory { // nolint
|
|||||||
registry.MustRegister(factory.metricClientConnections)
|
registry.MustRegister(factory.metricClientConnections)
|
||||||
registry.MustRegister(factory.metricTelegramConnections)
|
registry.MustRegister(factory.metricTelegramConnections)
|
||||||
registry.MustRegister(factory.metricDomainFrontingConnections)
|
registry.MustRegister(factory.metricDomainFrontingConnections)
|
||||||
|
registry.MustRegister(factory.metricIPListSize)
|
||||||
|
|
||||||
registry.MustRegister(factory.metricTelegramTraffic)
|
registry.MustRegister(factory.metricTelegramTraffic)
|
||||||
registry.MustRegister(factory.metricDomainFrontingTraffic)
|
registry.MustRegister(factory.metricDomainFrontingTraffic)
|
||||||
|
|||||||
@@ -169,6 +169,18 @@ func (suite *PrometheusTestSuite) TestEventReplayAttack() {
|
|||||||
suite.Contains(data, `mtg_replay_attacks 1`)
|
suite.Contains(data, `mtg_replay_attacks 1`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *PrometheusTestSuite) TestEventIPListSize() {
|
||||||
|
suite.prometheus.EventIPListSize(mtglib.NewEventIPListSize(10, false))
|
||||||
|
suite.prometheus.EventIPListSize(mtglib.NewEventIPListSize(3, true))
|
||||||
|
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
|
data, err := suite.Get()
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.Contains(data, `mtg_iplist_size{ip_list="allowlist"} 10`)
|
||||||
|
suite.Contains(data, `mtg_iplist_size{ip_list="blocklist"} 3`)
|
||||||
|
}
|
||||||
|
|
||||||
func TestPrometheus(t *testing.T) {
|
func TestPrometheus(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
suite.Run(t, &PrometheusTestSuite{})
|
suite.Run(t, &PrometheusTestSuite{})
|
||||||
|
|||||||
@@ -121,6 +121,15 @@ func (s statsdProcessor) EventReplayAttack(_ mtglib.EventReplayAttack) {
|
|||||||
s.client.Incr(MetricReplayAttacks, 1)
|
s.client.Incr(MetricReplayAttacks, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s statsdProcessor) EventIPListSize(evt mtglib.EventIPListSize) {
|
||||||
|
tag := TagIPListBlock
|
||||||
|
if !evt.IsBlockList {
|
||||||
|
tag = TagIPListAllow
|
||||||
|
}
|
||||||
|
|
||||||
|
s.client.Gauge(MetricIPListSize, int64(evt.Size), statsd.StringTag(TagIPList, tag))
|
||||||
|
}
|
||||||
|
|
||||||
func (s statsdProcessor) Shutdown() {
|
func (s statsdProcessor) Shutdown() {
|
||||||
events := make([]mtglib.EventFinish, 0, len(s.streams))
|
events := make([]mtglib.EventFinish, 0, len(s.streams))
|
||||||
|
|
||||||
|
|||||||
@@ -196,6 +196,22 @@ func (suite *StatsdTestSuite) TestEventReplayAttack() {
|
|||||||
suite.Equal("mtg.replay_attacks:1|c", suite.statsdServer.String())
|
suite.Equal("mtg.replay_attacks:1|c", suite.statsdServer.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *StatsdTestSuite) TestEventIPListSizeAllowlist() {
|
||||||
|
suite.statsd.EventIPListSize(mtglib.NewEventIPListSize(10, false))
|
||||||
|
|
||||||
|
time.Sleep(statsdSleepTime)
|
||||||
|
suite.Contains(suite.statsdServer.String(), "mtg.iplist_size:10|g")
|
||||||
|
suite.Contains(suite.statsdServer.String(), "allowlist")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *StatsdTestSuite) TestEventIPListSizeBlocklist() {
|
||||||
|
suite.statsd.EventIPListSize(mtglib.NewEventIPListSize(10, true))
|
||||||
|
|
||||||
|
time.Sleep(statsdSleepTime)
|
||||||
|
suite.Contains(suite.statsdServer.String(), "mtg.iplist_size:10|g")
|
||||||
|
suite.Contains(suite.statsdServer.String(), "blocklist")
|
||||||
|
}
|
||||||
|
|
||||||
func TestStatsd(t *testing.T) {
|
func TestStatsd(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
suite.Run(t, &StatsdTestSuite{})
|
suite.Run(t, &StatsdTestSuite{})
|
||||||
|
|||||||
Reference in New Issue
Block a user