Merge branch 'remove-zap'
This commit is contained in:
commit
cdbcf0e03b
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
@ -17,8 +18,6 @@ import (
|
|||||||
"github.com/coreos/go-systemd/daemon"
|
"github.com/coreos/go-systemd/daemon"
|
||||||
sshlib "github.com/gliderlabs/ssh"
|
sshlib "github.com/gliderlabs/ssh"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"go.uber.org/zap"
|
|
||||||
"go.uber.org/zap/zapcore"
|
|
||||||
"golang.org/x/crypto/acme/autocert"
|
"golang.org/x/crypto/acme/autocert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -55,17 +54,17 @@ func ActionServe(c *cli.Context) error {
|
|||||||
|
|
||||||
// Setup logging
|
// Setup logging
|
||||||
loggers := setupLoggers(cfg)
|
loggers := setupLoggers(cfg)
|
||||||
loggers.rootLogger.Infow("Starting apiary.", "version", apiary.FullVersion())
|
loggers.rootLogger.Info("Starting apiary.", "version", apiary.FullVersion())
|
||||||
|
|
||||||
// Setup store
|
// Setup store
|
||||||
var s store.LoginAttemptStore
|
var s store.LoginAttemptStore
|
||||||
switch cfg.Store.Type {
|
switch cfg.Store.Type {
|
||||||
case "MEMORY", "memory":
|
case "MEMORY", "memory":
|
||||||
loggers.rootLogger.Infow("Initialized store.", "store_type", "memory")
|
loggers.rootLogger.Info("Initialized store.", "store_type", "memory")
|
||||||
s = &store.MemoryStore{}
|
s = &store.MemoryStore{}
|
||||||
case "POSTGRES", "postgres":
|
case "POSTGRES", "postgres":
|
||||||
pgStartTime := time.Now()
|
pgStartTime := time.Now()
|
||||||
loggers.rootLogger.Debugw("Initializing store.", "store_type", "postgres")
|
loggers.rootLogger.Debug("Initializing store.", "store_type", "postgres")
|
||||||
pgStore, err := store.NewPostgresStore(cfg.Store.Postgres.DSN)
|
pgStore, err := store.NewPostgresStore(cfg.Store.Postgres.DSN)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -73,33 +72,33 @@ func ActionServe(c *cli.Context) error {
|
|||||||
if err := pgStore.InitDB(); err != nil {
|
if err := pgStore.InitDB(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
loggers.rootLogger.Infow("Initialized store.", "store_type", "postgres", "init_time", time.Since(pgStartTime))
|
loggers.rootLogger.Info("Initialized store.", "store_type", "postgres", "init_time", time.Since(pgStartTime))
|
||||||
if cfg.Store.EnableCache {
|
if cfg.Store.EnableCache {
|
||||||
loggers.rootLogger.Debugw("Initializing store.", "store_type", "cache-postgres")
|
loggers.rootLogger.Debug("Initializing store.", "store_type", "cache-postgres")
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
cachingStore := store.NewCachingStore(pgStore)
|
cachingStore := store.NewCachingStore(pgStore)
|
||||||
s = cachingStore
|
s = cachingStore
|
||||||
loggers.rootLogger.Infow("Initialized store.", "store_type", "cache-postgres", "init_time", time.Since(startTime))
|
loggers.rootLogger.Info("Initialized store.", "store_type", "cache-postgres", "init_time", time.Since(startTime))
|
||||||
} else {
|
} else {
|
||||||
s = pgStore
|
s = pgStore
|
||||||
}
|
}
|
||||||
case "bolt", "BOLT":
|
case "bolt", "BOLT":
|
||||||
boltStartTime := time.Now()
|
boltStartTime := time.Now()
|
||||||
loggers.rootLogger.Debugw("Initializing store.", "store_type", "bolt")
|
loggers.rootLogger.Debug("Initializing store.", "store_type", "bolt")
|
||||||
boltStore, err := store.NewBBoltStore(cfg.Store.Bolt.DBPath)
|
boltStore, err := store.NewBBoltStore(cfg.Store.Bolt.DBPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer boltStore.Close()
|
defer boltStore.Close()
|
||||||
|
|
||||||
loggers.rootLogger.Infow("Initialized store.", "store_type", "bolt", "init_time", time.Since(boltStartTime))
|
loggers.rootLogger.Info("Initialized store.", "store_type", "bolt", "init_time", time.Since(boltStartTime))
|
||||||
|
|
||||||
if cfg.Store.EnableCache {
|
if cfg.Store.EnableCache {
|
||||||
loggers.rootLogger.Debugw("Initializing store.", "store_type", "cache-bolt")
|
loggers.rootLogger.Debug("Initializing store.", "store_type", "cache-bolt")
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
cachingStore := store.NewCachingStore(boltStore)
|
cachingStore := store.NewCachingStore(boltStore)
|
||||||
s = cachingStore
|
s = cachingStore
|
||||||
loggers.rootLogger.Infow("Initialized store.", "store_type", "cache-bolt", "init_time", time.Since(startTime))
|
loggers.rootLogger.Info("Initialized store.", "store_type", "cache-bolt", "init_time", time.Since(startTime))
|
||||||
} else {
|
} else {
|
||||||
s = boltStore
|
s = boltStore
|
||||||
}
|
}
|
||||||
@ -153,18 +152,18 @@ func ActionServe(c *cli.Context) error {
|
|||||||
|
|
||||||
// Start ssh server
|
// Start ssh server
|
||||||
go func() {
|
go func() {
|
||||||
loggers.rootLogger.Infow("Starting SSH server.", "addr", cfg.Honeypot.ListenAddr)
|
loggers.rootLogger.Info("Starting SSH server.", "addr", cfg.Honeypot.ListenAddr)
|
||||||
if err := hs.ListenAndServe(); err != nil && err != sshlib.ErrServerClosed {
|
if err := hs.ListenAndServe(); err != nil && err != sshlib.ErrServerClosed {
|
||||||
loggers.rootLogger.Warnw("SSH server returned error.", "error", err)
|
loggers.rootLogger.Warn("SSH server returned error.", "error", err)
|
||||||
}
|
}
|
||||||
loggers.rootLogger.Infow("SSH server stopped.")
|
loggers.rootLogger.Info("SSH server stopped.")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Start web server
|
// Start web server
|
||||||
go func() {
|
go func() {
|
||||||
loggers.rootLogger.Infow("Starting web server.", "addr", cfg.Frontend.ListenAddr)
|
loggers.rootLogger.Info("Starting web server.", "addr", cfg.Frontend.ListenAddr)
|
||||||
if err := web.StartServe(); err != nil && err != http.ErrServerClosed {
|
if err := web.StartServe(); err != nil && err != http.ErrServerClosed {
|
||||||
loggers.rootLogger.Warnw("Web server returned error.", "error", err)
|
loggers.rootLogger.Warn("Web server returned error.", "error", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -184,7 +183,7 @@ func ActionServe(c *cli.Context) error {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
loggers.rootLogger.Warnw("Unable to connect to NOTIFY_SOCKET.", "error", err)
|
loggers.rootLogger.Warn("Unable to connect to NOTIFY_SOCKET.", "error", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
loggers.rootLogger.Debug("Sent READY=1 to NOTIFY_SOCKET.")
|
loggers.rootLogger.Debug("Sent READY=1 to NOTIFY_SOCKET.")
|
||||||
@ -192,11 +191,11 @@ func ActionServe(c *cli.Context) error {
|
|||||||
// Setup timer
|
// Setup timer
|
||||||
timeout, err := daemon.SdWatchdogEnabled(false)
|
timeout, err := daemon.SdWatchdogEnabled(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
loggers.rootLogger.Warnw("Unable to get watchdog timeout.", "error", err)
|
loggers.rootLogger.Warn("Unable to get watchdog timeout.", "error", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if timeout == 0 {
|
if timeout == 0 {
|
||||||
loggers.rootLogger.Infow("Systemd watchdog not enabled.")
|
loggers.rootLogger.Info("Systemd watchdog not enabled.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,14 +208,14 @@ func ActionServe(c *cli.Context) error {
|
|||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
if healthy == nil {
|
if healthy == nil {
|
||||||
if _, err := daemon.SdNotify(false, daemon.SdNotifyWatchdog); err != nil {
|
if _, err := daemon.SdNotify(false, daemon.SdNotifyWatchdog); err != nil {
|
||||||
loggers.rootLogger.Warnw("Error notifying watchdog.", "err", err)
|
loggers.rootLogger.Warn("Error notifying watchdog.", "err", err)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// TODO: If unhealthy, should we retry healthcheck immediately, otherwise service will most likely get killed by watchdog.
|
// TODO: If unhealthy, should we retry healthcheck immediately, otherwise service will most likely get killed by watchdog.
|
||||||
loggers.rootLogger.Errorw("Store reported not healthy, might get killed by watchdog.", "err", healthy)
|
loggers.rootLogger.Error("Store reported not healthy, might get killed by watchdog.", "err", healthy)
|
||||||
case <-notifyCtx.Done():
|
case <-notifyCtx.Done():
|
||||||
loggers.rootLogger.Debugw("Notify context cancelled.")
|
loggers.rootLogger.Debug("Notify context cancelled.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,7 +229,7 @@ func ActionServe(c *cli.Context) error {
|
|||||||
defer sshShutdownCancel()
|
defer sshShutdownCancel()
|
||||||
loggers.rootLogger.Info("SSH server shutdown started.")
|
loggers.rootLogger.Info("SSH server shutdown started.")
|
||||||
if err := hs.Shutdown(sshShutdownCtx); err != nil {
|
if err := hs.Shutdown(sshShutdownCtx); err != nil {
|
||||||
loggers.rootLogger.Infow("Error shutting down SSH server.", "error", err)
|
loggers.rootLogger.Info("Error shutting down SSH server.", "error", err)
|
||||||
}
|
}
|
||||||
loggers.rootLogger.Info("SSH server shutdown complete.")
|
loggers.rootLogger.Info("SSH server shutdown complete.")
|
||||||
|
|
||||||
@ -240,7 +239,7 @@ func ActionServe(c *cli.Context) error {
|
|||||||
|
|
||||||
loggers.rootLogger.Info("Web server shutdown started.")
|
loggers.rootLogger.Info("Web server shutdown started.")
|
||||||
if err := web.Shutdown(webShutdownCtx); err != nil {
|
if err := web.Shutdown(webShutdownCtx); err != nil {
|
||||||
loggers.rootLogger.Infow("Error shutting down web server.", "error", err)
|
loggers.rootLogger.Info("Error shutting down web server.", "error", err)
|
||||||
}
|
}
|
||||||
loggers.rootLogger.Info("Web server shutdown complete.")
|
loggers.rootLogger.Info("Web server shutdown complete.")
|
||||||
rootCancel()
|
rootCancel()
|
||||||
@ -252,49 +251,36 @@ func ActionServe(c *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type loggerCollection struct {
|
type loggerCollection struct {
|
||||||
rootLogger *zap.SugaredLogger
|
rootLogger *slog.Logger
|
||||||
honeypotLogger *zap.SugaredLogger
|
honeypotLogger *slog.Logger
|
||||||
webAccessLogger *zap.SugaredLogger
|
webAccessLogger *slog.Logger
|
||||||
webServerLogger *zap.SugaredLogger
|
webServerLogger *slog.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupLoggers(cfg config.Config) *loggerCollection {
|
func setupLoggers(cfg config.Config) *loggerCollection {
|
||||||
logEncoderCfg := zap.NewProductionEncoderConfig()
|
opts := &slog.HandlerOptions{}
|
||||||
logEncoderCfg.EncodeCaller = func(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {}
|
|
||||||
|
|
||||||
var level zap.AtomicLevel
|
|
||||||
switch strings.ToUpper(cfg.Honeypot.LogLevel) {
|
switch strings.ToUpper(cfg.Honeypot.LogLevel) {
|
||||||
case "INFO":
|
case "INFO":
|
||||||
level = zap.NewAtomicLevelAt(zap.InfoLevel)
|
opts.Level = slog.LevelInfo
|
||||||
case "DEBUG":
|
case "DEBUG":
|
||||||
level = zap.NewAtomicLevelAt(zap.DebugLevel)
|
opts.Level = slog.LevelDebug
|
||||||
|
opts.AddSource = true
|
||||||
case "WARN", "WARNING":
|
case "WARN", "WARNING":
|
||||||
level = zap.NewAtomicLevelAt(zap.WarnLevel)
|
opts.Level = slog.LevelWarn
|
||||||
case "ERR", "ERROR":
|
case "ERR", "ERROR":
|
||||||
level = zap.NewAtomicLevelAt(zap.WarnLevel)
|
opts.Level = slog.LevelError
|
||||||
default:
|
default:
|
||||||
level = zap.NewAtomicLevelAt(zap.InfoLevel)
|
opts.Level = slog.LevelInfo
|
||||||
}
|
|
||||||
logEncoderCfg.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
|
||||||
logEncoderCfg.EncodeTime = zapcore.ISO8601TimeEncoder
|
|
||||||
logEncoderCfg.EncodeDuration = zapcore.StringDurationEncoder
|
|
||||||
rootLoggerCfg := &zap.Config{
|
|
||||||
Level: level,
|
|
||||||
OutputPaths: []string{"stdout"},
|
|
||||||
ErrorOutputPaths: []string{"stderr"},
|
|
||||||
Encoding: "console",
|
|
||||||
EncoderConfig: logEncoderCfg,
|
|
||||||
}
|
|
||||||
rootLogger, err := rootLoggerCfg.Build()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handler := slog.NewTextHandler(os.Stdout, opts)
|
||||||
|
rootLogger := slog.New(handler)
|
||||||
|
|
||||||
return &loggerCollection{
|
return &loggerCollection{
|
||||||
rootLogger: rootLogger.Named("APP").Sugar(),
|
rootLogger: rootLogger.With("module", "application"),
|
||||||
honeypotLogger: rootLogger.Named("HON").Sugar(),
|
honeypotLogger: rootLogger.With("module", "honeypot"),
|
||||||
webAccessLogger: rootLogger.Named("ACC").Sugar(),
|
webAccessLogger: rootLogger.With("module", "web-access-log"),
|
||||||
webServerLogger: rootLogger.Named("WEB").Sugar(),
|
webServerLogger: rootLogger.With("module", "web-server"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@
|
|||||||
mkdir -p web/frontend/dist
|
mkdir -p web/frontend/dist
|
||||||
cp -r ${frontend}/* web/frontend/dist
|
cp -r ${frontend}/* web/frontend/dist
|
||||||
'';
|
'';
|
||||||
vendorHash = "sha256-j3NT1caRun3sLXti1Whrljz8gW8GmALJXqWWJFGD+Ko=";
|
vendorHash = "sha256-fJnln143V5ajZgEEgVZN2y3dIz9/L9w6ZBLZk/eX61M=";
|
||||||
ldflags = [ "-X git.t-juice.club/torjus/apiary.Build=${rev}" ];
|
ldflags = [ "-X git.t-juice.club/torjus/apiary.Build=${rev}" ];
|
||||||
tags = [
|
tags = [
|
||||||
"embed"
|
"embed"
|
||||||
|
2
go.mod
2
go.mod
@ -16,7 +16,6 @@ require (
|
|||||||
github.com/prometheus/client_golang v1.21.1
|
github.com/prometheus/client_golang v1.21.1
|
||||||
github.com/urfave/cli/v2 v2.27.6
|
github.com/urfave/cli/v2 v2.27.6
|
||||||
go.etcd.io/bbolt v1.4.0
|
go.etcd.io/bbolt v1.4.0
|
||||||
go.uber.org/zap v1.27.0
|
|
||||||
golang.org/x/crypto v0.36.0
|
golang.org/x/crypto v0.36.0
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -39,7 +38,6 @@ require (
|
|||||||
github.com/prometheus/procfs v0.16.0 // indirect
|
github.com/prometheus/procfs v0.16.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
|
||||||
golang.org/x/net v0.37.0 // indirect
|
golang.org/x/net v0.37.0 // indirect
|
||||||
golang.org/x/sys v0.31.0 // indirect
|
golang.org/x/sys v0.31.0 // indirect
|
||||||
golang.org/x/text v0.23.0 // indirect
|
golang.org/x/text v0.23.0 // indirect
|
||||||
|
6
go.sum
6
go.sum
@ -166,19 +166,13 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
|||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
|
||||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
|
||||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
|
||||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
@ -13,7 +13,7 @@ var mmdb []byte
|
|||||||
func (s *HoneypotServer) LookupCountry(ip net.IP) string {
|
func (s *HoneypotServer) LookupCountry(ip net.IP) string {
|
||||||
db, err := maxminddb.FromBytes(mmdb)
|
db, err := maxminddb.FromBytes(mmdb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Logger.Warnw("Error opening geoip database", "error", err)
|
s.Logger.Warn("Error opening geoip database", "error", err)
|
||||||
return "??"
|
return "??"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ func (s *HoneypotServer) LookupCountry(ip net.IP) string {
|
|||||||
|
|
||||||
err = db.Lookup(ip, &record)
|
err = db.Lookup(ip, &record)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Logger.Warnw("Error doing geoip lookup", "error", err)
|
s.Logger.Warn("Error doing geoip lookup", "error", err)
|
||||||
return "??"
|
return "??"
|
||||||
}
|
}
|
||||||
if record.Country.ISOCode == "None" {
|
if record.Country.ISOCode == "None" {
|
||||||
|
@ -3,6 +3,7 @@ package ssh
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
"log/slog"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
@ -16,11 +17,10 @@ import (
|
|||||||
"git.t-juice.club/torjus/apiary/models"
|
"git.t-juice.club/torjus/apiary/models"
|
||||||
sshlib "github.com/gliderlabs/ssh"
|
sshlib "github.com/gliderlabs/ssh"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type HoneypotServer struct {
|
type HoneypotServer struct {
|
||||||
Logger *zap.SugaredLogger
|
Logger *slog.Logger
|
||||||
|
|
||||||
sshServer *sshlib.Server
|
sshServer *sshlib.Server
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ type HoneypotServer struct {
|
|||||||
func NewHoneypotServer(cfg config.HoneypotConfig, store store.LoginAttemptStore) (*HoneypotServer, error) {
|
func NewHoneypotServer(cfg config.HoneypotConfig, store store.LoginAttemptStore) (*HoneypotServer, error) {
|
||||||
var hs HoneypotServer
|
var hs HoneypotServer
|
||||||
hs.attemptStore = store
|
hs.attemptStore = store
|
||||||
hs.Logger = zap.NewNop().Sugar()
|
hs.Logger = slog.New(slog.NewTextHandler(io.Discard, nil))
|
||||||
|
|
||||||
hs.sshServer = &sshlib.Server{
|
hs.sshServer = &sshlib.Server{
|
||||||
Addr: cfg.ListenAddr,
|
Addr: cfg.ListenAddr,
|
||||||
@ -94,19 +94,19 @@ func (hs *HoneypotServer) passwordHandler(ctx sshlib.Context, password string) b
|
|||||||
}
|
}
|
||||||
country := hs.LookupCountry(la.RemoteIP)
|
country := hs.LookupCountry(la.RemoteIP)
|
||||||
if utf8.RuneCountInString(country) > 2 {
|
if utf8.RuneCountInString(country) > 2 {
|
||||||
hs.Logger.Warnw("Too many characters in country", "country", country, "runecount", utf8.RuneCountInString(country))
|
hs.Logger.Warn("Too many characters in country", "country", country, "runecount", utf8.RuneCountInString(country))
|
||||||
country = "??"
|
country = "??"
|
||||||
}
|
}
|
||||||
|
|
||||||
la.Country = country
|
la.Country = country
|
||||||
hs.Logger.Infow("Login attempt",
|
hs.Logger.Info("Login attempt",
|
||||||
"remote_ip", la.RemoteIP.String(),
|
"remote_ip", la.RemoteIP.String(),
|
||||||
"username", la.Username,
|
"username", la.Username,
|
||||||
"password", la.Password,
|
"password", la.Password,
|
||||||
"country", la.Country)
|
"country", la.Country)
|
||||||
|
|
||||||
if err := hs.attemptStore.AddAttempt(&la); err != nil {
|
if err := hs.attemptStore.AddAttempt(&la); err != nil {
|
||||||
hs.Logger.Warnw("Error adding attempt to store", "error", err)
|
hs.Logger.Warn("Error adding attempt to store", "error", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cFunc := range hs.attemptsCallbacks {
|
for _, cFunc := range hs.attemptsCallbacks {
|
||||||
@ -117,7 +117,7 @@ func (hs *HoneypotServer) passwordHandler(ctx sshlib.Context, password string) b
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *HoneypotServer) connCallback(ctx sshlib.Context, conn net.Conn) net.Conn {
|
func (s *HoneypotServer) connCallback(ctx sshlib.Context, conn net.Conn) net.Conn {
|
||||||
s.Logger.Debugw("Connection received.", "remote_addr", conn.RemoteAddr())
|
s.Logger.Debug("Connection received.", "remote_addr", conn.RemoteAddr())
|
||||||
|
|
||||||
throttledConn := newThrottledConn(conn)
|
throttledConn := newThrottledConn(conn)
|
||||||
throttledConn.SetSpeed(s.throttleSpeed)
|
throttledConn.SetSpeed(s.throttleSpeed)
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Version = "v0.2.1"
|
Version = "v0.2.2"
|
||||||
Build string
|
Build string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ func (s *Server) LoggingMiddleware(next http.Handler) http.Handler {
|
|||||||
if s.cfg.AccessLogIgnoreMetrics && r.URL.Path == "/metrics" && ww.Status() == http.StatusOK {
|
if s.cfg.AccessLogIgnoreMetrics && r.URL.Path == "/metrics" && ww.Status() == http.StatusOK {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.AccessLogger.Infow(r.Method,
|
s.AccessLogger.Info(r.Method,
|
||||||
"path", r.URL.Path,
|
"path", r.URL.Path,
|
||||||
"status", ww.Status(),
|
"status", ww.Status(),
|
||||||
"written", ww.BytesWritten(),
|
"written", ww.BytesWritten(),
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
@ -20,7 +21,6 @@ import (
|
|||||||
"github.com/go-chi/chi/v5/middleware"
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
"go.uber.org/zap"
|
|
||||||
"golang.org/x/crypto/acme/autocert"
|
"golang.org/x/crypto/acme/autocert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -35,8 +35,8 @@ type Server struct {
|
|||||||
honeypotServer *ssh.HoneypotServer
|
honeypotServer *ssh.HoneypotServer
|
||||||
store store.LoginAttemptStore
|
store store.LoginAttemptStore
|
||||||
|
|
||||||
ServerLogger *zap.SugaredLogger
|
ServerLogger *slog.Logger
|
||||||
AccessLogger *zap.SugaredLogger
|
AccessLogger *slog.Logger
|
||||||
|
|
||||||
attemptListenersLock sync.RWMutex
|
attemptListenersLock sync.RWMutex
|
||||||
attemptListeners map[string]chan models.LoginAttempt
|
attemptListeners map[string]chan models.LoginAttempt
|
||||||
@ -44,9 +44,10 @@ type Server struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(cfg config.FrontendConfig, hs *ssh.HoneypotServer, store store.LoginAttemptStore) *Server {
|
func NewServer(cfg config.FrontendConfig, hs *ssh.HoneypotServer, store store.LoginAttemptStore) *Server {
|
||||||
|
discardLogger := slog.New(slog.NewTextHandler(io.Discard, nil))
|
||||||
s := &Server{
|
s := &Server{
|
||||||
ServerLogger: zap.NewNop().Sugar(),
|
ServerLogger: discardLogger,
|
||||||
AccessLogger: zap.NewNop().Sugar(),
|
AccessLogger: discardLogger,
|
||||||
store: store,
|
store: store,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
}
|
}
|
||||||
@ -125,7 +126,7 @@ func (s *Server) StartServe() error {
|
|||||||
s.ServerLogger.Debug("Starting HTTP redirect server")
|
s.ServerLogger.Debug("Starting HTTP redirect server")
|
||||||
go func() {
|
go func() {
|
||||||
if err := s.httpRedirectServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
if err := s.httpRedirectServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||||
s.ServerLogger.Warnw("HTTP redirect server returned error", "error", err)
|
s.ServerLogger.Warn("HTTP redirect server returned error", "error", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -174,7 +175,7 @@ func (s *Server) HandlerAttemptStream(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
_, err = io.WriteString(w, fmt.Sprintf("data: %s\n\n", string(data)))
|
_, err = io.WriteString(w, fmt.Sprintf("data: %s\n\n", string(data)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.ServerLogger.Warnw("Error writing event", "error", err)
|
s.ServerLogger.Warn("Error writing event", "error", err)
|
||||||
}
|
}
|
||||||
flusher.Flush()
|
flusher.Flush()
|
||||||
ticker.Reset(streamKeepAliveDuration)
|
ticker.Reset(streamKeepAliveDuration)
|
||||||
@ -184,7 +185,7 @@ func (s *Server) HandlerAttemptStream(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
if _, err := io.WriteString(w, ": keep-alive\n\n"); err != nil {
|
if _, err := io.WriteString(w, ": keep-alive\n\n"); err != nil {
|
||||||
s.ServerLogger.Warnw("Error writing event", "error", err)
|
s.ServerLogger.Warn("Error writing event", "error", err)
|
||||||
}
|
}
|
||||||
flusher.Flush()
|
flusher.Flush()
|
||||||
}
|
}
|
||||||
@ -207,14 +208,14 @@ func (s *Server) HandlerStats(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
stats, err := s.store.Stats(statType, limit)
|
stats, err := s.store.Stats(statType, limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.ServerLogger.Warnw("Error fetching stats", "error", err)
|
s.ServerLogger.Warn("Error fetching stats", "error", err)
|
||||||
s.WriteAPIError(w, r, http.StatusInternalServerError, "Error fetching stats")
|
s.WriteAPIError(w, r, http.StatusInternalServerError, "Error fetching stats")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
encoder := json.NewEncoder(w)
|
encoder := json.NewEncoder(w)
|
||||||
if err := encoder.Encode(stats); err != nil {
|
if err := encoder.Encode(stats); err != nil {
|
||||||
s.ServerLogger.Debugf("Error encoding or writing response", "remote_ip", r.RemoteAddr, "error", err)
|
s.ServerLogger.Debug("Error encoding or writing response", "remote_ip", r.RemoteAddr, "error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,13 +242,13 @@ func (s *Server) HandlerQuery(w http.ResponseWriter, r *http.Request) {
|
|||||||
userResults, err := s.store.Query(uq)
|
userResults, err := s.store.Query(uq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.WriteAPIError(w, r, http.StatusInternalServerError, "Unable to perform query")
|
s.WriteAPIError(w, r, http.StatusInternalServerError, "Unable to perform query")
|
||||||
s.ServerLogger.Warnw("Error performing query", "error", err)
|
s.ServerLogger.Warn("Error performing query", "error", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
passwordResults, err := s.store.Query(pq)
|
passwordResults, err := s.store.Query(pq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.WriteAPIError(w, r, http.StatusInternalServerError, "Unable to perform query")
|
s.WriteAPIError(w, r, http.StatusInternalServerError, "Unable to perform query")
|
||||||
s.ServerLogger.Warnw("Error performing query", "error", err)
|
s.ServerLogger.Warn("Error performing query", "error", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,7 +264,7 @@ func (s *Server) HandlerQuery(w http.ResponseWriter, r *http.Request) {
|
|||||||
queryResults, err := s.store.Query(aq)
|
queryResults, err := s.store.Query(aq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.WriteAPIError(w, r, http.StatusInternalServerError, "Unable to perform query")
|
s.WriteAPIError(w, r, http.StatusInternalServerError, "Unable to perform query")
|
||||||
s.ServerLogger.Warnw("Error performing query", "error", err)
|
s.ServerLogger.Warn("Error performing query", "error", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +273,7 @@ func (s *Server) HandlerQuery(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
encoder := json.NewEncoder(w)
|
encoder := json.NewEncoder(w)
|
||||||
if err := encoder.Encode(&results); err != nil {
|
if err := encoder.Encode(&results); err != nil {
|
||||||
s.ServerLogger.Warnw("Error writing query results", "error", err)
|
s.ServerLogger.Warn("Error writing query results", "error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,6 +295,6 @@ func (s *Server) WriteAPIError(w http.ResponseWriter, r *http.Request, status in
|
|||||||
apiErr := APIErrorResponse{Error: message}
|
apiErr := APIErrorResponse{Error: message}
|
||||||
w.WriteHeader(status)
|
w.WriteHeader(status)
|
||||||
if err := encoder.Encode(&apiErr); err != nil {
|
if err := encoder.Encode(&apiErr); err != nil {
|
||||||
s.ServerLogger.Debugf("Error encoding or writing error response", "remote_ip", r.RemoteAddr, "error", err)
|
s.ServerLogger.Debug("Error encoding or writing error response", "remote_ip", r.RemoteAddr, "error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user