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