tunnel

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Overview

Package tunnel implements secure access tunneling for plexd mesh nodes.

Index

Constants

View Source
const DefaultMaxSSHSessions = 10

DefaultMaxSSHSessions is the default maximum number of concurrent SSH sessions.

View Source
const DefaultMaxSessions = 10

DefaultMaxSessions is the default maximum number of concurrent tunnel sessions.

View Source
const DefaultSSHIdleTimeout = 30 * time.Minute

DefaultSSHIdleTimeout is the default idle timeout for SSH connections.

View Source
const DefaultTimeout = 30 * time.Minute

DefaultTimeout is the default session timeout.

Variables

This section is empty.

Functions

func GenerateHostKey

func GenerateHostKey() (ssh.Signer, error)

GenerateHostKey generates a new Ed25519 keypair and returns it as an ssh.Signer.

func HandleSSHSessionSetup

func HandleSSHSessionSetup(mgr *SessionManager, reporter TunnelReporter) api.EventHandler

HandleSSHSessionSetup returns an api.EventHandler for ssh_session_setup events. It parses the SSE payload, creates a tunnel session via the SessionManager, and reports readiness via the TunnelReporter.

func HandleSessionRevoked

func HandleSessionRevoked(mgr *SessionManager, reporter TunnelReporter) api.EventHandler

HandleSessionRevoked returns an api.EventHandler for session_revoked events. It looks up the session by ID and closes it with reason "revoked". Revoking a non-existent session is a no-op.

func LoadOrGenerateHostKey

func LoadOrGenerateHostKey(dataDir string, logger *slog.Logger) (ssh.Signer, error)

LoadOrGenerateHostKey loads an existing Ed25519 host key from dataDir, or generates and persists a new one if none exists.

Types

type ClosedSessionInfo

type ClosedSessionInfo struct {
	Duration time.Duration
}

ClosedSessionInfo contains metadata about a session that was closed.

type Config

type Config struct {
	// Enabled controls whether tunneling is active.
	// Default: true (set by ApplyDefaults).
	Enabled bool `yaml:"enabled"`

	// MaxSessions is the maximum number of concurrent tunnel sessions.
	// Default: 10
	MaxSessions int `yaml:"max_sessions"`

	// DefaultTimeout is the default/maximum session timeout.
	// Default: 30m
	DefaultTimeout time.Duration `yaml:"default_timeout"`

	// SSHListenAddr is the address for the SSH mesh server to listen on.
	// If empty, the SSH server is not started.
	SSHListenAddr string `yaml:"ssh_listen_addr"`

	// HostKeyDir is the directory for storing the SSH host key.
	// If empty, a transient key is generated (not persisted).
	HostKeyDir string `yaml:"host_key_dir"`
}

Config holds the configuration for secure access tunneling.

func (*Config) ApplyDefaults

func (c *Config) ApplyDefaults()

ApplyDefaults sets default values for zero-valued fields. On a zero-valued Config, Enabled defaults to true. To disable tunneling, set Enabled=false before or after calling ApplyDefaults.

func (*Config) Validate

func (c *Config) Validate() error

Validate checks that configuration values are within acceptable ranges.

type Ed25519JWTVerifier

type Ed25519JWTVerifier struct {
	// contains filtered or unexported fields
}

Ed25519JWTVerifier verifies compact JWS tokens (alg=EdDSA) using an Ed25519 public key. It validates the signature and checks the "exp" claim without relying on any external JWT library.

func NewEd25519JWTVerifier

func NewEd25519JWTVerifier(publicKey ed25519.PublicKey) *Ed25519JWTVerifier

NewEd25519JWTVerifier creates a new verifier with the given Ed25519 public key.

func (*Ed25519JWTVerifier) Verify

func (v *Ed25519JWTVerifier) Verify(token string) error

Verify validates a compact JWS token (header.payload.signature). It checks the Ed25519 signature over the signing input and verifies the "exp" claim has not elapsed.

type JWTVerifier

type JWTVerifier interface {
	Verify(token string) error
}

JWTVerifier validates JWT tokens for SSH authentication.

type K8sProxy

type K8sProxy struct {
	// contains filtered or unexported fields
}

K8sProxy is a reverse proxy that forwards HTTP requests to a Kubernetes API server.

func NewK8sProxy

func NewK8sProxy(targetURL string, tlsConfig *tls.Config, logger *slog.Logger) (*K8sProxy, error)

NewK8sProxy creates a K8sProxy targeting the given API server URL. If tlsConfig is non-nil, it is used for TLS connections to the API server.

func (*K8sProxy) Handler

func (p *K8sProxy) Handler() http.Handler

Handler returns the proxy as an http.Handler.

func (*K8sProxy) ServeHTTP

func (p *K8sProxy) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler, forwarding requests to the K8s API server.

type MeshServer

