使用OpenSSL时出现SSL后端错误

89
我试图使用pip在虚拟环境中安装pycurl,但我收到了以下错误信息。
ImportError: pycurl: libcurl link-time ssl backend (openssl) is different from compile-time ssl backend (none/other)

我阅读了一些文档,其中提到:“要解决这个问题,你需要告诉setup.py使用哪个SSL后端”(来源),但是我不确定该如何做,因为我是使用pip安装的pycurl。

请问我如何在使用pip安装pycurl时指定SSL后端呢?

谢谢。


1
你的操作系统是什么? - Evgenii
26个回答

125

对于大多数人而言

阅读安装文件后,我通过设置环境变量并重新安装解决了我的问题。

# remove existing `pycurl` installation 
pip uninstall pycurl

# export variable with your link-time ssl backend (which is openssl above)
export PYCURL_SSL_LIBRARY=openssl

# then, re-install `pycurl` with **no cache**
pip install pycurl --no-cache-dir

可能有其他解决方案,但这对于我在virtualenvpip安装上完美地运作。

有些人遇到不同的错误信息,抱怨nss而不是openssl

ImportError: pycurl:libcurl链接时ssl后端(nss)

(关键部分是nss),所以您必须针对此错误消息执行某些操作:

pip uninstall pycurl
pip install --no-cache-dir --compile --compile-options="--with-nss" pycurl

2
谢谢,PYCURL_SSL_LIBRARY=openssl 完美地运行了! - thnee
对于_mac os x_用户:如果您使用的是_fish_控制台而不是_bash_,请记住使用set -x PYCURL_SSL_LIBRARY openssl而不是export PYCURL_SSL_LIBRARY=openssl - Serge
13
使用命令 "pip install pycurl --no-cache-dir" 安装pycurl库,其中 "--no-cache-dir" 选项表示不使用缓存。 - Shuguang Yang
谢谢。我查看了许多可能的解决方案来解决这个问题。这个解决方案第一次就奏效了。 - Matthew Setter
逐步虚拟环境安装示例 https://yippeecode.com/view-code/343QWQT144/如何在Linux Centos7中安装pycurl并修复SSL后端错误 - helloworld2013
除非在我的情况下必须使用 export PYCURL_SSL_LIBRARY=nss,因为这是我系统上安装的内容。 - caram

78

helloworld2013的回答是正确的,但关键在于匹配pycurl所期望的SSL库。错误信息可能如下所示:

pycurl: libcurl链接时的SSL后端(<library>)与编译时的SSL后端(<library>或“none/other”)不同

要修复它,您必须使用pycurl期望的库。在我的情况下,我的错误是“pycurl: libcurl链接时的SSL后端(nss)与编译时的SSL后端(openssl)不同”,所以我的解决方法是:

pip uninstall pycurl
export PYCURL_SSL_LIBRARY=nss
pip install pycurl

1
太棒了。这应该会获得更多的投票。原始答案适用于某些机器。这个答案是根据您的平台更一般化的修复方式。 - Nishant
6
在 Mac 上,这对我没有用。似乎 PYCURL_SSL_LIBRARY 完全被忽略了。 对于我来说,编译时的 SSL 后端始终为“(none/other)”,尽管 echo PYCURL_SSL_LIBRARY 显示的是 openssl - Edward Newell
1
就像@EdwardNewell所说,这个修复方法在Scientific Linux(Rhel)上对我没有用,尽管我已经指定了PYCURL_SSL_LIBRARY的nss,但后端仍然是(none/other)。 - Yondaime008
3
在Mac上,我移除了pycurl并使用以下标记进行安装:pip install --global-option="--with-openssl" --global-option=build_ext --global-option="-L/usr/local/opt/openssl/lib" --global-option="-I/usr/local/opt/openssl/include" pycurl - eigenein
2
这个方法可行,但只适用于在CentOS 7.3上使用以下选项进行安装:pip install pycurl --compile --no-cache-dir - Robert Yi
显示剩余2条评论

59

使用macOS 10.13,brew安装的openSSL和virtualenv,我成功地完成了以下操作:

# cd to your virtualenv, then…
pip uninstall pycurl
export PYCURL_SSL_LIBRARY=openssl
export LDFLAGS=-L/usr/local/opt/openssl/lib
export CPPFLAGS=-I/usr/local/opt/openssl/include
pip install pycurl --compile --no-cache-dir

5
是的,在MacOS 10.13.1(High Sierra)上,这就行了!非常感谢! 为了重新安装openssl: “brew reinstall openssl” - Denis Arnaud
1
已解决Mac OSX 10.13.4上的问题!谢谢。 - user1192748
1
谢谢!还解决了我的问题。Mac OSX 10.13.4 - Kyias
尝试了Michael Wilson的命令后,我尝试了import pycurl,结果出现了以下错误:ImportError: pycurl: libcurl link-time ssl backend (none/other) is different from compile-time ssl backend (openssl) - Daryl Spitzer
2
Daryl,很抱歉听到这个消息!在我的Mojave上它又可以工作了,所以我不确定出了什么问题。 - Michael Wilson
显示剩余2条评论

