IPv6非対応のISPでIPv6接続をしてみた

現在お世話になっているISPはIPv6デュアルスタックに対応していないため、自宅でのIPv6環境はあきらめていたんですが、どうやら無料のトンネルサービスがあるということに、一昨日BGPのピアを調べていたら気付きました。
いわずと知れた bgp.he.net です。

Free IPv6 Tunnel を見た瞬間にキター!って感じでした。

さっそくレジストしてRTX1200に設定を入れてみたんですが、参考になるサイトもいくつかあり、30分ほどで無事ルータから、IPv6を持っている自分のDTIのVPSにping6で疎通できることができました。
投入した設定は以下のような感じです。

ipv6 routing on
ipv6 route default gateway tunnel 3
ipv6 prefix 1 2001:470:xx4:xx::/64 ← 自分に割り当てられたセグメント
ipv6 lan1 address 2001:470:xx4:xx::1/64 ← ルータのLAN側(DMZ)側IP
ipv6 lan2 address 2001:470:xx3:xx::2/64 ← トンネル側IP

tunnel select 3
 tunnel encapsulation ipip
 tunnel endpoint address 192.168.0.1 74.82.46.6 ← ローカルアドレスと対向IP
 ip tunnel mtu 1280 ← コンパネにMTUの設定があるので事前に変更しておく
 ipv6 tunnel address 2001:470:xx3:xx::1/64 ← ピア相手のIP
 tunnel enable 3

nat descriptor masquerade static 1 9 192.168.0.1 ipv6 ← IPv6を許可

これで疎通自体はすぐできるようになりました。

こんどはクライアントのためにDHCPの設定を追加しました。

ipv6 lan1 rtadv send 1 o_flag=on
ipv6 lan1 dhcp service server

これでIPv6が有効になっているWindows7で特になにもせずにIPv6サイトにつながるようになりました。

test-ipv6でDNSだけ怒られたので、IPv6のプロパティから コンパネに書いてあるHurricane Electricのキャッシュサーバを指定したところ10/10のスコアがでました。
DNSもルータ側でなんとかしたいですね。これは宿題です。

自分はRTX1200で設定しましたが、本家でIOSとかvyattaとかいろんなOSの設定サンプルが見れるようになっています。

案外簡単ですね、これは地味に普及するかも。

ip_vsのhash tableについて調べてみた

ipvsadm -Ln しか使わない現場も多いと思います。
しかしip_vsについてちょっと気になって調べてみたらものすごい奥が深いことがわかりました。

自分の会社ではほぼすべてのトラフィックをグローバルIPを持たせたLVSマシンで受けています。
また提供しているサービスの特性で、ipvsadmのタイムアウトを短くしていても、多いときで30万ちょっとくらいのセッションがあります。

ipvsadm -Ln でも確認できるのですが、ipvsadm -Lnc | wc -l を以前から使っていました。
これはip_vsが保持しているセッションのリストを表示するオプションです。

とまあ、ここまでは理解していたんですが、 netfilterとかチューニングしてる過程でハッシュのチューニングとかしたし、何十万本もコネクションリストもってるip_vsも、実はコネクションリストを高速でスキャンするためのハッシュ領域があるんじゃね?と、思い調べ始めました。

ちなみに、ip_vsは新しいコネクションを作ろうとするたびにすべてのコネクションリストを評価する、とどこかに書いてありました。どこかに。何十万もセッションがある状態で、ハッシュが効率よく使われていないとしたら、恐ろしいCPUのリソースを無駄に消費してることになります。

調べたところハッシュの実体はすぐ見つかりました。以下の size=4096 です。

$ sudo ipvsadm -L                                                                                 
IP Virtual Server version 1.2.1 (size=4096)

果たしてこの値が最適なのか、変更できるかは以下のリンクを参考にしました。

http://daretoku-unix.blogspot.jp/2011/04/ipvs.html

IPVS 接続ハッシュテーブルはハッシュの衝突を扱うのにチェイニングスキーム
を使っています。大きなIPVS接続ハッシュテーブルを使うと100,000単位の
コネクションを扱う場合においてハッシュテーブルの衝突を大きく減らします。

デフォルト値ではせいぜい10万くらいがいいところというみたいです。
また実メモリの使用量なども書いてありますが、計算すればいいだけなので割愛します。

値の増やし方は以下のリンクを参考にしました。

http://kb.linuxvirtualserver.org/wiki/Performance_and_Tuning

カーネルを再構築しないとダメみたいです。

やたらめったらコネクションが多い場合は増やしたほうがいいということですね。
また自分の現場では設定済みですが、コネクションはタイムアウトを短くすることで減らすことができます。netfilterと一緒ですね。

ipvsadm --set tcp tcpfin udp(それぞれ秒)

そしてここまで調べて気になったのが”ハッシュの衝突”という表現です。

衝突したらコネクションは破棄されてしまうのか?もしかしてリハッシュとかしてCPUに余計なコストがかかってるんじゃないか?
など、気になり調べてみたんですが、ここまでくるとインフラではなくプログラミングのアルゴリズムの話です。

”ハッシュの衝突を扱うのにチェイニングスキーム”を使う、とドキュメントには書いてあります。
チェイニングスキームについてすぐ出てきたドキュメントが以下のリンクになります。(wikipediaですが・・・)

http://en.wikipedia.org/wiki/Hash_table#Separate_chaining

同じハッシュに複数の値が入るというアルゴリズムのようです。

プログラムをしっかり勉強した方ならわかると思いますが、ハッシュがコリジョンする確率とか、その場合の回避方法をいくつかしっていると思います。

ip_vsはパフォーマンスをできる限り優先するために、チェイニングスキームで多少コストがかかっても、生のコネクションリストをなめるよりはるかに早いので、多くのハッシュエントリーを確保して、コネクションリストをできるかぎり高速でスキャンするという設計思想みたいです。

ハッシュの衝突を回避するためには、そもそも箱を大きくすれば当たらないということですね。
デフォルトが小さすぎるんです。

ついでなんですが、32bitだと95%の確立を保てるのは15万前後のようです。

http://preshing.com/20110504/hash-collision-probabilities

興味深いですね。
誕生日パラドックスとか誕生日攻撃とか、ついでにいろいろ調べていて目に入りました。

知れば納得です。
こんどはnetfilterのハッシュの扱いについて調べてみようと思います。

当然ですがカーネルを再構築したところ確かにふえました。

$ sudo ipvsadm -L
IP Virtual Server version 1.2.1 (size=1048576)
Prot LocalAddress:Port Scheduler Flags
 -> RemoteAddress:Port Forward Weight ActiveConn InActConn