# バッチ設計書 42-100.chksetuid

## 概要

本ドキュメントは、FreeBSDのperiodicセキュリティフレームワークにおけるsetuid/setgidファイル変更検出バッチ `100.chksetuid` の設計仕様を記述するものである。

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

このバッチは、システム上のsetuid/setgidビットが設定されたファイルを検索し、前回実行時からの変更を検出・報告するセキュリティ監査スクリプトである。

**業務上の目的・背景**：setuid/setgidビットが設定されたファイルは、実行時にファイル所有者/グループの権限で動作するため、セキュリティ上の重要な監査対象である。不正にsetuidビットが設定されたファイルの出現や、既存のsetuidファイルの改変は、権限昇格攻撃の兆候となり得る。本バッチは日次でこれらのファイルを監視し、変更があった場合に管理者に通知することで、セキュリティインシデントの早期発見を支援する。

**バッチの実行タイミング**：日次（daily security checkの一部として実行。`security_status_chksetuid_period` のデフォルトは "daily"）

**主要な処理内容**：
1. periodic.confの読み込みと有効/無効判定
2. ufs/zfsファイルシステムのうち、nosuidおよびnoexecオプションが設定されていないマウントポイントを抽出
3. 対象マウントポイント配下で実行権限とsetuid/setgidビットを持つファイルをfindコマンドで検索
4. 検索結果をinode番号・パーミッション・タイムスタンプ付きで一覧化
5. `check_diff` 関数により前回結果との差分を検出し、変更があれば報告

**前後の処理との関連**：daily/weekly/monthlyの `450.status-security` バッチから呼び出されるセキュリティチェックスクリプト群の一つ。番号100は最初に実行されるセキュリティチェックである。

**影響範囲**：ファイルシステムの読み取りのみを行い、システムの状態を変更しない。ただし、`/var/log/setuid.today` および `/var/log/setuid.yesterday` のログファイルを更新する。

## バッチ種別

セキュリティ監査 / 変更検出レポート

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 日次（デフォルト。weekly/monthlyに変更可能） |
| 実行時刻 | daily security checkの実行時刻に準ずる |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | cron経由 `periodic daily` -> `450.status-security` -> 本スクリプト |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| security_status_chksetuid_enable | "YES" であること（デフォルト: YES） |
| security_status_chksetuid_period | 実行周期が現在のPERIODICコンテキストと一致すること（デフォルト: daily） |
| security.functions | `/etc/periodic/security/security.functions` が読み込み可能であること |

### 実行可否判定

`check_yesno_period security_status_chksetuid_enable` 関数により判定。enable設定がYESで、かつperiod設定が現在の実行コンテキスト（daily/weekly/monthly）と一致する場合に実行される。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| security_status_chksetuid_enable | YES/NO | No | YES | バッチの有効/無効 |
| security_status_chksetuid_period | 文字列 | No | daily | 実行周期（daily/weekly/monthly/NO） |
| security_status_logdir | パス | No | /var/log | ログ出力ディレクトリ |
| security_status_diff_flags | 文字列 | No | -b -U 0 | diff出力時のフラグ |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| /etc/defaults/periodic.conf | シェル変数定義 | デフォルト設定値 |
| mountコマンド出力 | テキスト | マウントされたufs/zfsファイルシステム一覧 |
| ファイルシステム | バイナリ/テキスト | setuid/setgidファイルの検索対象 |
| /var/log/setuid.today | テキスト | 前回実行時のsetuidファイル一覧 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力 | テキスト | 変更検出結果のdiff出力 |
| /var/log/setuid.today | テキスト | 最新のsetuidファイル一覧 |
| /var/log/setuid.yesterday | テキスト | 前回のsetuidファイル一覧（ローテーション） |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | setuid.today / setuid.yesterday |
| 出力先 | /var/log/ （security_status_logdir設定に依存） |
| 文字コード | システムロケール依存 |
| 区切り文字 | スペース区切り（ls -lid出力形式） |

## 処理フロー

### 処理シーケンス

```
1. 設定ファイル読み込み
   └─ periodic.confを読み込み、security.functionsをソース
2. 実行可否判定
   └─ check_yesno_period security_status_chksetuid_enable
3. マウントポイント抽出
   └─ mount -t ufs,zfs の出力からnosuid/noexecでないマウントポイントを抽出
4. setuid/setgidファイル検索
   └─ find -sx でsetuid/setgidかつ実行権限のあるファイルを検索
   └─ ls -lid -D "%FT%T" で詳細情報付きリスト化
5. 差分チェック
   └─ check_diff関数で/var/log/setuid.todayと比較
   └─ 変更があればdiff出力とファイルローテーション
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[periodic.conf読み込み]
    B --> C[security.functions読み込み]
    C --> D{check_yesno_period?}
    D -->|No| K[exit 0]
    D -->|Yes| E[ufs/zfsマウントポイント抽出]
    E --> F["find: setuid/setgidファイル検索"]
    F --> G["ls -lid: 詳細情報取得"]
    G --> H["check_diff: 前回結果と比較"]
    H --> I{差分あり?}
    I -->|Yes| J[diff出力 + ファイルローテーション]
    I -->|No| K2[変更なし]
    J --> L[exit rc]
    K --> L2[exit 0]
    K2 --> L
```

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

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

本バッチはデータベース操作を行わない。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 該当なし | - | - | - |

### テーブル別操作詳細

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 変更検出 | setuidファイル一覧に変更があった場合 | diff出力を確認し、正当な変更か不正な変更かを判断 |
| 3 | ファイル操作エラー | ログファイルのコピー/移動に失敗した場合 | ログディレクトリのパーミッションを確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

### 障害時対応

findコマンドの実行が失敗する場合は、ファイルシステムの状態（マウント状態、権限）を確認する。ログファイルの操作が失敗する場合は、`security_status_logdir`（デフォルト `/var/log`）のディスク容量とパーミッションを確認する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 該当なし（シェルスクリプト実行） |
| コミットタイミング | 該当なし |
| ロールバック条件 | 該当なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | ファイルシステム全体のsetuidファイル数（通常数十〜数百件） |
| 目標処理時間 | ファイルシステムサイズに依存（数分〜数十分） |
| メモリ使用量上限 | findプロセスに依存 |

## 排他制御

`-sx` フラグにより、findコマンドはマウントポイントを跨がない。ローカルファイルシステムのみを対象とし（`! -fstype local` で非ローカルを除外）、NFSなどのリモートファイルシステムは除外される。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | チェック開始時 | "Checking setuid files and devices:" |
| 差分ログ | 変更検出時 | "{host} setuid diffs:" とdiff出力 |
| 初回ログ | 初回実行時 | "No /var/log/setuid.today" |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| setuidファイル変更 | 差分1件以上 | daily_status_security_output（デフォルト: root） |

## 備考

- findコマンドは `-sx` オプションでクロスデバイス検索を防止している
- IFS=$'\n' により、スペースやタブを含むマウントポイント名を正しく処理する
- nosuidおよびnoexecオプションが設定されたファイルシステムは検索対象外
- ソースコード: `usr.sbin/periodic/etc/security/100.chksetuid`
