ping6.net
基礎

IPv6近隣探索プロトコル(NDP):デバイスが互いを見つける方法

IPv6でARPを置き換えるプロトコルであるNDPを深く掘り下げます。ルーター要請、近隣要請、およびアドレス解決の仕組みを学びます。

ping6.net2024年12月14日10 min read
IPv6NDP近隣探索ARP置き換えネットワーキング

NDPはARPだけでなく、より多くを置き換える#

IPv4では、アドレス解決はARP—別のレイヤー2プロトコルを使用します。ルーター発見はICMPルーター発見またはDHCPを使用します。リダイレクトメッセージはICMPを使用します。重複アドレス検出は全く存在しません。

IPv6はこれらすべての機能を近隣探索プロトコルに統合します。NDPは以下を処理します:

  • アドレス解決(ARPの仕事)
  • ルーター発見(デフォルトゲートウェイの検索)
  • プレフィックス発見(自動設定のためのネットワークプレフィックスの学習)
  • パラメータ発見(MTU、ホップ制限)
  • アドレス自動設定(SLAAC)
  • 重複アドレス検出(競合の防止)
  • 近隣到達可能性(私の近隣はまだそこにいるか?)
  • 次ホップ決定(どのルーターを使うべきか?)
  • リダイレクトメッセージ(より良いルートが存在する)

NDPは完全にICMPv6上で実行され、5つのメッセージタイプ(133-137)を使用します。オプションではありません。NDPをブロックすると、IPv6が機能しなくなります。

TL;DR - 要点まとめ

重要ポイント:

  • NDPはARP、ルーター発見、自動設定をICMPv6上で実行される1つのプロトコルに統合
  • 5つのメッセージタイプ(133-137)がアドレス解決からルーターアドバタイズメントまですべてを処理
  • セキュリティ:すべてのNDPメッセージはオフリンク攻撃を防ぐためホップリミット255が必要

ジャンプ: ルーターアドバタイズメント でSLAAC詳細、実際のアドレス解決 で実用例、または トラブルシューティング でよくある問題。

5つのNDPメッセージタイプ#

すべてのNDPメッセージは特定のタイプ番号を持つICMPv6パケットです。これら5つのメッセージを理解することは、IPv6ネットワークが基本レベルでどのように動作するかを理解することを意味します。

タイプ名前送信者目的宛先
133Router Solicitation (RS)ホストルーター情報を要求ff02::2 (all-routers)
134Router Advertisement (RA)ルーター存在と設定を通知ff02::1 (all-nodes) またはユニキャスト
135Neighbor Solicitation (NS)任意のノードアドレス解決、到達可能性要請ノードマルチキャストまたはユニキャスト
136Neighbor Advertisement (NA)任意のノードNSへの応答ユニキャストまたはff02::1
137Redirectルーターより良い次ホップが存在するユニキャスト(元の送信者)

すべてのNDPメッセージには共通のセキュリティ要件があります:ホップ制限は255でなければならない。これは、ルーターがホップ制限を減らすため、オフリンク攻撃を防ぎます。リモート攻撃者からのパケットはホップ制限 < 255で到着し、ドロップされます。

Router Solicitation(ルーター要請、タイプ133)#

ホストは、次のスケジュールされたルーター広告を待つ代わりに、ルーターが即座に自己通知することを望むときにルーター要請を送信します。

ICMPv6構造:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Type      |     Code      |          Checksum             |
|     (133)     |      (0)      |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Reserved                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Options ...
+-+-+-+-+-+-+-+-+-+-+-+-

フィールド:

  • Type: 133
  • Code: 0
  • Reserved: 32ビット、ゼロでなければならない
  • Options: Source Link-Layer Address(オプション、送信元アドレスが::でない場合に含める)

送信されるとき:

  • インターフェースが起動する
  • ホストがブートする
  • IPv6スタックが初期化される
  • ホストが迅速に設定を必要とする

送信元アドレス:

  • リンクローカルアドレス(設定されている場合)
  • ::(未指定、まだアドレスがない場合)

宛先: ff02::2(all-routersマルチキャストアドレス)

ホップ制限: 255(必須)

パケット例:

IPv6 Header:
  Source:fe80::a4b2:c3d4:e5f6:7890
  Destination:ff02::2
  Next Header:58 (ICMPv6)
  Hop Limit:255
 
ICMPv6:
  Type:133 (Router Solicitation)
  Code:0
  Options:
    Source Link-Layer Address:00:1a:2b:3c:4d:5e

レート制限:

ホストはルーター要請をあまり頻繁に送信してはいけません。RFC 4861は、最大3秒に1つを推奨します。これにより、ネットワークの不安定性の間にルーターがフラッドされるのを防ぎます。

なぜ重要か:

RSなしでは、ホストは定期的なルーター広告(数分ごとに送信)を待つことになります。RSはホストが数分ではなく数秒で設定を取得できるようにし、ネットワーク初期化を高速化します。

