Serafim Suhenky
Serafim Suhenky

Reputation: 2160

Fabrics 2.x ssh connection using identity fails to work

Trying to connect to the host described in ssh config using fabrics 2 and identity file.

con = Connection('my_host')
@task
def tt(c):
    con.run('uname -a')

~/.ssh/config :

Host my_host
    HostName 123.144.76.84
    User ubuntu
    IdentityFile ~/.keys/somekey

It fails with

paramiko.ssh_exception.AuthenticationException: Authentication failed.

While $ ssh my_host from the terminal works.

I've tried to do fab -i ~/.keys/somekey tt with same result.

Upvotes: 5

Views: 2410

Answers (3)

exhuma
exhuma

Reputation: 21747

There seems to be something afoot with paramiko. Without digging deeper I don't know if it's a bug or not. In any case, I had the same issue, and even a plain paramiko call got me the same error.

Following another SO question I was able to make it work by disabling rsa-sha2-256 and rsa-sha2-512 as mentioned.

Luckily, fabric exposes access to the paramiko arguments like so:

con = Connection(
    'my_host',
    connect_kwargs={
        "disabled_algorithms": {"pubkeys": ["rsa-sha2-256", "rsa-sha2-512"]}
    }
)

I find it unlucky that this is required in the fabfile. If someone else has a better/cleaner solution feel free to comment.

Upvotes: 2

herock
herock

Reputation: 69

Same problem.

You can try add -d for more detail when fabric run:

fab2 -d tt

I found the exception: paramiko.ssh_exception.SSHException: Invalid key, then regenerate key from server, problem solved.

Upvotes: 0

eternaltyro
eternaltyro

Reputation: 336

Fabric accepts a hosts iterable as parameters in tasks. Per the documentation:

An iterable of host-connection specifiers appropriate for eventually instantiating a Connection. The existence of this argument will trigger automatic parameterization of the task when invoked from the CLI, similar to the behavior of --hosts.

One of the members of which could be:

A string appropriate for being the first positional argument to Connection - see its docs for details, but these are typically shorthand-only convenience strings like hostname.example.com or user@host:port.

As for your example, please try this for fabfile.py:

host_list = ["my_host"]

@task(hosts=host_list)
def tt(c):
    c.run('uname -a')

Alternatively, you can omit the host declaration from the fabfile altogether. If you don't specify the host in fabfile.py, you can simply specify it as a host when invoking the fab cli utility. If your fabfile.py is this:

@task
def tt(c):
    c.run('uname -a')

You would now run fab -H my_host tt to run it on the alias tt from your SSH client config.

Hope this helps.

Upvotes: 1

Related Questions