ParallelSSH - SessionHandshakeError when using pssh2_client - python

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?

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.

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.

Related

pymongo: Resolver configuration could not be read or specified no nameservers

It's my first time using MongoDB but I can't seem to fix this one issue, my friend who uses MongoDB doesn't know how to use python so he can't really help me.
Here's my code:
import pymongo
# Replace the uri string with your MongoDB deployment's connection string.
conn_str = "mongodb+srv://sqdnoises:{mypass}#sqd.d4kjb.mongodb.net/myFirstDatabase?retryWrites=true&w=majority"
# set a 5-second connection timeout
client = pymongo.MongoClient(conn_str, serverSelectionTimeoutMS=5000)
try:
print(client.server_info())
print('\n\n\n aka connected')
except Exception:
print("Unable to connect to the server.")
Where {mypass} is my MongoDB password.
I keep getting this error:
Traceback (most recent call last):
File "/data/data/com.termux/files/usr/lib/python3.9/site-packages/dns/resolver.py", line 782, in read_resolv_conf
f = stack.enter_context(open(f))
FileNotFoundError: [Errno 2] No such file or directory: '/etc/resolv.conf'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/data/data/com.termux/files/usr/lib/python3.9/site-packages/pymongo/srv_resolver.py", line 88, in _resolve_uri
results = _resolve('_' + self.__srv + '._tcp.' + self.__fqdn,
File "/data/data/com.termux/files/usr/lib/python3.9/site-packages/pymongo/srv_resolver.py", line 41, in _resolve
return resolver.resolve(*args, **kwargs)
File "/data/data/com.termux/files/usr/lib/python3.9/site-packages/dns/resolver.py", line 1305, in resolve
return get_default_resolver().resolve(qname, rdtype, rdclass, tcp, source,
File "/data/data/com.termux/files/usr/lib/python3.9/site-packages/dns/resolver.py", line 1278, in get_default_resolver
reset_default_resolver()
File "/data/data/com.termux/files/usr/lib/python3.9/site-packages/dns/resolver.py", line 1290, in reset_default_resolver
default_resolver = Resolver()
File "/data/data/com.termux/files/usr/lib/python3.9/site-packages/dns/resolver.py", line 734, in __init__
self.read_resolv_conf(filename)
File "/data/data/com.termux/files/usr/lib/python3.9/site-packages/dns/resolver.py", line 785, in read_resolv_conf
raise NoResolverConfiguration
dns.resolver.NoResolverConfiguration: Resolver configuration could not be read or specified no nameservers.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/storage/emulated/0/! workspace/mongolearn/main.py", line 7, in <module>
client = pymongo.MongoClient(conn_str, serverSelectionTimeoutMS=5000)
File "/data/data/com.termux/files/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 677, in __init__
res = uri_parser.parse_uri(
File "/data/data/com.termux/files/usr/lib/python3.9/site-packages/pymongo/uri_parser.py", line 532, in parse_uri
nodes = dns_resolver.get_hosts()
File "/data/data/com.termux/files/usr/lib/python3.9/site-packages/pymongo/srv_resolver.py", line 119, in get_hosts
_, nodes = self._get_srv_response_and_hosts(True)
File "/data/data/com.termux/files/usr/lib/python3.9/site-packages/pymongo/srv_resolver.py", line 99, in _get_srv_response_and_hosts
results = self._resolve_uri(encapsulate_errors)
File "/data/data/com.termux/files/usr/lib/python3.9/site-packages/pymongo/srv_resolver.py", line 95, in _resolve_uri
raise ConfigurationError(str(exc))
pymongo.errors.ConfigurationError: Resolver configuration could not be read or specified no nameservers.
How do I fix this?
I am following https://docs.mongodb.com/drivers/pymongo/
indeed, the problem is that dnspython tries to open /etc/resolv.conf
import dns.resolver
dns.resolver.default_resolver=dns.resolver.Resolver(configure=False)
dns.resolver.default_resolver.nameservers=['8.8.8.8']
Just adde this code to the top of your main code, and that should be sufficient to get you past this hurdle..

Asn1 parsing error when trying to connect to mongo atlas

I am using MongoDB atlas for my discord bot but recently ran into an error. On the hosting (Heroku) everything works without errors, I first updated all the modules, but the error has not disappeared.
I am using motor as a driver to work with MongoDB atlas.
Checked the database connection URL, everything is correct.
Python version 3.10(on Heroku too)
Traceback (most recent call last):
File "D:\Проекты\AkainuBot\main.py", line 23, in <module>
mongo = AsyncIOMotorClient(
File "D:\Python\lib\site-packages\motor\core.py", line 159, in __init__
delegate = self.__delegate_class__(*args, **kwargs)
File "D:\Python\lib\site-packages\pymongo\mongo_client.py", line 718, in __init__
self.__options = options = ClientOptions(
File "D:\Python\lib\site-packages\pymongo\client_options.py", line 165, in __init__
self.__pool_options = _parse_pool_options(options)
File "D:\Python\lib\site-packages\pymongo\client_options.py", line 132, in _parse_pool_options
ssl_context, ssl_match_hostname = _parse_ssl_options(options)
File "D:\Python\lib\site-packages\pymongo\client_options.py", line 98, in _parse_ssl_options
ctx = get_ssl_context(
File "D:\Python\lib\site-packages\pymongo\ssl_support.py", line 159, in get_ssl_context
ctx.load_verify_locations(certifi.where())
File "D:\Python\lib\site-packages\pymongo\pyopenssl_context.py", line 276, in load_verify_locations
self._callback_data.trusted_ca_certs = _load_trusted_ca_certs(cafile)
File "D:\Python\lib\site-packages\pymongo\ocsp_support.py", line 79, in _load_trusted_ca_certs
_load_pem_x509_certificate(cert_data, backend))
File "D:\Python\lib\site-packages\cryptography\x509\base.py", line 436, in load_pem_x509_certificate
return rust_x509.load_pem_x509_certificate(data)
ValueError: error parsing asn1 value: ParseError { kind: InvalidValue, location: ["RawCertificate::tbs_cert", "TbsCertificate::serial"] }
I've solved my problem getting the parsing asn1 value error by adding the ssl_cert_reqs option on the MongoClient (and obviously importing ssl).
dbClient = pymongo.MongoClient(uri, ssl_cert_reqs=ssl.CERT_NONE)

ldap.OPT_X_TLS_CACERTDIR is not working with certificate file in the directory

My certificate is present in /etc/certs/mycer.pem file and I am able to authenticate with ldap using code below:
import ldap
import os
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND)
ls = ldap.initialize('ldaps://<ip>:10636')
ls.set_option(ldap.OPT_REFERRALS, 0)
ls.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
ls.set_option(ldap.OPT_X_TLS_CACERTFILE, "/etc/certs/mycer.pem") # line 7
ls.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
ls.simple_bind_s('uid=admin,ou=system', 'secret')
But if I change OPT_X_TLS_CACERTFILE to OPT_X_TLS_CACERTDIR in line 7 as:
ls.set_option(ldap.OPT_X_TLS_CACERTDIR, "/etc/certs/")
Code is not able to authenticate and throws error
>>> ls.simple_bind_s('uid=admin,ou=system', 'secret')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/dist-packages/ldap/ldapobject.py", line 445, in simple_bind_s
msgid = self.simple_bind(who,cred,serverctrls,clientctrls)
File "/usr/local/lib/python3.6/dist-packages/ldap/ldapobject.py", line 439, in simple_bind
return self._ldap_call(self._l.simple_bind,who,cred,RequestControlTuples(serverctrls),RequestControlTuples(clientctrls))
File "/usr/local/lib/python3.6/dist-packages/ldap/ldapobject.py", line 331, in _ldap_call
reraise(exc_type, exc_value, exc_traceback)
File "/usr/local/lib/python3.6/dist-packages/ldap/compat.py", line 44, in reraise
raise exc_value
File "/usr/local/lib/python3.6/dist-packages/ldap/ldapobject.py", line 315, in _ldap_call
result = func(*args,**kwargs)
ldap.SERVER_DOWN: {'desc': "Can't contact LDAP server", 'info': '(unknown error code)'}
There is only one file in the directory. How can python-ldap use multiple certificate files if this is not the correct way.
As I understand it, python will use OpenSSL and it subsequently scans the OPT_X_TLS_CACERTDIR directory for certificate files named *.crt.
But I cannot for the life of me find the source of that wisdom.
Edit:
I found an old script of mine that contains both:
conn.set_option(ldap.OPT_X_TLS_CACERTFILE, "")
conn.set_option(ldap.OPT_X_TLS_CACERTDIR, "/etc/ssl/cacerts")
Could it be that this empty OPT_X_TLS_CACERTFILE setting is somehow required?

Twisted reactor.listenUNIX erroring after update to python 3.8

I have updated twisted from 13.0.0 to 20.3.0 and python from 2.7 to 3.8 and now twisted is throwing this not helpful error. (Ubuntu 16.04.6 LTS)
I verified the permissions of the .sock file and the directory, made sure the socket file is deleted before reactor.listenUNIX is called.
What could be the cause of this and how can I troubleshoot this issue?
class UserServer(Plugin):
def setup(self):
socket = self.parent.socket
if os.path.exists(socket):
os.remove(socket)
self.console(socket)
self.console(self.parent.config.get_umask('sock'))
self.factory = UserServerFactory(self.parent)
reactor.listenUNIX(socket, self.factory, mode=self.parent.config.get_umask('sock'))
service: 'user_server' failed to initialize
Traceback (most recent call last):
File "/home/mcgen/tools/mark2/mk2/plugins/__init__.py", line 335, in load
plugin = cls(self.parent, name, **kwargs)
File "/home/mcgen/tools/mark2/mk2/plugins/__init__.py", line 165, in __init__
self.setup()
File "/home/mcgen/tools/mark2/mk2/services/user_server.py", line 148, in setup
reactor.listenUNIX(socket, self.factory, mode=self.parent.config.get_umask('sock'))
File "/usr/local/lib/python3.8/dist-packages/twisted/internet/posixbase.py", line 397, in listenUNIX
p.startListening()
File "/usr/local/lib/python3.8/dist-packages/twisted/internet/unix.py", line 408, in startListening
self.startReading()
File "/usr/local/lib/python3.8/dist-packages/twisted/internet/abstract.py", line 435, in startReading
self.reactor.addReader(self)
File "/usr/local/lib/python3.8/dist-packages/twisted/internet/epollreactor.py", line 109, in addReader
self._add(reader, self._reads, self._writes, self._selectables,
File "/usr/local/lib/python3.8/dist-packages/twisted/internet/epollreactor.py", line 96, in _add
self._poller.register(fd, flags)
OSError: [Errno 22] Invalid argument

Python ftplib - retrbinary fails with timeout for zero byte files

Using Python 2.6 and downloading files from an FTP server in passive mode, I found that retrbinary fails with a timeout if the source file is empty (0 bytes). Is this a bug or am I missing a configuration option?
ftp.retrbinary('RETR digital.conf', open('digital.conf','wb').write)
Downloading digital.conf
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "download.py", line 13, in run
ftp.retrbinary('RETR %s' % source, callback)
File "c:\Python26\lib\ftplib.py", line 398, in retrbinary
conn = self.transfercmd(cmd, rest)
File "c:\Python26\lib\ftplib.py", line 360, in transfercmd
return self.ntransfercmd(cmd, rest)[0]
File "c:\Python26\lib\ftplib.py", line 337, in ntransfercmd
resp = self.getresp()
File "c:\Python26\lib\ftplib.py", line 216, in getresp
raise error_temp, resp
ftplib.error_temp: 421 Timeout
Other non-zero byte files transfer fine.
This is Your session idle time too long.You can file after the President into instantiate ftplib. Otherwise. Modify ftp software configuration.
For example, you use vsftpd, you can add the following configuration to vsftpd.conf:
idle_session_timeout=60000 # The default is 600 seconds

Categories