Add more metrics
This commit is contained in:
parent
e7074257b1
commit
0560e2a76c
@ -82,7 +82,17 @@ func ActionServe(c *cli.Context) error {
|
|||||||
return fmt.Errorf("Invalid store configured")
|
return fmt.Errorf("Invalid store configured")
|
||||||
}
|
}
|
||||||
|
|
||||||
s = store.NewMetricsCollectingStore(s)
|
// Setup interrupt handling
|
||||||
|
interruptChan := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(interruptChan, os.Interrupt)
|
||||||
|
|
||||||
|
rootCtx, rootCancel := context.WithCancel(c.Context)
|
||||||
|
defer rootCancel()
|
||||||
|
serversCtx, serversCancel := context.WithCancel(rootCtx)
|
||||||
|
defer serversCancel()
|
||||||
|
|
||||||
|
// Setup metrics collection
|
||||||
|
s = store.NewMetricsCollectingStore(rootCtx, s)
|
||||||
|
|
||||||
// Setup honeypot
|
// Setup honeypot
|
||||||
hs, err := ssh.NewHoneypotServer(cfg.Honeypot, s)
|
hs, err := ssh.NewHoneypotServer(cfg.Honeypot, s)
|
||||||
@ -109,13 +119,6 @@ func ActionServe(c *cli.Context) error {
|
|||||||
web.TLSConfig = tlsConfig
|
web.TLSConfig = tlsConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup interrupt handling
|
|
||||||
interruptChan := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(interruptChan, os.Interrupt)
|
|
||||||
|
|
||||||
rootCtx, rootCancel := context.WithCancel(c.Context)
|
|
||||||
serversCtx, serversCancel := context.WithCancel(rootCtx)
|
|
||||||
|
|
||||||
// Setup portlistener, if configured
|
// Setup portlistener, if configured
|
||||||
if cfg.Ports.Enable {
|
if cfg.Ports.Enable {
|
||||||
portsCtx, cancel := context.WithCancel(rootCtx)
|
portsCtx, cancel := context.WithCancel(rootCtx)
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package store
|
package store
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.uio.no/torjus/apiary/models"
|
"github.uio.no/torjus/apiary/models"
|
||||||
)
|
)
|
||||||
@ -8,9 +11,12 @@ import (
|
|||||||
type MetricsCollectingStore struct {
|
type MetricsCollectingStore struct {
|
||||||
store LoginAttemptStore
|
store LoginAttemptStore
|
||||||
attemptsCounter *prometheus.CounterVec
|
attemptsCounter *prometheus.CounterVec
|
||||||
|
uniqueUsernamesCount prometheus.Gauge
|
||||||
|
uniquePasswordsCount prometheus.Gauge
|
||||||
|
uniqueIPsCount prometheus.Gauge
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMetricsCollectingStore(store LoginAttemptStore) *MetricsCollectingStore {
|
func NewMetricsCollectingStore(ctx context.Context, store LoginAttemptStore) *MetricsCollectingStore {
|
||||||
mcs := &MetricsCollectingStore{store: store}
|
mcs := &MetricsCollectingStore{store: store}
|
||||||
|
|
||||||
mcs.attemptsCounter = prometheus.NewCounterVec(
|
mcs.attemptsCounter = prometheus.NewCounterVec(
|
||||||
@ -21,7 +27,42 @@ func NewMetricsCollectingStore(store LoginAttemptStore) *MetricsCollectingStore
|
|||||||
},
|
},
|
||||||
[]string{"CountryCode"},
|
[]string{"CountryCode"},
|
||||||
)
|
)
|
||||||
|
mcs.uniqueUsernamesCount = prometheus.NewGauge(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Name: "apiary_ssh_unique_usernames_count",
|
||||||
|
Help: "Counter of unique usernames.",
|
||||||
|
ConstLabels: prometheus.Labels{"service": "honeypot_ssh"},
|
||||||
|
})
|
||||||
|
|
||||||
|
mcs.uniquePasswordsCount = prometheus.NewGauge(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Name: "apiary_ssh_unique_passwords_count",
|
||||||
|
Help: "Counter of unique passwords.",
|
||||||
|
ConstLabels: prometheus.Labels{"service": "honeypot_ssh"},
|
||||||
|
})
|
||||||
|
|
||||||
|
mcs.uniqueIPsCount = prometheus.NewGauge(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Name: "apiary_ssh_unique_ips_count",
|
||||||
|
Help: "Counter of unique IPs.",
|
||||||
|
ConstLabels: prometheus.Labels{"service": "honeypot_ssh"},
|
||||||
|
})
|
||||||
|
|
||||||
prometheus.MustRegister(mcs.attemptsCounter)
|
prometheus.MustRegister(mcs.attemptsCounter)
|
||||||
|
prometheus.MustRegister(mcs.uniqueUsernamesCount)
|
||||||
|
prometheus.MustRegister(mcs.uniquePasswordsCount)
|
||||||
|
prometheus.MustRegister(mcs.uniqueIPsCount)
|
||||||
|
|
||||||
|
// Kinda jank, we just fetch the stats every 10seconds, but it should be cached most of the time.
|
||||||
|
go func(ctx context.Context) {
|
||||||
|
ticker := time.NewTicker(10 * time.Second)
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
case <-ticker.C:
|
||||||
|
mcs.Stats(LoginStatsTotals, 0)
|
||||||
|
}
|
||||||
|
}(ctx)
|
||||||
|
|
||||||
return mcs
|
return mcs
|
||||||
}
|
}
|
||||||
@ -37,7 +78,23 @@ func (s *MetricsCollectingStore) All() ([]models.LoginAttempt, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *MetricsCollectingStore) Stats(statType LoginStats, limit int) ([]StatsResult, error) {
|
func (s *MetricsCollectingStore) Stats(statType LoginStats, limit int) ([]StatsResult, error) {
|
||||||
return s.store.Stats(statType, limit)
|
stats, err := s.store.Stats(statType, limit)
|
||||||
|
if statType == LoginStatsTotals {
|
||||||
|
for _, element := range stats {
|
||||||
|
switch element.Name {
|
||||||
|
case "UniquePasswords":
|
||||||
|
s.uniquePasswordsCount.Set(float64(element.Count))
|
||||||
|
case "UniqueUsernames":
|
||||||
|
s.uniqueUsernamesCount.Set(float64(element.Count))
|
||||||
|
case "UniqueIPs":
|
||||||
|
s.uniqueIPsCount.Set(float64(element.Count))
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stats, err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MetricsCollectingStore) Query(query AttemptQuery) ([]models.LoginAttempt, error) {
|
func (s *MetricsCollectingStore) Query(query AttemptQuery) ([]models.LoginAttempt, error) {
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Version = "v0.1.15"
|
var Version = "v0.1.16"
|
||||||
var Build string
|
var Build string
|
||||||
|
|
||||||
func FullVersion() string {
|
func FullVersion() string {
|
||||||
|
Loading…
Reference in New Issue
Block a user