qssh

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2025 License: MIT Imports: 12 Imported by: 1

README

QSSH - QUIC SSH Proxy

QSSH is a Go library and tool that provides SSH connections over QUIC transport, improving SSH reliability and performance over low-quality network connections.

Features

  • Better performance over unreliable networks compared to traditional TCP-based SSH
  • mTLS support
  • SSH ProxyCommand support
  • Works with existing SSH authentication methods. Client library returns a standard ssh.Client making it easy to use with existing packages transparently.

QSSH Server

QSSH requires a compatible QSSH server running on the target node. The server acts as the QUIC-to-SSH proxy and forwards connections to the local SSH daemon.

Installing the Server

Get the latest release from releases. You can use the provided systemd unit file to install QSSH server as a systemd service. Just place the qssh-server binary in /usr/local/bin/qssh-server and the config file in /etc/qssh-config.toml.

Server Configuration

The server uses a TOML configuration file. Create a config.toml file based on the example:

[server]
# QUIC server listen address
quic_addr = ":4433"

# SSH server to forward connections to
ssh_addr = "127.0.0.1:22"

[tls]
cert_file = "/etc/qssh/server.crt"
key_file = "/etc/qssh/server.key"

# If generate_certs is true, if the cert and key file don't exist, they will be generated
generate_certs = true

# Optional: Enable mutual TLS (mTLS) for client authentication
# client_ca = "/etc/qssh/client-ca.crt"
# require_mtls = false

[quic]
max_idle_timeout = 30
max_incoming_streams = 100
keep_alive_period = 10
Running the Server
./server -config-file /path/to/config.toml

Usage as a Library

Basic SSH Client
package main

import (
    "log"
    "github.com/cvhariharan/qssh"
)

func main() {
    config := qssh.PasswordConfig("user", "password")
    client, conn, err := qssh.Dial("server:8080", config)
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()
    defer conn.Close()

    // Use the SSH client as normal
    session, err := client.NewSession()
    if err != nil {
        log.Fatal(err)
    }
    defer session.Close()

    output, err := session.Output("ls -la")
    if err != nil {
        log.Fatal(err)
    }

    log.Println(string(output))
}
Public Key Authentication
privateKey, err := ssh.ParsePrivateKey(keyBytes)
if err != nil {
    log.Fatal(err)
}

config := qssh.KeyConfig("user", privateKey)
client, conn, err := qssh.Dial("server:8080", config)
mTLS Configuration
config := qssh.PasswordConfig("user", "password")
err := config.WithClientCert("client.crt", "client.key")
if err != nil {
    log.Fatal(err)
}
err = config.WithServerCA("server-ca.crt")
if err != nil {
    log.Fatal(err)
}

client, conn, err := qssh.Dial("server:8080", config)
As SSH ProxyCommand

Download the latest release from releases and extract the qssh-client binary.

Configure SSH to use QSSH client as a proxy:

# ~/.ssh/config
Host myserver
    ProxyCommand /usr/local/bin/qssh-client qssh-server.example.com:4433
    Hostname target-server.internal

Connect using SSH

ssh myserver
Proxy Mode

Use QSSH in proxy mode to tunnel connections. qssh.Proxy can tunnel any io.Reader and io.Writer.

err := qssh.Proxy(ctx, "proxy-server:8080", qssh.ProxyConfig{
    TLSConfig: &tls.Config{InsecureSkipVerify: true},
}, os.Stdin, os.Stdout)

Documentation

Overview

Package qssh provides a QUIC-based SSH client implementation.

A QSSH server should be running on the target node. This package allows establishing SSH connections over QUIC. The main purpose of this package is to improve SSH reliability over low network conditions. It supports both direct SSH client connections and proxy mode for SSH tunneling.

Basic usage:

config := qssh.PasswordConfig("user", "password")
client, conn, err := qssh.Dial("server:8080", config)
if err != nil {
    log.Fatal(err)
}
defer client.Close()
defer conn.Close()

Proxy usage:

err := qssh.Proxy(ctx, "proxy-server:8080", qssh.ProxyConfig{
    TLSConfig: &tls.Config{InsecureSkipVerify: true},
}, os.Stdin, os.Stdout)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Proxy

func Proxy(ctx context.Context, addr string, config ProxyConfig, r io.Reader, w io.Writer) error

Types

type Config

type Config struct {
	// SSH configuration
	SSHConfig *ssh.ClientConfig

	// TLS configuration for QUIC
	TLSConfig *tls.Config

	QUICConfig *quic.Config

	DialTimeout time.Duration
}

func DefaultConfig

func DefaultConfig(user string, auth []ssh.AuthMethod) Config

DefaultConfig returns a configuration with sensible defaults

func KeyConfig

func KeyConfig(user string, privateKey ssh.Signer) Config

KeyConfig creates a config with public key authentication

func PasswordConfig

func PasswordConfig(user, password string) Config

PasswordConfig creates a config with password authentication

func (*Config) WithClientCert

func (c *Config) WithClientCert(certFile, keyFile string) error

WithClientCert adds client certificate authentication to the TLS config for mTLS

func (*Config) WithServerCA

func (c *Config) WithServerCA(caFile string) error

WithServerCA adds server CA verification to the TLS config

type ProxyConfig

type ProxyConfig struct {
	TLSConfig  *tls.Config
	QUICConfig *quic.Config

	DialTimeout time.Duration
}

type QSSHConnection

type QSSHConnection struct {
	*quic.Stream
	// contains filtered or unexported fields
}

func Dial

func Dial(addr string, config Config) (*ssh.Client, *QSSHConnection, error)

Dial connects to the QSSH server and returns an ssh.Client and QSSH connection. Both ssh.Client and QSSH connection should be closed by the caller.

func DialContext

func DialContext(ctx context.Context, addr string, config Config) (*ssh.Client, *QSSHConnection, error)

DialContext connects to the QSSH server using the provided context and returns an ssh.Client and QSSH connection. Both ssh.Client and QSSH connection should be closed by the caller.

func (QSSHConnection) Close

func (q QSSHConnection) Close() error

func (QSSHConnection) LocalAddr

func (q QSSHConnection) LocalAddr() net.Addr

func (QSSHConnection) RemoteAddr

func (q QSSHConnection) RemoteAddr() net.Addr

Directories

Path Synopsis
cmd
client command
Package main implements a QSSH client that acts as an SSH ProxyCommand.
Package main implements a QSSH client that acts as an SSH ProxyCommand.
server module

Jump to

Keyboard shortcuts

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