easyssh

package module
v1.5.2 Latest Latest
Warning

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

Go to latest
Published: Oct 10, 2025 License: MIT Imports: 15 Imported by: 55

README

easyssh-proxy

GoDoc Lint and Testing codecov Go Report Card Sourcegraph

繁體中文

easyssh-proxy provides a simple implementation of some SSH protocol features in Go.

Feature

This project is forked from easyssh but add some features as the following.

  • Support plain text of user private key.
  • Support key path of user private key.
  • Support Timeout for the TCP connection to establish.
  • Support SSH ProxyCommand.
     +--------+       +----------+      +-----------+
     | Laptop | <-->  | Jumphost | <--> | FooServer |
     +--------+       +----------+      +-----------+

                         OR

     +--------+       +----------+      +-----------+
     | Laptop | <-->  | Firewall | <--> | FooServer |
     +--------+       +----------+      +-----------+
     192.168.1.5       121.1.2.3         10.10.29.68

Installation

go get github.com/appleboy/easyssh-proxy

Requirements: Go 1.24 or higher

Usage

You can see detailed examples of the ssh, scp, Proxy, and stream commands inside the examples folder.

MakeConfig

All functionality provided by this package is accessed via methods of the MakeConfig struct.

  ssh := &easyssh.MakeConfig{
    User:    "drone-scp",
    Server:  "localhost",
    KeyPath: "./tests/.ssh/id_rsa",
    Port:    "22",
    Timeout: 60 * time.Second,
  }

  stdout, stderr, done, err := ssh.Run("ls -al", 60*time.Second)
  err = ssh.Scp("/root/source.csv", "/tmp/target.csv")
  stdoutChan, stderrChan, doneChan, errChan, err = ssh.Stream("for i in {1..5}; do echo ${i}; sleep 1; done; exit 2;", 60*time.Second)

MakeConfig takes in the following properties:

property description
user The SSH user to be logged in with
Server The IP or hostname pointing of the server
Key A string containing the private key to be used when making the connection
KeyPath The path pointing to the SSH key file to be used when making the connection
Port The port to use when connecting to the SSH daemon of the server
Protocol The tcp protocol to be used: "tcp", "tcp4" "tcp6"
Passphrase The Passphrase to unlock the provided SSH key (leave blank if no Passphrase is required)
Password The Password to use to login the specified user
Timeout The length of time to wait before timing out the request
Proxy An additional set of configuration params that will be used to SSH into an additional server via the server configured in this top-level block
Ciphers An array of ciphers (e.g. aes256-ctr) to enable for the SSH connection
KeyExchanges An array of key exchanges (e.g. ecdh-sha2-nistp384) to enable for the SSH connection
Fingerprint The expected fingerprint to be returned by the SSH server, results in a fingerprint error if they do not match
UseInsecureCipher Enables the use of insecure ciphers and key exchanges that are insecure and can lead to compromise, see ssh

NOTE: Please view the reference documentation for the most up to date properties of MakeConfig and DefaultConfig

ssh

See examples/ssh/ssh.go

package main

import (
  "fmt"
  "time"

  "github.com/appleboy/easyssh-proxy"
)

func main() {
  // Create MakeConfig instance with remote username, server address and path to private key.
  ssh := &easyssh.MakeConfig{
    User:   "appleboy",
    Server: "example.com",
    // Optional key or Password without either we try to contact your agent SOCKET
    // Password: "password",
    // Paste your source content of private key
    // Key: `-----BEGIN RSA PRIVATE KEY-----
    // MIIEpAIBAAKCAQEA4e2D/qPN08pzTac+a8ZmlP1ziJOXk45CynMPtva0rtK/RB26
    // 7XC9wlRna4b3Ln8ew3q1ZcBjXwD4ppbTlmwAfQIaZTGJUgQbdsO9YA==
    // -----END RSA PRIVATE KEY-----
    // `,
    KeyPath: "/Users/username/.ssh/id_rsa",
    Port:    "22",
    Timeout: 60 * time.Second,

    // Parse PrivateKey With Passphrase
    Passphrase: "1234",

    // Optional fingerprint SHA256 verification
    // Get Fingerprint: ssh.FingerprintSHA256(key)
    // Fingerprint: "SHA256:mVPwvezndPv/ARoIadVY98vAC0g+P/5633yTC4d/wXE"

    // Enable the use of insecure ciphers and key exchange methods.
    // This enables the use of the the following insecure ciphers and key exchange methods:
    // - aes128-cbc
    // - aes192-cbc
    // - aes256-cbc
    // - 3des-cbc
    // - diffie-hellman-group-exchange-sha256
    // - diffie-hellman-group-exchange-sha1
    // Those algorithms are insecure and may allow plaintext data to be recovered by an attacker.
    // UseInsecureCipher: true,
  }

  // Call Run method with command you want to run on remote server.
  stdout, stderr, done, err := ssh.Run("ls -al", 60*time.Second)
  // Handle errors
  if err != nil {
    panic("Can't run remote command: " + err.Error())
  } else {
    fmt.Println("don is :", done, "stdout is :", stdout, ";   stderr is :", stderr)
  }
}
scp

