# 機能設計書 98-NTPデーモン

## 概要

本ドキュメントは、FreeBSDのNTP（Network Time Protocol）デーモン機能の機能設計を記述する。ntpdはネットワーク経由でシステムクロックを正確な時刻源と同期させるデーモンプログラムであり、NTPプロトコル（RFC 5905）を実装している。

### 本機能の処理概要

ntpdは、NTPサーバとの時刻同期を行うデーモンプロセスである。インターネット上の複数の時刻源（NTPサーバ、GPS受信機等）からの時刻情報を収集・評価し、最も信頼性の高い時刻源に基づいてシステムクロックを漸進的に調整する。

**業務上の目的・背景**：分散システムにおいて正確な時刻同期は、ログの一貫性、認証プロトコルの動作（Kerberos等）、データベースのタイムスタンプ整合性等に不可欠である。ntpdはこれらの要求に応えるための高精度時刻同期機能を提供する。

**機能の利用シーン**：システム起動時の時刻同期設定（bsdinstallの画面No.25でntpdサービスを有効化）、サーバの継続的時刻同期、ログサーバの時刻精度確保、Kerberos認証環境での時刻同期などで使用される。

**主要な処理内容**：
1. NTPサーバとのポーリング・時刻取得
2. 時刻オフセットの計算（クロックフィルタアルゴリズム）
3. 最適な時刻源の選択（クロック選択・クラスタアルゴリズム）
4. システムクロックの漸進的調整（スルーイング）
5. 大幅な時刻ずれの検出と即座の補正（ステップ調整）
6. リファレンスクロック（GPS、WWV等）のサポート
7. NTPv4対応（認証、Autokey）
8. ntpq/ntpdcによるモニタリング・制御

**関連システム・外部連携**：カーネルのタイムキーピング（kern_clock）、NTPサーバ群（pool.ntp.org等）、ntpq/ntpdc（モニタリングツール）

**権限による制御**：ntpdはroot権限で起動する必要がある（システムクロック変更のため）。起動後にドロップ可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 25 | サービス選択画面 | 補助機能 | ntpdサービスおよびntpd_sync_on_start設定 |

## 機能種別

システムサービス（時刻同期デーモン）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ntp.conf | ファイル | Yes | NTP設定ファイル | 構文チェック |
| -g | フラグ | No | 初回の大幅ステップ調整を許可 | - |
| -q | フラグ | No | 一度同期して終了 | - |
| -n | フラグ | No | フォアグラウンド実行 | - |

### 入力データソース

- /etc/ntp.conf 設定ファイル
- NTPサーバからのNTPパケット（UDP ポート123）
- リファレンスクロックデバイス（GPS等）
- カーネルの現在時刻

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| システムクロック調整 | adjtime/ntp_adjtime | カーネルへの時刻調整要求 |
| 統計ログ | ファイル | peerstats, loopstats, clockstats等 |
| NTPパケット応答 | NTPパケット | クライアントからの問い合わせへの応答 |

### 出力先

- カーネルの時刻調整インタフェース（adjtime(2)/ntp_adjtime(2)）
- ログファイル（/var/log/ntp/等）
- syslog
- NTPクライアントへのUDP応答

## 処理フロー

### 処理シーケンス

```
1. 初期化
   └─ 設定ファイル読み込み、サーバリスト構築、ソケットオープン
2. ポーリングループ
   └─ 各サーバに定期的にNTPリクエスト送信
3. 応答受信・処理
   └─ RTT計算、オフセット計算、クロックフィルタ適用
4. クロック選択
   └─ 交差アルゴリズム、クラスタアルゴリズムで最良の時刻源選択
5. 時刻調整
   └─ PLLまたはFLLでシステムクロックを漸進的に調整
6. ステータス更新
   └─ ntpq/ntpdc用のステータス情報更新
```

### フローチャート

