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

Mat*_*ari 56 python openssl compilation

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

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

所以我下载了python 6源码然后关闭了我:

./configure --prefix=/home/fds/rms/local
make >& make.log
Run Code Online (Sandbox Code Playgroud)

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

Failed to find the necessary bits to build these modules:
_bsddb             _curses            _curses_panel
_hashlib           _sqlite3           _ssl   <----------
Run Code Online (Sandbox Code Playgroud)

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

./config --prefix=/home/fds/rms/local shared
make
make install
Run Code Online (Sandbox Code Playgroud)

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

Failed to build these modules:
_hashlib           _ssl
Run Code Online (Sandbox Code Playgroud)

仔细检查日志文件可以发现:

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
Run Code Online (Sandbox Code Playgroud)

所以现在它正在拿起图书馆,但不是很正确(文件应该在哪里):

$ find /home/fds/rms/local -iname libssl.so.0.9.8
/home/fds/rms/local/lib/libssl.so.0.9.8
Run Code Online (Sandbox Code Playgroud)

接下来是跟踪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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

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

提前致谢.

Cos*_*ean 61

如果Modules/Setup.distOpenSSL不在标准位置,则需要进行编辑以指定OpenSSL的位置.从Python 2.5.1中获取SSL支持:

如果你发现自己在一个需要ssl支持的linux盒子里(在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
Run Code Online (Sandbox Code Playgroud)

然后获取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
Run Code Online (Sandbox Code Playgroud)

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

./configure
make
make install
Run Code Online (Sandbox Code Playgroud)

然后验证您的安装:

python /usr/local/lib/python2.5/test/test_socket_ssl.py
test_rude_shutdown ...
test_basic ...
test_timeout ...
Run Code Online (Sandbox Code Playgroud)

确保Modules/Setup.dist通过清理源根(例如make distclean)configuremake再次运行来获取更改.

  • 在标准位置未安装openssl时,在python3.7上不起作用 (3认同)
  • 这适用于在 RHEL 上安装 Python 3.7.4。使用默认的 openssl 安装,我必须更改 SSL 行:SSL=/etc/pki/tls,取消注释接下来的三行,我必须运行 sudo yum install openssl-devel (2认同)

Rav*_*ole 32

@PeterVanGalen有一个很好的方法,并且截至 2021 年都是相关的,但我不同意一些细节。

他修改Modules/Setup文件的方法导致 libssl.so 和 libcrypto.so 库成为python二进制文件本身的动态依赖项。这并不符合预期——那些应该是 python 可导入的依赖项.so,例如_ssl.cpython-39-x86_64-linux-gnu.so.

他的方法也不包括如何libssl.solibcrypto.so运行时而不是构建时找到的解决方案。如果它们位于某些不寻常的自定义路径中,这一点很重要,否则 python 将根本无法运行或无法运行import ssl。你可以用很多方法来解决它(LD_LIBRARY_PATH并且ld.so.conf想到),但我选择使用 rpath,这样.so当我使用这个 python 时,总是可以在其自定义位置找到文件,但否则不会妨碍。

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

# 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.
Run Code Online (Sandbox Code Playgroud)

通过这种方式完成后,openssl 库不再是 python 二进制文件的依赖项,而是_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)
Run Code Online (Sandbox Code Playgroud)

它有效:

$ ./python -c "import ssl; print('yay')"
yay

$ ./python Lib/test/test_ssl.py
# ... lots of good stuff...
OK (skipped=10)
Run Code Online (Sandbox Code Playgroud)

  • 它可以工作,但我必须在我的 openssl 安装中创建一个名为“lib”的符号链接,指向它旁边的“lib64”。万一它可以帮助某人。 (2认同)

Pet*_*len 13

在 Linux Red Hat 7.7 x86_64 上,以下操作可以在我的主目录 (/home/unix/vangalen) 中安装openssl-1.1.1dPython-3.8.1

将OpenSSL安装 源1 源2

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
Run Code Online (Sandbox Code Playgroud)

安装Python 源2 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
Run Code Online (Sandbox Code Playgroud)

在文本编辑器中修改 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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)


Sol*_*oli 6

在Bourne shell中(/ bin/sh或/ bin/bash):

$ LD_LIBRARY_PATH=/usr/local/lib
$ export LD_LIBRARY_PATH
$ make
Run Code Online (Sandbox Code Playgroud)

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

% setenv LD_LIBRARY_PATH /usr/local/lib
% make
Run Code Online (Sandbox Code Playgroud)