See examples/scp/scp.go

package main

import (
  "fmt"

  "github.com/appleboy/easyssh-proxy"
)

func main() {
  // Create MakeConfig instance with remote username, server address and path to private key.
  ssh := &easyssh.MakeConfig{
    User:     "appleboy",
    Server:   "example.com",
    Password: "123qwe",
    Port:     "22",
  }

  // Call Scp method with file you want to upload to remote server.
  // Please make sure the `tmp` floder exists.
  err := ssh.Scp("/root/source.csv", "/tmp/target.csv")

  // Handle errors
  if err != nil {
    panic("Can't run remote command: " + err.Error())
  } else {
    fmt.Println("success")
  }
}
SSH ProxyCommand

See examples/proxy/proxy.go

  ssh := &easyssh.MakeConfig{
    User:    "drone-scp",
    Server:  "localhost",
    Port:    "22",
    KeyPath: "./tests/.ssh/id_rsa",
    Timeout: 60 * time.Second,
    Proxy: easyssh.DefaultConfig{
      User:    "drone-scp",
      Server:  "localhost",
      Port:    "22",
      KeyPath: "./tests/.ssh/id_rsa",
      Timeout: 60 * time.Second,
    },
  }

NOTE: Properties for the Proxy connection are not inherited from the Jumphost. You must explicitly specify them in the DefaultConfig struct.

e.g. A custom Timeout length must be specified for both the Jumphost (intermediary server) and the destination server.

SSH Stream Log

See examples/stream/stream.go

func main() {
  // Create MakeConfig instance with remote username, server address and path to private key.
  ssh := &easyssh.MakeConfig{
    Server:  "localhost",
    User:    "drone-scp",
    KeyPath: "./tests/.ssh/id_rsa",
    Port:    "22",
    Timeout: 60 * time.Second,
  }

  // Call Run method with command you want to run on remote server.
  stdoutChan, stderrChan, doneChan, errChan, err := ssh.Stream("for i in {1..5}; do echo ${i}; sleep 1; done; exit 2;", 60*time.Second)
  // Handle errors
  if err != nil {
    panic("Can't run remote command: " + err.Error())
  } else {
    // read from the output channel until the done signal is passed
    isTimeout := true
  loop:
    for {
      select {
      case isTimeout = <-doneChan:
        break loop
      case outline := <-stdoutChan:
        fmt.Println("out:", outline)
      case errline := <-stderrChan:
        fmt.Println("err:", errline)
      case err = <-errChan:
      }
    }

    // get exit code or command error.
    if err != nil {
      fmt.Println("err: " + err.Error())
    }

    // command time out
    if !isTimeout {
      fmt.Println("Error: command timeout")
    }
  }
}
WriteFile

See examples/writeFile/writeFile.go

func (ssh_conf *MakeConfig) WriteFile(reader io.Reader, size int64, etargetFile string) error
func main() {
  // Create MakeConfig instance with remote username, server address and path to private key.
  ssh := &easyssh.MakeConfig{
    Server:  "localhost",
    User:    "drone-scp",
    KeyPath: "./tests/.ssh/id_rsa",
    Port:    "22",
    Timeout: 60 * time.Second,
  }

  fileContents := "Example Text..."
  reader := strings.NewReader(fileContents)

  // Write a file to the remote server using the writeFile command.
  // Second argument specifies the number of bytes to write to the server from the reader.
  if err := ssh.WriteFile(reader, int64(len(fileContents)), "/home/user/foo.txt"); err != nil {
    return fmt.Errorf("Error: failed to write file to client. error: %w", err)
  }
}
property description
reader The io.reader who's contents will be read and saved to the server
size The number of bytes to be read from the io.reader
etargetFile The location on the server that the file will be written to