Router Advertisement(ルーター広告、タイプ134)#

ルーターはルーター広告を送信して、その存在を通知し、ネットワークプレフィックスを広告し、設定パラメータを提供します。これはステートレスアドレス自動設定(SLAAC)の基礎です。

ICMPv6構造:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Type      |     Code      |          Checksum             |
|     (134)     |      (0)      |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Cur Hop Limit |M|O|H|Prf|Resvd|       Router Lifetime         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Reachable Time                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Retrans Timer                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Options ...
+-+-+-+-+-+-+-+-+-+-+-+-

フィールド:

Cur Hop Limit(8ビット): 発信パケットのホップ制限フィールドの推奨値です。通常64です。ホストはこれをIPv6ヘッダーのホップ制限フィールドにコピーします。

フラグ(8ビット):

  • M (Managed Address Configuration): アドレス用にDHCPv6を使用
  • O (Other Configuration): その他の設定(DNS、NTPなど)用にDHCPv6を使用
  • H (Home Agent): ルーターはモバイルIPv6ホームエージェント(ほとんど使用されない)
  • Prf (Router Preference): 2ビット優先度(00=中、01=高、11=低)
  • Reserved: 3ビット

Router Lifetime(16ビット): このルーターをデフォルトゲートウェイとして使用する期間(秒単位)です。0は「デフォルトルーターではない」を意味します。最大9000秒(2.5時間)です。

Reachable Time(32ビット): 到達可能性確認を受信した後、近隣を到達可能とみなす期間(ミリ秒単位)です。0は未指定(デフォルトまたは以前に受信した値を使用)を意味します。

Retrans Timer(32ビット): 近隣要請を再送信する間隔(ミリ秒単位)です。アドレス解決と近隣到達不能検出に使用されます。

一般的なオプション:

Source Link-Layer Address(タイプ1): ルーターのMACアドレスです。ホストがルーターの近隣要請をスキップできるようにします。

MTU(タイプ5): リンクの推奨MTUです。通常1500です。

Prefix Information(タイプ3): アドレス自動設定のためのネットワークプレフィックスです。これはSLAACの重要なオプションです。

RDNSS(タイプ25): 再帰的DNSサーバーアドレスです。RFC 8106です。

DNSSL(タイプ31): DNS検索リストです。RFC 8106です。

送信されるとき:

  • 定期的に(200-600秒ごと、通常200)
  • ルーター要請への応答として
  • ルーター設定が変更されたとき

送信元: ルーターのリンクローカルアドレス(fe80::/10)

宛先:

  • ff02::1(all-nodesマルチキャスト) 定期的な通知用
  • 要請ホストへのユニキャスト RSへの応答時

ホップ制限: 255(必須)

パケット例:

IPv6 Header:
  Source:fe80::1
  Destination:ff02::1
  Next Header:58 (ICMPv6)
  Hop Limit:255
 
ICMPv6:
  Type:134 (Router Advertisement)
  Code:0
  Cur Hop Limit:64
  Flags:M=0、O=0(SLAACのみ)
  Router Lifetime:1800秒(30分)
  Reachable Time:30000 ms
  Retrans Timer:1000 ms
 
  Options:
    Source Link-Layer Address:00:11:22:33:44:55
    MTU:1500
    Prefix Information:
      Prefix:2001:db8:1234:5678::/64
      Valid Lifetime:86400(24時間)
      Preferred Lifetime:14400(4時間)
      Flags:L=1(on-link)、A=1(autonomous/SLAAC)
    RDNSS:
      Lifetime:3600
      Addresses:2001:4860:4860::8888、2001:4860:4860::8844

フラグの組み合わせ:

MO動作
00SLAACのみ、DHCPv6なし(最も一般的)
01アドレス用SLAAC、DNS/NTPなど用DHCPv6
10アドレス用DHCPv6(珍しい、ほとんど使用されない)
11すべて用DHCPv6(エンタープライズネットワーク)

Prefix Informationオプション:

このオプションはSLAACを可能にするものです。アドレスを自動設定するときにホストが使用すべきネットワークプレフィックスを伝えます。

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Type      |    Length     | Prefix Length |L|A|R|Reserved1|
|      (3)      |      (4)      |               | | | |         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Valid Lifetime                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Preferred Lifetime                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Reserved2                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                            Prefix                             +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

フィールド:

  • Prefix Length: SLAACの場合、通常64
  • Lフラグ: On-link(プレフィックスはローカルリンク上にある)
  • Aフラグ: Autonomous(SLAACに使用)
  • Rフラグ: Router Address(プレフィックスにルーターのインターフェースIDが含まれる)
  • Valid Lifetime: アドレスが有効である期間(通常86400 = 24時間)
  • Preferred Lifetime: 新しい接続にアドレスを使用する期間(通常14400 = 4時間)
  • Prefix: 実際のネットワークプレフィックス(例:2001:db8:1234:5678::)

