#author("2018-11-23T00:23:05+09:00","default:nowsky","nowsky")
*radvd [#m204aa72]
[[IPv6 Router Advertisement Daemon:+http://www.litech.org/radvd/]]
 
IPv6で必要となるルータ広告を行う為のLinuxDaemon。
LinuxサーバをIPv6ルータとして動作させる時に利用する事が多い。
Raspberry PiをIPv6実験環境として利用したい場合には重宝する。
~
*インストール [#u9c3acbd]
&size(16){&font(b){1. ビルド・インストール};};
radvdは細かいオプションを付与しなくてもビルドは成功する。
今回はインストール先を分離する為にprefixのみ付与しておく。
 $ tar zxvf radvd-2.16.tar.gz
 $ cd radvd-2.16
 $ ./configure --prefix=/usr/local/radvd-2.16
 $ make
 $ make install
 $ cd /usr/local
 $ ln -s /usr/local/radvd-2.16 radvd
 $ cd /etc
 $ ln -s /usr/local/radvd/etc radvd
~
&size(16){&font(b){2. 起動オプションの設定};};
radvdを起動させる為のユーザ指定を行う。
chroot環境として動かす場合は、下記ファイルを書き換える事でchroot化出来る。
 # vi /etc/default/radvd
 --------------------------------------------------
 # No chroot; /var/run/radvd must be owned by -u.
 OPTIONS="-u radvd"
 
 # Chroot; directory structure under /var/chroot/radvd has to be populated.
 #OPTIONS="-u radvd -t /var/chroot/radvd"
~
&size(16){&font(b){3. 起動スクリプトの作成};};
Redhatの場合は、&font(b){"SOURCE/redhat/radvd.init"};をOS指定ディレクトリにコピーすれば良い。
Debianの場合は下記ファイルの様に、一部を改変する必要がある。
 $ vi /etc/init.d/radvd
 --------------------------------------------------
 #!/bin/sh
 #
 # radvd           radvd is the router advertisement daemon for IPv6.
 #
 ### BEGIN INIT INFO
 # Provides:       radvd
 # Required-Start: $network $remote_fs $syslog
 # Required-Stop:  $network $remote_fs $syslog
 # Default-Start:  2 3 4 5
 # Default-Stop:
 # Short-Description: Router Advertisement Daemon for IPv6
 ### END INIT INFO
 
 # Source function library.
 . /lib/lsb/init-functions
 
 [ -f /etc/default/radvd ] && . /etc/default/radvd
 
 RETVAL=0
 PROG="radvd"
 LOCKFILE=/var/lock/subsys/radvd
 
 # See how we were called.
 case "$1" in
     start)
         if [ ! -f /etc/radvd/radvd.conf ]; then
             echo $"Configuration file /etc/radvd/radvd.conf missing" 1>&2
             exit 6
         fi
         if [ `id -u` -ne 0 ]; then
             echo $"Insufficient privilege" 1>&2
             exit 4
         fi
         echo -n $"Starting $PROG: "
         /usr/local/radvd/sbin/radvd $OPTIONS
         RETVAL=$?
         echo
         if [ $RETVAL -eq 0 ]; then
             touch $LOCKFILE
         else
             if [ -f $LOCKFILE ]; then
                 RETVAL=0
             fi
         fi
         ;;
 
     stop)
         echo -n $"Stopping $PROG: "
         killproc radvd
         RETVAL=$?
         echo
         [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
         ;;
 
     restart)
         $0 stop
         $0 start
         RETVAL=$?
         ;;
 
     reload|force-reload)
         echo -n $"Reloading $PROG: "
         killproc radvd -HUP
         RETVAL=$?       
         echo
         ;;
 
     condrestart|try-restart)
         if [ -f $LOCKFILE ]; then
             $0 stop
             $0 start
             RETVAL=$?
         fi
         ;;
 
     *)
         echo $"Usage: $0 {start|stop|restart|try-restart|reload|force-reload}"
         exit 2
 esac
 
 exit $RETVAL
