Paramiko and ssh-agent

2,641 views
Skip to first unread message

Aleksej Romanov

unread,
Sep 19, 2012, 2:03:28 PM9/19/12
to ansible...@googlegroups.com
Hello.

Now Paramiko transport use have the following logic regarding to usage
of ssh-agent (and default ~/.ssh/id_{d,r}sa keys):

ssh.connect(self.host, username=user, allow_agent=True, \
look_for_keys=True<...>

So it always uses ssh-agent first, even if password is supplied to
Ansible with -k option. Also it always tries default SSH keys [1].

This is a problem if ssh-agent stores keys with 'confirmation required'
mode (keys added with ssh-add -c). Since Ansible connects to target for
every separate task, ssh-agent asks for confirmation way too much times
for big playbooks. Despite the fact that authtorization is performed
with password and ssh-agent is not related at all.

(As a side note, this 'try everything what we can' approach can mask
errors and does not look like the best way for me even if it would not
cause troubles)

I thought that it may be reasonable to stop checking default id_{d,r}sa
keys if key or password is provided. And if password is provided, then
also stop to talk with ssh-agent.
But Paramiko can use 'password' argument to SSHClient.connect() both as
password to decrypt private key and as password to authenticate with SSH
server. So it is not clear for Ansible if password provided with -k
option is intended for authentication via SSH or as passphrase for
~/.ssh/id_rsa.

So I'm not sure what can be done here. May be separate options for
private key password and remote system SSH password, not -k for both?
Would such patch be useful for anyone and accepted?

I understand that most Ansible users are not affected. But we placed
Ansible at a central server and allow it to login to our systems by
means of agent forwarding. And so it is desirable to keep keys with
'confirmation required' mode. But tons of unneeded requests to ssh-agent
make Ansible unusable. Paramiko transport is really needed for initial
setup as native 'ssh' supports only keys, not passwords.

[1]:
http://www.lag.net/paramiko/docs/paramiko.SSHClient-class.html#connect

Michael DeHaan

unread,
Sep 19, 2012, 2:24:55 PM9/19/12
to ansible...@googlegroups.com, ansible...@googlegroups.com
My suggestion would be just use -c ssh as paramiko is there for ease of initial usage and for older SSH hosts that can't do ControlPersist.

-- Michael

Aleksej Romanov

unread,
Sep 19, 2012, 2:42:21 PM9/19/12
to ansible...@googlegroups.com
Yes, we use -c ssh, but Paramiko is needed for basic host setup
(includes SSHd configuration and setting authorized_keys). Native ssh
does not support password authentication.

By the way, I bet Debian and Red Hat systems without ControlPersist are
quite usual in bigger companies (where configuration management systems
are important).

Michael DeHaan

unread,
Sep 19, 2012, 3:11:51 PM9/19/12
to ansible...@googlegroups.com
You can use a newer SSH on the control machine to talk to older RHEL systems, etc.

I don't think we want to change our paramiko connection policy but since modules are pluggable you could easily tweak it and make a variant connection plugin to meet your use case.

-- Michael

Michael Gliwinski

unread,
Sep 21, 2012, 8:20:27 AM9/21/12
to ansible...@googlegroups.com
On Thursday 20 Sep 2012 01:03:28 Aleksej Romanov wrote:
> So it always uses ssh-agent first, even if password is supplied to
> Ansible with -k option. Also it always tries default SSH keys [1].
...
> I thought that it may be reasonable to stop checking default id_{d,r}sa
> keys if key or password is provided. And if password is provided, then
> also stop to talk with ssh-agent.

IIRC, you can `unset SSH_AUTH_SOCK` to prevent it from talking to ssh-agent.


**********************************************************************************************
The information in this email is confidential and may be legally privileged. It is intended solely for the addressee and access to the email by anyone else is unauthorised.
If you are not the intended recipient, any disclosure, copying, distribution or any action taken or omitted to be taken in reliance on it, is prohibited and may be unlawful.
When addressed to our clients, any opinions or advice contained in this e-mail are subject to the terms and conditions expressed in the governing client engagement leter or contract.
If you have received this email in error please notify sup...@henderson-group.com

John Henderson (Holdings) Ltd
Registered office: 9 Hightown Avenue, Mallusk, County Antrim, Northern Ireland, BT36 4RT.
Registered in Northern Ireland
Registration Number NI010588
Vat No.: 814 6399 12
*********************************************************************************

Dag Wieers

unread,
Sep 24, 2012, 7:28:41 PM9/24/12
to ansible...@googlegroups.com
On Thu, 20 Sep 2012, Aleksej Romanov wrote:

> By the way, I bet Debian and Red Hat systems without ControlPersist are
> quite usual in bigger companies (where configuration management systems
> are important).

For those interested in (or forced to) running Ansible without
ControlPersist, paramiko could work a lot better if each Runner task did
not spawn a new connection, but connections would be reused and
connections idle for a certain idle time would be closed (in fact this
would be ControlPersist implemented in Ansible).

It was discussed here:

https://github.com/ansible/ansible/issues/987

This would speed up Ansible considerably using paramiko. We just need
someone with the skills and persistence to implement it ;-)

