sshlib

package module
Version: v0.1.10 Latest Latest
Warning

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

Go to latest
Published: Jun 9, 2022 License: MIT Imports: 33 Imported by: 2

README

go-sshlib

GoDoc

About

A library to handle ssh easily with Golang.It can do multiple proxy, x11 forwarding, etc. Supported on Linux, macOS and Windows.

If use pkcs11 authentication, cgo must be enabled.

Usage

See GoDoc reference.

Download

GO111MODULE=on go get github.com/blacknon/go-sshlib

Example

// Copyright (c) 2022 Blacknon. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.

// Shell connection Example file.
// Change the value of the variable and compile to make sure that you can actually connect.
//
// This file uses password authentication. Please replace as appropriate.

package main

import (
    "fmt"
    "os"

    sshlib "github.com/blacknon/go-sshlib"
    "golang.org/x/crypto/ssh"
)

var (
    host     = "target.com"
    port     = "22"
    user     = "user"
    password = "password"

    termlog = "./test_termlog"
)

func main() {
    // Create sshlib.Connect
    con := &sshlib.Connect{
        // If you use x11 forwarding, please set to true.
        ForwardX11: false,

        // If you use ssh-agent forwarding, please set to true.
        // And after, run `con.ConnectSshAgent()`.
        ForwardAgent: false,
    }

    // Create ssh.AuthMethod
    authMethod := sshlib.CreateAuthMethodPassword(password)

    // If you use ssh-agent forwarding, uncomment it.
    // con.ConnectSshAgent()

    // Connect ssh server
    err := con.CreateClient(host, port, user, []ssh.AuthMethod{authMethod})
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    // Set terminal log
    con.SetLog(termlog, false)

    // Create Session
    session, err := con.CreateSession()
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    // Start ssh shell
    con.Shell(session)
}

Documentation

Overview

Package sshlib is a library to easily connect with ssh by go. You can perform multiple proxy, x11 forwarding, PKCS11 authentication, etc...

Example simple ssh shell

It is example code. simple connect ssh shell. You can also do tab completion, send sigint signal(Ctrl+C).

package main

import (
	"fmt"
	"os"

	sshlib "github.com/blacknon/go-sshlib"
	"golang.org/x/crypto/ssh"
)

var (
	host     = "target.com"
	port     = "22"
	user     = "user"
	password = "password"

	termlog = "./test_termlog"
)

func main() {
	// Create sshlib.Connect
	con := &sshlib.Connect{
		// If you use x11 forwarding, please set to true.
		ForwardX11: false,

		// If you use ssh-agent forwarding, please set to true.
		// And after, run `con.ConnectSshAgent()`.
		ForwardAgent: false,
	}

	// Create ssh.AuthMethod
	authMethod := sshlib.CreateAuthMethodPassword(password)

	// If you use ssh-agent forwarding, uncomment it.
	// con.ConnectSshAgent()

	// Connect ssh server
	err := con.CreateClient(host, port, user, []ssh.AuthMethod{authMethod})
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// Set terminal log
	con.SetLog(termlog, false)

	// Start ssh shell
	con.Shell()
}

Example simple ssh proxy shell

Multple proxy by ssh connection is also available. Please refer to the sample code for usage with http and socks5 proxy.

package main

import (
	"fmt"
	"os"

	sshlib "github.com/blacknon/go-sshlib"
	"golang.org/x/crypto/ssh"
)

var (
	// Proxy ssh server
	host1     = "proxy.com"
	port1     = "22"
	user1     = "user"
	password1 = "password"

	// Target ssh server
	host2     = "target.com"
	port2     = "22"
	user2     = "user"
	password2 = "password"

	termlog = "./test_termlog"
)

func main() {
	// ==========
	// proxy connect
	// ==========

	// Create proxy sshlib.Connect
	proxyCon := &sshlib.Connect{}

	// Create proxy ssh.AuthMethod
	proxyAuthMethod := sshlib.CreateAuthMethodPassword(password1)

	// Connect proxy server
	err := proxyCon.CreateClient(host1, port1, user1, []ssh.AuthMethod{proxyAuthMethod})
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// ==========
	// target connect
	// ==========

	// Create target sshlib.Connect
	targetCon := &sshlib.Connect{
		ProxyDialer: proxyCon.Client,
	}

	// Create target ssh.AuthMethod
	targetAuthMethod := sshlib.CreateAuthMethodPassword(password2)

	// Connect target server
	err = targetCon.CreateClient(host2, port2, user2, []ssh.AuthMethod{targetAuthMethod})
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// Set terminal log
	targetCon.SetLog(termlog, false)

	// Start ssh shell
	targetCon.Shell()
}

