Search code examples
pythonpython-2.7pipopenssldebian

sudo pip list: OpenSSL issue


If I try one of the following commands:

  • sudo pip list
  • sudo pip uninstall <something>

I always get this error:

/usr/local/lib/python2.7/dist-packages/cryptography/hazmat/primitives/constant_time.py:26: CryptographyDeprecationWarning: Support for your Python version is deprecated. The next version of cryptography will remove support. Please upgrade to a release (2.7.7+) that supports hmac.compare_digest as soon as possible.
  utils.PersistentlyDeprecated2018,
Traceback (most recent call last):
  File "/usr/local/bin/pip", line 9, in <module>
    load_entry_point('pip==20.0.2', 'console_scripts', 'pip')()
  File "/usr/local/lib/python2.7/dist-packages/pip/_internal/cli/main.py", line 73, in main
    command = create_command(cmd_name, isolated=("--isolated" in cmd_args))
  File "/usr/local/lib/python2.7/dist-packages/pip/_internal/commands/__init__.py", line 96, in create_command
    module = importlib.import_module(module_path)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/usr/local/lib/python2.7/dist-packages/pip/_internal/commands/list.py", line 13, in <module>
    from pip._internal.cli.req_command import IndexGroupCommand
  File "/usr/local/lib/python2.7/dist-packages/pip/_internal/cli/req_command.py", line 15, in <module>
    from pip._internal.index.package_finder import PackageFinder
  File "/usr/local/lib/python2.7/dist-packages/pip/_internal/index/package_finder.py", line 21, in <module>
    from pip._internal.index.collector import parse_links
  File "/usr/local/lib/python2.7/dist-packages/pip/_internal/index/collector.py", line 12, in <module>
    from pip._vendor import html5lib, requests
  File "/usr/local/lib/python2.7/dist-packages/pip/_vendor/requests/__init__.py", line 97, in <module>
    from pip._vendor.urllib3.contrib import pyopenssl
  File "/usr/local/lib/python2.7/dist-packages/pip/_vendor/urllib3/contrib/pyopenssl.py", line 48, in <module>
    from cryptography.hazmat.backends.openssl import backend as openssl_backend
  File "/usr/local/lib/python2.7/dist-packages/cryptography/hazmat/backends/openssl/__init__.py", line 7, in <module>
    from cryptography.hazmat.backends.openssl.backend import backend
  File "/usr/local/lib/python2.7/dist-packages/cryptography/hazmat/backends/openssl/backend.py", line 75, in <module>
    from cryptography.hazmat.bindings.openssl import binding
  File "/usr/local/lib/python2.7/dist-packages/cryptography/hazmat/bindings/openssl/binding.py", line 205, in <module>
    _verify_openssl_version(Binding.lib)
  File "/usr/local/lib/python2.7/dist-packages/cryptography/hazmat/bindings/openssl/binding.py", line 169, in _verify_openssl_version
    "You are linking against OpenSSL 1.0.1, which is no longer "
RuntimeError: You are linking against OpenSSL 1.0.1, which is no longer supported by the OpenSSL project. You need to upgrade to a newer version of OpenSSL.

The error is pretty clear, I know! What's unclear is:

  • Why can't I just list my installed packages? OpenSSL error... with pip list?! What does OpenSSL have to do with the list of installed packages?! I just want to see what's installed on my server
  • Why can't I just uninstall a package? Again, what does OpenSSL have to do with it?
  • I have a server identical to the server with this problem (Debian 7, same OpenSSL version, same Python version) but on the other server everything works without problems (there isn't even a warning)

Additional info:

  • Python version: Python 2.7.3
  • OpenSSL version: OpenSSL 1.0.1e 11 Feb 2013
  • OS: Debian GNU/Linux 7

Solution

  • Python packaging is "fun". Let's go on an adventure!

    pip vendors urllib3, which automatically uses pyOpenSSL if it is present on Python < 2.7.9. This is done because Python < 2.7.9 does not support SNI in TLS; a critical modern feature. pyOpenSSL, in turn, depends on cryptography, which dropped 1.0.1 support in version 2.9. So when you attempt to do anything in pip it triggers an import sequence that results in this error.

    The (likely) reason that you don't see this problem on another nearly identical server is that cryptography also ships binary wheels that statically link newer OpenSSLs. If you are on pip 8.x or better (which you likely were on the server that works and likely were not on the server that is broken) it will fetch a wheel linked against OpenSSL 1.1.1-latest (provided you're on x86_64. i686 wheels were dropped in 2.7).

    Given the error message you're seeing you're almost certainly running cryptography 2.9.x on the broken server. That version supports an environment variable workaround. So if you do CRYPTOGRAPHY_ALLOW_OPENSSL_101=1 pip list it should work.

    If that works then you should immediately upgrade cryptography. Since you're now running pip 20.x on this server the command CRYPTOGRAPHY_ALLOW_OPENSSL_101=1 pip install -U cryptography should install version 3.1 from a wheel (assuming you're running on x86_64).

    If you are not running on x86_64 then you have two options (that don't involve upgrading your distribution, which you should since wheezy is long out of support!):

    1. Always pass CRYPTOGRAPHY_ALLOW_OPENSSL_101 and never upgrade cryptography again (2.9.2 being the last version that even secretly supports 1.0.1)
    2. Downgrade cryptography to 2.8 and also never upgrade it again.