kilin> how to> dhcp

CentOS DHCPサーバー

(2010.7.23-2016.12.7)

DHCPサーバーをたてる。冗長構成する方法もメモしておきます。
(環境) CentOS 6.5 64bit, CentOS 7.2 64bit, CentOS 5.5についてはこちら

dhcpのインストール

rootで(以下プロンプトが#ならroot,$なら普通のユーザー),
# yum install dhcp
インストールされるのはISC dhcp。2台で運用してどちらかが停止してもDHCPサービスが止まらないフェイルオーバー機能があり,冗長構成が可能。

ネットワークカード(NIC)の指定

ネットワークカード(NIC)が2枚以上あるときは,どちらを使うのか,使うほうのニックネーム(eth0, eth1, em1, em2などifconfigで表示される名前)をdhcpの起動引数に指定する。
# vi /etc/sysconfig/dhcpd

# Command line options here
DHCPDARGS="eth0"

dhcp設定ファイルの変更と起動

サンプル設定ファイルdhcpd.conf.sampleをコピーして設定変更。
# cp /usr/share/doc/dhcp-バージョン/dhcpd.conf.sample /etc/dhcp/dhcpd.conf
# vi /etc/dhcp/dhcpd.conf
サンプルの行は全て不要なのでコメントアウトする。
IPアドレスを配りたいsubnetを以下のように書いてゆく。
subnet 10.1.49.0 netmask 255.255.255.0 {
  option routers 10.1.49.1;
  option subnet-mask 255.255.255.0;
  range dynamic-bootp 10.1.49.151 10.1.49.200;
  option domain-name-servers xxx.xxx.xxx.xxx,yyy.yyy.yyy.yyy;
  default-lease-time 21600;
  max-lease-time 43200;
}
rangeは配るIPアドレスの範囲(複数行あっても可。10.1.56.50 10.1.58.200のようにIPを続けて書いても可)。default-lease-timeはクライアントが期限を求めない場合の割り当て期間(秒),max-lease-timeはクライアントが期限を求めた場合の最大割り当て期間(秒)。
なお,各subnetに共通の設定は,{ }から出して,最初のsubnet文よりも上に書くことができる。以下のような感じ。
option domain-name-servers xxx.xxx.xxx.xxx,yyy.yyy.yyy.yyy;
default-lease-time 21600;
max-lease-time 43200;
authoritative;

subnet 10.1.54.0 netmask 255.255.255.0 {
  option routers 10.1.54.1;
  option subnet-mask 255.255.255.0;
}

subnet 10.1.49.0 netmask 255.255.255.0 {
  option routers 10.1.49.1;
  option subnet-mask 255.255.255.0;
  range dynamic-bootp 10.1.49.151 10.1.49.200;
}

動作テスト

# dhcpd -f -d
うまくいったら,Ctrl+Cで停止。-fはプロセスをバックグラウンドではなくフォアグラウンドで実行するという意味,-dはログを標準エラー出力するという意味。

dhcpd再起動と自動起動の設定

(CentOS6)
# /etc/init.d/dhcpd restart
# /sbin/chkconfig dhcpd on
(CentOS7)
# systemctl restart dhcpd
# systemctl enable dhcpd
以上

dhcpアドレスリース状況(リース数)

dhcpアドレスリース状況は,
/var/lib/dhcpd/dhcpd.lease
に記録される。しかし
lease 10.2.59.193 {
  starts 3 2011/09/28 08:59:05;
  ends 3 2011/09/28 20:59:05;
  tstp 3 2011/09/28 20:59:05;
  binding state free;
  hardware ethernet ??:??:??:??:??:??;
  uid "\???\???\????\???\???\???";
}
のように,リース開始/終了時間が記録されているので,何か解析スクリプトを使わないとある瞬間の貸し出し数はわからない(と思う)。
awkスクリプト(ここからコピーさせて頂きました):
#!/bin/sh
awk '/^lease 10.2.5[6-9]/ { curlease = $2; } /^ binding state/ { lstates[curlease] = $3; } END { for (curl in lstates) { tstates[lstates[curl]]++; } for (curs in tstates) { print curs, tstates[curs]; } }' /var/lib/dhcpd/dhcpd.leases
使い方:
出力例
active; 494
free; 427

冗長構成I アドレスプール分割運用

DHCPを2台つないで,アドレスプールを重複しない2領域に分けて運用する際のコツ。書く設定ファイルは一つだけにして,簡単なawkスクリプトで各DHCPサーバー用の設定ファイルを生成する。
まず,上のようにして2台のDHCPサーバーを準備する。
1台目のdhcpd.confを次のように書き換える。dhcpd.confに記述してあった内容はdhcpd.poolsにコピーする。
include "/etc/dhcp/dhcpd.pool1";
2台目のdhcpd.confを次のように書き換える。dhcpd.masterは1台目のdhcpd.masterをコピーする。
include "/etc/dhcp/dhcpd.pool2";
dhcpd.pool1とdhcpd.pool2は,2台のDHCPサーバーで重ならないアドレス範囲を配る設定ファイル。以下のような,pool1とpool2用の重ならないアドレス範囲をrangeを2行使って書いたdhcpd.poolsからawkスクリプトで作る。 なおdhcpd.pool1,dhcpd.pool2の代わりにdhcpd.poolsをincludeすれば,一台のDHCPサーバーで全てのアドレスを配ることができるので,1台故障して修理中などの時はdhcpd.poolsをincludeする。

dhcpd.pools

subnet 10.1.48.0 netmask 255.255.255.0 {  
    option routers      10.1.48.1;
    option subnet-mask  255.255.255.0;
    range 10.1.48.50 10.1.48.150;  #pool1
    range 10.1.48.151 10.1.48.250; #pool2
}

pools

#!/bin/sh

awk '
/#pool2$/ {
  print "#" $0
  next
}
{
  print $0
}
' /etc/dhcp/dhcpd.pools > /etc/dhcp/dhcpd.pool1

