main pico / pkg / apps / feeds / ssh.go
Antonio Mika  ·  2026-10-10
 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/pssh"
11	"github.com/picosh/pico/pkg/send/auth"
12	"github.com/picosh/pico/pkg/send/list"
13	"github.com/picosh/pico/pkg/send/pipe"
14	"github.com/picosh/pico/pkg/send/protocols/rsync"
15	"github.com/picosh/pico/pkg/send/protocols/scp"
16	"github.com/picosh/pico/pkg/send/protocols/sftp"
17	"github.com/picosh/pico/pkg/shared"
18)
19
20func StartSshServer() {
21	appName := "feeds-ssh"
22
23	host := shared.GetEnv("FEEDS_HOST", "0.0.0.0")
24	port := shared.GetEnv("FEEDS_SSH_PORT", "2222")
25	promPort := shared.GetEnv("FEEDS_PROM_PORT", "9222")
26	cfg := NewConfig(appName)
27	logger := cfg.Logger
28
29	ctx, cancel := context.WithCancel(context.Background())
30	defer cancel()
31
32	dbh := NewDB(postgres.NewDB(cfg.DbURL, cfg.Logger))
33	defer func() {
34		_ = dbh.Close()
35	}()
36
37	handler := NewUploadHandler(cfg, dbh)
38
39	sshAuth := shared.NewSshAuthHandler(dbh, logger, "feeds")
40
41	// Create a new SSH server
42	server, err := pssh.NewSSHServerWithConfig(
43		ctx,
44		logger,
45		appName,
46		host,
47		port,
48		promPort,
49		"ssh_data/term_info_ed25519",
50		sshAuth.PubkeyAuthHandler,
51		[]pssh.SSHServerMiddleware{
52			pipe.Middleware(handler, ".txt"),
53			list.Middleware(handler),
54			scp.Middleware(handler),
55			rsync.Middleware(handler),
56			auth.Middleware(handler),
57			Middleware(dbh, cfg),
58			pssh.LogMiddleware(handler, dbh),
59		},
60		[]pssh.SSHServerMiddleware{
61			sftp.Middleware(handler),
62			pssh.LogMiddleware(handler, dbh),
63		},
64		nil,
65	)
66
67	if err != nil {
68		logger.Error("failed to create ssh server", "err", err.Error())
69		os.Exit(1)
70	}
71
72	done := make(chan os.Signal, 1)
73
74	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
75	logger.Info("Starting SSH server", "addr", server.Config.ListenAddr)
76	go func() {
77		if err = server.ListenAndServe(); err != nil {
78			logger.Error("serve", "err", err.Error())
79			os.Exit(1)
80		}
81	}()
82
83	exit := func() {
84		logger.Info("stopping ssh server")
85		cancel()
86	}
87
88	<-done
89	exit()
90}