# バッチ設計書 51-550.ipfwlimit

## 概要

本ドキュメントは、FreeBSD の periodic セキュリティスクリプト `550.ipfwlimit` のバッチ設計書である。ipfw ファイアウォールルールのログ制限到達状況を検出し、管理者に報告する。

### 本バッチの処理概要

本バッチは、ipfw(8) ファイアウォールのルールごとに設定されたログ記録上限（logamount）に到達したルールを検出し、セキュリティレポートとして管理者に通知する。ログ制限に達したルールは、それ以降のパケットマッチがログに記録されなくなるため、セキュリティ監視の盲点となる可能性がある。

**業務上の目的・背景**：ipfw ファイアウォールでは、各ルールに `log logamount N` を指定することでログ記録数の上限を設定できる。この上限に到達すると、以降のマッチはログに記録されなくなる。本バッチは、ログ上限に達したルールを早期に検出し、管理者がファイアウォールの監視状態を正確に把握できるようにする。これにより、セキュリティインシデントの見逃しを防止する。

**バッチの実行タイミング**：daily（日次）のセキュリティチェック（450.status-security）から呼び出される。periodic(8) フレームワークにより、`security_status_ipfwlimit_period` の設定に応じて daily/weekly/monthly のいずれかで実行される。デフォルトは daily。

**主要な処理内容**：
1. `net.inet.ip.fw.verbose` sysctl の値を確認し、ipfw の verbose モードが無効の場合は処理をスキップ
2. `ipfw -a list` コマンドでパケットカウンタ付きのルール一覧を取得
3. `log` キーワードを含むルールをフィルタリング
4. awk で各ルールのパケットカウント（$2）と logamount 制限値（$7）を比較
5. カウントが制限値を超過したルールを一時ファイルに出力
6. 超過ルールが存在する場合、レポートとして表示

**前後の処理との関連**：本バッチは `450.status-security`（daily/weekly/monthly のセキュリティチェック親スクリプト）から呼び出される。同じカテゴリの `500.ipfwdenied`（ipfw 拒否ログ確認）と関連し、ファイアウォール監視の一環として機能する。

**影響範囲**：ipfw ファイアウォールのルール状態を読み取り専用で参照する。システムの設定変更は行わない。一時ファイルを /tmp に作成し、処理後に削除する。

## バッチ種別

レポート生成 / セキュリティ監査

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 日次（デフォルト） |
| 実行時刻 | periodic(8) の daily セキュリティチェック実行時 |
| 実行曜日 | 毎日 |
| 実行日 | 毎日 |
| トリガー | cron 経由の periodic(8) フレームワーク |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| periodic.conf の読み込み | `/etc/defaults/periodic.conf` が読み取り可能であること |
| ipfw カーネルモジュール | ipfw がカーネルに組み込まれている、またはロードされていること |
| ipfw verbose モード | `net.inet.ip.fw.verbose` が 1（有効）であること |
| ipfw コマンド | `ipfw` コマンドが利用可能であること |

### 実行可否判定

1. `check_yesno_period security_status_ipfwlimit_enable` で有効/無効を判定（デフォルト: YES）
2. `sysctl -n net.inet.ip.fw.verbose` の値を確認し、0 または取得失敗の場合は exit 0 でスキップ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| security_status_ipfwlimit_enable | 文字列 | No | YES | バッチの有効/無効 |
| security_status_ipfwlimit_period | 文字列 | No | daily | 実行期間（daily/weekly/monthly） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| `ipfw -a list` 出力 | テキスト（標準出力） | パケットカウンタ付きの ipfw ルール一覧 |
| `sysctl net.inet.ip.fw.verbose` | 整数値 | ipfw verbose モードの有効/無効状態 |
| `/etc/defaults/periodic.conf` | シェル変数定義 | periodic フレームワークの設定ファイル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力 | テキスト | ログ制限に到達した ipfw ルールの一覧 |
| 終了コード | 整数 | 0: 制限到達ルールなし、1: 制限到達ルールあり |