A=1の場合、ホストはプレフィックスとインターフェース識別子を組み合わせてアドレスを生成します:

RAからのプレフィックス:  2001:db8:1234:5678::/64
インターフェースID:      a4b2:c3d4:e5f6:7890(MACから派生またはランダム)
結果のアドレス:          2001:db8:1234:5678:a4b2:c3d4:e5f6:7890

ルーター広告は重要

ICMPv6タイプ134をブロックすると、SLAACが機能しなくなります。ホストはリンクローカルアドレス(fe80::/10)のみを持ち、グローバル接続がありません。これは最も一般的なIPv6誤設定の1つです—どのタイプが不可欠かを理解せずにすべてのICMPv6をブロックするファイアウォールです。

Neighbor Solicitation(近隣要請、タイプ135)#

近隣要請はIPv6のARPの置き換えです。IPv6アドレスをリンク層(MAC)アドレスに解決し、近隣がまだ到達可能であることを確認します。

ICMPv6構造:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Type      |     Code      |          Checksum             |
|     (135)     |      (0)      |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Reserved                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                       Target Address                          +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Options ...
+-+-+-+-+-+-+-+-+-+-+-+-

フィールド:

  • Type: 135
  • Code: 0
  • Reserved: 32ビット、ゼロでなければならない
  • Target Address: 照会されるIPv6アドレス
  • Options: Source Link-Layer Address(送信元が::でない限り含まれる)

3つの使用ケース:

1. アドレス解決(ARP置き換え)#

ホストAは同じリンク上のホストBにパケットを送信する必要がありますが、BのMACアドレスを知りません。

プロセス:

  1. Aは近隣キャッシュをチェック—Bのエントリがない
  2. AはBの要請ノードマルチキャストアドレスにNSを送信
  3. BはNSを受信し、そのMACを含むNAで応答
  4. Aはマッピングをキャッシュし、元のパケットを送信

例:

# ホストAは2001:db8::10に送信したい
 
IPv6 Header:
  Source:2001:db8::1
  Destination:ff02::1:ff00:10(要請ノードマルチキャスト)
  Hop Limit:255
 
ICMPv6:
  Type:135 (Neighbor Solicitation)
  Target Address:2001:db8::10
  Options:
    Source Link-Layer Address:00:1a:2b:3c:4d:5e

要請ノードマルチキャストアドレスの計算:

IPv6は効率のためにブロードキャストの代わりに要請ノードマルチキャストを使用します。類似したアドレスを持つホストのみが各要請ノードグループをリッスンします。

式:ff02::1:ff + ターゲットアドレスの最後の24ビット
 
例:
  2001:db8::10                    -> ff02::1:ff00:10
  2001:db8::a4b2:c3d4:e5f6:7890  -> ff02::1:ff:f6:7890
  fe80::1                         -> ff02::1:ff00:1

これにより、不要な処理が減ります。IPv4では、ARPブロードキャストがネットワーク上のすべてのホストに到達します。IPv6では、アドレスが同じ24ビットで終わるホストのみがマルチキャストグループに参加してNSを受信します。

2. 近隣到達不能検出(NUD)#

以前到達可能だった近隣がまだ到達可能であることを確認します。

プロセス:

  1. ホストが最近近隣からトラフィックを受信していない
  2. ホストが近隣にNS(ユニキャスト)を送信
  3. NAを受信した場合、近隣は到達可能
  4. リトライ後も応答がない場合、近隣は到達不能とみなされる

例:

IPv6 Header:
  Source:2001:db8::1
  Destination:2001:db8::10(近隣へのユニキャスト)
  Hop Limit:255
 
ICMPv6:
  Type:135 (Neighbor Solicitation)
  Target Address:2001:db8::10
  Options:
    Source Link-Layer Address:00:1a:2b:3c:4d:5e

NUDはバックグラウンドで自動的に実行されます。ホストがトラフィックを送信するとき、近隣が応答するかどうかを追跡します。近隣がサイレントになった場合、NUDは死亡と宣言する前に到達可能性を確認します。

3. 重複アドレス検出(DAD)#

IPv6アドレスを使用する前に、ホストはDADを実行して、他のノードがそれを使用していないことを確認します。これにより、SLAACでのアドレス競合が防止されます。

プロセス:

  1. ホストが仮アドレスを生成する(SLAAC、DHCPv6、または手動設定経由)
  2. ホストが送信元::およびターゲット=仮アドレスでNSを送信
  3. 誰かがNAで応答した場合、アドレスはすでに使用中(競合)
  4. タイムアウト後に応答がない場合、アドレスは一意で使用可能

例:

# ホストは2001:db8::a4b2:c3d4:e5f6:7890を使用したい
# 最初にDAD NSを送信
 
IPv6 Header:
  Source:::(未指定アドレス—ホストはまだアドレスがない)
  Destination:ff02::1:ff:f6:7890(要請ノードマルチキャスト)
  Hop Limit:255
 
