sshlib

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 16, 2019 License: MIT Imports: 26 Imported by: 11

README

go-sshlib

GoDoc

About

A library to handle ssh easily with Golang.It can do multiple proxy, x11 forwarding, etc.

Usage

See GoDoc reference.

Example

// Copyright (c) 2019 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, user, port, []ssh.AuthMethod{authMethod})
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

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

    // Start ssh shell
    con.Shell()
}

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, user, port, []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, user1, port1, []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, user2, port2, []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.

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 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)

CreateSignerCertificate returns []ssh.Signer generated from PKCS11 token. PIN is required to generate a Signer from a PKCS 11 token.

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 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.

type Connect

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

	// ProxyDialer
	ProxyDialer proxy.Dialer

	// Session use tty flag.
	TTY bool

	// Stdin to be passed to ssh connection destination.
	// If the value is set here, it is treated as passed from the pipe.
	Stdin []byte

	// Forward ssh agent flag.
	ForwardAgent bool

	// 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(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) Cmd

func (c *Connect) Cmd(command string, output chan []byte) (err error)

Cmd 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) CmdWriter

func (c *Connect) CmdWriter(command string, output chan []byte, input chan io.Writer) (err error)

CmdWriter connect and run command over ssh. In order to be able to send in parallel from io.MultiWriter, it is made to receive Writer by channel.

func (*Connect) ConnectSshAgent

func (c *Connect) ConnectSshAgent()

ConnectSshAgent

func (*Connect) CreateClient

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

CreateClient

func (*Connect) CreateSession

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

CreateSession

func (*Connect) ForwardSshAgent

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

ForwardAgent forward ssh-agent in session.

func (*Connect) SendKeepAlive

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

SendKeepAlive send packet to session.

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) Shell

func (c *Connect) Shell() (err error)

Shell connect login shell over ssh.

func (*Connect) TCPForward

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

TCPForward forwarding tcp data. localAddr, remoteAddr is write as "address:port".

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

Example
// host
host := "target.com"
port := "22"
user := "user"
key := "~/.ssh/id_rsa"

// port forwarding
localAddr := "localhost:10022"
remoteAddr := "localhost:22"

// Create ssh.AuthMethod
authMethod := sshlib.CreateAuthMethodPublicKey(key, "")

// Create sshlib.Connect
con := &sshlib.Connect{}

// PortForward
con.TCPForward(localAddr, remoteAddr)

// Connect ssh server
con.CreateClient(host, user, port, []ssh.AuthMethod{authMethod})

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 environment 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
session, err := c.CreateSession()
if err != nil {
	return
}

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

type NetPipe

type NetPipe struct {
	PipeClient net.Conn
}

func (*NetPipe) Dial

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

type PKCS11

type PKCS11 struct {
	// pkcs11 provider path
	Pkcs11Provider string
	Ctx            *pkcs11.Ctx
	Label          string
	SlotID         uint
	KeyID          map[int][]byte
	PIN            string
	SessionHandle  pkcs11.SessionHandle
}

PKCS11 struct for pkcs11 processing.

func (*PKCS11) CreateCtx

func (p *PKCS11) CreateCtx() (err error)

CreateCtx create and into PKCS11.Ctx. This is the first process to be performed when processing with PKCS11.

func (*PKCS11) GetCryptoSigner

func (p *PKCS11) GetCryptoSigner() (signers []crypto.Signer, err error)

GetCryptoSigner return []crypto.Signer

func (*PKCS11) GetKeyID

func (p *PKCS11) GetKeyID() (err error)

GetKeyID acquire KeyID via PKCS11 and store it in PKCS11 structure.

func (*PKCS11) GetTokenLabel

func (p *PKCS11) GetTokenLabel() (err error)

GetTokenLabel get pkcs11 token label. and into PKCS11.Label. Only one token is supported.

func (*PKCS11) RecreateCtx

func (p *PKCS11) RecreateCtx(pkcs11Provider string) (err error)

RecreateCtx exchange PKCS11.Ctx with PIN accessible ctx. Recreate Ctx to access information after PIN entry.

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.

Jump to

Keyboard shortcuts

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