web-dev-qa-db-ja.com

Ubuntu Linuxでpipを使用してPythonパッケージをインストールできない:InsecurePlatformWarning、SSLError、tlsv1アラートプロトコルバージョン

以前はpipを使用してパッケージをインストールしていましたが、今はpipを使用してPythonライブラリをインストールしようとしています。SSLエラーが発生します。

 /home/teleduce/.virtualenvs/teleduce_handler/local/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:318: SNIMissingWarning: An HTTPS request has been made, but the SNI (Subject Name Indication) extension to TLS is not available on this platform. This may cause the server to present an incorrect TLS certificate, which can cause validation failures. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#snimissingwarning.
  SNIMissingWarning
 /home/teleduce/.virtualenvs/teleduce_handler/local/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:122: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
  Could not fetch URL https://pypi.python.org/simple/xlwt/: There was a problem confirming the ssl certificate: [Errno 1] _ssl.c:504: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version - skipping

OpenSSLおよびTLSバージョン

OpenSSL 1.0.1 14 Mar 2012
SSLv3
TLSv1.2

Pipバージョン

pip 8.1.2 from /home/teleduce/.virtualenvs/project_name/local/lib/python2.7/site-packages (python 2.7)

OS情報

Ubuntu 12.04.4 LTS (GNU/Linux 3.8.0-44-generic x86_64)

私は試した

pip install --upgrade pip
curl https://bootstrap.pypa.io/get-pip.py | python

しかし、それは私にはうまくいきません。エラーメッセージが出た

SSLルーチン:SSL23_GET_SERVER_HELLO:tlsv1アラートプロトコルバージョン

このエラーを修正するにはどうすればよいですか?

6
Karthikeyan K

SSLErrorが発生するのは、システムのOpenSSLライブラリのバージョン(コンパイル時にPythonにリンクされているバージョン)が1.0.1未満だったためPythonがインストールされた日または、現在のPythonバージョンが2.7.9/3.4未満である。これらのどちらも、実際にPythonパッケージインデックス(PyPI)であるTLS 1.2プロトコルバージョンをサポートしていないため 今は必要pipから接続します。

通常、ディストリビューションでは、OSを完全にアップグレードしないと、古いopensslとシステムPythonを簡単にアップグレードできません。これは、常に望ましいとは限りません。最近の sources から独自の「非システム」OpenSSLをコンパイルしてから、スタンドアロンの「非システム」- Python をコンパイルしたばかりのOpenSSLに対してリンクしようとすることができます。が、さまざまな制限により、このアプローチも実行できない場合があります。

解決

Pipインストールリクエスト[安全]やurllib3 [安全]などの一般的な推奨事項は、pip itself影響を受ける であり、接続できないため、pipを修正できない場合がありますPyPIにインストールしてください。 PipがPyPIに接続できないことを修正するためにPyPIに接続するように依頼することはできません。 :) Pythonをアップグレードせずに修正するには、関連パッケージを手動でインストールして、依存関係を解決する必要があります。

  • PyOpenSSLおよびcryptography(その_manylinux1_ホイールは新しいopensslライブラリを出荷します);
  • それらの依存関係:_asn1crypto_、cffi、_enum34_、idnaipaddresspycparsersix;
  • 以前のpipバージョンは実際には暗号化を使用していなかったため、任意のpip 10+バージョン-標準ライブラリのsslモジュールのみ(あなたのバージョンがすでに10以上の場合、新しいpipバージョンは必要ありません。任意のpip v10 +が使用します)

古い非稼働pipと古いシステムopensslバージョンを使用して、古代のUbuntuでテストされています。

ステップ1-ダウンロード

ダウンロード Pythonパッキングインデックス(pypi.org)から次のパッケージお好みのWebブラウザーを介して-最近のバージョンを選択manylinux1OS /プラットフォーム用のホイール(。whl):

pipasn1cryptoenum34idnasixipaddresspyOpenSSLcfficryptography ホイール;そしてまた pycparser (非ホイール、それはtar.gzになります)

