Zscalerが導入された環境下でAWS CLIにて SSL validation failed エラーが発生した際の対処方法

# 本記事で扱う事象

AWS CLI を実行しようとした際に、証明書のエラーが発生しました

一例としてはAmazon S3バケットのリストを表示した際に下記エラーが出力されます。

~~~
aws s3 ls --profile ****PowerUserAccess-************

SSL validation failed for https://s3.ap-northeast-1.amazonaws.com/ [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)
~~~

コマンドを実行した環境では Zscaler が導入されていることから、その証明書の処理に問題があると推測されました。
本記事では証明書に関連する対処を行い、改善ができた手順についてまとめます。

# 原因
Zscalerはセキュリティ対策としてSSL/TLS通信を検査するために中間者として機能し、
オリジナルの証明書を独自の証明書に置き換えています。AWS CLIはデフォルトではこの
証明書を信頼しないため、検証エラーが発生します。

# 事象発生環境

OS  Windows 11 Pro バージョン 23H2 ビルド 22631.4751
Windows PowerShell バージョン 5.1.22621.4391
PowerShell バージョン 7.5.0
AWS CLI バージョン 2.24.5

※  Windows PowerShell と PowerShell の双方で同じ事象が発生

# 解決方法の概要

対処は以下の4工程に分かれます。

1. Zscaler の証明書をエクスポート
2. エクスポートした証明書を pem 形式に変換
3. aws configure set で証明書を指定
4. PowerShell の環境変数への設定の追加

以下に詳細を記載します。

# Zscaler の証明書をエクスポート

最初にZscaler Root CA をエクスポートします。

1. スタートボタンを右クリックし、[ファイル名を指定して実行]を選択します
2. 名前欄に certmgr.msc と入力し、 [OK] ボタンをクリックします
3. certmgr が起動しましたら[ 信頼されたルート証明機関] - [証明書]の順に選択します
4. Zscaler Root CA を右クリックし、[すべてのタスク] - [エクスポート]の順に選択します
5. [証明書のエクスポート ウィザード]が表示されましたら、[次へ]をクリックします
6. Base 64 encoded X.509 (.CER)を選択して、[次へ]をクリックします
**※ DER encoded binary X.509 (.CER)で出力するとバイナリ形式にて出力されてしまい後続の手順が実施できなくなります**
![スクリーンショット 2025-02-24 112340.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833876/41ac4550-c99a-499a-bae6-9feb32f264f4.png)

7. エクスポートするファイル名を入力し、[次へ]をクリックします

8. [完了]をクリックします
9. [OK] ボタンをクリックします

# エクスポートした証明書を pem 形式に変換
AWS CLIはPEM形式の証明書を読み込むため、エクスポートしたCER形式をPEM形式に変換する必要があります。

1. 保存した cer ファイルをメモ帳で開きます下記のような出力になっていることを確認します
※ こちらで文字化けしている場合には、前項の手順6の選択が間違っています
![スクリーンショット 2025-02-24 120122.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833876/b45e461d-ef06-4dd7-9b5c-32e6cdf03c82.png)

2. [ファイル] - [名前を付けて保存]を選択します
3. 下記内容にて pem 形式で保存します
ファイル名 任意の名前.pem
ファイルの種類を すべてのファイル (*.*)
![スクリーンショット 2025-02-24 120702.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833876/4c373844-57be-406e-81b6-b06ea587b025.png)


# aws configure set で証明書を指定

Zscaler オフィシャルページに記載のありますコマンドを実行します。

具体的には

Adding Custom Certificate to an Application-Specific Trust Store | Zscaler
https://help.zscaler.com/zia/adding-custom-certificate-application-specific-trust-store

の Amazon Web Services (AWS CLI) に従い下記コマンドレットを実行します。

~~~
aws configure set default.ca_bundle 前項で保存した pem ファイルのパス
~~~

# PowerShell の環境変数への設定の追加

本来であれば aws configure set の実行のみで問題が解消すると思うのですが、私の環境では問題が解消されませんでした。
追加でPowerShell のプロファイルに環境変数の設定を追加することで解消しました。

1. PowerShellを起動します
2. 下記コマンドレットを実行します
    ~~~
    notepad $PROFILE
    ~~~
3. メモ帳が開きます。下記の内容を入力し保存します

    ~~~
    $env:AWS_CA_BUNDLE="pemファイルの保存先パス"
    ~~~
既に何らかの設定がなされている場合には、本内容を追記して保存します
（注）PowerShellプロファイルが存在しない場合は自動的に作成されます。
変更を反映させるにはPowerShellを再起動するか、`. $PROFILE`コマンドを実行してください。

[補足]
Windows PowerShell と PowerShell 双方を使っている場合には、[PowerShell の環境変数への設定の追加]は双方の環境で実施してください。

# 改善の確認

上記の対処を実行しますと、証明書のエラーが表示されずにコマンドが実行できるようになります。

Amazon S3バケットのリストを表示の場合ですと以下のように作成したバケットのリストの取得が可能です。
![スクリーンショット 2025-02-24 130036.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833876/5d90816e-e0f0-4b98-a83e-a27999a21a61.png)

# 代替解決策
本記事の方法以外にも、以下の方法で問題を解決できる場合があります：

1. `--no-verify-ssl` オプションを使用する方法

    ~~~
    aws s3 ls --profile PowerUserAccess-******** --no-verify-ssl
    ~~~
    ※セキュリティ上のリスクがあるため、テスト環境でのみ使用することをお勧めします

2. AWS_CA_BUNDLEを一時的な環境変数として設定

    ~~~
    $env:AWS_CA_BUNDLE="pemファイルのパス"
    aws s3 ls --profile PowerUserAccess-********
    ~~~
# セキュリティに関する注意点
Zscalerのようなセキュリティツールが導入されている環境では、SSL検証をバイパスするよりも正しく証明書を設定することが重要です。
企業ポリシーに従い、セキュリティチームと相談の上で対応することをお勧めします。