aikido-community.jp に無料の runtime firewall「Aikido Zen」を本番投入してちょうど1週間。攻撃ボットが日常的に来ている事実、自分のアプリが外に叩いているhostname全量、runtimeで実際にロードされたパッケージ一覧 — Zenのダッシュボードで見えた実データを公開する途中経過レポート。
aikido-community.jp に無料の runtime firewall「Aikido Zen」を入れて1週間。見えたことで一番大きかったのは、次の3つ。
攻撃者がすでに来ていた
ボットが米国・ウクライナ・スイス・アイルランドから、.env や .aws/credentials を片っ端から舐めに来ている。本番の Web サーバーは、立てた瞬間からこういう試行に晒されている。
自分のアプリが外に何を叩いているかが全部見えた
api.anthropic.com、api.x.com、fonts.googleapis.com など、自分のサイトから出ている通信先がすべてリストで見える。
ここに知らない hostname が一つでも増えた瞬間 — それは npm パッケージが侵害されて、攻撃者のサーバーに情報が送られ始めたサインかもしれない。最近の Shai-Hulud や durabletask のような supply chain 攻撃に対する、最後の防衛ラインがここで張れる。
実際に動いているパッケージの一覧も取れる
package.json に書いてある依存ではなく、runtime で実際にロードされたパッケージだけのリスト。「うちの本番、その侵害パッケージ動かしてる?」に正確に答えられる。
以下、実データと運用メモ。
aikido-community.jp の Zen ダッシュボードから直近1週間:

Zen は 1.8.27 系で稼働。全 route を Detection Only モード (検知のみ・遮断しない) に置き、本番影響ゼロで観測している段階だ。
ここから、3つの方向 (inbound / outbound / package) で見えたものを順に紹介する。
Firewall タブを開くと、ここ数日で複数の Attack Wave が検知されている。Wave とは、同一 IP からの一連の不審リクエストを Zen が自動でグルーピングしたもの。
GET /.env
GET /.env.local
GET /.env.production
GET /app/.env
GET /api/.env
GET /backend/.env
GET /.aws/credentials
GET /storage/.env
GET /.env.example
GET /.git/FETCH_HEAD
GET /.git/config
GET /.git/HEAD
GET /.git/refs/heads/main
GET /.git/logs/HEAD
GET /.git/refs/heads/master

User-Agent は Mozilla/5.0 (X11; Linux x86_64; rv:150.0) Gecko/20100101 Firefox/150.0。
これは特定の標的を狙ったものではなく、インターネット全体を機械的にスキャンする自動ボットの典型的な手口だ。Laravel や Node.js でよくある秘密情報の置き場所 (.env, .aws/credentials, .git/config) を片っ端から舐めていく。
直近2週間で同じ系統のパターンを検知した IP:
.env.bak, .env.old, /laravel/.env まで含む 15 パス国は分散しているが、リクエスト内容のシグネチャはほぼ同じ。標的型ではなく、世界中の Web サーバーを無差別に掃いている自動スキャナの一群と読める。
aikido-community.jp は Next.js の standalone build + Docker 構成で、production の image には .env ファイルも .git/ ディレクトリもそもそも含まれていない (環境変数は docker compose 経由で runtime に注入し、.git/ は build context にも入れていない)。つまりこの攻撃はそもそも実害につながらない。ただし「実害が出ないから無視していい」のではなく、こうした試行が日常的に来ている事実を可視化できていることが Zen の価値の一つだ。
通常の nginx アクセスログを目で追っていればわかると言えばわかる話だが、Zen は同一 IP からの試行を Wave としてまとめ、攻撃の意図 (Path Traversal 系の偵察) で自動分類してくれる。ログの「ノイズ」を「シグナル」に変換してくれる、という言い方が近い。
検知された Wave のうち、アイルランド (Dublin) からの 54.76.211.68 / 3.248.4.169 / 52.50.198.227 には Initiated by Aikido DAST というラベルが付く。これは Aikido 自身の DAST スキャナ (AWS eu-west-1 リージョン) から定期的に走っているテストだ。
運用上は次の手順を踏む。
DAST ラベル付きと付かないものを切り分けるだけで、ダッシュボードの S/N 比はかなり改善する。
WAF と聞くと多くの人は「外から来るリクエストを止めるもの」と認識している。だが Zen の Outbound タブは別の世界を見せてくる。自分のアプリケーションが外に向かって何を呼び出しているか、その全量を runtime で記録している。
| Hostname | Port | Requests | Status |
|---|---|---|---|
| runtime.aikido.dev | 443 | 12,700 | Allowed |
| guard.aikido.dev | 443 | 1,300 | Allowed |
| fonts.googleapis.com | 443 | 39 | Allowed |
| fonts.gstatic.com | 443 | 38 | Allowed |
| api.x.com | 443 | 11 | Allowed |
| www.aikido.dev | 443 | 9 | Allowed |
| api.anthropic.com | 443 | 3 | Allowed |
| cdn.jsdelivr.net | 443 | 3 | Allowed |