cp27-はPython 2.7を表しますcp36-はPython 3.6を表します;
mu-タイプ多くのLinuxホイールは、UnicodeデータをUCS-4(UTF-32)形式で保存するPythonの場合と同様に、一般的な選択肢です。確認方法は次のとおりです。
$ python -c "import sys; print('UCS4/UTF-32: mu-manylinux1' if sys.maxunicode > 65535 else 'UCS2/UTF-16: m-manylinux1')"

Python 3の注意事項:_cp34-abi3-manylinux1_暗号化のホイールはany Python version> = 3.4で使用できます。 abi3 support Python3の複数のバージョン、たとえばcryptography-2.5-cp34-abi3-manylinux1_x86_64.whl(2.4 MB)

基本的に、wheelsは、特別にフォーマットされたファイル名と.whl拡張子を持つZipアーカイブで、再配置可能なPythonパッケージが含まれています。パッケージは純粋なpythonにすることもできますが、pythonバインディング用のpre-compiled Cライブラリを含めることもできるため、gccなどの特定のシステム依存関係がなくてもインストールできます。 python-devおよびその他のCヘッダー/ライブラリ。通常、.tar.gz形式の従来のパッケージに必要です。これにより、各ホイールにバンドルされているプログラムの正確なバージョンを使用することもできます。 manylinux1 _ {x86_64、i686}ホイールプラットフォームタグは PEP-51 で採用され、manyを含むlinuxシステムで動作します一般的に使用されている人気のデスクトップおよびサーバーディストリビューション。今後はmanylinux2タグが期待されます!

たとえば、新しいディレクトリを作成するだけです。
_$ mkdir ~/wheels_dir_
ダウンロードしたすべてのパッケージをそのディレクトリにコピー(または移動)します。

他のファイル(ダウンロードしたホイールを除く)はなく、サブディレクトリもありません。

ステップ2-インストール

現在のpipバージョンが8.1未満の場合、他のすべてのパッケージを続行する前に、新しいpipバージョンをインストールする必要があります。
_$ pip install --user --no-index ~/wheels_dir/pip-19.0.1-py2.py3-none-any.whl_
新しいmultilinux1ホイール形式を処理するようにpipをアップグレードし、"このプラットフォームでサポートされていないホイール"エラーを回避します。

