*[[IPv6 PPPoE接続]](NGN経由でのIPv6 Internetのために) [#k1ddb893]
**はじめに [#q614e23a]
>
>ここでは、IPv6をNGN経由のPPPoE接続により提供するプロバイダにLinuxにより接続する方法をメモします。
<
-前提条件

>
>>
+対象のOSはCentOS5.8です。
+インストール時にPPPoEを含む各種のパッケージはすでにインストールされているものとします。~
特に必要なパッケージは~
radvd(radvd-0.9.1-4)~
dhcpv6(dhcpv6-1.0.10-20.el5)~
rp-pppoe(rp-pppoe-3.5-32.1)~
chkconfig(chkconfig-1.3.30.2-2.el5)~
perl(perl関連パッケージ)~
gccおよびKernelヘッダ、ライブラリ群(Wide版dhcpv6のコンパイルに必要)~
です。
+インタフェースeth0を使用してPPPoEを張ると共に、ローカルのNWに接続されているものとします。
<<
<
**準備 [#zb0933be]
***WIDE版DHCPv6パッケージの導入 [#q8e90fc0]
>
>CentOS5では、DHCPv6のパッケージとしてDHCP6cが用意されていますが、Prefix Delegationに対応していないため、WIDE版のDHCPv6パッケージを導入します。
<
-パッケージの取得

>
 # cd /usr/local
 # mkdir dhcpv6
 # wget "http://sourceforge.jp/frs/g_redir.php?m=jaist&f=%2Fwide-dhcpv6%2Fwide-dhcpv6
 %2Fwide-dhcpv6-20080615%2Fwide-dhcpv6-20080615.tar.gz"
 --201x-xx-xx 09:16:13-- http://sourceforge.jp/frs/g_redir.php?m=jaist&f=%2Fwide-dhcpv6
 %2Fwide-dhcpv6%2Fwide-dhcpv6-20080615%2Fwide-dhcpv6-20080615.tar.gz
 sourceforge.jp をDNSに問いあわせています... xxx.xxx.xxx.xxx
 sourceforge.jp|xxx.xxx.xxx.xxx|:80 に接続しています... 接続しました。
 HTTP による接続要求を送信しました、応答を待っています... 302 Found
 場所: http://jaist.dl.sourceforge.net/project/wide-dhcpv6/wide-dhcpv6/wide-dhcpv6-20080615/
 wide-dhcpv6-20080615.tar.gz 
 --20xx-x-02 09:16:13-- http://jaist.dl.sourceforge.net/project/wide-dhcpv6/wide-dhcpv6/
 wide-dhcpv6-20080615/wide-dhcpv6-20080615.tar.gz
 jaist.dl.sourceforge.net をDNSに問いあわせています... xxx.xxx.xxx.xxx, xxxx:xxxx:xxxx:xxxx::xxxx
 jaist.dl.sourceforge.net|xxx.xxx.xxx.xxx|:80 に接続しています... 接続しました。
 HTTP による接続要求を送信しました、応答を待っています... 200 OK
 長さ: 215354 (210K) [application/x-gzip]
 `wide-dhcpv6-20080615.tar.gz' に保存中
 100%[================================================>] 215,354 --.-K/s 時間 0.08s
 20xx-xx-xx 09:16:13 (2.64 MB/s) - `wide-dhcpv6-20080615.tar.gz' へ保存完了 [215354/215354]
 # 
<
-パッケージの展開

>
 # tar zxvf wide-dhcpv6-20080615.tar.gz
 wide-dhcpv6-20080615
 wide-dhcpv6-20080615/addrconf.c
 wide-dhcpv6-20080615/addrconf.h
 .....(省略).....
 wide-dhcpv6-20080615/missing/getifaddrs.c
 wide-dhcpv6-20080615/missing/sys
 wide-dhcpv6-20080615/missing/sys/queue.h
 #
 
<
-ビルド

>
 # cd dhcpv6
 # ./configure
 checking for a BSD-compatible install... /usr/bin/install -c
 checking whether make sets $(MAKE)... yes
 checking for gcc... gcc
 .....(省略).....
 checking for stdarg.h... yes
 configure: creating ./config.status
 config.status: creating Makefile
 # make
 gcc -g -O2 -I. -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=(以下省略)
 .....(省略).....
 gcc  -o dhcp6ctl dhcp6_ctlclient.o base64.o auth.o strlcpy.o strlcat.o arc4random.o -lfl
 #
 
<
-シンボリックリンクの設定

>
 # ln -s /usr/local/dhcpv6/wide-dhcpv6-20080615/dhcp6c /usr/local/dhcpv6/dhcp6c
<
-クライアントキーの作成

>
 # openssl rand -base64 16 > /usr/local/etc/dhcp6cctlkey
>>
>>既存のCentOSディストリビューションに含まれるdhcp6バイナリ群との競合/上書きを避けるため、''make install は実行しません。''
<<
<
***アドレスフォーマット変換ツールの設定 [#t89501e9]
>
>起動スクリプトで使用するIPv6アドレスフォーマット変換のPerlスクリプトを設定します。
>ファイルは /opt/ipv6_tools/ipv6_conv として作成します。作成後、実行可能なようにモードを a+x で変更してください。
<
>
 #!/usr/bin/perl -w
 #######################################################################################
 #                       IPv6 address format converter
 #
 # File Name:
 #       ipv6_conv
 #
 # Descriptions:
 #       ipv6_conv converts standard ipv6 address nortation to non zero suppress notation
 #
 #       option -r/--reverse:    print reverse format for DNS
 #       option -a/--all:        print non zero suppress notation and reverse format
 #
 # History(Change log):
 #       Version 1.0.0   2011.12.29      jj1req@ca.mbn.or.jp
 #               first appeared
 #
 #       CURRENT_VERSION="1.0.0"
 #
 #                       Copyright (c) 2011 Kazuhiro WATANABE
 #######################################################################################
 use strict;
 use Getopt::Long;                               # get commandline options
 #==================================================================
 # subroutines
 #==================================================================
 #******************************************************************
 # convert standard ipv6 address notation to non zero suppress notation
 #******************************************************************
 sub expand_ipv6( $ )
 {
         my @address;
         my @hex_adr;
         my $ipv6 = $_[0];
         if( $ipv6 =~ m/::/ )
         {
                 # expand the short form expression to long form.
                 my ( $adr_a, $adr_b ) = split( /::/, $ipv6 );
                 my @adr_a = split( /:/, $adr_a );
                 my @adr_b = split( /:/, $adr_b );
                 for (scalar @adr_a .. 7 - scalar @adr_b)
                 {
                         push( @adr_a, 0 );
                 }
                 @address = (@adr_a, @adr_b);
         }
         else
         {
                 @address = split( /:/, $ipv6 );
         }
         return( @address );
 }
 #******************************************************************
 #       non option
 #******************************************************************
 sub conv_nonzero( $ )
 {
         my @address = &expand_ipv6( $_[0] );
         my $ipv6 = sprintf( "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
                 hex($address[0]), hex($address[1]), hex($address[2]), hex($address[3]),
                 hex($address[4]), hex($address[5]), hex($address[6]), hex($address[7])
          );
         return( $ipv6 );
 }
 #******************************************************************
 #       reverse option
 #******************************************************************
 sub conv_reverse( $ )
 {
         my @address = &expand_ipv6( $_[0] );
         my $ipv6 = sprintf( "%04x%04x%04x%04x%04x%04x%04x%04x",
                 hex($address[0]), hex($address[1]), hex($address[2]), hex($address[3]),
                 hex($address[4]), hex($address[5]), hex($address[6]), hex($address[7])
          );
         my $i;
         my $str;
         my $rev = substr( $ipv6, 31, 1 );
         for( $i=30; $i>=0; $i-- )
         {
                 $str = substr( $ipv6, $i, 1 );
                 $rev = join( ".", $rev, $str );
         }
         return( $rev );
 }
 #==================================================================
 #               Main
 #==================================================================
         my $opt_rev = 0;
         my $opt_all = 0;
         my $ipv6;
         GetOptions( 'reverse' => \$opt_rev, 'all' => \$opt_all );
         if( @ARGV != 1 )
         {
                 $ipv6 = <STDIN>;
                 chomp( $ipv6 );
         }
         else
         {
                 $ipv6 = $ARGV[0];
         }
         unless( $ipv6 =~ /^[0-9a-fA-F:]+$/ )
         {
                 print( " Error! argument includes unrecognized character: " . $ipv6 . "\n" );
                 exit(1);
         }
         if( $opt_all == 1 )
         {
                 print( &conv_nonzero( $ipv6 ) . "\n" );
                 print( &conv_reverse( $ipv6 ) . "\n" );
                 exit(0);
         }
         if( $opt_rev == 1 )
         {
                 print( &conv_reverse( $ipv6 ) . "\n" );
         }
         else
         {
                 print( &conv_nonzero( $ipv6 ) . "\n" );
         }
         exit(0);
 #******************************************************************
 #               End of code.
 #******************************************************************
 
<
**DHCP6cの設定 [#n360af0a]
>
>次に導入したWIDE版DHCP6cに対する設定を行います。
>対象のコンフィグファイルは /etc/dhcp6c.conf です。
 #
 # /etc/dhcp6c.conf
 #
 interface ppp0 {
         send ia-pd 0;
 };
 id-assoc pd 0{
         prefix-interface eth0 {
                 sla-id 1;
                 sla-len 0;
         };
 };
 
<
**PPPoEの設定 [#lbd47b72]
>
>PPPoEの設定を行います。PPPoEへの接続情報はあらかじめプロバイダからの情報を確認しておいてください。
<
-設定ファイル~
対象のファイルは /etc/sysconfig/network-scripts/ifcfg-ppp0 です。

>
 # NGN IPv6 Tunnel
 # Refer to
 #     http://www.gcd.org/blog/2011/06/812/
 #     http://www.wandin.net/dotclear/index.php?post/2011/02/10/Native-IPv6-with-Internode-
 and-CentOS
 #     http://www.ln-lab.net/lunar-night.lab/Memo/OCNIPv6/ocnipv6.html
 #     http://lists.centos.org/pipermail/centos/2008-July/060532.html
 #
 USERCTL=yes
 BOOTPROTO=dialup
 NAME=DSLppp0
 DEVICE=ppp0
 TYPE=xDSL
 ONBOOT=no
 #
 # Ethernet Interface Name
 ETH=eth0
 #
 # process id file
 PIDFILE=/var/run/pppoe-adsl.pid
 #
 # Don't set Firewall
 #
 FIREWALL=NONE
 #
 # print strings waiting for start up
 PING=.
 #
 # clamp advised MSS to 1412 byte
 CLAMPMSS=1412
 #
 #DEFROUTE=yes
 # Don't use synchronous PPP
 SYNCHRONOUS=no
 #PROVIDER=DSLppp0
 # keep connection
 DEMAND=no
 #
 # User
 USER=xxxxxxx@xxx.xxx.xxx.xxx
 #
 # PPPD Configuration
 # Time out of start up (sec)
 CONNECT_TIMEOUT=10
 #
 # check delay time(sec) for start up
 CONNECT_POLL=2
 #
 PPPD_EXTRA="ipv6 ,"
 #
 # PPPoE Configuration
 # watch dog time(sec) for PPPoE
 PPPOE_TIMEOUT=80
 #
 # retry count for LCP Echo
 LCP_FAILURE=3
 #
 # send interval of LCP Echo
 LCP_INTERVAL=20
 #
 # no request DNS server info.
 #USEPEERDNS=no
 PEERDNS=no
 #
 # IPv6 Configuration
 IPV6INIT=yes
 IPV6_AUTOCONF=no
 
<
-パスワード~
パスワードを次のファイルに設定します。 /etc/ppp/chap-secrets

>
 # Secrets for authentication using CHAP
 # client        server  secret                  IP addresses
 "xxxxxx@xxx.xxx.xx.xx"     *       "(パスワードを入れる)"
 
<
**起動スクリプト [#q76edf55]
>
>実際にPPPoEを張るために、起動スクリプトを用意します。chkconfig により自動起動が可能なように記述します。
>ファイルは /opt/ipv6_tools/ipv6_control.sh として作成します。作成後、実行可能なようにモードを a+x で変更してください。
<
>
 #! /bin/sh
 #
 #
 #   Startup/shutdown script for ipv6_control
 #
 #   Linux chkconfig stuff:
 #
 #   chkconfig: 2345 12 88
 #   description: Startup/shutdown script for ipv6_control
 #   pidfile:
 #
 #   Copyright 2012 Kazuhiro WATANABE
 #
 #   These coded instructions, statements, and computer programs are the
 #   property of kazuhiro WATANABE.
 #
 # Source function library.
 . /etc/init.d/functions
 IP_ADDR_CONV="/opt/ipv6_tools/ipv6_conv"
 PPPD_START_COMMAND="/usr/sbin/adsl-start"
 PPPD_STOP_COMMAND="/usr/sbin/adsl-stop"
 PPPD_CONFIG="/etc/sysconfig/network-scripts/ifcfg-ppp0"
 PPPD_PID_FILE="/var/run/ppp0.pid"
 DHCP6C_START_COMMAND="/usr/local/dhcpv6/dhcp6c"
 DHCP6C_STOP_COMMAND="killproc dhcp6c"
 DHCP6C_CONFIG="/etc/dhcp6c.conf"
 LAN_IF="eth0"
 PPP_IF="ppp0"
 RETVAL=0
 start_ipv6() {
     test=`/sbin/ifconfig | /bin/grep ${PPP_IF}`
     if [ -n "$test" ] ; then
         echo "${PPP_IF} is already up"
     return 1
     fi
     echo -n $"Starting PPP Connection: "
     # start ppp connection
     ${PPPD_START_COMMAND} ${PPPD_CONFIG} > /dev/null 2>&1
     if [ -e $PPPD_PID_FILE ] ; then
         echo_success;
         /bin/logger -i -p user.info -t ipv6_control "Start PPP Connection: OK"
     else
         echo_failure;
         /bin/logger -i -p user.info -t ipv6_control "Start PPP Connection: NG"
     fi
     echo
     echo -n $"Starting IPv6 DHCP Client: "
     # start dhcp6 client
     ${DHCP6C_START_COMMAND} -c ${DHCP6C_CONFIG} ${PPP_IF} > /dev/null 2>&1
     if [ $? == 0 ] ; then
         echo_success;
         /bin/logger -i -p user.info -t ipv6_control "Start IPv6 DHCP Client: OK"
     else
         echo_failure;
         /bin/logger -i -p user.info -t ipv6_control "Start IPv6 DHCP Client: NG"
     fi
     echo
     echo -n $"Setup routing: "
     # del default gateway
     /sbin/ip -6 route del default > /dev/null 2>&1
     # add default gateway
     /sbin/ip -6 route add default dev ppp0  > /dev/null 2>&1
     if [ $? == 0 ] ; then
         echo_success;
         /bin/logger -i -p user.info -t ipv6_control "Setup routing: OK"
     else
         echo_failure;
         /bin/logger -i -p user.info -t ipv6_control "Setup routing: NG"
     fi
     echo
 }
 stop_ipv6() {
     echo -n $"Delete routing: "
     # del default gateway
     /sbin/ip -6 route del default dev ppp0 > /dev/null 2>&1
     if [ $? == 0 ] ; then
         echo_success;
         /bin/logger -i -p user.info -t ipv6_control "Delete routing: OK"
     else
         echo_failure;
         /bin/logger -i -p user.info -t ipv6_control "Delete routing: NG"
     fi
     echo
     echo -n $"Stopping IPv6 DHCP Client: "
     # stop dhcp6 client
     /usr/bin/killall ${DHCP6C_START_COMMAND}  > /dev/null 2>&1
     if [ $? == 0 ] ; then
         echo_success;
         /bin/logger -i -p user.info -t ipv6_control "Stop IPv6 DHCP Client: OK"
     else
         echo_failure;
         /bin/logger -i -p user.info -t ipv6_control "Stop IPv6 DHCP Client: NG"
     fi
     echo
     test=`/sbin/ifconfig | /bin/grep ${PPP_IF}`
     if [ -z "$test" ] ; then
         echo "${PPP_IF} is already down"
         return 1
     fi
     echo -n $"Stopping IPv6 PPP Connection: "
     # stop ppp connection
     ${PPPD_STOP_COMMAND} ${PPPD_CONFIG} > /dev/null 2>&1
     killproc pppd
     echo_success;
     /bin/logger -i -p user.info -t ipv6_control "Stop PPP Connection: OK"
     echo
 }
 show_address() {
     sleep 2
     IP_ADDR=`/sbin/ifconfig | /bin/grep "/56" | /bin/sed -e "s/.*inet6 addr: \(.*\)\/56.*$/\1/"`
     if [ "${IP_ADDR} != "" ]; then
 echo -n "  assigned Grobal address = "
         echo "${IP_ADDR}"
         echo -n "  Prefix(64) address = "
         IP_ADDR_LOG=`${IP_ADDR_CONV} ${IP_ADDR}`
         PREFIX_64=`echo "${IP_ADDR}" | /bin/sed -e "s/\(.*:.*:.*:.*\):.*:.*:.*:.*$/\1/"`
         echo  "${PREFIX_64}"
         /bin/logger -i -p user.info -t ipv6_control "IPv6 Address = ${IP_ADDR}(${PREFIX_64}/64)"
     else
 echo "No IPv6 Address is assigned"
         /bin/logger -i -p user.info -t ipv6_control "No IPv6 Address is assigned"
     fi
 }
 set_ipaddress() {
     /sbin/ip -6 route del default via fe80::xxxx:xxxx:xxxx:xxxx dev eth0
     /sbin/ip -6 addr add ${PREFIX_64}::xxxx/64 dev ${LAN_IF}
 }
 del_ipaddress() {
     /sbin/ip -6 route del ${PREFIX_64}::/64 dev ${LAN_IF}
     /sbin/ip -6 addr del ${PREFIX_64}::xxxx/64 dev ${LAN_IF}
     /sbin/ip -6 route add default via fe80::xxxx:xxxx:xxxx:xxxx dev eth0
 }
 start_radvd() {
     /bin/cat > /etc/radvd.conf <<EOF
 interface eth0
 {
     AdvSendAdvert on;
     AdvOtherConfigFlag on;
     MinRtrAdvInterval 30;
     MaxRtrAdvInterval 100;
     prefix ${PREFIX_64}::/64
     {
         AdvOnLink on;
         AdvAutonomous on;
         AdvRouterAddr off;
     };
 };
 EOF
     /sbin/service radvd start
 }
 stop_radvd() {
     /sbin/service radvd stop
 }
 start_dhcp6s() {
     /bin/cat > /etc/dhcp6s.conf <<EOF
 interface ${LAN_IF} {
     server-preference 255;
     renew-time 60;
     rebind-time 90;
     prefer-life-time 130;
     valid-life-time 200;
     allow rapid-commit;
     option dns_servers ${PREFIX_64}::xxxx;
     link AAA {
         range ${PREFIX_64}::ffff:1 to ${PREFIX_64}::ffff:100/64;
     };
 };
 EOF
     /sbin/service dhcp6s start
 }
 stop_dhcp6s() {
     /sbin/service dhcp6s stop
 }
 case $1 in
     start)
         /bin/logger -i -p user.info -t ipv6_control "Start IPv6 Control scripts..."
         start_ipv6
         show_address
         set_ipaddress
         start_radvd
         start_dhcp6s
         /bin/logger -i -p user.info -t ipv6_control "IPv6 Control scripts done."
         ;;
     stop)
         /bin/logger -i -p user.info -t ipv6_control "Stop IPv6 Control scripts..."
         show_address
         stop_dhcp6s
         stop_radvd
         del_ipaddress
         stop_ipv6
         /bin/logger -i -p user.info -t ipv6_control "IPv6 Control scripts done."
         ;;
     *)
         echo $"Usage: $0 {start|stop}"
         exit 3
     esac
 exit $RETVAL
 
<
**Chkconfigによる自動起動設定 [#t479e03b]
-リンクの設定

>
 # ln -s /opt/ipv6_tools/ipv6_control.sh /etc/init.d/ipv6_control
 
<
-登録

>
 # chkconfig --add ipv6_control
 # chkconfig --list ipv6_control
 ipv6_control    0:off   1:off   2:on    3:on    4:on    5:on    6:off
 #
 
>以上により自動サーバ起動時に自動的にPPPoEによりIPv6接続されます。
<
**起動 [#r60859aa]
>
>まず、コマンドベースで起動してみます。
<
>
 # service ipv6_control start
 Starting PPP Connection:                                   [  OK  ]
 Starting IPv6 DHCP Client:                                 [  OK  ]
 Setup routing:                                             [  OK  ]
 assigned Grobal address = xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
 Prefix(64) address = xxxx:xxxx:xxxx:xxxx
 RTNETLINK answers: No such process
 radvd を起動中:                                            [  OK  ]
 dhcp6s を起動中:                                           [  OK  ]
 #
<
**Log [#rb2e421d]
>
>ログはSyslogに User facilityで出力されます。Syslogの設定を変更していない場合は/var/log/messageに出力されます。なるべくuserファシリティは別ファイルに出力するように /etc/syslog.confを変更し、logrotateでログのローテーション設定を行ってください。
<

以上です。

お疲れ様でした。


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS