# 機能設計書 97-DNS解決

## 概要

本ドキュメントは、FreeBSDのDNS解決設定管理機能（resolvconf）の機能設計を記述する。resolvconfは複数のネットワークインタフェースやDHCPクライアント等からのDNS設定情報を統合管理し、/etc/resolv.confを動的に生成するフレームワークである。

### 本機能の処理概要

resolvconfは、openresolvプロジェクト由来のシェルスクリプトであり、DNS解決設定（ネームサーバアドレス、検索ドメイン等）をインタフェース単位で管理する。DHCPクライアント、PPP、VPN等の各種ネットワーク接続手段から通知されるDNS情報を統合し、優先順位に基づいて/etc/resolv.confを生成する。

**業務上の目的・背景**：複数のネットワークインタフェースが同時にアクティブな環境では、各インタフェースから異なるDNS設定が提供される。resolvconfはこれらの設定を統合管理し、適切な/etc/resolv.confを自動生成することで、名前解決の一貫性を確保する。

**機能の利用シーン**：bsdinstallでのDNS設定（画面No.12）、DHCPクライアントからのDNS設定反映、VPN接続時のDNS設定切り替え、手動でのDNS設定変更などで使用される。

**主要な処理内容**：
1. インタフェースごとのDNS情報の登録（-aオプション）
2. インタフェースのDNS情報の削除（-dオプション）
3. DNS情報の統合と/etc/resolv.conf生成（-uオプション）
4. 現在のDNS情報の表示（-lオプション）
5. インタフェース一覧の表示（-iオプション）
6. インタフェース優先順位に基づく統合
7. プライベート/排他的DNS設定のサポート

**関連システム・外部連携**：DHCPクライアント（dhclient）、unbound（ローカルDNSリゾルバ）、各種VPNクライアント

**権限による制御**：/etc/resolv.confの書き換えにはroot権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | DNS設定画面 | 主機能 | DNSサーチドメインおよびネームサーバ（IPv4/IPv6）のresolv.conf設定処理 |

## 機能種別

ネットワーク設定（DNS設定管理フレームワーク）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| -a $INTERFACE | string | Yes（登録時） | DNS情報を登録するインタフェース名 | 有効なインタフェース名 |
| -d $INTERFACE | string | Yes（削除時） | DNS情報を削除するインタフェース名 | 有効なインタフェース名 |
| stdin | resolv.conf形式 | Yes（-a時） | nameserver、search、domain行 | resolv.conf形式 |
| -m metric | string | No | インタフェースのメトリック（優先度） | 数値 |
| -p | flag | No | プライベートDNS設定フラグ | - |
| -x | flag | No | 排他的DNS設定フラグ | - |

### 入力データソース

- 標準入力（resolv.conf形式のDNS情報）
- /etc/resolvconf.conf 設定ファイル
- /var/run/resolvconf/interfaces/ ディレクトリの既存インタフェース設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| /etc/resolv.conf | ファイル | 統合されたDNS解決設定 |
| インタフェース情報 | stdout | -i/-lオプション時の表示情報 |

### 出力先

- /etc/resolv.conf への書き出し
- /var/run/resolvconf/ ディレクトリへのインタフェース情報保存
- 標準出力への情報表示

## 処理フロー

### 処理シーケンス

```
1. 引数解析
   └─ コマンド（-a/-d/-u/-l/-i）の判定
2. 設定ファイル読み込み
   └─ /etc/resolvconf.conf の解析
3. インタフェース情報操作
   └─ /var/run/resolvconf/interfaces/ への情報保存/削除
4. DNS情報統合
   └─ インタフェース優先順位に基づくマージ
5. resolv.conf生成
   └─ 統合結果を/etc/resolv.confに書き出し
6. サービス再起動通知
   └─ RESTARTCMD実行（unbound等のDNSサービス再起動）
```

### フローチャート

