#author("2019-08-16T00:50:11+09:00","default:nowsky","nowsky")
#author("2019-08-16T01:13:16+09:00","default:nowsky","nowsky")
*DHCP [#k05403b6]
[[ISC DHCP Server:+https://www.isc.org/downloads/dhcp/]]
フリーのDHCPサーバとして利用される事もあるソフトウェア。
DNSサーバのBINDで有名なISCが開発を行っている。

近年、後継のKEA DHCPに取って代わるとアナウンスされているが、
failoverなどの未実装機能が多い為、安定するまではISC DHCPの方が良いと思われる。
~
*インストール [#k1fee22c]
&size(16){&font(b){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
~
----
&size(16){&font(b){1. ソースコード改変};};
GCCのバージョンが8.2.0以上の場合、&font(b){ISC DHCP v4.4.1以下ではビルドエラー};が発生する。
GCCのバージョンが8.2.0以上の場合、&font(b){ISC DHCP v4.4.1以下では下記のビルドエラー};が発生する。
configureスクリプトの"-Werror"を削除する事でもビルドを通す事が可能だが、
ソース改変によって根本的なエラー対策が可能なのでソース改変を行う。
- [[BLFS DHCP 4.4.1 broken with GCC 8+ Patch Supplied):+https://www.mail-archive.com/blfs-dev@lists.linuxfromscratch.org/msg07575.html]]

"dhcp-4.4.1"をオリジナル、"dhcp_4.4.1_gcc"を修正後としてディレクトリパッチを作成。
 discover.c: In function 'discover_interfaces':
 discover.c:646:4: error: 'strncpy' output may be truncated copying 15 bytes from a string of length 15 [-Werror=stringop-truncation]
     strncpy(tmp->name, info.name, sizeof(tmp->name) - 1);
  
 cc1: all warnings being treated as errors
 make[2]: *** [Makefile:519: discover.o] Error 1
 make[2]: Leaving directory '/usr/local/src/dhcp-4.4.1/common'
 make[1]: *** [Makefile:582: all-recursive] Error 1
 make[1]: Leaving directory '/usr/local/src/dhcp-4.4.1/common'
 make: *** [Makefile:462: all-recursive] Error 1
 
[[参考情報:+https://www.mail-archive.com/blfs-dev@lists.linuxfromscratch.org/msg07575.html]]を元に、"dhcp-4.4.1"をオリジナル、"dhcp_4.4.1_gcc"を修正後としてディレクトリパッチを作成。
実際には3ファイルのみ修正する簡単な物なので、パッチ適用が面倒ならファイル毎に書き換える。
- discover.c
 diff -uprN dhcp-4.4.1/common/discover.c dhcp-4.4.1_gcc/common/discover.c
 --- dhcp-4.4.1/common/discover.c        2018-02-21 23:30:46.000000000 +0900
 +++ dhcp-4.4.1_gcc/common/discover.c    2019-08-14 15:36:23.890602209 +0900
 @@ -643,7 +643,7 @@ discover_interfaces(int state) {
                                 log_fatal("Error allocating interface %s: %s",
                                           info.name, isc_result_totext(status));
                         }
 -                       strncpy(tmp->name, info.name, sizeof(tmp->name) - 1);
 +                       memcpy(tmp->name, info.name, sizeof(tmp->name));
                         interface_snorf(tmp, ir);
                         interface_dereference(&tmp, MDL);
                         tmp = interfaces; /* XXX */

- parse.c
 diff -uprN dhcp-4.4.1/common/parse.c dhcp-4.4.1_gcc/common/parse.c
 --- dhcp-4.4.1/common/parse.c           2018-02-21 23:30:46.000000000 +0900
 +++ dhcp-4.4.1_gcc/common/parse.c       2019-08-14 15:33:21.330767736 +0900
 @@ -5567,7 +5567,8 @@ int parse_warn (struct parse *cfile, con
         va_list list;
         char lexbuf [256];
         char mbuf [1024];
 -       char fbuf [1024];
 +       char fbuf [2048];
 +       char final[4096];
         unsigned i, lix;
  
         do_percentm (mbuf, fmt);
 @@ -5578,7 +5579,7 @@ int parse_warn (struct parse *cfile, con
                   cfile -> tlname, cfile -> lexline, mbuf);
  
         va_start (list, fmt);
 -       vsnprintf (mbuf, sizeof mbuf, fbuf, list);
 +       vsnprintf (final, sizeof final, fbuf, list);
         va_end (list);
  
         lix = 0;
 @@ -5594,14 +5595,14 @@ int parse_warn (struct parse *cfile, con
         lexbuf [lix] = 0;
  
  #ifndef DEBUG
 -       syslog (LOG_ERR, "%s", mbuf);
 +       syslog (LOG_ERR, "%s", final);
         syslog (LOG_ERR, "%s", cfile -> token_line);
         if (cfile -> lexchar < 81)
                 syslog (LOG_ERR, "%s^", lexbuf);
  #endif
  
         if (log_perror) {
 -               IGNORE_RET (write (STDERR_FILENO, mbuf, strlen (mbuf)));
 +               IGNORE_RET (write (STDERR_FILENO, final, strlen (final)));
                 IGNORE_RET (write (STDERR_FILENO, "\n", 1));
                 IGNORE_RET (write (STDERR_FILENO, cfile -> token_line,
                                    strlen (cfile -> token_line)));

- dhcrelay.c
 diff -uprN dhcp-4.4.1/relay/dhcrelay.c dhcp-4.4.1_gcc/relay/dhcrelay.c
 --- dhcp-4.4.1/relay/dhcrelay.c         2018-02-21 23:30:46.000000000 +0900
 +++ dhcp-4.4.1_gcc/relay/dhcrelay.c     2019-08-14 15:37:23.620557375 +0900
 @@ -2119,7 +2119,7 @@ void request_v4_interface(const char* na
                   (flags & INTERFACE_UPSTREAM ? 'Y' : 'N'),
                   (flags & INTERFACE_DOWNSTREAM ? 'Y' : 'N'));
  
 -        strncpy(tmp->name, name, len);
 +        memcpy(tmp->name, name, len);
          interface_snorf(tmp, (INTERFACE_REQUESTED | flags));
          interface_dereference(&tmp, MDL);
  }
~
----
&size(16){&font(b){2. ビルド・インストール};};
事前にソースコードをダウンロードしておく。
必要に応じてビルドオプションを付与させる必要があるが、
今回は稼働テストなので出来る限り多くのオプションを付与しておく。
なお、automakeのバージョンが低い場合、ISC DHCPのビルドに失敗するので、
autoreconfを実行しautomakeの参照先を書き換えておく。
 $ tar zxvf dhcp-4.3.4.tar.gz
 $ cd dhcp-4.3.4
 $ autoreconf -f -i -v
 $ ./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
~
----
&size(16){&font(b){3. 起動オプションの設定};};
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サーバの追加起動オプション
~
----
&size(16){&font(b){4. 起動スクリプトの作成};};
ソースコードには起動スクリプトが同梱されていないので自作する必要がある。
今回は従来通りの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}"
 
 # IPv4
 ARGS="-user ${USER} -group ${GROUP} -cf ${CONFIG} -pf ${PIDFILE} -lf ${LEASEFILE}"
 # IPv6
 #ARGS="-6 -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
~
----
&size(16){&font(b){5. 起動準備};};
実行ユーザの準備や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
~
*コンフィグ [#neb6187d]
&size(16){&font(b){A. シングル構成・別セグメント待受};};
-[[Man page of dhcpd.conf:+https://linuxjm.osdn.jp/html/dhcp2/man5/dhcpd.conf.5.html]]
-[[dhcpd.conf 覚書:+http://qiita.com/JhonnyBravo/items/e5324715efa9a9264c9d]]
-[[UNIXサーバメモメモ - ISC DHCP設定ファイル:+http://unixservermemo.web.fc2.com/sv/dhcp-conf.htm]]

クライアントセグメントの外にDHCPサーバを設置し、複数セグメントのDHCPサーバを集約管理する時の設定。
DHCPサーバ設置セグメントにDHCPでIPアドレスを払い出さない場合でも、
サーバ自体が所属するサブネットについて設定を入れないと、プログラムが起動しなくなる点に注意する。
 
下記の設定内容では、サーバセグメントにはDHCPで払い出しを行わないが、
サーバを起動させる為に、&font(b){何も払い出さない設定};を追加してある。
 
・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|
|プライマリDNS   |10.0.0.10               |
|セカンダリDNS   |10.0.0.20               |
 
・補足
DHCPクライアントとDHCPサーバが別セグメントになり、DHCP DISCOVERがDHCPサーバまで届かなくなるので、
クライアントのデフォルトルートとなるルータに、[[DHCPリレー設定:+http://www.cisco.com/cisco/web/support/JP/docs/CIAN/IOS/IOSSWRels15_1/CG/001/iad_dhcp_rly_agt.html?bid=0900e4b1825ae5ce#44008]]を入れておく。
 
・設定内容
 $ 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;
     }
 }
~
----
&size(16){&font(b){B. 冗長構成・別セグメント待受};};
-[[FreeBSD Man Pages:+https://www.freebsd.org/cgi/man.cgi?query=dhcpd.conf&sektion=5&apropos=0&manpath=FreeBSD+9.0-RELEASE+and+Ports]]
-[[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]]
-[[UNIXサーバメモメモ - DHCPサーバの2重化(failover)の設定:+http://unixservermemo.web.fc2.com/sv/dhcp-failover.htm]]

Aの内容でDHCPサーバを冗長構成にした場合の設定サンプル。
DHCPサーバを楽に冗長化する場合、各サーバから払い出すIPアドレス範囲を重ならないように分割し、分散配置する場合が多いのだが、
今回はDHCPサーバのFailover機能を使って、lease情報の共有を行い冗長化をする。
 
・DHCPサーバ 構成情報
|                |Primary    |Secondary   |
|サーバIPアドレス|10.0.0.101 |10.0.10.101 |
|ネットワーク    |10.0.0.0/24|10.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|
|プライマリDNS   |10.0.0.10               |
|セカンダリDNS   |10.0.0.20               |
 
・補足
例の如く、[[DHCPリレー設定:+http://www.cisco.com/cisco/web/support/JP/docs/CIAN/IOS/IOSSWRels15_1/CG/001/iad_dhcp_rly_agt.html?bid=0900e4b1825ae5ce#44008]]を入れる必要があるのだが、
DHCPサーバが冗長化されている場合、両サーバにDHCP DISCOVERが届くように設定する必要がある。
 
CISCOルータの場合、1つのインターフェースに複数のリレー先を設定出来るが、
1812J-IOSv15でテストした所、設定したリレー先全てにDISCOVERが転送される事が確認出来た。
今回の冗長化構成では、lease情報を共有しているので複数のDHCPサーバに同時転送されても問題無いが、
払い出し範囲を分割する事で冗長化している場合、&font(b){もしかしたら不具合が起きる};かもしれない。
 
・設定内容(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;
         }
     }
 }
~
----
&size(16){&font(b){C. IPv6(RA)・DNSサーバ配布};};
-[[DHCPv6パケット転送時の設定内容:+https://www.alaxala.com/jp/techinfo/archive/manual/AX8600R/HTML/12_2/CFGUIDE3/0153.HTM]]
-[[Radvd and DHCPd6 Server Configuration:+http://sophiedogg.com/radvd-and-dhcpd6-server-configuration-for-dynamic-dns/]]
-[[ISC DHCPv6 configuration excerpt:+http://ipv6.web.cern.ch/content/isc-dhcpv6-configuration-excerpt]]

IPv6環境用のDHCPv6を構成する為の設定サンプル。
最近はRAによるEUI-64生成が多いが、DNSサーバなどの付加情報を付与するにはDHCPv6が必要となる。
なお、下記コンフィグではRAによるIPv6アドレス配布を前提としている。
 
dhcpdはオプション無しで起動するとIPv4動作となる為、
DHCPv6用で動かす為に、起動スクリプト内のARGS先頭に&font(b){"-6"};を付与してDHCPv6モードに切り替える。
 
・設定内容
 ddns-update-style   interim;
 ignore              client-updates;
 not                 authoritative;
 log-facility        daemon;
 allow               leasequery;
 deny                bootp;
 
 shared-network "DHCPv6" {
     subnet6 2001:aa:bb:cc::/64 {
         range6                          2001:aa:bb:cc::/64;                    #エラー回避の為、仮のIPv6アドレスレンジを指定
         #range6                         2001:aa:bb:cc::0 2001:aa:bb:cc::ffff;  #範囲指定する場合、割り当ての始点・終点を設定
         option dhcp6.name-servers       2001:aa:bb:cc::a,2001:aa:bb:cc::b;     #DNSサーバアドレス。間にカンマがある事に注意
         option dhcp6.domain-search      "local.domain.com";                    #DNS検索リスト
         option dhcp6.info-refresh-time  21600;
         option dhcp-renewal-time        3600;
         option dhcp-rebinding-time      7200;
         default-lease-time              10800;
         preferred-lifetime              10800;
         max-lease-time                  43200;
     }
 }
~
----
&size(16){&font(b){D. IPv6(EUI-64)・疑似クラスタ};};
-[[ISC DHCP Users - ipv6 and failover:+http://isc-dhcp-users.2343191.n4.nabble.com/ipv6-and-failover-td277.html]]
-[[dhcpd.conf:+https://www.isc.org/wp-content/uploads/2018/02/dhcp44.html]]

IPv4はDHCPフェールオーバー(RFC2132)による、DHCPサーバ冗長構成が取れるが、
IPv6のDHCPフェールオーバー(RFC8156)は、ISC DHCPに実装されていない為、
フェールオーバーを用いたDHCPv6サーバ冗長化が出来ない。
その為、IPv6環境下でDHCPv6サーバ冗長化を行う場合、アドレスプールを細かく設定したDHCPv6サーバを複数台構築するか、
バックエンドにデータベースを利用出来るKEA DHCPでフロントエンドを増やす事が多いが、構成の複雑化がネックとなる。
 
シンプル構成でDHCPv6サーバを冗長化するには、、ISC DHCPで&font(b){EUI-64方式によるIPv6アドレス配布};を行う事により、
複数台のサーバを構築してもアドレス衝突が発生しなくなり、結果としてDHCPv6サーバの冗長化を行う事が出来る。
ただし、通常のソースビルドではEUI-64方式でのアドレッシングに対応していない為、
ヘッダーを書き換えてEUI-64オプションを有効化した後、&color(#ff0000){ソースをリビルドする};必要がある。
 
・ヘッダー書換
 # vi dhcp-4.4.1/includes/site.h
 ---
 /* Enable EUI-64 Address assignment policy.  Instructs the server
  * to use EUI-64 addressing instead of dynamic address allocation
  * for IA_NA pools, if the parameter use-eui-64 is true for the
  * pool.  Can be at all scopes down to the pool level.  Not
  * supported by the configure script. */
 #define EUI_64
 
・設定内容
 ddns-update-style      interim;
 ignore                 client-updates;
 not                    authoritative;
 log-facility           daemon;
 allow                  leasequery;
 deny                   bootp;
 
 persist-eui-64-leases  true;  #EUI-64で割り当てたIPv6アドレスを、
                               #アドレスリースファイルに書き込む
 
 shared-network "DHCPv6" {
     subnet6 2001:aa:bb:cc::/64 {
         use-eui-64                      true;                #EUI-64でIPv6アドレスを配布する
         range6                          2001:aa:bb:cc::/64;  #EUI-64で割り当てる為、プレフィックスは必ず "/64" を設定
 
         option dhcp6.name-servers       2001:aa:bb:cc::a,2001:aa:bb:cc::b;
         option dhcp6.domain-search      "local.domain.com";
         option dhcp6.info-refresh-time  21600;
         option dhcp-renewal-time        3600;
         option dhcp-rebinding-time      7200;
         default-lease-time              10800;
         preferred-lifetime              10800;
         max-lease-time                  43200;
     }
 }