~
&size(16){&font(b){4. 起動準備};};
実行ユーザ作成と、iptablesのフィルタリング解除を行う。
クライアントからRAへ通信を行うには、下記のICMPv6パケットを通す必要がある。
 ・iptables開放
 ==================================================
 # ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request           -j ACCEPT
 # ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-reply             -j ACCEPT
 # ip6tables -A INPUT -p icmpv6 --icmpv6-type router-solicitation    -j ACCEPT
 # ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement   -j ACCEPT
 # ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation  -j ACCEPT
 # ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT

 ・実行ユーザ、グループ作成
 ==================================================
 $ groupadd radvd
 $ useradd -g radvd -d /var/run/radvd -s /usr/sbin/nologin radvd

 ・起動スクリプト登録
 ==================================================
 $ chmod 755 /etc/init.d/radvd
 $ systemctl enable radvd
~
&size(16){&font(b){5. コンフィグ作成};};
-[[radvd.conf - Linux man page:+https://linux.die.net/man/5/radvd.conf]]

今回は出番が一番多そうな下記条件でコンフィグを作成。
細かい所は上記のドキュメントを読みながら作成する。
 
・アドレス、設定内容
| EUI-64払出セグメント | 2001:aa:bb:cc::/64            |
| プライマリDNS        | 2001:aa:bb:cc::a              |
| セカンダリDNS        | 2001:aa:bb:cc::b              |
| Managedフラグ        | OFF (IPアドレスはEUI-64生成)  |
| OtherConfigフラグ    | ON (DNSサーバはDHCP取得)      |
| RA用Interface        | eth0.1 (サブインターフェース) |
 
・設定内容
 # vi /etc/radvd/radvd.conf
 --------------------------------------------------
 interface eth0.1 {
     AdvManagedFlag       off;
     AdvOtherConfigFlag   on;
     AdvSendAdvert        on;
     AdvDefaultPreference high;
     MinRtrAdvInterval    30;
     MaxRtrAdvInterval    100;
 
     RDNSS 2001:aa:bb:cc::a 2001:aa:bb:cc::b {
     };
 
     prefix 2001:aa:bb:cc::/64 {
         AdvOnLink     on;
         AdvAutonomous on;
         AdvRouterAddr on;
     };
 };
~
*冗長化設定(radvd+VRRP) [#s12801d8]
-[[High Available RADVD on Linux:+https://fy.blackhats.net.au/blog/html/2018/11/01/high_available_radvd_on_linux.html]]

RAではリンクローカルアドレスからのIPv6アドレス配布を前提としている為、
[[Keepalived:+https://www.ns-lab.org/wiki/?Linux/Source/Keepalived]] でユニキャストアドレスを生成し、
RA送信元もユニキャストアドレスに限定した場合、radvdはRAを送信出来なくなる。
この場合、Keepalivedにはリンクローカルアドレス(FE80::/10)も割り当てるように設定し、
radvdのRA送信元IPアドレスは、Keepalivedで生成したリンクローカルアドレスにする。

 # vi /etc/keepalived/keepalived.conf
 --------------------------------------------------
 vrrp_instance eth1-ipv6 {
     native_ipv6
     vrrp_version      3
     state             BACKUP
     interface         eth1
     virtual_router_id 80
     garp_master_delay 5
     advert_int        1
     priority          2
     unicast_src_ip    fe80::10:0:0:2
     unicast_peer {
         fe80::10:0:0:1
         fe80::10:0:0:2
     }
     authentication {
         auth_type PASS
         auth_pass vrrp_pass
     }
     virtual_ipaddress {
         fe80::1                #RA送信用リンクローカルアドレス
         2001:aaaa:bbbb:cccc::1 #RA送信I/Fのユニキャストアドレス
     }
 }

 # vi /etc/radvd/radvd.conf
 --------------------------------------------------
 interface eth0.1 {
     AdvManagedFlag       off;
     AdvOtherConfigFlag   on;
     AdvSendAdvert        on;
     AdvDefaultPreference high;
     MinRtrAdvInterval    30;
     MaxRtrAdvInterval    100;
 
     AdvRASrcAddress {
         fe80::1;
     };
 
     RDNSS 2001:aa:bb:cc::a 2001:aa:bb:cc::b {
     };
 
     prefix 2001:aa:bb:cc::/64 {
         AdvOnLink     on;
         AdvAutonomous on;
         AdvRouterAddr on;
     };
 };