仙石浩明の日記

2006年

2006年4月4日

人の上に立とう (1)

人の上に立とう、といっても、威張りちらしたい、というわけではない。 相手より高い視点を持てるよう努力しよう、ということだ。

大局的な判断ができる人がリーダシップをとり、 局所的な判断しかできない人は、その指示に従うことになる。 上司が指示を出し、部下がそれに従う、というわけではない。 もちろん指揮命令系統が決められている場合は、 そこから逸脱するのは難しいかも知れないが、 職種が違う場合はどうだろう?

セールスがお客様の言葉を錦の御旗よろしく振りかざして マーケタへマーケティング戦略を指示し、 マーケタが製品のあるべき姿をプランナへ指示し、 プランナが製品仕様を決めて技術者に指示する。

こうした指示の連鎖は、よく見かける光景だが、 セールス、マーケタ、プランナ、技術者は、 本来は上下関係はないはずである。 なぜこのような指示する側とされる側に分かれてしまうのか。

で、上下関係をひっくり返してみようと思った。 技術者である私が、セールスやマーケタやプランナに指示を出してみる。

もちろん、いきなり指示を出そうと思っても、 何を指示すべきか分からないから、準備が必要である。

まず営業同行して、セールスの人達がお客様と何を話しているか観察。 ところがお客様の顔がいかにも興味なさそうなのに、 とうとうと自社製品の説明を立て板に水のごとく話している姿を目撃。 う~ん、素人の私にだって、こういう営業方法が 論外なことくらいは分かる。 もちろん優秀な営業マンもいるのだが、 私の目から見てもダメダメな人がいるというのは発見だった。

つぎにマーケ本部の定例ミーティングに参加してみる。 最初のうちは全貌が把握できていないのでおとなしくしているが、 すぐに我慢ができなくなった。 自社のポジションがまるで理解できていない。 弊社は大企業とは違うのだ。 弊社のロゴを見たって誰も弊社のことを思い浮かべたりはしない。 それにいま攻めようとしている市場は導入期である。 新しいカテゴリを作ろうとしているのだから 成熟期の商品と同じ攻め方でいいわけがない。 もちろん優秀なマーケタもいるのだが、 マーケティングの教科書を一読だけで分かるようなことを押さえずに、 見よう見まねの SWOT 分析などをして マーケタ気取りの人がいるというのは発見だった。

プランナは、技術者に近い。技術者と同じく「作る」職種である。 仕様を考えつつどんどんプロトタイピングして実ユーザの声を聞く、 という開発手法もあるわけで、 プランナと技術者は対等の関係になることも多い。

セールスやマーケタは、「売る」職種である。 技術者とは別人種と言ってもいいだろう。 だからといって「売る」職種が、「作る」職種よりも 立場が上というわけではない。 単に「売る」職種の方が広い視野を持ちやすく、 「作る」職種が、ともすると目先の問題に固執しがち というだけのこと。

Filed under: 技術者の成長 — hiroaki_sengoku @ 08:38
2006年4月4日

DB サーバのセキュリティ向上策 (2)

KLab で採用している DB サーバのセキュリティ向上策を説明する前に、 DB アクセスの際に SSL クライアント認証を行なう方法について説明します。

DB サーバへのアクセスにおいて SSL クライアント認証を必須とし、

(a) 開発者が (デバッグ目的等で) DB アクセスを行なう時は、 その開発者個人が管理する SSL 秘密鍵を用いてアクセスするようにし、

(b) プログラムが DB アクセスを行なう時は、 そのプログラムの実行権限でのみアクセスできる SSL 秘密鍵を 用いるようにすれば、

普通のパスワード認証よりはセキュリティを向上させることができます。 SSL クライアント認証をサポートしている DB サーバであれば、 その機能を有効にするだけで良いので、とても手軽な方法です。

ここで注意したいのは、 普通に SSL を使う (つまり SSL による暗号化のみを行なう、 あるいは暗号化に加えて SSL サーバ認証のみ行なう) ことは、 あまり意味がない、ということです。

データセンタのラック内の通信の盗聴を心配しても仕方がないわけで、 通信路を暗号化すること自体には意味はないでしょう。 また、サーバ認証は接続先が意図したサーバか確認するための手段ですが、 これもラック内で、通信相手が意図通りのサーバでないか心配しても 仕方がないですね。

SSL クライアント認証をサポートしていない DB サーバでも、 拙作 stone を使えば、手軽に SSL クライアント認証を付け加えることができます。

例えば DB サーバへのアクセスを unix ドメインソケット /path/to/socket でのみ 受け付けている場合、このソケットへのアクセス権限を DB サーバの実行ユーザ (ここでは uid が 1001 番とします) 権限に限定して、 local ユーザがアクセスできないようにしておいて、 stone を次のように実行します。

stone -o 1001 -z verify \
      -z CApath=/usr/local/ssl/certs \
      -z key=/usr/local/ssl/private/db.pem \
      /path/to/socket 12345/ssl

「-z verify」が SSL クライアント認証を必須とするためのオプションです。 「-z CApath=/usr/local/ssl/certs」オプションで、 CA の証明書を置いてあるパスを指定します。

