1. はじめに
こんにちは。KHです。
以前、Azure Static Web Appsのフロントエンドに対し、
「クライアント証明書を使って認証し、アクセスする端末を制限したい」
という要件に取り組みました。
そこで、Azure Application Gatewayを用いて認証機能を実装したのですが、最終的には本番では採用されずお蔵入りとなりました。
とはいえ、当時の検証を通じて「意外とハマった」「こういう用語がややこしかった」といった学びが多かったので、自分なりに整理しつつこの記事としてまとめることにしました。
もし説明が足りなかったり、誤解を招く表現があれば、ぜひご指摘いただけると嬉しいです。
用語の読み分けについて
本記事では「クライアント証明書による認証」という言葉を使っています。
端的に言えば「クライアント側が証明書を提示し、その所有をもって接続を許可する」方式です。
「クライアント認証」だけだと意味が曖昧になりがちなので、ここではあえて少し長めですがこう呼称します。
また今回、記事中で「フロントエンド」「バックエンド」という単語が別々の文脈で現れ、混乱しやすかったため、要所要所で意味を説明しています。
先にイメージしておくと後がスムーズかなと思います。
Azure Application Gateway と Azure Static Web Apps の概要
-
Azure Application Gateway
Microsoft Azureが提供する「レイヤー7(アプリケーション層)」のロードバランサーです。
HTTP/HTTPSトラフィックを細かく制御し、セキュリティ強化やパフォーマンス改善を図れる機能が備わっています。
たとえばURLパスやホスト名に応じたルーティング、SSL/TLSの終端、Webアプリケーションファイアウォール(WAF)連携などが代表的な機能です。
公式ドキュメント(Application Gateway) -
Azure Static Web Apps
静的なHTML/CSS/JavaScriptファイルをホスティングしつつ、サーバーレスなバックエンド(Azure Functionsなど)と連携できるサービスです。
GitHubやAzure DevOpsと連携してCI/CDパイプラインを組むことも簡単にでき、フロントエンド開発に集中しつつ自動デプロイを実現できます。
公式ドキュメント(Static Web Apps)
この二つを組み合わせることで、Static Web Appsのシンプルさを活かしながら、Application Gatewayを経由してセキュリティを強化し、柔軟にトラフィックを制御するといったアーキテクチャが可能になります。
クライアント証明書認証の意義とユースケース
クライアント証明書認証は、公開鍵基盤(PKI)を使った認証方式で、クライアント側が所持する証明書を提示してアクセスを許可する仕組みです。
パスワード認証と比べて以下のようなメリットがあります。
- 高いセキュリティ
- パスワード漏洩の心配がなく、なりすましを防ぎやすい。
- 双方向認証
- サーバー側だけでなく、クライアント側もサーバーの証明書を検証できるため、双方の信頼性が担保される。
主な利用シナリオ
-
社内限定アクセス
社内ユーザー向けのWebアプリで、あらかじめ配布した証明書を持つ端末からのみログインを許可したい場合。
※今回の記事で取り組んだのはこのケースに近い形です。 -
B2B間のセキュアなデータ共有
パートナー企業間で高セキュリティ下にファイル共有やAPI連携をしたいとき。 -
金融システムや医療情報システム
取り扱うデータの機密性が極めて高いため、証明書ベースの認証を必須とする場合があります。
前提条件
- Static Web Appsでの静的サイトホスティングはすでに完了し、エンドポイントとなるURLが存在していること。
- 今回は商用CAを使わず、自己署名証明書を発行して検証するという想定です。
2. Azure Application Gatewayの基礎
Azure Application Gatewayは、レイヤー7(アプリケーション層)で動作するロードバランサーで、次のような特徴・機能があります。
主な特徴・機能
-
柔軟なリクエストルーティング
- URLパスやホスト名などでルーティング先を分岐できるため、複数のバックエンドを効率よく使い分けられます。
- たとえば
/api
はバックエンドA、/static
はバックエンドB といったルールを設定可能。
-
SSL/TLS 終端機能
- Application Gateway側でHTTPS通信(暗号化)の終端を行うことができ、バックエンドとApplication Gateway間は平文HTTPにして負荷を軽くするといった構成も組めます。
- 自己署名証明書やAzure Key Vaultに保管した証明書も指定できます。
-
Webアプリケーションファイアウォール(WAF)連携
- OWASP Top10 で代表的な脅威(SQLインジェクション、クロスサイトスクリプティングなど)を検出・防御するルールセットを提供します。
参考:OWASP TOP10 とは?
公式ドキュメント(WAF)
- OWASP Top10 で代表的な脅威(SQLインジェクション、クロスサイトスクリプティングなど)を検出・防御するルールセットを提供します。
-
スケーラビリティ
- トラフィック量に応じて自動的にスケールアップ・スケールダウンできるため、ピーク時でもパフォーマンスを維持しやすいです。
- コスト最適化にも貢献します。
-
ヘルスプローブ
- 定期的にバックエンドのヘルスチェックを行い、正常なインスタンスのみにトラフィックを振り分けます。
Static Web Apps との連携で得られるメリット
-
セキュリティ強化
- Static Web Apps 単体では細かいセキュリティ制御が難しい場合がありますが、Application Gateway を介すことでWAFやクライアント証明書認証などを追加し、堅牢な環境を作れます。
-
トラフィック管理の効率化
- SSL/TLS の終端やリクエストルーティングをすべてGatewayで行うことで、Static Web Apps 側はコンテンツ配信に集中でき、全体のパフォーマンスが向上します。
-
スケールの両輪
- Static Web Apps も Application Gateway もどちらもスケーリング機能を持っているため、トラフィック増加時にもシームレスに対応できます。
-
バックエンド統合の柔軟性
- Static Web Apps のみならず、Azure Functions や Azure App Service といった他のバックエンドも同一の Gateway を通じて運用できるため、統一的なエントリポイントを提供できます。
「フロントエンド」「バックエンド」の使い分け
冒頭でも触れましたが、この記事では同じ単語が二重に登場し、文脈によって指す対象が異なるタイミングがあるので、ここで整理しておきます。
1. Webアプリケーション視点のフロントエンド / バックエンド
-
アプリのフロントエンド
ユーザーのブラウザに表示される部分(HTML/CSS/JavaScript など)。
→ 本記事では「Static Web Apps」に該当します。 -
アプリのバックエンド
ビジネスロジックやデータベース連携を担うサーバー側(API やサーバーレス関数など)。
→ 本記事ではあまり深く触れませんが、必要に応じて Azure Functions 等が該当します。
2. Application Gateway視点のフロントエンド / バックエンド
-
Gateway のフロントエンド
Application Gateway に最初に届くリクエストやクライアントのことを指します。
→ 具体的にはブラウザなどから飛んでくるトラフィックそのものです。 -
Gateway のバックエンド
Gateway を通過した先にある実際のサーバーやサービスを指します。
→ 今回は「Static Web Apps のエンドポイント」が該当します。
便宜的な呼び方まとめ
- 「アプリのフロントエンド」→Static Web Apps
- 「アプリのバックエンド」→(本記事ではあまり出ませんが、Azure Functions や App Service など)
- 「フロントエンド」→Application Gateway における最初のエントリポイント(=クライアントからのトラフィック)
- 「バックエンド」→Application Gateway がトラフィックを流す先(=Static Web Apps)
これらを頭の片隅に置きつつ、以降は混乱しないよう意識して書いていきます。
3. クライアント証明書認証の仕組み
「クライアント証明書認証」は、クライアントがサーバーに接続する際に“証明書”を提示して本人確認を行う方法です。ここでは具体的な流れと、そのメリットを見ていきます。
認証の流れ
-
証明書の発行
- クライアント(ユーザーや端末)に、認証局(CA)が発行した証明書を配布します。
-
証明書の提示
- クライアントがサーバーに接続する際、証明書をブラウザやアプリケーションに登録し、通信時に証明書を提示します。
-
サーバー側で検証
- サーバー(やGateway)は、提示された証明書が信頼できるCAによって署名されているかをチェックします。
-
暗号化通信の確立
- 検証が成功すれば、サーバーとクライアント間でTLS通信が確立され、双方向に暗号化された通信が行われます。
クライアント証明書認証のメリット
1. 高いセキュリティ
パスワード認証と比べると、証明書はクライアント端末に安全に保管されるため、盗み見やブルートフォース攻撃による突破が難しくなります。
また、証明書の秘密鍵は外部に漏れにくく、なりすまし対策として非常に有効です。
2. 双方向認証が可能
クライアントがサーバーの証明書を検証すると同時に、サーバー側もクライアントの証明書を検証できるため、「どちらが接続してきているか」の信頼性が高まります。
いわゆる「お互いに信頼を確かめ合う」仕組みです。
3. パスワード運用の省力化
証明書はインストールするだけで自動的にブラウザやアプリが利用するため、ユーザーが毎回パスワードを入力する手間が省けます。
共通パスワード運用に伴うリスクもなくなります。
4. アクセス制御の強化
証明書を持つ端末だけにアクセスを許可することで、特定のデバイスやユーザーを厳密に管理できます。
許可外の端末は物理的に証明書を持っていないため、アクセスできません。
5. 大規模環境での拡張性
証明書ベースの認証は、大規模な組織やシステムでも柔軟に展開可能です。
新たなユーザーやデバイスが増えても、CAによる証明書発行手順を確立すればスケールしやすいです。
上記のように、クライアント証明書認証はセキュリティ面で非常に優れています。
次のセクションでは、Azure Application Gateway と Static Web Apps の組み合わせでどのようにこの認証を実現するかを解説します。
4. 実装手順の全体像
Azure Application Gateway と Static Web Apps を組み合わせてクライアント証明書認証を行うには、大きく以下の流れになります。
まずは「全体像」をざっくり把握しておきましょう。
全体のフロー
-
Azureリソースの用意
- Application Gateway、Static Web Apps、(必要に応じてKey Vaultなど)を作成します。
-
証明書の準備
- ルートCA(自己署名CA)を作成し、クライアント証明書とサーバー証明書を生成・配布します。
-
Application Gateway の設定
- HTTPSリスナーを作成し、サーバー証明書をアップロードします。
- SSLプロファイルを用意し、リクエストヘッダーにクライアント証明書情報を流すよう設定します。
-
バックエンド(Static Web Apps)の対応
- Static Web Apps 側で、クライアント証明書情報を受け取って認証判定するロジックを組み込む(例: Azure Functions を介して検証)。
-
テスト & 検証
- クライアント証明書をインストールした端末からアクセスし、正しく認証できるか確認します。
必要となる Azure リソース
-
Azure Application Gateway
- クライアント証明書を検証するためにHTTPSリスナーとSSLプロファイルを構成します。
- WAFを使う場合は別途WAF設定を有効化します。
-
Azure Static Web Apps
- 今回は静的サイトのホスティングに使います。
ここにリクエストを流しつつ、必要に応じて Azure Functions や API を組み合わせてクライアント証明書情報を検証します。
- 今回は静的サイトのホスティングに使います。
-
Azure Key Vault(任意)
- 証明書や秘密鍵を安全に保管したい場合に使用します。
- 今回はシンプルに自己管理する方法を前提としているので、Key Vault の使用は必須ではありません。
-
認証局(CA)または自己署名証明書
- テスト環境向けには自己署名のCAを作成し、そこからクライアント証明書を発行します。
- 商用環境では有償CAを使う想定もありますが、本記事では割愛します。
-
ネットワーク構成
- Application Gateway と Static Web Apps の間で通信できるよう、パブリックエンドポイントや必要に応じたプライベートリンクを設定します。
- Static Web Apps はもともとパブリック向けのサービスなので、主にNATやファイアウォールルールを確認します。
次節からは、証明書の作成~Application Gateway の設定手順を順を追って詳述します。
5. ルートCA/証明書の基礎知識
まずは「そもそもルートCA証明書って何?」「クライアント証明書ってどういう仕組みで動くの?」というところを整理します。
ルートCA(自己署名CA)とは
1. 自己署名証明書 vs 外部CA証明書
-
自己署名証明書
自分自身(=自分で生成したキー)で署名した証明書です。コストはかからずテスト用途には最適ですが、外部から信頼されるわけではないため、あくまで社内テストや開発環境向けとなります。 -
外部CA発行証明書
DigiCert や GlobalSign などの認証局が署名した証明書です。信頼性は高いものの、有償発行となります。商用サービスや公開環境ではこちらを使うのが一般的です。
2. ルートCA証明書の役割
- ルートCA証明書は、他のサーバー証明書やクライアント証明書を「このCAに認められたものですよ」と証明する元となるものです。
- クライアント証明書やサーバー証明書がルートCAの秘密鍵で署名されることで、「信頼できる証明書」とみなされます。
クライアント証明書のしくみ
1. 署名の流れ
- まず、ルートCAの秘密鍵で「クライアント用の公開鍵」を署名し、クライアント証明書(CRT)を生成します。
- クライアント(PCやスマホなど)には、秘密鍵(KEY)と証明書(CRT)をインストールします。
- サーバー(やGateway)がクライアントから提示された証明書を検証し、「ルートCA署名が本物である」ことを確認します。
- 確認が取れれば、そのクライアントからのアクセスを許可する、という流れです。
2. クライアントへのインストール
- Windows なら証明書をダブルクリックして「個人証明書ストア」にインポートできます。
- iOS/Android でもアプリや設定画面からプロファイルとしてインストールできます。
- ブラウザごとに管理方法が異なるため、具体的な手順は必要に応じて調べるとよいでしょう。
サーバー証明書のしくみ
サーバー証明書は、HTTPS通信を行う上で「このサーバーは信頼できる証明書を持っていますよ」という証明書です。Application Gateway の場合は、このサーバー証明書を使ってTLSの終端を行います。
- 証明書の発行手順(自己署名の場合)
- サーバーの秘密鍵(server.key)を作成
openssl genrsa -out server.key 2048
- CSR(Certificate Signing Request)を生成
openssl req -new -key server.key -out server.csr \ -subj "/C=JP/ST=Tokyo/L=Tokyo/O=ExampleOrg/OU=IT/CN=example.com"
- ルートCAで署名し、サーバー証明書を発行
openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial \ -out server.crt -days 365 -sha256
server.key
とserver.crt
を組み合わせて PFX(.pfx)形式に変換openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt -certfile ca.pem
- 生成した
server.pfx
を Application Gateway のHTTPSリスナー設定にアップロードして利用します。
- サーバーの秘密鍵(server.key)を作成
まとめ
- ルートCA証明書:クライアント証明書やサーバー証明書を署名する源。自己署名CAを作れば無料で手軽に使えるが、外部の信頼性はない。
- クライアント証明書:ルートCAによって発行され、クライアント端末にインストールする証明書。提示されたときにCA署名を検証することで本人確認を行う。
- サーバー証明書:クライアント(ブラウザなど)にサーバーの正当性を証明するための証明書。Application GatewayのHTTPSリスナーで使う。
次のセクションでは「自己署名CAを実際に作ってみる方法」について説明します。
6. 自己署名証明書の発行手順
ここでは、自己署名のCA証明書を作り、そこからクライアント証明書とサーバー証明書を発行する一連の手順を解説します。
実際にコマンドを打ちながら進めてみてください。
1. ルートCA証明書の作成
自己署名のルートCA証明書を作成し、以降の証明書発行元として利用します。
手順
-
ルートCAの秘密鍵(ca.key)を生成
openssl genrsa -out ca.key 2048
-
自己署名のルートCA証明書(ca.pem)を作成
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.pem \ -subj "/C=JP/ST=Tokyo/L=Tokyo/O=ExampleOrg/OU=IT/CN=ExampleCA"
ca.key
:ルートCAの秘密鍵ca.pem
:自己署名されたルートCA証明書-days 3650
は有効期間を10年に設定(テスト用途なら適宜変更可)
2. クライアント証明書の発行
ルートCAで署名したクライアント証明書を作成し、後述するテスト用端末にインストールします。
手順
-
クライアント秘密鍵(client.key)を生成
openssl genrsa -out client.key 2048
-
CSR(client.csr)を作成
openssl req -new -key client.key -out client.csr \ -subj "/C=JP/ST=Tokyo/L=Tokyo/O=ExampleOrg/OU=IT/CN=ClientDevice"
-
ルートCAで署名してクライアント証明書(client.crt)を発行
openssl x509 -req -in client.csr -CA ca.pem -CAkey ca.key -CAcreateserial \ -out client.crt -days 365 -sha256
client.key
:クライアントの秘密鍵client.csr
:証明書署名要求ファイルclient.crt
:ルートCAで署名されたクライアント証明書(有効期間1年)
-
PFX形式に変換(Windowsなどでインポートしやすいように)
openssl pkcs12 -export -out client.pfx -inkey client.key -in client.crt -certfile ca.pem
- 生成された
client.pfx
をクライアントPC等にインストールすると、秘密鍵込みの証明書として利用できます。
- 生成された
3. サーバー証明書の発行
Azure Application GatewayのHTTPSリスナーで使うためのサーバー証明書を作成します。
手順
-
サーバー秘密鍵(server.key)を生成
openssl genrsa -out server.key 2048
-
CSR(server.csr)を作成
openssl req -new -key server.key -out server.csr \ -subj "/C=JP/ST=Tokyo/L=Tokyo/O=ExampleOrg/OU=IT/CN=yourdomain.example.com"
CN
: Static Web Apps のカスタムドメインやデフォルトのFQDN(例:hogehoge.z13.web.core.windows.net
)を指定
-
ルートCAで CSR を署名してサーバー証明書(server.crt)を発行
openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial \ -out server.crt -days 365 -sha256
-
PFX形式に変換(Application Gateway にインポートするため)
openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt -certfile ca.pem
- 生成される
server.pfx
をAzureにアップロードしてHTTPS通信の終端として利用します。
- 生成される
注意点
- 自己署名CAで発行した証明書は「社内テスト」や「検証環境」でのみ使う想定です。
- 実運用やパブリックサービスでは、有償CA発行の証明書を使うようにしましょう。
- クライアント証明書は必ず秘密鍵(client.key)を安全に保管し、他者に渡さないように注意してください。
これで証明書の準備は完了です。次は Azure Portal 上で Application Gateway をセットアップし、これらの証明書を使って HTTPS リスナーや SSL プロファイルを作成する手順に移ります。
7. Azure Application Gateway のセットアップ
ここでは、Console(ポータル画面)を操作しながら、Application Gateway を構築し、クライアント証明書認証を有効化するまでの流れを説明します。基本的な作成手順と、SSL/クライアント証明書認証の設定方法を中心に解説します。
1. リソースグループと Application Gateway の作成
-
Azureポータルにサインイン
ポータル画面の左上にある「リソースの作成」または検索バーで「Application Gateway」と入力して作成画面に移動します。 -
リソースグループの選択・作成
- 既存のリソースグループを使うか、新規で作成します。
- Static Web Apps が属するリージョンと同じリージョンを選択すると、レイテンシが少なくなります。
-
Application Gateway の基本設定
- 名前:例
hogehoge-agw
- リージョン:Static Web Apps と同一
- スケーリング構成:Standard_V2 または WAF_V2(WAF を使う場合は後述)
- インスタンスサイズ・数:デフォルトで問題ないですが、トラフィック量が多い場合は調整可能。
- 名前:例
-
フロントエンド IP の設定
- パブリック IP:新規作成してパブリックアドレスを付与。
- プライベート IP:必要な場合に選択(今回の検証ではパブリックIPを使用)。
-
バックエンドプールの構成
- バックエンドプール名:例
staticwebapp-backendpool
-
ターゲット:Static Web Apps のエンドポイント URL(FQDN)を指定。
- 例:
hogehoge.z13.web.core.windows.net
のように、https://
を除いたホスト部分を入力します。
- 例:
- プロトコルは HTTPS、ポートは 443 とします。
- 「バックエンドサーバーの証明書は既知のCA発行ですか?」 → はい とする(自己署名CAの場合は「いいえ」にしても検証可能ですが、今回はあえてCAを信頼する形にします)。
- バックエンドプール名:例
-
設定を確認し、デプロイ
- 設定をすべて確認し、「確認および作成」→「作成」を押してデプロイします。
- デプロイ完了まで数分かかるため、しばらく待ちましょう。
2. HTTPS リスナーと SSL プロファイルの設定
-
リスナーの作成
- Application Gateway の設定画面から「リスナー」を選択し、「追加」をクリックします。
- リスナー名:例
HttpsListener-CertAuth
- フロントエンドIP:先ほど作成したパブリックIPを選択
- プロトコル:HTTPS
- ポート番号:443(デフォルト)
- SSLプロフィール:後述する「SSLプロファイル」を指定します。
-
SSL プロファイルの作成
- 「SSLプロファイル」→「追加」
- SSLプロファイル名:例
CertAuthProfile
-
サーバー証明書:先ほど作成した
server.pfx
をアップロード- PFXに設定したパスワードを入力
-
クライアント証明書認証の設定:
- 「クライアント証明書を必要とする」→はい
- 「ルートCA証明書」には自己署名CAの
ca.pem
をアップロード - これにより、Gatewayはクライアントが渡す証明書を検証し、CA署名の有無をチェックする
- 動作モード:ミューテックス(相互認証を厳格に行う)
-
HTTPヘッダーへの証明書情報転送:
- 「HTTPヘッダーでクライアント証明書情報をバックエンドに転送」→有効にする
- これにより、Application Gateway から Static Web Apps 側に証明書のサブジェクト情報などをヘッダー経由で渡せる
-
SSLプロファイルをリスナーに適用
- 先ほど作成した
HttpsListener-CertAuth
リスナーの編集画面で「SSLプロファイルを有効にする」にチェックを入れ、CertAuthProfile
を選択して保存します。
- 先ほど作成した
3. リクエストルーティング規則の作成
-
ルール名:例
CertAuthRule
-
リスナー:
HttpsListener-CertAuth
を選択 -
バックエンドターゲット:
staticwebapp-backendpool
(Static Web Apps のプール) -
バックエンドHTTP設定:新規作成または既存の設定を使用
- バックエンドプロトコル:HTTPS
- ホスト名オーバーライド:Static Web Apps の FQDN を設定(例:
hogehoge.z13.web.core.windows.net
) - 既知のCA証明書かどうか:はい(Static Web Apps 側で返す証明書が商用やCA署名なら「はい」に設定。自己署名でも無理やり「はい」にすると失敗するので「いいえ」に設定する必要がある場合もあります)
- その他パスベースルーティング:今回はシンプルに単一バックエンド宛なので不要
-
ルールを作成して保存
- これで、HTTPSで来たリクエストはすべて Static Web Apps 側のエンドポイントに流れるようになります。
これで Application Gateway の基本セットアップが完了です。次のセクションでは、準備したクライアント証明書を実際にインストールし、ブラウザ経由でテストする手順を解説します。
8. クライアント証明書認証のテスト
Application Gateway を経由して Static Web Apps にアクセスする際、クライアント証明書が正しく認証されるかどうかを確認します。以下の準備とテストケースを用意しましょう。
1. テストの前提と環境準備
サーバー側(Azure側)
- すでに Application Gateway に HTTPS リスナーと SSLプロファイルが設定済みであること。
- Static Web Apps 側に、Ribbon や Azure Functions などを組み込んでいない場合は、単純に「証明書検証結果に応じて 403 を返す」か、「正常時は静的コンテンツを返す」だけでも動作確認は可能です。
クライアント側(手元PCやスマホ)
-
クライアント証明書のインストール
- 生成しておいた
client.pfx
をクライアントPCにインストールする。 - Windows ならダブルクリックで「証明書のインポートウィザード」が起動しますので、パスワードを入力して「個人用ストア」にインポート。
- Mac や Linux、iOS、Android その他ブラウザでも設定方法が少しずつ異なるので、必要に応じて検索してインポートしてください。
- 生成しておいた
-
ブラウザの確認
- Chrome や Edge、Firefox でクライアント証明書を選択できるか確認。
- ブラウザによっては初回アクセス時に「どの証明書を使う?」とポップアップが出る場合があります。
2. テストケース設計
ケース 1:証明書あり(正常系)
- ブラウザにクライアント証明書をインストールした状態で、Application Gateway のパブリックIPまたはカスタムドメインに HTTPS でアクセス。
- Gateway がクライアント証明書を検証し、正当と判断したらリクエストを Static Web Apps に転送。
- Static Web Apps のトップページやAPIレスポンスが返ってくる(例:サイトのHTMLが表示される)。
- Azure Portal の診断ログや Application Gateway のアクセスログに「証明書検証成功」が記録される。
ケース 2:証明書なし or 無効証明書(異常系)
- 証明書をインストールしていないブラウザ、または署名されていない別の証明書をインストールしてアクセス。
- Gateway がクライアント証明書検証に失敗した場合、403 Forbidden が返ってくる。
- 診断ログには「証明書検証失敗」が記録される。
- 失敗理由(例:CA署名が無い、期限切れ、CNが不正など)をエラーメッセージから確認する。
3. ログの確認方法
- Azure Portal で Application Gateway を選択。
-
左側メニューの「診断設定」に移動し、「診断ログ」が有効かどうかを確認。
- 「AccessLog」や「PerformanceLog」、「FirewallLog」などが選択されているかチェック。
- Log Analytics や Storage Account を保存先として指定する場合は、これらにログが溜まるように連携しておく。
-
実際にアクセスしてみて
- Access Log にアクセス元IP、リクエストURL、ステータスコード(200/403など)や証明書のサブジェクト名が記録されていることを確認。
- 403 が返る場合は「854 (Client Certificate Authentication Failed)」などのエラーコードを確認すると、なぜ拒否されたかが分かります。
これでクライアント証明書認証の基本的な動作検証は完了です。次のセクションでは、設定にトラブルが発生した場合のトラブルシューティング手順を紹介します。
9. トラブルシューティング
実際に動かしてみると、「証明書が効かない」「403 が返ってくるが理由がわからない」「ログに出力されない」など、いくつかの問題に遭遇する可能性があります。ここではよくある問題と解決策をまとめました。
1. クライアント証明書が認識されない
原因例
- クライアントPCに証明書を正しくインストールできていない(証明書ストアに入っていない)。
- ブラウザ側で証明書を選択できていない、またはブラウザに対応していない形式でインポートした。
- 証明書の秘密鍵がパスワード保護されていない、あるいは形式が壊れている。
解決策
-
証明書の再インポート
- Windowsなら
certmgr.msc
を開き、「個人 → 証明書」にクライアント証明書が表示されているか確認。 - なければ再度
client.pfx
をダブルクリックし、正しいパスワードを入力してインストール。
- Windowsなら
-
ブラウザ設定の見直し
- Chrome や Edge では自動的にインポート先の「個人証明書」に向かいますが、Firefox は独自の証明書ストアを持つため、別途インポートが必要。
- それでも認識されない場合は、一度ブラウザを再起動して再度アクセスしてみる。
-
証明書ファイルの確認
client.crt
とclient.key
が正しくペアになっているか、オープンSSL などで中身を確認する。- PFXを再生成し直してみる。
2. 403 Forbidden が返ってくる
原因例
- クライアント証明書が無効(CA署名が不正、期限切れ、CNが間違っているなど)。
- Application Gateway の SSL プロファイル設定で、ルートCA証明書を正しくアップロードしていない。
- リスナーの SSL プロファイルが適用されていない、もしくは別のリスナー経由でアクセスしている。
- バックエンドの Static Web Apps 側が別途認証しており、そこで拒否されている。
解決策
-
証明書の有効期限・署名先を確認
openssl x509 -in client.crt -noout -text
で署名者(Issuer)がExampleCA
になっているか、期限が切れていないか確認。
-
SSL プロファイルのルートCA登録を再チェック
- Azure Portal の Application Gateway → SSL プロファイル → 「ルート証明書リスト」に
ca.pem
があるか確認。 - ない場合は再度アップロードし、リスナーへ適用。
- Azure Portal の Application Gateway → SSL プロファイル → 「ルート証明書リスト」に
-
リスナーが正しくHTTPSを受け付けているか
- HTTP → HTTPS ではなく、HTTPS → HTTPS になっているか。ポート番号が正しいかを確認。
- 必要に応じて Application Gateway を再起動することで反映漏れが防げる場合があります。
-
バックエンド側(Static Web Apps)のロギングを有効にする
- Static Web Apps が403を返している場合は、一度バックエンドで何が返っているかを Azure Functions などで詳細ログを出して確認してみましょう。
3. Application Gateway のログが出力されない
原因例
- 診断設定で「アクセスログ(AccessLog)」が有効になっていない。
- ログの保存先(Log Analytics / Storage Account / Event Hub)のいずれかが未設定。
- 膨大なログが出力されるためキャプチャにタイムラグが生じている。
解決策
-
診断設定の見直し
- Azure Portal → Application Gateway → 診断設定 → 「診断設定の追加」で AccessLog、FirewallLog、PerformanceLog などを選び、保存先を指定。
- 保存先が Log Analytics ワークスペースの場合は、ワークスペースが正常に機能しているかも確認。
- Storage Account を選んだ場合は、Blob コンテナにログファイルが溜まっているか確認する。
-
リアルタイム確認のための演習
- 診断設定を有効化した直後にテストアクセスし、Log Analytics のクエリ(例:
AzureDiagnostics | where ResourceType == "APPLICATIONGATEWAYS"
)でフィルタリングしてログが来ているか確認。
- 診断設定を有効化した直後にテストアクセスし、Log Analytics のクエリ(例:
4. バックエンドから期待したレスポンスが返ってこない
原因例
- バックエンドプールのエンドポイントが誤っている(FQDNやパスが間違い)。
- SSL プロファイルで「既知のCAによる発行」という設定を「いいえ」にしていないため自己署名のサーバー証明書が信用されず接続が失敗している。
- Static Web Apps 側の設定で、独自の認証ルールがかかっている(Azure Active Directory 認証など)可能性がある。
解決策
-
バックエンドプールのターゲットをチェック
- Azure Portal → Application Gateway → バックエンドプール → Static Web Apps のドメイン名が正しく登録されているか確認。
- HTTPS → HTTPS の場合は、「サーバー証明書は既知のCA発行ですか?」を自己署名の場合は「いいえ」にすると、証明書検証をスキップできます。
-
バックエンド側の動作確認
- 直接ブラウザから Static Web Apps の FQDN(例:
https://hogehoge.z13.web.core.windows.net
)にアクセスし、正常にコンテンツが返ってくるか確認。 - もしここで認証エラーが出るなら、Static Web Apps 側の設定(認証/認可など)を見直す。
- 直接ブラウザから Static Web Apps の FQDN(例:
以上が主なトラブル例とその対策です。設定を変更した際は、しばらく待ってキャッシュが反映されるか(10分程度)確認してみるとスムーズですし、診断ログを併用するとどこでエラーが起きているか掴みやすくなります。
10. セキュリティを強化する運用ポイント
クライアント証明書認証を導入しただけで終わりではなく、継続して安全に運用するためのポイントをまとめました。ここでは、有効期限の管理や証明書ローテーション、リボーク(失効)の手順などを押さえておきましょう。
1. クライアント証明書の有効期限管理
有効期限の設定
- 一般的には 1年~2年 程度の有効期限を設定することが多いです。
- あまり短いと管理が大変になりますが、長すぎると失効忘れリスクが増えるため、運用チームと相談して適切な期間を決めましょう。
期限切れ防止の仕組み
- 証明書管理ツール や Azure Key Vault の「シークレット期限通知機能」を使って、有効期限が近づいた証明書を把握。
- 自動メール通知やチャットツール連携を用意しておくと、証明書切れによるダウンタイムを防ぎやすいです。
2. 証明書のローテーション
証明書のローテーションとは、「新しい証明書を発行し、既存の証明書と置き換える」作業です。これを定期的に行うことで、万が一古い証明書が漏洩してもリスクを最小限にできます。
手順
-
新しいクライアント証明書を生成
- ルートCAから新たにクライアントCRT と KEY を発行。
-
新しい証明書をクライアントに配布
- 暗号化されたメールやセキュアなファイル共有経路で
client.pfx
を送付。
- 暗号化されたメールやセキュアなファイル共有経路で
-
Application Gateway に新しいルートCA/クライアント証明書を登録
- SSLプロファイルの「ルートCA証明書リスト」に新しい
ca.pem
を登録。 - 必要に応じて、古い CA を外すか順次複数のCAを登録してもよい。
- SSLプロファイルの「ルートCA証明書リスト」に新しい
-
クライアント側の証明書差し替え完了を確認
- 全クライアントが新版証明書を使ってアクセスできるかをテスト。
-
古い証明書の失効(リボーク)
- CAの CRL(Certificate Revocation List) を更新して、古いクライアント証明書をリボーク。
- Gateway 側が CRL を参照するよう設定されている場合は、古い証明書からのアクセスが失敗することで安全を保てます。
3. 証明書のリボーク(失効)手順
証明書が流出した、社員が退職した、盗難された等の理由で「証明書を無効化したい」場合にはリボークが必要です。
流れ
-
CAに失効リクエストを送信
- 認証局(自己署名CAの場合は自分)に対して「この証明書をリボークします」という記録を作成する。
-
CRL(Certificate Revocation List)の更新
- CA が CRL ファイルを更新し、そのリストを配布。
-
アプリケーション側で CRL/OCSP を参照
- Application Gateway などが CRL または OCSP(Online Certificate Status Protocol)を参照して、「この証明書はリボーク済みだ」という判定を行う。
- もし OCSP を使う場合は、CA側に OCSP レスポンダーを用意する必要があります。
4. 運用時のポイントまとめ
-
最小権限の原則
- 必要な端末やユーザーにだけクライアント証明書を発行し、漏れた場合はすぐリボークする。
-
証明書の利用状況とログ管理
- どの証明書を誰が使っているかを追跡しやすくするため、証明書サブジェクト名やシリアル番号をログに残す。
- 必要に応じて、Map や Excel 管理台帳を作るのも手。
-
定期的な監査
- 証明書の有効期限、リボークリストの状況、Application Gateway のログを定期的にチェックし、不審なアクセスがないか確認する。
-
インシデント対応計画の整備
- 証明書が漏洩した際の手順(誰に通知する、どの証明書をリボークする、影響範囲はどこにあるかなど)をあらかじめ明文化し、チームで共有しておく。
-
スケーリング時のテスト
- トラフィックが増えたときに、Gateway のスケールアウトや Static Web Apps のスケーラブル設定が正常に機能するかを定期的に検証。
以上のポイントを押さえておけば、クライアント証明書認証をより安全かつ安定して運用できるはずです。次は、今後の拡張や運用時に気を付けたい点を解説します。
11. 今後の拡張や運用時の留意点
セットアップがひと段落したら「この先どういう方向で拡張できるか」「運用時に具体的に何に注意するか」を考えておくと、将来的に手戻りが少なくて済みます。以下では代表的な拡張パターンと運用時の留意点を紹介します。
1. 拡張の方向性
1-1. APIや他サービスへの証明書認証適用
- Static Web Apps だけでなく、Azure Functions や App Service(API サーバー)にも同じクライアント証明書認証を導入して、よりセキュアな API 呼び出しを実現。
- Gateway のルーティング機能を使って、URL パスベースで Frontend → Static Web Apps、/api/* → App Service などと役割を分ける構成も考えられます。
1-2. WAF(Web Application Firewall)のルール強化
- Application Gateway に組み込まれた WAF を有効にして、OWASP Top10 などの脅威からアプリケーションを守る。
- IP レピュテーションやカスタムルールを追加して、特定の国・リージョンからのアクセス制限や、特定の攻撃パターンを防ぐ。
1-3. 多要素認証(MFA)との併用
- クライアント証明書認証だけでなく、Azure AD の MFA も導入することで、より強固な二要素認証を実現。
- ユーザー視点では多少手間が増えますが、機密性が極めて高いシステムであれば組み合わせる価値があります。
2. 運用時の注意点
2-1. 証明書有効期限管理の徹底
- 証明書の有効期限が切れると即座にアクセスできなくなるため、「いつまでに更新するのか」「誰が対応するのか」を明確にチームで共有しておく。
- Azure Key Vault を使う場合は、Secret に期限を登録し、期限前に通知が飛ぶようにアラートを仕掛けると便利です。
2-2. ログ監視と異常検知
- Application Gateway → Log Analytics などでアクセスログを取得し、「想定外のIPからの大量アクセス」「異常に多い 403 エラー」などをアラート設定すると、インシデントを早期に察知できます。
- 定期的にログをレビューし、不正アクセスの兆候がないかチェックしましょう。
2-3. インシデント対応計画の整備
- もしクライアント証明書が漏洩した場合、どの証明書をまずリボークするかを事前にリストアップしておく。
- チーム内で「証明書漏れ時対応フロー」をマニュアル化し、緊急時でも迅速に動けるようにしておく。
2-4. スケール時のテスト
- 新たな機能追加やトラフィック増を想定し、定期的に負荷試験を行う。
- 特に TLS 終端や WAF の性能がボトルネックになりやすいため、想定トラフィックをシミュレーションしてパフォーマンスを測定。
- 必要なら、インスタンス数を増やす自動スケール設定を検討。
3. コストへの配慮
- Application Gateway は稼働しているだけでコストが発生します。Standard_V2 で約 \$210/月(約33,000円/月)と言われることもあるので、不要になったらきちんとリソースを削除しましょう。
- Static Web Apps は比較的安価ですが、カスタムドメインや SSL 証明書を使う場合、追加費用や管理コストがかかる可能性があります。
- Azure Cost Management などで定期的に費用をモニタリングし、無駄なリソースが残っていないかチェックすることをおすすめします。
これらのポイントを抑えておくと、クライアント証明書認証を導入した後もスムーズに運用・拡張できます。最後に、本件の検証で発生したコスト例や注意点についてまとめて終わりにします。
12. 最後に(Azureリソースのコストについて)
今回の検証で新規に Azure Application Gateway を立ち上げた場合、コストがどの程度かかるかをザックリ確認してみます。なおコストは利用リージョンや構成によって大きく変動しますので、あくまで参考値としてください。
Application Gateway のおおよそのコスト例
-
リソース維持費(インスタンス維持)
Standard_V2(小規模構成)の場合、おおよそ \$200 ~ \$250/月 前後。- これだけで月々約 3万円超のコストとなるケースもあるため、検証目的の場合は、検証が終わったらすぐにリソースを停止・削除することが必須です。
-
データ処理量(データ送信量)
1GB あたり数セント程度の課金が発生します(Azure のアウトバウンド転送料金)。- Static Web Apps 側も同様にデータ送信量で課金が発生する場合があります。
-
WAF 使用時の追加コスト
WAF_V2 を有効化すると、別途 WAF ルールセット利用料がかかります。- ルール数や解析量に応じて料金が増減するため、高セキュリティ構成の場合は要注意です。
検証忘れによる「失敗例」
-
ケース:「金曜日の夕方にテストでデプロイしたが月曜まで削除を忘れて放置した」
- 1日あたり \$8 ~ \$10 のコストが積み上がるとすると、週末3日で \$30 程度。
- 為替レートにもよりますが、数千円の無駄遣いになります。
-
対策
- タグやリソースグループ名を工夫し、「検証用」「テスト用」などを明示して管理しやすくする。
- Azure Policy や Azure Cost Management のアラート機能を使い、「未使用のリソースが 24時間以上ある場合に通知を出す」といったルールを作成する。
- 検証終了後は即座にリソースを削除し、テスト専用のSubscriptionを用意するといった運用も検討。
公式ドキュメント(価格)
参考サイト(Azureサービス別コスト削減方法の紹介)
以上で、Azure Application Gateway を活用したクライアント証明書認証の導入から運用までを一通りご紹介しました。
エンジニアや営業の皆さんはもちろん、セキュリティ担当やインフラ担当の方にも参考になれば幸いです。
お読みいただき、ありがとうございました!