それぞれの意味は次のとおり。
runtime.aikido.dev, guard.aikido.dev, www.aikido.dev — Zen 自身がポリシー取得とテレメトリ送信に使うfonts.googleapis.com, fonts.gstatic.com — Web フォントapi.x.com — X (旧 Twitter) への記事自動投稿api.anthropic.com — Claude API 呼び出しcdn.jsdelivr.net — フロントエンド静的アセットこれだけ見ると「知ってる接続先しかない」普通の状態だ。が、ここに知らない hostname が一個でも増えた瞬間、それは異常を示す強いシグナルになる。
直近で記事化した durabletask の PyPI 改ざん (Shai-Hulud 系の "Here We Go Again" キャンペーン) や、過去の npm パッケージ侵害事例に共通するのは、
npm install または pip install するという流れだ。1 と 2 のフェーズは静的スキャンや SBOM だけでは原理的に検知が難しい (改ざん直後でシグネチャがまだ流通していない)。
ここで効くのが Outbound 監視だ。3 のフェーズで attacker-c2.example.com のような未知の hostname に対する接続が runtime で発生した瞬間、Zen はそれを記録する。Allow list 方式に切り替えていればその時点で遮断もできる。
つまり Zen の Outbound は、SBOM や静的解析がカバーできない時間帯 (改ざん発覚前のゼロデイ期間) に対する、もう一枚の網として機能する。
監査やコンプライアンスの場面でも、Outbound ログの意味は大きい。
「外部APIはこれを使う予定です」と申請書で示すよりも、「実際に使われているのはこれだけで、それ以外は出ていない」と runtime ログで示せるほうが、ずっと信頼できる。
前者は計画、後者は事実。重みが違う。
Packages タブには、Zen が runtime で実際にロードを観測した npm パッケージが並ぶ。
aikido-community.jp の場合、抜粋すると次のような構成になっている。
@aikidosec/firewall 1.8.27 — Zen 本体@next/env 15.5.12 — Next.js の環境変数ローダー@prisma/client 5.22.0 — Prisma の DB クライアント@npmcli/* — npm 内部ユーティリティchalk, abbrev など — 各種小規模ライブラリ
このリストの何がうれしいのか。package.json や package-lock.json を読めば依存はわかるはずだ、と思うかもしれない。
ところが、「lock ファイルに書かれている依存」と「runtime で実際に require / import されたコード」は同じではない。
つまり、static SBOM は「コード上の脅威空間の最大値」を示すが、runtime SBOM は「今この瞬間、実害につながり得るコードの集合」を示している。
durabletask 事件のような侵害が公表されたとき、最初に聞かれるのは「うちの本番、それ動かしてる?」だ。grep で package.json を見て該当があっても、Packages タブで該当パッケージが In Use になっていなければ、影響範囲をより精密に絞れる。
1週間の実運用で見えてきた暫定的な運用方針を整理しておく。これらは現時点での判断であり、今後さらに調整していく可能性がある。
導入直後にいきなり全 route を Block モードにすると、誤検知で本番影響が出るリスクが高い。aikido-community.jp は1週間経過した現時点でも全 route を Detection Only に置いている。
ステップは次の順で進める予定。
前述のとおり Aikido DAST 由来の Wave は False Positive フラグを立てる運用に統一する。ラベル機能があるので運用負荷は低い。
Outbound 側もいきなり遮断にすると、Web フォントや CDN が落ちて UI が崩れる。Detection Mode で一度全 hostname を洗い出し、想定外の hostname がないことを確認してから Allow list 化する手順を推奨する。
ダッシュボード上で「Setup Rate limiting」の警告が出ている。これは route ごとのレート制限ミドルウェアをまだ仕込んでいないためだ。次の宿題として、/api/* の書き込み系エンドポイントから順に設定していく予定。
.env 狩りボットが日常的に来ている事実が可視化された次回は2〜4週間運用したあとの傾向変化、または Detection Only から Block への切り替え判断の記録を書く予定。Rate Limiting middleware の導入も並行して進めていく。
aikido-community.jp ではこれまで、Aikido の守りを SDLC の時系列軸 で整理してきた。
これらはどれも、コードが本番に出るまで、あるいは本番に対する外部からのテストの話だった。本番で動いているアプリの内側で、実際のリクエストに対して何が起きているか という視点はまだ扱っていなかった。
今回の Zen はその視点を埋めるピース。SDLC の三層でも、外側から叩く DAST でもない、runtime 軸 の防御を担当する。本記事はその初回レポート。
Aikido Community Japan
公開日: 2026/5/24
最終更新: 2026/5/25
セキュリティの最新情報をお届けします。