概要 — 何をする画面か
ポート接続 は インフラ ▸ 接続性とトラフィック の主力画面、PORT OVERVIEW です。運用ポリシーで定義された 監視対象ポート(例: 80、443、22、3306 …)ごとに1枚のカードを描画し、カード内ではそのポートに紐づくTCPセッションを サーバー別 に状態ごとの100%積み上げバーへ分解します。目的は「いまこのポートに誰が、何本、どの状態で接続しているか」を1つのビューで把握することです。
データ元はレガシーのトラフィックDB(legacy_glory 接続)のテーブル traffic_session_ct で、check_ct.js コレクターが定期的に投入します。ここではアプリは 読み取り専用 です — この画面は何も書き込みません。
各サーバータイルの表示内容:
- TCP状態100%積み上げバー — ESTABLISHED / LISTEN / SYN SENT / SYN RECV / FIN WAIT / CLOSE WAIT / TIME WAIT の比率(それ以外はすべて
other)。ESTABLISHED は常に先頭に置き、残りはセッション数の降順に並べます。 - SRC サークル — そのサーバー・ポートに紐づく ユニークなソースIP(
remote_ip)の数です。クリックするとソースIP一覧のポップアップが開きます。 - 上位3件のソースIP — セッション数が最も多いリモートIP3件を、件数付きで表示します。
利用シーン
- 接続の急増・異常な状態を見つける: あるポートで SYN_RECV(ハーフオープン)や TIME_WAIT が急増していれば、SYNフラッド、コネクションストーム、アプリの接続リークの兆候です。
- どのサーバーが負荷を受けているかを見る: 同じポートでもサーバーごとにセッションの分布は異なり、ロードバランサーの偏りや過負荷のノードが浮かび上がります。
- 疑わしいソースを追う: 上位のソースIPまたは SRC サークルをクリックすると、そのIPがどのサーバー・ポートにどれだけ接続しているか、さらに geo/ASN と履歴まで掘り下げられます。そこから評判照会やブロックへ引き継げます。
- ディープリンクからの流入: 他の画面(例: サービス ▸ Web)から
?src_ip=…&port=…付きで到達すると、そのポートに自動で絞り込み、IP調査ポップアップを開きます。
画面構成
上部のコントロール
| 要素 | 動作 |
|---|---|
| タイマー 1分 / 5分 / 1時間 | セッション集計ウィンドウの幅です。選択内容は localStorage(infr:timer:traffic-ports)に保存され、次回以降の訪問でも維持されます。 |
| ポートチップ | 監視対象ポートの一覧(運用ポリシー)です。チップをクリックするとそのカードの表示・非表示を切り替えます。All は全選択・全解除を切り替えます。絞り込みはそのセッション限りで(保存されません)、新しく訪問するたびの初期状態は常に全ポートです。 |
| スナップショット時刻 | 現在のウィンドウの基準となる最新スナップショットのタイムスタンプです(表示タイムゾーン補正済み)。 |
| 更新 / ポーリング | 30秒ごとに /infra/traffic/ports/live を自動でポーリングし、カードを更新します。 |
ポートカード(メーソンリー)
カードは ドラッグで並べ替え でき、その順序は localStorage(infr:order:traffic-ports)に保存されます。カードの高さがまちまちなため、行スパン方式のメーソンリー(sortable_masonry ミックスイン)で隙間なく配置します。カード内のサーバータイルは ユニークなソースIP数 → 総セッション数 → サーバーインデックス の順に並びます。
TCP状態の凡例
積み上げバーの色はセマンティックなCSSトークン(var(--infr-state-*))に由来します。凡例は色と状態を対応付けます。
| トークン | ラベル | 意味 |
|---|---|---|
established |
ESTABLISHED | 正常に確立された接続 |
listen |
LISTEN | 待ち受け中(サーバーソケット) |
syn_sent |
SYN SENT | 接続の試行(クライアント) |
syn_recv |
SYN RECV | SYN受信/ハーフオープン — 急増は SYN フラッドを示唆します |
fin_wait |
FIN WAIT | クローズ処理中(FIN_WAIT1/2 を統合) |
close_wait |
CLOSE WAIT | 相手はクローズ済みだがアプリ側が未クローズ — 滞留は接続リークの兆候です |
time_wait |
TIME WAIT | クローズ後の待機 |
other |
Other | 上記7つ以外のすべての状態 |
使い方
- タイマーを選ぶ — 直近の最も狭いスナップショットのまとまりを見るなら
1min、傾向をなめらかに見るなら5min/1hourを使います。 - チップで対象のポートに絞る — 例えば 80・443 だけを残せば Web を監視できます。
- 積み上げバーを読む — ESTABLISHED の比率が低く SYN_RECV/TIME_WAIT が大きいのは、異常のシグナルです。
- SRC サークルをクリックする — そのサーバー・ポートの ソースIP一覧 ポップアップが開きます(リモートIP、リモートポート、セッション数、初回・最終検出)。
- IPをクリック → 単一IPの調査 — そのIPがどのサーバー・ポート・状態に接続しているか、geo/ASN、履歴(5分・1時間ごと・1日ごとのロールアップ)を分解して表示します。ここから 評判照会 やブロックへ進めます。
- カードを並べ替える — よく見るポートを上部へドラッグします。順序は保存されます。
日次(
1day)の履歴は、ロールアップの設計上、個別のIPではなくそのIPの /24 範囲(256個のIP) 単位で集計されます。ポップアップにby 211.224.128.0/24のような CIDR ラベルが表示された場合、その値は範囲全体の合計です。
データソース
すべてのクエリは legacy_glory 接続で実行され、App\Repositories\TrafficRepository に パラメータバインド されたクエリビルダー呼び出しとして隔離されています(文字列補間はありません)。
ウィンドウの基準合わせ
表示ウィンドウはアプリの now() ではなく、最新のデータスナップショット(MAX(snapshot_ts))を基準にします。コレクターの書き込み時計はアプリの時計より数時間遅れることがあるため、now() を基準にするとデータの範囲外に外れ、画面が空になってしまいます。
| タイマー | SQL の境界(snapshot_ts) |
|---|---|
| 1min | 最新スナップショットの分の startOfMinute … endOfMinute |
| 5min | (最新 − 4分)の startOfMinute … 最新の endOfMinute |
| 1hour | (最新 − 59分)の startOfMinute … 最新の endOfMinute |
snapshot_tsの WHERE 境界には、レガシー側に保存された生の時刻を使います。運用ポリシーの表示オフセット(traffic_tz_offset_hours)が加算されるのは 画面に表示されるスナップショット時刻 だけです。
中核クエリ — portOverview()
SELECT a.local_port, a.server_name, a.server_index, a.remote_ip,
a.state_code, b.state_name,
SUM(a.session_count) AS total_sessions
FROM traffic_session_ct AS a
LEFT JOIN protocol_state AS b ON a.state_code = b.state_code
WHERE a.snapshot_ts BETWEEN :min AND :max
AND a.local_port IN (:ports) -- 運用ポリシーの監視対象ポート
GROUP BY a.local_port, a.server_name, a.server_index,
a.remote_ip, a.state_code, b.state_name;
traffic_session_ct⋈protocol_stateにより、整数の状態コードを、凡例と積み上げバー用の人が読める状態名へ解決します。- 狭い
snapshot_ts BETWEENウィンドウとlocal_port INのホワイトリストによって、巨大なスナップショットテーブル(約60万5千行)を絞り込みます。
関連テーブル
| テーブル | 接続 | 役割 | 投入元 |
|---|---|---|---|
traffic_session_ct |
legacy_glory | セッションのスナップショット(ホスト/リモート/状態/件数) | check_ct.js |
protocol_state |
legacy_glory | TCP状態コード → 名称の参照表 | — |
traffic_session_ct_5min/_1hour/_1day |
legacy_glory | IP調査ポップアップ用の期間履歴 | aggregate.js |
ip_info_loop |
legacy_glory | IPポップアップ向けの geo/ASN/ISP エンリッチメント | — |
サーバー応答の形(抜粋)
{
"ports": [80, 443, 22],
"timer": 1,
"snapshot": "2026-08-13 10:24:00",
"ports_data": [
{ "port": 443, "server_data": [
{ "alias": "web1", "idx": 12, "host_count": 84,
"top_req": [ { "remote_ip": "203.0.113.10", "session_count": 61 } ],
"connections": [ { "state": "established", "count": 420, "pct": 78 } ],
"total": 538 }
] }
]
}
portsData() はリモートへの往復を抑えるため、20秒間キャッシュします(キーはタイマーとポート一覧のハッシュ)。
アクセス権限
インフラの役割領域は user_level 1(閲覧者)以上で表示できます。ポート接続は 読み取り専用 のため個別の書き込みゲートはなく、デモ(1)、スタッフ(5)、管理者(10)のいずれも閲覧できます。ルートが要求するのは infr.auth のセッション認証だけです。
| 操作 | 必要なレベル |
|---|---|
| ポート接続の表示、ポーリング、IP調査ポップアップを開く | 1(認証済みのすべてのユーザー) |
| 監視対象ポート一覧の編集(運用ポリシー) | 10(管理) — 運用ポリシー |
IP調査ポップアップから続く ブロック 操作は、セキュリティ ▸ ブロックリスト へ引き継がれ、書き込みには
user_level2以上と監査ログが必要です。この画面自体はブロックを行いません。
トラブルシューティングとFAQ
カードは表示されるが、サーバーのデータが空です。
そのウィンドウ内で、そのポートに紐づくセッションがありませんでした。タイマーを 5min/1hour に広げるか、そのポートが実際に開いていてトラフィックがあるかを確認してください。
すべてのカードが空で「接続スナップショットがありません」と表示されます。
legacy_glory の traffic_session_ct に最近のスナップショットがありません(check_ct.js コレクターが停止したか、DB接続に失敗しています)。最新スナップショット時刻が表示されない場合は、コレクターを確認してください。
見たいポートが表示されません。
監視対象ポートの一覧(infra_monitored_ports)に入っていなければ、カードは作られません。管理 ▸ 運用ポリシー で CSV として追加してください(1〜65535、最大30個、入力順を保持)。既定値:
infra_monitored_ports = 80,443,22,3306,25,465,27017,21,53,3030,8080,6379,6001
スナップショット時刻が数時間ずれています。
レガシーDBの保存時計が表示タイムゾーンと異なる場合は、運用ポリシーで traffic_tz_offset_hours(±14時間)を設定して表示時刻を補正してください。これは表示にのみ適用され、クエリの境界には決して適用されません。
日次の履歴が空です。
_1day のロールアップは1日遅れることがあり、/24 範囲単位で集計されます。代わりに5分または1時間の粒度を確認してください。
関連項目
- IP接続(ホストビュー) — サーバーごとのリモートピアIP × ポートの強度
- トラフィック(ネットワークI/O) — server_traffic の入出力バイト・パケットの時系列
- 運用ポリシー — 監視対象ポート一覧とタイムゾーンオフセットの設定
- IP評判 — 調査ポップアップからの AbuseIPDB 評判
- ファイアウォール(攻撃面) — 物理的な開放ポートの露出監視
- ブロックリスト・評判 — 調査ポップアップから続く IP ブロック
