pavelicii
pavelicii

Reputation: 1638

ParallelSSH - SessionHandshakeError when using pssh2_client

Using parallel-ssh module I'm trying to run SSH commands using Natinve Client but getting SessionHandshakeError. And if I use Paramiko Client instead, everything works fine. I met the requirement of my_pkey.pub being in the same directory as my_pkey.

Here is my code which uses Native Client (changed real IPs to 'ip1' and 'ip2'):

from pssh.pssh2_client import ParallelSSHClient

pkey = os.path.dirname(os.path.abspath(__file__)) + '/my_pkey'
hosts = ['ip1', 'ip2']
client = ParallelSSHClient(hosts, user='root', pkey=pkey)
output = client.run_command('hostname')
for host, host_output in output.items():
    for line in host_output.stdout:
        print(line)

Getting this error:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\pssh\ssh2_client.py", line 123, in _init
    self.session.handshake(self.sock)
  File "ssh2\session.pyx", line 81, in ssh2.session.Session.handshake
ssh2.exceptions.SessionHandshakeError: ('SSH session handshake failed with error code %s', -5)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\pssh\ssh2_client.py", line 123, in _init
    self.session.handshake(self.sock)
  File "ssh2\session.pyx", line 81, in ssh2.session.Session.handshake
ssh2.exceptions.SessionHandshakeError: ('SSH session handshake failed with error code %s', -5)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\pssh\ssh2_client.py", line 123, in _init
    self.session.handshake(self.sock)
  File "ssh2\session.pyx", line 81, in ssh2.session.Session.handshake
ssh2.exceptions.SessionHandshakeError: ('SSH session handshake failed with error code %s', -5)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:/Users/NazimokPP/Desktop/AnchorFree/QA-Automation/nodetest/nodetest.py", line 57, in <module>
    main(args.server_domain, args.test_type)
  File "C:/Users/NazimokPP/Desktop/AnchorFree/QA-Automation/nodetest/nodetest.py", line 45, in main
    output = client.run_command('hostname')
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\pssh\pssh2_client.py", line 182, in run_command
    encoding=encoding, use_pty=use_pty, timeout=timeout)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\pssh\base_pssh.py", line 91, in run_command
    self.get_output(cmd, output)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\pssh\base_pssh.py", line 136, in get_output
    (channel, host, stdout, stderr, stdin) = cmd.get()
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\gevent\greenlet.py", line 482, in get
    self._raise_exception()
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\gevent\greenlet.py", line 159, in _raise_exception
    reraise(*self.exc_info)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\gevent\_compat.py", line 33, in reraise
    raise value.with_traceback(tb)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\gevent\greenlet.py", line 536, in run
    result = self._run(*self.args, **self.kwargs)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\pssh\pssh2_client.py", line 188, in _run_command
    self._make_ssh_client(host)
File "C:\Program Files (x86)\Python36-32\lib\site-packages\pssh\pssh2_client.py", line 313, in _make_ssh_client
    allow_agent=self.allow_agent, retry_delay=self.retry_delay)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\pssh\ssh2_client.py", line 107, in __init__
    THREAD_POOL.apply(self._init)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\gevent\pool.py", line 325, in apply
    return self.spawn(func, *args, **kwds).get()
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\gevent\event.py", line 385, in get
    return self.get(block=False)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\gevent\event.py", line 375, in get
    return self._raise_exception()
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\gevent\event.py", line 355, in _raise_exception
    reraise(*self.exc_info)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\gevent\_compat.py", line 33, in reraise
    raise value.with_traceback(tb)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\gevent\threadpool.py", line 211, in _worker
    value = func(*args, **kwargs)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\pssh\ssh2_client.py", line 126, in _init
    return self._connect_init_retry(retries)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\pssh\ssh2_client.py", line 116, in _connect_init_retry
    return self._init(retries=retries)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\pssh\ssh2_client.py", line 126, in _init
    return self._connect_init_retry(retries)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\pssh\ssh2_client.py", line 116, in _connect_init_retry
    return self._init(retries=retries)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\pssh\ssh2_client.py", line 128, in _init
    raise SessionError(msg, self.host, self.port, ex)
pssh.exceptions.SessionError: ('Error connecting to host %s:%s - %s', 'ip1', 22, SessionHandshakeError('SSH session handshake failed with error code %s', -5))

Process finished with exit code 1

Here is my code which uses Paramiko Client (changed real IPs to 'ip1' and 'ip2'):

from pssh.pssh_client import ParallelSSHClient
from pssh.utils import load_private_key

key_path = os.path.dirname(os.path.abspath(__file__)) + '/my_pkey'
pkey = load_private_key(key_path)
hosts = ['ip1', 'ip2']
client = ParallelSSHClient(hosts, user='root', pkey=pkey)
output = client.run_command('hostname')
for host, host_output in output.items():
    for line in host_output.stdout:
        print(line)

And it works. Here's the output (should I care about warnings?):

C:\Program Files (x86)\Python36-32\lib\site-packages\paramiko\ecdsakey.py:202: CryptographyDeprecationWarning: signer and verifier have been deprecated. Please use sign and verify instead.
  signature, ec.ECDSA(self.ecdsa_curve.hash_object())
C:\Program Files (x86)\Python36-32\lib\site-packages\paramiko\rsakey.py:110: CryptographyDeprecationWarning: signer and verifier have been deprecated. Please use sign and verify instead.
  algorithm=hashes.SHA1(),
ip1.hostname
ip2.hostname

Process finished with exit code 0

What am I doing wrong with Native Client?

Upvotes: 0

Views: 932

Answers (2)

danny
danny

Reputation: 5270

This error was tracked down to the WinCNG back-end used for libssh2 on Windows - it does not support SHA-256 host key hashes which is now the default in recent versions of OpenSSH server.

The latest version of parallel-ssh, 1.6.0, fixes this issue by switching the Windows back-end to OpenSSL for better compatibility and to match the OSX and Linux binary wheels.

See release notes for more details.

Upvotes: 1

pavelicii
pavelicii

Reputation: 1638

Some explanations which I got from Panos in Google Groups thread. It didn't help me, but maybe it will be helpful for somebody else.

A -5 error is defined as a key exchange error in libssh2. It sounds like the key type is not supported by libssh2 and paramiko shows 'ecdsakey.py' being used. ECDSA keys are not currently supported by libssh2 (PR pending).

The warning are from paramiko itself, can't say if they matter.

Better exceptions for native client errors are being worked on for next release.

_

So for a private key 'my_pkey', there should be a 'my_pkey.pub' in same directory.

It may also be a case of the SSH server's key not being supported by the native client (same limitations as user keys) which would explain the key exchange error. Can check the type of key configured for the server in /etc/ssh/sshd_config, HostKey entry. There should be at least one non-ECDSA key configured, eg:

HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_dsa_key HostKey /etc/ssh/ssh_host_ecdsa_key

If there is only a ECDSA key entry, the native client will not be able to connect.

Upvotes: 0

Related Questions