Certbot: ImportError: 'pyOpenSSL' module missing required functionality

Created on 17 Apr 2017  ·  35Comments  ·  Source: certbot/certbot

My operating system is (include version):

CentOS Linux release 7.3.1611

I installed Certbot with (certbot-auto, OS package manager, pip, etc):

OS packager manager

I ran this command and it produced this output:

certbot renew

Traceback (most recent call last):
File "/bin/certbot", line 7, in
from certbot.main import main
File "/usr/lib/python2.7/site-packages/certbot/main.py", line 17, in
from certbot import client
File "/usr/lib/python2.7/site-packages/certbot/client.py", line 10, in
from acme import client as acme_client
File "/usr/lib/python2.7/site-packages/acme/client.py", line 31, in
requests.packages.urllib3.contrib.pyopenssl.inject_into_urllib3() # type: ignore
File "/usr/lib/python2.7/site-packages/requests/packages/urllib3/contrib/pyopenssl.py", line 112, in inject_into_urllib3
_validate_dependencies_met()
File "/usr/lib/python2.7/site-packages/requests/packages/urllib3/contrib/pyopenssl.py", line 147, in _validate_dependencies_met
raise ImportError("'pyOpenSSL' module missing required functionality. "
ImportError: 'pyOpenSSL' module missing required functionality. Try upgrading to v0.14 or newer.

Certbot's behavior differed from what I expected because:

It should renew successfully instead of errors.

Here is a Certbot log showing the issue (if available):

Logs are stored in /var/log/letsencrypt by default. Feel free to redact domains, e-mail and IP addresses as you see fit.

No log entries. I've removed pyopenssl and reinstall it.

pip show pyOpenssl

Name: pyOpenSSL
Version: 16.2.0
Summary: Python wrapper module around the OpenSSL library
Home-page: https://pyopenssl.readthedocs.io/
Author: Hynek Schlawack
Author-email: [email protected]
License: Apache License, Version 2.0
Location: /usr/lib64/python2.7/site-packages
Requires: six, cryptography

But the error still persists. Any idea ?

pkging

Most helpful comment

Guys, do not mix yum installed packages via pip ones. The proper fix involves removing pip packages and install everything from yum. I have outlined it here.

You do not need newer pyOpenSSL on CentOS 7 to run certbot! Not to say relying on third packages will not lead you to anything good, eventually :)

pip uninstall requests
yum reinstall python-requests

pip uninstall six
yum reinstall python-six

pip uninstall urllib3
yum reinstall python-urllib3

All 35 comments

Maybe there are multiple pyOpenSSL versions so that urllib3 gets confused. In /usr/lib/python2.7/site-packages/requests/packages/urllib3/contrib/pyopenssl.py, there should be some lines like this:

    # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509
    # attribute is only present on those versions.
    from OpenSSL.crypto import X509
    x509 = X509()
    if getattr(x509, "_x509", None) is None:
        raise ImportError("'pyOpenSSL' module missing required functionality. "
                          "Try upgrading to v0.14 or newer.")

Could you add some debugging codes and see what's the output?

    # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509
    # attribute is only present on those versions.
    import OpenSSL.crypto
    print(OpenSSL.crypto)
    from OpenSSL.crypto import X509
    x509 = X509()
    if getattr(x509, "_x509", None) is None:
        raise ImportError("'pyOpenSSL' module missing required functionality. "
                          "Try upgrading to v0.14 or newer.")

Beware that Python doesn't like tabs. Always insert spaces for identation. Also, you need root to modify this file.

Here is the output :

certbot renew



