repos / pico

pico services mono repo
git clone https://github.com/picosh/pico.git

pico / pkg / apps / pgs
Antonio Mika  ·  2025-03-30

ssh.go

 1package pgs
 2
 3import (
 4	"context"
 5	"os"
 6	"os/signal"
 7	"syscall"
 8
 9	"github.com/picosh/pico/pkg/pssh"
10	"github.com/picosh/pico/pkg/send/auth"
11	"github.com/picosh/pico/pkg/send/list"
12	"github.com/picosh/pico/pkg/send/pipe"
13	"github.com/picosh/pico/pkg/send/protocols/rsync"
14	"github.com/picosh/pico/pkg/send/protocols/scp"
15	"github.com/picosh/pico/pkg/send/protocols/sftp"
16	"github.com/picosh/pico/pkg/shared"
17	"github.com/picosh/pico/pkg/tunkit"
18	"github.com/picosh/utils"
19)
20
21func StartSshServer(cfg *PgsConfig, killCh chan error) {
22	host := utils.GetEnv("PGS_HOST", "0.0.0.0")
23	port := utils.GetEnv("PGS_SSH_PORT", "2222")
24	promPort := utils.GetEnv("PGS_PROM_PORT", "9222")
25	logger := cfg.Logger
26
27	ctx, cancel := context.WithCancel(context.Background())
28	defer cancel()
29
30	cacheClearingQueue := make(chan string, 100)
31	handler := NewUploadAssetHandler(
32		cfg,
33		cacheClearingQueue,
34		ctx,
35	)
36
37	sshAuth := shared.NewSshAuthHandler(cfg.DB, logger)
38
39	webTunnel := &tunkit.WebTunnelHandler{
40		Logger:      logger,
41		HttpHandler: createHttpHandler(cfg),
42	}
43
44	// Create a new SSH server
45	server, err := pssh.NewSSHServerWithConfig(
46		ctx,
47		logger,
48		"pgs-ssh",
49		host,
50		port,
51		promPort,
52		"ssh_data/term_info_ed25519",
53		sshAuth.PubkeyAuthHandler,
54		[]pssh.SSHServerMiddleware{
55			pipe.Middleware(handler, ""),
56			list.Middleware(handler),
57			scp.Middleware(handler),
58			rsync.Middleware(handler),
59			auth.Middleware(handler),
60			Middleware(handler),
61			pssh.LogMiddleware(handler, handler.Cfg.DB),
62		},
63		[]pssh.SSHServerMiddleware{
64			sftp.Middleware(handler),
65			pssh.LogMiddleware(handler, handler.Cfg.DB),
66		},
67		map[string]pssh.SSHServerChannelMiddleware{
68			"direct-tcpip": tunkit.LocalForwardHandler(webTunnel),
69		},
70	)
71
72	if err != nil {
73		logger.Error("failed to create ssh server", "err", err.Error())
74		os.Exit(1)
75	}
76
77	done := make(chan os.Signal, 1)
78	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
79	logger.Info("Starting SSH server", "addr", server.Config.ListenAddr)
80	go func() {
81		if err = server.ListenAndServe(); err != nil {
82			logger.Error("serve", "err", err.Error())
83			os.Exit(1)
84		}
85	}()
86
87	exit := func() {
88		logger.Info("stopping ssh server")
89		cancel()
90	}
91
92	select {
93	case <-killCh:
94		exit()
95	case <-done:
96		exit()
97	}
98}