This library was created for my ssh client (https://github.com/blacknon/lssh)

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func CreateAuthMethodCertificate

func CreateAuthMethodCertificate(cert string, keySigner ssh.Signer) (auth ssh.AuthMethod, err error)

CreateAuthMethodCertificate returns ssh.AuthMethod generated from Certificate. To generate an AuthMethod from a certificate, you will need the certificate's private key Signer. Signer should be generated from CreateSignerPublicKey() or CreateSignerPKCS11().

func CreateAuthMethodPKCS11

func CreateAuthMethodPKCS11(provider, pin string) (auth []ssh.AuthMethod, err error)

CreateAuthMethodPKCS11 return []ssh.AuthMethod generated from pkcs11 token. PIN is required to generate a AuthMethod from a PKCS 11 token. Not available if cgo is disabled.

WORNING: Does not work if multiple tokens are stuck at the same time.

func CreateAuthMethodPassword

func CreateAuthMethodPassword(password string) (auth ssh.AuthMethod)

CreateAuthMethodPassword returns ssh.AuthMethod generated from password.

func CreateAuthMethodPublicKey

func CreateAuthMethodPublicKey(key, password string) (auth ssh.AuthMethod, err error)

CreateAuthMethodPublicKey returns ssh.AuthMethod generated from PublicKey. If you have not specified a passphrase, please specify a empty character("").

func CreateSignerAgent added in v0.1.1

func CreateSignerAgent(sshAgent interface{}) (signers []ssh.Signer, err error)

CreateSignerAgent return []ssh.Signer from ssh-agent. In sshAgent, put agent.Agent or agent.ExtendedAgent.

func CreateSignerCertificate

func CreateSignerCertificate(cert string, keySigner ssh.Signer) (certSigner ssh.Signer, err error)

CreateSignerCertificate returns ssh.Signer generated from Certificate. To generate an AuthMethod from a certificate, you will need the certificate's private key Signer. Signer should be generated from CreateSignerPublicKey() or CreateSignerPKCS11().

func CreateSignerPKCS11

func CreateSignerPKCS11(provider, pin string) (signers []ssh.Signer, err error)

CreateSignerPKCS11 returns []ssh.Signer generated from PKCS11 token. PIN is required to generate a Signer from a PKCS 11 token. Not available if cgo is disabled.

WORNING: Does not work if multiple tokens are stuck at the same time.

func CreateSignerPublicKey

func CreateSignerPublicKey(key, password string) (signer ssh.Signer, err error)

CreateSignerPublicKey returns []ssh.Signer generated from public key. If you have not specified a passphrase, please specify a empty character("").

func CreateSignerPublicKeyData added in v0.1.1

func CreateSignerPublicKeyData(keyData []byte, password string) (signer ssh.Signer, err error)

CreateSignerPublicKeyData return ssh.Signer from private key and password

func CreateSignerPublicKeyPrompt added in v0.1.1

func CreateSignerPublicKeyPrompt(key, password string) (signer ssh.Signer, err error)

CreateSignerPublicKeyPrompt rapper CreateSignerPKCS11. Output a passphrase input prompt if the passphrase is not entered or incorrect.

Only Support UNIX-like OS.

func GetStdin added in v0.1.6

func GetStdin() io.ReadCloser

func RequestTty

func RequestTty(session *ssh.Session) (err error)

RequestTty requests the association of a pty with the session on the remote host. Terminal size is obtained from the currently connected terminal

Types

type AgentInterface

type AgentInterface interface{}

AgentInterface Interface for storing agent.Agent or agent.ExtendedAgent.

func ConnectSshAgent added in v0.1.1

func ConnectSshAgent() (ag AgentInterface)

ConnectSshAgent

type C11 added in v0.1.2

type C11 struct {
	Label string
	PIN   string
	Ctx   *crypto11.Context
}

C11 struct for Crypto11 processing. Not available if cgo is disabled.

func (*C11) CreateCtx added in v0.1.2

func (c *C11) CreateCtx(ctx *pkcs11.Ctx) (err error)

CreateCtx is create crypto11.Context Not available if cgo is disabled.

func (*C11) GetSigner added in v0.1.2

func (c *C11) GetSigner() (signer []crypto11.Signer, err error)

GetSigner return []crypto11.Signer. Not available if cgo is disabled.

type Connect

type Connect struct {
	// Client *ssh.Client
	Client *ssh.Client

	// Session
	Session *ssh.Session

	// Session Stdin, Stdout, Stderr...
	Stdin  io.Reader
	Stdout io.Writer
	Stderr io.Writer

	// ProxyDialer
	ProxyDialer proxy.Dialer

	// Connect timeout second.
	ConnectTimeout int

	// SendKeepAliveMax and SendKeepAliveInterval
	SendKeepAliveMax      int
	SendKeepAliveInterval int

	// Session use tty flag.
	TTY bool

	// Forward ssh agent flag.
	ForwardAgent bool

	// CheckKnownHosts if true, check knownhosts.
	CheckKnownHosts bool

	// OverwriteKnownHosts if true, if the knownhost is different, check whether to overwrite.
	OverwriteKnownHosts bool

	// KnownHostsFiles is list of knownhosts files path.
	KnownHostsFiles []string

	// TextAskWriteKnownHosts defines a confirmation message when writing a knownhost.
	// We are using Go's template engine and have the following variables available.
	// - Address ... ssh server hostname
	// - RemoteAddr ... ssh server address
	// - Fingerprint ... ssh PublicKey fingerprint
	TextAskWriteKnownHosts string

	// TextAskOverwriteKnownHosts defines a confirmation message when over-writing a knownhost.
	// We are using Go's template engine and have the following variables available.
	// - Address ... ssh server hostname
	// - RemoteAddr ... ssh server address
	// - OldKeyText ... old ssh PublicKey text.
	//                  ex: /home/user/.ssh/known_hosts:17: ecdsa-sha2-nistp256 AAAAE2VjZHN...bJklasnFtkFSDyOjTFSv2g=
	// - NewFingerprint ... new ssh PublicKey fingerprint
	TextAskOverwriteKnownHosts string

	// ssh-agent interface.
	// agent.Agent or agent.ExtendedAgent
	Agent AgentInterface

	// Forward x11 flag.
	ForwardX11 bool
	// contains filtered or unexported fields
}

Connect structure to store contents about ssh connection.

func (*Connect) AddKeySshAgent

func (c *Connect) AddKeySshAgent(sshAgent interface{}, key interface{})

AddKeySshAgent is rapper agent.Add(). key must be a *rsa.PrivateKey, *dsa.PrivateKey or *ecdsa.PrivateKey, which will be inserted into the agent.

Should use `ssh.ParseRawPrivateKey()` or `ssh.ParseRawPrivateKeyWithPassphrase()`.

func (*Connect) CheckClientAlive

func (c *Connect) CheckClientAlive() error

CheckClientAlive check alive ssh.Client.

func (*Connect) CmdShell added in v0.1.1

func (c *Connect) CmdShell(session *ssh.Session, command string) (err error)

Shell connect command shell over ssh. Used to start a shell with a specified command.

func (*Connect) Command added in v0.1.1

func (c *Connect) Command(command string) (err error)

Command connect and run command over ssh. Output data is processed by channel because it is executed in parallel. If specification is troublesome, it is good to generate and process session from ssh package.

func (*Connect) CreateClient

func (c *Connect) CreateClient(host, port, user string, authMethods []ssh.AuthMethod) (err error)

CreateClient set c.Client.

func (*Connect) CreateSession

func (c *Connect) CreateSession() (session *ssh.Session, err error)

CreateSession retrun ssh.Session

func (*Connect) ForwardSshAgent

func (c *Connect) ForwardSshAgent(session *ssh.Session)

ForwardAgent forward ssh-agent in session.

func (*Connect) SendKeepAlive

func (c *Connect) SendKeepAlive(session *ssh.Session)

SendKeepAlive send packet to session. TODO(blacknon): Interval及びMaxを設定できるようにする(v0.1.1)

func (*Connect) SetLog

func (c *Connect) SetLog(path string, timestamp bool)

SetLog set up terminal log logging. This only happens in Connect.Shell().

func (*Connect) SetLogWithRemoveAnsiCode added in v0.1.4

func (c *Connect) SetLogWithRemoveAnsiCode(path string, timestamp bool)

func (*Connect) Shell

func (c *Connect) Shell(session *ssh.Session) (err error)

Shell connect login shell over ssh.

func (*Connect) TCPDynamicForward added in v0.1.1

func (c *Connect) TCPDynamicForward(address, port string) (err error)

TCPDynamicForward forwarding tcp data. Like Dynamic forward (`ssh -D <port>`). listen port Socks5 proxy server.

func (*Connect) TCPLocalForward added in v0.1.1

func (c *Connect) TCPLocalForward(localAddr, remoteAddr string) (err error)

TCPLocalForward forwarding tcp data. Like Local port forward (ssh -L). localAddr, remoteAddr is write as "address:port".

example) "127.0.0.1:22", "abc.com:9977"

