Antonio Mika
·
2025-03-30
ssh.go
1package pipe
2
3import (
4 "context"
5 "os"
6 "os/signal"
7 "syscall"
8
9 "github.com/antoniomika/syncmap"
10 "github.com/picosh/pico/pkg/db/postgres"
11 "github.com/picosh/pico/pkg/pssh"
12 "github.com/picosh/pico/pkg/shared"
13 psub "github.com/picosh/pubsub"
14 "github.com/picosh/utils"
15 "golang.org/x/crypto/ssh"
16)
17
18func StartSshServer() {
19 appName := "pipe-ssh"
20
21 host := utils.GetEnv("PIPE_HOST", "0.0.0.0")
22 port := utils.GetEnv("PIPE_SSH_PORT", "2222")
23 portOverride := utils.GetEnv("PIPE_SSH_PORT_OVERRIDE", port)
24 promPort := utils.GetEnv("PIPE_PROM_PORT", "9222")
25 cfg := NewConfigSite(appName)
26 logger := cfg.Logger
27
28 ctx, cancel := context.WithCancel(context.Background())
29 defer cancel()
30
31 dbh := postgres.NewDB(cfg.DbURL, cfg.Logger)
32 defer dbh.Close()
33
34 cfg.Port = port
35 cfg.PortOverride = portOverride
36
37 pubsub := psub.NewMulticast(logger)
38 handler := &CliHandler{
39 Logger: logger,
40 DBPool: dbh,
41 PubSub: pubsub,
42 Cfg: cfg,
43 Waiters: syncmap.New[string, []string](),
44 Access: syncmap.New[string, []string](),
45 }
46
47 sshAuth := shared.NewSshAuthHandler(dbh, logger)
48
49 // Create a new SSH server
50 server, err := pssh.NewSSHServerWithConfig(
51 ctx,
52 logger,
53 appName,
54 host,
55 port,
56 promPort,
57 "ssh_data/term_info_ed25519",
58 func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
59 perms, _ := sshAuth.PubkeyAuthHandler(conn, key)
60 if perms == nil {
61 perms = &ssh.Permissions{
62 Extensions: map[string]string{
63 "pubkey": utils.KeyForKeyText(key),
64 },
65 }
66 }
67
68 return perms, nil
69 },
70 []pssh.SSHServerMiddleware{
71 Middleware(handler),
72 pssh.LogMiddleware(handler, dbh),
73 },
74 nil,
75 nil,
76 )
77
78 if err != nil {
79 logger.Error("failed to create ssh server", "err", err.Error())
80 os.Exit(1)
81 }
82
83 done := make(chan os.Signal, 1)
84 signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
85 logger.Info("Starting SSH server", "addr", server.Config.ListenAddr)
86 go func() {
87 if err = server.ListenAndServe(); err != nil {
88 logger.Error("serve", "err", err.Error())
89 os.Exit(1)
90 }
91 }()
92
93 exit := func() {
94 logger.Info("stopping ssh server")
95 cancel()
96 }
97
98 <-done
99 exit()
100}