ICMPv6:
  Type:135 (Neighbor Solicitation)
  Target Address:2001:db8::a4b2:c3d4:e5f6:7890
  Options:(なし—送信元は::)

別のホストがそのアドレスを使用している場合、近隣広告を送信します。要求ホストは競合を検出し、別のアドレスを選択する必要があります。

DADタイムアウト: 通常1秒です。ホストは応答を待つためにこれだけの時間待ちます。サイレントの場合、アドレスは一意であると想定されます。

セキュリティ問題: DADには認証がありません。攻撃者はすべてのDAD要求に応答し、ホストがアドレスを設定するのを防ぐことができます。これはDAD DoS攻撃と呼ばれます。解決策には、SEND(Secure Neighbor Discovery)またはRA Guardが含まれますが、採用は限られています。

Neighbor Advertisement(近隣広告、タイプ136)#

近隣要請への応答として送信されるか、アドレス/リンク層の変更を通知するために未要請で送信されます。

ICMPv6構造:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Type      |     Code      |          Checksum             |
|     (136)     |      (0)      |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|R|S|O|                     Reserved                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                       Target Address                          +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Options ...
+-+-+-+-+-+-+-+-+-+-+-+-

フィールド:

フラグ:

  • R (Router): 送信者はルーター
  • S (Solicited): 広告はNSへの応答
  • O (Override): 既存のキャッシュエントリを上書き

Target Address: この広告が送信されるアドレス

Options: Target Link-Layer Address(MACアドレス)

送信されるとき:

  • 近隣要請への応答(S=1)
  • アドレス変更の未要請通知(S=0)
  • リンク層アドレス変更後の近隣を更新するためのgratuitous NA

宛先:

  • 要請ノードへのユニキャスト(NSへの応答時)
  • ff02::1(all-nodes) 未要請通知用

ホップ制限: 255(必須)

NSへの応答例:

IPv6 Header:
  Source:2001:db8::10
  Destination:2001:db8::1(要求者へのユニキャスト)
  Hop Limit:255
 
ICMPv6:
  Type:136 (Neighbor Advertisement)
  Flags:R=0、S=1(要請された応答)、O=1(上書き)
  Target Address:2001:db8::10
  Options:
    Target Link-Layer Address:00:aa:bb:cc:dd:ee

フラグの意味:

S=1: これはあなたのNSへの応答です。キャッシュを更新してください。

S=0: 未要請通知です。何かを変更しました。

O=1: この情報で既存のキャッシュエントリを上書きします。

O=0: エントリが存在しない場合にのみキャッシュを更新します。

未要請NA例:

ホストがそのMACアドレスを変更します(まれですが、仮想マシンやインターフェースの再設定で発生します)。近隣を更新するために未要請NAを送信します:

IPv6 Header:
  Source:2001:db8::10
  Destination:ff02::1(all-nodes)
  Hop Limit:255
 
ICMPv6:
  Type:136 (Neighbor Advertisement)
  Flags:R=0、S=0(未要請)、O=1(上書き)
  Target Address:2001:db8::10
  Options:
    Target Link-Layer Address:00:ff:ee:dd:cc:bb(新しいMAC)

すべての近隣がこれを受信し、キャッシュを更新します。

Redirect(リダイレクト、タイプ137)#

ルーターは、特定の宛先に対してより良いファーストホップルーターが存在することをホストに通知するためにリダイレクトメッセージを送信します。

ICMPv6構造:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Type      |     Code      |          Checksum             |
|     (137)     |      (0)      |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Reserved                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                       Target Address                          +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                     Destination Address                       +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Options ...
+-+-+-+-+-+-+-+-+-+-+-+-

フィールド:

  • Type: 137
  • Code: 0
  • Target Address: より良い次ホップルーター(またはon-linkの場合は宛先)
  • Destination Address: より良いルートを使用すべき宛先
  • Options: Target Link-Layer Address、Redirected Header(元のパケットの一部)

送信されるとき:

ルーターR1がホストAからホストB宛てのパケットを受信します。R1は、ルーターR2(Aと同じリンク上)がBへのより良い次ホップであることを知っています。R1はパケットをR2に転送し、AND Aにリダイレクトを送信してR2を直接使用するように指示します。

シナリオ例:

ネットワークトポロジ:
  ホストA:2001:db8:1::10
  ルーターR1:2001:db8:1::1(Aのデフォルトゲートウェイ)
  ルーターR2:2001:db8:1::2(2001:db8:2::/64へのより良いルート)
  宛先B:2001:db8:2::20
 
フロー:
1. AがR1経由でBにパケットを送信(デフォルトゲートウェイ)
2. R1はR2が2001:db8:2::/64へのより良い次ホップであることを確認
3. R1はパケットをR2に転送
4. R1がAにリダイレクトを送信:
   Target Address:2001:db8:1::2(R2)
   Destination Address:2001:db8:2::20(B)
