Utilisation d'un fichier de clés SSH avec Fabric

100

Comment configurer Fabric pour se connecter à des hôtes distants à l'aide de fichiers de clés SSH (par exemple, des instances Amazon EC2)?

Yuval Adam
la source

Réponses:

69

Il convient également de mentionner ici que vous pouvez utiliser les arguments de ligne de commande pour cela:

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

Trouver un fabfile simple avec un exemple fonctionnel d'utilisation de fichier de clé SSH n'est pas facile pour une raison quelconque. J'ai écrit un article de blog à ce sujet ( avec l'essentiel ).

Fondamentalement, l'utilisation ressemble à ceci:

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

L'important est de définir la env.key_filenamevariable d'environnement, afin que la configuration Paramiko puisse la rechercher lors de la connexion.

Yuval Adam
la source
4
dans la pratique, c'est la meilleure réponse.
panchicore
3
env.key_filename peut contenir une liste de chaînes pour essayer plusieurs fichiers de clés pour une connexion.
Carl G
J'étais en train de définir la clé par programme dans l'une de mes tâches à l'aide du settingsgestionnaire de contexte et je ne pouvais pas lui faire reconnaître le key_filename jusqu'à ce que je change key_filename='/path/to/key'en key_filename=['/path/to/key']donc si quelqu'un d'autre a des problèmes, faire key_filename une liste de clés pourrait le résoudre. C'est avec fab 1.10.1 et Paramiko 1.15.2
Jaymon
2
@AseemHegshetye, Il a été supprimé dans le dernier Fabric 2. Cette réponse est pour Fabric 1.
Iulian Onofrei
1
Je préfère les importations explicites au lieu d'importation *
mit
64

Une autre fonctionnalité intéressante disponible à partir de Fabric 1.4 - Fabric prend désormais en charge les configurations SSH .

Si vous avez déjà tous les paramètres de connexion SSH dans votre ~/.ssh/configfichier, Fabric le prendra en charge nativement, il vous suffit d'ajouter:

env.use_ssh_config = True

au début de votre fabfile.

Yuval Adam
la source
2
Très utile! Si vous rencontrez des erreurs comme IOError: [Errno 2] No such file or directory: ' /path/to/.ssh/key'ou Login password for ' root':assurez-vous simplement que vous n'avez pas d'espaces dans votre fichier .ssh/config. C'est par exemple User=rootau lieu de User = root...
dennis
@dennis Cela semble encore être un problème en 2016 ..! Merci!
gabn88
17

Pour fabric2 dans fabfile, utilisez ce qui suit:

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

et exécutez-le avec:

fab staging do_something_remote

MISE À JOUR:
Pour plusieurs hôtes (un hôte fera également l'affaire), vous pouvez utiliser ceci:

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)

et exécutez-le avec fab ou fab2:

fab staging stop
MikeL
la source
1
C'est la bonne façon de faire dans fabric 2.x, puisque toutes les autres réponses ne fonctionneront pas.
Vivek Aditya
Comment prendre en charge plusieurs hôtes dans cette stagingtâche?
Black_Rider
1
@Black_Rider, l'a ajouté à ma réponse
MikeL
15

Pour moi, ce qui suit n'a pas fonctionné:

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

ou

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

Cependant, ce qui suit a fait:

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

ou

env.key_filename=['keyfileq.pem']
env.host_string="[email protected]"
Gaurav Toshniwal
la source
3
Votre premier exemple fonctionne pour moi si vous utilisez à la env.user="ubuntu"place de env.user=["ubuntu"].
Taylor Edmiston
7

Je devais le faire aujourd'hui, mon fichier .py était aussi simple que possible, comme celui publié dans la réponse de @YuvalAdam mais je continuais à être invité à entrer un mot de passe ...

En regardant le paramikojournal (la bibliothèque utilisée par fabric pour ssh), j'ai trouvé la ligne:

Homologue ssh incompatible (pas d'algorithme kex acceptable)

J'ai mis paramikoà jour avec:

sudo pip install paramiko --upgrade

Et maintenant ça marche.

flagg19
la source
1

Comme indiqué ci-dessus, Fabric prendra en charge les paramètres de fichier .ssh / config d'une certaine manière, mais l'utilisation d'un fichier pem pour ec2 semble être problématique. IOW un fichier .ssh / config correctement configuré fonctionnera à partir de la ligne de commande via «ssh servername» et ne fonctionnera pas avec «fab quelque chose» quand env.host = [«servername»].

Ce problème a été résolu en spécifiant env.key_filename = 'keyfile' dans mon fabfile.py et en dupliquant l'entrée IdentityFile déjà dans mon .ssh / config.

Cela pourrait être Fabric ou Paramiko, qui dans mon cas était Fabric 1.5.3 et Paramiko 1.9.0.

Jeff Doran
la source
1

Aucune de ces réponses n'a fonctionné pour moi sur py3.7, fabric2.5.0 et paramiko 2.7.1.

Cependant, l'utilisation de l'attribut PKey dans la documentation fonctionne: 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
la source