Verwenden einer SSH-Schlüsseldatei mit Fabric

100

Wie konfiguriere ich Fabric für die Verbindung mit Remote-Hosts mithilfe von SSH-Schlüsseldateien (z. B. Amazon EC2-Instanzen)?

Yuval Adam
quelle

Antworten:

69

Erwähnenswert ist hier auch, dass Sie die Befehlszeilenargumente dafür verwenden können:

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

Das Finden einer einfachen Fabdatei mit einem funktionierenden Beispiel für die Verwendung von SSH-Schlüsseldateien ist aus irgendeinem Grund nicht einfach. Ich habe einen Blog-Beitrag darüber geschrieben ( mit einem passenden Inhalt ).

Grundsätzlich geht die Verwendung ungefähr so:

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

Der wichtige Teil ist das Festlegen der env.key_filenameUmgebungsvariablen, damit die Paramiko-Konfiguration beim Herstellen einer Verbindung danach suchen kann.

Yuval Adam
quelle
4
In der Praxis ist dies die bessere Antwort.
Panchicore
3
env.key_filename kann eine Liste von Zeichenfolgen enthalten , um mehrere Schlüsseldateien für eine Verbindung zu testen.
Carl G
Ich war die Einstellung der Schlüssel programmatisch in einen meiner Aufgaben , die unter Verwendung von settingsKontext - Manager und konnte es nicht die key_filename zu erkennen , bis ich geändert , key_filename='/path/to/key'um key_filename=['/path/to/key']so , wenn jemand Schwierigkeiten hat, so dass key_filename eine Liste von Schlüsseln könnte es beheben. Dies ist mit Fab 1.10.1 und Paramiko 1.15.2
Jaymon
2
@AseemHegshetye, Es wurde in der neuesten Fabric 2 entfernt. Diese Antwort ist für Fabric 1.
Iulian Onofrei
1
Ich würde explizite Importe anstelle von Import * bevorzugen
mit
64

Eine weitere coole Funktion, die ab Fabric 1.4 verfügbar ist - Fabric unterstützt jetzt SSH-Konfigurationen .

Wenn Sie bereits alle SSH-Verbindungsparameter in Ihrer ~/.ssh/configDatei haben, wird Fabric diese nativ unterstützen. Sie müssen lediglich Folgendes hinzufügen:

env.use_ssh_config = True

am Anfang deines Fabfiles.

Yuval Adam
quelle
2
Sehr hilfreich! Wenn Sie auf Fehler stoßen IOError: [Errno 2] No such file or directory: ' /path/to/.ssh/key'oder Login password for ' root':nur sicherstellen, dass Sie keine Leerzeichen in Ihrem haben .ssh/config. Es ist zum Beispiel User=rootanstelle von User = root...
Dennis
@dennis Dies scheint auch 2016 ein Problem zu sein ..! Vielen Dank!
gabn88
17

Verwenden Sie für Fabric2 in Fabfile Folgendes:

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

und führen Sie es aus mit:

fab staging do_something_remote

UPDATE:
Für mehrere Hosts (ein Host reicht auch) können Sie Folgendes verwenden:

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)

und starte es mit fab oder fab2:

fab staging stop
MikeL
quelle
1
Dies ist der richtige Weg in Fabric 2.x, da alle anderen Antworten nicht funktionieren.
Vivek Aditya
Wie kann ich mehrere Hosts bei dieser stagingAufgabe unterstützen?
Black_Rider
1
@ Black_Rider, fügte es meiner Antwort hinzu
MikeL
15

Bei mir hat folgendes nicht funktioniert:

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

oder

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

Folgendes tat jedoch:

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

oder

env.key_filename=['keyfileq.pem']
env.host_string="[email protected]"
Gaurav Toshniwal
quelle
3
Ihr erstes Beispiel funktioniert für mich, wenn Sie env.user="ubuntu"anstelle von verwenden env.user=["ubuntu"].
Taylor Edmiston
7

Ich musste dies heute tun, meine .py-Datei war so einfach wie möglich, wie die in der Antwort von @YuvalAdam veröffentlichte, aber ich wurde trotzdem immer wieder zur Eingabe eines Passworts aufgefordert ...

Beim Betrachten des paramikoProtokolls (der von Fabric für SSH verwendeten Bibliothek) fand ich die folgende Zeile:

Inkompatibler SSH-Peer (kein akzeptabler Kex-Algorithmus)

Ich habe aktualisiert paramikomit:

sudo pip install paramiko --upgrade

Und jetzt funktioniert es.

flagg19
quelle
1

Wie oben erwähnt, unterstützt Fabric die Einstellungen für .ssh / config-Dateien auf eine bestimmte Weise, aber die Verwendung einer PEM-Datei für ec2 scheint problematisch zu sein. IOW Eine ordnungsgemäß eingerichtete .ssh / config-Datei funktioniert über die Befehlszeile über 'ssh servername' und funktioniert nicht mit 'fab sometask', wenn env.host = ['servername'].

Dies wurde überwunden, indem in meiner fabfile.py die Datei env.key_filename = 'keyfile' angegeben und der Eintrag IdentityFile bereits in meiner .ssh / config dupliziert wurde.

Dies kann entweder Fabric oder paramiko sein, in meinem Fall Fabric 1.5.3 und Paramiko 1.9.0.

Jeff Doran
quelle
1

Keine dieser Antworten funktionierte für mich unter py3.7, Fabric2.5.0 und Paramiko 2.7.1.

Die Verwendung des PKey-Attributs in der Dokumentation funktioniert jedoch: 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
quelle