go语言实现的简单 sftp客户端

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"time"

	"github.com/pkg/sftp"
	"golang.org/x/crypto/ssh"

	_ "github.com/pkg/sftp"
	_ "golang.org/x/crypto/ssh"
	_ "golang.org/x/crypto/ssh/agent"
)

var USER = flag.String("user", "root", "ssh user")
var PASSWD = flag.String("pass", "123456", "ssh passwd")
var HOST = flag.String("host", "localhost", "ssh server ip")
var PORT = flag.Int("port", 22, "ssh port")
var RPATH = flag.String("remotepath", "1.txt", "remote path")

func SftpCreate(user string, passwd string, host string, port int) (*sftp.Client, error) {
	auth := make([]ssh.AuthMethod, 0)
	auth = append(auth, ssh.Password(passwd))
	config := ssh.ClientConfig{
		User:            user,
		Auth:            auth,
		Timeout:         10 * time.Second,
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}

	addr := fmt.Sprintf("%s:%d", host, port)
	conn, err := ssh.Dial("tcp", addr, &config)
	if err != nil {
		return nil, err
	}

	fmt.Println("connet sftp server ok.")
	c, err := sftp.NewClient(conn)
	if err != nil {
		conn.Close()
		return nil, err
	}
	fmt.Println("create sftp client ok.")
	return c, nil
}

func SftpReadAll(user string, passwd string, host string, port int, path string) ([]byte, error) {
	sclient, err := SftpCreate(user, passwd, host, port)
	if err != nil {
		fmt.Println("create ftp client failed, err:%+v.", err)
		return nil, err
	}
	defer sclient.Close()
	fp, err := sclient.Open(path)
	if err != nil {
		fmt.Println("open remote file :%s, err:%+v failed.", path, err)
		return nil, err
	}
	defer fp.Close()
	bytes, err := ioutil.ReadAll(fp)
	return bytes, err
}

func main() {
	fmt.Println("hello ,begin sftp.")
	flag.Parse()
	fmt.Printf("user:%s, passwd:%s, host:%s,port:%d.\n", *USER, *PASSWD, *HOST, *PORT)

	bytes, err := SftpReadAll(*USER, *PASSWD, *HOST, *PORT, *RPATH)
	if err != nil {
		fmt.Println("read failed ,error:%+v", err)
		return
	}
	fmt.Printf("bytes len =%d.\n", len(bytes))
	fmt.Printf("%s", bytes)
	time.Sleep(1000 * time.Second)
}

利用开源库,实现一个简单的sftp客户端读取文件的逻辑。

注意,SFTP与FTP完全是2套不相关的协议

注意,此代码作为客户端,只支持passwd的方式认证,

实际上,很多sftp只支持keyboard-interactive方式,

请参考:

http://www.nljb.net/default/Go-SSH/

 keyboardInteractiveChallenge := func(
        user,
        instruction string,
        questions []string,
        echos []bool,
    ) (answers []string, err error) {
        if len(questions) == 0 {
            return []string{}, nil
        }
        return []string{this.Password}, nil
    }

    authMethods = append(authMethods, ssh.KeyboardInteractive(keyboardInteractiveChallenge))


你可能感兴趣的:(golang)