```mermaid
flowchart TD
    A[コマンド引数解析] --> B{コマンド種別}
    B -->|-a| C[インタフェースDNS情報を保存]
    B -->|-d| D[インタフェースDNS情報を削除]
    B -->|-u| E[更新処理開始]
    B -->|-l| F[DNS情報表示]
    B -->|-i| G[インタフェース一覧表示]
    C --> E
    D --> E
    E --> H[インタフェース優先順位でソート]
    H --> I[DNS情報を統合]
    I --> J[/etc/resolv.conf 生成]
    J --> K[サービス再起動通知]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-97-1 | インタフェース優先順位 | lo, lo[0-9]*が最優先、次に一般、動的(tap, tun, vpn, ppp)が最後 | DNS情報統合時 |
| BR-97-2 | ローカルネームサーバ | 127.*, 0.0.0.0, 255.255.255.255, ::1はローカルネームサーバとして識別 | 常時 |
| BR-97-3 | ブラックリスト | 0.0.0.0はネームサーバとして無効 | ネームサーバ検証時 |
| BR-97-4 | 排他的設定 | -xフラグのインタフェースがある場合、そのインタフェースのDNS設定のみを使用 | -xフラグ設定時 |

### 計算ロジック

特に複雑な計算ロジックはない。インタフェースの優先順位は、interface_orderとdynamic_orderのパターンマッチで決定される。

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 一般エラー | 引数不正、権限不足等 | stderrにエラーメッセージ出力 |

### リトライ仕様

リトライ機構はない。

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

ロックディレクトリ（$VARDIR/lock）により同時実行を排他制御する。

## パフォーマンス要件

- シェルスクリプト実装のため、C言語実装と比べてオーバーヘッドがある
- DNS設定変更時にのみ実行されるため、常時のパフォーマンスへの影響はない

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

- /etc/resolv.confの書き込みにroot権限が必要
- 不正なDNSサーバアドレスの注入リスク（DHCPサーバ信頼性に依存）
- プライベートDNS設定による情報漏洩防止

## 備考

- openresolvプロジェクト（バージョン3.9.2）由来
- contrib/openresolv/以下にアップストリームソースが配置
- FreeBSD固有のパス設定はMakefile経由で@SYSCONFDIR@等のプレースホルダが置換される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | resolvconf.conf | `contrib/openresolv/resolvconf.conf` | 設定ファイルの形式。name_servers, search_domains, interface_order等の設定項目 |

**読解のコツ**: resolvconfはシェルスクリプトであるため、データ構造はシェル変数とファイルシステム上のディレクトリ構造で表現される。/var/run/resolvconf/interfaces/ディレクトリ内に各インタフェースのDNS情報がファイルとして保存される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | resolvconf.in | `contrib/openresolv/resolvconf.in` | メインスクリプト。OPENRESOLV_VERSION="3.9.2"（28行目）。変数定義（local_nameservers, dynamic_order, interface_order, name_server_blacklist: 45-49行目）。設定読み込み（53-61行目）。usage関数（80-99行目） |

**主要処理フロー**:
1. **27-34行目**: 基本変数定義（SYSCONFDIR, LIBEXECDIR, VARDIR等）
2. **42-49行目**: デフォルト設定（local_nameservers, dynamic_order, interface_order）
3. **53-61行目**: resolvconf.confからの設定読み込み
4. **62-67行目**: ディレクトリパス定義（IFACEDIR, METRICDIR, PRIVATEDIR, EXCLUSIVEDIR, LOCKDIR）

#### Step 3: コマンド処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | resolvconf.in | `contrib/openresolv/resolvconf.in` | -aコマンド: インタフェース情報をIFACEDIRに保存。-dコマンド: インタフェース情報を削除。-uコマンド: resolv.conf再生成 |

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

```
resolvconf [シェルスクリプト]
    │
    ├─ 設定読み込み
    │      └─ /etc/resolvconf.conf
    │
    ├─ -a $INTERFACE (DNS情報登録)
    │      ├─ stdin → /var/run/resolvconf/interfaces/$INTERFACE
    │      └─ -u (更新トリガー)
    │
    ├─ -d $INTERFACE (DNS情報削除)
    │      ├─ /var/run/resolvconf/interfaces/$INTERFACE 削除
    │      └─ -u (更新トリガー)
    │
    └─ -u (resolv.conf更新)
           ├─ インタフェース一覧取得・ソート
           ├─ DNS情報統合
           ├─ /etc/resolv.conf 生成
           └─ RESTARTCMD実行 (オプション)
```

### データフロー図

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

dhclient (DHCPACK後)    ───▶ resolvconf -a em0       ───▶ interfaces/em0
VPNクライアント         ───▶ resolvconf -a tun0      ───▶ interfaces/tun0
手動設定               ───▶ resolvconf -a manual     ───▶ interfaces/manual

resolvconf.conf        ───▶ 設定読み込み
                              │
interfaces/*           ───▶ DNS情報統合              ───▶ /etc/resolv.conf
                              │
                       ───▶ RESTARTCMD              ───▶ DNSサービス再起動
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| resolvconf.in | `contrib/openresolv/resolvconf.in` | スクリプト | メインスクリプト（テンプレート） |
| resolvconf.conf | `contrib/openresolv/resolvconf.conf` | 設定 | デフォルト設定ファイル |
| resolvconf.8.in | `contrib/openresolv/resolvconf.8.in` | マニュアル | manページテンプレート |
| resolvconf.conf.5.in | `contrib/openresolv/resolvconf.conf.5.in` | マニュアル | 設定ファイルmanページ |
| Makefile | `sbin/resolvconf/Makefile` | ビルド | ビルド設定 |
