#環境
- Mac OS X 10.11.6 (El Capitan)
- Python 3.5.1
- pip 9.0.1
- 今日の日付 2018-07-18 (案外重要)
#経緯
twitterのbotが作りたくて、tweepyかtwythonをpipでインストールしようとしました。
$ pip install tweepy
すると、以下のエラーが発生
Collecting tweepy
Could not fetch URL https://pypi.python.org/simple/tweepy/: There was a problem confirming the ssl certificate: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:645) - skipping
Could not find a version that satisfies the requirement tweepy (from versions: )
No matching distribution found for tweepy
#解決策(?)その1
検索してみると、下記のコマンドを使ってpipをアップグレードするといい、という情報が見つかりました。
curl https://bootstrap.pypa.io/get-pip.py | python3
参考:
https://github.com/pypa/pip/issues/5236
その通りやってみると…
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1603k 100 1603k 0 0 2151k 0 --:--:-- --:--:-- --:--:-- 2149k
Collecting pip
Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError('certificate verify failed, error code: 5',),)': /simple/pip/
Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError('certificate verify failed, error code: 5',),)': /simple/pip/
Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError('certificate verify failed, error code: 5',),)': /simple/pip/
Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError('certificate verify failed, error code: 5',),)': /simple/pip/
Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError('certificate verify failed, error code: 5',),)': /simple/pip/
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError(SSLError('certificate verify failed, error code: 5',),)) - skipping
Could not find a version that satisfies the requirement pip (from versions: )
No matching distribution found for pip
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError(SSLError('certificate verify failed, error code: 5',),)) - skipping
うまくいきません。
##原因
エラーの中心はcertificate verify failed
ですね。「証明書の検証に失敗」です。
調べてみると、どうやら、パッケージをインストールする先方のURLが変更になり、pip側が「そんなURLは知らないぞ!信用出来ないんじゃないのか??」と疑って、エラーを出している、ということっぽいです。多分。ちゃんとわかってなくてすみません。
参考:
https://github.com/pypa/pip/issues/5288
https://packaging.python.org/guides/migrating-to-pypi-org/
↑2個目のURLが公式アナウンスです。
#解決策(?)その2
次の参考URLに書いてあるように、新しいURLについて「このURLは信用していいよ〜」という情報をpipに教えてあげましょう。
pypi.org
とfiles.pythonhosted.org
を信用するように指示すれば良いようです。
でも、この方法ではうまくいきませんでした。
pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org <package_name>
そもそもpipをアップグレードする必要があるので、先に使いたいコマンドはcurl
なんですよね。pip
ではなく。
しかし
curl https://bootstrap.pypa.io/get-pip.py | python3
の中でどうやらpip
が使われてるらしく、ここでは--trusted-host
の指定をしていないので、結局同じエラーがでる。
ということで、同じ参考URLにあったもう一つの方法を使います。
pip.conf
という設定ファイルを作って、そこに「このURLは信用していいよ」という内容を記述します。(Windowsの場合はpip.ini
)
#結論
結局、下記のようにしてうまくいきました。
##pip.confの作成(Windowsの場合はpip.ini)
まず、pip.conf
を所定の場所に作り、下記の記述をします。
[global]
trusted-host = pypi.python.org
pypi.org
files.pythonhosted.org
これで、これらのURLは信用され、これらのURLからパッケージをダウンロードしてくれるようになります。
pip.conf
を置く場所については下記を参考に。
参考:
https://stackoverflow.com/questions/45337029/pip-conf-not-paying-attention-to-trusted-host
##pipのアップグレード
curl https://bootstrap.pypa.io/get-pip.py | python3
これを実行します。pip
が10.0.1
にアップグレードされます。
##パッケージのインストール
ようやくここまで来ましたが、これが当初やりたかったやつです。本来、これだけでできるはずなんだよなあ。
僕の場合はtweepy
をインストールしました。
pip install tweepy
以上です。
#追記(2018-07-19)VPSサーバーでもpipを動かす
#VPSサーバーの環境
- CentOS Linux release 7.0.1406 (Core)
- curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.15.4 zlib/1.2.7 libidn/1.28 libssh2/1.4.3
- Python 3.6.2
- pip 9.0.1
#経緯
僕の場合tweepyはVPSサーバー上で動いてくれないと意味がないので、VPSサーバーにも上記の方法でインストールしようとした所、
curl https://bootstrap.pypa.io/get-pip.py | python3.6
を実行した時点で、ローカルの時とは異なるエラーが発生。
(コマンドの最後がpython3ではなくpython3.6になっているのは、僕のVPS環境でpython3を呼び出すコマンドがpython3.6
になっているからです。)
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (35) Peer reports incompatible or unsupported protocol version.
調べてみると、どうも、Curlのバージョンが古いのが原因のようです。
参考:
https://stackoverflow.com/questions/43975973/how-to-fix-error-failed-to-download-on-rbenv-install
--verboseオプションをつけて
curl --verbose https://bootstrap.pypa.io/get-pip.py | python3.6
を実行してみると、以下のような詳細が出ました。
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* About to connect() to bootstrap.pypa.io port 443 (#0)
* Trying 2a04:4e42:11::175...
* Connected to bootstrap.pypa.io (2a04:4e42:11::175) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* NSS error -12190 (SSL_ERROR_PROTOCOL_VERSION_ALERT)
* Peer reports incompatible or unsupported protocol version.
* Error in TLS handshake, trying SSLv3...
> GET /get-pip.py HTTP/1.1
> User-Agent: curl/7.29.0
> Host: bootstrap.pypa.io
> Accept: */*
>
* Connection died, retrying a fresh connect
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
* Closing connection 0
* Issue another request to this URL: 'https://bootstrap.pypa.io/get-pip.py'
* About to connect() to bootstrap.pypa.io port 443 (#1)
* Trying 2a04:4e42:11::175...
* Connected to bootstrap.pypa.io (2a04:4e42:11::175) port 443 (#1)
* TLS disabled due to previous handshake failure
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* NSS error -12286 (SSL_ERROR_NO_CYPHER_OVERLAP)
* Cannot communicate securely with peer: no common encryption algorithm(s).
* Closing connection 1
curl: (35) Peer reports incompatible or unsupported protocol version.
TLSのハンドシェイクプロトコルでエラーが発生し、NSS error として報告されています。
(ハンドシェイクプロトコルでは、やりとりする2者が両方とも使える暗号化プロトコルを選ぶのですが、そこで合致するプロトコルがなかったということらしい。)
ということで、参考URLにある方法をそのまま使って、NSS error を解決します。
#解決策(?)1
##NSSのアップデート
ルート権限で以下を実行します。
yum update nss nss-util nspr
……結果から言うと、何も解決しませんでした。なんなんだ。
#解決策(?)2
こちらのサイトにある方法を試します。
yum update curl.x86_64
を実行した後に、curlのバージョンを確認。
curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.34 zlib/1.2.7 libidn/1.28 libssh2/1.4.3
はい。変わってませんね。7.29のままです。
NSSのバージョンが3.15.4から3.34に上がってますが、NSSをupdateしたからなのか、今curlのupdateをしたからなのか、今となってはわからなくなってしまった。
どっちにしても、問題は解決していない。
#解決策(?)3
下記3サイトに、ほぼ同じ方法が解決策が書いてあるので、実行してみます。
参考:
https://support.plesk.com/hc/en-us/articles/214029229-How-to-update-cURL-to-the-latest-version-on-a-Plesk-server
https://serverfault.com/questions/321321/upgrade-curl-to-latest-on-centos
https://stackoverflow.com/questions/28495444/how-to-upgrade-php-curl-to-version-7-36-0
/etc/yum.repos.d/city-fan.repo
というファイルを作り、中身を次のようにします。
[CityFan]
name=City Fan Repo
baseurl=http://www.city-fan.org/ftp/contrib/yum-repo/rhel$releasever/$basearch/
enabled=1
gpgcheck=0
そしたら次を実行します。
yum clean all
yum install curl
すると………
次のエラーが出ます!!!!
Loaded plugins: fastestmirror
CityFan | 2.9 kB 00:00:00
base | 3.6 kB 00:00:00
epel/x86_64/metalink | 6.6 kB 00:00:00
epel | 3.2 kB 00:00:00
extras | 3.4 kB 00:00:00
Could not retrieve mirrorlist https://mirrors.iuscommunity.org/mirrorlist?repo=ius-centos7&arch=x86_64&protocol=http error was
14: curl#60 - "Peer's Certificate issuer is not recognized."
One of the configured repositories failed (Unknown),
and yum doesn't have enough cached data to continue. At this point the only
safe thing yum can do is fail. There are a few ways to work "fix" this:
1. Contact the upstream for the repository and get them to fix the problem.
2. Reconfigure the baseurl/etc. for the repository, to point to a working
upstream. This is most often useful if you are using a newer
distribution release than is supported by the repository (and the
packages for the previous distribution release still work).
3. Disable the repository, so yum won't use it by default. Yum will then
just ignore the repository until you permanently enable it again or use
--enablerepo for temporary usage:
yum-config-manager --disable <repoid>
4. Configure the failing repository to be skipped, if it is unavailable.
Note that yum will try to contact the repo. when it runs most commands,
so will have to try and fail each time (and thus. yum will be be much
slower). If it is a very temporary problem though, this is often a nice
compromise:
yum-config-manager --save --setopt=<repoid>.skip_if_unavailable=true
Cannot find a valid baseurl for repo: ius/x86_64
はい。
何にもうまくいかないな……。。。。。
#結論(curlのアップデートを諦める)
curlのアップデートを諦めます。
要は、pythonプログラムである https://bootstrap.pypa.io/get-pip.py を実行すればいいわけなので、これを直接ローカルにダウンロードして、scpでサーバーにアップロードします。
で、普通にpythonプログラムとして実行
python3.6 get-pip.py
これでVPSサーバー上でもpipを10.0.1に更新できました。
そのままpip install tweepy
も問題なく済みました。
curlのアップデートがうまくいかなかった理由がわかる方がいらっしゃいましたら、どうか教えてください。