# バッチ設計書 54-800.loginfail

## 概要

本ドキュメントは、FreeBSD の periodic セキュリティスクリプト `800.loginfail` のバッチ設計書である。認証ログからログイン失敗を検出し、セキュリティレポートとして管理者に通知する。

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

本バッチは、`/var/log/auth.log` およびそのローテーション済みファイルから前日分のログイン失敗メッセージを抽出し、セキュリティレポートとして管理者に通知する。ブルートフォース攻撃や不正ログイン試行の検出に役立つ。

**業務上の目的・背景**：ログイン失敗は、不正アクセスの試行（パスワード推測攻撃、辞書攻撃等）の兆候である可能性がある。本バッチは、認証ログを日次で解析し、失敗したログイン試行を管理者に報告することで、セキュリティインシデントの早期検出を支援する。特に SSH ブルートフォース攻撃やローカルアカウントへの不正アクセス試行の監視に有効である。

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

**主要な処理内容**：
1. `security_status_logdir`（デフォルト `/var/log`）から `auth.log` およびローテーション済みファイル（`auth.log.*`）を収集
2. RFC 3164（従来形式）および RFC 5424（新形式）の syslog タイムスタンプに対応した前日の日付パターンを生成
3. `catmsgs` 関数で直近2日以内の auth.log ファイルを時系列順に結合
4. `egrep` でログイン失敗を示すキーワード（fail, failures, failed, invalid, bad, illegal, auth.*error）を含む前日分のメッセージを抽出
5. 該当メッセージを標準エラー出力に表示し、件数をカウント

**前後の処理との関連**：本バッチは `450.status-security` から呼び出される。`410.logincheck`（ログイン異常検出）と関連し、認証セキュリティ監視の一環として機能する。同じカテゴリの `400.passwdless`（パスワード未設定アカウント検出）とも補完関係にある。

**影響範囲**：認証ログファイルを読み取り専用で参照する。システムの設定変更は行わない。

## バッチ種別

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

## 実行スケジュール

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

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| periodic.conf の読み込み | `/etc/defaults/periodic.conf` が読み取り可能であること |
| auth.log の存在 | `security_status_logdir` 配下に `auth.log` が存在すること |
| find/zcat コマンド | `find`, `zcat`, `egrep` コマンドが利用可能であること |

### 実行可否判定

`check_yesno_period security_status_loginfail_enable` で有効/無効を判定（デフォルト: YES）。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| security_status_loginfail_enable | 文字列 | No | YES | バッチの有効/無効 |
| security_status_loginfail_period | 文字列 | No | daily | 実行期間（daily/weekly/monthly） |
| security_status_logdir | 文字列 | No | /var/log | ログディレクトリ |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| `${LOG}/auth.log` | syslog テキスト | 現在の認証ログファイル |
| `${LOG}/auth.log.*` | syslog テキスト（圧縮含む） | ローテーション済み認証ログファイル |
| `/etc/defaults/periodic.conf` | シェル変数定義 | periodic フレームワークの設定ファイル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力 | テキスト | "{host} login failures:" ヘッダ |
| 標準エラー出力 | テキスト | 前日分のログイン失敗メッセージ（tee /dev/stderr 経由） |
| 終了コード | 整数 | 0: ログイン失敗なし、1: ログイン失敗あり |

### 出力ファイル仕様

本バッチは永続的な出力ファイルを生成しない。結果は標準出力および標準エラー出力に出力される。

## 処理フロー

### 処理シーケンス

```
1. 設定ファイルの読み込み
   └─ /etc/defaults/periodic.conf を読み込み、source_periodic_confs で追加設定を適用
2. ログディレクトリの設定
   └─ LOG 変数に security_status_logdir の値を設定
3. 日付パターンの生成
   └─ RFC 3164 形式: "^Mon DD " （例: "^Jan 31 "）
   └─ RFC 5424 形式: "^<PRI>1 YYYY-MM-DDT" （例: "^<[0-9]{1,3}>1 2026-01-31T"）
   └─ 両形式を OR 結合: "(RFC3164|RFC5424)"
4. 有効/無効判定
   └─ check_yesno_period security_status_loginfail_enable で実行可否を判定
5. ヘッダ出力
   └─ "{host} login failures:" を表示
6. ログファイル収集・検索
   └─ catmsgs 関数で auth.log.* を mtime -2 で検索
   └─ sort -t. -r -n -k 2,2 で番号降順にソート
   └─ 各ファイルを zcat -f で展開
   └─ 最後に auth.log を cat で出力
7. パターンマッチング
   └─ egrep -ia で前日の日付パターンとログイン失敗キーワードを含む行を抽出
   └─ tee /dev/stderr で結果を表示しつつ wc -l でカウント
8. 結果判定
   └─ 件数 > 0 の場合 rc=1、それ以外は rc=0
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[設定ファイル読み込み]
    B --> C[日付パターン生成<br>RFC 3164 + RFC 5424]
    C --> D{security_status_loginfail_enable?}
    D -->|NO| Z["exit 0"]
    D -->|YES| E["'{host} login failures:' 表示"]
    E --> F["catmsgs: auth.log.* を収集・結合"]
    F --> G["egrep で前日分のログイン失敗を抽出"]
    G --> H["tee /dev/stderr で表示 + wc -l でカウント"]
    H --> I{件数 > 0?}
    I -->|YES| J["rc=1"]
    I -->|NO| K["rc=0"]
    J --> L["exit $rc"]
    K --> L
```

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

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

本バッチではデータベース操作は行わない。ログファイルの読み取り専用アクセスのみ。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 0 | 正常終了 | ログイン失敗なし、または無効設定 | 対処不要 |
| 1 | 警告 | ログイン失敗が検出された | 管理者が失敗内容を確認し、不正アクセスの有無を判断 |

### リトライ仕様

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

### 障害時対応

auth.log が存在しない場合、catmsgs 関数は find の結果が空となり、最後の `[ -f ${LOG}/auth.log ] && cat` も実行されないため、egrep への入力は空となる。この場合、件数は 0 となり正常終了する。

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

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

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | auth.log のサイズに依存（通常数百〜数千行/日） |
| 目標処理時間 | 数秒〜数十秒（ログサイズに依存） |
| メモリ使用量上限 | 最小（パイプライン処理） |

## 排他制御

排他制御は実装されていない。ログファイルへの読み取り専用アクセスのため、ログローテーションとの競合に注意が必要だが、`-mtime -2` による直近2日分のファイル参照で対処している。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| ヘッダ | バッチ開始時 | "{host} login failures:" |
| 失敗ログ | ログイン失敗検出時 | 前日分のログイン失敗メッセージ（stderr 経由） |

## 監視・アラート

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

## 備考

- RFC 3164 タイムスタンプ形式: `Jan 31 ` のような従来の syslog 形式
- RFC 5424 タイムスタンプ形式: `<PRI>1 2026-01-31T` のような構造化 syslog 形式
- `date -v-1d` は FreeBSD の date コマンド固有の相対日付指定で、前日の日付を生成する
- egrep のパターン `\b(fail(ures?|ed)?|invalid|bad|illegal|auth.*error)\b` で幅広いログイン失敗メッセージを捕捉する
- `-i` オプションにより大文字・小文字を区別しない検索を行う
- `-a` オプションによりバイナリファイルもテキストとして処理する
- `tee /dev/stderr` は出力を表示しつつ、パイプラインの次段（wc -l）にも渡すためのテクニック
- `sort -t. -r -n -k 2,2` でログファイルを番号の降順（古い順）にソートし、時系列で結合する