Traceback (most recent call last):
File "/bin/certbot", line 7, in
from certbot.main import main
File "/usr/lib/python2.7/site-packages/certbot/main.py", line 17, in
from certbot import client
File "/usr/lib/python2.7/site-packages/certbot/client.py", line 10, in
from acme import client as acme_client
File "/usr/lib/python2.7/site-packages/acme/client.py", line 31, in
requests.packages.urllib3.contrib.pyopenssl.inject_into_urllib3() # type: ignore
File "/usr/lib/python2.7/site-packages/requests/packages/urllib3/contrib/pyopenssl.py", line 112, in inject_into_urllib3
_validate_dependencies_met()
File "/usr/lib/python2.7/site-packages/requests/packages/urllib3/contrib/pyopenssl.py", line 149, in _validate_dependencies_met
raise ImportError("'pyOpenSSL' module missing required functionality. "
ImportError: 'pyOpenSSL' module missing required functionality. Try upgrading to v0.14 or newer.

/usr/lib64/python2.7/site-packages/OpenSSL/crypto.so

This path looks like from an earlier pyOpenSSL package. Could you remove pyOpenSSL via yum and try again?

I am having the same problem on centos7. Removing pyOpenSSL.x86_64 0:0.13.1-3.el7 does not help, because yum install certbot will reinstall it again.

However I found a workaround for the broken RPM:

yum remove pyOpenSSL.x86_64
cd
mkdir virtualenv
cd virtualenv/
virtualenv --no-site-packages -p /usr/bin/python2.7 certbot
. ~/virtualenv/certbot/bin/activate
pip import six packaging appdirs
pip install setuptools --upgrade                                                                                                                                                                                    pip install certbot
certbot help

Same problem here on a fresh centos install.

rpm --query centos-release  # centos-release-7-3.1611.el7.centos.x86_64
wget ftp://ftp.muug.mb.ca/mirror/centos/7.3.1611/cloud/x86_64/openstack-mitaka/common/pyOpenSSL-0.15.1-1.el7.noarch.rpm
sudo rpm -Uvh pyOpenSSL-0.15.1-1.el7.noarch.rpm
sudo yum install certbot
certbot renew  # OK

I think this is more a CentOS issue rather than certbot's. Can anyone report to CentOS that their pyOpenSSL is too old?

The problem persisted on my system even after an upgrade to pyOpenSSL 16.something

The same problem occurred recently on my CentOS 7 machine.
The only working workaround is to pip install pyOpenSSL=0.13.1

The last two months, it failed.
And I tried it again just now, it failed again.

The output:

>> sudo certbot certonly --standalone -d mydomain.com

<< Traceback (most recent call last):
  File "/bin/certbot", line 9, in <module>
    load_entry_point('certbot==0.12.0', 'console_scripts', 'certbot')()
  File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 378, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 2566, in load_entry_point
    return ep.load()
  File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 2260, in load
    entry = __import__(self.module_name, globals(),globals(), ['__name__'])
  File "/usr/lib/python2.7/site-packages/certbot/main.py", line 21, in <module>
    from certbot import client
  File "/usr/lib/python2.7/site-packages/certbot/client.py", line 10, in <module>
    from acme import client as acme_client
  File "/usr/lib/python2.7/site-packages/acme/client.py", line 31, in <module>
    requests.packages.urllib3.contrib.pyopenssl.inject_into_urllib3()
  File "/usr/lib/python2.7/site-packages/requests/packages/urllib3/contrib/pyopenssl.py", line 112, in inject_into_urllib3
    _validate_dependencies_met()
  File "/usr/lib/python2.7/site-packages/requests/packages/urllib3/contrib/pyopenssl.py", line 147, in _validate_dependencies_met
    raise ImportError("'pyOpenSSL' module missing required functionality. "
ImportError: 'pyOpenSSL' module missing required functionality. Try upgrading to v0.14 or newer.

Then I try this and it works:

_20170502100430

The answer's link: https://serverfault.com/questions/830284/certbot-for-letsencrypt-missing-pyopenssl-module

Just for reference ... it's generally unsafe to update pyOpenSSL via pip on CentOS since it's possible to break yum that way.

Which certbot package are you using? I'd appreciate it if you could install 0.13.0 from epel-testing, and always ensure your system has a full yum update.

You may need to use yum reinstall pyOpenSSL to repair your system (check the state of it with rpm -qV pyOpenSSL).

There's an issue with the systemd renew timer with that package, which is why I've not pushed it stable, but just doing certbot requests and a manual certbot renew will work.

The 0.14.0 release is on it's way as well... and I literally just tested that in AWS.

I'm curious - the original author installed it via a package manager, so where would we pin a version for pip?
Are people still having this problem? And if so what install method are you using?

You may want to try the method described in this Dockerfile, which worked for me:
https://github.com/identinetics/docker-nginx/blob/master/Dockerfile#L65

Still having the problem on fresh installed and updated centOS 7.3.
Fixed the problem by installing updated pyOpenSSL rpm (pyOpenSSL-0.14-3.fc222 seemed enough, while pyOpenSSL-16.2.0-1.fc25 didn't work), but how to be sure it's not breaking anything else ?!

https://www.rpmfind.net/linux/rpm2html/search.php?query=pyOpenSSL

Thanks

@tisc0 I'm very interested in more detail over exactly how you installed and ran this to end up with that problem.

When I built the centos7 certbot packages I tested them in AWS with no problems - certainly not what you have described or this issue describes.

It's a terrible idea to install a fedora rpm like that directly on centos7 - especially with a core package like pyOpenSSL.

Hi Hogarthj,
Sorry for the lack of details, kinda busy this days :)
In short :

  • the install of the fedora rpm didn't solved the problem (only the certbot --help was working, as I recall)
  • after playing a long time with the packages, and checking it was actually working in another fresh centos 7 (with out the box packages), I re-installed them and got finally another error about urllib3 (also asking to install an updated version, which I didn't buy ;]).
  • I decided to remove/reinstall urllib3 with yum (rather than with rpm -e) and all the dependent packages ; in this case, some common packages also needed by ipa-client...
  • I re-installed (in that order) urllib3 and certbot : it worked
  • I finally re-installed ipa-client and it's now working.

[root@c7-dse ~]# echo N | yum remove python-urllib3 | awk '{print $1}'
(...)
Dependencies

==============
Package
Removing:
python-urllib3
Removing
certbot
ipa-client
python-requests
python2-acme
python2-certbot
python2-ipaclient
python2-ipalib

Any idea to explain why reinstalling some packages made it work are welcome :)

@tisc0 thanks for the additional detail

Force installing/removing packages can often cause problems - as can pip upgrades of system libraries.

It's rarely a good idea to just grab a Fedora package for CentOS use without carrying out a rebuild of the package itself from the src.rpm

By reinstalling packages (rather than doing a remove and install with dependency issues yum reinstall can be a lifesaver) the original files are verified to be in place.

I'm very glad to hear that reinstall the CentOS packages has it working for you :)

Since @tisc0 seems to have a working setup now I'm going to close this issue. If anyone is still having issues please file a new issue, as this thread is getting pretty crowded.

for CentOS7,Just do "mv /usr/lib64/python2.7/site-packages/OpenSSL /usr/lib64/python2.7/site-packages/pyOpenSSL", and that works like a charm for me!!!

Dirty hack :1st_place_medal: ;)

Just had the same issue, that is because pip install -U did overwrite the python modules installed from the RPM.

To solve this I did the following:

issue

  File "/usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py", line 147, in _validate_dependencies_met
    raise ImportError("'pyOpenSSL' module missing required functionality. "
ImportError: 'pyOpenSSL' module missing required functionality. Try upgrading to v0.14 or newer.

solution

[root@kolla ~]# rpm -qf /usr/lib64/python2.7/site-packages/OpenSSL/
pyOpenSSL-0.13.1-3.el7.x86_64
[root@kolla ~]# rpm -qf /usr/lib/python2.7/site-packages/urllib3
python-urllib3-1.10.2-2.el7_1.noarch

[root@kolla ~]# rpm --nodeps -e python-urllib3
[root@kolla ~]# rm -rf /usr/lib/python2.7/site-packages/urllib3/
[root@kolla ~]# yum -y install python-urllib3

issue

  File "/usr/lib/python2.7/site-packages/requests/__init__.py", line 90, in <module>
    from urllib3.exceptions import DependencyWarning
ImportError: cannot import name DependencyWarning
[root@kolla ~]# rpm -qf /usr/lib/python2.7/site-packages/requests
python-requests-2.6.0-1.el7_1.noarch

solution

[root@kolla ~]# rpm --nodeps -e python-requests
[root@kolla ~]# rm -rf /usr/lib/python2.7/site-packages/requests
[root@kolla ~]# yum -y install python-requests   

Update from January 29th, 2018:

Came across the same issue again, this time it was much easier to use the docker container :)

alias certbot='docker run --rm -ti -v /etc/letsencrypt:/etc/letsencrypt -p 80:80 certbot/certbot:v0.21.1'

@cnritng It's also works for me

Anyone who still has this problem, try this:

rpm --query centos-release  # centos-release-7-3.1611.el7.centos.x86_64
wget ftp://ftp.muug.ca/mirror/centos/7/cloud/x86_64/openstack-newton/common/pyOpenSSL-0.15.1-1.el7.noarch.rpm
sudo rpm -Uvh pyOpenSSL-0.15.1-1.el7.noarch.rpm
sudo yum install certbot
certbot renew  # OK

from @sulliwane . notice that the ftp://ftp.muug.ca/mirror/... address has changed.

Thanks @JellyBool

Guys, do not mix yum installed packages via pip ones. The proper fix involves removing pip packages and install everything from yum. I have outlined it here.

You do not need newer pyOpenSSL on CentOS 7 to run certbot! Not to say relying on third packages will not lead you to anything good, eventually :)

