tunnel

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Sep 25, 2025 License: Apache-2.0 Imports: 15 Imported by: 1

README

tunnel

Go Reference

tunnel is a very simple library that allows you to create multi-hop SSH tunnels. From the endpointof the tunnel you can then Dial() to create network connections, or you can Listen() for incoming connections.

This library supports both using the SSH Agent to load any keys you might need as well as loading keys from files or from []byte slices in PEM format.

Per default the implementation will keep track of any connections or listeners you make. If you shut this off you have to manage the connections yourself. I recommend using the default behavior (library tracks connections).

You can create multiple connections through the same tunnel.

Usage Examples

Please have a look in the examples directory for some usage examples.

Typical use

Import

Add the following import and run go mod tidy to add tunnel to your project.

import "github.com/borud/tunnel"
Creating the tunnel

This example just creates a tunnel with two hops

tun, err := tunnel.Create(
  tunnel.WithHop("[email protected]"), 
  tunnel.WithHop("[email protected]"), 
  tunnel.WithAgent(), 
  tunnel.WithHostKeyCallback(ssh.InsecureIgnoreHostKey()),
)
Dial

You can Dial to create a new connection over the tunnel like so:

  conn, err := tun.Dial("tcp", "service.example.com:4711")

If everything went according to plan you now have a tunnel that terminates at second.example.com (since it is the last hop) and connects from there to port 4711 on service.example.com

Listen

You can also listen on the remote endpoint.

listener, err := tunnel.Listen("tcp", ":80")

A note on Listen ports

When you want to Listen to remote ports that should be externally available, you have to make sure that the SSH daemon is configured to allow this. Please review the GatewayPorts and AllowTcpForwarding configuration options in sshd_config. If you were too lazy to read this paragraph and are just looking for a cut and paste, the config is:

GatewayPorts yes
AllowTcpForwarding yes

Documentation

Overview

Package tunnel is a very simple library that allows you to create multi-hop SSH tunnels.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoHops = errors.New("no hops configured")
	ErrNoAuth = errors.New("no SSH auth methods configured")
	ErrClosed = errors.New("tunnel closed")
)

errors

Functions

This section is empty.

Types

type Config

type Config struct {
	Hops           []Hop
	Signers        []ssh.Signer
	UseAgent       bool
	KnownHostsPath string
	HostKeyCB      ssh.HostKeyCallback // global override (lowest priority: hop > global > path)
	PerHopTimeout  time.Duration
	KeepAlive      time.Duration
	TrackConns     bool
	Logger         *slog.Logger
}

Config contains the configuration for the tunnel.

type Hop added in v0.2.0

type Hop struct {
	User            string
	HostPort        string
	HostKeyCallback ssh.HostKeyCallback
	KnownHostsPath  string
	Timeout         time.Duration
}

Hop describes one SSH jump (user@host:port).

func ParseHop added in v0.2.0

func ParseHop(s string) (Hop, error)

ParseHop parses hop from string format.

func ParseHops added in v0.2.0

func ParseHops(hops []string) ([]Hop, error)

ParseHops parses multiple hops from their string representations.

type Option added in v0.2.0

type Option func(*Config) error

Option is a configuration option

func WithAgent added in v0.2.0

func WithAgent() Option

WithAgent enables using the SSH agent for authentication, if SSH_AUTH_SOCK is set. If no agent is available, no agent auth method will be added.

func WithConnTracking added in v0.2.0

func WithConnTracking(enable bool) Option

WithConnTracking enables or disables connection tracking. When enabled, Tunnel.Close() will also close any Conns or Listeners created by the tunnel.

func WithHop added in v0.2.0

func WithHop(s string) Option

WithHop adds a single hop in "user@host:port" form. If port is omitted, defaults to :22. If user is omitted, the current user is used.

func WithHops added in v0.2.0

func WithHops(hops ...Hop) Option

WithHops adds multiple pre-parsed Hop objects to the configuration.

