Cisco vpnclient物語

ここtwitterで愚痴ってるように最近Ciscoというネットワーク機器メーカの製品に鬱ってました。
しかしそれも今日の16時ぐらいまでのこと。問題は(多分)解決できた!!!本当に良くやった!!!解決したときは心のそこから「よっしゃー!!!!」って叫びたかったよ。




本当に長かったこの1ヶ月(実際は他のことも少していたけど)。これほどまでに長く同じ問題に取り組んだのは初めてだ。会社に入ってから記憶にある限りかなり苦しんだ問題は今までで2つ。どちらもrdesktopというソフトの機能について1週間ほど悩んだ末に解決できた(しかもパッチを投稿したりもした)。何よりつらいのは問題は自分のみで解決するということ。同じ開発チームの2人(というか上司)はいつも他の仕事で手がいっぱいだし、今の製品は基本僕が全て実装している(といっても言いすぎじゃないと思う)から必然的にそうなってしまう。今回も問題の表層については報告するが、実際のデバッグは僕1人で行った。


Ciscoルータ(IPsec)に取り掛かった最初は甘く見ていた。Ciscoから純正のLinux版クライアント(vpnclient)が出てるので、問題ないと思った。仮にもあのCiscoが出してるんだ、動かないはずがない。だけど現実はそんなにあまくなかった。動くんだけど不安定。あれやこれやと調べるけど全然わからない。さっさとあきらめて違うクライアント(Openswan , vpnc)を試すけど満足の行く結果が得られない。vpnclient、Openswan、vpncをぐるぐる回しながら調べるが一行に前に進まない。本当に1ミリも前に進む感触がなかった。


そんな感じで1週間、2週間、1ヶ月がすぎた。集中力も切れ、Ciscoを触るのも嫌になり、会社に行くのも憂鬱になった。ブログやtwitterで愚痴をこぼしたりして気を紛らわしてた。


ところが今日、その時は突然やってきた。偶然がすごく重なった。straceというコマンドについて調べたら-F , -fでforkした子プロセスもトレースできることがわかり、子プロセスをトレースしてみると/dev/randomを使用してることがわかり、/dev/randomについて調べたら、エントロピーについてわかり、そしてそれが原因だということが分かった(詳しくは後で)


その時僕は本当に興奮した。今まで1ミリも進んでいなかったものが一気にゴールにたどり着いた感覚。僕は1人震えながら、それが正しいことを確かめるために違う部屋に行き、うろうろしながら考えた。「これが原因であることを確固たるものにするためのログを探そう」そう思い席に戻ってさがしてみたら、予想通りのログが見つかった。そして二人の上司に「原因がわかりました。」と伝えた。詳しい内容を報告しながら僕はやっと終わったと思い、その後はもう力がでなかった。




今読んでる本の影響で少し物語調で書いてみました(笑)。


詳しい原因はこんな感じ。

  • vpnclientからforkした子プロセスが/dev/randomからランダム値を頻繁に読んでいる。
  • /dev/randomは周辺機器からのノイズを元にしたエントロピーからランダム値を生成している
  • そしてエントロピーが無くなると読み込みをブロックする
  • 接続/切断を何回も繰り返しvpnclientを使っているとエントロピーが無くなりブロックに陥る
  • 結果としてvpnclientが止まってしまったようになる

解決してから思えば「vpnclientが止まってしまったときにマウスorキーを動かすと正常に動作しだす」という不可解な現象についてよく分かる(マウスorキーを動かすとエントロピーがたまり、/dev/randomのブロックが解除される)
解決策は/dev/randomを使うのではなく/dev/urandomを使うこと。vpnclientはバイナリ配布のみなのでソースは変更できない。なのでvpnclientをだますために/dev/randomを/dev/urandomへのシンボリックリンクにしてしまう。基本的には/dev/randomではなく/dev/urandomを使うことを推奨されている(SSH,GPG,SSL等長期にわたる使用の場合は/dev/randomを使うべき)
/dev/randomについては404 - エラー: 404を参照。


まあこんな感じで無事に解決しました。けどまた何か起こるかもしれないので油断は許されない。でも久々に憂鬱な気分を忘れた休日を迎えられそうだ。
(と思ったけど、膝の調子が悪いので明日は病院に行って来る。ひどい病気じゃないことを祈る)