数週間前からウイルス定義の更新が止まっているノートPCが、それでも社内アプリを開けてしまうなら、たいていの場合ポリシー文書が間違っているわけではない。アクセスを拒否する前に、三つの別々の仕組みが一致していなければならない。何かがエンドポイントを測定し、何かがその測定を許可か拒否の判定に変え、何かが実際に通信を落とす。不適合な端末がそれでも入ってくるなら、そのいずれか一つの環が欠けているか、信じるべきでない証拠を信じている。以下の確認はその順序で進み、それぞれに止まるべき地点がある。

遮断は最初の段階ではなく、最後の段階だ

認証とデバイス状態は別の問いに答える。ログインの成功は資格情報が提示されたことを証明するだけで、それを提示した機械で何が動いているかは何も語らない。その隙間があるからこそ、コピーしたクライアントプロファイルが、健全に見えるセッションを不健全なホストへ運べてしまう。

エンドポイント準拠の仕事には、この連鎖のための語彙がすでにある。RFC 5209 の NEA 参照モデルは、仕事を収集、評価の段階、適用の地点に分け、自分の状態について嘘をつくクライアントはモデルの外にあると明言している。この但し書きは図よりも重要だ。信頼されたプラットフォームモジュールは、自己申告の測定を事実には変えない。

収集の範囲について誠実であれ。ポリシーが名指しする属性を、アクセスを求める端末上で報告し、それ以外はほとんど報告しない。インストール済みの全パッケージを列挙する資産管理エージェントは、状態収集とは別の道具であり、その差は保存の問題でも精度の問題でもある。レポートを一つの端末識別子に結び付けられないなら、評価者はどの機械をたった今通したのかを推測していることになる。

赤い状態を表示するダッシュボードは制御ではない。拒否された利用者がまだ何に届くかを問うべきだ。Wiki、ファイル共有、データベースのポートはどうか。是正には狭い面が一つあればよく、それ以外は遮断の後ろに置く。

ルールを読む前にレポートを読む

クライアントの緑のチェックからではなく源から始めるのがよく、Windows ではローカルの測定は Defender か Security Center に登録した製品から来るもので、どちらもベンダーのコンソールなしで読める。

Get-MpComputerStatus | Select-Object AMServiceEnabled, RealTimeProtectionEnabled, AntivirusSignatureLastUpdated
Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntiVirusProduct | Select-Object displayName, productState

二つ目のコマンドは productState という整数を返す。そのビットは緩くしか文書化されておらず、有効化と最新性のフラグの詰め方もベンダーごとに違うので、解析するのではなく裏取りする。サードパーティ製スイートはアンインストール後も Security Center の項目を残し、それはディスク上にもう無いソフトについて報告する。

人々が飛ばすのは年齢の項目で、署名のタイムスタンプは評価を行う機械の時計と照らして初めて意味を持つので、目分量で見積もるのではなく間隔に変換する。

$sig = (Get-MpComputerStatus).AntivirusSignatureLastUpdated
[int](New-TimeSpan -Start $sig -End (Get-Date)).TotalHours

これでポリシーには読むべき数が一つできた。ルールが 72 時間と言っているなら、それが使う数であり、一週間眠っていたノートPCは誰かがラベルを解釈しなくても落ちる。しきい値はコマンドの横に記録しておくこと、エンドポイントの道具が入れ替わると両者はずれるからだ。

各端末の状態を書かれた判定に変える

状態をめぐる争いの多くは、実のところ未知の行をめぐる争いだ。最初のインシデントの前に、証拠と判定と所有者を名指しする表の中で決めておく。そうすれば誰もゲートウェイのコンソールで即興しない。

Evidence the assessor hasVerdictWhat it protects against
Timestamp inside the policy window, protective service runningAdmit to normal applicationsNothing yet; the other checks still apply
Timestamp older than the windowDeny, admit remediation page onlySignature rollback and dormant laptops
Service disabled or reporting offDeny, escalate to the endpoint ownerAn agent reporting stale success
No report at all for this sessionTreat as deny, never as healthyAgents that fail open under load

製品が分かれるのは下の行だ。接続を拒否して理由を説明するゲートウェイもあれば、トンネルを上げたまま制限付きのポリシーを当てるものもあり、少数は最後に知られた良好なレポートへ戻る。擁護できるのは最初の二つだけで、自分のものがどちらかを試す価値はある。

識別と許可も別の車線に置く。状態の試験をすべて通るノートPCでも、アプリには正しい人による承認が要るし、デバイス証明書が証明するのは鍵の所持であってファイルシステムの状態ではない。三つを一つの真偽値に潰すと、ヘルプデスクのアカウントが本番への常設アクセスを得る。

適用の経路はダッシュボードではなく、リクエストで確かめる

適用はリクエストの性質であり、不適合な機械をトンネルに載せて実際の利用者がする呼び出しを行えば、リクエスト一つで測れる。

curl -sS -o /dev/null -w '%{http_code}
' --max-time 5 https://app.internal.example/health

遮断されるべき端末から 200 が返るなら、判定はデータの経路に届いていない。よくある原因は二つあり、ポリシーがテストアカウントの入っていないグループに付いているか、アプリが VPN の持たない経路で届いてしまうかだ。

まず経路の前提を確かめる。内部名が、クライアントがすでにローカル LAN で届くアドレスに解決されるなら、トンネルは無関係でポリシーは適用されない。そのアドレスを、ゲートウェイが押し出す経路と比べる。OpenVPN ではクライアントごとのポリシーがコモンネームで鍵をかけたファイルにあり、確認は容易だ。

ls /etc/openvpn/ccd/
cat /etc/openvpn/ccd/laptop-17

disable を含むファイルはそのクライアントを完全に切断し、push "route ..." の行は届く範囲を狭める。どちらも適用であり、どちらもレポートを調べる者に見える。

四つのケースを一つの試験アカウントで試す

最後の確認は小さなマトリックスであって、順風満帆の道ではない。試験アカウントを四つの状態に通す。最新、期限切れの署名、保護が無効、エージェント未導入。それぞれについて、判定を評価ログに、アプリが返す HTTP の状態を、是正ページが読み込まれたかどうかを記録する。

foreach ($case in 'current', 'stale', 'disabled', 'absent') {
  Get-MpComputerStatus | Select-Object AMServiceEnabled, AntivirusSignatureLastUpdated
  curl.exe -sS -o NUL -w "%{http_code}
" --max-time 5 https://app.internal.example/health
}

見落としやすい点が二つある。まず再生については、機械が健全だったときに取ったレポートを同じ端末の後続セッションで受け入れてはならないので、現在の接続に結び付いたタイムスタンプを探す。次に除去については、エージェントを外したら古いレポートと同じ拒否になるべきで素通りになってはいけないが、このケースは最もよく未検証のまま残る。

マトリックスが表と一致したら、コマンドとしきい値と期待される四つの結果を、次にゲートウェイを運用する人へ渡す。この引き継ぎこそが本当の成果物で、ポリシー文書の中だけに生きる状態設計は、エンドポイントの道具が報告の項目を変えた最初の瞬間にずれる。

関連記事