5. Aはルーティングテーブルを更新:2001:db8:2::/64にはR2を使用
6. AのBへの将来のパケットはR2に直接行く

R1からAへのリダイレクトメッセージ:

IPv6 Header:
  Source:fe80::1(R1のリンクローカル)
  Destination:2001:db8:1::10(ホストA)
  Hop Limit:255
 
ICMPv6:
  Type:137 (Redirect)
  Target Address:fe80::2(R2—より良い次ホップ)
  Destination Address:2001:db8:2::20(B—R2経由で到達する宛先)
  Options:
    Target Link-Layer Address:00:11:22:33:44:55(R2のMAC)
    Redirected Header:(リダイレクトをトリガーした元のパケットヘッダー)

セキュリティ上の考慮事項:

リダイレクトメッセージは悪用される可能性があります。ローカルリンク上の攻撃者は悪意のあるリダイレクトを送信して以下を行うことができます:

  • トラフィックを攻撃者のマシン経由でルーティングする(中間者攻撃)
  • 存在しないルーターにリダイレクトしてトラフィックをブラックホール化する
  • ルーティングループを作成する

保護:

  • SEND(Secure Neighbor Discovery)がリダイレクトメッセージを認証する
  • 多くのホストはデフォルトゲートウェイルーター以外からのリダイレクトを無視する
  • 一部のセキュリティ意識の高いネットワークはリダイレクト処理を完全に無効にする
  • リダイレクトは現在のファーストホップルーターから来なければならない(ホストによってチェックされる)

リダイレクトを許可すべきか?

ホーム/小規模ネットワーク: 安全です。複数のルーターが存在する場合にルーティングを最適化します。

エンタープライズネットワーク: しばしば無効化されます。制御されたルーティングテーブルと潜在的なセキュリティリスクが利点を上回ります。

データセンター: 通常無効化されます。静的ルーティングまたは動的プロトコル(BGP、OSPF)がルートを管理します。

実際のアドレス解決#

同じリンク上のホストAがホストBにパケットを送信する完全なプロセスをトレースしましょう。

初期状態:

  • ホストA:2001:db8::1(MAC:aa:aa:aa:aa:aa:aa)
  • ホストB:2001:db8::10(MAC:bb:bb:bb:bb:bb:bb)
  • Aの近隣キャッシュは空

ステップ1:アプリケーションが接続を開始

# ホストA上
ping6 2001:db8::10

ステップ2:近隣キャッシュをチェック

# Aは近隣キャッシュをチェック
ip -6 neigh show 2001:db8::10
# (空—エントリなし)

ステップ3:近隣要請を送信

Aは要請ノードマルチキャストアドレスにNSを送信:

IPv6 Header:
  Source:2001:db8::1
  Destination:ff02::1:ff00:10(2001:db8::10の要請ノード)
  Hop Limit:255
 
Ethernet Header:
  Source MAC:aa:aa:aa:aa:aa:aa
  Dest MAC:33:33:ff:00:00:10(ff02::1:ff00:10のマルチキャストMAC)
 
ICMPv6:
  Type:135 (Neighbor Solicitation)
  Target Address:2001:db8::10
  Options:
    Source Link-Layer Address:aa:aa:aa:aa:aa:aa

ステップ4:BがNSを受信

ホストBはff02::1:ff00:10をリッスンしています(そのアドレスが:10で終わるため)。NSを受信して処理します。

ステップ5:Bが近隣広告を送信

IPv6 Header:
  Source:2001:db8::10
  Destination:2001:db8::1(Aへのユニキャスト)
  Hop Limit:255
 
Ethernet Header:
  Source MAC:bb:bb:bb:bb:bb:bb
  Dest MAC:aa:aa:aa:aa:aa:aa
 
ICMPv6:
  Type:136 (Neighbor Advertisement)
  Flags:R=0、S=1(要請された)、O=1(上書き)
  Target Address:2001:db8::10
  Options:
    Target Link-Layer Address:bb:bb:bb:bb:bb:bb

ステップ6:Aが近隣キャッシュを更新

# Aの近隣キャッシュにエントリができた
ip -6 neigh show 2001:db8::10
# 2001:db8::10 dev eth0 lladdr bb:bb:bb:bb:bb:bb REACHABLE

ステップ7:Aが元のパケットを送信

AがBのMACを知っているので、pingパケットを送信します:

IPv6 Header:
  Source:2001:db8::1
  Destination:2001:db8::10
 
Ethernet Header:
  Source MAC:aa:aa:aa:aa:aa:aa
  Dest MAC:bb:bb:bb:bb:bb:bb(NAから学習)
 
ICMPv6:
  Type:128 (Echo Request)

合計時間:ミリ秒。プロセスはアプリケーションには見えません。

近隣キャッシュの状態#