pip uninstall requests
yum reinstall python-requests

pip uninstall six
yum reinstall python-six

pip uninstall urllib3
yum reinstall python-urllib3

The above steps from @dvershinin did the trick for me

also got things working with what @dvershinin posted. just had to change the last line from "yum reinstall python-urllib3" to "yum install python-urllib3"

for CentOS7,Just do "mv /usr/lib64/python2.7/site-packages/OpenSSL /usr/lib64/python2.7/site-packages/pyOpenSSL", and that works like a charm for me!!!

The *nix like system always has the similarly problems: file dependency broken.

Guys, do not mix yum installed packages via pip ones. The proper fix involves removing pip packages and install everything from yum. I have outlined it here.

You do not need newer pyOpenSSL on CentOS 7 to run certbot! Not to say relying on third packages will not lead you to anything good, eventually :)

pip uninstall requests
yum reinstall python-requests

pip uninstall six
yum reinstall python-six

pip uninstall urllib3
yum reinstall python-urllib3

Thank you! It's work!

@dvershinin fix does notwork for me currently - after following the steps he described on Centos 7 I receive the following error:

VersionConflict: (urllib3 1.10.2 (/usr/lib/python2.7/site-packages), Requirement.parse('urllib3>=1.20,<1.26'))

@keir-lavelle my fix is only an attempt to restore a system to the original state after it was severely damaged by using pip under root user (which so many tutorials out there make people do, without accounting for the fact that it should never be done in CentOS/RHEL systems!)

So if you feel adventurous in fixing it, you may follow the link I gave which attempts at fixing it further by removing all Python packages (mind you, yum is Python-based too), which is a furthermore dangerous enterprise. (because you can break more).

  • If you can restore your server from some snapshot/backup where certbot worked, then you should be fine
  • Otherwise, the "remove all Python packages / reinstall" seems like the only way to fix (but be sure to account for consequences of doing so if, for some reason, you can't get yum to a working state).

And of course it helps to remember again: do not use pip or python installs under root. That's how it breaks in the first place. If it didn't happen - it wouldn't break.

Thanks for taking the time to explain, I'm just testing things at the moment so the server is disposable so no big deal if it breaks but appreciate the information

Was this page helpful?
0 / 5 - 0 ratings