はじめに
Zscalerが導入された環境でPythonのrequestsモジュールを使用したコードを実行すると、以下のようなSSL証明書関連のエラーが発生することがあります。
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1020)
このエラーは、Pythonが適切なSSL証明書を検証できないことが原因です。本記事では、Windows環境を前提にこの問題の適切な対処方法を解説します。
なお、一時的な回避策としてrequests.get(url, verify=False)
のようにverify=False
オプションを使用する方法もありますが、urllib3公式ドキュメントでも指摘されているように、このアプローチはセキュリティ上の理由から非推奨です。本記事では、より安全で恒久的な解決策を紹介します。
対処方法1:標準的な方法
Zscalerの公式ドキュメントによると、REQUESTS_CA_BUNDLE
環境変数に証明書のパスを指定することで問題を解決できます。
この方法は大きく分けて2つのステップからなります:
- Zscaler Root CA証明書のエクスポート
- 環境変数の設定
それぞれの手順を詳しく説明します。
1. Zscaler Root CA証明書のエクスポート
- スタートボタンを右クリックし、「ファイル名を指定して実行」を選択
-
certmgr.msc
と入力し、「OK」をクリック - 証明書マネージャーが起動したら「信頼されたルート証明機関」→「証明書」の順に選択
- 「Zscaler Root CA」を右クリックし、「すべてのタスク」→「エクスポート」を選択
- 「証明書のエクスポート ウィザード」が表示されたら「次へ」をクリック
- 「Base 64 encoded X.509 (.CER)」を選択して「次へ」をクリック
※ 重要: DER encoded binary X.509 (.CER)ではなく、必ずBase 64形式を選択してください
- エクスポート先のファイル名とパスを指定し、「次へ」をクリック
- 「完了」をクリック
- エクスポート成功のメッセージが表示されたら「OK」をクリック
補足:エクスポートするファイル形式について
Zscalerの公式情報ではPEM形式の証明書を指定していますが、Windows標準の証明書マネージャー(certmgr.msc)ではPEM形式での直接エクスポートができません。そのため、PEM形式と同様にBase64でエンコードされたCERファイルをエクスポートし、それを使用します。
2. 環境変数の設定
-
スタートボタンを右クリックし、「ターミナル」または「Windows PowerShell」を選択
-
以下のいずれかのコマンドを実行します:
ユーザーの環境変数として設定する場合(推奨)
[System.Environment]::SetEnvironmentVariable("REQUESTS_CA_BUNDLE", "前項で保存したcerファイルのパス", "User")
システム全体の環境変数として設定する場合
[System.Environment]::SetEnvironmentVariable("REQUESTS_CA_BUNDLE", "前項で保存したcerファイルのパス", "Machine")
注意点:
Zscaler公式情報ではシステム環境変数での設定方法が紹介されていますが、システム環境変数の設定には管理者権限が必要です。また、システム全体の設定となるため、その端末を使用する全ユーザーに影響します。多くの場合、ユーザー環境変数での設定で十分であり、より安全な選択肢です。 -
設定後、Pythonスクリプトを再実行してエラーが解消されたことを確認してください。
対処方法2:PowerShellコマンドレットによる自動化
標準的な手順でも数分で対処できますが、より効率的に設定したい場合は、以下のPowerShellコマンドレットを使用することで一括して処理できます。
- スタートボタンを右クリックし、「ターミナル」または「Windows PowerShell」を選択
- 以下のコマンドレットをコピー&ペーストして実行します:
$userFolderPath = [Environment]::GetFolderPath("UserProfile")
$folderPath = "$userFolderPath\zscalercertification"
if (-Not (Test-Path -Path $folderPath)) {
New-Item -Path $folderPath -ItemType Directory
}
$cert = Get-ChildItem -Path Cert:\CurrentUser\Root | Where-Object { $_.Subject -like "*Zscaler Root CA*" }
$tempCertPath = "$folderPath\zscaler_temp.cer"
$finalCertPath = "$folderPath\zscaler_base64.cer"
Export-Certificate -Cert $cert -FilePath $tempCertPath
certutil -encode $tempCertPath $finalCertPath
Remove-Item -Path $tempCertPath
[System.Environment]::SetEnvironmentVariable("REQUESTS_CA_BUNDLE", $finalCertPath, "User")
コマンドレットの説明
- 最初のブロック:ユーザーフォルダ配下に
zscalercertification
フォルダを作成 - 2番目のブロック:Zscaler Root CA証明書を検索、エクスポート、Base64形式に変換
- 最後の行:ユーザー環境変数
REQUESTS_CA_BUNDLE
に証明書のパスを設定
コマンド実行後、Pythonスクリプトを再実行してエラーが解消されたことを確認してください。
トラブルシューティング:設定後も問題が解決しない場合
上記の手順を実施しても問題が解決しない場合は、以下の点を確認してください:
-
実行環境の再起動:
- 使用しているIDE(VSCode、PyCharmなど)やPowerShellを再起動
- 環境変数が反映されるには再起動が必要な場合があります
-
再ログイン/再起動:
- ユーザー環境変数を設定した場合:Windowsからサインアウトし、再度サインイン
- システム環境変数を設定した場合:端末を再起動
-
証明書ファイルの確認:
- エクスポートした.cerファイルをメモ帳で開き、テキスト形式(Base64エンコード)になっているか確認
- 文字化けしている場合は、バイナリ形式(DER形式)でエクスポートされている可能性があります
- その場合は、手順に従って再度Base64形式で証明書をエクスポートしてください
-
パスの確認:
- 環境変数に設定したファイルパスが正確か確認
- パスにスペースが含まれる場合は引用符で囲む必要があります
まとめ
Zscaler環境下でのPython requestsモジュールのSSL証明書検証エラーは、適切な証明書を環境変数に設定することで解決できます。「verify=False」のような安全でない回避策ではなく、本記事で紹介した恒久的な解決策を実装することをお勧めします。
この設定を行うことで、セキュリティを犠牲にすることなく、Pythonの外部APIリクエストを正常に実行できるようになります。