Blog

証明書には気をつけろ

この記事は、ニフティグループ Advent Calendar 2024 20日目の記事です。

はじめに

こんにちは。会員システムグループに所属しています、たかたか と申します。

最近、健康への意識が高まり、運動を始めました。ただし、食事制限はまだ行っていません。無理をせず徐々に健康体へ近づいていければと思っています。

さて、本ブログでは、最近起こしてしまった失敗について書いていこうと思います。エンジニアとしての仕事や日常生活の中で、もしかしたら起こるかもしれないミスや失敗を共有することで、皆さんの参考になればと思います。

起こったこと

とあるシステムのリプレイスのメンテナンスが終了した後、それは起こってしまいました。

なんと、HTTPSでの接続で証明書の検証がうまくいかず、サーバー間の通信ができなくなってしまったのです。

まあ、そんなこともあるよね、と感じていただけている方もいるかと思いますがその諸々について書いていこうと思います。

まずは証明書の検証について確認

まず、証明書の検証について、簡単に説明させていただきます

  1. まず、クライアントがサーバーにHTTPS接続をお願いします
  2. サーバーは自分の身分証明書(デジタル証明書)をクライアントに見せます
  3. クライアントは以下のようなチェックを行います:
    • 信頼できる機関が発行した証明書かどうか確認
    • 証明書の親子関係(証明書チェーン)が正しいか確認
    • 証明書の期限が切れていないか確認
    • 証明書が無効になっていないか確認
    • 証明書に書かれている名前と接続先が同じか確認
  4. すべての確認がOKだった場合、安全な通信路を作ります
    • 暗号化のための鍵を作って交換
    • 安全な通信をスタート

このチェックの中で一つでも問題があると、接続できなくなります。

経緯

AWSのマネジメントコンソールから必要なリソースを作成し、システムの構築を進めていました。その中で、サーバー間の通信にはHTTPSを使用することになっていたのですが、中間証明書とサーバ証明書の設定を間違えてしまいました。

  • この設定画面です

本番環境へのデプロイ前の検証では、curlコマンドで動作確認を行ってしまい、問題に気付くことができませんでした。

仕組み的にどうすればよかったのか

証明書の検証について、今回原因となったのは設定を間違えてしまったというところが根本的な原因です。しかし、ちゃんと動いているかどうかの確認で、HTTPのリクエストを送るツールが証明書をどのように、どのような環境で検証しているかというところも大事なポイントだと思っています。

サーバー証明書はPEM形式で

  • サーバー自身のサーバー証明書
  • 中間証明書
  • ルート証明書(通常はサーバーには含めません)

の内容を記載することができます。

webブラウザなどは中間証明書の内容がなくてもサーバー証明書の内容から補完することができたりしますが、スクリプトからhttpリクエストを送信しようとすると失敗することがよくあります。

サーバー証明書の設定は、使用するツールや環境によって検証結果が異なる場合があります。実際の運用環境では、複数のツールで検証を行うことが重要です。それでは、具体的な検証例を見ていきましょう。

検証

試しに、記載されているチェーンが不完全な証明書を用意し、検証してみましょう。

  • 設定を間違った証明書

以下のツールを使用して、私の端末で検証したいと思います

  • curl
    何かhttpリクエストを送りたいときよく使いますよね。 今回は動作検証をこれだけで実施してしまったので、失敗に気づけなかったです。 基本的に、ローカルに保存されている証明書ストアの情報と照合してちゃんと検証が行われるはずですが、私の使用している端末ではたまたまラッキーで証明書の検証が通過してしまいました。
  • pythonのrequestsモジュール
    pythonでhttp通信を行うときの鉄板ですよね。certifiというライブラリに保存されている証明書群に依存しており、ブラウザのように証明書の情報を自動で補完したりすることはないです。誤った証明書が設定されている等の原因で通信ができなくなったりします。
  • openssl
    証明書の検証といえばこれが使用されます。 証明書のチェーンが間違っていれば自動補完とかはせず、検証に失敗しますので、ここがOKなら大丈夫でしょう。

※入力・出力結果は一部改変しています

  • curlの実行結果

普通に返ってきましたね。

何か異常は見受けられません

  • requestsの実行結果

失敗しておりますね。

エラー内容を見ると、SSLCertVerificationErrorの文字が。

  • opensslの実行結果

Verification errorが発生してますね。

このような結果から 次のような教訓を得ることができました。

第一に、サーバー証明書の検証は使用するツールによって結果が異なる可能性があるため、複数のツールで確認することが重要。

第二に、curlコマンドだけでの検証は不十分で、より厳密な検証ツール(opensslなど)を併用する必要があります。

最後に

使用している技術への理解を深め、起こりうるミスのパターンを網羅できれば完璧なのですが、中々そうはいきませんよね。

エンジニアとしての活動がまだまだ短い私ではありますが、これから沢山経験を積んで成長していければと思っています。

明日は、swimland0306 さんの「ニフティにSREとして入社して2年間でやってきたこと」です。
お楽しみに!

ニフティでは、
さまざまなプロダクトへ挑戦する
エンジニアを絶賛募集中です!
ご興味のある方は以下の採用サイトより
お気軽にご連絡ください!

ニフティに興味をお持ちの方は
キャリア登録をぜひお願いいたします!

connpassでニフティグループに
参加いただくと
イベントの
お知らせが届きます!