近隣キャッシュエントリは、NUDが到達可能性を追跡するときにいくつかの状態を経ます。

状態意味次のアクション
INCOMPLETENS送信、NAを待機中タイムアウトまたはNAを受信
REACHABLE最近NAを受信、到達可能と確認トラフィックを送信またはタイムアウト
STALEエントリが古い、最近確認されていないトラフィックを送信(プローブをトリガー)
DELAY古いエントリにトラフィックを送信、待機中タイムアウトがプローブをトリガー
PROBE到達可能性を確認するためにNSを送信中NAを受信またはタイムアウト
FAILEDプローブへの応答なしエントリを削除

状態遷移:

INCOMPLETE --NAを受信--> REACHABLE
REACHABLE --タイムアウト--> STALE
STALE --トラフィック送信--> DELAY
DELAY --タイムアウト--> PROBE
PROBE --NAを受信--> REACHABLE
PROBE --タイムアウト--> FAILED

近隣キャッシュをチェック(Linux):

ip -6 neigh show
 
# 出力例:
# 2001:db8::1 dev eth0 lladdr aa:aa:aa:aa:aa:aa REACHABLE
# 2001:db8::10 dev eth0 lladdr bb:bb:bb:bb:bb:bb STALE
# fe80::1 dev eth0 lladdr cc:cc:cc:cc:cc:cc DELAY

タイマー:

  • REACHABLEタイムアウト: 30秒(設定可能、RAのReachable Timeから)
  • DELAYタイムアウト: PROBEに遷移する前の5秒
  • 再送信間隔: 1秒(設定可能、RAのRetrans Timerから)
  • MAX_MULTICAST_SOLICIT: FAILEDと宣言する前の3回の試行

これらにより、死んだ近隣が迅速に検出されると同時に、不要なNUDトラフィックが最小化されます。

SLAAC:アドレス自動設定#

ルーター広告と重複アドレス検出を組み合わせることで、ステートレスアドレス自動設定が作成されます。ホストはDHCPサーバーなしで自己設定します。

完全なSLAACプロセス:

ステップ1:インターフェースが起動

ホストがインターフェースeth0でIPv6を有効にします。

ステップ2:リンクローカルアドレスを生成

fe80:: + インターフェース識別子
fe80::a4b2:c3d4:e5f6:7890(MAC派生IIDを使用する場合)
fe80::1234:5678:9abc:def0(ランダムIIDを使用する場合)

ステップ3:リンクローカルでDADを実行

送信元::でNSを送信してfe80::アドレスが一意であることを確認します。

ステップ4:ルーター要請を送信

IPv6 Header:
  Source:fe80::a4b2:c3d4:e5f6:7890
  Destination:ff02::2
  Hop Limit:255
 
ICMPv6:
  Type:133 (Router Solicitation)

ステップ5:ルーター広告を受信

ICMPv6:
  Type:134 (Router Advertisement)
  Flags:M=0、O=0(SLAAC)
  Prefix Information:
    Prefix:2001:db8:1234:5678::/64
    Flags:A=1(autonomous)
    Valid Lifetime:86400
    Preferred Lifetime:14400

ステップ6:グローバルアドレスを生成

Prefix:2001:db8:1234:5678::/64
IID:a4b2:c3d4:e5f6:7890
結果:2001:db8:1234:5678:a4b2:c3d4:e5f6:7890

ステップ7:グローバルアドレスでDADを実行

NSを送信して2001:db8:1234:5678:a4b2:c3d4:e5f6:7890が一意であることを確認します。

ステップ8:アドレスを設定

ip -6 addr show eth0
 
# 出力:
# inet6 2001:db8:1234:5678:a4b2:c3d4:e5f6:7890/64 scope global dynamic
# inet6 fe80::a4b2:c3d4:e5f6:7890/64 scope link

ステップ9:デフォルトルートを設定

ルーターのリンクローカルアドレスをデフォルトゲートウェイとして使用:

ip -6 route show
 
# 出力:
# default via fe80::1 dev eth0 metric 1024
# 2001:db8:1234:5678::/64 dev eth0 proto kernel metric 256

合計時間: 数秒。

プライバシー拡張(RFC 4941):

MAC派生インターフェースIDはネットワーク間で追跡可能です。プライバシー拡張は定期的に変更されるランダムなIIDを生成します。

元のもの:2001:db8:1234:5678:a4b2:c3d4:e5f6:7890(静的)
プライバシー:2001:db8:1234:5678:1a2b:3c4d:5e6f:7a8b(毎日変更)

ほとんどの最新のOSは、着信接続用に安定したアドレスを保持しながら、発信接続用にデフォルトでプライバシー拡張を有効にします。

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

NDPには脆弱性があります。信頼されたローカルネットワークを想定して設計されたためです。同じリンク上の攻撃者は以下ができます:

不正なルーター広告#

