From 534d5b755e089bde072d9495c700bb99857c130c Mon Sep 17 00:00:00 2001 From: 9seconds Date: Mon, 21 Mar 2022 13:38:59 +0300 Subject: [PATCH] Add tags for ip blocklisted metric --- mtglib/events.go | 18 ++++++++++++++++-- mtglib/events_test.go | 9 +++++++++ mtglib/proxy.go | 2 +- stats/prometheus.go | 23 ++++++++++++++--------- stats/prometheus_test.go | 13 ++++++++++++- stats/statsd.go | 9 +++++++-- stats/statsd_test.go | 10 +++++++++- 7 files changed, 68 insertions(+), 16 deletions(-) diff --git a/mtglib/events.go b/mtglib/events.go index fdc387b..f1c5152 100644 --- a/mtglib/events.go +++ b/mtglib/events.go @@ -83,7 +83,8 @@ type EventConcurrencyLimited struct { type EventIPBlocklisted struct { eventBase - RemoteIP net.IP + RemoteIP net.IP + IsBlockList bool } // EventReplayAttack is emitted when mtg detects a replay attack on a @@ -172,7 +173,20 @@ func NewEventIPBlocklisted(remoteIP net.IP) EventIPBlocklisted { eventBase: eventBase{ timestamp: time.Now(), }, - RemoteIP: remoteIP, + RemoteIP: remoteIP, + IsBlockList: true, + } +} + +// NewEventIPAllowlisted creates a NewEventIPBlocklisted event with a mark that +// it is supposed to be for allow list. +func NewEventIPAllowlisted(remoteIP net.IP) EventIPBlocklisted { + return EventIPBlocklisted{ + eventBase: eventBase{ + timestamp: time.Now(), + }, + RemoteIP: remoteIP, + IsBlockList: false, } } diff --git a/mtglib/events_test.go b/mtglib/events_test.go index 56da979..ddce9cc 100644 --- a/mtglib/events_test.go +++ b/mtglib/events_test.go @@ -60,6 +60,15 @@ func (suite *EventsTestSuite) TestEventIPBlocklisted() { suite.Empty(evt.StreamID()) suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond) + suite.True(evt.IsBlockList) +} + +func (suite *EventsTestSuite) TestEventIPAllowlisted() { + evt := mtglib.NewEventIPAllowlisted(net.ParseIP("10.0.0.10")) + + suite.Empty(evt.StreamID()) + suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond) + suite.False(evt.IsBlockList) } func (suite *EventsTestSuite) TestEventReplayAttack() { diff --git a/mtglib/proxy.go b/mtglib/proxy.go index 99fe486..e8d3b44 100644 --- a/mtglib/proxy.go +++ b/mtglib/proxy.go @@ -112,7 +112,7 @@ func (p *Proxy) Serve(listener net.Listener) error { if !p.allowlist.Contains(ipAddr) { conn.Close() logger.Info("ip was rejected by allowlist") - p.eventStream.Send(p.ctx, NewEventIPBlocklisted(ipAddr)) + p.eventStream.Send(p.ctx, NewEventIPAllowlisted(ipAddr)) continue } diff --git a/stats/prometheus.go b/stats/prometheus.go index 17882df..eec64b5 100644 --- a/stats/prometheus.go +++ b/stats/prometheus.go @@ -110,8 +110,13 @@ func (p prometheusProcessor) EventConcurrencyLimited(_ mtglib.EventConcurrencyLi p.factory.metricConcurrencyLimited.Inc() } -func (p prometheusProcessor) EventIPBlocklisted(_ mtglib.EventIPBlocklisted) { - p.factory.metricIPBlocklisted.Inc() +func (p prometheusProcessor) EventIPBlocklisted(evt mtglib.EventIPBlocklisted) { + tag := TagIPListBlock + if !evt.IsBlockList { + tag = TagIPListAllow + } + + p.factory.metricIPBlocklisted.WithLabelValues(tag).Inc() } func (p prometheusProcessor) EventReplayAttack(_ mtglib.EventReplayAttack) { @@ -150,10 +155,10 @@ type PrometheusFactory struct { metricTelegramTraffic *prometheus.CounterVec metricDomainFrontingTraffic *prometheus.CounterVec + metricIPBlocklisted *prometheus.CounterVec metricDomainFronting prometheus.Counter metricConcurrencyLimited prometheus.Counter - metricIPBlocklisted prometheus.Counter metricReplayAttacks prometheus.Counter } @@ -223,6 +228,11 @@ func NewPrometheus(metricPrefix, httpPath string) *PrometheusFactory { // nolint Name: MetricDomainFrontingTraffic, Help: "Traffic which is generated talking with front domain.", }, []string{TagDirection}), + metricIPBlocklisted: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: metricPrefix, + Name: MetricIPBlocklisted, + Help: "A number of rejected sessions due to ip blocklisting.", + }, []string{TagIPList}), metricDomainFronting: prometheus.NewCounter(prometheus.CounterOpts{ Namespace: metricPrefix, @@ -234,11 +244,6 @@ func NewPrometheus(metricPrefix, httpPath string) *PrometheusFactory { // nolint Name: MetricConcurrencyLimited, Help: "A number of sessions that were rejected by concurrency limiter.", }), - metricIPBlocklisted: prometheus.NewCounter(prometheus.CounterOpts{ - Namespace: metricPrefix, - Name: MetricIPBlocklisted, - Help: "A number of rejected sessions due to ip blocklisting.", - }), metricReplayAttacks: prometheus.NewCounter(prometheus.CounterOpts{ Namespace: metricPrefix, Name: MetricReplayAttacks, @@ -253,10 +258,10 @@ func NewPrometheus(metricPrefix, httpPath string) *PrometheusFactory { // nolint registry.MustRegister(factory.metricTelegramTraffic) registry.MustRegister(factory.metricDomainFrontingTraffic) + registry.MustRegister(factory.metricIPBlocklisted) registry.MustRegister(factory.metricDomainFronting) registry.MustRegister(factory.metricConcurrencyLimited) - registry.MustRegister(factory.metricIPBlocklisted) registry.MustRegister(factory.metricReplayAttacks) return factory diff --git a/stats/prometheus_test.go b/stats/prometheus_test.go index e530095..9adcb1b 100644 --- a/stats/prometheus_test.go +++ b/stats/prometheus_test.go @@ -156,7 +156,18 @@ func (suite *PrometheusTestSuite) TestEventIPBlocklisted() { data, err := suite.Get() suite.NoError(err) - suite.Contains(data, `mtg_ip_blocklisted 1`) + suite.Contains(data, `mtg_ip_blocklisted{ip_list="blocklist"} 1`) +} + +func (suite *PrometheusTestSuite) TestEventIPAllowlisted() { + suite.prometheus.EventIPBlocklisted( + mtglib.NewEventIPAllowlisted(net.ParseIP("2001:db8::68"))) + + time.Sleep(100 * time.Millisecond) + + data, err := suite.Get() + suite.NoError(err) + suite.Contains(data, `mtg_ip_blocklisted{ip_list="allowlist"} 1`) } func (suite *PrometheusTestSuite) TestEventReplayAttack() { diff --git a/stats/statsd.go b/stats/statsd.go index a19f561..1c6a99f 100644 --- a/stats/statsd.go +++ b/stats/statsd.go @@ -113,8 +113,13 @@ func (s statsdProcessor) EventConcurrencyLimited(_ mtglib.EventConcurrencyLimite s.client.Incr(MetricConcurrencyLimited, 1) } -func (s statsdProcessor) EventIPBlocklisted(_ mtglib.EventIPBlocklisted) { - s.client.Incr(MetricIPBlocklisted, 1) +func (s statsdProcessor) EventIPBlocklisted(evt mtglib.EventIPBlocklisted) { + tag := TagIPListBlock + if !evt.IsBlockList { + tag = TagIPListAllow + } + + s.client.Incr(MetricIPBlocklisted, 1, statsd.StringTag(TagIPList, tag)) } func (s statsdProcessor) EventReplayAttack(_ mtglib.EventReplayAttack) { diff --git a/stats/statsd_test.go b/stats/statsd_test.go index f3eaafd..6107f3c 100644 --- a/stats/statsd_test.go +++ b/stats/statsd_test.go @@ -186,7 +186,15 @@ func (suite *StatsdTestSuite) TestEventIPBlocklisted() { mtglib.NewEventIPBlocklisted(net.ParseIP("10.0.0.10"))) time.Sleep(statsdSleepTime) - suite.Equal("mtg.ip_blocklisted:1|c", suite.statsdServer.String()) + suite.Equal("mtg.ip_blocklisted:1|c|#ip_list:blocklist", suite.statsdServer.String()) +} + +func (suite *StatsdTestSuite) TestEventIPAllowlisted() { + suite.statsd.EventIPBlocklisted( + mtglib.NewEventIPAllowlisted(net.ParseIP("10.0.0.10"))) + + time.Sleep(statsdSleepTime) + suite.Equal("mtg.ip_blocklisted:1|c|#ip_list:allowlist", suite.statsdServer.String()) } func (suite *StatsdTestSuite) TestEventReplayAttack() {