func WithHostKeyCallback added in v0.2.0

func WithHostKeyCallback(cb ssh.HostKeyCallback) Option

WithHostKeyCallback sets a custom ssh.HostKeyCallback for host key verification. This overrides known_hosts file configuration.

func WithKeepAlive added in v0.2.0

func WithKeepAlive(d time.Duration) Option

WithKeepAlive sets the interval for sending SSH keep-alive requests to each hop. Use 0 to disable keep-alives. Default is 30 seconds.

func WithKey added in v0.2.0

func WithKey(pemBytes []byte, passphrase []byte) Option

WithKey parses a private key from in-memory PEM data and adds it as an ssh.Signer. If passphrase is non-nil, it is used to decrypt the key.

func WithKeyFile added in v0.2.0

func WithKeyFile(path string, passphrase []byte) Option

WithKeyFile loads a private key from a PEM file on disk and adds it as an ssh.Signer. If passphrase is non-nil, it is used to decrypt the key.

func WithKnownHosts added in v0.2.0

func WithKnownHosts(path string) Option

WithKnownHosts sets the path to a known_hosts file for host key verification. If not provided, defaults to ~/.ssh/known_hosts.

func WithLogger added in v0.2.0

func WithLogger(l *slog.Logger) Option

WithLogger replaces the default slog.Logger with a custom logger.

func WithPerHopTimeout added in v0.2.0

func WithPerHopTimeout(d time.Duration) Option

WithPerHopTimeout sets the timeout used when dialing each SSH hop. Defaults to 10 seconds.

func WithSigner added in v0.2.0

func WithSigner(s ssh.Signer) Option

WithSigner adds an in-memory ssh.Signer (private key) to be used for authentication.

func WithoutAgent added in v0.2.0

func WithoutAgent() Option

WithoutAgent disables SSH agent usage, even if SSH_AUTH_SOCK is set.

type Tunnel

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

Tunnel implements an SSH tunneling helper.

func Create

func Create(opts ...Option) (*Tunnel, error)

Create a new tunnel

func (*Tunnel) Close added in v0.2.0

func (t *Tunnel) Close() error

Close closes all clients, tracked conns, and listeners.

func (*Tunnel) Dial

func (t *Tunnel) Dial(network, addr string) (net.Conn, error)

Dial dials a remote address through the tunnel using a background context.

func (*Tunnel) DialContext added in v0.2.0

func (t *Tunnel) DialContext(ctx context.Context, network, addr string) (net.Conn, error)

DialContext dials a remote address through the tunnel.

func (*Tunnel) Listen

func (t *Tunnel) Listen(network, laddr string) (net.Listener, error)

Listen starts a remote listener on the last hop using a background context.

func (*Tunnel) ListenContext added in v0.2.0

func (t *Tunnel) ListenContext(ctx context.Context, network, laddr string) (net.Listener, error)

ListenContext asks the last hop in the tunnel to start listening on laddr. Example: ("tcp", "0.0.0.0:8080") will bind a TCP listener on the remote side. The returned net.Listener accepts connections forwarded back through the tunnel.

For remote listening to work, the SSH server on the last hop must allow it: GatewayPorts yes and AllowTcpForwarding yes in sshd_config.

func (*Tunnel) LocalForward added in v0.2.0

func (t *Tunnel) LocalForward(ctx context.Context, laddr, raddr string) (net.Listener, error)

LocalForward listens locally and forwards to a remote address via the tunnel.

Directories

Path Synopsis
examples
http-multihop command
Package main implements a multihop example
Package main implements a multihop example
http-simple command
Package main implements a simple example of a tunneled HTTP client.
Package main implements a simple example of a tunneled HTTP client.
http-with-key command
Package main shows how you can use an SSH key rather than SSH Agent.
Package main shows how you can use an SSH key rather than SSH Agent.

Jump to

Keyboard shortcuts

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