go-scp库不起作用,但scp正常工作。

huangapple go评论89阅读模式
英文:

go-scp library not working but scp is working fine

问题

我正在使用go-scp库尝试将文件复制到SolarWinds服务器(Windows服务器),但是出现了等待超时错误,而使用命令行的scp命令则可以正常工作。

我还发现,在go-scp库的CopyPassThru函数中,当我移除了err := a.Session.Run(fmt.Sprintf("%s -qt %q", a.RemoteBinary, remotePat)行中的-q选项后,就没有等待超时错误,但是远程服务器上的文件是空的。

我无法通过命令行SSH到SolarWinds服务器。

以下是代码片段:

package main

import (
	"fmt"
	scp "github.com/bramvdbogaerde/go-scp"
	"golang.org/x/crypto/ssh"
	"os"
	"strings"
	"time"
)

func main() {
	// 使用auth包中的SSH密钥认证
	// 在这个例子中我们忽略了主机密钥,请根据实际情况修改
	// 创建SSH客户端配置
	var authParam ssh.AuthMethod
	authParam = ssh.Password("1234")
	clientConfig := &ssh.ClientConfig{
		User: "admin",
		Auth: []ssh.AuthMethod{
			authParam,
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		Timeout:         time.Minute,
	}

	// 其他认证方法请参考ssh.ClientConfig和ssh.AuthMethod

	// 创建一个新的SCP客户端
	client := scp.NewClient("10.154.92.32:22", clientConfig)

	// 连接到远程服务器
	err := client.Connect()
	if err != nil {
		fmt.Println("无法建立与远程服务器的连接", err)
		return
	}

	// 在文件被复制后关闭客户端连接
	defer client.Close()

	// 最后,复制文件
	// 用法:CopyFile(fileReader, remotePath, permission)
	fileString := "testing \n"
	myReader := strings.NewReader(fileString)
	err = client.CopyFile(myReader, "/test", "0777")
	if err != nil {
		fmt.Println("复制文件时出错", err)
	}
}
英文:

I am using go-scp and trying to copy to solarwinds server(windows server) and getting waiting timed out error whereas I tried command line scp it works fine.

Also I found out that after removing -q option in line err := a.Session.Run(fmt.Sprintf("%s -qt %q", a.RemoteBinary, remotePat)
in CopyPassThru function in go-scp library, there was no waiting timed out error but the file was empty at the remote server

I am unable to SSH to solarwinds server through command line.

Code snipped as below

package main

import (
	"fmt"
	scp "github.com/bramvdbogaerde/go-scp"
	"golang.org/x/crypto/ssh"
	"os"
	"strings"
	"time"
)

func main() {
	// Use SSH key authentication from the auth package
	// we ignore the host key in this example, please change this if you use this library
    // create ssh client config
	var authParam ssh.AuthMethod
	authParam = ssh.Password("1234")
	clientConfig := &ssh.ClientConfig{
		User: "admin",
		Auth: []ssh.AuthMethod{
			authParam,
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		Timeout:time.Minute,
	}

	// For other authentication methods see ssh.ClientConfig and ssh.AuthMethod

	// Create a new SCP client
	client := scp.NewClient("10.154.92.32:22", clientConfig)

	// Connect to the remote server
	err := client.Connect()
	if err != nil {
		fmt.Println("Couldn't establish a connection to the remote server ", err)
		return
	}

	// Close client connection after the file has been copied
	defer client.Close()

	// Finally, copy the file over
	// Usage: CopyFile(fileReader, remotePath, permission)
	fileString := "testing \n" 
	myReader := strings.NewReader(fileString)
	err = client.CopyFile(myReader, "/test", "0777")
	if err != nil {
		fmt.Println("Error while copying file ", err)
	}
}

答案1

得分: 2

对于遇到scp包问题的任何人(我也遇到了问题),这是一个使用cat传输单个文件的解决方法。它只使用了ssh包。

思路是使用没有参数的cat命令从标准输入读取内容。在会话对象中,我们将本地文件提供给标准输入。然后,我们使用>将cat的输出重定向到目标文件。

反向操作类似,这次我们拦截会话对象的标准输出。我们使用cat命令读取远程文件,并将会话的标准输出复制到本地文件。

以下是代码:

package main

import (
	"bytes"
	"errors"
	"os"

	"golang.org/x/crypto/ssh"
)

func main() {
	config := &ssh.ClientConfig{
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		User:            "user",
		Auth:            []ssh.AuthMethod{ssh.Password("password")},
	}
	client, err := ssh.Dial("tcp", "10.0.0.1:22", config)
	if err != nil {
		panic(err)
	}
	defer client.Close()

	err = setFile(client, "local/file", "remote/file")
	if err != nil {
		panic(err)
	}

	err = getFile(client, "remote/file", "local/file")
	if err != nil {
		panic(err)
	}
}

func setFile(client *ssh.Client, from, to string) error {
	f, err := os.Open(from)
	if err != nil {
		return err
	}
	defer f.Close()

	session, err := client.NewSession()
	if err != nil {
		return err
	}
	defer session.Close()

	session.Stdin = f
	var stderr bytes.Buffer
	session.Stderr = &stderr
	err = session.Run("cat > '" + to + "'")
	if err != nil && stderr.Len() > 0 {
		err = errors.New(err.Error() + ": " + string(stderr.Bytes()))
	}
	return err
}

func getFile(client *ssh.Client, from, to string) error {
	f, err := os.Create(to)
	if err != nil {
		return err
	}
	defer f.Close()

	session, err := client.NewSession()
	if err != nil {
		return err
	}
	defer session.Close()

	session.Stdout = f
	var stderr bytes.Buffer
	session.Stderr = &stderr
	err = session.Run("cat '" + from + "'")
	if err != nil && stderr.Len() > 0 {
		err = errors.New(err.Error() + ": " + string(stderr.Bytes()))
	}
	return err
}

希望对你有帮助!

英文:

For anybody having problems with that scp package (I had problems as well), this is a work-around that uses cat to transfer single files. It uses only the ssh package.

The idea is to use cat without arguments to read from standard input. In our session object we provide our local file as standard input. Then we pipe cat's output with > to the desired file.

The reverse way is similar, this time we intercept standard output of our session object. We cat the remote file and copy the session's standard output to our local file.

Here is the code:

package main
import (
"bytes"
"errors"
"os"
"golang.org/x/crypto/ssh"
)
func main() {
config := &ssh.ClientConfig{
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
User:            "user",
Auth:            []ssh.AuthMethod{ssh.Password("password")},
}
client, err := ssh.Dial("tcp", "10.0.0.1:22", config)
if err != nil {
panic(err)
}
defer client.Close()
err = setFile(client, "local/file", "remote/file")
if err != nil {
panic(err)
}
err = getFile(client, "remote/file", "local/file")
if err != nil {
panic(err)
}
}
func setFile(client *ssh.Client, from, to string) error {
f, err := os.Open(from)
if err != nil {
return err
}
defer f.Close()
session, err := client.NewSession()
if err != nil {
return err
}
defer session.Close()
session.Stdin = f
var stderr bytes.Buffer
session.Stderr = &stderr
err = session.Run("cat > '" + to + "'")
if err != nil && stderr.Len() > 0 {
err = errors.New(err.Error() + ": " + string(stderr.Bytes()))
}
return err
}
func getFile(client *ssh.Client, from, to string) error {
f, err := os.Create(to)
if err != nil {
return err
}
defer f.Close()
session, err := client.NewSession()
if err != nil {
return err
}
defer session.Close()
session.Stdout = f
var stderr bytes.Buffer
session.Stderr = &stderr
err = session.Run("cat '" + from + "'")
if err != nil && stderr.Len() > 0 {
err = errors.New(err.Error() + ": " + string(stderr.Bytes()))
}
return err
}

huangapple
  • 本文由 发表于 2022年3月24日 17:07:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/71599643.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定