攻撃者が次のような偽のRAを送信します:

  • 間違ったプレフィックス(トラフィックをブラックホールまたは攻撃者経由でルーティング)
  • 短いライフタイム(頻繁なRA処理を強制)
  • M=1フラグ(攻撃者のサーバーへのDHCPv6を強制)

影響: ホスト設定の完全な制御。

緩和策:

  • RA Guard: ルーター以外のポートからのRAをブロックするスイッチ機能
  • SEND(Secure Neighbor Discovery): 暗号化認証(複雑、ほとんど展開されていない)
  • ルーター優先度: 正当なルーターで高優先度値を使用

近隣広告スプーフィング#

攻撃者が別のホストであると主張する偽のNAを送信します。

影響: 中間者攻撃、トラフィック傍受。

緩和策:

  • SEND: NAを認証
  • ポートセキュリティ: スイッチがMACアドレスバインディングを強制
  • 監視: 重複MACアドレスを検出

DAD DoS#

攻撃者がすべてのDAD要求に応答し、アドレス設定を防ぎます。

影響: ホストがアドレスを取得できず、接続なし。

緩和策:

  • SEND: DADメッセージを認証
  • レート制限: 単一の送信元からのNAを制限
  • 静的アドレス: SLAACを完全にバイパス(スケーラブルではない)

リダイレクト攻撃#

攻撃者が偽のリダイレクトを送信してトラフィックを攻撃者経由でルーティングします。

影響: 中間者攻撃、トラフィック傍受。

緩和策:

  • リダイレクトを無効化: 多くのOSがリダイレクト処理の無効化を許可
  • SEND: リダイレクトを認証
  • 送信元を確認: ホストがリダイレクトが現在のファーストホップルーターから来ることを確認すべき

現実: ほとんどのネットワークは複雑さのためSENDを使用しません。スイッチ上のRA Guardがエンタープライズネットワークの実用的な防御です。

NDPの問題のトラブルシューティング#

ホストにグローバルアドレスがない#

症状:

  • fe80::アドレスのみ
  • リンクローカルはpingできるが、グローバルはできない
  • デフォルトルートがない

診断:

# ルーター広告をチェック
sudo tcpdump -i eth0 -vv 'icmp6 && ip6[40] == 134'
 
# RA受け入れをチェック
sysctl net.ipv6.conf.eth0.accept_ra
# ホストの場合は1または2であるべき
 
# 手動でRSを送信
rdisc6 eth0

一般的な原因:

  • リンク上にルーターがない
  • タイプ134をブロックするファイアウォール
  • accept_raが無効化されている
  • IPv6転送が有効化されている(RA処理を無効にする)

修正: ルーターを有効にし、ICMPv6タイプ134を許可し、accept_ra=1に設定します。

近隣キャッシュが常にFAILED#

症状:

  • 近隣に到達できない
  • NSが送信されたがNAが受信されない
  • 近隣キャッシュがFAILEDを表示

診断:

# NS/NA交換を監視
sudo tcpdump -i eth0 -vv 'icmp6 && (ip6[40] == 135 || ip6[40] == 136)'
 
# 近隣キャッシュをチェック
ip -6 neigh show
 
# 手動NS(Linux ndisc6ツール)
ndisc6 2001:db8::10 eth0

一般的な原因:

  • タイプ135/136をブロックするファイアウォール
  • ターゲットホストのIPv6が無効化されている
  • マルチキャストをフィルタリングするスイッチ
  • 間違ったリンク(ターゲットが別のサブネット上)

修正: ファイアウォールを通してNDPを許可し、ターゲット上でIPv6が有効化されていることを確認します。

DAD失敗#

症状:

  • アドレスが「dadfailed」を表示
  • インターフェースがアドレスを設定できない
  • カーネルログがDAD競合を表示

診断:

# アドレス状態をチェック
ip -6 addr show eth0
 
# DAD失敗の出力例:
# inet6 2001:db8::10/64 scope global tentative dadfailed
 
# 重複をチェック
ping6 -c 1 2001:db8::10

一般的な原因:

  • 同じアドレスを使用している別のホスト
  • NAをスプーフィングする攻撃者(DAD DoS)
  • クローンされたMACアドレスを持つ仮想マシン

修正: アドレスを変更し、重複ホストを調査し、VM設定をチェックします。

ツールによる実用的な例#

tcpdumpでNDPを監視#

# すべてのNDPトラフィック
sudo tcpdump -i eth0 -vv 'icmp6 && ip6[40] >= 133 && ip6[40] <= 137'
 
# ルーター広告のみ
sudo tcpdump -i eth0 -vv 'icmp6 && ip6[40] == 134'
 
# アドレス解決(NS/NA)
sudo tcpdump -i eth0 -vv 'icmp6 && (ip6[40] == 135 || ip6[40] == 136)'
 
# ターゲットアドレスでフィルター
sudo tcpdump -i eth0 -vv 'icmp6 && ip6[40] == 135' | grep '2001:db8::10'