awk '
/#pool1$/ {
  print "#" $0
  next
}
{
  print $0
}
' /etc/dhcp/dhcpd.pools > /etc/dhcp/dhcpd.pool2

冗長構成II failover peer

2台で運用してどちらかが停止してもDHCPサービスが止まらないISC DHCPのフェイルオーバー機能を使った冗長構成の方法。
--- 我々は冗長構成を使うのをやめました。(理由1)1台のDHCPが壊れた時,うまく作動しなかった,かつ,もう一台も引きずられて止まってしまった。(理由2)配布できるアドレスがかなり減ってしまう。 2016.11.16
まず,上のようにして2台のDHCPサーバーを準備する。
1台目のdhcpd.confを次のように書き換える。dhcpd.confに記述してあった内容はdhcpd.masterにコピーする。
failover peer "my-dhcp" {
  primary;
  address 10.1.54.2;
  port 519;
  peer address 10.1.54.4;
  peer port 519;
  max-response-delay 60;
  max-unacked-updates 10;
  mclt 3600;
  split 128;
  load balance max seconds 3;
}

include "/etc/dhcp/dhcpd.master";
2台目のdhcpd.confを次のように書き換える。dhcpd.masterは1台目のdhcpd.masterをコピーする。
failover peer "my-dhcp" {
  secondary;
  address 10.1.54.4;
  port 519;
  peer address 10.1.54.2;
  peer port 519;
  max-response-delay 60;
  max-unacked-updates 10;
}

include "/etc/dhcp/dhcpd.master";
これは,2台のDHCPサーバーをそれぞれprimaryとsecondaryとして,それぞれのIPアドレス(address)と互いの状態の通信用ポート(port)を指定している。通信用ポートは何番でもよく標準ではprimaryとsecondaryに異なる番号を指定する(ここでの設定のように同じでもよい)。その他の行の意味は,

dhcpd.master

dhcp.masterには次のように各サブネットにfailover peer行とdeny dynamic bootp clients;行を追加し,pool{ }で囲む。
subnet 10.1.48.0 netmask 255.255.255.0 {
  pool{
    failover peer "my-dhcp";
    option routers      10.1.48.1;
    option subnet-mask  255.255.255.0;
    range 10.1.48.151 10.1.48.200;
    deny dynamic bootp clients;
  }
}

ファイアーウオール

519/tcpを開く。
(CentOS6)
setupを使う。
(CentOS7)
# firewall-cmd --permanent --add-port=519/tcp
# firewall-cmd --reload
# systemctl start firewalld

テスト

以上の設定が終わったら,dhcpd -f -dで2台のdhcpdを動かして,様子をみる。以下のような文字列が見えれば多分OK。どちらかをCtrl-Cで止めると,これらの文字列は現れなくなる。
primary:
DHCPDISCOVER ...load balance to peer my-dhcp
DHCPREQUEST ... lease owned by peer
secondary:
bind update on ... from my-dhcp rejected: incoming update is less critical than outgoing update
上手くいったらCtrl-Cで止めてサーバーを再起動。

参考

CentOSで自宅サーバー構築 (http://centossrv.com/) 2008.5現在
DHCPサーバを立てるには (http://www.atmarkit.co.jp/flinux/rensai/linuxtips/539usedhcpd.html) 2010.7現在
isc-dhcp-serverでdhcpサーバの冗長構成 (http://www.prosper2.org/devwiki/index.php?isc-dhcp-server%E3%81%A7dhcp%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E5%86%97%E9%95%B7%E6%A7%8B%E6%88%90) 2016.2現在
DHCPサーバの2重化(failover)の設定 (http://unixservermemo.web.fc2.com/sv/dhcp-failover.htm) 2016.2現在
DHCPのフロー (http://www.unix-power.net/linux/dhcp.html) 2016.2現在
Failover with ISC DHCP (https://www.madboa.com/geek/dhcp-failover/) 2016.2現在