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