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.1
と192.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:01
が0 192.168.1.1
に相当し,18:c0:a8:1e:c0:a8:01:fe
が24 192.168.30 192.168.1.254
に相当している.変換が面倒なときは,hexrouteという便利なツールを使えば良い.ただし,こちらも0.0.0.0/0
を処理できない…
参考
- https://askubuntu.com/questions/767002/dhcp-connection-does-not-set-default-gateway-automatically
- https://packages.ubuntu.com/xenial/isc-dhcp-client
- http://www.hits-net.com/blog/?p=2963
- http://www.atmarkit.co.jp/fnetwork/netcom/netcom06/option.html
- https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml#options
- https://tools.ietf.org/html/rfc3442
-
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 ↩