func (*Connect) TCPRemoteForward added in v0.1.1

func (c *Connect) TCPRemoteForward(localAddr, remoteAddr string) (err error)

TCPRemoteForward forwarding tcp data. Like Remote port forward (ssh -R). localAddr, remoteAddr is write as "address:port".

example) "127.0.0.1:22", "abc.com:9977"

func (*Connect) TCPReverseDynamicForward added in v0.1.7

func (c *Connect) TCPReverseDynamicForward(address, port string) (err error)

TCPReverseDynamicForward reverse forwarding tcp data. Like Openssh Reverse Dynamic forward (`ssh -R <port>`).

func (*Connect) X11Forward

func (c *Connect) X11Forward(session *ssh.Session) (err error)

X11Forward send x11-req to ssh server and do x11 forwarding. Since the display number of the transfer destination and the PATH of the socket communication file are checked from the local environmsdent variable DISPLAY, this does not work if it is not set.

Also, the value of COOKIE transfers the local value as it is. This will be addressed in the future.

Example
// Create session
con := &Connect{}
session, err := con.CreateSession()
if err != nil {
	return
}

// X11 forwarding
err = con.X11Forward(session)
if err != nil {
	log.Fatal(err)
}
Output:

type NetPipe

type NetPipe struct {
	Command string
}

