在非标准位置使用SSL支持构建Python

时间:2011-05-09 13:10:48

标签: python openssl compilation

我需要在RHEL上安装几个Python模块,我没有root访问权限。至少有一个模块还需要访问Python.h

在这种情况下,我发现最好的方法是在~/local中安装python及其依赖项。它通常只是工作,但这次Python无法构建SSL模块(请参阅下面的详细信息)。这是我正在做的事情的痕迹。

所以我下载了python 6源代码,然后我去了:

./configure --prefix=/home/fds/rms/local
make >& make.log

检查日志显示ssl模块尚未编译,但没有提及原因(make或configure中没有其他ssl发生):

Failed to find the necessary bits to build these modules:
_bsddb             _curses            _curses_panel
_hashlib           _sqlite3           _ssl   <----------

所以我想,python根本找不到任何ssl库(这很奇怪,但是嘿......)。所以我下载openssl-0.9.8r和

./config --prefix=/home/fds/rms/local shared
make
make install

现在回到Python,我./configure并重新制作。它失败了,但这一次有所不同:

Failed to build these modules:
_hashlib           _ssl

仔细检查日志文件就会发现:

gcc -pthread -shared build/temp.linux-x86_64-2.6/home/fds/rms/installers/Python-2.6.6/Modules/_ssl.o -L/home/fds/rms/local/lib -L/usr/local/lib -lssl -lcrypto -o build/lib.linux-x86_64-2.6/_ssl.so
*** WARNING: renaming "_ssl" since importing it failed: libssl.so.0.9.8: cannot open shared object file: No such file or directory

所以现在它正在拿起图书馆但是没有完全正确(文件应该在哪里):

$ find /home/fds/rms/local -iname libssl.so.0.9.8
/home/fds/rms/local/lib/libssl.so.0.9.8

接下来就是跟踪make并查看它在哪里寻找文件:

