【実務・中級編】 Azure AD (Microsoft Entra ID) 条件付きアクセスによるリスクベース認証の構成 – インフラ・ネットワーク & クラウドセキュリティ防御ガイド

現場のエンジニア諸君、日々のアラート対応とデプロイで疲弊していないか?
今日は「パスワードさえ強固にすればいい」という幻想を捨ててもらう。ID/パスワードが漏洩するのは、もはや「防げない前提の事故」だ。重要なのは、「漏れたIDが使われた瞬間に、いかにして無力化するか」という出口戦略に他ならない。

今回は、Entra ID(旧Azure AD)の条件付きアクセス(Conditional Access)を用い、攻撃者が喉から手が出るほど欲しがる「セッションの乗っ取り」すら跳ね返す、実戦的な防御策を解説する。

なぜ「リスクベース認証」が必要なのか:攻撃者の視点

昨今の攻撃者は、フィッシングでセッションCookieを盗み取る「AiTM(Adversary-in-the-Middle)」攻撃を多用している。多要素認証(MFA)を突破するこの手法に対し、従来の「場所とパスワード」だけの防御は紙の盾だ。

攻撃者は、あなたの会社の社内ネットワークIPを偽装し、盗んだセッションを使って深夜にログインを試みる。このとき、「デバイスが準拠しているか」「サインインリスクは高くないか」を動的に評価する条件付きアクセスが組まれていなければ、防御側はなすすべもなく侵入を許す。

実践:条件付きアクセスの設計指針

条件付きアクセスは「誰が、どこで、何を使って、どのリスク状態で」アクセスしているかを判断するロジックだ。以下のポリシーを構成することで、攻撃者のコストを跳ね上げろ。

1. 必須の防御レイヤー:リスクベースの強制MFA

「サインインリスク」が中以上の場合、たとえID/パスワードが正しくても、必ずMFAを再要求する。

  • 割り当て: 全ユーザー
  • 対象アプリ: 全クラウドアプリ
  • 条件:
  • サインインリスク: 「高」「中」
  • デバイスプラットフォーム: すべて
  • アクセス制御: 「アクセスの許可」→「多要素認証を要求する」

2. コンプライアンスによる防御

未管理のデバイスからのアクセスを拒否または制限する。

  • 条件: デバイスの状態「準拠しているとしてマーク済み」を必須とする。
  • これにより、Intuneで管理されていない私物端末からのアクセスを遮断し、攻撃者がバックドアとして利用する「個人のPC」を排除できる。

エンジニアのための自動化:Graph APIによる監視コード

GUIでの設定は基本だが、運用の「冪等性」を保つにはコードによる管理が必要だ。Azure ADのポリシー状態を定期的にチェックするPythonスクリプト例を置いておく。

# 必要ライブラリ: pip install msgraph-sdk
from msgraph import GraphServiceClient
from azure.identity import DefaultAzureCredential

# 認証情報の取得
credential = DefaultAzureCredential()
client = GraphServiceClient(credential)

async def check_conditional_access_policies():
    # 現在設定されている条件付きアクセスルールを取得して出力する
    policies = await client.conditional_access.policies.get()
    
    for policy in policies.value:
        print(f"ポリシー名: {policy.display_name}")
        print(f"状態: {policy.state}")
        
        # もしポリシーが無効化されていたら警告を出す(運用監視の自動化)
        if policy.state == "disabled":
            print(f"【警告】ポリシー {policy.display_name} が無効になっています!")

# 実際の運用では、これをGitHub ActionsやAzure Functionsで定期実行し、
# ポリシーが改ざんされたらSlackにアラートを飛ばす仕組みにするのが鉄則。

Webアプリ側で実装すべき「ラストワンマイル」の防御

条件付きアクセスでネットワークを固めても、アプリ側のコードが甘ければ意味がない。特にセッション管理は盲点だ。例えば、PHPでセッションを扱う際、php.iniの設定だけで満足していないか?

<?php
// セッションクッキーを強固にするための設定
// これを怠ると、セッションハイジャックが容易になる
ini_set('session.cookie_httponly', 1); // JSからのセッションID読み取りを不可にする
ini_set('session.cookie_secure', 1);   // HTTPS接続のみでクッキーを送信
ini_set('session.use_strict_mode', 1); // 攻撃者が生成したセッションIDの拒否

session_start();

// さらに、IPアドレスやユーザーエージェントをセッションに紐付け、
// 変化した場合は強制的に破棄するロジックを実装せよ
if (!isset($_SESSION['user_agent'])) {
    $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
} elseif ($_SESSION['user_agent'] !== $_SERVER['HTTP_USER_AGENT']) {
    session_regenerate_id(true); // セッションIDを再生成して無効化
    session_destroy();
}
?>

最後に:防御は「多層」でなければならない

諸君、条件付きアクセスは万能ではない。攻撃者は常に「ポリシーの穴」を探している。だからこそ、システムを設計する際は「ゼロトラスト」を合言葉にしろ。

1. Entra IDの条件付きアクセスで、怪しいアクセスを入り口で弾く。
2. Intuneでデバイスを管理し、箱の中身をクリーンに保つ。
3. アプリケーションコードで、セッションの寿命と整合性を厳格に管理する。

これら全てを組み合わせて初めて、寝ている間に会社のデータが流出するような最悪の事態を防げる。泥臭い作業だが、これがプロのエンジニアの仕事だ。明日から自分の管理する環境のポリシーを再確認してくれ。健闘を祈る。

コメント

タイトルとURLをコピーしました