seveas / python-hpilo

Accessing the HP iLO XML interface from python

Home Page:https://seveas.github.io/python-hpilo

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

HP ProLiant DL360 Gen9: No cipher can be selected

vaishalipavashe opened this issue · comments

We are using hpilo_boot ansible module. It worked with release 4.3 but fails with 4.4.1:

Error: hpilo.IloCommunicationError: Cannot establish ssl session with X.X.X.X:443: ('No cipher can be selected.',)

ansible-playbook 2.9.11
Python 3.8.5
python-hpilo 4.4.1

Tried enabling Enforce AES/3DES Encryption in iLO -> Security -> Encryption but no luck.

can you try with Python2.7.13? i'am not sure if the ssl version making the trouble. I get info with iLO3 by python2 but fail by python3.7

Yeah, I'm afraid that this is outside python-hpilo's control. More and more os'es and python distributions drop support for older ssl/tls versions. You'll need to use an older python version and maybe even an older os (to get an older openssl) to upgrade your ilo firmware to a version that supports modern tls versions.

I've traced it back to this line that was added somewhere between v4.3 and v4.4.1:

self.ssl_context.set_ciphers("RC4-SHA:" + ssl._DEFAULT_CIPHERS)

It's problematic on e.g. Python 3.9.0 on MacOS, where using the above code results in this ssl.SSLError: ('No cipher can be selected.',), but changing that line the following way (to drop "RC4-SHA") makes it work again:

-self.ssl_context.set_ciphers("RC4-SHA:" + ssl._DEFAULT_CIPHERS)
+self.ssl_context.set_ciphers(ssl._DEFAULT_CIPHERS)

I don't fully understand why Python/SSL simply won't ignore this cipher that it maybe doesn't support in that version. Documentation states:

If no cipher can be selected (because compile-time options or other configuration forbids use of all the specified ciphers), an SSLError will be raised.

ssl._DEFAULT_CIPHERS in this version of OpenSSL evaluates to DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK.

However, digging into the definition of CIPHER LIST FORMAT (v1.1.0), I see a note about the DEFAULT cipher group alias:

DEFAULT
The default cipher list. This is determined at compile time and is normally ALL:!COMPLEMENTOFDEFAULT:!eNULL. When used, this must be the first cipherstring specified.

For OpenSSL v1.1.1, it says:

The cipher list can be prefixed with the DEFAULT keyword...

Indeed, when moving the "RC4-SHA" to the end to let "DEFAULT" be first, there is no ssl.SSLError exception thrown:

-self.ssl_context.set_ciphers("RC4-SHA:" + ssl._DEFAULT_CIPHERS)
+self.ssl_context.set_ciphers(ssl._DEFAULT_CIPHERS + ":RC4-SHA")

I can't tell whether RC4-SHA will actually work as I don't have iLO that supports it and likely this version of Python/OpenSSL would not, but I believe is a generally more compatible way of expressing the original intention of this code.

Tested on:

Python 3.9.0 (default, Nov 21 2020, 14:55:42)
[Clang 12.0.0 (clang-1200.0.32.27)] on darwin
ssl.OPENSSL_VERSION = 'OpenSSL 1.1.1h 22 Sep 2020'