SSL証明書検証が有効な環境でMCPサーバーのSSL証明書エラーが発生した時の解決方法
はじめに
MCPサーバを使用していると、SSL証明書エラーに遭遇することがあります。特にSSL証明書検証が有効なネットワークでは、この問題が発生します。
今回はuvxでMCPサーバを起動した際に発生した事象を例に解説しますが、Dockerや仮想環境からプロキシ経由で接続する際にも同様に起こりうる事象です。
この記事では、SSL証明書検証が有効な環境でMCPサーバを使用する際のSSL証明書エラーの原因と解決方法について、技術的な背景を含めて解説します。
SSL証明書エラーとは?
SSL証明書エラーはHTTPS通信時、SSL証明書検証に失敗することで発生するエラーです。
ファイアウォールやプロキシがSSL証明書検証するため、この問題が発生します。
なぜ、SSL証明書エラーが起きたのか?
今回、MCPサーバを立てて通信する際、下記のSSL証明書エラーが出力されました。
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain
エラーの意味:
-
CERTIFICATE_VERIFY_FAILED:SSL証明書検証に失敗 -
self-signed certificate in certificate chain:証明書チェーン内に自己署名証明書が含まれている
HTTPS通信時にuvxでSSL証明書を信頼できないと判断したために発生しています。
SSL証明書エラーが発生する主な原因
SSL証明書エラーが発生する理由は、ファイアウォールやプロキシによる証明書検証です。PCからの接続には異常はありませんでしたが、uvxで起動してAWSサーバとの通信する際に、証明書検証に失敗しました。uvxでAWSサーバと通信する際の証明書検証で、カスタムCA証明書のパスが指定されていなかったことが原因でした。
通常の通信フロー
あなたのPC → AWSサーバ
└── AWS公式の証明書で直接通信
SSL証明書検証が有効な環境での通信フロー
あなたのPC → ファイアウォール → AWSサーバ
├── ファイアウォールがAWS証明書を傍受
├── カスタムCA証明書で再署名
└── 再署名されたカスタムCA証明書がOS(macOS)の証明書ストアに登録されているため通信成功
SSL証明書検証が有効な環境での通信フロー(仮想環境)
仮想環境(uvx) → ファイアウォール → AWSサーバ
├── ファイアウォールがAWS証明書を傍受
├── カスタムCA証明書で再署名
└── 再署名されたカスタムCA証明書がPythonの証明書ストアに登録されていない → エラー
解決策
uvxで起動するときは、SSL_CERT_FILE環境変数でカスタムCA証明書のパスを指定する必要があります。
もし、SSL証明書検証のメカニズムの詳細を知りたい人はこちら
前提
このガイドは以下の環境で実行しました。
実行環境
- OS:macOS
- パッケージマネージャー:uv(uvxコマンドでPythonアプリケーション実行)
- エディタ:Cursor
- MCPサーバ:uvx経由でインストール・実行
必要なツール
- OpenSSL:証明書の確認と操作(macOSに標準搭載)
- uvx:Pythonアプリケーションを仮想環境で実行するツール
- Python:MCPサーバの実行に必要なランタイム環境
セットアップ手順
1. uvxのインストール(未インストールの場合)
# Homebrewでuvxをインストール
brew install uv
# インストール確認
uvx --version
2. OpenSSLの確認
なぜOpenSSLを使うのか?
- 証明書の詳細情報を確認できる
- 証明書チェーンの分析が可能
- 標準的なツールで信頼性が高い
OpenSSLの基本的な使い方
# OpenSSLバージョン確認
openssl version
# 特定サイトの証明書情報を確認
openssl s_client -connect example.com:443 -servername example.com
# 証明書チェーン全体を表示
openssl s_client -connect example.com:443 -showcerts
# 証明書ファイルの内容を確認
openssl x509 -in certificate.crt -text -noout
# 証明書の有効期限を確認
openssl x509 -in certificate.crt -enddate -noout
# 証明書の発行者と主体を確認
openssl x509 -in certificate.crt -subject -issuer -noout
解決のステップ
1. SSL証明書検証が有効な環境のルートCA証明書の確認
SSL証明書検証が有効な環境でHTTPS通信する際に実際に使用されるルートCA証明書を確認し、システム上での配置場所を特定します。
証明書チェーンの確認方法:
# 証明書チェーンの主体と発行者を番号付きで表示
echo | openssl s_client -connect docs.aws.amazon.com:443 -showcerts 2>/dev/null | \
awk '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/' | \
awk 'BEGIN{cert_num=0} /-----BEGIN CERTIFICATE-----/{cert_num++; cert=""} {cert=cert $0 "\n"} /-----END CERTIFICATE-----/{print "=== 証明書 " cert_num " ==="; print cert | "openssl x509 -noout -subject -issuer"; close("openssl x509 -noout -subject -issuer"); print ""}'
自己署名証明書の判定条件:
- 主体(Subject)と発行者(Issuer)が同じ
コマンド出力例:
=== 証明書 1 ===
subject=CN=docs.aws.amazon.com
issuer=C=US, O=Corporate Inc., CN=Corporate CA
=== 証明書 2 ===
subject=C=US, O=Corporate Inc., CN=Corporate CA
issuer=C=US, O=Corporate Inc., CN=Corporate CA
この例では最後の証明書2がルートCA証明書になります。主体と発行者が同じなので、自己署名証明書であることから、SSL_CERT_FILEには最後のルートCA証明書ファイルのパスを指定しましょう。
2. uvxでのMCPサーバ設定
envオブジェクトの中にSSL_CERT_FILEを追加します。
SSL_CERT_FILEを追加することで、証明書検証に使う「カスタムCA証明書ファイル」を指定できます。
Cursorでの設定例:
{
"mcpServers": {
"awslabs.aws-documentation-mcp-server": {
"command": "uvx",
"args": ["awslabs.aws-documentation-mcp-server@latest"],
"env": {
"FASTMCP_LOG_LEVEL": "ERROR",
"SSL_CERT_FILE": "{カスタムCA証明書ファイルのパス}"
},
"disabled": false,
"autoApprove": []
}
}
}
MCPサーバを起動して、対象のサーバと接続できていれば無事に完了です。
まとめ
調査して試行錯誤した結果、環境変数を1つ追加するだけで解決できました。 SSL証明書エラーを適切に解決することで、SSL証明書検証が有効な環境でのMCPサーバの安定運用が実現できます。
この記事がSSL証明書エラーの解決に役立てば幸いです!質問やフィードバックがあれば、コメントでお気軽にお聞かせください。
参考リンク
Appendix: SSL証明書検証の詳細メカニズム
A1. 直接通信でのSSL証明書検証
通常のHTTPS通信でのSSL証明書検証
通常のWebサイトアクセス:
あなたのブラウザ → example.com
├── ブラウザ:「example.comの証明書を見せて」
├── サーバー:「GlobalSignが発行した証明書です」
├── ブラウザ:「GlobalSignって誰?」
├── ブラウザ:「GlobalSign Root CAが保証してる」
├── ブラウザ:「GlobalSign Root CAは信頼できるCAだ」
└── 接続成功
証明書チェーンのSSL証明書検証プロセス
証明書チェーンの例:
example.com証明書
├── 発行者:GlobalSign Organization Validation CA
├── GlobalSign Organization Validation CA証明書
│ └── 発行者:GlobalSign Root CA
└── GlobalSign Root CA(ルートCA証明書)
└── 発行者:GlobalSign Root CA(自己署名)
SSL証明書検証ステップ:
- サーバ証明書のSSL証明書検証:example.com証明書の署名と有効期限を確認
- 中間証明書のSSL証明書検証:GlobalSign Organization Validation CA証明書の署名と有効期限を確認
- ルートCA証明書のSSL証明書検証:GlobalSign Root CAがOS(macOS)やPythonの証明書ストアに存在するかチェック
A2. プロキシ経由でのSSL証明書検証
プロキシ経由でのSSL証明書検証の仕組み
通信フロー:
あなたのPC → ファイアウォール/プロキシ → AWSサーバ
ステップ1:元のリクエスト
├── あなたのPC:「AWSの証明書を見せて」
├── ファイアウォール:「リクエストを傍受」
ステップ2:証明書の置き換え
├── ファイアウォール:「AWSサーバに接続」
├── ファイアウォール:「AWSの証明書を取得」
├── ファイアウォール:「AWS証明書をカスタムCAで再署名」
ステップ3:新しい証明書の提供(カスタムCA未設定の場合)
├── ファイアウォール:「カスタムCAが発行したAWS証明書です」
├── あなたのPC:「カスタムCAって誰?」
├── あなたのPC:「知らないな...証明書ストアにない = 信頼できない」
└── ❌ SSL証明書エラー発生
ステップ3:新しい証明書の提供(カスタムCA設定の場合)
├── ファイアウォール:「カスタムCAが発行したAWS証明書です」
├── あなたのPC:「カスタムCAって誰?」
├── あなたのPC:「このカスタムCAは信頼できるCAだ!」
├── あなたのPC:「証明書チェーンも有効」
├── あなたのPC:「docs.aws.amazon.comの証明書として受け入れ」
└── ✅ SSL証明書検証成功・接続確立
証明書の置き換えプロセス
元のAWS証明書:
├── 主体:docs.aws.amazon.com
├── 発行者:Amazon Root CA 1
└── 署名:Amazon Root CA 1
ファイアウォールが作成する証明書:
├── 主体:docs.aws.amazon.com(同じ)
├── 発行者:カスタムCA(変更)
└── 署名:カスタムCA(変更)
A3. カスタムCA証明書の信頼問題
なぜカスタムCAが信頼されないのか?
OS(macOS)やPythonの証明書ストア:
├── VeriSign CA証明書
├── GlobalSign CA証明書
├── Let's Encrypt CA証明書
├── カスタムCA証明書 ← これがない!
└── その他の信頼できるCA証明書
問題の核心:
- カスタムCA証明書がOS(macOS)やPythonの証明書ストアに登録されていない
- システムが「このCAは知らない」と判断
- 信頼できないCAとして扱われる
A4. セキュリティ上の理由
なぜ接続を拒否するのか?
セキュリティ上の理由:
├── 中間者攻撃(MitM)の防止
│ ├── 悪意のあるプロキシが偽の証明書を提供
│ └── システムが知らないCAの証明書は危険
├── データの機密性保護
│ ├── 信頼できない証明書での通信は安全ではない
│ └── 通信内容が傍受されるリスク
└── 証明書の真正性確保
├── 正規のCAが発行した証明書のみを信頼
└── 偽造証明書による攻撃を防ぐ
SSL証明書検証が導入される理由
SSL証明書検証の目的:
├── HTTPS通信の内容を監視
├── マルウェアや機密情報の漏洩を防止
├── セキュリティポリシーに違反する通信をブロック
└── セキュリティの向上
そのため、開発環境ではカスタムCA証明書を適切に設定する必要があります。
Appendix: まとめ
SSL証明書の仕組みを理解しておくと、エラーが出た時に「何が起こっているのか」が分かるようになります。SSL証明書検証が有効な環境での開発では、セキュリティを保ちながら効率よく作業することが大切で、今回学んだ知識がその手助けになってくれます。
次に似たような証明書の問題に出会った時も、この理解があることでスムーズに対応できるようになるはずです。
Discussion