Documentation

Overview

Package easyssh provides a simple implementation of some SSH protocol features in Go. You can simply run a command on a remote server or get a file even simpler than native console SSH client. You don't need to think about Dials, sessions, defers, or public keys... Let easyssh think about it!

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrProxyDialTimeout is returned when proxy dial connection times out
	ErrProxyDialTimeout = errors.New("proxy dial timeout")
)

Functions

This section is empty.

Types

type DefaultConfig

type DefaultConfig struct {
	User         string
	Server       string
	Key          string
	KeyPath      string
	Port         string
	Protocol     Protocol
	Passphrase   string
	Password     string
	Timeout      time.Duration
	Ciphers      []string
	KeyExchanges []string
	Fingerprint  string

	// Enable the use of insecure ciphers and key exchange methods.
	// This enables the use of the the following insecure ciphers and key exchange methods:
	// - aes128-cbc
	// - aes192-cbc
	// - aes256-cbc
	// - 3des-cbc
	// - diffie-hellman-group-exchange-sha256
	// - diffie-hellman-group-exchange-sha1
	// Those algorithms are insecure and may allow plaintext data to be recovered by an attacker.
	UseInsecureCipher bool
}

DefaultConfig for ssh proxy config

type MakeConfig

type MakeConfig struct {
	User         string
	Server       string
	Key          string
	KeyPath      string
	Port         string
	Protocol     Protocol
	Passphrase   string
	Password     string
	Timeout      time.Duration
	Proxy        DefaultConfig
	ReadBuffSize int
	Ciphers      []string
	KeyExchanges []string
	Fingerprint  string

	// Enable the use of insecure ciphers and key exchange methods.
	// This enables the use of the the following insecure ciphers and key exchange methods:
	// - aes128-cbc
	// - aes192-cbc
	// - aes256-cbc
	// - 3des-cbc
	// - diffie-hellman-group-exchange-sha256
	// - diffie-hellman-group-exchange-sha1
	// Those algorithms are insecure and may allow plaintext data to be recovered by an attacker.
	UseInsecureCipher bool

	// RequestPty requests a pseudo-terminal from the server.
	RequestPty bool
}

MakeConfig Contains main authority information. User field should be a name of user on remote server (ex. john in ssh [email protected]). Server field should be a remote machine address (ex. example.com in ssh [email protected]) Key is a path to private key on your local machine. Port is SSH server port on remote machine. Note: easyssh looking for private key in user's home directory (ex. /home/john + Key). Then ensure your Key begins from '/' (ex. /.ssh/id_rsa)

func (*MakeConfig) Connect

func (ssh_conf *MakeConfig) Connect() (*ssh.Session, *ssh.Client, error)

Connect to remote server using MakeConfig struct and returns *ssh.Session

func (*MakeConfig) Run

func (ssh_conf *MakeConfig) Run(command string, timeout ...time.Duration) (outStr string, errStr string, isTimeout bool, err error)

Run command on remote machine and returns its stdout as a string

func (*MakeConfig) Scp

func (ssh_conf *MakeConfig) Scp(sourceFile string, etargetFile string) error

Scp uploads sourceFile to remote machine like native scp console app.

func (*MakeConfig) Stream

func (ssh_conf *MakeConfig) Stream(command string, timeout ...time.Duration) (<-chan string, <-chan string, <-chan bool, <-chan error, error)

Stream returns one channel that combines the stdout and stderr of the command as it is run on the remote machine, and another that sends true when the command is done. The sessions and channels will then be closed.

func (*MakeConfig) WriteFile added in v1.3.10

func (ssh_conf *MakeConfig) WriteFile(reader io.Reader, size int64, etargetFile string) error

WriteFile reads size bytes from the reader and writes them to a file on the remote machine

type Protocol added in v1.4.0

type Protocol string
const (
	PROTOCOL_TCP  Protocol = "tcp"
	PROTOCOL_TCP4 Protocol = "tcp4"
	PROTOCOL_TCP6 Protocol = "tcp6"
)

Jump to

Keyboard shortcuts

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