すると、その CA が署名した SSL 証明書に対応する秘密鍵を 持っているクライアントが、その SSL 証明書を提示して ポート 12345 番に SSL 接続してきた時のみ、 stone はそれを /path/to/socket へ中継します。

CA が署名した SSL 証明書ならなんでも OK とするのではなく、 特定の CA の特定の証明書のみを受け付ける場合は、

stone -o 1001 -z verify \
      -z CApath=/usr/local/ssl/certs \
      -z key=/usr/local/ssl/private/db.pem \
      -z depth=1 \
      -z re1='/CN=KLAB Root CA[/$]' \
      -z re0='/CN=dbuser[0-9]*[/$]' \
      /path/to/socket 12345/ssl

などのように、SSL証明書の発行対象の名称 (CN) を特定するための 正規表現 (この例では「/CN=dbuser[0-9]*[/$]」) を指定します。

なお、ここでいう証明書は、いわゆる「オレオレ証明書」で構いません。 つまり DB サーバの管理者が必要に応じて何枚でも独自に発行できます。

「オレオレ証明書」が問題となるのは、認証する側が認めていない CA が 証明書を発行する場合です。 例えばサーバ認証を行なう場合は、認証する側は WWW ブラウザなどになります。 WWW ブラウザのユーザが認めていない CA を勝手に立てて証明書を発行し、 ユーザにきちんと説明することなくその証明書を受け入れることを 強要すべきではありません。これがいわゆる「オレオレ証明書」です。

一方、クライアント認証の場合は、認証を行なうのはサーバ側であるので、 サーバの管理者が認める CA ならばなんでも構いません。 もちろんサーバの管理者が独自に立てた CA で OK です。

上記の例では、KLab で立てた「KLAB Root CA」が発行した証明書で、 かつその発行対象の名称 (CN) が「dbuser」+ 0桁以上の数字 の場合 のみ接続を受け付けます。

DB へアクセスする必要がある開発者と、DB へアクセスするプログラム それぞれに別々の証明書を発行すれば、DB 側で 誰からのアクセスか特定することが可能になります。

しかしながら、

(1) プログラム用の秘密鍵を誰が管理するのか?

(2) SSL クライアント認証にともなう負荷増大

という問題が残ります。(2) はコストを度外視すれば済むので、 高いパフォーマンスが要求されない場合は問題とならないかも知れません。 が、(1) はなかなかやっかいです。

プログラムの開発者は、プログラムの実行権限で読むことができるファイルは 何でも読めます。例えば、秘密鍵を読んで特定の場所へコピーするよう プログラムを改変することは至って簡単でしょう。 したがって、プログラム専用の秘密鍵というのは実は 開発者全員で共同管理している秘密鍵と大差ありません。

プログラムの開発者なら誰でも DB にアクセスできる、 という状況を許容するなら、わざわざクライアント認証のような 負荷の高い方法を選択しなくても、と思うのが人情です。

ではどういう方法がよいでしょうか?

(続きは次回に)

Filed under: stone 開発日記,システム構築・運用 — hiroaki_sengoku @ 08:03
2006年4月3日

DB サーバのセキュリティ向上策 (1)

KLab が運用しているコンテンツで使用している DB サーバは、
パスワードを知っているだけではアクセスできません。
どういう仕掛けになっているかの説明は後のお楽しみ、ということで
まずは前振りから...

パスワードというのは知る人が多くなればなるほど漏れるものですし、
ひとたび漏れてしまえば、どこまで漏れるかコントロール不能です。
したがって DB に限らず、KLab ではパスワードへの依存を
できる限り減らしています。

例えば、サーバへのログインは、必ず ssh の RSA 認証を使うことを必須とし、
コンテンツ管理のためのページでは SSL クライアント認証を行なっています。
つまり、秘密鍵を持っている人のみがアクセスできるようにしておいて、
秘密鍵自体は各人の責任において管理してもらう、という方式です。
万一、サーバへ不正なアクセスが行なわれたら、
誰の秘密鍵によってアクセスされたかログが残りますから、
誰の責任か明確になるわけです。

ところが、プログラムが DB サーバなどへアクセスする場合は事情が
変わってきます。まず、

(1) プログラムには責任を負わせることができない ;-)

そのプログラムを開発したり運用したりする人が、
秘密鍵を管理するしかありませんが、
秘密鍵というのはあくまで一人の個人が管理するからこそ
責任を負わせられるのであって、
共同管理ということにしてしまっては、
万一漏れた時に、どこから漏れたのか調べようがなくなります。

かといって、そのプログラムが動作する時に用いる鍵の管理を、
一人の個人が管理するルールにしてしまうと、
運用がとても大変になります。
障害が起きた時に、その人がいなければ原因究明もままなりません。

二番目の問題として、

(2) DB アクセスには高いパフォーマンスが要求される

人がサーバ等へログインするときは、所詮は人間のスピードですから、
大したレスポンススピードは必要ありません。
秘密鍵による認証を行なう余裕は充分にあります。
一方、Web アプリケーション等のプログラムが DB サーバへアクセスする場合は、
ページのヒット数が高ければ高いほど、高いパフォーマンスが要求されます。

