2

如何在 Perl 中自动输入密码?

代码:

my $makecmd .=  system "ssh remotehost;";
system( "$makecmd" );

输出:

Enter passphrase for key '~/.ssh/id_rsa':
4

3 回答 3

7

您可以使用 SSH 代理将密码短语存储在内存中。虽然这种方法比使用未加密的密钥更麻烦,但它稍微安全一些。在 O'Reilly 的书SSH,The Secure Shell: The Definitive Guide的第 11.1 章,Unattended SSH: Batch or cron Jobs中对这两种方法进行了很好的比较。

使用未加密的密钥

使用未加密(无密码)密钥的一大优势是易于配置。要生成具有空密码的密钥或在现有密钥上将密码设置为空,请运行

ssh-keygen -f ~/.ssh/id_rsa -p

就是这样,不需要更多的配置。这样做的最大缺点是您的私钥现在以纯文本形式存在于您的文件系统中。

使用代理

SSH 代理的配置过程更复杂,取决于您使用的代理。O'Reilly 书籍的第 6.3 章、SSH 代理和 IBM developerWorks 文章SSH 安全性和配置入门介绍了如何配置ssh-agentOpenSSH 中包含的默认代理。SSH Keys 上的 archlinux wiki 页面还描述了其他代理,例如 GNOME Keyring 和 pam_ssh。

让我们看一下 的设置过程ssh-agent。当你运行命令时

ssh-agent

它不仅会启动代理,还会输出 shell 命令来设置一些环境变量。在 Bourne 风格的 shell 中,输出如下所示:

$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-barrett/ssh-3654-agent; export SSH_AUTH_SOCK;
SSH_AGENT_PID=3655; export SSH_AGENT_PID;
echo Agent pid 3655;

这些环境变量告诉你的 shell 如何访问代理。任何使用代理的脚本都需要设置这些环境变量。首次调用代理时,您可以将 shell 命令保存到文件中以供以后使用:

$ ssh-agent | head -2 > ~/agent-info

接下来,您需要将您的私钥添加到代理:

$ source ~/agent-info
$ ssh-add ~/.ssh/id_rsa
Need passphrase for ~/.ssh/id_rsa
Enter passphrase: **************

最后,您需要确保在调用 Perl 脚本时设置了适当的环境变量。一种方法是编写一个包装脚本:

#!/bin/sh
source ~/agent-info
/path/to/perl/script "$@"

只要代理正在运行,您的脚本就可以使用私钥而无需输入密码。请注意,如果只有一个 uid 将使用代理,那么在该 uid 下启动代理是最简单的:

$ su <script_user> ssh-agent ...

使用代理的一个缺点是您必须手动重新启动代理并在服务器重新启动时重新输入您的密码。这是您为使用加密密钥获得的(可以说是边际的)额外安全性付出的代价。

于 2013-11-13T18:54:23.880 回答
0

Net::OpenSSH支持带有密码短语的密钥:

use Net::OpenSSH;
my $ssh = Net::OpenSSH->new($host, passphrase => $passphrase);
$ssh->system($makecmd);

在任何情况下,在脚本中包含密码短语大多会违背其目的。

于 2013-11-14T09:53:03.130 回答
-2

您可以使用 Expect 来执行此操作。从这个页面:http ://metacpan.org/pod/Net::SSH::Expect

使用密码:

    # Starting ssh without password
    # 1) run the constructor
    my $ssh = Net::SSH::Expect->new (
        host => "myserver.com", 
        user => 'bnegrao', 
        raw_pty => 1
    );
    # 2) now start the ssh process
    $ssh->run_ssh() or die "SSH process couldn't start: $!";

使用密码:

    use Net::SSH::Expect; 
    # Making an ssh connection with user-password authentication
    # 1) construct the object
    my $ssh = Net::SSH::Expect->new (
        host => "myserver.com", 
        password=> 'pass87word', 
        user => 'bnegrao', 
        raw_pty => 1
    );

    # 2) logon to the SSH server using those credentials.
    # test the login output to make sure we had success
    my $login_output = $ssh->login();
    if ($login_output !~ /Welcome/) {
        die "Login has failed. Login output was $login_output";
    }
于 2013-11-13T16:05:24.783 回答