$ strace -f make 2>&1 | grep libssl.so.0.9.8
[pid  5584] open("/lib/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  5584] open("/usr/lib/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  5584] open("/lib64/tls/x86_64/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  5584] open("/lib64/tls/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  5584] open("/lib64/x86_64/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or   directory)
[pid  5584] open("/lib64/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  5584] open("/usr/lib64/tls/x86_64/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  5584] open("/usr/lib64/tls/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  5584] open("/usr/lib64/x86_64/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  5584] open("/usr/lib64/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  5584] write(1, "*** WARNING: renaming \"_ssl\" sin"..., 131*** WARNING: renaming "_ssl" since importing it failed: libssl.so.0.9.8: cannot open shared object file: No such file or directory
[pid  5584] open("/lib/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  5584] open("/usr/lib/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  5584] open("/lib64/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  5584] open("/usr/lib64/tls/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  5584] open("/usr/lib64/libssl.so.0.9.8", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  5584] write(1, "*** WARNING: renaming \"_hashlib\""..., 135*** WARNING: renaming "_hashlib" since importing it failed: libssl.so.0.9.8: cannot open shared object file: No such file or directory

嗯,它正在寻找所有错误的地方。我试着给出一个提示:

CPPFLAGS="-I/home/fds/rms/local/include -I/home/fds/rms/local/include/openssl" LDFLAGS="-L/home/fds/rms/local/lib" ./configure --prefix=/home/fds/rms/local

但没有任何变化,make似乎根本没有尝试/home/fds/rms/local/lib

我多年没有这样做过,所以也许我忽视了一些事情。任何人都可以帮忙解决这个问题吗?

提前致谢。

11 个答案:

答案 0 :(得分:56)

如果OpenSSL不在标准位置,您需要编辑Modules/Setup.dist以指定OpenSSL的位置。来自Getting SSL Support in Python 2.5.1

  

如果你发现你自己在一个需要ssl支持的Linux机器人的python(to   在httplib.HTTPSConnection或。之类的东西中使用客户端   imaplib.IMAP4_SSL),然后让我为你节省几个小时的时间   在网络上(当然,如果你发现了这就意味着   你已经完成了一些水平的狩猎!)。

     

你会知道你是否需要编译到你的python中的ssl支持   安装如果您收到以下异常消息:   AttributeError:'module'对象没有属性'ssl'

     

为了让它消失,你可以继续愉快地投掷   python代码,你需要首先确保你有OpenSSL   安装。默认情况下,它从源代码安装在:/ usr / local / ssl

     

如果该目录不存在,则抓取源包。

     

做标准:

tar zxf openssl-0.9.8g.tar.gz
cd openssl-0.9.8g
./config
make
make install
     

然后获取2.5.1的python源代码:tar zxf Python-2.5.1.tgz   &安培;&安培; cd Python-2.5.1

     

然后你需要编辑Modules / Setup.dist:

204:# Socket module helper for SSL support; you must comment out the other
205:# socket line above, and possibly edit the SSL variable:
206:SSL=/usr/local/ssl
207:_ssl _ssl.c \
208:    -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
209:    -L$(SSL)/lib -lssl -lcrypto
     

如果您在默认位置安装OpenSSL,则可以   取消注释206-209行,然后:

./configure
make
make install
     

然后使用以下命令验证您的安装:

python /usr/local/lib/python2.5/test/test_socket_ssl.py
test_rude_shutdown ...
test_basic ...
test_timeout ...

确保通过清除源根(例如Modules/Setup.dist)并再次运行make distcleanconfigure来获取对make的更改。

答案 1 :(得分:8)

在Linux Red Hat 7.7 x86_64上,以下工作将 openssl-1.1.1d Python-3.8.1 安装到我的主目录(/ home / unix / vangalen):

安装OpenSSL source1 source2

cd ~
wget https://www.openssl.org/source/openssl-1.1.1d.tar.gz
tar -xzf openssl-1.1.1d.tar.gz
cd /home/unix/vangalen/openssl-1.1.1d
./config --prefix=/home/unix/vangalen/openssl --openssldir=/home/unix/vangalen/openssl
make
make test
make install

安装Python source2 source3 source4

cd ~
wget https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tgz
tar xf Python-3.8.1.tgz

在文本编辑器中修改Python-3.8.1 / Modules / Setup。如果该文件不存在,则可能需要先执行失败的运行。取消注释行,并在第206到213行中调整SSL的别名::

_socket socketmodule.c

# Socket module helper for SSL support; you must comment out the other
# socket line above, and possibly edit the SSL variable:
SSL=/home/unix/vangalen/openssl
_ssl _ssl.c \
  -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
  -L$(SSL)/lib -lssl -lcrypto
cd ~/Python-3.8.1
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/home/unix/vangalen/openssl/lib
./configure --prefix=/home/unix/vangalen/py-381 --with-openssl=/home/unix/vangalen/openssl
make
make test
make install

答案 2 :(得分:6)

Bourne shell中的

(/ bin / sh或/ bin / bash):

$ LD_LIBRARY_PATH=/usr/local/lib
$ export LD_LIBRARY_PATH
$ make

在C-shell中(/ bin / csh或/ bin / tcsh):

% setenv LD_LIBRARY_PATH /usr/local/lib
% make

答案 3 :(得分:4)

对我来说编辑Modules/Setup是不够的,因为_hashlib模块仍然使用错误的OpenSSL版本;并且在我的SLES系统上没有在运行时考虑LD_LIBRARY_PATH

通过按GitHub patch: eddy-geek/ python_custom_openssl.diff编辑_ssl,然后_hashlib,将本地OpenSSL静态链接到setup.pymake clean && make是有效的。

有关我在Coredump when compiling python with a custom openssl version处使用Stack Overflow上的静态链接的原因的详细信息。

答案 4 :(得分:3)

这是我在Python 2.7.11中使用的完整过程。

在顶级Python2.7.11源目录中:

  1. 更改Modules/Setup.distModules/Setup:取消注释_ssl部分,注释掉_socket(如果已注释掉,则为no-op),取消注释并适当设置SSL(新ssl lib/includes的路径等)。

    注意:模块/设置文件最初不存在,但在第一次运行后,它从Modules / Setup中获取内容。我相信。确保每次运行前都会在此处反映更改。

  2. 应用补丁:http://gist.github.com/eddy-geek/9604982 (如果以前曾经做过make makecle),

    ./configure --prefix=/root/.local/aks/py-ssl/python2.7 --enable-shared
    
    # modify: Makefile -> set svnversion to ""
    
    make
    
    make altinstall
    

答案 5 :(得分:2)

我得到了相同的结果,直到我回到openssl的日志。 在那里我看到你在构建openssl时需要使用-fPIC: 建立'_ssl'扩展名:

gcc -pthread -fPIC -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/usr/local/ssl/include -I. -IInclude -I./Include -I/usr/local/include -I/home/feramos/Python-2.7.3/Include -I/home/feramos/Python-2.7.3 -c /home/feramos/Python-2.7.3/Modules/_ssl.c -o build/temp.linux-x86_64-2.7/home/feramos/Python-2.7.3/Modules/_ssl.o
gcc -pthread -shared build/temp.linux-x86_64-2.7/home/feramos/Python-2.7.3/Modules/_ssl.o -L/usr/local/ssl/lib -L/usr/local/lib -lssl -lcrypto -o build/lib.linux-x86_64-2.7/_ssl.so
/usr/bin/ld: /usr/local/ssl/lib/libcrypto.a(x86_64cpuid.o): relocation R_X86_64_PC32 against `OPENSSL_cpuid_setup' can not be used when making a shared object; recompile with -fPIC

openssl-0.9.8g]# .config -fPIC

然后,make,make install for openssl然后再次构建Python。

答案 6 :(得分:2)

我有一组针对静态openssl和静态libintl的补丁,用于下面的2和3。

对于openssl(第一个补丁),你必须设置env var OPENSSL_ROOT。

这是基于https://example.com的补丁。

对于Python 2.7.14:

http://gist.github.com/eddy-geek/9604982

https://gist.github.com/rkitover/2d9e5baff1f1cc4f2618dee53083bd35

对于Python 3.6.3:

https://gist.github.com/rkitover/afab7ed3ac7ce1860c43a258571c8ae1

https://gist.github.com/rkitover/93d89a679705875c59275fb0a8f22b45

答案 7 :(得分:2)

@PeterVanGalen has a good method,截至 2021 年是相关的,但我不同意某些细节。

他修改 Start = Table.Min([MyTable], "SortTime") 文件的方法导致 libssl.so 和 libcrypto.so 库成为 Modules/Setup 二进制文件本身的动态依赖项。这不是预期的 - 这些应该是 python 可导入的 python 的依赖项,例如 .so

他的方法也不包含如何在运行时而不是构建时找到 _ssl.cpython-39-x86_64-linux-gnu.solibssl.so 的解决方案。如果它们位于某个不寻常的自定义路径中,这很重要,否则 python 将根本无法运行或无法libcrypto.so。您可以通过多种方式解决它(import sslLD_LIBRARY_PATH 浮现在脑海中)但我选择使用 rpath,这样当我在自定义位置时始终可以找到 ld.so.conf 文件使用这个 python,否则会避开。

这是我对@PeterValGalen 方法的修改:

.so

这样做后,openssl 库不是 python 二进制文件的依赖项,而是 # First we need openssl installed in a custom location... tar zxf openssl-1.1.1j.tar.gz cd openssl-1.1.1j ./config --prefix=/my/weird/path --openssldir=/my/weird/path/ssl make make install # Add `sudo` if needed for permission to /my/weird/path. cd .. # Now the python part... wget https://www.python.org/ftp/python/3.9.2/Python-3.9.2.tgz tar xf Python-3.9.2.tgz cd Python-3.9.2 LDFLAGS="${LDFLAGS} -Wl,-rpath=/my/weird/path/lib" ./configure --with-openssl=/my/weird/path make make install # Add `sudo` if needed for permissions. 的依赖项

_ssl*.so

它有效:

$ ldd ./python | grep weird
# [Nothing]

$ ldd build/lib.linux-x86_64-3.9/_ssl.cpython-39-x86_64-linux-gnu.so  | grep weird
        libssl.so.1.1 => /my/weird/path/lib/libssl.so.1.1 (0x00007f733ee73000)
        libcrypto.so.1.1 => /my/weird/path/lib/libcrypto.so.1.1 (0x00007f733e9ab000)

答案 8 :(得分:1)

我正在构建Python2.7.13,我也看到了同样的问题。对于2.7.13,你必须使用&#34; openssl1.0.0e&#34;或以上使它工作。我试过openssl-0.9.8g而且它没有用。 不知怎的,我不能让它只修改Modules / Setup.dist,所以我必须手动编译_ssl.o。 我想这是因为我提供的openssl-0.9.8g无法正常工作,它搜索了系统默认的libssl.so.10,它也不起作用。

答案 9 :(得分:0)

尝试将-Wl,-rpath,/home/fds/rms/local/lib添加到LDPATH

答案 10 :(得分:0)

对于 MAC OS HIGH Sierra , 和 Python-3.5.6 在上面的答案中,openssl的安装是使用源代码完成的,但是如果您使用brew进行安装,它会告诉您已安装的软件包在哪里,因此如果您使用brew来安装openssl

brew install openssl

这将在 /usr/local/Cellar/openssl/1.0.2o_2 / 中安装openssl,该路径需要在Modules / Setup.dist中的

处进行更新。

Follow this answer which is mentioned above where the location of openssl installation is not mentioned to update the Modules/Setup.dist

在以上各行中,将SSL值更新为

SSL=/usr/local/Cellar/openssl/1.0.2o_2/

然后取消注释 做一个CMM,您的python将用openssl编译。