type MeshServer struct {
	// contains filtered or unexported fields
}

MeshServer composes the SSH mesh server with the existing SessionManager, managing their lifecycle together.

func NewMeshServer

func NewMeshServer(cfg Config, hostKey ssh.Signer, verifier JWTVerifier, logger *slog.Logger) *MeshServer

NewMeshServer creates a MeshServer that manages the SSH server and session manager. If cfg.SSHListenAddr is empty, the SSH server is not created.

func (*MeshServer) SSHServer

func (m *MeshServer) SSHServer() *SSHServer

SSHServer returns the underlying SSH server, or nil if not configured.

func (*MeshServer) SessionManager

func (m *MeshServer) SessionManager() *SessionManager

SessionManager returns the underlying session manager.

func (*MeshServer) Shutdown

func (m *MeshServer) Shutdown() error

Shutdown gracefully stops the mesh server. Ordering: close SSH listener first, then drain session manager.

func (*MeshServer) Start

func (m *MeshServer) Start(ctx context.Context) error

Start begins the SSH server (if configured) and returns.

type SSHServer

type SSHServer struct {
	// contains filtered or unexported fields
}

SSHServer is a mesh-facing SSH server that authenticates clients via JWT and provides direct-tcpip channel forwarding.

func NewSSHServer

func NewSSHServer(cfg SSHServerConfig, hostKey ssh.Signer, verifier JWTVerifier, logger *slog.Logger) *SSHServer

NewSSHServer creates a new SSHServer with the given configuration.

func (*SSHServer) Addr

func (s *SSHServer) Addr() string

Addr returns the listener address or empty string if not started.

func (*SSHServer) Shutdown

func (s *SSHServer) Shutdown() error

Shutdown gracefully stops the SSH server.

func (*SSHServer) Start

func (s *SSHServer) Start(ctx context.Context) error

Start begins listening for SSH connections on the configured address.

type SSHServerConfig

type SSHServerConfig struct {
	// MaxSessions is the maximum number of concurrent SSH sessions.
	// Default: 10
	MaxSessions int

	// IdleTimeout is the idle timeout for SSH connections.
	// Default: 30m
	IdleTimeout time.Duration

	// ListenAddr is the address to listen on (mesh IP + port).
	// Required.
	ListenAddr string
}

SSHServerConfig holds the configuration for the SSH mesh server.

func (*SSHServerConfig) ApplyDefaults

func (c *SSHServerConfig) ApplyDefaults()

ApplyDefaults sets default values for zero-valued fields.

func (*SSHServerConfig) Validate

func (c *SSHServerConfig) Validate() error

Validate checks that configuration values are within acceptable ranges.

type Session

type Session struct {
	SessionID  string
	TargetHost string
	TargetPort int
	MeshIP     string
	// contains filtered or unexported fields
}

Session represents an active tunnel session with a local TCP listener that forwards connections to a target host through the mesh.

func NewSession

func NewSession(sessionID, targetHost string, targetPort int, meshIP string, expiresAt time.Time, logger *slog.Logger) *Session

NewSession creates a Session with the given parameters.

func (*Session) Close

func (s *Session) Close() error

Close shuts down the session idempotently.

func (*Session) ListenAddr

func (s *Session) ListenAddr() string

ListenAddr returns the listener address or empty string if not started.

func (*Session) Start

func (s *Session) Start(ctx context.Context) (string, error)

Start opens a TCP listener bound to the mesh IP and begins accepting connections.

type SessionManager

type SessionManager struct {
	// contains filtered or unexported fields
}

SessionManager manages the lifecycle of tunnel sessions.

func NewSessionManager

func NewSessionManager(cfg Config, meshIP string, logger *slog.Logger) *SessionManager

NewSessionManager creates a new SessionManager with default config applied.

func (*SessionManager) ActiveCount

func (m *SessionManager) ActiveCount() int

ActiveCount returns the number of active sessions.

func (*SessionManager) CloseSession

func (m *SessionManager) CloseSession(sessionID, reason string) *ClosedSessionInfo

CloseSession closes and removes a session by ID. Returns session metadata if the session existed, or nil if not found.

func (*SessionManager) CreateSession

func (m *SessionManager) CreateSession(ctx context.Context, setup api.SSHSessionSetup) (string, error)

CreateSession creates and starts a new tunnel session.

func (*SessionManager) Shutdown

func (m *SessionManager) Shutdown()

Shutdown closes all active sessions. This is a local cleanup operation during node shutdown and does not report individual close events to the control plane — the control plane infers session loss from the node going offline (heartbeat timeout).

type TunnelReporter

type TunnelReporter interface {
	ReportReady(ctx context.Context, sessionID, listenAddr string)
	ReportClosed(ctx context.Context, sessionID, reason string, duration time.Duration)
}

TunnelReporter reports tunnel session lifecycle events to the control plane.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL