編譯Python3.7並配置ssl庫爲LibreSSL

背景

重新安裝Python 3.7.0的版本。

按照之前的套路,安裝系統依賴:

yum install bzip2-devel
yum install python-devel
yum install libffi-dev
yum install sqlite-devel
yum install libuuid-devel
yum install readline-devel
yum install mysql-devel

下載源碼,手動編譯:./configure --prefix=/opt/python/,安裝: make && make install

一切順利。

問題

在本地執行fab redeploy:python3.7(編寫好了fabric腳本,改了創建虛擬環境的命令爲python3.7 -m venv),結果:

pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.

Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")'

解決

做爲Python老鳥,這樣的錯誤顯然遇到過不少次,方案如下:

1. 手動編譯安裝openssl包,放到/opt/openssl下。 2. 配置編譯Python時的環境變量:

export LDFLAGS="-L/opt/openssl/lib"
export CPPFLAGS="-I/opt/openssl/include"
export PKG_CONFIG_PATH="/opt/openssl/lib/pkgconfig"

3. 再次make

這裏我用的是openssl的1.0.2o的版本,奇怪的是make的時候會有warning:

Could not build the ssl module!
Python requires an OpenSSL 1.0.2 or 1.1 compatible libssl with X509_VERIFY_PARAM_set1_host().
LibreSSL 2.6.4 and earlier do not provide the necessary APIs, https://github.com/libressl-portable/portable/issues/381

不太懂爲什麼不匹配。

不過既然warning中提到了LibreSSL了,索性去看下這個東西。

LibreSSL是OpenSSL加密軟件庫的一個分支,是一個安全套接層(SSL)和傳輸層安全(TLS)協議的開源實現。在OpenSSL爆出心臟出血安全漏洞之後,一些OpenBSD開發者於2014年4月創立了LibreSSL,目標是重構OpenSSL的代碼,以提供一個更安全的替代品。LibreSSL復刻自OpenSSL庫的1.0.1g分支,它將遵循OpenBSD基金會在其他項目所使用的安全指導原則。

--- 維基百科

它的Logo很有寓意,滴血的心臟(Heartbleed bug)。

於是下載了並安裝了LibreSSL,重複上面的邏輯,make時沒warning。安裝成功。

不過安裝完後運行python3.7:import ssl還是會報錯:

    import _ssl             # if we can't import it, let the error propagate
ImportError: libssl.so.45: cannot open shared object file: No such file or directory

最終還需要配置:export LD_LIBRARY_PATH=/libressl/lib(你自己的安裝路徑)。把這個命令放到/etc/bashrc中。

參考

  • 《ctypes find_library should search LD_LIBRARY_PATH on Linux》 https://bugs.python.org/issue9998
  • https://www.libressl.org/
  • https://www.openssl.org/news/newslog.html
  • https://hltj.me/security/2017/05/26/libressl-instead-openssl.html

補充

可能還需要修改源碼包中的Module/Setup文件,取消對應的註釋:

SSL=/usr/local/ssl
_ssl _ssl.c \
        -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
        -L$(SSL)/lib -lssl -lcrypto

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章