以前作成したalixなブロードバンドルータをフリービットのFeel6接続サービスを使ってIPv6に対応させてみました。
この手の作業は同じlinuxでもディストリビューションや環境に左右されるので、まず今回の環境をまとめておきます。
- インターネット接続:NTT東日本 Bフレッツ + 固定IP
- ブロードバンドルータHW:Alix 2C3
- ブロードバンドルータSW:Debian lenny (eth0:Global ipv4 addr, eth1:192.168.1.1, eth2:192.168.10.1)
- DTCPクライアント:自作Perlスクリプト
- RAサーバ:debian lenny付属のradvdパッケージ from http://v6web.litech.org/radvd/dist/
- クライアント1:Ubuntu 8.04 x86_64 (192.168.1.x)
- クライアント2:Mac OS X 10.6.2 (192.168.1.x)
- Feel6接続サービスへの登録
- DTCP接続を試してみる
- AlixをIpv6ルータとして構成する
- DTCPの出力からAlixにIPv6アドレスを付与する
- 実際にIPv6環境を構築していく
- radvdクライアントの起動
- クライアントの接続確認
- さいごに
Feel6接続サービスへの登録
IPv6なネットワークに接続する方法はいくつかありますが、今回はフリービットのサービスを使う事にしました。 固定IPを使っているので静的にトンネルを作ってもらっても良かったのですが、将来プロバイダを変更するかもしれないですしね。
登録はFeel6のトップページから必要事項を送信するだけです。
DTCP接続を試してみる
Feel6のサーバにIPv6ネットワークへのトンネルを作ってもらうわけですが、その情報のやりとりはDTCPというプロトコルを使用するようです。 ここら辺の解説は「Linux 上で DTCP を使って IPv6 over IP トンネルを張る」がとても参考になりました。
検索してみるとDTCPの使い方としては、次のような方法がありました。
- DTCPクライアントを自作する方法
- USAGIプロジェクトが配布しているdtcpcコマンドを使用する方法
「Linux 上で DTCP を使って IPv6 over IP トンネルを張る」にある"setup-dtcp"スクリプトやUSAGIプロジェクトのdtcpcを使ってみました。しかし内部で呼び出しているコマンドの実行に失敗するなど簡単にはできなかったため"setup-dtcp"の元になったスクリプトをベースに手作業でコマンドを実行していきました。
DTCPクライアントの自作
最終的には作り直したのですが、まずは参考にしたPerlスクリプトでトンネル状態を維持する事にしました。 参考にしたページにあるスクリプトでは変数定義が抜けているのと、Feel6から貰ったIPv6アドレスがわからないので出力ようにして、だいたい次のようなコードを追加しています。
#!/usr/bin/perl
my $host = "dtcp.feel6.jp";
my $port = 20200;
my $user = "xxxxxx";
my $pass = "xxxxxx";
...
($local, $remote, $prefix, $nbits) = ($1, $2, $3, $4);
printf(STDERR "local=%s,remote=%s,prefix=%s,nbits=%s\n", $1, $2, $3, $4);
} else {
...
ここで$userと$passには、Feel6登録時に入力したものを記入します。 実行に成功すると4つの文字列が手に入ります。
DTCPクライアントは接続を維持するために毎分PINGメッセージを送信しています。 そのためIPv6を使う間はずっと起動しておく必要があります。
AlixをIpv6ルータとして構成する
ここからはDTCPクライアントが裏側で動いている前提で書いています。
Feel6とは関係なしにBフレッツを使っているとNTTからIPv6アドレスが付与されます。 ただしこれは/64なプリフィックスなので、サブネット用に番号を加える事ができません。 また他の方のブログなどをみるとオプションを申し込まないと、NTTが準備したコンテンツ以外にアクセスする事は難しいようです。
Alixで確認すると、NTTから自動的に割り当てられるこのアドレスは以前Alixをルータにする投稿の中で、Bフレッツとの接続に使ったeth0に割り当てられています。
eth0 Link encap:イーサネット ハードウェアアドレス 00:0d:xx:xx:xx:xx
inet6アドレス: 2001:c90:489e:xxxx:xxxx:xxxx:xxxx:xxxx/64 範囲:グローバル
inet6アドレス: fe80::xxxx:xxxx:xxxx:xxxx/64 範囲:リンク
...
Feel6から付与されるプリフィックスは/48ですから、前半64bitの残り16bit(0xffff分)を使ってネットワークを分割する事が可能になります。IPv4ではeth1, eth2でネットワークを分けているので、それにならってIPv6でもeth1, eth2でサブネットを設定する事にしました。
IPv6ルータになるための設定項目
Bフレッツ用のIPv6アドレスが割り当てられていた理由は、lennyのデフォルトとしてRouter Advertisement(RA)を受け付けるようになっている事に起因します。 ルータ自身がRAに反応しては困るらしくsysctlの設定を変更します。
Fee6を使う場合はRAを有効にしても大丈夫なんじゃないかという気はしつつ、先達に習うことにしました。 その他のアイデアとしてはeth0ではRAを受信してNTTのアドレスを構成しつつ、eth1, eth2はRAを無視して自分でアサインする、という構成も考えられましたが今回は試していません。
...
net.ipv6.conf.all.accept_ra=0
net.ipv6.conf.all.accept_redirects=0
net.ipv6.conf.all.forwarding=1
...
また直接は関係ないですが、この他にsysctl.confではipv6関連の設定を2つ行なっています。
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_source_route = 0
proc経由での設定変更について
sysctl.conf周りの設定は/procファイルシステムを通しても可能で、IPv6を説明した多くのサイトで$ echo 1 > /proc/sys/net/ipv6/conf/all/accept_raのようなコードが書かれています。 しかし恒久的な変更には/etc/sysctl.confファイルを使いましょう。
procに"0"や"1"を書き出したいが、sudoを使わないとという場合にはteeコマンドを使いましょう。
$ echo 1 | sudo tee /proc/sys/net/ipv6/conf/all/accept_ra
DTCPの出力からAlixにIPv6アドレスを付与する
DTCPクライアントの出力から次のような情報が得られています。
- local - 自分のGlobal IPアドレス:219.117.xxx.xxx
- remote - Feel6への接続用IPアドレス:43.244.xxx.xx
- prefix - IPv6接続に使用するプリフィックス:2001:03xx:xxxx::/48
Alixの各インタフェースに割り当てる情報を決めていく
prefixは最後の2byte(16bit)が空いているので、ここを埋めてeth1, eth2にどのようなサブネットを設定するか考えます。 何でも良いのですが、IPv4に合わせて最後は0001,0010としました。
- eth1 prefix - 2001:03xx:xxxx:1::/64
- eth2 prefix - 2001:03xx:xxxx:10::/64
ここまでを踏まえてそれぞれのIPv6アドレスを決めました。 アドレスは何でも良いですが、"192.168.1.1", "192.168.10.1"を16進数に変換した"c0a8:0101", "c0a8:a101"を使う事にしました。
- eth1 ipv6 addr - 2001:03xx:xxxx:1::c0a8:0101/64
- eth2 ipv6 addr - 2001:03xx:xxxx:10::c0a8:0a01/64
ただしalixから外部に通信する必要がなければサイトローカルユニキャストアドレス(fe80::/64)で十分なはずで、必要だとしても2つも追加する必要はなかったりします。 まぁどちらかのデバイスをダウンさせる事もあるかもしれないので、こういう設定にしてみました。
実際にIPv6環境を構築していく
情報は決まったのでコマンドをパチパチ打っていきます。
トンネルの構築
remoteアドレスをベースにsit0, sit1インタフェースを構成します。
$ sudo /sbin/ifconfig sit0 up tunnel ::43.244.xxx.xx
Alixではiptablesを構成しているので、通常の構成ではカプセル化したパケットが出ていきません。 dropしたパケットのログをみると次のようになっています。
...
[135368.059979] netfilter drop IN= OUT=ppp0 SRC=219.117.xxx.xxx DST=43.244.xxx.xx LEN=124 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=41
...
[136225.974684] netfilter drop IN=ppp0 OUT= MAC= SRC=43.244.xxx.xx DST=219.117.xxx.xxx LEN=124 TOS=0x00 PREC=0x00 TTL=246 ID=16480 PROTO=41
...
このproto=41を通すためにiptablesに設定を追加します。
iptables -A inppp -s 43.244.xxx.xx --proto 41 -j ACCEPT iptables -A outppp -d 43.244.xxx.xx --proto 41 -j ACCEPT
ルーティング情報の設定
eth0にはBフレッツから割り当てられたアドレスが付いています。 当然デフォルトゲートウェイはeth0に向いているので、このルーティングを削除しつつ、Feel6に変更する設定を行ないます。
$ sudo /sbin/route -A inet6 del ::/0 dev eth0 $ sudo /sbin/route -A inet6 add ::/0 dev sit1
eth1, eth2にIPv6アドレスを付与する
外部との通信に使用するために、IPv6でいうところのグローバルユニキャストアドレスを追加します。
$ sudo /sbin/ip -f inet6 addr add 2001:03xx:xxxx:1::c0a8:0101/64 dev eth1 $ sudo /sbin/ip -f inet6 addr add 2001:03xx:xxxx:10::c0a8:a101/64 dev eth2
ここまでの稼働確認
おそらくping6は既にインストールされていると思うので、これを使って接続が確立しているか確認します。
$ ping6 www.kame.net $ ping6 2001:200:0:8002:203:47ff:fea5:3085
PING www.kame.net(orange.kame.net) 56 data bytes
64 bytes from orange.kame.net: icmp_seq=1 ttl=54 time=14.2 ms
64 bytes from orange.kame.net: icmp_seq=2 ttl=54 time=13.3 ms
PING 2001:200:0:8002:203:47ff:fea5:3085(2001:200:0:8002:203:47ff:fea5:3085) 56 data bytes
64 bytes from 2001:200:0:8002:203:47ff:fea5:3085: icmp_seq=1 ttl=54 time=14.6 ms
64 bytes from 2001:200:0:8002:203:47ff:fea5:3085: icmp_seq=2 ttl=54 time=13.5 ms
生のIPv6アドレスはwww.kame.netのものです。 将来的に変更されているかもしれないので、nslookupでアドレスを確認してからping6に渡してください。
$ nslookup -type=AAAA www.kame.net
$ nslookup -type=AAAA www.kame.net
Server: 192.168.1.x
Address: 192.168.1.x#53
Non-authoritative answer:
www.kame.net has AAAA address 2001:200:0:8002:203:47ff:fea5:3085
....
もしping6がインストールされていなければ、iputils-pingパッケージを導入してください。 nslookupはdnsutilsパッケージに含まれています。
$ sudo apt-get install iputils-ping
ここまでうまく行けば、radvdクライアントを動かすか、クライアント側を適切に設定すればIPv6ネットワークに接続する事ができるようになります。
トラブルシュート
もしping6の実行に失敗してデバイスを指定する次のようなコマンドが成功するとしたら、ルーティング情報が間違っているはずです。
$ ping6 -I sit1 2001:200:0:8002:203:47ff:fea5:3085
またping6実行時にping: sendmsg: Operation not permittedメッセージが出力されているとすれば、iptablesの設定に失敗しているか、ip6tablesが設定されているのが原因でしょう。
いまはIPv6用のfirewallは素通しの状態になっているはずで、次のコマンドでデフォルトが"(policy ACCEPT)"になっている事を確認します。
sudo /sbin/ip6tables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
radvdクライアントの起動
Alixではパッケージで配布されているradvdコマンドを使用します。
$ sudo apt-get install radvd
今回は次のような設定ファイルを準備しました。
interface eth1
{
AdvSendAdvert on;
MinRtrAdvInterval 3;
MaxRtrAdvInterval 10;
prefix 2001:03xx:xxxx:1::/64
{
AdvOnLink on;
AdvAutonomous on;
};
};
interface eth2
{
AdvSendAdvert on;
MinRtrAdvInterval 3;
MaxRtrAdvInterval 10;
prefix 2001:03xx:xxxx:10::/64
{
AdvOnLink on;
AdvAutonomous on;
};
};
最後にradvdを起動して終りです。
$ sudo /etc/init.d/radvd start
radvdの初期設定について
パッケージに含まれる通常の構成だとAlixの再起動時に自動的にradvdが起動します。 これが悪いとはいいませんが、トンネルの構成をまだ自動化していないので意図しないタイミングでradvdが起動してしまうかもしれません。
今回はradvdを制御する目的で明示的に/etc/init.d/radvdスクリプトを実行する事にして、自動起動は停止する事にしました。
$ sudo mv /etc/rc2.d/S50radvd /etc/rc2.d/K50radvd
クライアントの接続確認
本当は手動でルーティングをしていたのですが、radvdを使う方法を書く事にしたのでクライアント側でする事はあまりありません。 Ubuntu 8.04 x86_64以外にMac 10.6でもブラウザをいくつか立ち上げて確認をしています。
Ubuntu 8.04での稼働確認
accept_raは有効になっているので、基本的にIPアドレスはすでに割り当てられていました。 しかしufwを有効にしているせいかip6tablesのデフォルトポリシーがDROPになっていたためping6の実行に失敗しました。
ip6tablesの構成は後でする事にして、いまは全部の通信を許可しています。
$ sudo /sbin/ip6tables -P INPUT ACCEPT $ sudo /sbin/ip6tables -P OUTPUT ACCEPT $ sudo /sbin/ip6tables -P FORWARD ACCEPT
とりあえずWebブラウザだけを使って、keme.netの亀が踊るかどうか確認します。
http://www.kame.net/
Mozilla Firefox 3.0.17, Google Chromium 5.0.315.0 (37939) Ubuntu, Opera 10.10で確認しました。 結果としてOperaだけがIPv4で接続していました。
OperaはIPv6周りののバグ対策として、とりあえずIPv6を使えなくしたようですね。 一時的とはいえ後ろ向きな感じがしなくてはない対応ですが、フレームワークの問題で抜本的な対策が難しかったのかなぁ…。
Mac 10.6での稼働確認
Ubuntu同様に自動的にグローバルアドレスを受信しているので、Safariなどで何も考えなくても亀が踊っています。Opera 10.10を試してみたところやはりIPv6では接続できませんでした。
さいごに
Bフレッツのアドレスを使えるのであれば、eth0とbound0を組んでradvdだけ起動してしまえば使えそうな気もします。 それにサブネットを分ける必要性があるのか、という気もします。 まぁせっかくalixにはNICが3つも付いているので、これもまた良いでしょう。
しかし、一応動いているとはいえ頭の中が完全にIPv4のネットワークのマナーに染まっているので、IPv6的な考え方がまったくできていないと実感しています。 ここに書いた対応も成功事例ではありますが、本当のベストプラクティスとはいえないところがあるだろうと思います。まぁしばらくIPv6で遊んでみるつもりです。
この後の残作業はFirewall周りの他に、基本的なところでDTCPクライアントからeth1, eth2にサブネットワークを構成して、そのアドレスを反映したradvd.confを作成するところまでを自動化する必要があります。
まっさらなところからの自動化自体は簡単ですが、途中からのやり直しなんかを考えると、各作業の粒度を考えて個別のスクリプトにしないと安定しそうにありません。これも少し時間を考えて試行錯誤したいと思います。
とりあえずは次のステップはfirewallの設定ですかね。
0 件のコメント:
コメントを投稿