コネクションをプールするなどの手法によって、
認証コストを下げることは可能であるものの、
プログラム-DBサーバ間の通信路の暗号化などを行なっていては、
暗号化処理のぶんだけサーバ負荷が余計にかかります。
つまり DB サーバへのアクセスに SSL クライアント認証を行なう、
などの方法は、なるべくなら避けたいところです。

ではどうすればいいでしょうか?
(続きは次回に)

Filed under: システム構築・運用 — hiroaki_sengoku @ 11:20
2006年4月3日

IPv6 (2) hatena_b

IPv6ブリッジ機能付きルーター (ブルータ) を使えば、 NAT 内の LAN でそのまま IPv6 を使えるわけで、 IPv6 の敷居は一気に下がる。

つまり、ほとんどの OS がすでに IPv6 をサポートしているので、 ルータが IPv6 を素通し (ブリッジ) しさえすれば、 LAN 内で IPv6 を意識せずに使える。

今まで通り IP を (NAT 経由したプライベートアドレスで) 使いながら、IPv6 のオイシイところ (end-to-end 通信ができる) だけを ツマミ食いできるわけで、 今度こそ (^^;) IPv6 が普及するのではないかと...

Linux でブルータを実現するには、 まずブリッジ機能をカーネルに組み込んでおく。

# brctl show br0
bridge name     bridge id               STP enabled     interfaces
br0             8000.00022Axxxxxx       no              eth0
                                                        eth1

このままだと IP までブリッジしてしまうので、 IP に対してはルータとして機能し、 IPv6 に対してだけブリッジさせるために、ebtables を使う。

# ebtables -t broute -L
Bridge table: broute

Bridge chain: BROUTING, entries: 3, policy: DROP      …… (3)
-j mark --set-mark 0x0 --mark-target CONTINUE         …… (0)
-p IPv6 -i eth0 -j mark --set-mark 0x600              …… (1)
-p IPv6 -i eth1 -j mark --set-mark 0x601              …… (2)

上記設定の意味は、

(0) まず全パケットに対し 0x0 のマークをつける。
    で、
(1) eth0 から入ってきた (LAN内から外へ出ていく)
    IPv6 パケットは、0x600 のマークをつけてブリッジする。
(2) 逆に eth1 から入ってきた (外から入ってきた)
    IPv6 パケットは、0x601 のマークをつけてブリッジする。
(3) それ以外 (IP パケットや PPPoE パケット) はブリッジしない (DROP)
    つまり IP に対してはルータとして機能する

さらに ip6tables を使ってフィルタリングする。

ip6tables -P FORWARD DROP                                       …… (*)
ip6tables -I FORWARD -j incoming -m mark --mark 0x601/0xffff    …… (2)
ip6tables -I FORWARD -j ACCEPT -m mark --mark 0x600/0xffff      …… (1)
(1) 0x600 のマークがついているパケットは、素通し (ACCEPT) する。
(2) 0x601 のマークがついているパケットは、incoming チェインへ渡す。

incoming チェインで ACCEPT されなかったパケットは、
(*) FORWARD チェインのポリシーに従って、DROP される。

ebtables でマーク付して ip6tables でそのマークに基づいて フィルタリングするという、 まわりくどい方法をとっているのは、 ebtables はあくまで L2 のフィルタなので IPv6 アドレスに基づいたフィルタリングができず、 逆に ip6tables は L3 のフィルタなので eth0/eth1 はまとめてブリッジインタフェース br0 としてしか見えず、 どちらの物理インタフェースから入ってきたパケットか 判別できないため。

ちなみに iptables だと、 L3 フィルタといいながら physdev モジュールがあるので、 ブリッジのどちら側から入ってきたか判別できたりする。 ip6tables の機能拡張に期待したいところ。

Filed under: IPv6,システム構築・運用 — hiroaki_sengoku @ 07:20
2006年4月2日

stone 2.3a (候補) ベンチマーク

select でも性能低下を招かないように修正した stone のベンチマーク結果。

req/sec ms/req KB/sec
select 681.83 1.467 191.59
epoll 692.74 1.444 194.66
apache 983.60 1.017 278.36

select 版と epoll 版で、ほぼ同等の速度。もちろん、listen するポート数が多くなれば差が出てくる可能性はある。

測定条件:

