使用带有Fabric的SSH密钥文件

时间:2011-03-16 15:20:02

标签: python fabric

如何使用SSH密钥文件(例如,Amazon EC2实例)配置连接到远程主机的结构?

8 个答案:

答案 0 :(得分:145)

由于某些原因,使用SSH密钥文件使用的工作示例查找简单的fabfile并不容易。我写了一篇blog post关于它(with a matching gist)。

基本上,用法是这样的:

from fabric.api import *

env.hosts = ['host.name.com']
env.user = 'user'
env.key_filename = '/path/to/keyfile.pem'

def local_uname():
    local('uname -a')

def remote_uname():
    run('uname -a')

重要的是设置env.key_filename环境变量,以便Paramiko配置在连接时可以查找它。

答案 1 :(得分:64)

此处值得一提的是,您可以使用命令行参数:

fab command -i /path/to/key.pem [-H [user@]host[:port]]

答案 2 :(得分:64)

Fabric 1.4提供的另一个很酷的功能 - Fabric now supports SSH configs

如果您已在~/.ssh/config文件中拥有所有SSH连接参数,Fabric将本机支持它,您需要做的就是添加:

env.use_ssh_config = True

在fabfile的开头。

答案 3 :(得分:14)

对我来说,以下不起作用:

env.user=["ubuntu"]
env.key_filename=['keyfile.pem']
env.hosts=["xxx-xx-xxx-xxx.ap-southeast-1.compute.amazonaws.com"]

fab command -i /path/to/key.pem [-H [user@]host[:port]]

然而,以下做了:

env.key_filename=['keyfile.pem']
env.hosts=["ubuntu@xxx-xx-xxx-xxx-southeast-1.compute.amazonaws.com"]

env.key_filename=['keyfileq.pem']
env.host_string="ubuntu@xxx-xx-xxx-xxx.ap-southeast-1.compute.amazonaws.com"

答案 4 :(得分:10)

对于使用fabfile的fabric2,您可以使用以下内容:

|> Enum.map(fn chat ->
  Map.update!(chat, :chat_users, fn chat_users ->
    case Enum.at(chat_users, 0) do
      nil -> nil
      _ ->
        chat_user =
        chat_users
        |> List.first
        |> Map.update!(:chat_messages, & [List.first(&1)])
      [chat_user]
    end
  end)
end)

并运行:

from fabric import task, Connection

@task
def staging(ctx):
    ctx.name = 'staging'
    ctx.user = 'ubuntu'
    ctx.host = '192.1.1.1'
    ctx.connect_kwargs.key_filename = os.environ['ENV_VAR_POINTS_TO_PRIVATE_KEY_PATH']

@task
def do_something_remote(ctx):
    with Connection(ctx.host, ctx.user, connect_kwargs=ctx.connect_kwargs) as conn:
        conn.sudo('supervisorctl status')

更新:
对于多个主机(一个主机也可以),您可以使用以下方法:

fab staging do_something_remote

并在fab或fab2上运行它:

from fabric2 import task, SerialGroup

@task
def staging(ctx):
    conns = SerialGroup(
        'user@10.0.0.1',
        'user@10.0.0.2',
        connect_kwargs=
        {
            'key_filename': os.environ['PRIVATE_KEY_TO_HOST']
        })
    ctx.CONNS = conns
    ctx.APP_SERVICE_NAME = 'google'

@task
def stop(ctx):
    for conn in ctx.CONNS:
        conn.sudo('supervisorctl stop ' + ctx.APP_SERVICE_NAME)

答案 5 :(得分:7)

我今天必须这样做,我的.py文件尽可能简单,就像在@YuvalAdam的答案中发布的一样,但我仍然不断提示输入密码......

查看paramiko(fabric用于ssh的库)日志,我找到了这一行:

  

不兼容的ssh peer(没有可接受的kex算法)

我使用以下内容更新了paramiko

sudo pip install paramiko --upgrade

现在它正在发挥作用。

答案 6 :(得分:1)

如上所述,Fabric会在时尚之后支持.ssh / config文件设置,但是对ec2使用pem文件似乎有问题。如果正确设置.ssh / config文件将通过'ssh servername'从命令行工作,并且在env.host = ['servername']时无法使用'fab sometask'。

通过在f​​abfile.py中指定env.key_filename ='keyfile'并复制我的.ssh / config中已有的IdentityFile条目,可以解决这个问题。

这可能是Fabric或paramiko,在我的例子中是Fabric 1.5.3和Paramiko 1.9.0。

答案 7 :(得分:1)

这些答案都不适用于py3.7,fabric2.5.0和paramiko 2.7.1。

但是,使用文档中的PKey属性确实可以:http://docs.fabfile.org/en/2.5/concepts/authentication.html#private-key-objects

from paramiko import RSAKey
ctx.connect_kwargs.pkey = RSAKey.from_private_key_file('path_to_your_aws_key')
with Connection(ctx.host, user, connect_kwargs=ctx.connect_kwargs) as conn:
    //etc....