[小ネタ]AWS CLIで`SSL Validation Failed`が出た時の対処法

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/965ac457-3456-3f02-a6ce-0a47899e6c47.png)

結論：AWS CLIが証明書を認識できるように環境変数を設定します

# 動作環境
|項目名|値|
|:-|:-|
|OS|64bit版 Windows 11 Pro|
|エディタ|Visual Studio Code 1.96.2 (Default Terminal: Git Bash)|
|AWS CLI|aws-cli/2.23.9 Python/3.12.6 Windows/11 exe/AMD64|

# 背景
ある環境でいつも通りAWS CLIを利用したら以下のエラーが発生。
```
$ aws s3 ls

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)
```

このエラーは、AWS CLIがローカルPC内の証明書を認識出来ないために発生するエラーです。公式にも記載がありました。

>AWS CLI コマンドを使用すると、[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed というエラーメッセージが表示されます。これは、企業が認定機関 (CA) に設定されており、プロキシの証明書が自己署名されているなどの要因により、AWS CLI がプロキシの証明書を信頼していないことが原因です。これにより、AWS CLI はローカル CA レジストリにある企業の CA ルート証明書を検索できません。

https://docs.aws.amazon.com/ja_jp/cli/v1/userguide/cli-chap-troubleshooting.html#tshoot-certificate-verify-failed

ZscalerやNetskopeなどのクラウド型Proxyを利用している企業環境だと発生する可能性があります。
このようなエラーが発生した場合、AWS CLIから該当の証明書を認識できるように設定する必要があります。
なので今回対処方法をまとめ実際にその方法を試してみました。

# 対処方法一覧
対処方法としては大きく３つあります。

|対処法|メリット|デメリット|
|:-|:-|:-|
|コマンドオプションに `--ca-bundle 保存した証明書のパス` を追加|特になし|毎回オプションを指定すること|
|configファイルに `ca_bundle=保存した証明書のパス` を追加|プロファイルごとに証明書の設定が可能|プロファイルが複数ある場合に同様の設定追加が必要|
|環境変数 `AWS_CA_BUNDLE=保存した証明書のパス` を追加|環境全体に適用されるためconfigファイルへの個別設定が不要|証明書変更時に環境変数の修正と読み込みが必要|

### コマンドオプション
コマンドを実行するたびにオプションを追加する方法になります。
```
$ aws s3 ls --ca-bundle 保存した証明書の絶対パス/証明書ファイル名
```

### configファイル
`~/.aws/config` ファイルのプロファイル毎に設定を追加する方法になります。
```diff:~/.aws/config
[default]
region = ap-northeast-1
output = json
+ ca_bundle = 保存した証明書の絶対パス/証明書ファイル名
```

### 環境変数
環境変数 `AWS_CA_BUNDLE` を追加し読み込ませる方法になります。
```
export AWS_CA_BUNDLE=保存した証明書の絶対パス/証明書ファイル名
```

# 実践
今回は、環境変数を利用する方法を実践します。また、エクスポートした証明書をpem形式のファイルで管理するようにします。そうすることで、仮に証明書が追加になった場合でもpemファイルに追記していくことでデメリットである環境変数のパス設定を変更しなくてもすみます。

### 証明書エクスポート
まずは該当の証明書をローカルPCにエクスポートします。
1. Windows環境の方は、デスクトップの検索タブから「証明書」と入力すると「ユーザー証明書の管理」がヒットするので開きます。
2. 信頼されたルート証明書機関」の中から該当の証明書を「右クリック」→「すべてのタスク」→「エクスポート」で任意のフォルダにエクスポートします。
:::note info
エクスポート形式は「Base 64 encoded X.509(.CER)(S)」
:::
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984127/fab92231-f27c-b823-49b0-3f71976605d7.png)

### pemファイル作成
続いてpemファイルを作成します。ファイル名および作成場所は任意で構いません。
作成したpemファイルに、先ほどエクスポートしたcerファイルをテキストで開き、中身すべてをコピーして貼り付けます。
```XXX.pem
-----BEGIN CERTIFICATE-----
~~~~~~~
~~~~~~~
-----END CERTIFICATE-----
```

:::note info
別の証明書を追加する場合は、同様に追加したい証明書の `-----BEGIN CERTIFICATE-----` から `-----END CERTIFICATE-----` を次の行に張り付けていきます
:::

### 環境変数設定
最後に環境変数を設定します。今回私の環境では、bashを利用しているため以下のコマンドを実行します。
```bash
$ export AWS_CA_BUNDLE=作成したpemファイルが保存されているパス/XXX.pem
```

加えて、環境変数を永続化させるため、 `~/.bashrc` もしくは `~/.bash_profile` に追加します。今回は `~/.bashrc` に追加します。

```bash
# 事前にファイルは作成してください
sed -i '$aexport AWS_CA_BUNDLE=作成したpemファイルが保存されているパス/XXX.pem' ~/.bashrc
```

作成後、再度ターミナルを開けば正常にコマンドが実行できます。

# まとめ
今回は小ネタとしてAWS CLI利用時の証明書検証エラーへの対応方法をまとめました。
とても地味ですが、誰かのお役に立てれば幸いです。

# 参考文献
### リファレンス
* [AWS CLIのエラーのトラブルシューティング-AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/v1/userguide/cli-chap-troubleshooting.html#tshoot-certificate-verify-failed)
* [AWS re:Post-SSL validation failed on AWS CLI](https://repost.aws/ja/questions/QUb1GzApZvS6erbGyG4BXEqA/ssl-validation-failed-on-aws-cli)