func (ssh_conf *MakeConfig) Connect() (*ssh.Session, *ssh.Client, error) {
	var client *ssh.Client
	var err error
	targetConfig, closer := getSSHConfig(DefaultConfig{
		User:              ssh_conf.User,
		Key:               ssh_conf.Key,
		KeyPath:           ssh_conf.KeyPath,
		Passphrase:        ssh_conf.Passphrase,
		Password:          ssh_conf.Password,
		Timeout:           ssh_conf.Timeout,
		Ciphers:           ssh_conf.Ciphers,
		KeyExchanges:      ssh_conf.KeyExchanges,
		Fingerprint:       ssh_conf.Fingerprint,
		UseInsecureCipher: ssh_conf.UseInsecureCipher,
	})
	if closer != nil {
		defer closer.Close()
	}
	if ssh_conf.Proxy.Server != "" {
		proxyConfig, closer := getSSHConfig(DefaultConfig{
			User:              ssh_conf.Proxy.User,
			Key:               ssh_conf.Proxy.Key,
			KeyPath:           ssh_conf.Proxy.KeyPath,
			Passphrase:        ssh_conf.Proxy.Passphrase,
			Password:          ssh_conf.Proxy.Password,
			Timeout:           ssh_conf.Proxy.Timeout,
			Ciphers:           ssh_conf.Proxy.Ciphers,
			KeyExchanges:      ssh_conf.Proxy.KeyExchanges,
			Fingerprint:       ssh_conf.Proxy.Fingerprint,
			UseInsecureCipher: ssh_conf.Proxy.UseInsecureCipher,
		})
		if closer != nil {
			defer closer.Close()
		}
		proxyClient, err := ssh.Dial("tcp", net.JoinHostPort(ssh_conf.Proxy.Server, ssh_conf.Proxy.Port), proxyConfig)
		if err != nil {
			return nil, nil, err
		}
		conn, err := proxyClient.Dial("tcp", net.JoinHostPort(ssh_conf.Server, ssh_conf.Port))
		if err != nil {
			return nil, nil, err
		}
		ncc, chans, reqs, err := ssh.NewClientConn(conn, net.JoinHostPort(ssh_conf.Server, ssh_conf.Port), targetConfig)
		if err != nil {
			return nil, nil, err
		}
		client = ssh.NewClient(ncc, chans, reqs)
	} else {
		client, err = ssh.Dial("tcp", net.JoinHostPort(ssh_conf.Server, ssh_conf.Port), targetConfig)
		if err != nil {
			return nil, nil, err
		}
	}
	session, err := client.NewSession()
	if err != nil {
		return nil, nil, err
	}
	return session, client, nil
}
Connect to remote server using MakeConfig struct and returns *ssh.Session
package easyssh
import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"os"
	"path/filepath"
	"sync"
	"time"
	"github.com/ScaleFT/sshkeys"
	"golang.org/x/crypto/ssh"
	"golang.org/x/crypto/ssh/agent"
)
var defaultTimeout = 60 * time.Second
type (
	MakeConfig struct {
		User         string
		Server       string
		Key          string
		KeyPath      string
		Port         string
		Passphrase   string
		Password     string
		Timeout      time.Duration
		Proxy        DefaultConfig
		Ciphers      []string
		KeyExchanges []string
		Fingerprint  string
		UseInsecureCipher bool
	}
	DefaultConfig struct {
		User         string
		Server       string
		Key          string
		KeyPath      string
		Port         string
		Passphrase   string
		Password     string
		Timeout      time.Duration
		Ciphers      []string
		KeyExchanges []string
		Fingerprint  string
		UseInsecureCipher bool
	}
)
func getKeyFile(keypath, passphrase string) (ssh.Signer, error) {
	var pubkey ssh.Signer
	var err error
	buf, err := ioutil.ReadFile(keypath)
	if err != nil {
		return nil, err
	}
	if passphrase != "" {
		pubkey, err = sshkeys.ParseEncryptedPrivateKey(buf, []byte(passphrase))
	} else {
		pubkey, err = ssh.ParsePrivateKey(buf)
	}
	if err != nil {
		return nil, err
	}
	return pubkey, nil
}
func getSSHConfig(config DefaultConfig) (*ssh.ClientConfig, io.Closer) {
	var sshAgent io.Closer
	auths := []ssh.AuthMethod{}
	if config.Password != "" {
		auths = append(auths, ssh.Password(config.Password))
	}
	if config.KeyPath != "" {
		if pubkey, err := getKeyFile(config.KeyPath, config.Passphrase); err != nil {
			log.Printf("getKeyFile error: %v\n", err)
		} else {
			auths = append(auths, ssh.PublicKeys(pubkey))
		}
	}
	if config.Key != "" {
		var signer ssh.Signer
		var err error
		if config.Passphrase != "" {
			signer, err = sshkeys.ParseEncryptedPrivateKey([]byte(config.Key), []byte(config.Passphrase))
		} else {
			signer, err = ssh.ParsePrivateKey([]byte(config.Key))
		}
		if err != nil {
			log.Printf("ssh.ParsePrivateKey: %v\n", err)
		} else {
			auths = append(auths, ssh.PublicKeys(signer))
		}
	}
	if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil {
		auths = append(auths, ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers))
	}
	c := ssh.Config{}
	if config.UseInsecureCipher {
		c.SetDefaults()
		c.Ciphers = append(c.Ciphers, "aes128-cbc", "aes192-cbc", "aes256-cbc", "3des-cbc")
		c.KeyExchanges = append(c.KeyExchanges, "diffie-hellman-group-exchange-sha1", "diffie-hellman-group-exchange-sha256")
	}
	if len(config.Ciphers) > 0 {
		c.Ciphers = append(c.Ciphers, config.Ciphers...)
	}
	if len(config.KeyExchanges) > 0 {
		c.KeyExchanges = append(c.KeyExchanges, config.KeyExchanges...)
	}
	hostKeyCallback := ssh.InsecureIgnoreHostKey()
	if config.Fingerprint != "" {
		hostKeyCallback = func(hostname string, remote net.Addr, publicKey ssh.PublicKey) error {
			if ssh.FingerprintSHA256(publicKey) != config.Fingerprint {
				return fmt.Errorf("ssh: host key fingerprint mismatch")
			}
			return nil
		}
	}
	return &ssh.ClientConfig{
		Config:          c,
		Timeout:         config.Timeout,
		User:            config.User,
		Auth:            auths,
		HostKeyCallback: hostKeyCallback,
	}, sshAgent
}