--
-- dag wieers, d...@wieers.com, http://dag.wieers.com/
-- dagit linux solutions, in...@dagit.net, http://dagit.net/

[Any errors in spelling, tact or fact are transmission errors]

Michael DeHaan

unread,
Sep 24, 2012, 9:45:01 PM9/24/12
to ansible...@googlegroups.com
>
> This would speed up Ansible considerably using paramiko. We just need
> someone with the skills and persistence to implement it ;-)

Yep, the issue/idea queue is quite large at the moment. If someone
else wants to take a look (preferably someone who has a vested
interest in using the paramiko connection type over a decent number of
hosts), that would be welcome.

Aleksej Romanov

unread,
Sep 25, 2012, 2:42:41 AM9/25/12
to ansible...@googlegroups.com
We already patched code a bit, but yes, deleting SSH_AUTH_SOCK helps
and would be easier, thank you!

diff --git a/lib/ansible/runner/connection_plugins/paramiko_ssh.py b/lib/ansible/runner/connection_plugins/paramiko_ssh.py
index d4083f5..e89c778 100644
--- a/lib/ansible/runner/connection_plugins/paramiko_ssh.py
+++ b/lib/ansible/runner/connection_plugins/paramiko_ssh.py
@@ -58,8 +58,18 @@ class Connection(object):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

+ # If password is given, don't mess with anything else at all
+ # If private key is explicitly specified, don't try default ~/.ssh/id_dsa and ~/.ssh/id_rsa
+ # Otherwise use Paramiko's default: first try ssh-agent and after that id_{d,r}sa
+ allow_agent = True
+ look_for_keys = True
+ if not self.runner.remote_pass is None:
+ allow_agent = False
+ look_for_keys = False
+ elif not self.runner.private_key_file is None:
+ look_for_keys = False
try:
- ssh.connect(self.host, username=user, allow_agent=True, look_for_keys=True,
+ ssh.connect(self.host, username=user, allow_agent=allow_agent, look_for_keys=look_for_keys,
key_filename=self.runner.private_key_file, password=self.runner.remote_pass,
timeout=self.runner.timeout, port=self.port)
except Exception, e:

Michael DeHaan

unread,
Sep 25, 2012, 7:55:28 AM9/25/12
to ansible...@googlegroups.com
Does setting look_for_keys=False make it not look for regular SSH
keys? That seems quite undesirable because while you might not be
setting a keyfile, you could have keys of your own. This would more
or less force usage of ssh-agent.

I'm fine with the part that disables the agent if the password is set
-- send me a pull request.

Aleksej Romanov

unread,
Sep 26, 2012, 10:18:02 AM9/26/12
to ansible...@googlegroups.com
On 25.09.2012 07:55:28, Michael DeHaan wrote:
> Does setting look_for_keys=False make it not look for regular SSH
> keys? That seems quite undesirable because while you might not be
> setting a keyfile, you could have keys of your own. This would more
> or less force usage of ssh-agent.
This makes Ansible not look for ~/.ssh/id_dsa and ~/.ssh/id_rsa if
private_key_file is set. I believe this is correct behaviour: if user
specified private key, we don't need to try default ones.

Michael DeHaan

unread,
Sep 26, 2012, 10:20:54 AM9/26/12
to ansible...@googlegroups.com
ok, send me a pull request and I can try it.
Reply all
Reply to author
Forward
0 new messages