func (*NetPipe) Dial

func (n *NetPipe) Dial(network, addr string) (con net.Conn, err error)

type OverwriteInventory added in v0.1.7

type OverwriteInventory struct {
	Address     string
	RemoteAddr  string
	Fingerprint string
	OldKeyText  string
}

type Proxy

type Proxy struct {
	// Type set proxy type.
	// Can specify `http`, `https`, `socks`, `socks5`, `command`.
	//
	// It is read at the time of specification depending on the type.
	Type string

	// Addr set proxy address.
	//
	Addr string

	// Port set proxy port.
	//
	Port string

	// Port set proxy user.
	//
	User string

	// Port set proxy user.
	//
	Password string

	// Command only use Type `command`.
	//
	Command string

	// Forwarder set Dialer.
	Forwarder proxy.Dialer
}

func (*Proxy) CreateHttpProxyDialer

func (p *Proxy) CreateHttpProxyDialer() (proxyDialer proxy.Dialer, err error)

CreateHttpProxy return proxy.Dialer as http proxy.

func (*Proxy) CreateProxyCommandProxyDialer

func (p *Proxy) CreateProxyCommandProxyDialer() (proxyDialer proxy.Dialer, err error)

CreateProxyCommandProxyDialer as ProxyCommand. When passing ProxyCommand, replace %h, %p and %r etc...

func (*Proxy) CreateProxyDialer

func (p *Proxy) CreateProxyDialer() (proxyDialer proxy.Dialer, err error)

CreateProxyDialer retrun proxy.Dialer.

func (*Proxy) CreateSocks5ProxyDialer

func (p *Proxy) CreateSocks5ProxyDialer() (proxyDialer proxy.Dialer, err error)

CreateSocks5Proxy return proxy.Dialer as Socks5 proxy.

type WriteInventory added in v0.1.7

type WriteInventory struct {
	Address     string
	RemoteAddr  string
	Fingerprint string
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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