9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

通信時に証明書エラーに悩まされる環境との付き合い方

Posted at

前置き

所属企業のネットワークの話とは関係ありません。よくある話ですから。

背景

昨今の情報セキュリティ意識の高まりから、組織の情報セキュリティ担当部門は管理下のコンピュータについて、通信内容を検査可能にすることがトレンドとなっている。

その代表例が TLSインスペクション(SSLインスペクション、MITM) である。
この構成では、HTTPSを含むTLS通信は

  • クライアント ― 検査装置間
  • 検査装置 ― 実際のサーバ間

の 2つのTLSセッションに分断される。
つまり、本来成立するはずのクライアントとサーバ間の暗号通信は成立していない。

図:本来の暗号化通信と、TLSインスペクション時の通信
TLSとインスペクション時.png

一方で、WebブラウザのようにOSの証明書ストアをそのまま利用するソフトウェアに限れば、利用者が個別設定を行わなくても通信が成立するため、見かけ上は「透過的」に動作する。

しかし、我々のようなエンジニアは、プログラミング言語のランタイム、パッケージマネージャ、CLIツール、顧客指定製品などはこの前提から外れることが多く、エンジニアは高頻度でTLS関連の通信トラブルに遭遇する。

本記事の目標

通信トラブル発生時に以下を自力で行えるようになることを目的とする。

  1. 自組織がTLSインスペクションを行っているかの判断
  2. HTTPS(TLS)を復号する仕組み
  3. 典型的なエラーの読み取り
  4. 実務的な対処アプローチの理解

自組織での検査状況の確認

最も簡単な確認方法は、WebブラウザでHTTPSサイトの証明書を確認することである。

Chromeで https://example.com の証明書を表示した例を以下に示す。

図:証明書ビューア
image.png

確認すべき点は サーバ証明書の発行元(Issuer) である。

  • 正常な場合:DigiCert、GlobalSign、Let’s Encrypt、Cloudflare など
  • TLSインスペクション下:組織名、プロキシ製品名など

特に以下の状態であれば、TLSインスペクションが行われている可能性が極めて高い。

  • 複数のドメインを開いても、同一の発行元である
  • 発行元が社内向け名称である

CA証明書とは何か(本記事での扱い)

TLS通信では、サーバ証明書が「誰によって発行されたか」を検証することで、
相手が正しいサーバであるかを判断する。

この「発行してよいと信頼されている証明書」を CA証明書 と呼ぶ。

クライアントはあらかじめ信頼するCA証明書の一覧を持っており、
サーバ証明書がそのいずれかに連なって検証できた場合のみ通信を成立させる。

本記事では、特に断りがない限り、
「TLSインスペクション装置が発行するサーバ証明書を正当と判断させるために
クライアント側へ配布されるCA証明書」を指して CA証明書 と呼ぶ。

通常、CA証明書はTLSインスペクションのため、OSやソフトウェアが保持する「信頼する証明書ストア」に登録される。

HTTPS(TLS)を復号する仕組み

通常のTLS通信では、概略として以下の流れになる。

  1. サーバがサーバ証明書をクライアントに提示
  2. クライアントが証明書チェーンを検証
  3. 検証成功後、鍵交換を行い共通鍵を合意
  4. 以降の通信を共通鍵で暗号化

TLSインスペクションでは、クライアントとサーバ間の通信を検査するために以下を行う。

  1. クライアントからの接続を検査装置が終端する
  2. 実サーバの証明書はクライアントに渡さない
  3. 検査装置が 動的に生成したサーバ証明書 をクライアントに提示する
  4. その証明書を正当と判断させるため、検査装置のルートCA証明書をクライアント側で信頼させる

この結果、通信内容は検査装置上で平文として取得可能になる。

前項の証明書の発行元の確認は、この仕組みが存在するかを確認している。

通信トラブルの例

TLSインスペクション環境で問題が発生すると、以下のようなエラーが典型的に出力される。

SELF_SIGNED_CERT_IN_CHAIN

SSL routines:tls_post_process_server_certificate:certificate verify failed

ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate

これらは表現こそ異なるが、本質的には 証明書チェーンの検証失敗 を示している。

TLSインスペクション環境で起きる通信トラブルの原因は、
「必要なCA証明書をつかわず検証している」ことである。

通信トラブルの解決方法

「必要なCA証明書をつかわず検証している」ことを解消するために、
必要なCA証明書をプロセスに渡す手順を整理する。

  1. CA証明書の特定
    Webブラウザが通信できている場合、少なくともOSの証明書ストアにはCA証明書が登録されている。
    Windowsでは「信頼されたルート証明機関」から、サーバ証明書の発行元に対応するCA証明書をエクスポートする。
    組織のPCセットアップ手順でCA証明書が配布されている場合は、それをそのまま利用する。

  2. CA証明書の利用

    1. 環境変数による利用
      プロセスによっては環境変数を介してCA証明書を参照させることができる

      • NODE_EXTRA_CA_CERTS
        node.js / npm / Claude Code / Roo Code など
      • SSL_CERT_FILE
        Python(urllib3 等)
      • AWS_CA_BUNDLE
        aws-cli

      最も安全で影響範囲が限定される方法。

    2. OSのCAストアによる利用(システム全体)
      OSが参照するCAストアに追加することで、多くのツールが自動的に利用する

      # Ubuntuの場合
      sudo cp org-ca.crt /usr/local/share/ca-certificates/
      sudo update-ca-certificates
      

      影響範囲が広く、どのソフトウェアに影響するかを事前に特定しきれない。

    3. OSのCAストアを参照させるソフトウェアの導入
      Windows証明書ストアを参照させるためのツールも存在する。
      win-ca
      truststore
      セキュリティモデルは十分理解した上で使用すること

注意事項(重要)

  • 本番環境・顧客環境に同じ設定を持ち込まないこと

結論

仕組みを理解した上で正しくCA証明書を扱えば、
TLSインスペクション環境下でも通信ができる。

参考

本記事で説明した通信を復号する仕組みを提供するソフトウェアが存在する。
正確な情報や本記事の内容を検証するにはこちらを参照のこと。

MITMProxy – How mitmproxy works

9
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?