在Python 2.7中更新openssl

30

请问有人能够解释一下Python2.7中如何使用OpenSSL吗?我不确定Python是使用自己的OpenSSL还是从本地机器/环境中提取。让我解释一下:

(如果我在Python中这样做)

>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 0.9.8x 10 May 2012'

(在终端中)

$ openssl version
OpenSSL 0.9.8x 10 May 2012
$ which openssl 
/usr/bin/openssl

现在我更新了 OpenSSL(下载.)

$ cd openssl-1.0.1c
$ ./Configure darwin64-x86_64-cc --prefix=/usr --openssldir=/opt/local/etc/openssl shared
$ make
$ sudo make install

这创建了一个独立的目录(如指定的那样),因此我将其复制到了旧路径。

cp -f /usr/local/ssl/bin/openssl /usr/bin/openssl

现在终端中,OpenSSL版本已经更新了,但Python没有更新!

$ openssl version
OpenSSL 1.0.1c 10 May 2012

我注意到 .dylib 文件仍指向旧版本,该如何更改?

$ ls -l /usr/lib/*ssl*
-rwxr-xr-x  1 root  wheel  411680 Jul 17  2012 /usr/lib/libssl.0.9.7.dylib
-rwxr-xr-x  1 root  wheel  602800 May 24 03:43 /usr/lib/libssl.0.9.8.dylib
-rwxr-xr-x  1 root  wheel  390908 Sep  9 17:37 /usr/lib/libssl.1.0.0.dylib
lrwxr-xr-x  1 root  wheel      18 Jul 17  2012 /usr/lib/libssl.dylib -> libssl.0.9.8.dylib

更新:我更改了链接,但是在 Python 上仍然得到旧版本。

$ ls -l /usr/lib/*ssl*
-rwxr-xr-x  1 root  wheel  411680 Jul 17  2012 /usr/lib/libssl.0.9.7.dylib
-rwxr-xr-x  1 root  wheel  602800 May 24 03:43 /usr/lib/libssl.0.9.8.dylib
-rwxr-xr-x  1 root  wheel  390908 Sep  9 17:37 /usr/lib/libssl.1.0.0.dylib
lrwxr-xr-x  1 root  wheel      18 Sep 11 15:47 /usr/lib/libssl.dylib -> libssl.1.0.0.dylib

4
不要使用安装前缀为/或/usr来覆盖系统的OpenSSL,也不要通过符号链接或复制系统中的OpenSSL文件,否则会造成严重问题,可能导致系统崩溃。请谨慎操作。 - user246672
6个回答

33

请参考http://rkulla.blogspot.kr/2014/03/the-path-to-homebrew.html

在MAC上使用Homebrew升级openssl至1.0.1j后,系统Python仍然引用旧版本0.9.8。结果发现系统Python是依赖于openssl的。为此,我安装了带有brewed openssl的新Python,并解决了这个问题,但Ubuntu还没有解决。

在Mac OS X 10.10版本和系统Python 2.7.6版本上,我的操作步骤如下:

$ brew update

$ brew install openssl

然后您可以看到openssl版本为1.0.1j。

$ brew link openssl --force 

$ brew install python --with-brewed-openssl    

你需要安装使用brewed openssl的新Python。然后,你就可以看到/usr/local/Cellar/python/2.7.8_2/bin/python。

$ sudo ln -s /usr/local/Cellar/python/2.7.8_2/bin/python /usr/local/bin/python

当然,/usr/local/* 应该是被$USER所拥有,而不是root,这是Ryan告诉我们的,但我使用了'sudo'。在执行这个指令之前,我没有/usr/local/bin/python。执行完这个指令后,你就可以使用Python版本2.7.8而不是2.7.6.

最后,你可以像下面这样看到结果;

$ python --version  
Python 2.7.8

$ python -c "import ssl; print ssl.OPENSSL_VERSION"
OpenSSL 1.0.1j 15 Oct 2014

目前,我正在Ubuntu 12.04上进行此操作。如果我有针对Ubuntu 12.04的解决方案,那么我会更新我的答案。希望这个过程能帮助您。


这个方法虽然我稍微有些不同,但是也能够工作。我的步骤如下:$ brew update && brew install openssl, 跳过链接: brew update python --with-brewed-openssl 我已经用brew安装了python $ /usr/local/Cellar/python/2.7.13_1/bin/python2 -c "import ssl; print ssl.OPENSSL_VERSION" OpenSSL 1.0.2l 25 May 2017 系统版本:OpenSSL 0.9.8zh 14 Jan 2016 - user666406
我得到了...curl: (23) 写入正文失败(0 != 16384) 尝试使用镜像... ==> 正在下载 https://dl.bintray.com/homebrew/mirror/pkg-config-0.29.2.tar.gz 警告:无法创建文件 警告:/Users/paulkenjora/Library/Caches/Homebrew/pkg-config-0.29.2.tar.gz.in 警告:完成:权限被拒绝 - Paul Kenjora
1
在Kivy上升级OpenSSL是否有相应的等效方法,而不是像“$ brew install python --with-brewed-openssl”那样在Python上进行升级? - user761567

19

过时的SSL是多个平台上常见的问题:

以下是一般的解决方法...

0. 安装OpenSSL

  • 选项一:安装系统包中的 OpenSSL 1.x libs (-dev 或 -devel) 包。

    # FreeBSD
    
    pkg install openssl
    OPENSSL_ROOT=/usr/local
    
    
    # Mac (brew)
    
    brew install openssl # 不要进行任何奇怪的符号链接操作,它是 KEG-ONLY 的!
    OPENSSL_ROOT="$(brew --prefix openssl)"
    
  • 选项二:从源代码安装 OpenSSL 到临时目录

    OPENSSL_ROOT="$HOME/.build/openssl-1.0.1e"
    
    curl http://www.openssl.org/source/openssl-1.0.1e.tar.gz | tar zxvf -
    cd openssl-1.0.1e
    mkdir -p "$OPENSSL_ROOT"
    ./config no-hw --prefix="$OPENSSL_ROOT" --openssldir=...
    # osx (instead of previous line): ./Configure darwin64-x86_64-cc no-hw --prefix="$OPENSSL_ROOT" --openssldir=...
    make install
    cd ..
    rm -rf openssl-1.0.1e
    

1. 从源代码构建Python

  • 选项A:使用pyenv

    export CONFIGURE_OPTS="CPPFLAGS=-I"$OPENSSL_ROOT"/include LDFLAGS=-L"$OPENSSL_ROOT"/lib [在此处添加其他选项]"
    pyenv install 2.7.6
    
  • 选项B:从源代码安装Python

    ./configure CPPFLAGS="-I$OPENSSL_ROOT/include" LDFLAGS="-L$OPENSSL_ROOT/lib" [在此处添加其他选项]`
    make
    # ...
    # 如果已编译的openssl被使用,可以安全地删除它,因为python的ssl模块会静态链接openssl。
    

例子:FreeBSD 9.2(为演示目的跳过make install

pkg install openssl curl gmake gdbm sqlite3 readline ncurses
OPENSSL_ROOT=/usr/local
curl http://www.python.org/ftp/python/2.7.6/Python-2.7.6.tar.xz | tar jxvf -
cd Python-2.7.6
./configure CPPFLAGS="-I$OPENSSL_ROOT/include" LDFLAGS="-L$OPENSSL_ROOT/lib" [your other options here]
make
./python -c 'import ssl; print(ssl.OPENSSL_VERSION)' # osx: ./python.exe ...
# prints: OpenSSL 1.0.1e 11 Feb 2013

接下来,临时的 OpenSSL 库不再需要,因为 SSL 模块已经静态地与 OpenSSL 集成到 Python 可执行文件中(可以使用 otoolreadelf 进行验证)。


我在 https://dev59.com/Z1YO5IYBdhLWcg3wDNQb#46476640 遇到了同样的问题,你的答案对我很有帮助。这仍然是2017年末的正确答案。您需要在 ./configure 命令中传递 CPPFLAGS 和 LDFLAGS;您不能在环境中设置它们,否则 setup.py 将无法注意到它们。 - iLikeDirt
4
为什么只需要更新OpenSSL,我就必须重新构建/重新安装整个Python呢? - normanius
1
如果一个二进制文件静态链接了像 OpenSSL 这样的库,那么链接器会将它合并到二进制文件中,无法直接替换。如果它是动态链接到共享库,有时候只需更新库即可获取新代码...但这必须非常小心地进行。编译 OpenSSL 的目的是为了获得更新的版本。如果只升级了动态链接二进制文件中的 OpenSSL,则可以在旧版本的基础上自定义编译新版本的 OpenSSL,而无需重新编译 Python。Python 也必须使用 --enable-shared 进行配置。 - user246672

4

这可能是由于Python版本过旧导致的。

在Python 2.7.1上运行python -c "import ssl; print ssl.OPENSSL_VERSION"后,我发现我使用的OpenSSL版本过旧:OpenSSL 0.9.7l 28 Sep 2006

这个论坛的说明,似乎我的Python版本依赖于一个已经停用的OpenSSL版本:

对于即将发布的Python 2.7.9版本(计划于12月初发布),我打算让python.org OS X安装程序中的Python使用自己的OpenSSL版本,因此不再依赖于现在已被弃用的系统OpenSSL。

我升级到了Python 2.7.9,问题立即得到解决。现在,在运行python -c "import ssl; print ssl.OPENSSL_VERSION"之后,我得到的是OpenSSL 0.9.8za 5 Jun 2014


1
以下方法对我有用。我已经成功将OpenSSL从0.9.8zh更新到1.0.2o版本,但是在发现这个建议使用pyenv重新安装Python(我想要的版本为2.7.10)之前,Python从未访问过更新的版本。
brew update
brew install pyenv

echo 'eval "$(pyenv init -)"' >> .bashrc
source .bashrc

pyenv install 2.7.10
pyenv global 2.7.10

然后检查...

python --version
Python 2.7.10

python -c 'import ssl; print ssl.OPENSSL_VERSION'
OpenSSL 1.0.2o  27 Mar 2018

当然,我确实需要重新安装Python包。

来源:https://github.com/ianunruh/hvac/issues/75


1
我认为Python已经意识到这是一个问题:https://www.python.org/downloads/release/python-2715/

注意

注意macOS用户:从2.7.15开始,所有python.org的macOS安装程序都内置了OpenSSL。此外,还有一种新的适用于macOS 10.9+的附加安装程序变体,包含了内置的Tcl/Tk 8.6版本。有关更多信息,请参阅安装程序自述文件。

只需安装2.7.15即可解决我的OpenSSL问题。

-6

问题已解决,没有任何黑客行为,以上所有方法都对我无效。最终我采取了更简单、不复杂的方法...

  1. 从官方网站安装Python 2.7.13,它实际上会自动升级旧的Python系统,并成为默认的Python版本(是的!)。

https://www.python.org/downloads/mac-osx/

2. 在 Python 安装后升级 OpenSSL。将其更新为系统 Python(是的!)。
sudo pip install --upgrade pyOpenSSL
3. 您将不得不重新安装所有 Python 模块(因为您替换了 Python),我强烈建议使用 pip。经过几分钟的 pip 安装,我的默认 OSX Python 已经升级,我已经升级了 OpenSSL,并且我有所有的模块(包括 Django 运行)。

2
请不要这样做。替换RHEL上的系统Python可能会产生一些意想不到的后果。还有很多其他工具可以用来备份安装不同版本的Python和不同版本的OpenSSL。Conda是这样一个工具的例子。 - disflux

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