```mermaid
flowchart TD
    A[初期化: ntp.conf読み込み] --> B[ポーリングタイマー起動]
    B --> C[NTPリクエスト送信]
    C --> D[NTPレスポンス受信]
    D --> E[クロックフィルタ: オフセット/遅延/分散計算]
    E --> F[クロック選択: 交差アルゴリズム]
    F --> G[クラスタリング: 外れ値除去]
    G --> H[結合アルゴリズム: 最終オフセット算出]
    H --> I{オフセット > 128ms?}
    I -->|Yes| J[ステップ調整: 即座に時刻設定]
    I -->|No| K[スルー調整: PLLで漸進的調整]
    J --> B
    K --> B
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-98-1 | ステップ/スルー閾値 | オフセットが128ms以上の場合ステップ調整、未満の場合スルー調整 | 時刻調整時 |
| BR-98-2 | パニック閾値 | オフセットが1000秒以上の場合はパニック終了（-gオプションで初回のみ無視可） | 時刻調整時 |
| BR-98-3 | ポーリング間隔 | 64秒から1024秒の範囲で動的に調整 | ポーリング時 |
| BR-98-4 | 最小サーバ数 | 正確な時刻同期には最低3台のサーバが推奨 | サーバ選択時 |

### 計算ロジック

NTPオフセット計算: offset = ((t2 - t1) + (t3 - t4)) / 2、ラウンドトリップ遅延: delay = (t4 - t1) - (t3 - t2)

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

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| パニック終了 | 致命的 | オフセット > 1000秒 | -gオプションまたは手動時刻設定後に再起動 |
| サーバ不到達 | ネットワーク | 全NTPサーバ無応答 | ネットワーク接続確認、サーバ設定確認 |
| 認証失敗 | セキュリティ | NTP認証キー不一致 | キー設定の確認 |

### リトライ仕様

NTPポーリングは自動的にリトライされる。到達不能なサーバのポーリング間隔は段階的に延長される。

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

該当なし。各NTPパケット交換が独立した処理単位。

## パフォーマンス要件

- 時刻精度: LAN環境でマイクロ秒オーダー、WAN環境でミリ秒オーダー
- CPU使用率: ポーリング間隔が長いため、継続的なCPU負荷は極めて小さい

## セキュリティ考慮事項

- NTP認証: シンメトリックキーまたはAutokey（NTPv4）による認証
- DDoS対策: ntpdcによるモニタリングインタフェースの制限
- ACL: restrict ディレクティブによるアクセス制御
- NTP増幅攻撃対策: monlistの無効化

## 備考

- FreeBSDに含まれるのはNTP Reference Implementation（ntp.org）
- contrib/ntp/以下にアップストリームソースが配置
- sntpコマンド（簡易NTPクライアント）も含まれる
- ntpdate（非推奨）の代替としてntpd -qまたはsntpを使用

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ntp.h | `contrib/ntp/include/ntp.h` | NTPプロトコルの基本データ構造。struct peer（ピア情報）、struct pkt（NTPパケット構造）等 |
| 1-2 | ntp_types.h | `contrib/ntp/include/ntp_types.h` | NTP固有の型定義（l_fp: 固定小数点タイムスタンプ等） |

**読解のコツ**: NTPのタイムスタンプはl_fp型（64bit固定小数点、上位32bitが秒、下位32bitが小数秒）で表現される。NTPエポックは1900年1月1日。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ntpd.c | `contrib/ntp/ntpd/ntpd.c` | メインプログラム（1898行）。初期化、設定ファイル読み込み、メインループの起動 |

#### Step 3: 設定処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ntp_config.c | `contrib/ntp/ntpd/ntp_config.c` | ntp.conf設定ファイルの解析 |

#### Step 4: プロトコル処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ntp_control.c | `contrib/ntp/ntpd/ntp_control.c` | NTPモード6/7制御メッセージ処理（ntpq/ntpdc対応） |

#### Step 5: クロック制御を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | ntp_clockdev.c | `contrib/ntp/ntpd/ntp_clockdev.c` | リファレンスクロックデバイスの管理 |

### プログラム呼び出し階層図

```
ntpd main() [ntpd.c]
    │
    ├─ ntp_config.c: 設定ファイル解析
    │      └─ server/pool/restrict等のディレクティブ解析
    │
    ├─ メインループ
    │      │
    │      ├─ NTPパケット送信（ポーリング）
    │      │      └─ 各ピアへのNTPリクエスト
    │      │
    │      ├─ NTPパケット受信・処理
    │      │      ├─ パケット検証
    │      │      ├─ オフセット/遅延/分散計算
    │      │      └─ クロックフィルタ適用
    │      │
    │      ├─ クロック選択アルゴリズム
    │      │      ├─ 交差アルゴリズム
    │      │      ├─ クラスタリング
    │      │      └─ 結合アルゴリズム
    │      │
    │      └─ 時刻調整
    │             ├─ adjtime(2) / ntp_adjtime(2)
    │             └─ settimeofday(2) [ステップ調整時]
    │
    └─ ntp_control.c: ntpq/ntpdc応答
```

### データフロー図

```
[入力]                        [処理]                          [出力]

NTPサーバ群          ───▶ NTPパケット受信           ───▶ ピア情報更新
(pool.ntp.org等)           │
                     クロックフィルタ
                           │
                     クロック選択アルゴリズム      ───▶ 最良時刻源決定
                           │
                     PLL/FLLループフィルタ
                           │
ntp.conf             ───▶ 設定解析                ───▶ adjtime(2)
                                                  ───▶ カーネル時刻調整
                                                  ───▶ 統計ログ出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ntpd.c | `contrib/ntp/ntpd/ntpd.c` | ソース | メインプログラム |
| ntp_config.c | `contrib/ntp/ntpd/ntp_config.c` | ソース | 設定ファイル解析 |
| ntp_control.c | `contrib/ntp/ntpd/ntp_control.c` | ソース | 制御メッセージ処理 |
| ntp_clockdev.c | `contrib/ntp/ntpd/ntp_clockdev.c` | ソース | クロックデバイス管理 |
| ntp_crypto.c | `contrib/ntp/ntpd/ntp_crypto.c` | ソース | NTP認証・暗号処理 |
| config.h | `usr.sbin/ntpd/config.h` | 設定 | FreeBSD固有ビルド設定 |
| Makefile | `usr.sbin/ntpd/ntpd/Makefile` | ビルド | ビルド設定 |