### 出力ファイル仕様

一時ファイルを使用するが、最終的な永続出力ファイルは生成しない。

| 項目 | 内容 |
|-----|------|
| ファイル名 | `mktemp -t security` による一時ファイル |
| 出力先 | `$TMPDIR` または `/tmp` |
| 文字コード | システムデフォルト |
| 区切り文字 | スペース区切り（ipfw list 出力形式） |

## 処理フロー

### 処理シーケンス

```
1. 設定ファイルの読み込み
   └─ /etc/defaults/periodic.conf を読み込み、source_periodic_confs で追加設定を適用
2. 有効/無効判定
   └─ check_yesno_period security_status_ipfwlimit_enable で実行可否を判定
3. ipfw verbose モード確認
   └─ sysctl -n net.inet.ip.fw.verbose の値が 0 または取得失敗の場合はスキップ
4. 一時ファイル作成
   └─ mktemp -t security で一時ファイルを作成
5. ipfw ルール解析
   └─ ipfw -a list | grep " log " でログルールを抽出
   └─ grep で数値+スペース+数値の行パターンでフィルタ
   └─ awk でパケットカウント ($2) と logamount ($7) を比較し、超過ルールを抽出
6. 結果判定・出力
   └─ 一時ファイルにデータがある場合（-s）、rc=1 にセットし結果を表示
7. クリーンアップ
   └─ 一時ファイルを削除
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{security_status_ipfwlimit_enable?}
    B -->|NO| Z[exit 0]
    B -->|YES| C{net.inet.ip.fw.verbose 確認}
    C -->|0 または取得失敗| Z
    C -->|1（有効）| D[一時ファイル作成]
    D --> E["ipfw -a list でルール一覧取得"]
    E --> F["grep でログルールをフィルタ"]
    F --> G["awk でカウント > logamount を抽出"]
    G --> H{超過ルールあり?}
    H -->|あり| I[rc=1 に設定し結果表示]
    H -->|なし| J[rc=0 のまま]
    I --> K[一時ファイル削除]
    J --> K
    K --> L["exit $rc"]
```

## データベース操作仕様

### 操作別データベース影響一覧

本バッチではデータベース操作は行わない。ipfw のカーネル内ルールテーブルを読み取り専用で参照する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 0 | 正常終了 | 制限到達ルールなし、または ipfw verbose 無効 | 対処不要 |
| 1 | 警告 | ログ制限に到達したルールが検出された | 管理者がルールの logamount を増加、またはカウンタをリセット |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（リトライ機構なし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

本バッチは読み取り専用の監査スクリプトであり、失敗時のリカバリは不要。sysctl 取得失敗時は自動的にスキップされる。一時ファイルは処理終了時に `rm -f` で削除される。

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（データベース操作なし） |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | ipfw ルール数に依存（通常数十〜数百ルール） |
| 目標処理時間 | 数秒以内 |
| メモリ使用量上限 | 最小（パイプライン処理） |

## 排他制御

排他制御は実装されていない。ipfw ルールテーブルの読み取り専用アクセスのため、同時実行による問題は発生しない。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 警告ログ | ログ制限到達ルール検出時 | "ipfw log limit reached:" に続き、該当ルールの詳細 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 1（制限到達検出） | periodic(8) のメール通知先（daily セキュリティレポート） |

## 備考

- ipfw の verbose モードが無効（`net.inet.ip.fw.verbose=0`）の場合、本バッチは何も出力せず正常終了する
- awk の処理では、`$6 == "logamount"` でログ制限値フィールドの位置を特定し、`$2 > $7` でパケットカウントと制限値を比較している
- 本バッチは FreeBSD 固有の ipfw ファイアウォールを対象としており、他のファイアウォール（pf, ipf）には別のスクリプトが存在する
