如何在scp中传递密码?

450

我知道这并不被推荐,但是有没有可能将用户的密码传递给SCP呢?

作为批处理作业的一部分,我想通过SCP复制文件,而接收服务器当然需要密码,但是,我不能轻易地将其更改为基于密钥的身份验证。


2
请参考以下问题:https://dev59.com/UnM_5IYBdhLWcg3wPAnU 其中一个答案提到了另一种可能的解决方法。(注意:这不是重复的问题 - 这是其他问题的原始问题。) - Jonathan Leffler
非常相关: 如何在纯bash中传递ssh密码 - Gabriel Staples
不必通过scp登录并复制,您可以首先使用ssh设置主连接,然后通过主连接运行scp来复制文件,无需密码。请参见https://unix.stackexchange.com/a/2869/17823。 - ryenus
22个回答

738

使用sshpass

sshpass -p "password" scp -r user@example.com:/some/remote/path /some/local/path

以便密码不会出现在bash历史记录中。

sshpass -f "/path/to/passwordfile" scp -r user@example.com:/some/remote/path /some/local/path

以上命令将远程主机路径的内容复制到本地。

安装:

  • ubuntu/debian
    • apt install sshpass
  • centos/fedora
    • yum install sshpass
  • mac w/ macports
    • port install sshpass
  • mac w/ brew
    • brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb

20
在Ubuntu 12.04上,只有在密码上使用单引号(例如'password'而不是"password")才适用于我。 - odedfos
7
@odedfos,是的,你需要使用单引号,因为一些密码生成的字符在双引号字符串插值中可能具有特殊解释。 - TerryE
7
这是安装sshpass的方法:apt-get install sshpass - Jan-Terje Sørensen
6
在CentOS上,使用命令yum -y install sshpass进行安装。 - jgritty
27
最安全的方法是使用一个密码文件,就像这样:sshpass -f passwdfile scp[...]。这样,密码不会在ps列表中显示,您可以通过文件权限来保护密码。 - Christopher Schultz
显示剩余10条评论

68

只需生成一个 SSH 密钥,如下所示:

ssh-keygen -t rsa -C "your_email@youremail.com"

复制 ~/.ssh/id_rsa.pub 的内容,最后将其添加到远程机器的 ~/.ssh/authorized_keys 文件中。

确保远程机器的权限:0700 用于 ~./ssh 文件夹0600 用于 ~/.ssh/authorized_keys 文件


71
正如我之前所写的一样:不,我不能轻松地切换到基于密钥的认证。 - Argelbargel
3
你的意思是 .authorized_keys 而不是 .authorization_keys 吗? - ABCD
2
一个有效的用途是编写一个bash脚本,该脚本会对远程服务器进行多个scp/ssh调用,并要求用户输入远程服务器的密码。这样,密码就不会显示在历史记录中,而且您仍然可以挑战密码...但只需一次。我不想使用密钥文件,因为我希望仍然对脚本用户进行身份验证。 - Wes Grant
2
另一个有效的用途是,如果您无法轻松地在目标上启用基于密钥的身份验证。例如:主要NAS生产商之一 - Synology及其DSM 6.0 - 即使在2016年也不支持它。当然,您可以搞乱配置文件,并希望更新不会再次覆盖它(频繁更新DSM确实会破坏自定义修改)。有时候 - 特别是当OP明确写下他们已经意识到这不是最佳选择时 - 人们只需要一个解决方案。 - Aaa
6
请使用命令 ssh-copy-id -i ~/.ssh/id_rsa.pub <remote_server> 将密钥复制到远程服务器。 - alexandre-rousseau
显示剩余6条评论

60

2
请举个例子。 - SDsolar
另外,您可能需要将C:\ Program Files(x86)\ PuTTY添加到您的路径中以使用这些命令。 - SDsolar
4
这是一个语法示例:pscp -pw 'MyPa$$word' username@servername:/somedir/somefile ~/somedest(我不喜欢这样使用putty,但它可以工作)。 - geneorama
2
@geneorama 密码对我有效,但只有在没有单引号的情况下才有效。谢谢。 - amyassin

