如何使用 Fabric 和 fabfile 解密受密码保护的 SSH 密钥?

How to decrypt passphrase-protected SSH key using Fabric and fabfile?

我正在 GettingStarted 使用 Fabric 2.4.0,但我想不出一种优雅而安全的方法来解密我的 SSH 密钥以将其传递给 Fabric。我的代码如下:

#!/usr/bin/env python3
"""fabfile"""
from fabric import Connection

c = Connection('user@ip.address')
result = c.run('uname -s')

在这个简单的例子中,运行ning python fabfile.py 我得到了错误:

File "/Users/user.name/GitHub/app_name/fabfile.py", line 6, in <module>
result = c.run('uname -s')
File "<decorator-gen-3>", line 2, in run
File "/Users/user.name/anaconda/envs/virtual_env/lib/python3.6/site-packages/fabric/connection.py", line 29, in opens
self.open()
File "/Users/user.name/anaconda/envs/virtual_env/lib/python3.6/site-packages/fabric/connection.py", line 615, in open
self.client.connect(**kwargs)
File "/Users/user.name/anaconda/envs/virtual_env/lib/python3.6/site-packages/paramiko/client.py", line 437, in connect
passphrase,
File "/Users/user.name/anaconda/envs/virtual_env/lib/python3.6/site-packages/paramiko/client.py", line 749, in _auth
raise saved_exception
File "/Users/user.name/anaconda/envs/virtual_env/lib/python3.6/site-packages/paramiko/client.py", line 720, in _auth
filename, pkey_class, passphrase
File "/Users/user.name/anaconda/envs/virtual_env/lib/python3.6/site-packages/paramiko/client.py", line 571, in _key_from_filepath
key = klass.from_private_key_file(key_path, password)
File "/Users/user.name/anaconda/envs/virtual_env/lib/python3.6/site-packages/paramiko/pkey.py", line 206, in from_private_key_file
key = cls(filename=filename, password=password)
File "/Users/user.name/anaconda/envs/virtual_env/lib/python3.6/site-packages/paramiko/rsakey.py", line 55, in __init__
self._from_private_key_file(filename, password)
File "/Users/user.name/anaconda/envs/virtual_env/lib/python3.6/site-packages/paramiko/rsakey.py", line 175, in _from_private_key_file
data = self._read_private_key_file("RSA", filename, password)
File "/Users/user.name/anaconda/envs/virtual_env/lib/python3.6/site-packages/paramiko/pkey.py", line 279, in _read_private_key_file
data = self._read_private_key(tag, f, password)
File "/Users/user.name/anaconda/envs/virtual_env/lib/python3.6/site-packages/paramiko/pkey.py", line 329, in _read_private_key
raise PasswordRequiredException("Private key file is encrypted")
paramiko.ssh_exception.PasswordRequiredException: Private key file is encrypted
  1. 如何让 Fabric 和 paramiko 向我询问我的加密密码 运行 上面的 fabfile?
  2. python fabfile.py 是运行 上述命令可接受的语法吗?
  3. 2018 年自动将 SSH 密钥从用户计算机传递到脚本的最佳安全做法是什么?使用 os.environ() 可以接受吗?

我在 authentication 的文档中看到,Fabric 注释 The connect_kwargs.passphrase config option is the most direct way to supply a passphrase to be used automatically.

但紧接着它说:

Using actual on-disk config files for this type of material isn’t always wise, but recall that the configuration system is capable of loading data from other sources, such as your shell environment or even arbitrary remote databases.

从安全角度来看,我担心设置错误。使用环境变量传递 ssh 密码是否足够安全?如果是这样,使该命令与加密的 SSH 密钥一起工作的工作代码片段是什么样的?

#!/usr/bin/env python3
"""fabfile"""
from fabric import Connection

c = Connection('user@ip.address')
result = c.run('uname -s')

在使用 CLI 选项执行命令之前,系统会提示您的脚本用户输入 SSH 密钥的密码。

这负责合并转发给 Paramiko 的 connect_kwargs 选项中的密码。

fab --prompt-for-passphrase <command>

上述方法的问题是每次 运行 命令时都必须输入密码。

根据文档中的建议,您可以在 shell 会话中导出环境变量。 例如

export SSH_PASSPHRASE="gongo-aso!"

然后可以在传递给 Connection 对象的构造函数的 connect_kwargs 选项中读取和使用它。

#!/usr/bin/env python3
"""fabfile"""
from os import getenv
from fabric import Connection

connect_kwargs = {
    'passphrase': getenv('SSH_PASSPHRASE')
}

c = Connection('user@ip.address', connect_kwargs=connect_kwargs)
result = c.run('uname -s')