アラート疲れ:セキュリティモニターから1日82通のメール
一人で運用するセキュリティモニターは、アラートをどれだけ送るべきでしょうか。 私の数字では、1日にメール約1通と、何か対応を求めるまれな1通です。11月1日、私のモニターは太平洋時間の午前0時から13:32までに74通のメールをメールサービスに渡しました。内訳は、すでに実施済みのブロックについての55通、クリティカルアラート16通、1時間ごとの件数アラート2通、そしてMac上のスキャナーからの1通です。12 その日の午後の私の読みでは、どれもエッジがすでに止めていた日常的なスキャンを伝えるものでした。3 ただしクリティカルのフラッドについては、6節で示すとおり、この読みは甘すぎました。修正したのは閾値ではなくポリシーです。ハートビートを兼ねる1日1通のダイジェスト、ブロックの通知はメールではなくチャットへ、エッジがすでに処理したクリティカルはダイジェストに畳み込む、そしてクラウド側の各クリティカルにその顛末(outcome)を書き込む、というものです。翌日、あるスキャナーが私のサイト群で6分足らずのうちに4件のクリティカルを発生させましたが、モニターはそれについてメールを1通も送りませんでした。4 それでもその日のメールは1通ではなく19通で、その理由こそがこの話で最も役に立つ部分です。5
モニターのメールを読むのは私一人です。受信箱に74通とあったとき、私はこれが日常的なものなのか本物の脅威なのかを問いました。正直な答えは、件名からはモニターにも判断がつかない、というものでした。どの件名も、音量を変えて同じことを言っていたからです。1 唯一の読み手が読むのをやめたモニターは、検出器がまだ何を捕まえていようと、もう監視をしていません。以下では、その件数、それに代わったポリシー、1つのテストケース、そしてきれいな話がほころぶ3つの箇所を順に述べます。
TL;DR
- 13:32までに74通、深夜0時までに82通。 私が苦情を言う前の時点について、私自身の表とログから導いた件数は74通で一致しています(ブロックごと55通、クリティカル16通、1時間ごと2通、ローカル1通)。11月1日全体では、ログに記録された81通に、私が手動で送ったダイジェスト1通を加えた数になりました。125
- 74通のうち22通は証明できません。 これらはメールサービスの応答を確認せずに「sent」とログに書くコードから出たもので、ログが証明するのは受け渡しが試みられたことであって、メッセージが届いたことではありません。26
- 答えとなる原則は、すでに文献にありました。 Googleの『Site Reliability Engineering』(SRE本)は、監視の出力としてアラート、チケット、ロギングの3つだけを認め、「Every page should be actionable」(すべてのページは対処可能であるべき)と述べ、メールのアラートを「alert spam」(アラートスパム)と呼んでいます。The Joint Commission(米国の医療機関認定団体)の警告は、「between 85 and 99 percent of alarm signals do not require clinical intervention」(アラーム信号の85〜99%は臨床的介入を必要としない)という推定を引用しています。78910
- テストケースはうまくいきました。 11月2日、オランダのホスティング事業者の1つのアドレスが、5分51秒のうちに私のサイト群で4件のクリティカルを発生させました。モニターはそれを一度ブロックし、ブロックをチャットに投稿し、すべてのクリティカルをダイジェストに畳み込み、メールは1通も送りませんでした。41112
- 翌日もまだ1通ではなく19通でした。 14通は、ブロックもチャレンジも記録されていないイベントを含むクリティカルなWAFフラッドのアラートでした。その件名は、エッジがイベントを1件もブロックしていない場合でも「WAF blocks」と書いていました(その日に2回。前日の夜には、エッジが何もブロックもチャレンジもしていないのに「104 WAF blocks」と書いたものが1通ありました)。件数を数えた当日に行った最初の書き換えも、まだ2種類の件数を1行に混ぜており、この記事のレビューがそれを見つけました。51314
- 2つのシグナルは誤りでした。 Mac上のコード署名チェックはAppleのSpotlightデーモンを署名のない暗号通貨マイナーと判定しました。ダイジェストの「RUNS SHORT 162/207」(実行回数不足 162/207)は、一部がスリープ、一部が実際より遅い実行間隔、そしてタイミングから見て一部がウォッチドッグによる3回の強制終了でした。151617
- 変えたこと: 1日1通のダイジェストが、ハートビート、すべてのブロック、すべてのクラウド側クリティカルの顛末を運びます。即座にメールを送るのは、どちらの畳み込み条件にも当てはまらないクリティカル、1時間ごとの件数アラート、ローカルスキャナーだけです。11月1日の82通は、11月2日には19通になりました。185
1. 11月1日の受信箱
11月1日の太平洋時間13:32、私はインフラを動かしているエージェントのセッションに書き込みました。モニターのメールが受信箱をスパムのように埋めている、何か変えるべきことはあるか、これは日常的なものか本物の脅威か、と。1 その日の午後に作った表では、深夜0時からのメール74通を送信元別に数えていました。ブロック1件ごとの通知55通、クリティカルアラート16通、1時間ごとの件数アラート2通、そしてMac上のスキャナーからのクリティカル1通です。1
件数は1つのルールに基づいているので、数字の前にそのルールを示します。この記事でいうメールとは、メールサービスへの受け渡しを記録した、モニターのログの1行です。スクリプトで10月31日から11月2日までの6つのログファイルを走査し、そうした行をすべてストリーム別、結果別に分類しました。5 13:32までで区切ると、スクリプトはストリームごとに私の表と一致します。55、16、2、1で、合計74です。2 現地時間の1日全体、深夜0時まででは、ログに記録されたメールは81通(ブロックごと55通、クリティカル22通、1時間ごと3通、ローカル1通)でした。これに、13:48に私が手動で送ったダイジェスト1通が加わります。このダイジェストはモニターのログに送信行がなく、合計で82通です。51
一致の中に、重要な点が2つあります。私の表はクリティカルについて「9 before the fold went live at 00:30 PT; the 7 after」(畳み込みが00:30 PTに稼働する前に9通、後に7通)と書いていました。ところがログでは、00:30より前のクリティカルの「sent」行が11、後が5で、ブロック通知に畳み込まれた最初のクリティカルは00:54:43に現れます。畳み込みの変更が入ったのは00:46 PDTで、私の表が挙げた00:30ではありませんでした。218 合計は合っていますが、手で書いた内訳は2つずれていました。2つ目はもっと大きな問題です。74通のうち22通(ブロックごと10通、クリティカル11通、1時間ごと1通)は、メールサービスの応答を捨て、返ってきたものが何であれ「sent」とログに書く送信処理から出ていました。26 その朝、時計が戻る前の01:04 PDTに入れた修正で、クラウド側の送信処理はサービスのHTTPステータスをログに残し、2xxのときだけ「sent」と書くようになりました。ローカルスキャナーの送信処理は、リクエストがエラーを出さなかったときにだけ、素の「Critical email sent」(クリティカルメール送信済み)という行を書きます。6 それ以前の22行が証明するのは、モニターが試みたことです。メールサービスが何かを受け付けたことは証明しません。10月31日の私のログは、クラウド側のメールは「most likely were」(おそらく)届いたと判断していました。妥当な推測ですが、推測であることに変わりはありません。19
2xxでさえ、「sent」という言葉が示唆するほどのことは証明しません。Resendのドキュメントは、email.sentイベントを「Occurs whenever the API request was successful. Resend will attempt to deliver the message to the recipient’s mail server,」(APIリクエストが成功するたびに発生する。Resendは受信者のメールサーバーへのメッセージ配信を試みる)と定義し、配信は別の、後のイベントとして挙げています。20 送信呼び出し自体はidを返すだけです。21 以下の件数はすべて、メールサービスが受け付けた受け渡しの件数です。ただし11月1日の22通と10月31日の10通、計32通については、モニターが試みた受け渡しの件数です。5 どれも、私が読んだメッセージの件数ではありません。
時間帯別に見ると、その日は崖と台地のような形をしています。
11月1日、現地時間:1時間ごとのメール数と、メールにならなかったアラートの数。13:50のポリシー変更を示しています。22
最初の1時間には22通のメールがあり、すべて未検証のコードからでした(ブロックごと10通、クリティカル11通、1時間ごと1通)。22 その後、ブロックごとの通知は1時間に1〜5通のペースで続きました。エッジがスキャナーをブロックし続け、ブロックのたびに私宛てに手紙が書かれたからです。ブロックごとのメールの最後の1通は13:25:57に出ており、代わりにダイジェストに畳み込まれたブロックごとの通知の最初の1件は14:20:35に現れます。22 13:50の変更の後、メールは1時間に0〜2通に落ち、畳み込みや抑制されたアラートは1時間に最大23件まで増えます。22 トラフィックは減っていません。減ったのはメールです。
前日は比較の基準として不適切です。11月1日の私のログには「Yesterday had 10」(昨日は10通)とあり、スクリプトも同じ数を出します。しかし10月31日のログは、私がモニターを再稼働させた夜の22:31から始まっているので、その10通は89分間をカバーしているにすぎません。15 私の読みでは、74通という数字は、スキャナーの行動の変化ではなく、インターネットのバックグラウンドノイズを丸1日受けて検出器が働いた結果を測ったものです。
2. アラートは何のためのものだったか
モニターは2つの部分からなります。クラウド側は、私のMac上で5分ごとに実行されるようスケジュールされ、私の各ゾーンについて、Cloudflareにファイアウォールイベントと集計されたリクエスト数を問い合わせます。どのアドレスがどのパスにどれだけアクセスし、エッジが各イベントにどんなアクションを取ったか、という情報です。1823 このデータについては、Cloudflare自身の説明がそのまま適切な枠組みになります。「Security Events displays information about requests actioned or flagged by Cloudflare security products, including features such as Browser Integrity Check.」(Security Eventsは、Browser Integrity Checkなどの機能を含むCloudflareのセキュリティ製品がアクションを取った、またはフラグを立てたリクエストに関する情報を表示する)24 ローカル側はMac自体を10分ごとに段階的にチェックするスキャナーで、プロセスとそのコード署名、マシン上のエージェントのフック、パス上でシステムのバイナリを覆い隠すツールなどを調べます。12
クラウド側がそのデータで何をするかは、簡単に述べられます。重大度(critical、high、medium)とカテゴリごとに検出結果を上げ、クリティカルについては誰かに知らせる前に行動しようとします。1つのアドレスがイベントの十分な割合を占めていれば、そのアドレスを、全ゾーンがエッジで適用するアカウント全体のブロックリストに7日間追加します。124 11月1日の変更までは、そうした行動の1つ1つがメールも生んでいました。サイトとカテゴリごとの2時間の制限で抑制されなかったクリティカルも、各セッションの終了も、ブロックが多かった1時間ごとにも、同じくメールが出ていました。185 ローカルスキャナーは独自に検出結果を上げ、クリティカルのメールも自分で送ります。25 Cloudflare自身のAlertsには2種類あり、「Monitors that you define yourself, and Platform Notifications」(自分で定義するMonitorsと、Platform Notifications)、つまりスケジュール実行されるSQL APIクエリと、あらかじめ構成された製品アラートで、どちらもダッシュボードで設定します。26 私のものはそのどちらでもありません。Mac上のスクリプトがファイアウォールイベントを自分で読むもので、それはつまり、ノイズを直すのも私の仕事だということです。
3. 文献がすでに述べていたこと
以下のどれも新しい話ではなく、そこが居心地の悪いところです。私はそのほとんどを読んでいながら、イベントごとにメールを送るモニターを作ってしまいました。
出力は3つ、そしてメールはそのどれでもない。 GoogleのSite Reliability Engineeringの序章は「There are three kinds of valid monitoring output」(有効な監視の出力には3種類ある)と述べています。アラートは「Signify that a human needs to take action immediately」(人間がただちに行動する必要があることを示す)もの、チケットは「Signify that a human needs to take action, but not immediately.」(人間が行動する必要があるが、ただちにではないことを示す)もの、そしてロギングは「No one needs to look at this information, but it is recorded for diagnostic or forensic purposes.」(誰もこの情報を見る必要はないが、診断やフォレンジックの目的で記録される)ものです。7 同じページは、私が採っていた設計について率直です。「a system that requires a human to read an email and decide whether or not some type of action needs to be taken in response is fundamentally flawed.」(人間がメールを読み、それに応じて何らかの行動が必要かどうかを判断しなければならないシステムは、根本的に欠陥がある)7 この分類に当てはめると、ブロックごとの55通のメールは、アラートとして届けられたロギングでした。エッジはすでに行動しており、人間がやるべきことは何も残っていませんでした。
すべてのページは対処可能であるべき。 同じ本の監視に関するRob Ewaschukの章は、アラートを「A notification intended to be read by a human and that is pushed to a system such as a bug or ticket queue, an email alias, or a pager,」(人間に読まれることを意図し、バグやチケットのキュー、メールエイリアス、ポケベルなどのシステムに送られる通知)と定義し、メールの種類についての脚注は「Sometimes known as “alert spam,” as they are rarely read or acted on.」(めったに読まれず対処もされないため、「アラートスパム」と呼ばれることもある)となっています。9 この章のページに関するルールは3行に収まります。「Every page should be actionable.」(すべてのページは対処可能であるべき)「I can only react with a sense of urgency a few times a day before I become fatigued.」(疲弊するまでに、緊急性をもって反応できるのは1日に数回だけだ)「If a page merely merits a robotic response, it shouldn’t be a page.」(ページが機械的な反応にしか値しないなら、それはページであるべきではない)8 ブロックごとのメールに対する私の機械的な反応は、削除することでした。この章はノイズのコストにも名前を付けています。「When pages occur too frequently, employees second-guess, skim, or even ignore incoming alerts, sometimes even ignoring a “real” page that’s masked by the noise.」(ページが頻繁すぎると、従業員は届いたアラートを疑い、流し読みし、無視さえするようになり、ノイズに埋もれた「本物の」ページを無視することすらある)27 さらに、「spent significant amounts of time triaging the alerts to find the few that were really actionable,」(本当に対処が必要な少数を見つけるためにアラートのトリアージにかなりの時間を費やした)チームを描いていますが、これは私の11月1日の午後をかなり正確に言い表しています。28
原因より症状を、そしてページのためのテスト。 Ewaschukの以前のエッセイは、本人によればその章の土台となったもので、テストを1文に凝縮しています。「Pages should be urgent, important, actionable, and real.」(ページは緊急で、重要で、対処可能で、本物であるべきだ)29 原因については、「Cause-based alerts are bad (but sometimes necessary)」(原因に基づくアラートは悪い(ただし時には必要))と題した節の下で、「Include cause-based information in symptom-based pages or on dashboards, but avoid alerting directly on causes,」(原因に基づく情報は症状に基づくページやダッシュボードに含め、原因に直接アラートを出すのは避けよ)と述べています。29 私はファイアウォールのブロックを原因レベルの事実と読みます。スキャナーがルールに当たった、ということです。私が気にかける症状は、機密性のあるパスが配信されることやサイトが落ちることで、私の読みでは、74通のどれもそのどちらも報告していませんでした。その日のプローブパスへのリクエストには、機密性のあるパスへの2xxは1件もありませんでした。3 このエッセイはダイジェストも先取りしています。「A daily (or more frequent) report can work too,」(1日1回(あるいはもっと頻繁な)レポートも機能しうる)と述べつつ、「without a system of accountability this amounts to less-spammy email alerts」(説明責任の仕組みがなければ、これは少しスパムが減っただけのメールアラートにすぎない)と警告しています。30 彼の処方は人です。「make sure the oncall person (or someone else) is designated to triage these every day」(オンコール担当者(または他の誰か)が毎日これをトリアージするよう指名されていることを確かめよ)30 一人で運用するモニターでは、その人は私しかいません。4節の顛末フィールドは私自身の補助的な仕組みであって、彼のものではありません。それは毎日のトリアージに確認すべきもの、つまり各クリティカルがどうなったかを与えますが、トリアージそのものを行うわけではありません。
適合率と再現率。 The Site Reliability Workbook(SRE本の実践編)のアラートの章は、何がまずかったのかを語る語彙を与えてくれます。適合率(precision)は「The proportion of events detected that were significant.」(検出されたイベントのうち重要だったものの割合)、再現率(recall)は「The proportion of significant events detected.」(重要なイベントのうち検出されたものの割合)です。31 私はモニターの再現率を測っていません。それには見逃した重要なイベントの数が必要で、5節ではそのうちの1件を説明します。メールのストリームとしての適合率はほぼゼロでした。74通のメールがあり、私の読みでは、私に何かをするよう求めるメッセージは1通もありませんでした。同じ章はリセット時間にも名前を付けています。「How long alerts fire after an issue is resolved. Long reset times can lead to confusion or to issues being ignored.」(問題が解決した後もアラートがどれだけ発火し続けるか。リセット時間が長いと、混乱や問題の無視につながりうる)31 リセット時間は発火し続けるアラートについて定義されたものです。ブロックごとのメールは1回発火した後、解決の更新を何も運びません。スキャナーが去ったとは決して言わないのです。
同じ失敗の病院版。 SREの章自体がソフトウェアの外、心臓モニターのアラーム管理を「for an example of alert fatigue in another context.」(別の文脈におけるアラート疲れの例として)指し示しています。28 2013年4月8日に発行されたThe Joint CommissionのSentinel Event Alert(重大事象警告)は、医療機器のアラーム安全性について、そこに数字を与えています。「The number of alarm signals per patient per day can reach several hundred」(患者1人あたり1日のアラーム信号の数は数百に達することがある)そして「It is estimated that between 85 and 99 percent of alarm signals do not require clinical intervention」(アラーム信号の85〜99%は臨床的介入を必要としないと推定されている)。10 この警告には見習う価値のある慎重さがあります。85〜99%が対象とするのは介入を必要としないアラームであって、誤報だけではなく、警告はその2つを分けていません。警告が記録している帰結は、私が半ば陥りかけていたものです。臨床医は「become desensitized or immune to the sounds,」(音に鈍感になる、あるいは免疫ができる)ようになり、「may turn down the volume of the alarm, turn it off, or adjust the alarm settings outside the limits that are safe and appropriate for the patient」(アラームの音量を下げたり、切ったり、患者にとって安全かつ適切な範囲を超えてアラーム設定を調整したりすることがある)。10 警告は2009年1月から2012年6月までのアラーム関連の事象98件を数え、そのうち80件が「resulted in death,」(死亡に至った)としています。そして、そのデータベースに報告された要因とは別に、アラーム疲れを「the most common contributing factor.」(最も一般的な寄与要因)と名指ししています。10 私の場合の利害ははるかに小さなものです。仕組みは同じです。アラームは自分を必要としないと学んだ人は、次の本物のアラームについてもそう学んでしまいます。
NIST、当時と現在。 2012年版のNISTのインシデント対応ガイドSP 800-61r2は、「it is not uncommon for an organization to receive thousands or even millions of intrusion detection sensor alerts per day.」(組織が1日に数千、あるいは数百万もの侵入検知センサーのアラートを受け取ることは珍しくない)と警告していました。32 2025年4月の改訂版SP 800-61r3は「supersedes SP 800-61r2,」(SP 800-61r2に取って代わる)ものですが、この文を削除しています。最も近いのは次の推奨です。「The volume of potentially adverse events to be analyzed is generally quite high, so organizations should rely on technical solutions that filter large event datasets down to a subset that is suitable for human viewing and analysis.」(分析すべき潜在的な有害事象の量は一般にきわめて多いため、組織は大量のイベントデータセットを人間の閲覧と分析に適した部分集合に絞り込む技術的な解決策に頼るべきである)33 私はこのフィルターを指示として受け取り、ダイジェストをその1つと考えています。
ベンダー調査は1件、ベンダー調査として明示する。 Vectra AIの2023年の調査は、Sapio Researchが2,000人のセキュリティアナリストを対象に実施したもので、「SOC teams receive an average of 4,484 alerts per day, and over two-thirds (67%) of them are ignored.」(SOCチームは1日平均4,484件のアラートを受け取り、その3分の2以上(67%)が無視されている)と報告しています。34 これはベンダーが委託した意識調査で、67%は回答者がそう答えた数字であって、測定値ではありません。私がこれを引用するのは1点のためだけです。この失敗は規模が小さくなっても起こる、という点です。アナリストは1日4,484件のアラートの3分の2を無視していると答え、チームのいない一人の読み手は74通で読むのをやめました。
4. ルールとしての再設計
変更は11月1日の13:50、私のメッセージから18分後に入り、14:00の2つ目の変更でその条件の1つが厳しくなりました。18 私はそれをルールとして書き、それぞれになぜ存在するのかの理由を添えました。
ルール1:ダイジェストは1日1通、そしてそれがハートビートである。 現地時間07:00以降の最初のモニター実行が、前回のダイジェスト以降の期間をまとめた1通のメールを送ります。1835 ダイジェスト自身の説明が、このメールが何に置き換わるかを述べています。「One email a day … in place of an email per auto-block and per WAF-handled CRITICAL.」(1日1通のメール……自動ブロックごと、WAFが処理したCRITICALごとのメールの代わりに)35 ダイジェストは実行の健全性(記録された実行数、開始して完了した実行数、失敗、送信されたクリティカルメールと抑制されたクリティカルメール)から始まり、続いてゾーン、理由、ネットワーク事業者付きの自動ブロック、すべてのクリティカルとその顛末、重大度とカテゴリ別の検出結果、プローブされたパス、ローカルスキャナーの未解決の検出結果が並びます。12 ダイジェストを作る理由は受信箱です。それを毎日送る理由は同じ説明の中にあります。「The digest is also the heartbeat: it goes out on a quiet day too」(ダイジェストはハートビートでもある。静かな日にも送られる)35 何かが起きたときだけ話すアラートのストリームには、穏やかな日と死んだモニターの違いを私に伝えることができません。必ず届くダイジェストにはそれができます。沈黙は穏やかさではなく故障を意味するのです。このプログラム自身のメモが、私がそれを気にかける理由を記録しています。2026年の初め、このモニターは何か月も止まったままで、何もそれに気づきませんでした。35
ルール2:ブロックはメールではなくチャットへ。 設計メモはこれを4語で言い表しています。「Per block: Slack only.」(ブロックごと:Slackのみ)3 ブロックとは、エッジが私に代わって行動したことです。SRE本の用語でいえばロギングにあたります。記録され、後で役に立ち、人間が対処する必要は何もありません。7 チャットは見ていたい瞬間のためにライブのストリームを保ち、ダイジェストは記録を保ちます。
ルール3:エッジがすでに処理したクリティカルは畳み込む。 クリティカルはまずブロックを試みます。その後で、モニターはそれがメールに値するかどうかを判断します。3 ダイジェストに畳み込む条件は2つあり、この順に確認されます。1つ目は、検出結果自身のアドレスと、そこに含まれる自動ブロックの対象となるすべてのアドレスが、すでに有効なブロックリストに載っていて、エッジが今まさにそれらのアドレスを止めていることです。314 この確認は他のアドレスを見ず、サンプルを調べる前に実行されます。そのため、これによって畳み込まれたフラッドには、ブロックの基準に満たないアドレスからの、ブロックもチャレンジも記録されていないイベントがまだ含まれている可能性があります。この分岐が言っているのはレスポンダーの標的がブロックされているということであって、すべてのイベントが対処されたということではありません。2つ目はWAFフラッド、つまり1つのゾーンでのファイアウォールイベントの急増に適用されます。ボットかどうかにかかわらずサンプル中のすべてのイベントにブロックかチャレンジが記録されていて、かつサンプルが完全な場合にだけ畳み込みます。「A solved or bypassed challenge, log, allow and skip all count as unmitigated.」(解決または回避されたチャレンジ、log、allow、skipはすべて未対処として数える)3 この4つが畳み込みに不利に数えられる理由は、Cloudflareの定義にあります。チャレンジの後は「If successful, Cloudflare accepts the matched request」(成功すれば、Cloudflareは一致したリクエストを受け入れる)とされ、logアクションは「Records matching requests in the Cloudflare Logs.」(一致したリクエストをCloudflare Logsに記録する)だけです。36 持続的スキャナーの検出結果は、エッジがブロックまたはチャレンジしたイベントだけを数えるので、その理由からWAFによる畳み込みのルールで畳み込まれます。11月2日のもののようにアドレスがすでにリストに載っている場合は、ブロックリストによる畳み込みのルールで畳み込まれます。3 それ以外はすべて即座にメールで送られます。
ルール4:顛末は検出結果に書き込む。 ポリシーでは、クラウド側からのクリティカルはすべて、記録された顛末を1つ持ちます。アドレスがブロックリストに載っているため畳み込み、エッジがサンプル中のすべてのイベントをブロックまたはチャレンジしたため畳み込み、メール送信、抑制(サイトとカテゴリごとに2時間に1通という制限の内側)、メール失敗のいずれかです。337 記録はポリシーに届いていません。UTCで11月1日付のクリティカルのうち、118件には顛末がありません。117件はフィールドが存在する前に上げられたもので、1件のクラウド側クリティカルは14:13 PSTと、その後に来たものです。その実行は、開始から約4分後に終わった7節の3回のうちの1回で、自動ブロックの最中、顛末が書かれる前に止まりました。ローカルスキャナーのクリティカルには顛末が付くことはなく、11月2日の3件にもありません。3738 11月3日以降、モニターは自動ブロックの実行前にクリティカルに「pending」(保留中)と書くので、途中で打ち切られた実行は空欄ではなく目に見える状態を残します。14 ダイジェストは、それを約束する見出し「Every CRITICAL and what became of it」(すべてのCRITICALとその顛末)の下で、クラウド側のすべてのクリティカルの横に顛末を表示します。12 顛末フィールドは私の仕組みであって、Ewaschukのものではありません。日次レポートについての彼の条件は、毎日それをトリアージするよう指名された人がいることで、ここではその人は私です。フィールドはそのトリアージに確認すべきものを与えます。30 各行に顛末があることで、ダイジェストは私が11月1日に投げかけた問い、日常的なものか本物か、にクリティカル1件ずつ答えてくれます。ただし、「emailed」や「folded」が言うのはクリティカルがどこへ行ったかであって、何かが解決したということではありません。
ルール5:1時間ごとの件数アラートは残す。 再びメモから。「Hourly volume alert (responder): still immediate, at most once an hour」(1時間ごとの件数アラート(レスポンダー):引き続き即時、最大で1時間に1回)3 1件のブロックは日常的なものです。1時間のうちにそれが急に積み上がることは、クラウド側が持っているもののうちで症状に最も近いもの、つまりインターネットが私に対してしていることの変化です。11月2日には1回発火しました。5
ルール6:ローカルスキャナーのクリティカルは引き続き即座にメールする。 設計メモは、それがまれなものであるはずだという理由で即時のままにしています。3 私はもう1つの理由で残しています。エッジが私のサイトとスキャナーの間に立つようには、私のMacとローカルの検出結果の間に立つものは何もありません。ブロックリストはアドレスを止められますが、Macの外にあるものは、Mac上のプロセスを止められません。このルールのコストは7節に現れます。
ルールが稼働した日、メールのストリームは13:32までの74通から、その日の残りの時間でログに記録された7通(クリティカル6通と1時間ごとのアラート1通)に減りました。これに私が手動で送ったダイジェストが加わります。52 その日の午後に書いた予測は「Under today’s traffic that would have been 0 immediate emails instead of 16.」(今日のトラフィックなら、即時メールは16通ではなく0通になっていたはずだ)でした。1 この予測は外れました。その理由は6節で説明します。
5. テストケース:11月2日、11:03から11:21
ルールの最初の本格的なテストは翌朝やって来ました。オランダのホスティング事業者に属する1つのアドレスが、私のサイトに対して脆弱性スキャナーを走らせたのです。12 以下はモニターが書いたもので、ログから現地の太平洋時間のまま逐語的に引用し、アドレスは「[the address]」に置き換え、間の行は省いています。4
[2026-11-02 11:03:53] [INFO] New finding [critical]: Request flood from [the address] on blakecrosley.com
[2026-11-02 11:04:02] [RESPOND] [INFO] Block notification: Slack posted, email folded into the daily digest
[2026-11-02 11:04:03] [INFO] Critical alert folded into the daily digest (IP on the block ledger): Request flood from [the address] on blakecrosley.com
[2026-11-02 11:04:04] [INFO] New finding [critical]: Scanner from [the address] on blakecrosley.com
[2026-11-02 11:04:05] [RESPOND] [INFO] Skip: [the address] already has active real block in blakecrosley.com (dedup)
[2026-11-02 11:04:05] [INFO] Critical alert folded into the daily digest (IP on the block ledger): Scanner from [the address] on blakecrosley.com
[2026-11-02 11:09:22] [INFO] New finding [critical]: 726 WAF blocks in 5 minutes
[2026-11-02 11:09:23] [INFO] Critical alert folded into the daily digest (IP on the block ledger): 726 WAF blocks in 5 minutes
[2026-11-02 11:09:44] [INFO] New finding [critical]: Persistent scanner: [the address] blocked 743 times today
[2026-11-02 11:09:47] [RESPOND] [INFO] Block notification: Slack posted, email folded into the daily digest
[2026-11-02 11:09:47] [INFO] Critical alert folded into the daily digest (IP on the block ledger): Persistent scanner: [the address] blocked 743 times today
1分ごとに見ていきます。
- 11:03:53。 リクエストフラッドの検出器が、そのアドレスに対してクリティカルを上げます。8秒後の11:04:01にレスポンダーがアドレスをブロックリストに追加し、11:04:02にブロック通知がチャットに送られ、そのメールはダイジェストに畳み込まれます。4
- 11:04:03。 クリティカル自体が畳み込まれます。アドレスがすでにブロック台帳(block ledger)に載っているので、メールが私に頼むはずの仕事を、エッジがすでにこなしているからです。4
- 11:04:04。 2つ目の検出器であるスキャナーチェックが、同じアドレスについて独自のクリティカルを上げます。レスポンダーのブロック要求は重複としてスキップされ、クリティカルは1秒後に畳み込まれます。4
- 11:09:22。 WAFフラッドの検出器が、そのゾーンについて3つ目のクリティカルを上げます。違反元は台帳に載っており、畳み込まれます。411 これを決めたのはブロックリストによる畳み込みだけです。サンプル中の8件のイベントにはブロックもチャレンジも記録されておらず、サンプルは上限に達していたので、WAFによる畳み込みだけならメールが送られていたはずです。11
- 11:09:44。 持続的スキャナーのチェックは、1つのアドレスからエッジがブロックまたはチャレンジしたイベントを私の全ゾーンにわたって数えるもので、4つ目を上げます。記録先は私の別のサイトで、そのアドレスからその日にブロックまたはチャレンジされたイベントは743件でした。12 レスポンダーはアドレスをリストにもう一度書き込み(欠陥です。後述します)、チャットに投稿し、11:09:47にクリティカルを畳み込みます。411
- 11:14:58と11:20:40。 同じゾーンについてさらに2件のWAFフラッドのクリティカル。どちらも同じように畳み込まれます。11
5分51秒で4件のクリティカル、11:20までに6件。すべて、アドレスがブロックされたため畳み込まれたと検出結果に記録されています。11 ブロックされたアドレスは1つ。重複チェックが当時サイト単位で動いていたためリストのエントリは2回書き込まれ(11月3日に修正)、さらに4件のブロック要求が重複としてスキップされました。414 メールは0通。ログには11:03から11:21までの間に送信されたメールの記録がありません。その時間帯で畳み込まれもメール送信もされなかった唯一のクリティカルは11:03:13に抑制されたもので、別のアドレスからの、別のサイトでのフラッドでした。4
次のダイジェストは、これを自動ブロックの表の2行(ゾーン、理由、ネットワーク事業者付きの最初のブロックと、持続的スキャナーによる再追加)と、すべてのクリティカルの表の6行として運び、それぞれに「blocked」(ブロック済み)または「blocked earlier」(以前にブロック済み)の印が付いていました。12 私の読みでは、最初の検出から8秒後、スキャン開始から8分後にモニターがブロックしたスキャナーには、それが正しい重みです。コーヒーを飲みながら読める数行であって、ページではありません。4
このテストケースが示していないことが1つあり、11月3日に判明しました。同じスキャナーは私のサイトの問い合わせフォームにも投稿しており、私のアプリはそれらの投稿に200で応答していました。それ自体によるメールは多くても31通で、姉妹記事の主題になっています。そしてモニターのフォームフラッドのチェックは、ライブでは検出結果を何も上げませんでした。11:03:23までの5分間について完全なデータで再生すると、同じチェックが重大度high(メールでもブロックでもなく、ダイジェストの1行)で検出結果を上げます。根拠は39件の投稿で、うち23件は拒否されていました。39 ライブの実行は、問い合わせた瞬間に終わる期間をCloudflareに求めていました。実行開始から37秒後、最新のイベントがまだ出そろう前です。その期間にそのアドレスから1,914件のリクエストを数えましたが、完全なデータでの再生では2,143件です。439 この遅れはアドレスのすべてのリクエストについて測ったもので、チェックが数えるフォーム投稿について測ったものではありません。私の読みでは、同じ遅れがライブでそれらの投稿をチェックの基準未満にとどめました。さらに、各実行はちょうど5分さかのぼって調べる一方、実行の開始間隔は約5.6〜5.8分だったので、どの間隔にも一度も走査されない部分がありました。3917 修正はその日のうちに入りました。各期間は今では前回の期間が終わったところから始まり、実行の90秒前に終わります。ただし前回の記録がない、1分未満と新しすぎる、あるいはMacのスリープ後のように15分より古い場合は、単純な5分間のさかのぼりに戻ります。39 11月2日の期間を変更後のコードで再生すると同じ検出結果が得られるので、この変更は固定された期間での検出を乱していません。再生では期間の連結(タイリング)や遅れを試せません。それらはライブの実行でしか作用しないからです。11月3日以降のライブ実行がそのテストになります。39
6. まだメールが送られるもの、そしてその理由
11月2日は新しいルールの下での最初の丸1日で、送られたメールは1通ではなく19通でした。クリティカル14通、1時間ごとの件数アラート1通、ダイジェスト1通、ローカルスキャナーから3通です。5 ブロックごとのメールは1通も出ていません。代わりに108件のブロック通知がダイジェストに畳み込まれ、クリティカルは177件が畳み込まれ、さらに37件が2時間の制限で抑制されました。いずれも現地時間の日付で数えたものです。この記事の後半にある顛末の件数はUTCの日付によるもので、そのため数字が異なります。5
現地時間の日ごとのメール数、ストリーム別。10月31日は、ログ開始後の89分間のみを対象としています。5
13:50の変更から11月2日の終わりまでにメールが送られたクラウド側のクリティカルは計20件(11月1日の残りの時間に6件、11月2日に14件)で、すべてresumegeni.comかblakecrosley.comでのWAFフラッドであり、少なくとも1件のイベントにブロックもチャレンジも記録されていませんでした。13 WAFによる畳み込みは、それぞれを自身のルールどおり正しく見送りました。サンプルに未対処のイベントがあったので、モニターはエッジがそれを処理したとは言えなかったのです。3 それらのフラッドでは、自動ブロックの対象となるほど多くのイベントを持つアドレスがなく、ブロックリストによる畳み込みには確認すべきアドレスがありませんでした。13 ダイジェストもこのグループを同じように呼んでいます。「a CRITICAL that was neither blocked nor already handled by the WAF」(ブロックもされず、WAFによる処理も済んでいないCRITICAL)。12
それらのメールの件名は違う話をしていて、それは欠陥でした。フラッドの要約は「N WAF blocks in 5 minutes」(5分間にN件のWAFブロック)となっていましたが、Nはエッジがどんなアクションを取ったかにかかわらず、その期間のボット以外のファイアウォールイベントをすべて数えていました。13 検出結果から2つの例を、現地時間で示します。
| 日時(PT) | サイト | 件名の表記 | ブロック | チャレンジ | 未対処 |
|---|---|---|---|---|---|
| 11月1日 16:51 | blakecrosley.com | 「104 WAF blocks in 5 minutes」 | 0 | 0 | 117件中117件 |
| 11月1日 22:45 | resumegeni.com | 「108 WAF blocks in 5 minutes」 | 18 | 62 | 179件中99件 |
最初のメールは、エッジが何もブロックしていないのに104件のブロックを主張していました。13 私の読みでは、ブロックが記録されていないイベントについて「blocks」と言う件名はノイズより悪いものです。処理されていないかもしれないものをシステムが処理したと、唯一の読み手に告げるからです。これらの件数を出した当日、11月3日の最初の修正も、それ自体が誤っていました。Nにはボット以外の件数を残したまま、ブロック、チャレンジ、残りをすべてのイベントについて数えたので、16:51の急増は104 WAF events in 5 minutes: 0 blocked, 0 challenged, 117 throughと表示されていたはずです。1行に2つの母集団です。この記事のレビューがそれを見つけ、私は同じ日にもう一度直しました。14 フラッドの要約、そしてそれに伴うメールの件名は、今では1つの母集団、つまりサンプルされたすべてのファイアウォールイベントを数え、N WAF events in 5 minutes: B blocked, C challenged, U unmitigated (S from non-bot user agents)と表示します。JavaScriptチャレンジはチャレンジとして数え、自動ブロックの理由はN WAF events from this address in 5 minとなります。14 16:51の急増なら117 WAF events in 5 minutes: 0 blocked, 0 challenged, 117 unmitigated (104 from non-bot user agents)です。1314 WAFによる畳み込みはもともと未対処のイベントを基準にしていたので、件名と判定は今では同じものを数えています。この修正で変わるのは14通の件名が言う内容です。送られた数は変わらず、19通が11月2日の正直な数字として残ります。
11月1日に書いた予測が外れたのは、前提が誤っていたからです。予測は新しいルールなら「would have been 0 immediate emails instead of 16,」(即時メールは16通ではなく0通になっていたはずだ)と述べていましたが、それはその朝00:30以降の7件のクリティカルについて「Cloudflare had already blocked every one of those requests.」(Cloudflareはそれらのリクエストをすでにすべてブロックしていた)という思い込みに基づいていました。1 検出結果はそれらについても違うことを言っています。ログ上00:30以降にメールが送られた5件は、それぞれの要約にある76〜89件のイベントに対して、記録されたブロックは最大1件、チャレンジは最大9件でした。13 そして、その日の午後と夜にメールが送られた6件のクリティカルのそれぞれで、エッジがブロックまたはチャレンジしたのはイベントの一部だけでした(16:51の急増ではまったくゼロ)。したがって、ボット以外のすべてのイベントをブロックとチャレンジが覆う場合にだけ畳み込む13:50のルールでさえ、すべてをメールで送っていたはずです。131 13:50の変更から10分後、2つ目の変更でWAFによる畳み込みは、ボットのユーザーエージェントかどうかにかかわらずすべてのイベントを数え、完全なサンプルだけを信頼するようになりました。ルールは厳しくなりましたが、予測が外れた理由はそこではありません。183 予測は私が信じていたブロックを数え、ルールは実際にそこにあったイベントを数えたのです。
私にわからないのは、その14通、つまりメールが送られた11月2日のクリティカルが、メールに値したかどうかです。検出結果は、未対処、つまりブロックもチャレンジも記録されていないイベントがいくつあったかは記録していますが、それらがどんなアクションを伴っていたか、logルールなのか、skipなのか、allowなのか、クライアントが解いたチャレンジなのかは記録していません。13 また、未対処のイベントは私のサイトに到達したリクエストと同じではありません。Cloudflareは「A single HTTP request can generate one or more security events when it triggers security features,」(1つのHTTPリクエストは、セキュリティ機能を発動させると1つ以上のセキュリティイベントを生成しうる)と述べ、logとskipを、ブロックのようにはルール評価を終わらせないアクションとして挙げています。したがって私の読みでは、同じリクエストに別のルールがまだ作用しうるのです。2436 CloudflareのGraphQLチュートリアルはactionフィールドと"log"や"block"のようなサンプル値を示していますが、そのフィールドが取りうる値をすべて列挙してはいません。23 CloudflareのSecurity Eventsダッシュボードもサンプリングをしています。「For large volumes of traffic, Cloudflare uses sampling to return results faster.」(大量のトラフィックについては、Cloudflareは結果を速く返すためにサンプリングを使う)24 モニターが各未対処イベントの背後にあるアクションを記録し、イベントをリクエストに結び付けるまでは、それらのメールのどれがエッジの通したトラフィックを伝えていたのか、私には言えません。そしてその答えが、それらがメールに値するかどうかを決めます。
11月2日のローカルの3通は、もう1つの未解決事項です。それらは13:50にシェルがcurlを起動した「Browser -> shell chain」(ブラウザからシェルへの連鎖)を報告しており、検出結果の中で未解決のままです。40 それがその日の午後に私が動かしていたエージェントのツールだったのか、それとも別の何かだったのかは検証していません。なので、誤報としては数えていません。
7. 2つの誤ったシグナル
Spotlightだった暗号通貨マイナー
11月1日の10:03、ローカルスキャナーはAppleのSpotlightデーモンであるspotlightknowledgedに対し、CPU使用率74.9%でクリティカル「High CPU unsigned process - possible crypto miner」(高CPUの署名なしプロセス:暗号通貨マイナーの可能性)を上げ、2秒後に「Critical email sent」とログに書きました。15 バグは私のものでした。チェックは、コード署名の表示コマンドcodesign -dの出力に「valid on disk」という語句があるかを探していました。スキャナーのメモは今、その欠陥を1つの節で記録しています。その語句は「which only codesign -v prints, so every process read as unsigned」(codesign -vだけが出力するもので、そのためすべてのプロセスが署名なしと読まれた)ものだった、と。25 スキップリストが、Appleのフレームワークのデーモンが急増するまでその欠陥を隠しており、その日の私のログにもそう書いてあります。1 検出結果には今、その解決が記録されています。「false positive, Apple platform binary」(誤検知、Appleのプラットフォームバイナリ)41
コストはメール1通で、11月1日の唯一のローカルメールでした。5 それ以前の10月31日と11月1日のローカルのクリティカル16件は、Xcode、HomebrewのPython、私自身のアプリのビルド、フックの変更、パス上のバージョンマネージャーのシム、別のプロジェクトのエージェント向け指示に一致したAIワームのパターン、そして自分自身のクエリに一致したイベントタップのチェックにフラグを立てていました。それらは15回の送信試行を生み、そのすべてが失敗しました。5251915 メールサービスはCloudflareの背後にあり、CloudflareはPythonのデフォルトのユーザーエージェントに対して、キーが読まれる前にエラー1010を返していました。私はわざと不正なキーを使ってそれを再現しました。19 Cloudflareのこのエラーのページは、PagesとWorkersのホストについての注記の中で、そのクライアントを直接名指ししています。「a User-Agent header that Browser Integrity Check treats as a non-browser client (for example, the default Python urllib user agent).」(Browser Integrity Checkがブラウザ以外のクライアントとして扱うUser-Agentヘッダー(たとえば、Python urllibのデフォルトのユーザーエージェント))42 壊れた送信処理のおかげで、私自身のツールと私自身の変更についての15通のメールから救われたわけです。15 スキャナーのメモは、より大きな教訓を率直に書いています。「most of the CRITICALs it raised in its first live days were its own noise.」(稼働初期の数日に上げたCRITICALのほとんどは、それ自身のノイズだった)25 それでも私はローカルのクリティカルを即時のままにし、誤ったものはストリームを黙らせるのではなく、1つずつそのチェックで直しています。
RUNS SHORT 162/207
11月2日の朝、最初のスケジュールされたダイジェストは「Mon Nov 2: 71 blocks on 15 zones, 11 criticals emailed, RUNS SHORT 162/207」(11月2日(月):15ゾーンで71件のブロック、クリティカル11件をメール送信、実行回数不足 162/207)という件名を運んできました。16 ダイジェストのルールは単純な算数でした。期待される実行回数は期間の分数を5で割ったもので、件名は不足にフラグを立てます。35 期間は11月1日の13:48から11月2日の07:05まで、1,036.5分なので、5分の枠は207です。ログに記録された実行は162回でした。17
11月2日の私のログは、その差を1行で説明していました。「The RUNS SHORT line is the Mac asleep,」(RUNS SHORTの行はMacがスリープしていたせいだ)とし、モニターに不具合はないとしたのです。43 その行は、モニターが失敗しなかった(11月2日に未完了のまま残った実行はない)という点では正しく、原因については誤っていました。11月2日についても、その数字が表していた期間全体についてもです。実行間隔の分析は、欠けた45枠をおおよそ次のように分けます。約25が実行間隔によるもの、約16がスリープによるもの、早く終わった実行の後の長い間隔でさらに約1、そして自分を記録しなかった3回の実行です。17
| 原因 | 枠数(概算) | 根拠 |
|---|---|---|
| 実際の実行間隔 | 25 | 実行間の通常の間隔160個、中央値5.60分、5.35分未満はなし。合計926.0分で、5分の枠185個分 |
| スリープ | 16 | 10分を超える間隔3つ、計93.0分。電源ログのアイドルスリープ期間の中にあり、短いメンテナンスのための起動中に実行が再開している |
| 早期停止後の長い間隔 | 1 | 10分を超える4つ目の間隔。早く終わった14:19の実行の後の10.0分 |
| 自分を記録しなかった実行 | 3 | 記録された実行162回に対し、実行開始165回 |
| その3回の背後にあるもの | 3回の実行が開始から約4分後に、終了行を記録しないまま終わった。タイミングから見て240秒のウォッチドッグで、すべて11月1日。午後に2回、その夜遅くに1回 |
電源ログは、23:21:30にアイドルスリープ、00:30:05に完全な起動、そして06:01:20に再びアイドルスリープ、06:30:28に完全な起動を示しています。44 3回の実行は11月1日の14:09、14:19、23:10に始まり、それぞれ約4分後に終了行を記録しないまま終わりました。私の読みでは、これは240秒のウォッチドッグです。4回目の実行は開始から28秒後に終わり、目に見える原因はありません。1738 11月2日の暦日では、288の5分枠に対して242回の実行が始まり、不足は46で、未完了のまま残ったものはありませんでした。10分を超えた間隔は2つだけで計35.8分なので、その日も不足の大部分はスリープではなく実行間隔によるものでした。17
誤った想定は私のもので、ダイジェストの中にありました。5分に設定されたスケジューラーは、Macが起きている間でさえ約5.6〜5.8分ごとにしか実行を届けなかったので、5分の算数では健全な日も不足と判定されてしまいます。17 起きている間の実行間隔がなぜ遅いのかは、まだ突き止めていません。11月3日に算数を置き換えました。実行の健全性は今では、記録された実行数、実行間の分数の中央値、最長の間隔とその時刻を報告し、件名は20分を超える間隔にだけフラグを立てます。その朝のプレビューは「about one every 5.6 min」(約5.6分に1回)と表示し、件名は「RUN GAP 31 min at 05:56」(05:56に31分の実行間隔)で終わっていました。14 間隔は私が対処できる症状です。Macがスリープしたか、モニターが止まったかです。スケジューラーが一度も届けたことのない実行間隔に対する比率は、そのどちらでもありませんでした。
私が残したルール
- メールを変える前に、ストリーム別に、明示したルールで数える。 私の表とログの件数が74で一致したのは、何をメールとして数えるかを先に書き留めたからにほかなりません。12
- 「sent」とログに書くのは、メールサービスがイエスと言ったときだけにする。 74通のうち22通について、私が証明できるのは試みたことだけです。26
- エッジがすでに実施したブロックは、アラートではなくログの1行である。 SRE本の3つの出力はそれをそこに置きます。そしてブロックごとのメール55通をチャットに移しても、私が対処していたものは何も失われませんでした。75
- 何も起きなかった日にも日次ダイジェストを送る。 必ず届くダイジェストはハートビートであり、それが届かないことがアラートになります。35
- クリティカルを畳み込むのは、エッジが証明する条件のときだけにする。 私の場合、それは検出結果のブロック対象アドレスがすでにブロックリストに載っていること、そしてすべてのイベントにブロックかチャレンジが記録された完全なサンプルであることです。2つ目の条件こそが、11月2日にまだ14通がメールで送られた理由です。313
- クラウド側の各クリティカルに顛末を書く。 誰も説明責任を負わない日次レポートは、Ewaschukの言葉を借りれば「less-spammy email alerts」(少しスパムが減っただけのメールアラート)です。各行の顛末こそが、私の毎日のトリアージが確認するものです。3012
- 件名には、エッジが何をしたかを書かせる。 ブロックがゼロだった急増に付いた「104 WAF blocks」は、その週で私が書いた最悪の1行でした。13
- スケジュールに対する比率ではなく、間隔を報告する。 5分のタイマーは約5.6分ごとにしか実行を届けなかったので、162/207は障害のように見えて、その大部分は時計の問題でした。17
- 誤報は受信箱ではなく、そのチェックで直す。 コマンド出力を1つ読み違えただけで、AppleのSpotlightデーモンが暗号通貨マイナーになりました。修正はチェックに入れました。25
何が変わりうるか
- 未対処のイベントが解かれたチャレンジだと判明した場合、 それだけでは、まだメールが送られるWAFフラッドのクリティカルがノイズになるわけではありません。クライアントがチャレンジを通過すると「Cloudflare accepts the matched request」(Cloudflareは一致したリクエストを受け入れる)、つまりリクエストは先へ進みます。それはリクエストが無害だったことも、対応が何も要らないことも示しません。それらのクリティカルを畳み込むには、同じイベントに結び付いたリクエストの証拠で、その中に人を必要とするものが何もなかったと示す必要があり、チャレンジの完了だけではその証拠になりません。もしそれらが
logやskipのルールだと判明すれば、問題はそのルールが私の意図どおりに動いているかどうかで、それがわかるまでは各メールは読む価値があります。モニターはまだ、それがどれなのかを記録していません。1336 - 1日のクリティカルメールが再び数十通に近づいた場合、 サイトとカテゴリごとの2時間の制限が本来ルールのすべき仕事をしていることになり、ルールを見直す必要があります。3
- ダイジェストが届かなくなった場合、 モニターと私の受信箱の間の何かが止まっています。モニター、それが動くMac、送信処理、あるいは配信経路のいずれかです。受け付けられた送信は、まだ配信された送信ではないからです。これが、この設計が「見に行け」という合図として扱う唯一の沈黙です。3520
- ローカルスキャナーが、私自身のツールでは説明できないクリティカルを上げた場合、 即時のメールは正しい判断だったことになります。11月2日の未解決の3件のシェル連鎖の検出結果が、その未決のテストです。40
- 読み手を1人増やした場合、 ページとチケットが同じ人ではなくなり、SRE本のアラートとチケットの区別には、私の受信箱ではなくチケットキューが必要になるでしょう。7
要点
自分のためにモニターを運用しているなら
- 私は半日で74通に届く手前のどこかで読むのをやめました。74通は、私の受信箱が午後の早い時間に達した数です。1
- 静かな日にも届く日次ダイジェストは、タダで手に入るハートビートです。イベントのときだけ話すモニターは、自分が死んだことを伝えられません。35
- ログは、一度も出ていかなかったメールについて「sent」と言っているかもしれません。件数を信じる前にコードを確認してください。619
モニターを作るなら
- まず行動し、それから知らせるかどうかを決めます。ブロックし、ブロックリストかエッジがすでにカバーしていればアラートを畳み込みます。3
- 各クリティカルの顛末を検出結果に記録してダイジェストに表示し、日次レポートをトリアージしなければならないとEwaschukが言う人に確認すべきものを与えます。私のモニターでは、その人は私です。3012
- イベントには、エッジがそれについて記録したもの(ブロック、チャレンジ、未対処)で名前を付け、1行では1つの母集団を数え、エッジがしてくれたと期待したことで名前を付けてはいけません。1314
- 手元にあるスケジューラーを測ってください。私のものは、5分のタイマーで5.6分ごとに実行していました。17
受信箱を読むのがあなたなら
- すべてのアラートについて、それが「urgent, important, actionable, and real」(緊急で、重要で、対処可能で、本物)かを問いましょう。そうでないものはダイジェストかログに入れるべきです。29
- 私の初日の予測は外れました。即時のクリティカルはゼロと言っていましたが、翌日には14通が送られました。15
よくある質問
アラート疲れとは何ですか?
アラート疲れとは、自分に何も求めないアラームをあまりに多く受け取る側の人に起こることです。The Joint Commissionの言葉では、人は「desensitized or immune to the sounds,」(音に鈍感になる、あるいは免疫ができる)ようになり、アラームの音量を下げたり切ったりし始めます。10 GoogleのSRE本は運用の世界で同じことを描いており、人は「second-guess, skim, or even ignore incoming alerts, sometimes even ignoring a “real” page that’s masked by the noise.」(届いたアラートを疑い、流し読みし、無視さえするようになり、ノイズに埋もれた「本物の」ページを無視することすらある)ようになります。27 私自身のケースは1日で起きました。13:32までに74通、そしてその日の午後の私の読みでは、どれも私に行動を求めていませんでした。1
1日に何件のセキュリティアラートからが多すぎますか?
人にとって、SREの章の正直な答えは「数件」です。「I can only react with a sense of urgency a few times a day before I become fatigued.」(疲弊するまでに、緊急性をもって反応できるのは1日に数回だけだ)8 Vectraのベンダー調査は、チームが1日平均4,484件のアラートを受け取り、本人たちの申告によればその67%を無視していると報告しています。34 私の一人用モニターにとっての実務上の答えは、1日1通のダイジェストに、今すぐ人を必要とするアラートを加えたものです。11月2日にはそれでもまだ19通で、そのうちのWAFフラッドのクリティカル14通は、確定したコストではなく未解決の問いとして扱っています。513
セキュリティアラートは日次ダイジェストにすべきですか、リアルタイムにすべきですか?
両方です。人が何をしなければならないかで分けます。モニターがすでに処理済みと数えるもの(ブロックリストに載せたアドレスや、サンプルされたすべてのイベントがブロックまたはチャレンジされたフラッド)はダイジェストに入り、残りは2時間の制限の範囲内で即座に送られます。3 Ewaschukは日次レポートも「can work too,」(機能しうる)と認めていますが、条件が1つあります。説明責任がなければそれは「amounts to less-spammy email alerts,」(少しスパムが減っただけのメールアラートにすぎない)ので、誰かが「designated to triage these every day」(毎日これをトリアージするよう指名されている)ことを求めています。30 私のモニターではそれは私で、私のダイジェストはトリアージに確認すべきものを与えるため、クラウド側のすべてのクリティカルの顛末を表示します。12
ハートビートアラートとは何ですか?
ハートビートとは、何かが起きたかどうかにかかわらず予定どおりに届くメッセージで、それが届かないことが何かの故障を意味します。私の日次ダイジェストがハートビートです。「it goes out on a quiet day too,」(静かな日にも送られる)ので、動かなくなったモニターはメールが届かないという形で現れます。35 送信の失敗や配信の喪失も同じように現れるので、届かないダイジェストは、モニター、それが動くホスト、送信処理、配信経路を確認する合図になります。20 実行の健全性のセクションは実行間の最長の間隔も報告し、20分を超える間隔には件名でフラグを立てます。14
なぜCloudflareのWAFアラートでメールがあふれるのですか?
私の場合にあふれたのは、各ブロックと各クリティカルがそれぞれ1通のメッセージになり、インターネットが公開されているすべてのゾーンを1日中スキャンしているからでした。5 Cloudflare自身のAlerts、「Monitors that you define yourself, and Platform Notifications,」(自分で定義するMonitorsと、Platform Notifications)はメールで配信でき、ダッシュボードで設定します。私のもののように、そのAPIに対して自分で作ったモニターはそのどちらでもなく、自分で組み込んだイベントごとのメール送信をそのまま引き継ぎます。26 アラートが何を数えているかも確認してください。Cloudflareのアクションにはlogとskipが含まれ、これらはブロックのようにはルール評価を終わらせません。またクライアントが解いたチャレンジは、Cloudflareがリクエストを受け入れることで終わります。したがって「WAF events」と「WAF blocks」は別の数字です。36 私の件名は11月3日までこの2つを混同していました。1314
メールAPIから2xxが返れば、アラートは配信されたということですか?
いいえ。Resendのemail.sentイベントは「Occurs whenever the API request was successful. Resend will attempt to deliver the message to the recipient’s mail server,」(APIリクエストが成功するたびに発生する。Resendは受信者のメールサーバーへのメッセージ配信を試みる)もので、配信は別のイベントです。20 2xxが意味するのは、サービスがメッセージを受け付けたということです。ステータスコードをログに残し、配信は別の問題として扱ってください。6
このサイトの関連記事:スパムがレート制限付きの問い合わせフォームを破った理由は、同じ11月2日のスキャナーを問い合わせフォームの側から追っています。寝る前に実行することは毎晩の本番チェックで、私が見ていない間に動くもう1つのルーティンです。AIエージェントを無人で実行すると実際に何が壊れるのかは、無人のエージェントセッションの障害モードを、それぞれの検出シグナルとともに挙げています。フックはすべて傷跡であるは、私のエージェントのフックの1つ1つを、それを生んだ障害までたどります。誤報をそのチェックで直すのと同じ習慣です。Claude Code の auto モードはセキュリティ境界ではないは、エージェントの周りの壁のほうが分類器より重要だと論じています。そしてAIエージェントのオブザーバビリティは、エージェントがディスク、CPU、ネットワークに何をしているかを見ることの必要性を説いています。
出典
著者自身のデータの時刻は、UTCと明記したものを除き、すべて現地の太平洋時間です。11月1日は02:00にPDTからPSTに戻りました。公開ページは2026年11月3日、記載のUTC時刻に取得しました。
-
著者の運用ログ(Captain’s Log)、2026年11月1日:13:32 PTのメッセージ、深夜0時からのメール74通のストリーム別の表(ブロックごと55、クリティカル16、1時間ごとの件数2、ローカル1)、13:50の畳み込みルール(ボット以外のすべてのイベントをブロックとチャレンジが覆う場合)、クリティカルの内訳「9 before the fold went live at 00:30 PT; the 7 after」と、「Cloudflare had already blocked every one of those requests」という思い込み、「Yesterday had 10」、13:48 PTに手動で送った最初のダイジェスト、予測「Under today’s traffic that would have been 0 immediate emails instead of 16」、そしてスキップリストがコード署名のバグを隠していたという記録。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩
-
著者のデータ:11月1日13:32 PTで区切り、モニターのログからスクリプトで導いたメールの件数。74(ブロックごと55、クリティカル16、1時間ごとの件数2、ローカル1)で、そのうち22(ブロックごと10、クリティカル11、1時間ごと1)は無条件に「sent」とログに書く送信処理から出たもの。現地時間の1日全体では81。同じスクリプトの行一覧では、クリティカルの「sent」行が00:30より前に11、後に5あり、ブロック通知に畳み込まれた最初のクリティカルは00:54:43。 ↩↩↩↩↩↩↩↩↩
-
著者によるモニターの設計メモ、通知のセクション、2026年11月3日時点:「Every one described routine mass-scanning the edge had already stopped」、「Per block: Slack only」、2つの畳み込み条件とその順序、「A solved or bypassed challenge, log, allow and skip all count as unmitigated」、即時のまま残した1時間ごとの件数アラート、まれなものであるはずという理由で即時のまま残したローカルスキャナーのクリティカル。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩
-
著者のデータ:モニターのログ、2026年11月2日11:03〜11:21 PT。5節で引用した行(アドレスは置換)、11:04:01と11:09:46の7日間の有効期限付きのブロックリストへの書き込み、重複としてスキップされた4件のブロック要求、チャットへの投稿、そしてこの時間帯には11:03:13の別のサイトでの抑制されたフラッドを除きメールの行がないこと。最初のクリティカルを上げた実行は11:02:46に始まり、その検出器の期間は37秒後の11:03:23に終わり、そのブロック理由はその期間にそのアドレスからのリクエストを1,914件と数えていた。スキャンの最初のリクエストはブロックの8分前、10:56 PTにサイトに到達していた(著者の11月2日の運用ログと、そのアドレスについてのCloudflareの1分ごとのリクエスト数による)。 ↩↩↩↩↩↩↩↩↩↩↩↩↩
-
著者のデータ:2026年10月31日から11月2日までのモニターの6つのログ(クラウド側とローカルスキャナー)からスクリプトで導いたメールの件数。メールサービスへの受け渡しを記録した1行を1通とする。現地時間の日ごと:10月31日(ログは22:31開始)10通(ブロックごと4、クリティカル6、すべて無条件に「sent」とログに書く送信処理から。2時間の制限で抑制されたクリティカル3、失敗したローカル送信13)。11月1日、ログ記録81通(ブロックごと55、クリティカル22、1時間ごとの件数3、ローカル1。失敗したローカル送信2)に加え、手動で送ったダイジェスト1通。11月2日19通(クリティカル14、1時間ごとの件数1、ダイジェスト1、ローカル3)。11月2日にメールで送られなかったもの:ダイジェストに畳み込まれたブロック通知108件とクリティカル177件、抑制されたクリティカル37件。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩
-
著者のコード:2026年10月31日に稼働させた時点のモニターの送信処理。メール要求の応答を破棄し、その後無条件に「sent」とログに書いていた。そして11月1日01:04 PDT、時計が戻る前の変更。以後、クラウド側の送信処理はメールサービスのHTTPステータスをログに残し、2xxのときだけ「sent」と書く。ローカルスキャナーの送信処理は、リクエストがエラーを出さなかったときにだけ、素の「Critical email sent」行を書く。 ↩↩↩↩↩↩
-
Benjamin Treynor Sloss, “Introduction,” Site Reliability Engineering: How Google Runs Production Systems(Google、O’Reilly Media刊)第1章、14:19:33Z取得:有効な監視の出力の3種類(アラート、チケット、ロギング)の引用、およびメールを読んで判断するアラートを「fundamentally flawed」と呼ぶ一節。 ↩↩↩↩↩↩
-
Rob Ewaschuk, “Monitoring Distributed Systems,” Site Reliability Engineering(Google、O’Reilly Media)第6章、14:18:54Z取得:「Every page should be actionable」、緊急性についての1行、機械的な反応についての1行の引用。 ↩↩↩
-
Ewaschuk, “Monitoring Distributed Systems,” 14:18:54Z取得:アラートの定義と、メールのアラートについての脚注22(「alert spam」)の引用。 ↩↩
-
The Joint Commission, “Medical device alarm safety in hospitals,” Sentinel Event Alert Issue 50、2013年4月8日。Wayback Machineの2024年11月13日のキャプチャから読み、14:21:49Z取得(発行元自身のURLは403を返した):患者1人あたり1日のアラーム信号数。85〜99%という推定(警告はこれをAAMIに帰しており、誤報を分けずに臨床的介入を必要としないアラームを対象とする)。鈍感化と音量を下げることについての一節。2009年1月から2012年6月までのアラーム関連の事象98件、うち80件が死亡に至ったこと。そして「the most common contributing factor」は、Sentinel Eventデータベースに報告された要因とは別の、警告の要因リストからの引用で、データベース自体の報告要因リストとは別のもの。 ↩↩↩↩↩
-
著者のデータ:モニターの検出結果ファイルにある、11月2日のスキャナーについての6件のクリティカルな検出結果(11:03:53 リクエストフラッド、11:04:04 スキャナー、11:09:22 WAFフラッド、11:09:44 持続的スキャナー、11:14:58と11:20:40 WAFフラッド)。どれもアドレスがブロックリストに載っていたため畳み込まれたと記録されている。11:09:22のWAFフラッドには、ブロックもチャレンジも記録されていないサンプルイベント8件と、モニターのサンプル上限に等しいファイアウォールイベント数も記録されており、サンプルが上限に達していたことを示す。 ↩↩↩↩↩↩
-
著者のデータ:2026年11月3日にダイジェストプログラムのプレビューモードが描画した次のダイジェスト(期間は11月2日(月)07:05から11月3日(火)06:17 PSTまで。プレビューは何も送信しない)。そのセクション構成、ローカルスキャナーの10分ごとの段階、全ゾーンで7日間適用されるアカウント全体のブロックリスト、ネットワーク事業者付きの自動ブロックの表(11月2日のスキャナーについてはオランダのホスティング事業者)、「Criticals that emailed you」という見出しの文言、そして「Every CRITICAL and what became of it」の表。 ↩↩↩↩↩↩↩↩↩↩↩↩
-
著者のデータ:顛末フィールドが始まる11月1日13:50 PSTの変更から11月2日PSTの終わりまでに、メール送信と記録されたすべてのクリティカル、計20件(UTCで11月1日と2日付が15件、UTCで11月3日付が5件で、送信は16:42、17:58、20:34、21:07、23:08 PST)。検出結果ファイルから、それぞれを決めた詳細とともに。すべてresumegeni.comかblakecrosley.comでのWAFフラッドで、ブロックもチャレンジも記録されていないイベントを含む。11月1日の6件では、エッジがブロックまたはチャレンジしたボット以外のイベント(検出結果のacted数)がイベント数を下回る(83中5、153中95、104中0、128中67、135中54、108中80)。11月2日の2件はブロックがゼロ(05:55 PST、チャレンジ26。12:06 PST、チャレンジ204)。20件すべてについて、モニターのログには、ブロックに足るイベントを持つ単一のアドレスがない。6節の表の2行(2026-11-02T00:51:04Zと06:45:59Z)。ボット以外のすべてのファイアウォールイベントを「WAF block」と数える要約文。16:51の急増については、ボット以外のイベント104件、全体で117件、ブロックもチャレンジもなし。そして、11月1日の00:30から13:32 PTの間にメール送信されたとログが示す5件のクリティカルについての、検出結果のブロック数とチャレンジ数(79イベントに対し0と0、81に対し0と9、89に対し1と0、84に対し1と9、76に対し0と5)。検出結果は、それらのイベントがどんなアクションを伴っていたかを記録していない。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩
-
著者のコードとデータ、2026年11月3日:モニターのWAFフラッド要約テンプレート。その朝まず
N WAF events in 5 minutes: B blocked, C challenged, U through(Nはボット以外の件数)に書き換え、この記事のレビューの後、サンプルされたすべてのイベントについてのN WAF events in 5 minutes: B blocked, C challenged, U unmitigated (S from non-bot user agents)に書き換えた。JavaScriptチャレンジはチャレンジとして数える。自動ブロックの理由N WAF events from this address in 5 min。自動ブロックの実行前にクリティカルに書かれる「pending」の顛末(ダイジェストはこれを、アラート処理が終わる前に打ち切られた実行として表示する)。ブロックリストによる畳み込みのアドレス集合(検出結果自身のアドレスと、自動ブロックの対象となるアドレス)と、WAFによる畳み込みより前というその位置。それまでサイト単位で動いていたため11月2日のアドレスをリストに2回書き込んだ自動ブロックの重複チェックを、その日アドレス単位にしたこと(そのバージョンのモニターの設計メモと11月3日の運用ログ)。ダイジェストの実行の健全性のルール(記録された実行数、実行間の分数の中央値、最長の間隔とその時刻、20分を超える間隔についてだけの件名フラグ)。そしてその朝のプレビュー。「about one every 5.6 min」と「RUN GAP 31 min at 05:56」と表示していた。 ↩↩↩↩↩↩↩↩↩↩↩ -
著者のデータ:ローカルスキャナーのログ、2026年11月1日:Appleの
spotlightknowledgedに対するCPU使用率74.9%での10:03:04のクリティカルな検出結果と、10:03:06の「Critical email sent」の行。その日のそれ以前のクリティカル2件(00:48:55、パスのシム)で、それぞれの後に送信の失敗。そして10月31日のログのクリティカル14件。その中には22:52:57のAIワームのパターンと、22:41の「Claude hook modified」の検出結果5件があり、そのうち4件の後に送信の失敗(フックは10月24日に変更されていたと、10月31日の運用ログが記録している)。 ↩↩↩↩ -
著者のデータ:11月2日のダイジェスト後のダイジェストプログラムの状態記録。件名「Mon Nov 2: 71 blocks on 15 zones, 11 criticals emailed, RUNS SHORT 162/207,」、期間2026-11-01T21:48:49Zから2026-11-02T15:05:17Z、実行162回。モニターのログは07:05:19 PSTに送信を記録している。 ↩↩
-
著者のデータ:2026年11月1日と2日のモニターのログに対するスクリプトでの実行間隔分析。11月2日のダイジェストの期間(1,036.5分、5分の枠207)について:実行開始165回、そのうち4回は次の開始までに「run complete」なし。通常の間隔160個、中央値5.60分、平均5.79、最小5.35、合計926.0分(185枠)。10分を超える間隔4つ、計103.0分。11月2日の暦日(深夜0時から深夜0時、1,440分、5分の枠288)について:開始242回、枠より46少なく、未完了なし。通常の間隔239個、中央値5.62分、合計1,374.7分(約275枠)。10分を超える間隔2つ、計35.8分。内訳はこれらの数字からの概算の算数:実行間隔によるもの約25.2枠(通常の間隔160個は5分の枠185.2個分にわたり、実行160回を含む)、3つのスリープの間隔に約15.6枠(93.0分、18.6枠、実行3回)、14:19の実行の後の10.0分の間隔に約1.0枠、記録されなかった実行3回で、計約45。 ↩↩↩↩↩↩↩↩↩
-
著者のデータ:リポジトリから読んだモニターの構成履歴。10月31日22:44 PDTの稼働(クリティカルごと、セッション終了ごとにメール)。11月1日00:46 PDT(クリティカルをブロックのメールに畳み込む)。11月1日13:50 PST(07:00にダイジェストを有効化、ブロックごとのメールを無効化、エッジが処理したクリティカルを畳み込む)。11月1日14:00 PST(構成の変更はなし。WAFによる畳み込みのコードを、すべてのイベントを数え、完全なサンプルを要求するよう変更)。 ↩↩↩↩↩↩↩
-
著者の運用ログ(Captain’s Log)、2026年10月31日:ローカルスキャナーの送信が、Pythonのデフォルトのユーザーエージェントに対するCloudflareのエラー1010で失敗していたこと(不正なキーで再現)。その夜のクリティカル14件に対する送信失敗13件という件数。クラウド側のメールは「most likely were」配信されたという判断。 ↩↩↩↩
-
Resend, “Event Types,” Webhookのドキュメント、14:23:37Z取得:
email.sentの定義の引用と、別のイベントとしてのemail.delivered。 ↩↩↩↩ -
Resend, “Send Email,” APIリファレンス、14:18:59Z取得:レスポンスボディは
id。 ↩ -
著者のデータ:2026年11月1日の現地時間ごとの数字。同じスクリプトから、01:00台はPDTとPSTに分けている。1時間ごとのメール数(深夜0時台に22通、すべて未検証)、1時間ごとの畳み込みまたは抑制されたアラート数、13:25:57のブロックごとのメールの最後の1通、14:20:35の畳み込まれたブロックごとの通知の最初の1件。 ↩↩↩↩
-
Cloudflare, “Querying Firewall Events with GraphQL,” Analyticsのドキュメント、14:19:01Z取得:
actionを含むクエリのフィールドと、"log"と"block"を含むサンプル出力。このページはactionの値をすべて列挙してはいない。 ↩↩ -
Cloudflare, “Security Events,” WAFのドキュメント、14:23:10Z取得:セキュリティイベントの定義、1つのリクエストが複数のイベントを生成しうるという文、サンプリングについての文の引用。 ↩↩↩
-
著者によるローカルスキャナーの設計メモ、「Check fixes and false positives」:「most of the CRITICALs it raised in its first live days were its own noise」、誤検知の表(Homebrew Python、Xcode、著者のアプリのビルド、イベントタップの自己一致、バージョンマネージャーのシム、別のプロジェクトのエージェント向け指示に対するAIワームのパターン)、そしてコード署名の項目の引用。スキャナーは自身のクリティカルを自分でメールする。 ↩↩↩↩↩
-
Cloudflare, “Cloudflare Alerts,” Notificationsのドキュメント、14:19:00Z取得:アラートの2つのカテゴリの引用。スケジュール実行されるSQL APIクエリとしてのMonitorsと、あらかじめ構成された製品アラートとしてのPlatform Notificationsで、どちらもダッシュボードから作成し、すべてのプランでメール配信が可能。 ↩↩
-
Ewaschuk, “Monitoring Distributed Systems,” 14:18:54Z取得:頻繁すぎるページについての一節の引用。 ↩↩
-
Ewaschuk, “Monitoring Distributed Systems,” 14:18:54Z取得:アラートをトリアージするチームの事例研究と、心臓モニターのアラーム管理を「for an example of alert fatigue in another context」として指し示す脚注24の引用。 ↩↩
-
Rob Ewaschuk, “My Philosophy on Alerting,” Googleドキュメント、HTMLエクスポートから読み、14:18:55Z取得:その考えがSRE本の章の土台となっているという文書の注記、「Pages should be urgent, important, actionable, and real」、そして原因に基づくアラートについての一節と節の題の引用。 ↩↩↩
-
Ewaschuk, “My Philosophy on Alerting,” 14:18:55Z取得:日次レポートについての一節、その説明責任についての但し書き、そしてレポートを毎日トリアージするよう指名された人を求める部分の引用。 ↩↩↩↩↩↩
-
Steven Thurgood, with Jess Frame, Anthony Lenton, Carmela Quinito, Anton Tolchanov, and Nejc Trdin, “Alerting on SLOs,” The Site Reliability Workbook(Google、O’Reilly Media)第5章、14:18:55Z取得:適合率、再現率、リセット時間の定義の引用。 ↩↩
-
NIST, SP 800-61 Revision 2, Computer Security Incident Handling Guide(2012年、廃止済み)、14:18:58Z取得:「thousands or even millions」の文の引用。 ↩
-
NIST, SP 800-61 Revision 3(2025年4月)、14:18:57Z取得:r2に取って代わるという記述と、Adverse Event Analysisの下の推奨R1の引用。 ↩
-
Vectra AI, “2023 State of Threat Detection”(ベンダー調査。2023年3月から4月、Vectraの委託、実地調査はSapio Research、10の市場の従業員1,000人超の組織に属するセキュリティアナリスト2,000人)、14:22:49Z取得:回答者の報告による、1日4,484件のアラートと無視される67%。 ↩↩
-
著者のコード:ダイジェストプログラムの説明(「One email a day … in place of an email per auto-block and per WAF-handled CRITICAL」、「The digest is also the heartbeat: it goes out on a quiet day too」、2026年初めにモニターが何か月も止まっていた期間)と、11月2日時点での、期間の分数を5で割るという期待実行回数のルール。 ↩↩↩↩↩↩↩↩↩
-
Cloudflare, “Actions reference,” Ruleset Engineのドキュメント、14:19:01Z取得:
block、チャレンジ、skip、logの各アクション、チャレンジとlogの定義の引用、そして非終端として挙げられたskipとlog。 ↩↩↩↩ -
著者のデータ:モニターの検出結果ファイルから、UTCの日付ごとに、記録された顛末とカテゴリ別のクリティカルな検出結果。11月1日:129件、そのうち118件は顛末なし。117件は顛末が記録される前に上げられたもの(その中には、顛末を持つことのないローカルスキャナーのプロセス、フック、サプライチェーンのカテゴリが含まれる)、そして1件は変更後の14:13 PSTのクラウド側スキャナーのクリティカルで、その実行の最後のログ行は、それが引き起こした自動ブロック(モニターの11月1日のログ)。11月2日:236件(アドレスがブロックされていたため畳み込み160、WAFが処理したため畳み込み1、抑制58、メール送信14、顛末のないローカル3)。 ↩↩
-
著者のデータ:モニターのログ、2026年11月1日:3回の実行(開始14:09:49、14:19:46、23:10:31)で、最後の行が開始の約4分後にあり、ウォッチドッグ、タイムアウト、強制終了の行は記録されていない。著者はこれをモニターの240秒のウォッチドッグと読んでいる(コードは240秒で実行を強制終了する)。そして14:36:06に始まり、「run complete」なしに14:36:34で終わる実行。 ↩↩
-
著者による再生、2026年11月3日:11月2日18:58:23から19:03:23 UTC(10:58:23から11:03:23 PST)の完全なCloudflareのデータに対する、モニター自身のフォームフラッドのチェック。ライブ実行が見逃した検出結果を重大度high(モニターはこれをメールやブロックリストではなくダイジェストに送る)で上げ、根拠は39件の投稿でうち23件が拒否、ライブ実行が1,914件と数えたそのアドレスからのリクエストを2,143件と数える。その日モニターのコードから読み取った2つの原因(各実行の期間は検出器が問い合わせた瞬間に終わり、Cloudflareの最新のデータが出そろう前だったこと、そして5分より間隔の空いた実行での5分間のさかのぼりが、どの間隔にも走査されない部分を残したこと)と、その日に行った修正(ライブの期間は前回の期間の終わりの記録から連結し、90秒早く終わる。記録がない、60秒未満、または15分を超える場合は5分間のさかのぼりに戻る。再生は記録を読まない)。変更後のコードで同じ期間を再生すると同一の検出結果が得られ、これは変更が固定された期間での検出に手を付けていないことを示し、期間の連結や遅れは試していない。問い合わせフォームへのスキャナーの投稿は、著者の11月2日の運用ログの記録による。11月3日のコードでの再生は、この記事の他の証拠とともに保存されている。その正確なコマンド、読んだ期間、そして実行の期間とフォームの18:58から19:05 UTCの分についての検出器の完全な出力で、実行は11月3日15:55:04 UTC。11月3日のそれより早い時刻に、修正前のコードで行った最初の再生は、同じ件数とともに私のプログラムのメモに記録されているが、その生の出力は保存されていない。 ↩↩↩↩↩
-
著者のデータ:ローカルスキャナーの2026年11月2日のログと、11月3日のダイジェストのプレビュー:13:50 PSTの3件のクリティカルな「Browser -> shell chain」の検出結果。シェルが
curlを起動したもので、検出結果ファイルの中で未解決。 ↩↩ -
著者のデータ:検出結果ファイルにある、11月1日の
spotlightknowledgedの検出結果に記録された解決の引用。 ↩ -
Cloudflare, “Error 1010,” サポートドキュメント、14:19:00Z取得:エラーの定義とPython urllibの例の引用。このページはその例を、
*.pages.devと*.workers.devのホスト名およびPagesのカスタムドメインへのリクエストについて挙げている。 ↩ -
著者の運用ログ(Captain’s Log)、2026年11月2日:RUNS SHORTの行の引用。 ↩
-
著者のデータ:Macの電源ログ(11月1日13:40 PSTからのSleepとWakeの行):アイドルスリープ23:21:30と完全な起動00:30:05、アイドルスリープ06:01:20と完全な起動06:30:28。 ↩