ISC DHCP

ISC DHCP Server
フリーのDHCPサーバとして利用される事もあるソフトウェア。
DNSサーバのBINDで有名なISCが開発を行っている。

近年、後継のKEA DHCPに取って代わるとアナウンスされているが、
failoverなどの未実装機能が多い為、安定するまではISC DHCPの方が良いと思われる。

インストール

0. 事前準備
ISC DHCPをビルドするには、autoconf 2.65以上が必要になる。
CentOS6でautoconfをデフォルトのまま使っていた場合、この条件を満たせないので、
事前に最新版のautoconfを導入しておく。
 
この時、インストール先ディレクトリによってはPATH優先度の関係で、
既存のautoconfのPATH(/usr/bin)が優先されてしまい、
追加インストールしたautoconfを参照していない状態になるので注意する

$ tar zxvf autoconf-2.69.tar.gz
$ cd autoconf-2.69
$ ./configure
$ make && make install
$ cd /usr/bin
$ mv autoconf   autoconf.yum-org
$ mv autoheader autoheader.yum-org
$ mv autom4te   autom4te.yum-org
$ mv autoreconf autoreconf.yum-org
$ mv autoscan   autoscan.yum-org
$ mv autoupdate autoupdate.yum-org
$ mv ifnames    ifnames.yum-org
$ ln -s /usr/local/bin/autoconf
$ ln -s /usr/local/bin/autoheader
$ ln -s /usr/local/bin/autom4te
$ ln -s /usr/local/bin/autoreconf
$ ln -s /usr/local/bin/autoscan
$ ln -s /usr/local/bin/autoupdate
$ ln -s /usr/local/bin/ifnames



1. ビルド・インストール
事前にソースコードをダウンロードしておく。
必要に応じてビルドオプションを付与させる必要があるが、
今回は稼働テストなので出来る限り多くのオプションを付与しておく。

$ tar zxvf dhcp-4.3.4.tar.gz
$ cd dhcp-4.3.4
$ ./configure --prefix=/usr/local/dhcp-4.3.4 \
              --enable-dependency-tracking   \
              --enable-maintainer-mode       \
              --enable-early-chroot          \
              --enable-failover              \
              --enable-execute               \
              --enable-tracing               \
              --enable-ipv4-pktinfo          \
              --enable-dhcpv4o6              \
              --enable-dhcpv6
$ make
$ make install
$ cd /usr/local
$ ln -s /usr/local/dhcp-4.3.4 dhcp



2. 起動オプションの設定
DHCPサーバを実行するユーザ・グループの設定や、
DHCP DISCOVERを待ち受けるインターフェースを指定する。

$ vi /etc/sysconfig/dhcpd
--------------------------------------------------
PROG="dhcpd"
USER="dhcpd"
GROUP="dhcpd"
INTERFACE="eth0"
CONFIG="/usr/local/dhcp/etc/dhcpd.conf"
OPTION=""
==================================================
PROG      = バイナリ名
USER      = 実行ユーザ
GROUP     = 実行グループ
INTERFACE = パケット待ち受けインターフェース
CONFIG    = 設定ファイルPATH
OPTION    = DHCPサーバの追加起動オプション



3. 起動スクリプトの作成
ソースコードには起動スクリプトが同梱されていないので自作する必要がある。
今回は従来通りのinitスクリプトで起動を行う。
サービスの実行ユーザ設定などは、上記のsysconfigファイルで行い、
initスクリプトはプロセスの起動・停止に特化したスクリプトとする。

$ vi /etc/init.d/dhcpd
--------------------------------------------------
#!/bin/sh
#
# dhcpd           This shell script takes care of starting and stopping
#                 dhcpd (DHCP server).
#
# chkconfig: 345 55 45
# description: dhcpd is a Dynamic Host Configuration Protocol Server
# probe: true

# Program configuration
. /etc/sysconfig/dhcpd

RUNDIR="/var/run/${PROG}"
PIDFILE="${RUNDIR}/${PROG}.pid"
LEASEFILE="${RUNDIR}/${PROG}.lease"
LOCKFILE="/var/lock/subsys/${PROG}"

EXEC="/usr/local/dhcp/sbin/${PROG}"
ARGS="-user ${USER} -group ${GROUP} -cf ${CONFIG} -pf ${PIDFILE} -lf ${LEASEFILE}"

# Make running directory
if [ ! -e ${RUNDIR} ] ;then
    mkdir ${RUNDIR}
    chown ${USER}.${GROUP} ${RUNDIR}
    chmod 750 ${RUNDIR}
fi

# Make lease file
if [ ! -e ${LEASEFILE} ] ;then
    touch ${LEASEFILE}
    chown ${USER}.${GROUP} ${LEASEFILE}