25

使用pip 7.1,您可以将以下内容放入要求文件中:

pycurl==7.19.5.1 --global-option="--with-nss"

只需将 nss 替换为相应的 SSL 后端库。


1
这个解决方案比导出变量并重新安装更好,因为它可以在 requirements.txt 文件中共享,而且不必每个用户都重复。 - dfarrell07
1
在CentOS 7上,我的导出无法工作。但是设置全局选项可以解决问题。谢谢! - Aaron Nguyen
我不得不结合你的解决方案和@Michael Wilson的来使它在macOS上运行。看起来像是一个加密问题 - 这里有一些讨论:https://github.com/pyca/cryptography/issues/3489 - kip2

20

Mac OS High Sierra更新后修复pycurl的方法:

  1. 重新安装curl库以使用OpenSSL而不是SecureTransport

brew install curl --with-openssl
  • 使用正确的构建环境和路径安装pycurl

  • export PYCURL_SSL_LIBRARY=openssl
    pip uninstall pycurl 
    pip install --no-cache-dir --global-option=build_ext --global-option="-L/usr/local/opt/openssl/lib" --global-option="-I/usr/local/opt/openssl/include" --user pycurl
    

    2
    在 High Sierra 上(使用 virtualenv)对我有效。 - djangoat
    1
    是的!还请查看这篇文章 https://cscheng.info/2018/01/26/installing-pycurl-on-macos-high-sierra.html - somecallitblues
    在 High Sierra 上(使用 virtualenv),这对我起作用了,但我必须删除 --user 标志。 - user495732 Why Me
    非常感谢!那真是太有帮助了。在运行High Sierra并花费了几个小时后,这是唯一有效的解决方案 :) - Alessandro
    在没有使用--user的情况下执行上述操作后,似乎成功安装了。但是当我执行import pycurl时,出现了以下错误:ImportError: pycurl: libcurl link-time ssl backend (none/other) is different from compile-time ssl backend (openssl) - Daryl Spitzer
    显示剩余2条评论

    19

    这对我起作用了:

    pip uninstall pycurl
    export PYCURL_SSL_LIBRARY=nss
    easy_install pycurl
    

    对我来说,这些都没用(请注意区别只是easy_install和pip):

    pip uninstall pycurl
    export PYCURL_SSL_LIBRARY=[nss|openssl|ssl|gnutls]
    pip install pycurl
    #xor
    curl -O https://pypi.python.org/packages/source/p/pycurl/pycurl-7.19.3.1.tar.gz
    #...
    python setup.py --with-[nss|openssl|ssl|gnutls] install
    

    1
    “easy_install”选项是唯一有效的选项。我不明白为什么这么复杂。我需要“export PYCURL_SSL_LIBRARY=openssl”。我的编译库报告了“none/other”。 - CMCDragonkai
    刚遇到了这个问题,这个解决方案是唯一有效的。 - Boudewijn Aasman
    2
    根据我的经验,pip 无法完全删除与操作系统安装的旧版本 pycurl 相关的文件(在我的情况下是在Centos7.2上)。Pip 没有触及早期版本中 /usr/lib64/python2.7/site-packages/pycurl.so 和 egg-info 文件。而另一方面,easy_install 则会将以上文件以及放置 pycurl egg 到 site-packages 下的文件全部清除。 - sokhaty
    尝试了以上所有方法都没用。当我的原始错误信息是 ImportError: pycurl: libcurl link-time ssl backend (openssl) is different from compile-time ssl backend (none/other)时,这个方法对我有用。 - James McCormac

    10

    我遇到了这个问题好几天。最终,在其他答案的帮助下(主要是Alexander Tyapkov的),我让它在AWS Elastic Beanstalk上工作。

    手动安装(通过SSH连接):

    sudo pip uninstall pycurl
    curl -O https://pypi.python.org/packages/source/p/pycurl/pycurl-7.43.0.tar.gz
    sudo pip install pycurl-7.43.0.tar.gz --global-option="--with-nss"
    

    重要提示: 请注意确保您使用的是正确版本的Python和PIP,否则可能会将其编译为Python 2.x并使用v3.x。

    Elastic Beanstalk中的自动安装:

    files:
      "/usr/local/share/pycurl-7.43.0.tar.gz" :
        mode: "000644"
        owner: root
        group: root
        source: https://pypi.python.org/packages/source/p/pycurl/pycurl-7.43.0.tar.gz
    
    commands:
      01_download_pip3:
        # run this before PIP installs requirements as it needs to be compiled with OpenSSL
        command: 'curl -O https://bootstrap.pypa.io/get-pip.py'
      02_install_pip3:
        # run this before PIP installs requirements as it needs to be compiled with OpenSSL
        command: 'python3 get-pip.py'
      03_pycurl_uninstall:
        # run this before PIP installs requirements as it needs to be compiled with OpenSSL
        command: '/usr/bin/yes | sudo pip uninstall pycurl'
      04_pycurl_download:
        # run this before PIP installs requirements as it needs to be compiled with OpenSSL
        command: 'curl -O https://pypi.python.org/packages/source/p/pycurl/pycurl-7.43.0.tar.gz'
      05_pycurl_reinstall:
        # run this before PIP installs requirements as it needs to be compiled with OpenSSL
        command: 'sudo pip install pycurl-7.43.0.tar.gz --global-option="--with-nss"'
    
    container_commands:
      09_pycurl_reinstall:
        # run this before PIP installs requirements as it needs to be compiled with OpenSSL
        # the upgrade option is because it will run after PIP installs the requirements.txt file.
        # and it needs to be done with the virtual-env activated
        command: 'source /opt/python/run/venv/bin/activate && pip3 install /usr/local/share/pycurl-7.43.0.tar.gz --global-option="--with-nss" --upgrade'
    

    我遇到这个问题是因为我正在尝试在Elastic Beanstalk中使用Celery 4配置Django 1.10。 如果你也遇到了同样的问题,我写了一篇关于此的完整博客文章


    哎呀,谢谢。这些东西可能很烦人,特别是因为 eb 配置文件似乎非常难以处理,从不给出合理的错误提示(包括格式问题)。 - Ian
    我给这个答案点了赞,因为它帮助我解决了在AWS上安装pycurl时遇到的类似问题:https://dev59.com/C1UK5IYBdhLWcg3w_z60#56260434 - Greg Holst

    8

    我使用的是CentOS 7操作系统。我尝试了以上所有方法,但都没有成功。最终发现需要以root用户身份运行这些命令。如果你也遇到了问题,可以尝试使用以上任何一种解决方法并以root用户身份运行。以下是我成功运行的示例:

    su -
    pip uninstall pycurl
    export PYCURL_SSL_LIBRARY=[nss|openssl|ssl|gnutls]
    pip install pycurl
    

    当然,运行为root用户的所有通常免责声明都适用。
    注意:上面代码中的[nss|openssl|ssl|gnutls]意味着选择一个,不要包括方括号或管道符号。提出原始问题的人会选择openssl。在我的特定情况下,我选择了nss。您的错误信息应该告诉您该做出哪种选择。
    2019年更新:执行sudo pip安装可能会导致机器中Python系统安装出现问题。也许尝试在Python虚拟环境中工作并在那里安装软件包。如果这样做不起作用,那么我答案中的sudo技巧可能是最后考虑的选项之一。

    5
    您可以从这里下载tar.gz文件,然后将其解压到一个文件夹中。您会在其中找到一个setup.py文件,请按照网站上的指示执行命令。例如:
    python setup.py --with-[ssl|gnutls|nss] install
    

    提供信息:我尝试在Windows上安装pycurl,但失败了。但是在我的Linux上成功了。


    谢谢回复,但如果我是通过 virtualenv 和 pip 进行安装的话,这对我可能不起作用。 - helloworld2013
    @Sabuj 要在 Windows 上安装 _pycurl_,请使用此优秀网站提供的其中一个安装程序:http://www.lfd.uci.edu/~gohlke/pythonlibs/#pycurl - Adam

    5

    我在OS X上运行此程序,其中一些解决方案不起作用。与Edward Newell's comment类似,PYCURL_SSL_LIBRARY变量似乎被完全忽略了。
    进一步阅读PycURL installation doc发现以下内容:

    pip可能会重新安装它先前编译过的软件包,而不是使用新指定的选项重新编译pycurl。

    因此,我必须强制使用以下命令进行编译:

    pip install --compile pycurl

    这适用于许多情况。但是,我遇到了一些系统仍然忽略该变量,所以类似于maharg101's answer,我采用了通过pip设置的安装选项:

    pip install pycurl --global-option="--with-[ssl|gnutls|nss]"

    在方括号内选择三个选项之一。请注意,可用选项为ssl而不是openssl。如果指定--with-openssl,则会出现错误。还要注意,如果您正在与PYCURL_SSL_LIBRARY变量玩弄,并将其切换为奇怪的值以查看会发生什么,那么此命令肯定会捕获它并在设置但无效时抛出错误。


    1
    首先卸载pycurl,然后执行pip install pycurl --global-option="--with-nss"即可。值得一提的是,我的错误信息是ImportError: pycurl: libcurl link-time ssl backend (nss) is different from compile-time ssl backend (openssl) - ahyong
    感谢@ahyong,全局选项技巧对我很有帮助,即使我在从tar安装时尝试过,它可以使用pip但无法使用setup.py,奇怪的现象... - Yondaime008

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接