Eric Bower
·
2026-01-25
ssh.go
1package feeds
2
3import (
4 "context"
5 "os"
6 "os/signal"
7 "syscall"
8
9 "github.com/picosh/pico/pkg/db/postgres"
10 "github.com/picosh/pico/pkg/filehandlers"
11 "github.com/picosh/pico/pkg/pssh"
12 "github.com/picosh/pico/pkg/send/auth"
13 "github.com/picosh/pico/pkg/send/list"
14 "github.com/picosh/pico/pkg/send/pipe"
15 "github.com/picosh/pico/pkg/send/protocols/rsync"
16 "github.com/picosh/pico/pkg/send/protocols/scp"
17 "github.com/picosh/pico/pkg/send/protocols/sftp"
18 "github.com/picosh/pico/pkg/shared"
19)
20
21func StartSshServer() {
22 appName := "feeds-ssh"
23
24 host := shared.GetEnv("FEEDS_HOST", "0.0.0.0")
25 port := shared.GetEnv("FEEDS_SSH_PORT", "2222")
26 promPort := shared.GetEnv("FEEDS_PROM_PORT", "9222")
27 cfg := NewConfigSite(appName)
28 logger := cfg.Logger
29
30 ctx, cancel := context.WithCancel(context.Background())
31 defer cancel()
32
33 dbh := postgres.NewDB(cfg.DbURL, cfg.Logger)
34 defer func() {
35 _ = dbh.Close()
36 }()
37
38 hooks := &FeedHooks{
39 Cfg: cfg,
40 Db: dbh,
41 }
42
43 fileMap := map[string]filehandlers.ReadWriteHandler{
44 "fallback": filehandlers.NewScpPostHandler(dbh, cfg, hooks),
45 }
46 handler := filehandlers.NewFileHandlerRouter(cfg, dbh, fileMap)
47
48 sshAuth := shared.NewSshAuthHandler(dbh, logger, "feeds")
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 sshAuth.PubkeyAuthHandler,
60 []pssh.SSHServerMiddleware{
61 pipe.Middleware(handler, ".txt"),
62 list.Middleware(handler),
63 scp.Middleware(handler),
64 rsync.Middleware(handler),
65 auth.Middleware(handler),
66 Middleware(dbh, cfg),
67 pssh.LogMiddleware(handler, dbh),
68 },
69 []pssh.SSHServerMiddleware{
70 sftp.Middleware(handler),
71 pssh.LogMiddleware(handler, dbh),
72 },
73 nil,
74 )
75
76 if err != nil {
77 logger.Error("failed to create ssh server", "err", err.Error())
78 os.Exit(1)
79 }
80
81 done := make(chan os.Signal, 1)
82
83 signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
84 logger.Info("Starting SSH server", "addr", server.Config.ListenAddr)
85 go func() {
86 if err = server.ListenAndServe(); err != nil {
87 logger.Error("serve", "err", err.Error())
88 os.Exit(1)
89 }
90 }()
91
92 exit := func() {
93 logger.Info("stopping ssh server")
94 cancel()
95 }
96
97 <-done
98 exit()
99}