Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSH ProxyCommand support #153

Closed
sergzin opened this issue Apr 14, 2014 · 11 comments
Closed

SSH ProxyCommand support #153

sergzin opened this issue Apr 14, 2014 · 11 comments
Assignees

Comments

@sergzin
Copy link
Contributor

sergzin commented Apr 14, 2014

To establish connection via intermedate security hardened box.

@jeremyschulman
Copy link
Contributor

@sergzin - are you asking if the library supports using SSH-tunneling through a jumphost; i.e. a security hardended box? If so, that functionality is supported and I can provide details. If you are looking for something else, could you please include a URL to the functionality of ProxyCommand you are inquiring about? Thank you!

@sergzin
Copy link
Contributor Author

sergzin commented Apr 15, 2014

yes,
I am looking for a way to connect through a jumphost.
something like this: ssh -o ProxyCommand="ssh -W %h:%p jumphost.example.org" server.example.org

http://en.wikibooks.org/wiki/OpenSSH/Cookbook/Proxies_and_Jump_Hosts#Passing_through_a_gateway_using_netcat_mode

Thank you.

@jeremyschulman
Copy link
Contributor

@sergzin - Ok, so the py-junos-eznc will support jumphosting natively. You will need to setup your ssh config file (typically $HOME/.ssh/config) and have the tunnel active prior. Here is a blog that talks about the process. Here.

Hope this helps!

@yang-dev
Copy link

I can't get nested proxycommand to work.

In my SSH config,

  • Host router -> ProxyCommand through jumphost_inside
  • Host jumphost_inside -> ProxyCommand through jumphost_outside

ERROR:ncclient.transport.ssh:Exception: Error reading SSH protocol banner with _read_timeout()

in https://github.com/Juniper/py-junos-eznc/blob/master/lib/jnpr/junos/device.py I am not seeing anything loading proxycommand at all

@dhanakane
Copy link

I can't get nested proxycommand to work.

In my SSH config,

* Host router -> ProxyCommand through jumphost_inside

* Host jumphost_inside -> ProxyCommand through jumphost_outside

ERROR:ncclient.transport.ssh:Exception: Error reading SSH protocol banner with _read_timeout()

in https://github.com/Juniper/py-junos-eznc/blob/master/lib/jnpr/junos/device.py I am not seeing anything loading proxycommand at all

To make things worse, the docs on the Juniper website are also inaccurate.

Also, starting in Junos PyEZ Release 1.2, Junos PyEZ provides support for ProxyCommand, which enables you to access a target device through an intermediary host that supports netcat. This is useful when you can only log in to the target device through the intermediate host.

If it helps the maintainers, then this feature is available in Netmiko which builds on Paramiko. ProxyJump can also be used on Paramiko. It would be really nice to have a fix for this one. I've read the blog post which asks the user to setup port forwarding and then run a shell command to open up a tunnel prior to running the program/script. This is counterinituitive. If SSH can support proxying, and the library can interpret SSH config files then it should be able to honour what's in the file.

@vnitinv
Copy link
Contributor

vnitinv commented Mar 20, 2020

@dhanakane Will work and get this closed by next week.

@a-v-popov
Copy link

a-v-popov commented Mar 20, 2020

It is working for me (please note it doesn't mean it is working for everybody):

$ cat ~/.ssh/config-lab
Host lab
  HostName x.x.x.x
  IdentityFile ~/.ssh/key_rsa
  ControlMaster auto
  ControlPath ~/.ssh/cm/%r@%h-%p
  ControlPersist 60
 
Host * !lab
  ProxyCommand ssh -W %h:%p -q lab
$ python
Python 3.6.10 (default, Mar  9 2020, 12:07:57)
[GCC 9.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from jnpr.junos import Device
>>> dev = Device(host="mx480", user="qwe",password="asd", ssh_config="~/.ssh/config-lab", port=22)
>>> dev.open()
Device(mx480)
>>> dev.close()

ProxyCommand is loaded by ncclient here:
https://github.com/ncclient/ncclient/blob/6a2b112388142362c2cdc43e87586e185157d038/ncclient/transport/ssh.py#L273

You can verify if it is working in the debug logs:

>>> import logging
>>> logging.basicConfig(level=0)
>>> dev.open()
DEBUG:ncclient.transport.session:[host None session 0x7f72bc098828] <SSHSession(session, initial daemon)> created: client_capabilities=<dict_keyiterator object at 0x7f72bbea1868>
DEBUG:ncclient.transport.ssh:[host mx480 session 0x7f72bc098828] Configuring Proxy. ssh -W mx480:22 -q lab
...

Or try to mimic the same thing manually:

>>> import paramiko
>>> import os
>>> ssh_config = open(os.path.expanduser("~/.ssh/config-lab"))
>>> config = paramiko.SSHConfig()
>>> config.parse(ssh_config)
>>> config=config.lookup("mx480")
>>> config.get("proxycommand")
'ssh -W mx480:22 -q lab'
>>>

Please note that I am using keys to authenticate to the jumphost and the keys are load into agent, which can be confirmed by ssh-add -l

@jalphonso
Copy link

jalphonso commented Mar 20, 2020

@dhanakane the error you see "Error reading SSH protocol banner" in this case is because hostname/ip resolution of the end device on the jumphost fails. Try adding the host entry to /etc/hosts on the jumphost and remove the Hostname param from your ssh config for the device that requires the jumphost. This should resolve it in the interim.

@a-v-popov
Copy link

If we have config like this

Host mx480
  HostName 192.168.100.22
  ProxyCommand ssh -W %h:%p -q lab

PyEZ will overwrite Host with Hostname here:

self._hostname = found.get('hostname', self._hostname)

It is then passed to ncclient as host. As result ncclient will be trying to get config for wrong Host and fail to get ProxyCommand.

@dhanakane
Copy link

dhanakane commented Mar 24, 2020

@a-v-popov do you mean that token expansion breaks? When I debug with a known working SSH config file using ProxyCommand (i.e: I can ssh somehostnamenotinDNSusingajumphost from the command line and it works fine) it looks like token expansion will expand it to the IP address.

In my case, Host in my SSH config file is not in DNS, so it must use the HostName entry which has the IP address for the target device when connecting. Also, my code does not use IP addresses because that's not super readable to maintain a mapping of hostnames to IP addresses, but I could work around this by wrapping the call to the Device module.

I'm currently working around this using local portforwarding with wrapped subprocess calls to turn up and turn down the tunnel. Super hacky, but I have no choice until there's a fix that honours my SSH config file.

@jalphonso that was not the error I was referring to, but thanks for chiming in. I learned something else there.

@a-v-popov
Copy link

You don't need to resolve it locally. It should be resolvable on the jumphost.
If you cannot fix hostname resolution on the jumphost, you could try to embed IP in ProxyCommand.

apopov@gentoo ~/.ssh $ cat config-test3
Host lab
  HostName x.x.x.x
  IdentityFile ~/.ssh/key_rsa

host mx480
  ProxyCommand ssh -W 192.168.100.22:%p -q lab

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants