オルタナティブ・ブログ > プログラマー社長のブログ >

プログラミングでメシが食えるか!?

ISCのDHCPサーバで固定IP払い出しを行う際の注意

»

よく使われているISCのDHCPサーバの動きを見ていて、今さらながら気がついたことを備忘録も兼ねて書いておきます。
DHCPでは開いているIPアドレスを端末に割り当てるという運用が多いのですが、毎回固定で割り当てたい機器もあります。一般的にはMACアドレスに対して割り当てるIPアドレスを定義する方法をよく使います(他にもいろいろな定義方法はあります)。この場合、ISCの設定ファイルではhostを記述することになります。

subnet 192.168.33.0 netmask 255.255.255.0 {
range 192.168.33.10 192.168.33.20;
max-lease-time 7200;
default-lease-time 3600;
option routers 192.168.33.254;
host some-fix-host {
hardware ethernet 02:00:00:00:00:00;
fixed-address 192.168.33.10;
}
}

この状態でMACアドレス02:00:00:00:00:00でリクエストしてみると以下のようになります。

daemon.info: dhcpd: DHCPDISCOVER from 02:00:00:00:00:00 via 192.168.33.212
daemon.info: dhcpd: DHCPOFFER on 192.168.33.10 to 02:00:00:00:00:00 via 192.168.33.212
daemon.err: dhcpd: Dynamic and static leases present for 192.168.33.10.
daemon.err: dhcpd: Remove host declaration some-fix-host or remove 192.168.33.10
daemon.err: dhcpd: from the dynamic address pool for 192.168.33.0/24
daemon.info: dhcpd: DHCPREQUEST for 192.168.33.10 (192.168.33.211) from 02:00:00:00:00:00 via 192.168.33.212
daemon.info: dhcpd: DHCPACK on 192.168.33.10 to 02:00:00:00:00:00 via 192.168.33.212
daemon.info: dhcpd: DHCPRELEASE of 192.168.33.11 from 02:00:00:00:00:00 via eth3 (not found)

予定通り192.168.33.10が払い出されましたが、


Dynamic and static leases present for 192.168.33.10.
Remove host declaration some-fix-host or remove 192.168.33.10
from the dynamic address pool for 192.168.33.0/24

こんなエラーが出ています。「range 192.168.0.10 192.168.0.20とhostの192.168.0.10があるので、どちらかを消せ」という感じです。

とりあえず、このまま続けてみましょう。なお、動的に割り当てた場合はdhcpd.leasesに記録されるのですが、固定割り当ての場合はdhcpd.leasesには記録されず、上記の割り当ては記録されません。

さて、上の流れでは最後にDHCPRELEASEで開放しています。この状態で別のMACアドレス02:00:00:00:00:01から要求してみましょう。

daemon.info: dhcpd: DHCPDISCOVER from 02:00:00:00:00:01 via 192.168.33.212
daemon.info: dhcpd: DHCPOFFER on 192.168.33.10 to 02:00:00:00:00:01 via 192.168.33.212
daemon.info: dhcpd: DHCPREQUEST for 192.168.33.10 (192.168.33.211) from 02:00:00:00:00:01 via 192.168.33.212
daemon.info: dhcpd: DHCPACK on 192.168.33.10 to 02:00:00:00:00:01 via 192.168.33.212
daemon.info: dhcpd: DHCPRELEASE of 192.168.33.11 from 02:00:00:00:00:01 via eth3 (not found)

なんと、192.168.33.10が割り当てられてしまっています!
このとき、dhcpd.leasesには以下のように記録されます。

lease 192.168.33.10 {
starts 3 2016/08/10 07:24:27;
ends 3 2016/08/10 08:24:27;
cltt 3 2016/08/10 07:24:27;
binding state active;
next binding state free;
hardware ethernet 02:00:00:00:00:01;
uid "\001\002\000\000\000\000\001";
}

次に、02:00:00:00:00:01で192.168.33.10を借りたままにしてみましょう。

daemon.info: dhcpd: DHCPDISCOVER from 02:00:00:00:00:01 via 192.168.33.212
daemon.info: dhcpd: DHCPOFFER on 192.168.33.10 to 02:00:00:00:00:01 via 192.168.33.212
daemon.info: dhcpd: DHCPREQUEST for 192.168.33.10 (192.168.33.211) from 02:00:00:00:00:01 via 192.168.33.212
daemon.info: dhcpd: DHCPACK on 192.168.33.10 to 02:00:00:00:00:01 via 192.168.33.212

このとき、dhcpd.leasesには以下のようにbinding state activeで記録され、貸し出し中となります。

lease 192.168.33.10 {
starts 3 2016/08/10 07:27:21;
ends 3 2016/08/10 08:27:21;
cltt 3 2016/08/10 07:27:21;
binding state active;
next binding state free;
hardware ethernet 02:00:00:00:00:01;
uid "\001\002\000\000\000\000\001";
}

この状態で、02:00:00:00:00:00から要求してみると、

daemon.info: dhcpd: DHCPDISCOVER from 02:00:00:00:00:00 via 192.168.33.212
daemon.info: dhcpd: DHCPOFFER on 192.168.33.10 to 02:00:00:00:00:00 via 192.168.33.212
daemon.info: dhcpd: DHCPREQUEST for 192.168.33.10 (192.168.33.211) from 02:00:00:00:00:00 via 192.168.33.212
daemon.info: dhcpd: DHCPACK on 192.168.33.10 to 02:00:00:00:00:00 via 192.168.33.212

192.168.33.10が応答されてしまいます。IPアドレスの重複が発生してしまいます。
このとき、dhcpd.leasesには何も記録されません。
さらに、02:00:00:00:00:00が192.168.33.10を開放していない状態のまま、02:00:00:00:00:01で要求すると、

daemon.info: dhcpd: DHCPDISCOVER from 02:00:00:00:00:01 via 192.168.33.212
daemon.info: dhcpd: DHCPOFFER on 192.168.33.10 to 02:00:00:00:00:01 via 192.168.33.212
daemon.info: dhcpd: DHCPREQUEST for 192.168.33.10 (192.168.33.211) from 02:00:00:00:00:01 via 192.168.33.212
daemon.info: dhcpd: DHCPACK on 192.168.33.10 to 02:00:00:00:00:01 via 192.168.33.212

やはり、192.168.33.10が払い出されてしまい、dhcpd.leasesにも追記されます。

lease 192.168.33.10 {
starts 3 2016/08/10 07:29:35;
ends 3 2016/08/10 08:29:35;
cltt 3 2016/08/10 07:29:35;
binding state active;
next binding state free;
hardware ethernet 02:00:00:00:00:01;
uid "\001\002\000\000\000\000\001";
}

要するに、最初にエラーが出たとおり、この記述では正しい動きにならないのです。DHCPサービス起動時にエラーを出してくれればまだ分かりやすいと思いますが、リクエストが来たときにエラーが出るのでは実にわかりにくいですね。

正しくは、以下のようにrangeとhostで同じIPアドレスは使わないようにしなければならないようです。

subnet 192.168.33.0 netmask 255.255.255.0 {
range 192.168.33.11 192.168.33.20;
max-lease-time 7200;
default-lease-time 3600;
option routers 192.168.33.254;
host some-fix-host {
hardware ethernet 02:00:00:00:00:00;
fixed-address 192.168.33.10;
}
}

こうすれば実現したい動きになります。
とはいえ、この記述はやや使いにくいですね。複数の固定IPアドレスが連続していないとrangeを細かく分けて記述しなければなりません。また、hardware ethernet FF:FF:FF:FF:FF:FF;としてあるIPアドレスを払い出さなくするような使い方も、rangeを調整しなければならないので、それなら最初からrangeを歯抜けにすることになるでしょう。

実は、ISCのDHCPサーバを使っていて、「固定IPアドレス定義しているのに他の端末に払い出されてしまう」という現象で困っているというのは、ProDHCPの商談をしていてかなり耳にしていました。あまり詳しく現象を教わったりしなかったので「そんなものかな?」と思ってはいたのですが、おそらくこの記述の問題だったのでしょう。
なお、ProDHCPではrangeとhostで同じIPアドレスが存在しても問題なく、hostが優先されます。あるIPアドレスを一時的に封鎖したい場合も、hardware ethernet FF:FF:FF:FF:FF:FF;でhost定義を作って簡単に対応できます。もともとそれが当然だろうと開発当初から思い込んでいましたが、実はISCと異なる仕様だったということを最近気がついたのでした。開発当初はむしろ、払い出し対象はrangeでの指定が絶対に必要で、hostで使うものもrangeに書いてあるのが前提、と思っていたくらいだったのですが、それはかなり早い段階で「rangeがなくてもhostを書けばそれだけで固定払い出しはできるよ」と言われて対応していたくらいでした。

ISCのDHCPサーバを運用する場合は十分注意して下さい。

なお、固定IP払い出しに関してはdhcpd.leasesに記録されないというのも気をつける必要があります。ようするに、ISCのDHCPサーバでは、固定IP払い出しの場合はリース状態を全く管理していないということになります。そもそもISCのDHCPサーバはリース時間が満了してもRELEASEのログは出力されません。ログ出力に関してもProDHCPは回線事業者のユーザの皆様から「犯罪調査にも使われるので、リース状態の変化は完璧にログに出すように」と言われてきましたので、払い出し時間満了時はもちろん、設定変更反映時など、ログは必ず出るようになっています。

Comment(0)