WSL(Ubunu) 環境 Python のSSL: CERTIFICATE_VERIFY_FAILED を対処する
概要
- 今回、PCにCA 証明書を配置する必要があり、WSL(Ubunu) 環境にてPython の SSL: CERTIFICATE_VERIFY_FAILED を経験しましたので対処方法をまとめます。
エラーの発生状況
- WSL(Ubunu) 環境でAWS を管理する際に使用している aws-mfa のツールを実行した際に、以下のエラーを経験しました。(エラーメッセージの詳細は後述)
- " [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain"
- エラーメッセージからCA 証明書を配置する必要があることは分かりましたが、Ubuntu のOS が参照する全般の証明書は配置済みであり、この(Pythonで出来ている)ツールをエラーなく実行するために何を行えば良いか調べることにしました。
エラーメッセージの詳細
Traceback (most recent call last):
File "/home/niikawa/.local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 468, in _make_request
self._validate_conn(conn)
File "/home/niikawa/.local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 1097, in _validate_conn
conn.connect()
File "/home/niikawa/.local/lib/python3.10/site-packages/urllib3/connection.py", line 642, in connect
sock_and_verified = _ssl_wrap_socket_and_match_hostname(
File "/home/niikawa/.local/lib/python3.10/site-packages/urllib3/connection.py", line 783, in _ssl_wrap_socket_and_match_hostname
ssl_sock = ssl_wrap_socket(
File "/home/niikawa/.local/lib/python3.10/site-packages/urllib3/util/ssl_.py", line 471, in ssl_wrap_socket
ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
File "/home/niikawa/.local/lib/python3.10/site-packages/urllib3/util/ssl_.py", line 515, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
File "/usr/lib/python3.10/ssl.py", line 513, in wrap_socket
return self.sslsocket_class._create(
File "/usr/lib/python3.10/ssl.py", line 1100, in _create
self.do_handshake()
File "/usr/lib/python3.10/ssl.py", line 1371, in do_handshake
self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1007)
** 省略 **
対処方法
前提作業
- WSL(Ubunu) 環境にCA 証明書を配置する必要があります。以下、オペレーション例です。CA 証明書は、PEM形式で準備しておきます。
- これでUbuntu のOS は、配置されたCA 証明書を参照します。しかし、Python は個別でCA 証明書を設定する必要がありました。
% sudo su -
# mkdir /usr/share/ca-certificates/myca
# cp myca-certificates.pem /usr/share/ca-certificates/myca
# echo "myca/myca-certificates.pem" >> /etc/ca-certificates.conf
# update-ca-certificates
Python環境変数に CA_BUNDLE パスを設定する
- aws-mfa のツールでSSL証明書の検証が行われています。こちらのドキュメントによれば、requests の API にverify 引数を指定してCA_BUNDLE パスを渡せる様です。しかし、間接的にPython のrequests を使用しているだけであり、ツール自体に手を加えたくはありません。
- そのため、今回は環境変数 のREQUESTS_CA_BUNDLE を設定し、CA_BUNDLE パスを指定してaws-mfa のツール (Python) を実行します。
- 必要に応じて、シェル起動時のスクリプトに環境変数を追記ください。
## Pythonの cacert.pem のパスを確認する
$ sudo find /usr -name cacert.pem -print
## cacert.pem にCA 証明書の内容を追記する
$ sudo vi /usr/local/lib/python3.10/dist-packages/pip/_vendor/certifi/cacert.pem
## 環境変数 REQUESTS_CA_BUNDLE を設定する
$ export REQUESTS_CA_BUNDLE="/usr/local/lib/python3.10/dist-packages/pip/_vendor/certifi/cacert.pem"