$Id: stone.c,v 2.2.2.15 2006/04/02 00:03:56 hiroaki_sengoku Exp $
senri% stone -rn localhost:80 2345 >& /dev/null
asao% ab -n 1000 -c 10 http://senri:2345/health
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.121.2.4 $> apache-2.0
Document Path:          /health
Document Length:        131 bytes
Concurrency Level:      10
req/sec
Requests per second [#/sec] (mean)
ms/req
Time per request [ms] (mean, across all concurrent requests)
KB/sec
Transfer rate [Kbytes/sec] received
Filed under: stone 開発日記 — hiroaki_sengoku @ 09:16
2006年4月1日

stone 2.3 が遅い理由

epoll 化にあたって stone 2.3 のコードの全面的な見直しを 行っていたところ、性能低下を引き起こす問題点を発見。

stone 2.3 において、TCP 接続を accept し、 中継先へ connect する部分の構造は、 次のようになっている(説明のため大幅に単純化している)。

fd_set rin;

main() {
    ....
    for (;;) repeater();
}

void repeater(void) {
    ....
    rout = rin;
    ret = select(FD_SETSIZE, &rout, &wout, &eout, timeout);
    ....
    if (FD_ISSET(stone->sd, &rout)) {
        FD_CLR(stone->sd, &rin);
        ....
        ASYNC(asyncAccept, stone);
    }
}

void asyncAccept(Stone *stone) {
    ....
    nsd = accept(stonep->sd, from, &fromlen);
    FD_SET(stonep->sd, &rin);
    ....
}

つまり、select(2) によって listen しているポート (stone->sd) が accept 可能であることが判明すると、 まず rin の該当ビットをクリア(FD_CLR)し、 accept 処理を行う子スレッドを立てる(asyncAccept)。 このスレッドは accept(2) を呼び出し、 rin の該当ビットを再セット(FD_SET)する。

ところが、子スレッドと親スレッドのどちらが先に処理されるか、 という問題がある。 子スレッドが先に実行されるなら、 rin の該当ビットが再セットされた後、 親スレッドの select(2) が実行されるので問題は起きないが、 普通のスレッド実装では、 親スレッドの実行が優先されるようだ。

つまり、親スレッドの処理が先に実行されると、 rin の該当ビットがクリアされたままで、 親スレッドが select に突入してしまう。 親スレッドが select 待ちになってから、 子スレッドが rin を再セットするが、 時すでに遅し、 親スレッドが呼び出した select では、 listen しているポート (stone->sd) は 監視しない状態になってしまっている。

このため、この select が timeout して、 次回の select 待ちに入るまで、 接続を受け付けない状態が続いてしまう。 timeout は 0.1秒なので、 秒あたり高々10回の接続しか受け付けられなくなってしまう。

この問題を回避するには、 子スレッドで accept するのではなく、 親スレッドで accept すればよい。 この場合、rin の該当ビットをクリアする必要もなくなる。

で、なぜ epoll 化したことによって高速化されたかというと、 epoll の場合、rin に相当するものがカーネル空間にあるわけで、 子スレッドで EPOLL_CTL_MOD (FD_SET に相当) すると、 即それが epoll_wait 待ち (select 待ちに相当) している 親スレッドに反映するためだろう。

Filed under: stone 開発日記 — hiroaki_sengoku @ 18:37
2006年3月31日

ネイティブ IPv6

昨日に引き続き、これも tech ML で流した IPv6 ネタですが...

KLab のイントラのサーバである kamiya で、

ping6 -I eth0 ff02::1

を実行してみると、20台程度のマシンが反応します。うち、半分くらいは、 私が IPv6 をインストールしたマシンだったりします。 Linux や WindowsXP は標準で IPv6 をサポートしてますし、 Windows2000 も IPv6 Technology Preview を使えば IPv6 が使えます。興味がある人は試してみては? 今まで鳴かず飛ばずだった IPv6 ですが、なんとなく いろいろ使えそうな予感がします。 いろいろな仕掛けを IPv6 へ移行中...

# ついでに言うと stone も、IPv6 をサポートしています

六本木LAN の kamiya からフツーに IP で、私の自宅サーバ asao.gcd.org へ ping を打って、

kamiya:/home/sengoku % ping -t 64 asao.gcd.org
PING asao.gcd.org (60.32.85.216) from 10.10.0.2 : 56(84) bytes of data.
64 bytes from gcd.org (60.32.85.216): icmp_seq=1 ttl=50 time=6.55 ms

asao.gcd.org 側で見ると、

asao.gcd.org:/root # tcpdump -v -i ppp0 icmp
tcpdump: listening on ppp0, link-type LINUX_SLL (Linux cooked), capture size 96 bytes
09:34:55.115600 IP (tos 0x0, ttl  50, id 0, offset 0, flags [DF], length: 84) 161.90.128.210.bf.2iij.net > asaogw.gcd.org: icmp 64: echo request seq 256

64 に設定した ttl が 50 まで減っています。つまり 14 hop あるということ ですね。ping パケットは

六本木LAN → PPPoE (IPv6網) → IIJ (6 hop) ─┐
                                             ↓
                                           MFEED
                                             │
  自宅LAN ← PPPoE (IPv6網) ← OCN (7 hop) ←┘

と延々と旅をしてますし、しかも IPv6網は PPPoE でトンネリングして しまっているので、IPv6網での物理的な hop 数はカウントされていません。 実質的には合計で 20 ~ 22 hop 程度はあると考えるべきでしょう。

一方 IPv6 で asao.gcd.org へ ping を打つと、

asao.gcd.org:/root # tcpdump -v -i br0 icmp6
tcpdump: WARNING: br0: no IPv4 address assigned
tcpdump: listening on br0, link-type EN10MB (Ethernet), capture size 96 bytes
09:37:10.664278 kamiya.v6.klab.org > asao.v6.gcd.org: icmp6: echo request seq 256 (len 64, hlim 60)

hlim が 60 までしか減ってません。つまりわずか 4 hop ですね。

六本木LAN → IPv6網 → 自宅LAN

しかも途中に PPPoE のような邪魔なものは入っていないので、 mtu は 1500 のままです。

Filed under: IPv6,システム構築・運用 — hiroaki_sengoku @ 08:38
2006年3月31日

中途半端のススメ

仕事をやりかけのまま中断する。 たくさんの仕事がやりかけのまま溜まっていることになる。

やりかけのまま中断しているものは、いつでも再開できるように、

書きかけのメールなら、
メーラで開きっぱなしでいつでも送信できるように
書きかけの文書なら、
いつでも続きが書けるようにアプリケーションで開きっぱなしに
開発途中のプログラムなら、
いつでもデバッグできるようにデバッグ環境を立ち上げっぱなしに
アイディアを練るときは、
いつでも思いついたことをメモできるように書きかけのメモを身近に
チャットしようとして返事がないときは、
チャットウィンドウを開きっぱなしにしておく
WWW で調べものをするときは、
とりあえず検索して関係のありそうなページを開くだけ開いておく

効用1: 隙間時間を有効に活用できる

一つの仕事を一気に完了させようとしなければ、 とりあえず始めるだけ始めるということでよしとするなら、 隙間時間でも始めることはできる。 あるいは、やりかけの仕事を少しだけ進めることなら、 隙間時間でも活用できる。 また、待ちが多い仕事は多重化することによって、 同時に進行させることができる。

効用2: 心理面

一つの仕事を、ゼロから始めるのは敷居が高い。 やりかけている仕事の続き、ということだと敷居が低い。 一つの仕事を完了させようとすると、 細かいところまで神経を配る必要があって大変。 細部は後で考えればいいやと割り切れば気が楽。 逆に、ほとんど完成していて細部の仕上げだけの仕事は どんどん片付けられるので気分的に楽。

効用3: 同時に考えよう

無意識の思考の活用。 仕事をやりかけのまま寝かせておくと、 いい考えを思いつくことが多々ある。 書きかけの文章を寝かせておくと、 適切な言い回しを思いつくことが多々ある。

4/3追記: 同じような趣旨の日記を見つけた。
 結城浩の日記
 複数の仕事をすることについて
 勉強日記の書き方

Filed under: 自己啓発 — hiroaki_sengoku @ 07:16
2006年3月30日

glibc 2.3 での IPv6

一年以上前に tech ML で取り上げたネタなのですが、現在よく使われている Linux ディストリビューションでも glibc 2.3.2 あたりが使われることもある ようなので紹介します。


KLab のイントラのサーバには、IPv6 なアドレスも割り当ててあります。 例えば、

% host kamiya.v6.klab.org
kamiya.v6.klab.org has IPv6 address 2001:c90:c1c:100e:2e0:81ff:feab:cdef

% host 2001:c90:c1c:100e:2e0:81ff:feab:cdef
f.e.d.c.b.a.e.f.f.f.1.8.0.e.2.0.e.0.0.1.c.1.c.0.0.9.c.0.1.0.0.2.ip6.arpa domain name pointer kamiya.v6.klab.org.

のような感じ。kamiya というホスト名は KLab が六本木ヒルズへ移転してくる 前は、神谷町にオフィスがあったことにちなんでいます。イントラのサーバ群に は地名がつけられているマシンが多く、もちろん roppongi というホスト名の マシンもあります。

で、当時は Linux サーバの多くは glibc 2.2 を使っていたのですが、一部の マシンは glibc 2.3 にバージョンアップしていました。ところが、glibc 2.3 な マシンから ping6 を打ってみると異様に遅い...

% time ping6 -c 3 kamiya.v6.klab.org
PING kamiya.v6.klab.org(kamiya.v6.klab.org) 56 data bytes
64 bytes from kamiya.v6.klab.org: icmp_seq=1 ttl=64 time=1.10 ms
64 bytes from kamiya.v6.klab.org: icmp_seq=2 ttl=64 time=0.563 ms
64 bytes from kamiya.v6.klab.org: icmp_seq=3 ttl=64 time=0.363 ms

--- kamiya.v6.klab.org ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 20022ms
rtt min/avg/max/mdev = 0.338/0.475/0.569/0.102 ms
0.006u 0.004s 0:40.04 0.0%      0+0k 0+0io 0pf+0w

3 発 ping を打つだけなのに 40 秒もかかっています。-n オプションを 指定して、逆引きを抑制すると、

% time ping6 -nc 3 kamiya.v6.klab.org
PING kamiya.v6.klab.org(2001:c90:c1c:100e:2e0:81ff:feab:cdef) 56 data bytes
64 bytes from 2001:c90:c1c:100e:2e0:81ff:feab:cdef: icmp_seq=1 ttl=64 time=0.981 ms
64 bytes from 2001:c90:c1c:100e:2e0:81ff:feab:cdef: icmp_seq=2 ttl=64 time=0.354 ms
64 bytes from 2001:c90:c1c:100e:2e0:81ff:feab:cdef: icmp_seq=3 ttl=64 time=0.273 ms

--- kamiya.v6.klab.org ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 0.273/0.536/0.981/0.316 ms
0.003u 0.004s 0:02.02 0.0%      0+0k 0+0io 0pf+0w

などとフツーに 2 秒程度で終わるので、DNS の逆引きに問題があることが 分かります。一回の逆引きに 10 秒ほどかかっているようです。 てっきりネームサーバの設定の問題かと思ったのですが、host コマンドや dnsqr コマンドを使う限り、このような遅れは生じません。ping6 をはじめ、 glibc の getnameinfo(3) を使う場合だけ遅延が発生します。

後で気づいたのですが、この問題が起きるのは glibc 2.3 だけで glibc 2.2 では起きません (つまり kamiya とかでは正常に ping6 できる)。また、 当然ながら glibc 2.3 でも IP の逆引きは正常で、問題なのは IPv6 の逆引き だけです。

# 後述するように問題があるのは glibc 2.3.3 までで 2.3.4 は問題ありません こーいうときは tcpdump が基本だよね、つーことでパケットダンプしてみると、 getnameinfo(3) の場合は、

\[x20010c900c1c100e02e081fffeabcdef/128].ip6.arpa.

というクエリがまず飛び、10 秒ほどたってタイムアウトした後に

f.e.d.c.b.a.e.f.f.f.1.8.0.e.2.0.e.0.0.1.c.1.c.0.0.9.c.0.1.0.0.2.ip6.arpa.

というクエリが飛ぶことが分かりました。前者は見慣れない形式だったのですが、 「Binary Label」ないし「Bit-String」などと呼ばれる形式のようです (ちなみ に後者は nibble 形式)。「Binary Label」は、ドメイン名の一形式として RFC1035 で規定され、DNS での使い方が RFC2673 で決められたにもかかわらず、 ネームサーバでサポートされなかったために、RFC3363 で IPv6 の逆引きの方法 としては、使うのを断念されてしまった不幸な形式のようです。

とはいえ、「DNS で、どーして上位バイトが先にくるんだ~ 実装のこと何も 考えてないな~」と脊髄反射的に拒否したくなる、頭悪い (brain damaged) 形式なので、断念されて幸い、ということもできますね。

2002年8月に RFC3363 で正式に断念された形式なら、そのまま人々の記憶から 忘れ去られて欲しかったのですが、何を血迷ったか、glibc 2.3 は IPv6 の 逆引きで、まず「Bit-String」クエリを試し、タイムアウトしたら「nibble」 クエリを送信するという実装になっています (glibc の resolv は BIND 由来 だから?)。

少なくとも 2004年8月3日に公開された glibc 2.3.3 では Bit-String が デフォルトのままですね。一刻も早く Bit-String が使われなくなることを 願ってやみません。

願ってるだけではアレ (^^;) なので、ソースを見てみると、 glibc-2.3.3/resolv/nss_dns/dns-host.c (2003年10月26日) では

case AF_INET6:
  /* XXX Maybe we need an option to select whether to use the nibble
     or the bitfield form.  The RFC requires the bitfield form so
     we use it.  */

って書いてありますね (Maybe って書くくらいならオプション指定できるように しろよ...)。これが glibc-2.3.4/resolv/nss_dns/dns-host.c (2004年10月25日) だと

case AF_INET6:
  /* Only lookup with the byte string format if the user wants it.  */
  if (__builtin_expect (_res.options & RES_USEBSTRING, 0))
    {
      qp = stpcpy (qbuf, "\\[x");
      ...

に修正されています! つまりデフォルトでは nibble 形式に変更されたんです ね。めでたしめでたし。さっさと glibc 2.3.4 (2005年1月26日) に上げよっと。

...と書いてる間に自宅マシンで 2.3.4 を make して install してみました。 無事、getnameinfo(3) が遅延なく IPv6 の逆引きができるようになりました。 メール書いているうちに自己完結してしまったわけですが、まあ何かの参考に なるかも知れないし、IPv6 に興味を持ってくれる人が増えるといいな、 ということで tech に投げておきます。

#12237                                                          仙石 浩明
https://www.gcd.org/sengoku/             Hiroaki Sengoku <sengoku@gcd.org>
2006年3月30日

IPv6 (1)

バックボーンには導入が進むものの、 一般ユーザには一向に普及する兆しのない IPv6。 可能性があるとすれば、安価なブルータの普及が鍵だろうと思う。

ADSL や FTTH によって安価にインターネットへ常時接続できるようになり、 また一家に複数の PC を持つことが普通になってルータも普及してきた。 このルータに、IPv6 ブリッジ機能が標準で搭載されるようになれば、 IPv6 への移行は格段に容易になるに違いない。 つまりユーザが意識しなくても NAT の内側の LAN 上の PC で IPv6 が使えるようになる。

実際、NTT東日本のフレッツドットネット対応を謳って、 IPv6 ブリッジ機能を持つ安価なルータが多数販売されている。

IPv6対応(フレッツドットネット対応=IPv6ブリッジ機能付き) ルータ一覧

IPv6 が IP に比べて優れた点があるとは思わないが、 IP の「やり直し」という意味はあるだろう。 IP アドレスの割当問題しかり、 無防備な PC の氾濫しかり。

IP が提案された当時、現在のような普及状況は誰も予測していなかったわけで、 今、やり直すことができるのなら、もっと効率的なアドレス割当ができるだろう。

IP スタックが OS に標準搭載されるのが一般的になり始めた頃、 現在のようなウィルス蔓延の可能性を、 アプリケーション開発者の大半が意識できていなかったわけで、 今、やり直すことができるのなら、IP 通信を受付けることの危険性を 認識した上での開発ができるだろう。

Filed under: IPv6,システム構築・運用 — hiroaki_sengoku @ 13:13
2006年3月29日

分からない時は、『分からない』と言おう (3) tweets

「分からない」と言えることが重要だと私が感じるようになったのは、 実は中学・高校時代に遡ります。 中学の時も、高校の時も、それぞれ同級生に、 とても優秀な友人がいました。 そしてどちらに対しても、とても敵わないと思ったものでした。

例えば、何かの説明を彼にしようとして、 頭の中で説明の筋道を考えた上で彼に話しはじめると、 まだ 10 のうち 1 ほども説明していないのに、 「分かった」と言われてしまったことがしばしばでした。 まだ説明は序の口にも到達していないような状況だったので、 話はこれから面白くなるのにと思いつつ、 佳境の部分を端折って説明しようとしたら、 先回りして 「要するに○○ということだろう!」 と要点だけ言われてしまいました。

異常に早く「分かった」と言う彼でしたが、 「分からない」も連発していました。 当時の私には、 彼ほど優秀な人がなぜ「分からない」と言うのかとても謎でした。 私にとっては、 「なるほどなるほど」と相槌を打ちたくなるような話 (別の友人が話した話題だったり、 数学の証明だったり、 コンピュータの仕組みの説明だったり、 SF の設定だったりしましたが) に対しても、 彼は「分からない」と言うのです。

なにぶん 20年以上も前のことなので詳細は覚えていないのですが、 どこが分からないのか問い詰めていったら、 実は私も分かっていなかったことが判明して、 「なるほど!」と腑に落ちたことだけは覚えています。

いかに簡単に、 分かったつもりになってしまうか痛感した瞬間でした。

分かったつもりになっているだけなのか、 ちゃんと分かっているのか、 なかなか判別できるようにはなれなかったのですが、 彼と同じ内容について見聞きした後、 彼が分からない、 というかどうか聞くのが楽しみになりました。

自分は分かったと思っても、 彼が分からない、と言った時は、 慌てて自己の思考過程を振り返り、 どこに論理の飛躍があるのか一生懸命考えたものです。 どう考えても自明なことのように思われるのに、 彼が「分からない」と言った時は、 それはそれは彼が立派に見えたものです。

そんなわけで私は、 「分からない」と言える人を尊敬してしまうようになったので、 「『分からない』と言うことが恥ずかしい」 と思っている人に対して違和感を覚えるのです。

Filed under: 自己啓発 — hiroaki_sengoku @ 09:36
2006年3月29日

OS

OS って何だろう。

言うまでもなく OS といえば、 コンピュータのリソースを管理するものであり、 またハードウェアの仕様の差を吸収して、 異なるハードウェア上で同一のプログラムを 走らせることができるようにするソフトウェアである。

ただ、OS といっても、 ほとんどカーネルと呼んだほうがいいような場合もあるし、 ミドルウェアの機能をまで含んで、 アプリケーションの操作性を統一するようなものまである。 さらには Windows における Internet Explorer のように、 従来はアプリケーションと思われていたものまで OS としてしまう場合すらある。

わたしが初めて使った OS (と呼べるかどうかは微妙だが) は、 CP/M だった。自作 PC (今風に言う自作 PC ではなく、 回路の設計から半田付けまですべて自分で作る PC である。 CPUなどはもちろん LSI を使うが、 ほかは汎用 TTL でロジックをくみ上げているので、 今風に言うチップセットは存在しない) 用の BIOS を スクラッチから開発して、市販されていた CP/M を移植した。

低機能な OS をハードウェアレベルから くみ上げるところから始めたということもあって、 OS というとわたしはカーネルに近いレベルを想定してしまう。一方、

システム管理コラム集 実践してみてわかったことシリーズその1

などを読むと、 あらためて人によって OS という言葉から思い浮かべるものが 異なるものだと実感する。 私にとっては Linux の各ディストリビューションごとの差異など あまり気にしなかったりするのだが、 最近の人にとっては、ディストリビューションが違うと、 異なる OS ととらえることもあるのだろう。

ちなみに、私の自宅サーバは、 10年以上前にインストールした Slackware をベースにしている。 ベースにしているといっても、 カーネルや libc をはじめとして ほとんどすべてのプログラムをアップデートしているので、 元のディストリビューションの痕跡は皆無といっていい。 自作ディストリビューションと呼べるかもしれない。 これを私が管理する全ての Linux マシンにコピーして使っている。

会社 (KLab(株)) のサーバは、私の直轄のチームが管理していて、 こちらはさすがに自作ディストリビューションというわけにはいかず、Debian をベースにしているが、 コアの部分は KLab 独自の拡張を加えている。 つまり誰が作っても同じようになる部分は 既存のディストリビューションを使うことによって「手を抜き」、 コアの部分は独自に開発して運用コストを下げたり、 耐故障性能を向上させたり、パフォーマンスを改善したりしている。

Filed under: システム構築・運用 — hiroaki_sengoku @ 08:08
2006年3月28日

分からない時は、『分からない』と言おう (2)

tech ML に、 「分からない時は、『分からない』と言おう」 キャンペーン を書いたら、 E コマース案件を担当している T さんが書き込んできました。

あえて「分からない」が言えないシーン、 心理状態を想像してみると、 直接コミュニケーションをとっている中で、 「ちょっと調べれば分かりそうなことを聞いてしまうことが恥ずかしい、 (話の腰を折るのが悪い)」 というような心理的なブレーキが作用しているような気がします。 でも分かってないまま話を続けさせるのって相手に失礼ですよね (^^;

まあ、そういう心理なのでしょうね。 「自分で調べてから」 というのは正しい態度のようにも思われますが、 多くの場合は調べる前に忘れちゃったりするわけで、 あまりよろしくありません。

そういう意味では 「分からない」 を言いやすい環境作り、 「分からない」 と言われやすいキャラ作りも一考の価値あるかな、 とも思いました。

さすが T さん、 「分からない」 と言えない人のことだけでなく、 その相手のことまで考えています。 何事もいろいろな角度から見ることが必要ですからね。

だけど、 私が言いたいのは 「分からない」ことをどうやって意識させるか、 なので相手のことを考えてしまうと主題が発散してしまいます。 困ったな (^^;)。

つまり、 「分からない」 を言いやすい環境でないと 「分からない」 と言えないでは、 ダメなんです。 「分からない」 と言うのが一番ためらわれる状況でも、 「恥ずかしい」 という気持ちを押え込んで声を出す訓練を積み上げていって欲しいと思っています。

例えば、講演会等で、質疑応答の時間になった時、 誰も質問しなくって、 大きな会場が静まり返る、 という状況はよくありますよね? その静寂を打ち破って質問できるでしょうか? ほとんどの人は、 たとえ質問したいことがあっても、 なかなか声を出せないんじゃないでしょうか?

私が個人的に尊敬している人って、 ほとんど例外なくそういう場でも臆することなく質問できる人なんですよね。 「分からない」 と言える勇気を持つことと、 スキルアップできること、 との間には強い相関があるように思えてなりません。

大人数が参加する講演会場とかで質問するのは、 まあ後々の課題として、 せめて社内の勉強会や tech ML とかでは、 どんどん 「分からない」 と言えるようになってもらいたいです。

Filed under: 自己啓発 — hiroaki_sengoku @ 10:56
2006年3月28日

ジェイムズ・P・ホーガン

昨日、「ガニメデの優しい巨人」の一節を引用したので、 帰宅してから思わず昔読んだ本を取り出して読み出してしまった。

「わたしは、偶然の一致というのを信じない」

という言葉を 44ページ目に発見。20年以上前に読んだ本なのだが、 当時何度も繰り返し読んだので、 いまでも細部の言い回しなどがどんどん思い起こされる。 原著で読んだこともあるのだが、 日本語訳をほとんどそらで語れるほどだったので、 英語で読んでもスラスラ読めた。ちなみに上記セリフは、原著では

“I don't believe in coincidences,”

となっている。英語だと言い回しのバリエーションがないのだろうか、 誰の発言でも全く同じセンテンスになってしまう。 ジェイムズ・P・ホーガンといえば、真っ先に思い出すのが次の一節:

太陽の連続的な高度低下に伴った大気による短波長の顕著な散乱は、六百五十ナノメートル以下の選択的伝達をもたらし、家畜化した羊類を飼う素朴な牧夫たちの心に非合理的な陶酔感の傾向を生み出す

原著では、

Pronounced atmospheric scattering of shorter wavelengths, resulting in selective transmission below 650 nanometers with progressively reducing solar elevation, produces a tendency toward irrational euphoria among primitive herders of domesticated ovines.
Filed under: その他 — hiroaki_sengoku @ 07:02
2006年3月27日

わたしは、偶然の一致というのを信じない

私が好きな SF の主人公のセリフに、こういうものがある:
「わたしは、偶然の一致というのを信じない」
ガニメデの優しい巨人
ジェイムズ・P・ホーガン (著)

ある事象の直後に、本来直接は関係ないはずの別の事象が起きたら、 両者の間に、なんらかの因果関係があるはず、と考えるのが、 「偶然の一致を信じない」人のとるべき態度であるし、 この考え方は、技術者や科学者にとっての鉄則だと思う。

同じ事象を観測していても、偶然の一致を見つけ出せるか、 それとも代わり映えしない観測データと思って見過ごすかが、 大きな分かれ目になりそうだ。

プログラムの動作ログも同じ。同じログを見ていても、 そこからどれだけの内容を汲み取れるかは、 技術者の資質に大きく依存すると思うし、 スキルアップを目指すなら、自分より優れている技術者が、 そのデータから何を引き出すことができて、 自分がどうしてそれを引き出すことができなかったのか、 詳細に省みるべきだろう。

Filed under: 技術者の成長 — hiroaki_sengoku @ 15:45
« Newer PostsOlder Posts »