fi

# Source function library
. /etc/rc.d/init.d/functions

# Source networking configuration
. /etc/sysconfig/network

# Check that networking is up
[ ${NETWORKING} = "no" ] && exit 0
[ -f ${EXEC} ]           || exit 0
[ -f ${CONFIG} ]         || exit 0

# See how we were called
case "$1" in
    start)
        # Start daemon
        echo -n "Starting ${PROG}: "
        if [ -e ${LOCKFILE} ] ;then
            echo "${PROG} running"
            exit 0
        else
            daemon ${EXEC} ${ARGS} ${OPTION} ${INTERFACE}
            echo
            touch ${LOCKFILE}
        fi
        ;;
    stop)
        # Stop daemon
        echo -n "Shutting down ${PROG}: "
        killproc -p ${PIDFILE}
        rm -f ${LOCKFILE}
        echo
        ;;
    restart)
        $0 stop
        $0 start
        exit $?
        ;;
    *)
        echo "Usage: ${PROG} {start|stop|restart}"
        exit 1
esac

exit 0



4. 起動準備
実行ユーザの準備やiptablesのポート開放を設定する。
DHCPサーバ宛はUDP:67、DHCPクライアント宛はUDP:68を使う点に注意。
下記の内容は例なので、自環境に合わせてチューニングした上で設定を行う。

・実行ユーザ、グループ作成
==================================================
$ groupadd dhcpd
$ useradd -g dhcpd -d /var/run/dhcpd -s /sbin/nologin dhcpd
・起動スクリプト登録
==================================================
$ chmod 755 /etc/init.d/dhcpd
$ chkconfig --add  dhcpd
$ chkconfig --list dhcpd
--------------------------------------------------
dhcpd    0:off  1:off  2:off  3:on  4:on  5:on  6:off
・iptables開放
==================================================
$ iptables -A INPUT -p udp --dport 67 -j ACCEPT



5-1. コンフィグ作成 (シングル構成、別セグメント待受)

クライアントセグメントの外にDHCPサーバを設置し、複数セグメントのDHCPサーバを集約管理する時の設定。
DHCPサーバ設置セグメントにDHCPでIPアドレスを払い出さない場合でも、
サーバ自体が所属するサブネットについて設定を入れないと、プログラムが起動しなくなる点に注意する。
 
下記の設定内容では、サーバセグメントにはDHCPで払い出しを行わないが、
サーバを起動させる為に、何も払い出さない設定を追加してある。
 
・DHCPサーバ 構成情報

ネットワーク10.0.0.0/24
インターフェースeth0 (1NIC構成)

 
・DHCPクライアント IP払出し情報

ネットワーク10.10.0.0/24
デフォルトルート10.10.0.254
IP払い出し範囲10.10.0.100~10.10.0.200
プライマリDNS10.0.0.10
セカンダリDNS10.0.0.20

 
・補足
DHCPクライアントとDHCPサーバが別セグメントになり、DHCP DISCOVERがDHCPサーバまで届かなくなるので、
クライアントのデフォルトルートとなるルータに、DHCPリレー設定を入れておく。
 
・設定内容

$ vi /usr/local/dhcp/etc/dhcpd.conf
--------------------------------------------------
ddns-update-style  interim;         #DHCPリース要求時の開放動作設定
ignore             client-updates;  #DNSサーバエントリ自動更新時のドメイン制御指定
not                authoritative;   #セグメント設定情報の信頼度
log-facility       local1;          #ログ出力先


shared-network "DHCP" {
    subnet 10.0.0.0  netmask 255.255.255.0 {
    }

    subnet 10.10.0.0 netmask 255.255.255.0 {
        option routers              10.10.0.254;
        option subnet-mask          255.255.255.0;
        option broadcast-address    10.10.0.255;
        option domain-name-servers  10.0.0.10,10.0.0.20;      #プライマリとセカンダリの間に、カンマを入れる
        range                       10.10.0.100 10.10.0.200;  #始点と終端の間に、スペースを入れる
        default-lease-time          3600;
        max-lease-time              86400;
    }
}



5-2. コンフィグ作成 (冗長構成、別セグメント待受)

5-1の内容でDHCPサーバを冗長構成にした場合の設定サンプル。
DHCPサーバを楽に冗長化する場合、各サーバから払い出すIPアドレス範囲を重ならないように分割し、分散配置する場合が多いのだが、
今回はDHCPサーバのFailover機能を使って、lease情報の共有を行い冗長化をする。
 
・DHCPサーバ 構成情報

