# Ansible SSH Proxyjump

**URL:** <https://forum.ansible.com/t/ansible-ssh-proxyjump/11289>\
**Category:** Get Help\
**Tags:** ansible-core\
**Created:** [December 3, 2024, 9:22am UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289 "2024-12-03T09:22:24Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![jorgenspange](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jorgenspange/32/9667_2.png) [@jorgenspange](https://forum.ansible.com/u/jorgenspange)\
**Post date:** [December 3, 2024, 9:22am UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/1 "2024-12-03T09:22:24Z")

</div>

Good day,

I’ve been using my Macbook Pro M1 2021 as my ansible controller for a couple of years with ssh\_args specified like this:

```auto
ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q 192.198.10.10'

```

And my ~/.ssh/config like this:

```auto
Host 192.168.10.10
  User myuser@domain.net
  IdentityFile ~/.ssh/id_rsa.pub

```

This way ssh key is used to authenticate towards the jumphost and ansible\_password is used to authenticate to the cisco network device, this setup has worked flawlessly.

But now all of a sudden it seems like this is not working.  
Running ansible-core 2.18.0 paramiko will give me this error:

```auto
fatal: [switch]: FAILED! => changed=false
  msg: Error reading SSH protocol banner[Errno 54] Connection reset by peer

```

Whilst libssh gives me this:

```auto
fatal: [switch]: FAILED! => changed=false
  msg: 'ssh connection failed: ssh connect failed: Timeout connecting to 10.10.13.37'

```

It seems like the ansible\_ssh\_common\_args for some reason are now not appreciated at all, I’m also using a yubikey and it is completely dead while i try to run something.

And also yes, when I do the same with SSH directly everything is working as expected:

```auto
[user@MBP ~/Documents]$ ssh -o 'ProxyCommand ssh -W %h:%p -q myuser@domain.net@192.168.10.10' ansible_user@"10.10.13.37"
(ansible_user@10.10.13.37) Password:
switch#

```

Anyone experienced the same after upgrade of either ansible-core or ansible.netcommon?  
Unfortunately I havent kept good track of my versions so not sure exactly when this occured 🥸

Best regards.

---

<div class="post-metadata">

**Author:** ![bvitnik](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/bvitnik/32/4132_2.png) [@bvitnik](https://forum.ansible.com/u/bvitnik)\
**Post date:** [December 3, 2024, 9:45pm UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/2 "2024-12-03T21:45:15Z")

</div>

Can you run ansible with `-vvvv` option? It will tell you the exact SSH command used by the ansible and show you a way to manually reproduce the problem.

---

<div class="post-metadata">

**Author:** ![chris](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/chris/32/293_2.png) [@chris](https://forum.ansible.com/u/chris)\
**Post date:** [December 4, 2024, 9:19am UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/3 "2024-12-04T09:19:14Z")

</div>

Does it work if you put all the configuration in your `~/.ssh/config`, for example:

```auto
Host 192.168.10.10
  User myuser@domain.net
  IdentityFile ~/.ssh/id_rsa.pub

Host 10.10.13.37
  User ansible_user
  ProxyJump 192.168.10.10

```

---

<div class="post-metadata">

**Author:** ![jorgenspange](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jorgenspange/32/9667_2.png) [@jorgenspange](https://forum.ansible.com/u/jorgenspange)\
**Post date:** [December 5, 2024, 8:08am UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/4 "2024-12-05T08:08:56Z")

</div>

I think my problem is that the ssh-agent which ansible decides to use is the wrong one.

Here’s what I have in my bashrc to make sure that it’s done when I run ssh, but seems like ansible/ansible.netcommon does not appreciate this:

```auto
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)

```

---

<div class="post-metadata">

**Author:** ![jorgenspange](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jorgenspange/32/9667_2.png) [@jorgenspange](https://forum.ansible.com/u/jorgenspange)\
**Post date:** [December 5, 2024, 8:11am UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/5 "2024-12-05T08:11:31Z")

</div>

Thank you for your reply, I’ve tried this, but result is still the same.  
The thing is that I have my private key stored on a yubikey, when ssh’ing locally this is invoced by using gpg as ssh-agent. This has been working before, but seems like at some point ansible.netcommon/paramiko does not appreciate this configuration anymore.

---

<div class="post-metadata">

**Author:** ![jorgenspange](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jorgenspange/32/9667_2.png) [@jorgenspange](https://forum.ansible.com/u/jorgenspange)\
**Post date:** [December 5, 2024, 8:12am UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/6 "2024-12-05T08:12:58Z")

</div>

Ran this command

```auto
ansible switch -i inventory/ -m ios_ping -vvvv -a "dest=8.8.8.8"

```

This is the output:

```auto
The full traceback is:
  File "/Users/username/.ansible/collections/ansible_collections/cisco/ios/plugins/module_utils/network/ios/ios.py", line 60, in get_capabilities
    capabilities = Connection(module._socket_path).get_capabilities()
  File "/opt/homebrew/Cellar/ansible/11.0.0_1/libexec/lib/python3.13/site-packages/ansible/module_utils/connection.py", line 183, in __rpc__
    raise ConnectionError(to_text(msg, errors='surrogate_then_replace'), code=code)
switch | FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "afi": "ip",
            "count": null,
            "dest": "8.8.8.8",
            "df_bit": false,
            "egress": null,
            "ingress": null,
            "size": null,
            "source": null,
            "state": "present",
            "timeout": null,
            "vrf": null
        }
    },
    "msg": "Error reading SSH protocol banner[Errno 54] Connection reset by peer"
}

```

---

<div class="post-metadata">

**Author:** ![Thulium-Drake](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/thulium-drake/32/833_2.png) [@Thulium-Drake](https://forum.ansible.com/u/Thulium-Drake)\
**Post date:** [December 5, 2024, 10:48am UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/7 "2024-12-05T10:48:58Z")

</div>

You could also have a look at `assh`, which is a really nice, compact toolkit for SSH that handles the connection setup for stuff like this (and a whole lot more)

> **[GitHub - moul/assh: :computer: make your ssh client smarter](https://github.com/moul/assh)**
>
> :computer: make your ssh client smarter

---

<div class="post-metadata">

**Author:** ![bvitnik](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/bvitnik/32/4132_2.png) [@bvitnik](https://forum.ansible.com/u/bvitnik)\
**Post date:** [December 5, 2024, 3:17pm UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/8 "2024-12-05T15:17:54Z")

</div>

> [@jorgenspange](#):
>
> This is the output:
> 
> ```auto
> The full traceback is:
> ...
> 
> ```

Yes but what is preceding this line? Those blue lines where Ansible prints the exact SSH commands it is running? Try running some of them manually to understand what is happening.

---

<div class="post-metadata">

**Author:** ![jorgenspange](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jorgenspange/32/9667_2.png) [@jorgenspange](https://forum.ansible.com/u/jorgenspange)\
**Post date:** [December 10, 2024, 12:36pm UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/10 "2024-12-10T12:36:07Z")

</div>

Sorry, here is the entire thing:

```auto
ansible [core 2.18.1]
 config file = user/Documents/git/ansible-network-automation/ansible.cfg
 configured module search path = ['user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
 ansible python module location = /opt/homebrew/Cellar/ansible/11.1.0/libexec/lib/python3.13/site-packages/ansible
 ansible collection location = user/.ansible/collections:/usr/share/ansible/collections
 executable location = /opt/homebrew/bin/ansible
 python version = 3.13.1 (main, Dec 3 2024, 17:59:52) [Clang 16.0.0 (clang-1600.0.26.4)] (/opt/homebrew/Cellar/ansible/11.1.0/libexec/bin/python)
 jinja version = 3.1.4
 libyaml = True
Using user/Documents/git/ansible-network-automation/ansible.cfg as config file
setting up inventory plugins
Loading collection ansible.builtin from
host_list declined parsing {{ inventory_path }}/campus as it did not pass its verify_file() method
script declined parsing {{ inventory_path }}/campus as it did not pass its verify_file() method
auto declined parsing {{ inventory_path }}/campus as it did not pass its verify_file() method
Parsed {{ inventory_path }}/campus inventory source with ini plugin
setting up inventory plugins
host_list declined parsing {{ inventory_path }}/datacenter as it did not pass its verify_file() method
script declined parsing {{ inventory_path }}/datacenter as it did not pass its verify_file() method
auto declined parsing {{ inventory_path }}/datacenter as it did not pass its verify_file() method
Parsed {{ inventory_path }}/datacenter inventory source with ini plugin
setting up inventory plugins
host_list declined parsing {{ inventory_path }}/management as it did not pass its verify_file() method
script declined parsing {{ inventory_path }}/management as it did not pass its verify_file() method
auto declined parsing {{ inventory_path }}/management as it did not pass its verify_file() method
Parsed {{ inventory_path }}/management inventory source with ini plugin
setting up inventory plugins
host_list declined parsing {{ inventory_path }}/routers as it did not pass its verify_file() method
script declined parsing {{ inventory_path }}/routers as it did not pass its verify_file() method
auto declined parsing {{ inventory_path }}/routers as it did not pass its verify_file() method
Parsed {{ inventory_path }}/routers inventory source with ini plugin
redirecting (type: modules) ansible.builtin.ios_ping to cisco.ios.ios_ping
Loading collection cisco.ios from user/.ansible/collections/ansible_collections/cisco/ios
Loading callback plugin minimal of type stdout, v2.0 from /opt/homebrew/Cellar/ansible/11.1.0/libexec/lib/python3.13/site-packages/ansible/plugins/callback/minimal.py
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
Trying secret FileVaultSecret(filename='user/Documents/git/ansible-network-automation/.secret/vault_pass.txt') for vault_id=default
Trying secret FileVaultSecret(filename='user/Documents/git/ansible-network-automation/.secret/vault_pass.txt') for vault_id=default
Trying secret FileVaultSecret(filename='user/Documents/git/ansible-network-automation/.secret/vault_pass.txt') for vault_id=default
Trying secret FileVaultSecret(filename='user/Documents/git/ansible-network-automation/.secret/vault_pass.txt') for vault_id=default
Loading collection ansible.netcommon from user/.ansible/collections/ansible_collections/ansible/netcommon
Loading collection ansible.utils from user/.ansible/collections/ansible_collections/ansible/utils
Trying secret FileVaultSecret(filename='user/Documents/git/ansible-network-automation/.secret/vault_pass.txt') for vault_id=default
Trying secret FileVaultSecret(filename='user/Documents/git/ansible-network-automation/.secret/vault_pass.txt') for vault_id=default
Trying secret FileVaultSecret(filename='user/Documents/git/ansible-network-automation/.secret/vault_pass.txt') for vault_id=default
redirecting (type: modules) ansible.builtin.ios_ping to cisco.ios.ios_ping
redirecting (type: action) ansible.builtin.ios to cisco.ios.ios
<192.168.10.10> Using network group action ios for ios_ping
redirecting (type: action) ansible.builtin.ios to cisco.ios.ios
<192.168.10.10> attempting to start connection
<192.168.10.10> using connection plugin ansible.netcommon.network_cli
<192.168.10.10> local domain socket does not exist, starting it
<192.168.10.10> control socket path is user/.ansible/pc/fee0104b9e
<192.168.10.10> Loading collection ansible.builtin from
<192.168.10.10> Loading collection ansible.netcommon from user/.ansible/collections/ansible_collections/ansible/netcommon
<192.168.10.10> Loading collection ansible.utils from user/.ansible/collections/ansible_collections/ansible/utils
<192.168.10.10> Loading collection cisco.ios from user/.ansible/collections/ansible_collections/cisco/ios
<192.168.10.10> local domain socket listeners started successfully
<192.168.10.10> loaded cliconf plugin ansible_collections.cisco.ios.plugins.cliconf.ios from path user/.ansible/collections/ansible_collections/cisco/ios/plugins/cliconf/ios.py for network_os cisco.ios.ios
<192.168.10.10> ssh type is set to paramiko
<192.168.10.10> Loading collection ansible.builtin from
<192.168.10.10> local domain socket path is user/.ansible/pc/fee0104b9e
redirecting (type: action) ansible.builtin.ios to cisco.ios.ios
<192.168.10.10> ANSIBLE_NETWORK_IMPORT_MODULES: enabled
redirecting (type: modules) ansible.builtin.ios_ping to cisco.ios.ios_ping
<192.168.10.10> ANSIBLE_NETWORK_IMPORT_MODULES: found ios_ping at user/.ansible/collections/ansible_collections/cisco/ios/plugins/modules/ios_ping.py
<192.168.10.10> ANSIBLE_NETWORK_IMPORT_MODULES: running ios_ping
<192.168.10.10> ANSIBLE_NETWORK_IMPORT_MODULES: complete
The full traceback is:
 File "user/.ansible/collections/ansible_collections/cisco/ios/plugins/module_utils/network/ios/ios.py", line 60, in get_capabilities
   capabilities = Connection(module._socket_path).get_capabilities()
 File "/opt/homebrew/Cellar/ansible/11.1.0/libexec/lib/python3.13/site-packages/ansible/module_utils/connection.py", line 183, in __rpc__
   raise ConnectionError(to_text(msg, errors='surrogate_then_replace'), code=code)
switch | FAILED! => {
   "changed": false,
   "invocation": {
       "module_args": {
           "afi": "ip",
           "count": null,
           "dest": "8.8.8.8",
           "df_bit": false,
           "egress": null,
           "ingress": null,
           "size": null,
           "source": null,
           "state": "present",
           "timeout": null,
           "vrf": null
       }
   },
   "msg": "Error reading SSH protocol banner[Errno 54] Connection reset by peer"
}

```

Thanks!

---

<div class="post-metadata">

**Author:** ![bvitnik](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/bvitnik/32/4132_2.png) [@bvitnik](https://forum.ansible.com/u/bvitnik)\
**Post date:** [December 10, 2024, 1:14pm UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/11 "2024-12-10T13:14:31Z")

</div>

> [@jorgenspange](#):
>
> `network_cli`

Ah, this is using `network_cli` connection plugin, not a standard SSH connection plugin, plus it uses paramiko so you don’t get any SSH client commands in the output. I’m not familiar with `network_cli` connection plugin so I’m not sure how to debug this. Maybe some network guy can help here 🙂 ?

This is the example of what I was hoping to see:

```auto
<192.168.10.10> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.10.10> SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="somekey"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o 'ControlPath="/home/bvitnik/.ansible/cp/ba7fe97e5a"' 192.168.10.10 '/bin/sh -c '"'"'/usr/bin/python3 && sleep 0'"'"''

```

Then it is easy to run the command manually to reproduce the problem.

---

<div class="post-metadata">

**Author:** ![jorgenspange](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jorgenspange/32/9667_2.png) [@jorgenspange](https://forum.ansible.com/u/jorgenspange)\
**Post date:** [December 10, 2024, 1:25pm UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/12 "2024-12-10T13:25:09Z")

</div>

Right, I’ve also tried with ansible-pylibssh, as mentioned in the original post, but the problem is the same just a different output.

I think that the root cause is that I have defined “gpg-agent” as my ssh-agent locally, this does the lookup for my private key which is stored on a yubikey. But this configuration is not appreciated by ansible and hence everything times out while it’s trying to exchange keys with the proxy host.

---

<div class="post-metadata">

**Author:** ![bvitnik](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/bvitnik/32/4132_2.png) [@bvitnik](https://forum.ansible.com/u/bvitnik)\
**Post date:** [December 10, 2024, 1:39pm UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/13 "2024-12-10T13:39:57Z")

</div>

That may be the case but you said that this setup with yubikey worked for you before and is not working now with Ansible 2.18. What changed in the mean time? OS version? Ansible version? Some SSH and yubikey related config?

---

<div class="post-metadata">

**Author:** ![jorgenspange](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jorgenspange/32/9667_2.png) [@jorgenspange](https://forum.ansible.com/u/jorgenspange)\
**Post date:** [December 10, 2024, 1:41pm UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/14 "2024-12-10T13:41:32Z")

</div>

That’s on me, but I dont really know exactly when this stopped working, unfortunately…

But was working one or two months ago atleast, and since then I’ve mainly ran things from our AAP deployment, and haven’t really kept track of when this setup stopped working.

---

<div class="post-metadata">

**Author:** ![shertel](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/shertel/32/1241_2.png) [@shertel](https://forum.ansible.com/u/shertel)\
**Post date:** [December 16, 2024, 9:17pm UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/15 "2024-12-16T21:17:16Z")

</div>

The `ansible_ssh_common_args` variable configured the `ssh_common_args` option for the paramiko connection plugin, which was removed in 2.18. It’s still configurable as the `proxy_command` option: [ansible.builtin.paramiko\_ssh connection – Run tasks via Python SSH (paramiko) — Ansible Community Documentation](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/paramiko_ssh_connection.html#parameter-proxy_command)

---

<div class="post-metadata">

**Author:** ![jorgenspange](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jorgenspange/32/9667_2.png) [@jorgenspange](https://forum.ansible.com/u/jorgenspange)\
**Post date:** [January 10, 2025, 7:49am UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/16 "2025-01-10T07:49:05Z")

</div>

Inserting this to ansible.cfg did the trick:

```auto
[paramiko_connection]
proxy_command = "ssh -W %h:%p -q 192.168.10.10"

```

Tried defining it within the inventory as a variable aswell, but this does not seem to work.

Thanks for all the help!

---

<div class="post-metadata">

**Author:** ![shertel](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/shertel/32/1241_2.png) [@shertel](https://forum.ansible.com/u/shertel)\
**Post date:** [January 13, 2025, 2:16pm UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/17 "2025-01-13T14:16:03Z")

</div>

You should also be able to configure this with the variable `ansible_paramiko_proxy_command` (just tested on devel and it works). If you have a template in the variable, there’s a bug that was recently fixed, and should be backported to 2.18 soon ([[2.18] fix reset\_connection with templated connection variables (#84240) by s-hertel · Pull Request #84439 · ansible/ansible · GitHub](https://github.com/ansible/ansible/pull/84439)). 🤞

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [February 12, 2025, 2:16pm UTC](https://forum.ansible.com/t/ansible-ssh-proxyjump/11289/18 "2025-02-12T14:16:15Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
