Edited at

DHCPで静的経路の配布 (Classless Static Routes)

DHCPでClassless Static Routes option (option 121)を使って静的経路情報をDHCPクライアントに配布すると,Router option (option 3)が無視されてしまいハマったのでその対策の備忘録.

この記事の環境


  • DHCP クライアント: Ubuntu 16.04

  • DHCP サーバ: CISCO IOS 15.6.3M2(ED) (CISCO1921), isc-dhcpd, dnsmasq


そもそもClassless Static Routes option (option 121)とは

DHCPサーバからDHCPクライアントに対し,静的ルートを配布できるDHCPの機能.デフォルトゲートウェイのルータに静的経路が入っていれば通常問題ないが,たまにこれがあると便利な時がある.自分が経験したのは下記2つのケース.


  • ケース1: VPNのトンネル終端点がデフォルトゲートウェイとは違うIPアドレスかつ同じサブネットで動作している場合.

  • ケース2: マルチホーム環境下で,通常のトラヒックはeth0でいいけど,一部の宛先だけ,eth1から特定のゲートウェイを通して通信したい場合.

ちなみに,普通のブロードバンドルータでは見かけないが,本来DHCPはデフォルトゲートウェイ(Router option)やDNS(Name Server option)だけでなく,NTPサーバ(NTP Servers option)やドメイン名(Domain Name option)等かなり沢山の項目を配布できる.ちゃんと設定すると結構便利だったりする.オプションの一覧は,@ITのDHCPオプション一覧IANAのDHCPのページを参照されたい.


クライアントの挙動

RFC 3442によれば,Classless Static Routes optionとRouter optionが同時に配布された場合,Router optionを無視することと明記されている.


If the DHCP server returns both a Classless Static Routes option and

a Router option, the DHCP client MUST ignore the Router option.


しかし,Windows 7やMacOSX El CapitanではRouter optionは無視されない.Ubuntu 16.04では正しく無視された.

追記.AndroidもUbuntu 16.04同様にRouter optionを無視するようです1


Ubuntu 16.04の挙動をRFCに反した挙動にさせるには

/sbin/dhclient-scriptあたりのファイルを改変すれば良いと思われる.$new_rfc3442_classless_static_routesがあれば,デフォルトゲートウェイ追加の処理がスキップされるようになっている.


isc-dhcp-clientでの実装

また,/etc/dhclient/dhclient-exit-hooks.d/rfc3442-classless-routesにClassless Static Routes optionを処理する実装が書かれている.とても単純な動作になっているので読んでみると面白い.


古いWindows

Windows 7ではoption 121でClassless Static Routes optionが適用されるが,古いWindowsでは,option 249での指定が必要.今の御時世で249が必要になることはほとんどないと思われる.


サーバの設定

Classless Static Routes optionでデフォルトゲートウェイを配布する方法も含めて設定を例示する.

前述の通り,クライアントでは,Classless Static Routes option指定時にRouter optionによるデフォルトゲートウェイの指定が無視されてしまうため,Classless Static Routes optionでデフォルトゲートウェイを指定する.


isc-dhcpd

dhcpd.confに下記の様に記載.サブネットマスクを先頭において,サブネットを表現する. 192.168.30.0/24のゲートウェイが192.168.1.1のときは,24, 192,168,30, 192,168,1,1となる.サブネットマスクの値に応じてオクテット単位で省略する.

option rfc3442-classless-static-routes code 121 = array of integer 8;

option rfc3442-classless-static-routes 24, 192,168,30, 192,168,1,254, 0, 192,168,1,1;


dnsmasq

dnsmasq.confに下記の様に記載.こっちはわかりやすい.

dhcp-option=121,192.168.1.0/24,1.2.3.4,10.0.0.0/8,5.6.7.8


CISCO IOS

0.0.0.0/0 192.168.1.1192.168.30.0/24 192.168.1.254を設定する例.サブネットマスクを先頭に持ってくる書き方はdhcpd.confと同様.更に,オクテット単位で,hexに変換してコンフィグを投入する.ip表記も可能だが,0.0.0.0を受け付けないため,デフォルトゲートウェイが投入できない.

ip dhcp pool SAMPLE

network 192.168.1.0 255.255.255.0
dns-server 192.168.1.1 8.8.8.8
! option 121 ip 0.0.0.0 192.168.1.1 24.192.168.30 192.168.1.254
! ip指定だとデフォルトゲートウェイが設定できない
option 121 hex 00:c0:a8:01:01:18:c0:a8:1e:c0:a8:01:fe

00:c0:a8:01:010 192.168.1.1に相当し,18:c0:a8:1e:c0:a8:01:fe24 192.168.30 192.168.1.254に相当している.変換が面倒なときは,hexrouteという便利なツールを使えば良い.ただし,こちらも0.0.0.0/0を処理できない…


参考





  1. Wifi connects but will not transmit data when DHCP info contains CLASSLESS STATIC ROUTE Information [36920068] - Visible to Public - Issue Tracker https://issuetracker.google.com/issues/36920068