Usar un archivo de claves SSH con Fabric

100

¿Cómo se configura la estructura para conectarse a hosts remotos mediante archivos de claves SSH (por ejemplo, instancias Amazon EC2)?

Yuval Adam
fuente

Respuestas:

69

También vale la pena mencionar aquí que puede usar los argumentos de la línea de comando para esto:

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

Encontrar un fabfile simple con un ejemplo funcional del uso de archivos de claves SSH no es fácil por alguna razón. Escribí una publicación de blog al respecto ( con una esencia coincidente ).

Básicamente, el uso es algo como esto:

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')

Lo importante es configurar la env.key_filenamevariable de entorno, para que la configuración de Paramiko pueda buscarla al conectarse.

Yuval Adam
fuente
4
en la práctica, esta es la mejor respuesta.
panchicore
3
env.key_filename puede contener una lista de cadenas para probar varios archivos de claves para una conexión.
Carl G
Estaba configurando la clave programáticamente en una de mis tareas usando el settingsadministrador de contexto y no pude hacer que reconociera el nombre_archivo_clave hasta que cambié key_filename='/path/to/key'a, key_filename=['/path/to/key']así que si alguien más tiene problemas, hacer que nombre_archivo clave sea una lista de claves podría solucionarlo. Esto es con fab 1.10.1 y Paramiko 1.15.2
Jaymon
2
@AseemHegshetye, se eliminó en la última tela 2. Esta respuesta es para la tela 1.
Iulian Onofrei
1
Preferiría importaciones explícitas en lugar de importación *
mit
64

Otra característica interesante disponible a partir de Fabric 1.4: Fabric ahora admite configuraciones SSH .

Si ya tiene todos los parámetros de conexión SSH en su ~/.ssh/configarchivo, Fabric lo admitirá de forma nativa, todo lo que necesita hacer es agregar:

env.use_ssh_config = True

al comienzo de su fabfile.

Yuval Adam
fuente
2
¡Muy útil! Si se encuentra con errores como IOError: [Errno 2] No such file or directory: ' /path/to/.ssh/key'o Login password for ' root':simplemente asegúrese de no tener espacios en blanco en su .ssh/config. Es, por ejemplo, en User=rootlugar de User = root...
dennis
@dennis ¡Esto todavía parece ser un problema en 2016 ..! ¡Gracias!
gabn88
17

Para fabric2 en fabfile, use lo siguiente:

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')

y ejecutarlo con:

fab staging do_something_remote

ACTUALIZACIÓN:
para varios hosts (un host también lo hará) puede usar esto:

from fabric2 import task, SerialGroup

@task
def staging(ctx):
    conns = SerialGroup(
        '[email protected]',
        '[email protected]',
        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)

y ejecutarlo con fab o fab2:

fab staging stop
MikeL
fuente
1
Esta es la forma correcta de hacerlo en fabric 2.x, ya que todas las demás respuestas no funcionarán.
Vivek Aditya
¿Cómo admitir varios hosts en esta stagingtarea?
Black_Rider
1
@Black_Rider, lo agregué a mi respuesta
MikeL
15

Para mí, lo siguiente no funcionó:

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

o

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

Sin embargo, lo siguiente hizo:

env.key_filename=['keyfile.pem']
env.hosts=["[email protected]"]

o

env.key_filename=['keyfileq.pem']
env.host_string="[email protected]"
Gaurav Toshniwal
fuente
3
Su primer ejemplo funciona para mí si usa en env.user="ubuntu"lugar de env.user=["ubuntu"].
Taylor Edmiston
7

Tuve que hacer esto hoy, mi archivo .py era lo más simple posible, como el que se publicó en la respuesta de @YuvalAdam, pero aún así me seguían pidiendo una contraseña ...

Mirando el paramikoregistro (la biblioteca utilizada por fabric para ssh), encontré la línea:

Peer ssh incompatible (no hay algoritmo kex aceptable)

Actualicé paramikocon:

sudo pip install paramiko --upgrade

Y ahora está funcionando.

flagg19
fuente
1

Como se indicó anteriormente, Fabric admitirá la configuración del archivo .ssh / config de alguna manera, pero usar un archivo pem para ec2 parece ser problemático. IOW, un archivo .ssh / config correctamente configurado funcionará desde la línea de comandos a través de 'ssh servername' y no funcionará con 'fab sometask' cuando env.host = ['servername'].

Esto se superó especificando env.key_filename = 'keyfile' en mi fabfile.py y duplicando la entrada IdentityFile que ya estaba en mi .ssh / config.

Este podría ser Fabric o paramiko, que en mi caso fue Fabric 1.5.3 y Paramiko 1.9.0.

Jeff Doran
fuente
1

Ninguna de estas respuestas me funcionó en py3.7, fabric2.5.0 y paramiko 2.7.1.

Sin embargo, el uso del atributo PKey en la documentación funciona: 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.... 
Keith Entzeroth
fuente