現場でネットワークを運用していると、「新しく立てたVLANからDHCPでIPが降りてこない」系の問い合わせは、定期的に湧いてくる。先日もまさにそれ。深夜のメンテでL3スイッチに新規SVIを切って、VLAN 200を追加。クライアントを繋いだ。IPが、取れない。

こういうときに真っ先に疑うのが ip helper-address の設定漏れ。ただ、本当に厄介なのは「設定してるのに動かない」パターン。今回は、そっちの「動かない」側を現場で3回ぐらい踏み抜いたので、切り分けのフローを自分用にもまとめておく。

Cisco L3スイッチでのip helper-addressによるDHCPリレー構成図
DHCPリレーの全体像。クライアントのブロードキャストをL3スイッチがユニキャストに変換してDHCPサーバーへ中継する

結局どこで詰まるのか

DHCPリレーのトラブルは、ざっくり3ヶ所のどこかで止まる。ここを分けて潰していくのが一番早い。

  • クライアント → L3スイッチ(DiscoverがSVIまで上がってこない)
  • L3スイッチ → DHCPサーバー(ユニキャストで飛ばせていない)
  • DHCPサーバー → クライアント(Offerが戻ってこない/giaddrを見てスコープが選べていない)

ぶっちゃけ、Wiresharkなりミラーポートなりでキャプチャを取るのが一番早い。感覚で切り分けるより、パケットが来てるか来てないか事実で見ることに尽きる。

ip helper-address の基本をざっと振り返る

Cisco IOSでの設定はこんな感じ。クライアント側のSVIに入れるのがポイント。

Switch(config)# interface vlan 200
Switch(config-if)# ip address 192.168.200.1 255.255.255.0
Switch(config-if)# ip helper-address 192.168.100.10
Switch(config-if)# no shutdown

ちなみに ip helper-address は、DHCP(UDP 67/68)だけじゃなく、TFTP(69)、DNS(53)、Time(37)、NetBIOS-NS(137)、NetBIOS-DS(138)、TACACS(49)までまとめて転送する。地味にセキュリティ的に気になるので、必要なければ

Switch(config)# no ip forward-protocol udp tftp
Switch(config)# no ip forward-protocol udp 137
Switch(config)# no ip forward-protocol udp 138

あたりで不要なプロトコルは絞っておくのが個人的な好み。ただ、今回の本題からは逸れるのでここまで。

現場でガッツリ踏んだ3つの落とし穴

1. SVIが up/up になっていない

一番しょうもないけど、一番よくある原因。VLANインターフェースは up/up じゃないと、DHCPの受け口として機能しない。show interfaces vlan 200 で line protocol を見る。

VLAN 200 に所属するアクセスポートが1本も up になっていないと、SVIは落ちる。Trunkで通ってるだけだと up にならない機種もあるので、ここは必ず目視確認。ダミーで1ポートだけshutdown解除して検証、というのは自分もよくやる。

2. helper-address を物理IFに入れてしまう

以前、客先でこのエラーに遭遇したとき、原因が「ルーティング先の物理インターフェースに ip helper-address を入れていた」だったことがある。これは動かない。

helper-addressは、クライアントからブロードキャストを受け取る側のインターフェース、つまりSVIに入れないといけない。経験が浅いと普通にやるミス。自分も新人のときやって、先輩に苦笑いされた記憶がある。

3. DHCPサーバー側のスコープが giaddr にマッチしない

これ、現場で一番時間を溶かしたパターン。Windows Server の DHCP や Infoblox の場合、パケットの giaddr(Gateway IP Address)に入っているIPに該当するスコープがないと、Offerを返してくれない。

L3スイッチからは正しくユニキャストで飛んでる。サーバーにもパケットは届いてる。なのに戻ってこない。キャプチャ見ると「Server側が黙ってる」状態。調べると、サーバー側に 192.168.200.0/24 のスコープがまだ作られていなかった。

正直、ネットワーク側は完璧だったのに詰まる典型パターン。SEチーム間の連携ミスあるある、という感じ。

切り分け用のコマンド集

L3スイッチでリレーが動いているかを見るには、debug ip dhcp server packet が定番。

Switch# debug ip dhcp server packet
*Apr 10 03:12:45.231: DHCPD: DHCPDISCOVER received from client 0180.c200.0001 on interface Vlan200.
*Apr 10 03:12:45.232: DHCPD: setting giaddr to 192.168.200.1.
*Apr 10 03:12:45.233: DHCPD: forwarding BOOTREQUEST to server 192.168.100.10.

ここまで出ていれば、L3スイッチからサーバーへの送信は成立している。戻りがない場合は、サーバー側 or サーバーまでのルーティングを疑う。ping 192.168.100.10 source Vlan200 で、SVIのIPからサーバーまで到達できるか確認するのが手早い。

下流側(クライアント起点)を見るなら debug ip udp を併用することもある。ただ、出力が多いので本番環境では叩くタイミングを選びたい。

Catalyst 9300系だと、バージョン次第で debug出力のフォーマットが微妙に違う。2025年のIOS XE 17.15系で確認したときは、上記とほぼ同じ形式で出力された。旧IOSだと少し表記が違うので、出てこないからといって焦らない方がいい。

option 82 を使っている場合の追加確認

Relay Agent Information(RFC 3046、いわゆるoption 82)を付与している環境では、話がもう一段ややこしくなる。サーバー側でoption 82ベースの認証やIP割り当てポリシーを組んでいる場合、付与の有無や値の整合性でハマる。

具体的には、ip dhcp relay information trust-all が必要になるケースがある。

Switch(config)# ip dhcp relay information trust-all
Switch# show ip dhcp relay information trusted
List of trusted interfaces:
Vlan200

この辺りは環境差が大きいので、サーバー担当者と一緒にパケット見ながら詰めるのが現実的。

余談:毎回「サーバー側のせい」になる理由

正直なところ、DHCPリレーのトラブルシュートって、ネットワーク側の設定が正しければ正しいほど「DHCPサーバー側の問題」に落ちやすい。で、サーバー担当者には「設定入ってます」で押し切られがち。

こういうとき、L3スイッチの debug ログとキャプチャを添えて「giaddr=192.168.200.1 でDiscover送ってるのに、サーバーからOfferが返ってきてない」と事実ベースで説明すると話が早い。証拠があると強い。

まとめ

  • ip helper-address は必ずクライアント側のSVIに入れる
  • SVIが up/up か、VLANに所属するアクセスポートが1本以上 up か確認
  • L3スイッチからDHCPサーバーまでユニキャスト到達性を ping ... source で確認
  • サーバー側に giaddr と一致するスコープがあるかチェック(意外な盲点)
  • 行き詰まったら debug ip dhcp server packet で事実確認

より詳しい仕様は Cisco 公式の IP Addressing: DHCP Configuration Guide に書かれている。option 82周りの挙動は RFC 3046 を当たるのが確実。

この記事はCatalyst系での事例ベースなので、別メーカー(特にArista、Juniper)だと挙動が違う部分もあると思う。確認が取れたら追記するつもり。次はFortiGateをリレーにしたときの注意点もまとめたい。