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

5

我正在使用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')

在这个简单的例子中,运行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()可接受吗?

我在身份验证文档中看到,Fabric指出:connect_kwargs.passphrase 配置选项是提供自动使用的密码短语的最直接方法。

但紧接着它说:

对于这种类型的材料,使用实际的磁盘配置文件并不总是明智的,但请记住,配置系统能够从其他来源加载数据,例如您的shell环境或任意远程数据库。

从安全角度考虑,我担心设置错误。使用环境变量传递ssh密码短语是否足够安全?如果可以,请问一个工作代码片段是什么样的,以便与加密的SSH密钥一起使用此命令?

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

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

4

在使用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')

请注意,至少在 fabric 2.7.1 版本中,这个答案会导致一个 SSHException: Invalid key 错误。可以通过将 'passphrase': ... 更改为 'password': ... 来避免此错误 :) - Cole Robertson

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