49

curl可以作为替代scp的工具来复制文件,并且它支持在命令行中输入密码。

curl --insecure --user username:password -T /path/to/sourcefile sftp://desthost/path/

1
它比“scp”慢得多,但它完成工作还是不错的。 - Victor
我发现这个方法在目标主机配置了长时间的密码提示延迟时更快。scp 必须等待30多秒让我输入密码,但是 curl 立即可以工作。 - Ghost8472
4
我收到了“curl: (1) Protocol "sftp" not supported or disabled in libcurl”这个错误提示。它的意思是libcurl库不支持或禁用了"SFTP"协议。 - lobotmcj
我收到了一个错误提示,说curl不认识-T作为参数。 - Andrés Marafioti
Invoke-WebRequest:无法处理参数,因为参数名称“T”不明确。可能的匹配项包括:-TimeoutSec -TransferEncoding。 在第1行第40个字符处:
  • curl --insecure --user andres:notmypassword -T nottheserver:/home/andr ...
  • ~~
    • CategoryInfo : InvalidArgument: (:) [Invoke-WebRequest],ParameterBindingException
    • FullyQualifiedErrorId : AmbiguousParameter,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
- Andrés Marafioti
显示剩余3条评论

43

您可以使用诸如expect这样的工具对其进行脚本编写(还有方便的绑定,例如Python的Pexpect)。


1
链接到http://expect.nist.gov/已经失效。也许应该使用这个链接:http://expect.sourceforge.net/。 - Katapofatico
1
sudo apt-get install expect - SDsolar
2
错误:没有名为“sshpass”的可用配方 我们不会添加sshpass,因为它会让新手SSH用户轻易破坏SSH的安全性。;) - Lukas N.P. Egger

25
你可以在Unix / 终端使用'expect'脚本。例如,创建'test.exp'文件:
#!/usr/bin/expect
        spawn scp  /usr/bin/file.txt root@<ServerLocation>:/home
        set pass "Your_Password"
        expect {
        password: {send "$pass\r"; exp_continue}
                  }

运行脚本

expect test.exp 

我希望那能有所帮助。


8
先决条件:sudo apt-get install expect。 - SDsolar

11
您可以使用ssh-copy-id命令添加SSH密钥:
$which ssh-copy-id #check whether it exists

如果存在:

ssh-copy-id  "user@remote-system"

太棒了。简单易用,无需第三方软件包或ssh-keygen设置。 - SigmaX

9

下面是使用expect工具的示例:

sub copyover {
    $scp = Expect->spawn("/usr/bin/scp ${srcpath}/$file $who:${destpath}/$file");
    $scp->expect(30,"ssword: ") || die "Never got password prompt from $dest:$!\n";
    print $scp 'password' . "\n";
    $scp->expect(30,"-re",'$\s') || die "Never got prompt from parent system:$!\n";
    $scp->soft_close();
    return;
}

3
这是Perl语言,抱歉我没有写明。(5年前的代码 :) ) - Espo

7

17
5年前,在user524607的回答中提到过。 - Barmar
找到了,并将 C:\Program Files (x86)\PuTTY 添加到我的路径中。 - SDsolar
在WINE下?在Windows上使用plink。顺便说一句,putty-tools是一个软件包。 - mckenzm

4

一旦您按照上面的说明设置了ssh-keygen,您可以执行以下操作:

scp -i ~/.ssh/id_rsa /local/path/to/file remote@ip.com:/path/in/remote/server/

如果您想减少每次键入的次数,可以修改您的.bash_profile文件并输入以下内容:

alias remote_scp='scp -i ~/.ssh/id_rsa /local/path/to/file remote@ip.com:/path/in/remote/server/

然后在终端中执行 source ~/.bash_profile。之后,如果在终端中输入 remote_scp,它应该可以无需密码地运行 scp 命令。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接