月下博客

certbot: ImportError: ‘pyOpenSSL’ module missing required functionality

接之前的文章: 使用Let’s Encrypt的免费证书

今天在新的服务器上使用certbot安装证书,出现了如下错误提示: ImportError: ‘pyOpenSSL’ module missing required functionality. Try upgrading to v0.14 or newer.

错误相关跟踪栈信息为:

Traceback (most recent call last):
  File "/usr/bin/certbot", line 9, in <module>
    load_entry_point('certbot==0.13.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 17, in </module><module>
    from certbot import client
  File "/usr/lib/python2.7/site-packages/certbot/client.py", line 10, in </module><module>
    from acme import client as acme_client
  File "/usr/lib/python2.7/site-packages/acme/client.py", line 31, in </module><module>
    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 in
ject_into_urllib3
    _validate_dependencies_met()
  File "/usr/lib/python2.7/site-packages/requests/packages/urllib3/contrib/pyopenssl.py", line 147, in _v
alidate_dependencies_met
    raise ImportError("'pyOpenSSL' module missing required functionality. "
ImportError: 'pyOpenSSL' module missing required functionality. Try upgrading to v0.14 or newer.
</module>

使用最后一行的信息在搜索引擎上找问题,发现github上已经有相关的issue。主要原因是RHEL/CentOS的官方源和epel源的pyOpenSSL版本太旧了,新版的certbot依赖于高版本的pyOpenSSL库,从而失败。参与讨论的部分人指出: 这是(CentOS)系统的问题而非certbot的问题

issue中提出的解决方案包括: 限定pyOpenSSL的版本: pip install pyOpenSSL=0.13.1, 测试失败;作者建议使用epel-testing库中的v0.13版本,但实测开启epel-testing源安装v0.13版本存在同样的问题。

如何解决这个突然的错误?想到certbot是python程序,从pip安装或许能够绕过系统的pyOpenSSL限制。以下是解决问题的尝试过程:

  1. 错误提示使用v0.14或者更新版本,先看看pip中的版本: pip search certbot,显示版本为0.14.0;
  2. 卸载yum安装的certbot和pyOpenSSL: yum remove certbot pyOpenSSL;
  3. 升级pip(如果不是最新版本,pip会提示你升级后再使用): pip install --upgrade pip
  4. pip安装certbot: pip install certbot。 碰到了Python.h或者pyconfig.h找不到的错误,于是安装Python的devel包: yum install -y python-devel;再次运行命令,提示找不到opensslv.h头文件,于是安装OpenSSL的devel包: yum install -y openssl-devel;再次运行pip install certbot命令,成功安装certbot;
  5. 测试certbot是否可用: certbot certificates。输出正常,说明pip安装了最新版的certbot,并且能正确运行。

参考

  1. https://serverfault.com/questions/830284/certbot-for-letsencrypt-missing-pyopenssl-module
  2. https://github.com/certbot/certbot/issues/4514