【发布时间】:2020-06-01 00:02:18
【问题描述】:
我正在使用 org/x/crypto/ssh 包构建一个 cli 应用程序,以通过堡垒 ssh 使用 ssh 证书连接到服务器。基本工作流程是; cli 工具获取用户公钥并从 Vault ssh ca 对其进行签名,并且生成的证书用于向服务器验证用户身份。 效果很好。
configure := &ssh.ClientConfig{
User: "ec2-user",
Auth: []ssh.AuthMethod{
// Use the PublicKeys method for remote authentication.
ssh.PublicKeys(certSigner),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
//log.Println(config.bastionserver.publicIP)
// Connect to the remote server and perform the SSH handshake.
proxyClient, err := ssh.Dial("tcp", net.JoinHostPort(config.bastion.publicIP, "22"), configure)
if err != nil {
log.Fatalln(err)
}
session, err := proxyClient.NewSession()
if err != nil {
log.Fatalln(err)
}
defer session.Close()
if err = session.Shell(); err != nil {
log.Fatalln(err)
}
session.Wait()
我做了一些更改并恢复到代码,我开始收到以下错误。我用 git 还原。
ssh:握手失败:ssh:无法验证,尝试的方法 [publickey none],没有支持的方法
所以我降低了复杂性并尝试了以下块来尝试通过我正在构建的 cli 应用程序连接到堡垒。
cmd := exec.Command("ssh", "-i", signedKeyPath, "-i", privateKeyPath, "ec2-user@host")
fmt.Println(cmd.String())
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
log.Fatalln(err)
}
它仍然退出
/usr/bin/ssh -i /home/rochana/.ssh/id_rsa-cert.pub -i /home/rochana/.ssh/id_rsa ec2-user@host ec2-user@host:权限被拒绝(公钥、gssapi-keyex、gssapi-with-mic)。 2020-02-17 11:01:25.168548退出状态 255。
我尝试在另一台 PC 上编译和运行它,我得到了相同的结果。我尝试将证书保存到磁盘并给出路径。
但是如果我在终端上运行相同的命令。它工作正常并连接到实例。
ssh -i ~/.ssh/id_rsa-cert.pub -i ~/.ssh/id_rsa ec2-user@host
或者只是复制并粘贴 cmd.String() 输出
/usr/bin/ssh -i /home/rochana/.ssh/id_rsa-cert.pub -i /home/rochana/.ssh/id_rsa ec2-user@host
当我直接在终端上运行但不使用 exec 命令时,一切正常
【问题讨论】:
-
您不需要提供 .pub 文件,因此您可以省略第一个“-i”参数。如果您使用“-l”、“ec2-user”作为参数,会有什么不同吗? (相对于“ec2-user@host”)
-
我刚刚尝试了你的建议,但我仍然得到同样的错误。让我感到困惑的是所有命令在终端上都可以正常工作,但在代码中却不行。
-
Permission denied 听起来好像有一个文件您没有足够的权限来读取/执行。您是否以与 shell 相同的用户身份运行 go 程序?我看不到
signedKeyPath中的内容 - 您确定它与您直接传递给 ssh 的文件名相同吗? (它应该真的有一个 .key 或什么的文件扩展名。)您可以尝试更改所有文件的 perms +rx 。您也可以尝试使用绝对路径名来确保找到正确的文件。 -
@Andrew /usr/bin/ssh -i /home/rochana/.ssh/id_rsa-cert.pub -i /home/rochana/.ssh/id_rsa ec2-user@host 这是 cmd.String() 的输出,是的,我使用的是绝对路径。如果只是将上述命令复制并粘贴到终端上,它就可以工作。
err = ioutil.WriteFile(expandPath("~/.ssh/id_rsa-cert.pub"), []byte(signedKey), 0644)这是我保存签名证书文件的方式。我什至试过 0777 -
这对我有用,使用命令
cmd := exec.Command("ssh", "-i", privateKeyPath, "-vv", "user@address")```. Note I added-vv``提供一些诊断信息,因为我的第一次尝试失败了。问题原来是用户名前面的空格;这让我开始思考,所以我在证书文件名的开头添加了一个空格并得到了Permission denied (publickey)(将该命令复制到控制台会起作用)。所以检查是否有任何杂散空间,看看-v提供的信息是否有帮助。