Antonio Mika
·
2025-04-10
ssh.go
1package prose
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 uploadimgs "github.com/picosh/pico/pkg/filehandlers/imgs"
13 "github.com/picosh/pico/pkg/pssh"
14 "github.com/picosh/pico/pkg/send/auth"
15 "github.com/picosh/pico/pkg/send/list"
16 "github.com/picosh/pico/pkg/send/pipe"
17 "github.com/picosh/pico/pkg/send/protocols/rsync"
18 "github.com/picosh/pico/pkg/send/protocols/scp"
19 "github.com/picosh/pico/pkg/send/protocols/sftp"
20 "github.com/picosh/pico/pkg/shared"
21 "github.com/picosh/pico/pkg/shared/storage"
22 "github.com/picosh/utils"
23)
24
25func StartSshServer() {
26 appName := "prose-ssh"
27
28 host := utils.GetEnv("PROSE_HOST", "0.0.0.0")
29 port := utils.GetEnv("PROSE_SSH_PORT", "2222")
30 promPort := utils.GetEnv("PROSE_PROM_PORT", "9222")
31 cfg := NewConfigSite(appName)
32 logger := cfg.Logger
33
34 ctx, cancel := context.WithCancel(context.Background())
35 defer cancel()
36
37 dbh := postgres.NewDB(cfg.DbURL, cfg.Logger)
38 defer dbh.Close()
39
40 hooks := &MarkdownHooks{
41 Cfg: cfg,
42 Db: dbh,
43 }
44
45 var st storage.StorageServe
46 var err error
47 if cfg.MinioURL == "" {
48 st, err = storage.NewStorageFS(cfg.Logger, cfg.StorageDir)
49 } else {
50 st, err = storage.NewStorageMinio(cfg.Logger, cfg.MinioURL, cfg.MinioUser, cfg.MinioPass)
51 }
52
53 if err != nil {
54 logger.Error("storage", "err", err.Error())
55 return
56 }
57
58 fileMap := map[string]filehandlers.ReadWriteHandler{
59 ".md": filehandlers.NewScpPostHandler(dbh, cfg, hooks),
60 ".css": filehandlers.NewScpPostHandler(dbh, cfg, hooks),
61 "fallback": uploadimgs.NewUploadImgHandler(dbh, cfg, st),
62 }
63 handler := filehandlers.NewFileHandlerRouter(cfg, dbh, fileMap)
64
65 sshAuth := shared.NewSshAuthHandler(dbh, logger)
66
67 // Create a new SSH server
68 server, err := pssh.NewSSHServerWithConfig(
69 ctx,
70 logger,
71 appName,
72 host,
73 port,
74 promPort,
75 "ssh_data/term_info_ed25519",
76 sshAuth.PubkeyAuthHandler,
77 []pssh.SSHServerMiddleware{
78 pipe.Middleware(handler, ".md"),
79 list.Middleware(handler),
80 scp.Middleware(handler),
81 rsync.Middleware(handler),
82 auth.Middleware(handler),
83 pssh.PtyMdw(pssh.DeprecatedNotice(), 200*time.Millisecond),
84 pssh.LogMiddleware(handler, dbh),
85 },
86 []pssh.SSHServerMiddleware{
87 sftp.Middleware(handler),
88 pssh.LogMiddleware(handler, dbh),
89 },
90 nil,
91 )
92
93 if err != nil {
94 logger.Error("failed to create ssh server", "err", err.Error())
95 os.Exit(1)
96 }
97
98 done := make(chan os.Signal, 1)
99 signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
100 logger.Info("Starting SSH server", "addr", server.Config.ListenAddr)
101 go func() {
102 if err = server.ListenAndServe(); err != nil {
103 logger.Error("serve", "err", err.Error())
104 os.Exit(1)
105 }
106 }()
107
108 exit := func() {
109 logger.Info("stopping ssh server")
110 cancel()
111 }
112
113 <-done
114 exit()
115}