tuns
created pr with
ps-69
added ps-70
1: 4bd8050 = 1: 4bd8050 feat: metric drain
-: ------- > 2: ea49338 chore: add userId to metric drain visit
added ps-71
1: 4bd8050 = 1: 4bd8050 feat: metric drain
2: ea49338 = 2: ea49338 chore: add userId to metric drain visit
-: ------- > 3: 343f29e chore: update pubsub
changed status to
accepted
cmds
checkout latest patchset:
ssh pr.pico.sh print pr-34 | git am -3checkout any patchset in a patch request:
ssh pr.pico.sh print ps-X | git am -3add changes to patch request:
git format-patch main --stdout | ssh pr.pico.sh pr add 34set PR to open (enables RSS notifications):
ssh pr.pico.sh pr open 34set PR to draft (stops RSS notifications):
ssh pr.pico.sh pr draft 34
Patchset
ps-71
feat: metric drain
Eric Bower
2024-11-13T02:16:16ZThis change will enable http remote forwards to have site analytics enabled automatically.
Semantic diff summary
2 added,
7 modified,
0 signature changed,
0 removed
across 6 analyzed files
(2 files skipped: unsupported file type)
+4
-0
Makefile
#
@@ -19,3 +19,7 @@ docs-prod: ssg
dev:
go run main.go --http-address localhost:3000 --domain testing.ssi.sh
.PHONY: dev
+
+fmt:
+ go fmt ./...
+.PHONY: fmt
+7
-2
cmd/sish.go
#
@@ -17,6 +17,7 @@ import (
"github.com/spf13/viper"
"gopkg.in/natefinch/lumberjack.v2"
+ "github.com/picosh/pubsub"
pipeLogger "github.com/picosh/pubsub/log"
picoUtils "github.com/picosh/utils"
)
@@ -206,17 +207,21 @@ func initConfig() {
slog.NewTextHandler(multiWriter, &slog.HandlerOptions{AddSource: true, Level: logLevel}),
)
- realLogger, err := pipeLogger.SendLogRegister(logger, &pipeLogger.PubSubConnectionInfo{
+ info := &pubsub.RemoteClientInfo{
RemoteHost: picoUtils.GetEnv("PICO_PIPE_ENDPOINT", "send.pico.sh:22"),
KeyLocation: picoUtils.GetEnv("PICO_PIPE_KEY", "ssh_data/term_info_ed25519"),
KeyPassphrase: picoUtils.GetEnv("PICO_PIPE_PASSPHRASE", ""),
RemoteHostname: picoUtils.GetEnv("PICO_PIPE_REMOTE_HOST", "send.pico.sh"),
RemoteUser: picoUtils.GetEnv("PICO_PIPE_USER", "pico"),
- }, 100)
+ }
+ realLogger, err := pipeLogger.SendLogRegister(logger, info, 100)
if err != nil {
slog.Error("unable to set real logger", slog.Any("error", err))
}
+ metricDrain := pubsub.NewRemoteClientWriter(info, logger, 100)
+ go metricDrain.KeepAlive("pub metric-drain -b=false")
+
trueLogger := logger
if realLogger != nil {
+2
-0
go.mod
#
@@ -2,6 +2,8 @@ module github.com/antoniomika/sish
go 1.23.1
+replace github.com/picosh/pubsub => /home/erock/dev/pico/pubsub
+
require (
github.com/ScaleFT/sshkeys v1.2.0
github.com/antoniomika/multilistener v0.0.0-20240307222635-f0dc097d8acc
+28
-0
httpmuxer/httpmuxer.go
#
@@ -31,6 +31,16 @@ import (
"github.com/gin-gonic/gin"
)
+type MetricDrainVisit struct {
+ UserID string `json:"user_id"`
+ Host string `json:"host"`
+ Path string `json:"path"`
+ IpAddress string `json:"ip_adress"`
+ UserAgent string `json:"user_agent"`
+ Referer string `json:"referer"`
+ Status int `json:"status"`
+}
+
// Start initializes the HTTP service.
func Start(state *utils.State) {
releaseMode := gin.ReleaseMode
@@ -106,6 +116,24 @@ func Start(state *utils.State) {
param.ErrorMessage,
)
+ visit := MetricDrainVisit{
+ UserID: "",
+ Host: param.Request.Host,
+ IpAddress: param.ClientIP,
+ Status: param.StatusCode,
+ Path: originalURI,
+ UserAgent: param.Request.UserAgent(),
+ Referer: param.Request.Referer(),
+ }
+ data, err := json.Marshal(visit)
+ if err != nil {
+ slog.Error("could not json marshall visit record", "err", err)
+ }
+ _, err = state.MetricDrain.Write(data)
+ if err != nil {
+ slog.Error("could not send to visit to metric-drain", "err", err)
+ }
+
slog.Info(logLine)
if viper.GetBool("log-to-client") && param.Keys["httpHolder"] != nil {
+13
-0
sshmuxer/sshmuxer.go
#
@@ -16,6 +16,8 @@ import (
"github.com/antoniomika/sish/httpmuxer"
"github.com/antoniomika/sish/utils"
"github.com/antoniomika/syncmap"
+ "github.com/picosh/pubsub"
+ picoUtils "github.com/picosh/utils"
"github.com/pires/go-proxyproto"
"github.com/spf13/viper"
"golang.org/x/crypto/ssh"
@@ -70,10 +72,21 @@ func Start() {
utils.WatchKeys()
+ info := &pubsub.RemoteClientInfo{
+ RemoteHost: picoUtils.GetEnv("PICO_PIPE_ENDPOINT", "send.pico.sh:22"),
+ KeyLocation: picoUtils.GetEnv("PICO_PIPE_KEY", "ssh_data/term_info_ed25519"),
+ KeyPassphrase: picoUtils.GetEnv("PICO_PIPE_PASSPHRASE", ""),
+ RemoteHostname: picoUtils.GetEnv("PICO_PIPE_REMOTE_HOST", "send.pico.sh"),
+ RemoteUser: picoUtils.GetEnv("PICO_PIPE_USER", "pico"),
+ }
+ metricDrain := pubsub.NewRemoteClientWriter(info, slog.Default(), 100)
+ go metricDrain.KeepAlive("pub metric-drain -b=false")
+
state := utils.NewState()
state.Ports.HTTPPort = httpPort
state.Ports.HTTPSPort = httpsPort
state.Ports.SSHPort = sshPort
+ state.MetricDrain = metricDrain
state.Console.State = state
+10
-0
utils/conn.go
#
@@ -99,6 +99,16 @@ func (s *SSHConnection) User() string {
return user
}
+// User returns the user of the session, either using the extensions user or the passed user.
+func (s *SSHConnection) UserId() string {
+ user, ok := s.SSHConn.Permissions.Extensions["userId"]
+ if !ok {
+ user = ""
+ }
+
+ return user
+}
+
// TeeConn represents a simple net.Conn interface for SNI Processing.
type TeeConn struct {
Conn net.Conn
+1
-0
utils/state.go
#
@@ -231,6 +231,7 @@ type State struct {
ActiveConnections prometheus.GaugeFunc
ActiveTunnels *prometheus.GaugeVec
ConnectionTime *prometheus.GaugeVec
+ MetricDrain io.Writer
}
// NewState returns a new State struct.
+6
-0
utils/utils.go
#
@@ -597,7 +597,13 @@ func checkAuthenticationKeyRequest(authUrl string, authKey []byte, addr net.Addr
return false, extensionsInfo, nil
}
+ userId, ok := userData["id"].(string)
+ if !ok {
+ return false, extensionsInfo, nil
+ }
+
extensionsInfo["user"] = userName
+ extensionsInfo["userId"] = userId
}
return true, extensionsInfo, nil