ユーザーのホームレベルですべてのパッケージをインストールするには:
_$ pip install --user --no-index ~/wheels_dir/*_
_$ pip3_ in Python 3

新規または既存のvirtualenvにインストールする場合は、_--user_オプションを省略します。

_$ source bin/activate
$ pip install --no-index ~/wheels_dir/*
_

Pipは正しいインストール順序と依存関係のオートマgicallyを解決します。 (必要に応じて、このためのrequirements.txtを作成することもできます)

注:Python virtualenvまたはvenvにインストールする場合を除き、pipで常に_--user_フラグを使用することを強くお勧めします。次に、〜/ .local/lib /のホームディレクトリの下にpythonパッケージをデプロイします。実際、このオプションは、デフォルトで常にOnです。 _python3-pip_と_python-pip_パッケージ最近 Ubuntu、Debian、Fedoraなどの人気のあるディストリビューションのバージョン。試してみてください avoid _Sudo pip_、rootアクセスでpipを使用すると、OSパッケージマネージャーサブシステム(apt、yumなど)に干渉し、ディストリビューションが提供するシステムpythonに依存する必須のOSコンポーネント affect が必要になる場合があるため。

_$ pip freeze_(または_pip3 freeze_ in Python 3)コマンドを実行して結果を確認し、Python環境にすべてのパッケージがインストールされていることを確認します。

おめでとう!これで、pipがPyPIで動作するようになり、オンラインPyPIリポジトリから_pip search colorama_のようなものを検索してみることができます。

確認

インストールされているpyOpenSSL libを直接クエリすると、システムのSSL/TLS設定の詳細な概要を確認できます。
_$ python -m OpenSSL.debug_
ModuleNotFoundErrorは、pyOpenSSLパッケージがインストールされなかったことを意味します)

暗号化にリンクされたOpenSSL共有libは、システムのPythonのopensslバージョンとまったく競合しません。最新のpython certifiパッケージをインストールして、将来のルートSSL証明書のコレクションも更新する良い機会になるかもしれません。

なぜ機能するのか

以前のバージョンのpip(10より前)は、標準ライブラリのsslモジュール(システムOpenSSLライブラリのPython AP​​I)のみを使用し、cryptographyなどの他のライブラリへのフォールバックはありませんでした。バージョン10以降、pipは環境に存在する場合、暗号化でpyOpenSSLを使用できるようになりました。

cryptographyパッケージの_manylinux1_ホイールincludesプラットフォームの内容に関係なく、v1.3までのすべてのTLSプロトコルをサポートする最近のOpenSSLライブラリ(PyPIはpipがTLSv1.2をサポートすることを期待しています)。これがこのホイールの重量が2.1 Mbである理由です-アーカイブは共有libバインディングを出荷します:

_$ strings site-packages/cryptography/hazmat/bindings/_openssl.so | grep OpenSSL -m1  
OpenSSL 1.1.1a  20 Nov 2018  
$ python -c "from cryptography.hazmat.backends.openssl import backend as b; print b.openssl_version_text()"  
OpenSSL 1.1.1a  20 Nov 2018  
$ python -c "from OpenSSL import SSL; print SSL.SSLeay_version(0)"  
OpenSSL 1.1.1a  20 Nov 2018  
$ python -c "import requests; print requests.get('https://www.howsmyssl.com/a/check').json()['tls_version']"  
TLS 1.3  
_

暗号化ホイールには、静的にリンクされたOpenSSLバインディングが含まれているため、システムの依存関係を壊すことなく、最新のOpenSSLリリースに確実にアクセスできます。
これにより、Pythonプログラムで最新のOpenSSLを利用できるようにしながら、比較的古いLinuxディストリビューション(LTSリリースなど)を引き続き使用できます。 ( https://cryptography.io/en/latest/installation/

Python 2では、標準ライブラリのsslモジュールがバージョン2.7.9以降、PROTOCOL_TLSv1_2フラグを明示的にサポートし始めましたが、Python 3では、バージョン3.4以降です。しかし、TLSv1.2接続は機能するだけですifとonly if TLSv1.2対応のシステム全体のOpenSSLライブラリはすでに利用可能までにシステムでPythonはコンパイルされ、リンクされていました。 TLSv1.2が機能するには、少なくともOpenSSL 1.0.1が必要ですが、OpenSSL 1.0.2(またはそれ以降)が一般的に推奨されます(デフォルトでTLSv1.2を使用します)。

Python 2.7.9+または3.4+があり、そのsslモジュールが実際にシステムのopenssl、たとえばv1.0.2kに対してコンパイルされている場合、古いpip(v6.0.8など) )この記事の執筆時点ではstillはPyPIで動作しており、暗号化も必要ありません。標準ライブラリPython sslおよびシステムのopensslバージョンを確認するには:
$ python -c "import ssl; print(ssl.OPENSSL_VERSION)" && openssl version
OpenSSL 0.9.8o 01 Jun 2010

古いディストリビューション提供のopensslをアップグレードしたり、最新のものをコンパイルしたりした場合でも、既存のPythonインストールをそれに再リンクすることはできません。sslモジュールがシステム提供のハードリンクされましたPythonのコンパイル/インストール時のOpenSSL、およびその逆。したがって、基本的に、Python自体(少なくともバージョン2.7.9+/3.4+である必要があります)を再コンパイル/再インストールして新しいシステムのopensslライブラリにリンクしないと、新しいTLSプロトコルを利用できません。上記のpyopenssl + _cryptographyのアプローチが役に立ちます。

幸せなTLSing! :)


11
Alex C.