# DHCP UDPを使うプロトコルのもうひとつとして、DHCPを見ていきましょう。 DHCPは、私たちがネットワークにPCやスマートフォンを接続する際に、IPアドレスを自動的に割り当てるためのプロトコルです。こちらもUDPが使われています。 なかなか興味深い作りになっていますので、各部の役割を見ていきましょう。 ## DHCPの基本 DHCPは、Dynamic Host Configuration Protocolの略で、ネットワーク上のデバイスにIPアドレスやその他の設定情報を自動的に割り当てるためのプロトコルです。以下のような構成要素があります。 - DHCPサーバ: DHCPに基づいてIPアドレスの割り当てを管理するサーバー。 - DHCPクライアント: 私たちの手元にある、コンピューターやスマートフォン、ゲーム機やタブレットなど対応している機器。 ```{mermaid} sequenceDiagram participant Client as DHCPクライアント participant Server as DHCPサーバ Client->>Server: DHCP Discover Server-->>Client: DHCP Offer Client->>Server: DHCP Request Server-->>Client: DHCP Acknowledgment ``` DHCPでの基本的な動きは、上記のグラフの通りです。 - 大雑把に『2往復』で行っています。 - 1往復目で『DHCPサーバーの検出』と『IPアドレスの取得』を行います。 - 2往復目で『IPアドレスの選択』と『利用確認・関連情報の取得』を行います。 ### 1往復目: DHCPサーバーの検出とIPアドレスの取得 最初の段階では、DHCPクライアントとなるコンピューターなどは以下のような状況です。 - ネットワークに接続されているが、IPアドレスが割り当てられていない。 - 無線LANであれば、SSIDに接続しているが、IPアドレスが取得できていない状態。 - DHCPサーバーの存在はわからない。 このため、まずはネットワーク上にあるDHCPサーバーを検出する必要があります。 IPでの通信はできない状態ですが、データリンクは確立しているため、MACアドレスを使った通信は可能です。 ```{mermaid} sequenceDiagram participant Client as DHCPクライアント participant Server as DHCPサーバ Client->>Server: DHCP Discover Server-->>Client: DHCP Offer ``` そこで、以下の構造のIPおよびUDPパケットを作成します。 - イーサネットフレームヘッダ - 宛先MACアドレス: **ブロードキャストアドレス(FF:FF:FF:FF:FF:FF)** - 送信元MACアドレス: 自身のMACアドレス --(1) - IPアドレスを以下に設定する - 送信元IPアドレス: 自身のIPアドレスが未確定なので、0.0.0.0 - 宛先IPアドレス: ブロードキャストアドレス(255.255.255.255) - UDPヘッダを以下に設定する - 送信元ポート: 68(DHCPクライアントのポート) - 宛先ポート: 67(DHCPサーバのポート) - UDPペイロードにDHCP Discover仕様のメッセージ このパケットをネットワークに出すと、ブロードキャスト宛のためデータリンクの範囲内にDHCPサーバーがあればこのパケットを受信します(ブロードキャスト送信のため、全コンピュータに届く)。 DHCPサーバーは、受信したDHCP Discoverメッセージに対して、以下のようなDHCP Offerメッセージを返します。 - イーサネットフレームヘッダ - 宛先MACアドレス: DHCPクライアントのMACアドレス --(1) - 送信元MACアドレス: DHCPサーバーのMACアドレス --(2) - IPアドレスを以下に設定する - 送信元IPアドレス: DHCPサーバーのIPアドレス --(3) - 宛先IPアドレス: DHCPクライアントのIPアドレスが未確定なので、0.0.0.0 - UDPヘッダを以下に設定する - 送信元ポート: 67(DHCPサーバのポート) - 宛先ポート: 68(DHCPクライアントのポート) - UDPペイロードにDHCP Offer仕様のメッセージ このDHCP Offerメッセージには、DHCPサーバーが提案するIPアドレスやその他の設定情報が含まれています。 DHCPクライアントは、このDHCP Offerメッセージを受信し、提案されたIPアドレスを検討します。 ```{note} - DHCPサーバーは、もしかすると同一ネットワークに複数存在する可能性があります - よって、DHCPクライアント(DISCOVERを出したもの)は、複数のDHCPサーバーからのOfferを受け取ることがあります。 - その場合、DHCPクライアントは最初に受け取ったOfferを選択することが一般的ですが、どれでも選択できるということになります。そのため決定するのではなく候補の提供という話になっています(そのためOfferと呼ばれます)。 ``` ### 2往復目: IPアドレスの選択と利用確認・関連情報の取得 DHCPクライアントは、受け取ったDHCP Offerメッセージの中から、最適なIPアドレスを選択します。 選択したIPアドレスをDHCPサーバーに通知するために、以下のようなDHCP Requestメッセージを送信します。 ```{mermaid} sequenceDiagram participant Client as DHCPクライアント participant Server as DHCPサーバ Client->>Server: DHCP Request Server-->>Client: DHCP Acknowledgment ``` このDHCP Requestメッセージは、選択したIPアドレスをDHCPサーバーに通知するためのものです。 以下の構造のパケットを作成して送信します。 - イーサネットフレームヘッダ - 宛先MACアドレス: DHCPサーバーのMACアドレス --(2) - 送信元MACアドレス: DHCPクライアントのMACアドレス --(1) - IPアドレスを以下に設定する - 送信元IPアドレス: DHCPクライアントのIPアドレスが未確定なので、0.0.0.0 - 宛先IPアドレス: DHCPサーバーのIPアドレス --(3) - UDPヘッダを以下に設定する - 送信元ポート: 68(DHCPクライアントのポート) - 宛先ポート: 67(DHCPサーバのポート) - UDPペイロードにDHCP Request仕様のメッセージ このDHCP Requestメッセージには、選択したIPアドレスやその他の設定情報が含まれています。 DHCPサーバーは、受信したDHCP Requestメッセージに対して、以下のようなDHCP Acknowledgmentメッセージを作成し、返送します。 - イーサネットフレームヘッダ - 宛先MACアドレス: DHCPクライアントのMACアドレス --(1) - 送信元MACアドレス: DHCPサーバーのMACアドレス --(2) - IPアドレスを以下に設定する - 送信元IPアドレス: DHCPサーバーのIPアドレス --(3) - 宛先IPアドレス: DHCPクライアントのIPアドレスが確定したらそのIPアドレス - UDPヘッダを以下に設定する - 送信元ポート: 67(DHCPサーバのポート) - 宛先ポート: 68(DHCPクライアントのポート) - UDPペイロードにDHCP Acknowledgment仕様のメッセージ このDHCP Acknowledgmentメッセージには、DHCPサーバーが選択したIPアドレスやその他の設定情報が含まれています。 メッセージ中に含まれる主な情報としては、以下のものが該当します。 - IPアドレス: DHCPサーバーが割り当てるIPアドレス。 - サブネットマスク: ネットワークのサブネットマスク。 - デフォルトゲートウェイ: ネットワークのデフォルトゲートウェイのIPアドレス。 - DNSサーバー: ネットワークで使用するDNSサーバーのIPアドレス。 - **リース期間: DHCPサーバーが割り当てるIPアドレスのリース期間。** クライアント側は、これらの情報を利用してIPの構成を行って通信が可能となります。 なお、なんらかの理由でDHCPサーバーがDHCP Acknowledgmentメッセージを送信できない場合は、DHCP NACK(Negative Acknowledgment)メッセージが送信されることがあります。 この場合、クライアントの取りうる可能性としては以下の2つが考えられます。 - 他にOfferが来ていたアドレスを利用するため、別のDHCPサーバーに対してDHCP Requestを送信する。 - 少し待ってから再度DHCP Discoverを送信し、DHCPサーバーを再検出する。 ## DHCPサーバーは何をしているのか DHCPサーバー側は、事前の準備として、サーバー(むしろネットワークの)管理者が、**アドレスプール**というものを用意します。 これは、DHCPサーバーがクライアントに対して割り当てることができるIPアドレスの範囲を定義したものです。 そしてDHCPサーバーは起動して待機状態に入り、クライアントからのDHCP Discoverメッセージを受信するのを待ちます。 DHCP Discoverメッセージを受信すると、DHCPサーバーは以下のような処理を行います。 1. **アドレスプールから利用可能なIPアドレスを選択**: DHCPサーバーは、アドレスプールから利用可能なIPアドレスを選択します。 2. **DHCP Offerメッセージの作成**: 選択したIPアドレスやその他の設定情報を含むDHCP Offerメッセージを作成します。 3. **DHCP Offerメッセージの送信**: DHCPサーバーは、DHCPクライアントに対してDHCP Offerメッセージを送信します。 その後、DHCPサーバーはDHCP Requestメッセージを受信するのを待ちます。 DHCP Requestメッセージを受信すると、DHCPサーバーは以下のような処理を行います。 1. **リース期間の確認**: DHCPサーバーは、DHCPクライアントが要求したIPアドレスのリース期間を確認します。 2. **DHCP Acknowledgmentメッセージの作成**: リース期間やその他の設定情報を含むDHCP Acknowledgmentメッセージを作成します。 3. **DHCP Acknowledgmentメッセージの送信**: DHCPサーバーは、DHCPクライアントに対してDHCP Acknowledgmentメッセージを送信します。 この時点で、DHCPサーバー側では、配布したIPアドレスを使用中とし、リース期間の記録を付けておきます。 ## リース期間 据え置きではないコンピューターやスマートフォンでは、IPアドレスを長期間使用し続けることはありません。そのうちどこかへ行ってしまうため、IPアドレスを固定的に割り当てても使われないことが発生します。 そのため、DHCPでアドレスを配布する際に、**リース期間**という概念が導入されています。 リース期間は、DHCPサーバーがクライアントに割り当てるIPアドレスの使用期間を定義します。 リース期間については、以下の考え方で取り扱いが行われています。 - **リース期間の開始**: DHCP Acknowledgmentメッセージが送信された時点で、リース期間が開始されます。 - **リース期間の更新**: クライアントは、リース期間の半分が経過した時点で、DHCPサーバーに対してリース期間の更新を要求することができます。これにより、IPアドレスを引き続き使用することができます。 - **リース期間の終了**: リース期間が終了すると、DHCPサーバーはそのIPアドレスを再利用可能な状態に戻します。クライアントは、リース期間が終了する前にDHCPサーバーに対してDHCP Requestメッセージを送信し、リース期間の更新を要求することができます。 なお、DHCPサーバー側では、とりあえず貸出時間に相当する『ソフトリミット』と上限となる『ハードリミット』を用意して、DHCP Acknowledgment時にソフトリミットを送付していることがあります。 その後、延長要求が来たらリース期間の延長を行っていき、最終的にハードリミットに達した場合は延長禁止とし、IPアドレスを再利用可能な状態に戻します。 なお、リース期間内にDHCPクライアントがネットワークから切断される場合、いくつかのケースが考えられます。 - **正常な切断**: クライアントがネットワークから切断される前に、DHCPサーバーに対してDHCP Releaseメッセージを送信することがあります。これにより、DHCPサーバーはそのIPアドレスを再利用可能な状態に戻します。 - **異常な切断**: クライアントがネットワークから異常に切断された場合、DHCPサーバーはリース期間の終了を待つ必要があります。リース期間が終了すると、DHCPサーバーはそのIPアドレスを再利用可能な状態に戻します。現実としては非常に多く、モバイルデバイスを持って部屋から出て行くなど、ネットワーク圏外に出てしまえばこちらに該当します。 ## 再要求について リース期間が切れたり、既に一度接続しているネットワークの場合、Discover/Offerのやり取りを行わずに、DHCP Request/Acknowledgmentのやり取りを行うことがあります。 ```{mermaid} sequenceDiagram participant Client as DHCPクライアント participant Server as DHCPサーバ Client->>Server: DHCP Request Server-->>Client: DHCP Acknowledgment ``` これは、クライアントが以前にDHCPサーバーから割り当てられたIPアドレスを再利用するための手続きです。 リクエストの際、以前使っていたIPアドレスを含めて送出することになります。 DHCPサーバーは、過去に割り当てを行ったときのMACアドレスの情報を保持しているため、可能(既に他のホストに割り当てているなどの状況になっていない)であれば、以前のIPアドレスを再度割り当てることができます。 ## DHCPサーバーの連携 DHCPサーバーは、ネットワーク上に複数存在することがあります。 これらのサーバーは、以下のような方法で連携して動作することがあります。 - **DHCPリレーエージェント**: DHCPリレーエージェントは、DHCP Discoverメッセージを受信し、適切なDHCPサーバーに転送する役割を果たします。これにより、DHCPクライアントが異なるサブネットに存在する場合でも、DHCPサーバーからIPアドレスを取得できるようになります。 - **DHCPサーバーの冗長化**: 複数のDHCPサーバーが同じアドレスプールを共有し、冗長化を実現することがあります。これにより、1つのDHCPサーバーがダウンしても、他のサーバーがIPアドレスの割り当てを継続できます。 - **DHCPサーバーの同期**: 複数のDHCPサーバーが同じアドレスプールを共有する場合、サーバー間でアドレスプールの状態を同期することがあります。これにより、同じIPアドレスが複数のクライアントに割り当てられることを防ぎます。 - この部分は、リレーエージェントを用いた上下関係で構築することで一元化して対応することもあります。 - DHCPリレーエージェントが外見としてDHCPサーバーのようにふるまうことになります。 ```{mermaid} sequenceDiagram participant Client as DHCPクライアント participant Relay as DHCPリレーエージェント participant Server as DHCPサーバ Client->>Relay: DHCP Request Relay->>Server: アドレスの要求(クライアントのMACアドレスベース) Server->>Server: アドレスプールの更新 Server->>Relay: アドレスの送信 Relay-->>Client: DHCP Acknowledgment ``` ## MACアドレスランダム化との弊害 最近のコンピューターやスマートフォンでは、MACアドレスのランダム化というものを使用する場合があります。 これは、プライバシー保護のために、ネットワーク上でのトラッキングを防ぐ目的で導入されています。 目的としてはいいかもしれませんが、DHCPにおいては問題となる場合があります。 もしランダム化されたMACアドレスを使っている状態でネットワークに接続し、DHCPによる自動設定を行う場合、以下の状況が発生します。 - `DHCP Discover`メッセージを送信する際、ランダム化されたMACアドレスを使用することになります。 - DHCPサーバーは、ランダム化されたMACアドレスを持つクライアントに対してIPアドレスを割り当てます。 - しかし、次回ネットワークに接続する際に、同じMACアドレスを使用しない場合、DHCPサーバーは以前の割り当て情報を持っていないため、新しいIPアドレスを割り当てることになります。 いわば『使い捨てられた』アドレスの情報がDHCPサーバー側に大量に残る可能性があります。 これは想定以上に早くアドレスプールを使い切ってしまう可能性があります。 もちろん使われなくなったIPアドレスとMACアドレスのセットはそのうち破棄されて、プールに戻っているIPアドレスの再割り当ては可能ですが、ランダム化されたMACアドレスを使用することで、DHCPサーバーの管理が複雑になる可能性があります。 そのため、企業での端末利用においては、MACアドレスのランダム化を無効にすることが推奨される場合があります。