如何自动输入带密码的ssh私钥密码
我以前编写过一个linux env程序,它自动运行SSHFS二进制文件作为用户并输入一个存储的ssh私钥密码。 (公众一半已经在远程服务器上)我曾在一台服务器上使用简单的pexpect命令。 (Ubuntu服务器14.04,ssh版本6.6,sshfs版本2.5)但是,当应用程序移动到Redhat机器(RHEL6.5,ssh版本5.3,sshfs版本2.4)时,这个程序的单个部分被证明是一个问题。简单的一步一直让我疯狂,所以现在我转向这个社区寻求支持。我原来的代码(简体)看起来像这样:如何自动输入带密码的ssh私钥密码
proc = pexpect.spawn('sshfs %[email protected]%s:%s...') #many options, unrelated
proc.expect([pexpect.EOF, 'Enter passphrase for key.*', pexpect.TIMEOUT], timeout=30)
if proc.match_index == 1:
proc.sendline('thepassphrase')
它在ubuntu上运行,但不是rhel。我也尝试了管道到子处理的后备方法,但没有取得太大的成功。
proc = subprocess.Popen('sshfs %[email protected]%s:%s...', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc.stdin.write('thepassphrase'+'\n')
proc.stdin.flush()
当然,我已经尝试了很多这种轻微的变化没有成功,当然,当我手动运行命令时,命令运行良好。
更新3/3: 今天我也有手动编译和安装在RHEL 6.6的ssh看是否这是造成问题,但这个问题即使有新的SSH二进制文件仍然存在。
更新3/9:
今天,我发现其中一个作品特定的解决方案,但我不愉快的事实,许多其他不同的解决方案没有工作,我仍然在寻找答案至于为什么。以下是目前为止我能做的最好的:
proc = subprocess.check_call("sudo -H -u %s ssh-keygen -p -P %s -N '' -f %s" % (user, userKey['passphrase'], userKey['path']), shell=True)
time.sleep(2)
proc = subprocess.Popen(cmd, shell=True)
proc.communicate()
time.sleep(1)
proc = subprocess.check_call("sudo -H -u %s ssh-keygen -p -P '' -N %s -f %s" % (user, userKey['passphrase'], userKey['path']), shell=True)
从密钥中删除密码,装入驱动器,然后重新添加密钥。很明显,我不喜欢这个解决方案,但是它必须要做,直到我能够深入到底。
更新3/23:
好,由于我的愚蠢,我没有看到这种方法眼前的问题到现在为止,现在我回到绘图板。虽然此解决方法在第一次连接时有效,但-o重新连接显然失败,因为sshfs不知道重新连接的密码。这意味着这个解决方案已经不再可行了,如果有人知道如何让pexpect版本工作,我会真的。
在与开发人员亲自交谈之后,我确定这是一个已知的bug,并且没有以问题中指定的相同样式运行命令的正确方法。然而,开发人员很快提出了一个同样有用的方法,其中涉及产生另一个终端进程。
passphrase = 'some passphrase'
cmd = "sudo -H -u somebody sshfs [email protected]:/somewhere-else /home/somebody/testmount -o StrictHostKeychecking=no -o nonempty -o reconnect -o workaround=all -o IdentityFile=/somekey -o follow_symlinks -o cache=no"
bash = pexpect.spawn('bash', echo=False)
bash.sendline('echo READY')
bash.expect_exact('READY')
bash.sendline(cmd)
bash.expect_exact('Enter passphrase for key')
bash.sendline(passphrase)
bash.sendline('echo COMPLETE')
bash.expect_exact('COMPLETE')
bash.sendline('exit')
bash.expect_exact(pexpect.EOF)
我测试过这个解决方案,它已经作为一个很好的解决方法,没有太多的额外开销。您可以查看他的全部回复here。
呃......如果你正在存储PK的加密密钥,明文,为什么要加密密钥呢? – SingleNegationElimination 2015-03-03 03:51:49
这是用户在线输入密码字段中的密码的Web应用程序的一部分。密码只能在RAM中“保存”不到一分钟,我猜这不是绝对的最好,但似乎不是一个重大的安全问题。 – user2205380 2015-03-03 14:18:50
“ssh-agent”对你来说不是一个可行的解决方案吗? – twalberg 2015-03-09 17:17:53