手動の近隣キャッシュ管理#

# すべての近隣を表示
ip -6 neigh show
 
# 特定の近隣を表示
ip -6 neigh show 2001:db8::10
 
# エントリを削除(再解決を強制)
sudo ip -6 neigh del 2001:db8::10 dev eth0
 
# 静的エントリを追加
sudo ip -6 neigh add 2001:db8::10 lladdr aa:bb:cc:dd:ee:ff dev eth0

SLAACのテスト#

# アドレスをフラッシュ
sudo ip -6 addr flush dev eth0
 
# IPv6を再有効化
sudo sysctl -w net.ipv6.conf.eth0.disable_ipv6=0
 
# 自動設定を監視
ip -6 addr show eth0
ip -6 route show

関連記事#

  • ICMPv6の説明 - NDPはICMPv6上で実行されます。基礎となるプロトコルを理解します。
  • IPv6アドレスタイプ - NDPで使用されるリンクローカル、要請ノードマルチキャスト、その他のアドレスタイプについて学びます。
  • IPv6セキュリティ - 重要な機能を許可しながら、NDP攻撃に対してセキュアにします。

実際のNDPをテスト

Pingツールを使用してアドレス解決をトリガーし、Tracerouteを使用してホストが次ホップルーターをどのように発見するかを確認します。

よくある質問#

NDPがARPのようにブロードキャストの代わりにマルチキャストを使用するのはなぜですか?

マルチキャストの方が効率的です。ARPブロードキャストはネットワーク上のすべてのホストに到達します—すべてがターゲットでなくてもフレームを処理する必要があります。NDPはターゲットのIPv6アドレスから計算された要請ノードマルチキャストアドレスを使用します。一致するアドレスを持つホストのみがそのマルチキャストグループに参加してパケットを受信します。ホストは一致しないマルチキャストをハードウェア(NIC)でフィルタリングし、CPU負荷を減らします。数千のホストを持つ大規模なネットワークでは、これは大きなパフォーマンスの違いを生みます。

ARPを無効化できるように、NDPを無効化できますか?

いいえ。NDPはIPv6動作に必須です。アドレス解決、ルーター発見、自動設定を処理します。NDPを無効化すると、IPv6が完全に機能しなくなります。静的ARPエントリを使用できるIPv4とは異なり、IPv6はルーター広告(デフォルトゲートウェイとプレフィックスを提供)のためにNDPを必要とします。静的近隣でも、ルーターを学習したりアドレスを自動設定する方法がありません。

重複アドレス検出はどのように競合を防ぎますか?

アドレスを使用する前に、ホストは送信元アドレス::(未指定)およびターゲットを使用したいアドレスに設定して近隣要請を送信します。別のホストがすでにそのアドレスを使用している場合、近隣広告で応答します。要求ホストは応答を確認し、競合を検出し、別のアドレスを選択する必要があります。約1秒以内に応答が到着しない場合、アドレスは一意であると想定されます。DADはリンクローカルアドレスとグローバルアドレスの両方で実行されます。

要請ノードマルチキャストアドレスとは何ですか?

要請ノードマルチキャストアドレスは、式ff02::1:ff:XX:XXXXを使用してIPv6アドレスの最後の24ビットから派生します。すべてのIPv6アドレスは、対応する要請ノードマルチキャストグループに自動的に参加します。アドレス解決を実行するとき、送信者はブロードキャストの代わりに要請ノードアドレスにNSを送信します。同じ24ビットで終わるアドレスを持つホストのみがそれを受信します。これにより、ブロードキャストベースのARPと比較して不要な処理が減ります。

NDPパケットがホップ制限255を持たなければならないのはなぜですか?

セキュリティです。正当なNDPは常にローカルリンク上で発生し、ホップ制限を255に設定します。ルーターは転送時にホップ制限を減らすため、リモート攻撃者からのパケットはホップ制限 < 255で到着します。ホップ制限 != 255のNDPパケットを拒否することで、ホストはオフリンク攻撃者がスプーフィングされたルーター広告、近隣広告、またはリダイレクトを送信することから保護します。この簡単なチェックは、複雑な認証を必要とせずに多くのリモート攻撃を防ぎます。

SEND(Secure Neighbor Discovery)を展開すべきですか?

おそらくそうではありません。SENDは公開鍵暗号化を使用してNDPの暗号化認証を提供し、スプーフィング攻撃を防ぎます。理論的には素晴らしいです。実際には複雑で、PKIインフラストラクチャが必要で、OSサポートが不十分で、アドレス解決などの時間に敏感な操作にレイテンシを追加します。ほとんどのネットワークはよりシンプルな緩和策を使用します:スイッチ上のRA Guard(ルーター以外のポートからのRAをブロック)、不正なRAの監視、物理/リンク層セキュリティです。SENDは、インフラストラクチャと複雑さに投資する意思のある高セキュリティ環境に適しています。