Использование ключевого файла SSH с Fabric

100

Как настроить фабрику для подключения к удаленным хостам с помощью ключевых файлов SSH (например, инстансов Amazon EC2)?

Юваль Адам
источник

Ответы:

69

Также стоит упомянуть, что для этого вы можете использовать аргументы командной строки:

fab command -i /path/to/key.pem [-H [user@]host[:port]]
Томас
источник
151

Найти простой fabfile с рабочим примером использования ключевого файла SSH по какой-то причине непросто. Я написал об этом сообщение в блоге ( с подходящей сутью ).

В основном, использование происходит примерно так:

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 могла искать ее при подключении.

Юваль Адам
источник
4
на практике это лучший ответ.
panchicore
3
env.key_filename может содержать список строк для проверки нескольких ключевых файлов для подключения.
Carl G
Я программно устанавливал ключ в одной из моих задач с помощью settingsдиспетчера контекста и не мог заставить его распознавать key_filename, пока я не изменил его key_filename='/path/to/key'на, key_filename=['/path/to/key']поэтому, если у кого-то еще возникнут проблемы, сделав key_filename списком ключей, это может исправить. Это с fab 1.10.1 и Paramiko 1.15.2
Jaymon
2
@AseemHegshetye, Он был удален в последней версии Fabric 2. Этот ответ относится к Fabric 1.
Юлиан Онофрей,
1
Я бы предпочел явный импорт вместо import *
mit
64

Еще одна интересная функция, доступная в Fabric 1.4 - Fabric теперь поддерживает конфигурации SSH .

Если у вас уже есть все параметры SSH-соединения в вашем ~/.ssh/configфайле, Fabric изначально будет поддерживать его, вам нужно лишь добавить:

env.use_ssh_config = True

в начале вашего fabfile.

Юваль Адам
источник
2
Очень полезно! Если вы столкнетесь с ошибками, например, IOError: [Errno 2] No such file or directory: ' /path/to/.ssh/key'или Login password for ' root':просто убедитесь, что у вас нет пробелов в вашем .ssh/config. Это, например, User=rootвместо User = root...
Деннис
@dennis Это все еще проблема в 2016 году ..! Спасибо!
gabn88 08
17

Для fabric2 в fabfile используйте следующее:

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

ОБНОВЛЕНИЕ:
для нескольких хостов (один хост тоже подойдет) вы можете использовать это:

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)

и запустите его с помощью fab или fab2:

fab staging stop
MikeL
источник
1
Это правильный способ сделать в fabric 2.x, поскольку все остальные ответы не будут работать.
Вивек Адитья,
Как поддерживать несколько хостов в этой stagingзадаче?
Black_Rider
1
@Black_Rider, добавил это в свой ответ
MikeL
15

Для меня не сработало следующее:

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"
Гаурав Тошнивал
источник
3
Ваш первый пример работает для меня, если вы используете env.user="ubuntu"вместо env.user=["ubuntu"].
Тейлор Эдмистон
7

Мне пришлось сделать это сегодня, мой файл .py был максимально простым, как тот, что был опубликован в ответе @YuvalAdam, но все же меня постоянно просили ввести пароль ...

Посмотрев на paramikoжурнал (библиотеки, используемой тканью для ssh), я нашел строку:

Несовместимый узел SSH (нет приемлемого алгоритма kex)

Я обновил paramiko:

sudo pip install paramiko --upgrade

И теперь все работает.

флагg19
источник
1

Как указано выше, Fabric будет поддерживать настройки файла .ssh / config в какой-то мере, но использование файла pem для ec2 кажется проблематичным. IOW правильно настроенный файл .ssh / config будет работать из командной строки через 'ssh servername' и не сможет работать с 'fab sometask', если env.host = ['servername'].

Это было преодолено путем указания env.key_filename = 'keyfile' в моем fabfile.py и дублирования записи IdentityFile уже в моем .ssh / config.

Это может быть Fabric или paramiko, в моем случае это Fabric 1.5.3 и Paramiko 1.9.0.

Джефф Доран
источник
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.... 
Кейт Энцерот
источник