PrimarySecondary
サーバIPアドレス10.0.0.10110.0.10.101
ネットワーク10.0.0.0/2410.0.10.0/24
インターフェースeth0 (1NIC構成)
keep-alive通信TCP/647

 
・DHCPクライアント IP払出し情報

ネットワーク10.10.0.0/24
デフォルトルート10.10.0.254
IP払い出し範囲10.10.0.100~10.10.0.200
プライマリDNS10.0.0.10
セカンダリDNS10.0.0.20

 
・補足
例の如く、DHCPリレー設定を入れる必要があるのだが、
DHCPサーバが冗長化されている場合、両サーバにDHCP DISCOVERが届くように設定する必要がある。
 
CISCOルータの場合、1つのインターフェースに複数のリレー先を設定出来るが、
1812J-IOSv15でテストした所、設定したリレー先全てにDISCOVERが転送される事が確認出来た。
今回の冗長化構成では、lease情報を共有しているので複数のDHCPサーバに同時転送されても問題無いが、
払い出し範囲を分割する事で冗長化している場合、もしかしたら不具合が起きるかもしれない。
 
・設定内容(Primary)

$ vi /usr/local/dhcp/etc/dhcpd.conf
--------------------------------------------------
ddns-update-style  interim;
ignore             client-updates;
not                authoritative;
log-facility       local1;


failover peer "failover" {
    primary;                                #Primaryサーバである事を宣言
    address                   10.0.0.101;   #自サーバIPアドレス
    port                      647;          #自サーバのFailoverプロトコル待ち受けポート。プロトコルはTCPのみ。デフォルトはTCP/647
    peer address              10.0.10.101;  #ピアサーバのIPアドレス
    peer port                 647;          #ピアサーバのFailoverプロトコル待ち受けポート。プロトコルはTCPのみ。デフォルトはTCP/647

    load balance max seconds  3;            #ピアがDHCP DISCOVERを処理出来なかった際に、強制で自サーバが処理を代行するまでの時間
    max-response-delay        30;           #ピアとの接続断と判断するまでの時間
    max-unacked-updates       10;           #Failrecovery後に1回の制御通信で同期するlease情報最大数
    mclt                      3600;         #Primary限定。Primary障害時にlease時間を延長出来る最大時間
    split                     128;          #Primary限定。負荷分散優先度を0~255で設定。0or255にするとActive-Standbyに(負荷分散しなく)なる
}


shared-network "DHCP" {
    subnet 10.0.0.0  netmask 255.255.255.0 {
    }

    subnet 10.0.10.0 netmask 255.255.255.0 {
    }

    subnet 10.10.0.0 netmask 255.255.255.0 {
        option routers              10.10.0.254;
        option subnet-mask          255.255.255.0;
        option broadcast-address    10.10.0.255;
        option domain-name-servers  10.0.0.10,10.0.0.20;
        default-lease-time          3600;
        max-lease-time              86400;

        pool {                                                #設定を見やすくする為に、冗長化設定箇所をpoolで囲んでおく
            failover peer           "failover";               #Failoverする際に使う設定項目を指定
            range                   10.10.0.100 10.10.0.200;  #Primary-Secondary共通のIPアドレス払い出し範囲
            deny dynamic bootp clients;                       #BOOTP-leaseは冗長化出来ないので拒否する
        }
    }
}

 
・設定内容(Secondary)

$ vi /usr/local/dhcp/etc/dhcpd.conf
--------------------------------------------------
ddns-update-style   interim;
ignore              client-updates;
not                 authoritative;
log-facility        daemon;


failover peer "failover" {
    secondary;                                #Secondaryサーバである事を宣言
    address                     10.0.10.101;  #自サーバIPアドレス。Primaryと逆設定になる点に注意
    port                        647;          #自サーバのFailoverプロトコル待ち受けポート
    peer address                10.0.0.101;   #ピアサーバのIPアドレス。Primaryと逆設定になる点に注意
    peer port                   647;          #ピアサーバのFailoverプロトコル待ち受けポート

    load balance max seconds    3;
    max-response-delay          30;
    max-unacked-updates         10;
}


shared-network "DHCP" {
    subnet 10.0.0.0  netmask 255.255.255.0 {
    }
    
    subnet 10.0.10.0 netmask 255.255.255.0 {
    }
    
    subnet 10.10.0.0 netmask 255.255.255.0 {
        option routers              10.10.0.254;
        option subnet-mask          255.255.255.0;
        option broadcast-address    10.10.0.255;
        option domain-name-servers  10.0.0.10,10.0.0.20;
        default-lease-time          3600;
        max-lease-time              86400;

        pool {
            failover peer           "failover";
            range                   10.10.0.100 10.10.0.200;
            deny dynamic bootp clients;
        }
    }
}