Antonio Mika
·
2025-04-10
ssh.go
1package pastes
2
3import (
4 "context"
5 "os"
6 "os/signal"
7 "syscall"
8 "time"
9
10 "github.com/picosh/pico/pkg/db/postgres"
11 "github.com/picosh/pico/pkg/filehandlers"
12 "github.com/picosh/pico/pkg/pssh"
13 "github.com/picosh/pico/pkg/send/auth"
14 "github.com/picosh/pico/pkg/send/list"
15 "github.com/picosh/pico/pkg/send/pipe"
16 "github.com/picosh/pico/pkg/send/protocols/rsync"
17 "github.com/picosh/pico/pkg/send/protocols/scp"
18 "github.com/picosh/pico/pkg/send/protocols/sftp"
19 "github.com/picosh/pico/pkg/shared"
20 "github.com/picosh/utils"
21)
22
23func StartSshServer() {
24 appName := "pastes-ssh"
25
26 host := utils.GetEnv("PASTES_HOST", "0.0.0.0")
27 port := utils.GetEnv("PASTES_SSH_PORT", "2222")
28 promPort := utils.GetEnv("PASTES_PROM_PORT", "9222")
29 cfg := NewConfigSite(appName)
30 logger := cfg.Logger
31
32 ctx, cancel := context.WithCancel(context.Background())
33 defer cancel()
34
35 dbh := postgres.NewDB(cfg.DbURL, cfg.Logger)
36 defer dbh.Close()
37 hooks := &FileHooks{
38 Cfg: cfg,
39 Db: dbh,
40 }
41
42 fileMap := map[string]filehandlers.ReadWriteHandler{
43 "fallback": filehandlers.NewScpPostHandler(dbh, cfg, hooks),
44 }
45 handler := filehandlers.NewFileHandlerRouter(cfg, dbh, fileMap)
46 sshAuth := shared.NewSshAuthHandler(dbh, logger)
47
48 // Create a new SSH server
49 server, err := pssh.NewSSHServerWithConfig(
50 ctx,
51 logger,
52 appName,
53 host,
54 port,
55 promPort,
56 "ssh_data/term_info_ed25519",
57 sshAuth.PubkeyAuthHandler,
58 []pssh.SSHServerMiddleware{
59 pipe.Middleware(handler, ""),
60 list.Middleware(handler),
61 scp.Middleware(handler),
62 rsync.Middleware(handler),
63 auth.Middleware(handler),
64 pssh.PtyMdw(pssh.DeprecatedNotice(), 200*time.Millisecond),
65 pssh.LogMiddleware(handler, dbh),
66 },
67 []pssh.SSHServerMiddleware{
68 sftp.Middleware(handler),
69 pssh.LogMiddleware(handler, dbh),
70 },
71 nil,
72 )
73
74 if err != nil {
75 logger.Error("failed to create ssh server", "err", err.Error())
76 os.Exit(1)
77 }
78
79 done := make(chan os.Signal, 1)
80 signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
81 logger.Info("Starting SSH server", "addr", server.Config.ListenAddr)
82 go func() {
83 if err = server.ListenAndServe(); err != nil {
84 logger.Error("serve", "err", err.Error())
85 os.Exit(1)
86 }
87 }()
88
89 exit := func() {
90 logger.Info("stopping ssh server")
91 cancel()
92 }
93
94 <-done
95 exit()
96}