_ なんかメールきた。セキュリティまわりのいつものアナウンスとはまったく違う形式なんだけど、もう exploit code が出回ってるのでちゃんとした SA は後回しにしてとりいそぎ パッチ出すよ、ということらしい。
_ んーと、修正内容を見ると、unsetenv(3) の返り値をチェックしていないため、危険な環境変数を除去しようとして失敗してもそのまま突っ走ってしまって LD_PRELOAD からコードを注入できてしまう、ということかな。よりにもよって ld-elf.so.1 の中だし。
_ ……え、返り値ってなにそれ? unsetenv() って void を返すんじゃないの?
_ 調べてみると、どうやらちょっと前(freebsd は 6、glibc だと 2.2.2)までは void だったけど、最近では成功/失敗を int で返すように変わったらしい。今回の穴が freebsd >=7 なのも、この変更にあわせて大幅にコードを書き換えたときにいらんことをやってしまったような気配。
_ 今回の work around なパッチでは返り値のチェックを追加してるだけなので、これとは無関係なところで unsetenv() を呼んでるものは環境変数を消したつもりでも条件によっては消えてない、ということが起きるはず。たとえば、てきとーにソースを grep したところでは、logger(1) は成功判定なしで unsetenv("TZ") してるので、なんかのはずみで時間のズレたログが syslog に書かれる、とか起きちゃったりする、かな? 推測だけど。本質的には unsetenv() の返り値をチェックしないことよりも、そもそも unsetenv() が気まぐれにコケてしまうこと自体が問題なんで、ちゃんとした SA が出るときはこのへんが修正されてくるんじゃないかと思われ。
_ パッチを当てた ld-elf.so.1 に入れ替えるとき、おかしな手順でやるとシステム内のほとんどすべてのバイナリが動かなくなるので注意。その場合でも、/rescue の下にある静的リンクのバイナリは動くはず。自分では試してないけどねっ。
そもそも unsetenv() が気まぐれにコケてしまうこと自体が問題なんで、ちゃんとした SA が出るときはこのへんが修正されてくるんじゃないかと思われ。ひゃっほう。修正されてないよ! やっぱり unsetenv() コケるよ! exploit 並のおかしなことをやらんと失敗しないわけだからふつーに使うぶんには問題ないけど。
ローソンの生鮮コンビニは10月末現在、「ストア100」と「SHOP99」の店名で計944店。うちから駅までのたった1kmちょいの間に944店のうち4店があるんですね…。「3都市圏では、数年で通常のローソンと生鮮コンビニの数が同じくらいになる可能性がある」ふつーのローソンはひとつです…。
_ 事前にキャッシュを温めておくことでレイテンシを下げましょう、なキャッシュ DNS サービスらしい。8.8.8.8 とかよく取れたな。
_ 以下、箇条書きにて。
- 応答には authority section と additional section が含まれない
- answer section がゼロのとき(NXDOMAIN だったり、A を聞いたのに A がなくて MX だけあるような場合)は authority section を含む
- version.bind、hostname.bind を聞くと SERVFAIL が返る
- bind では返す文字列を変更できるだけで、答えないようには設定できない
- unbound では応答しないように設定すると REFUSED を返す
- djbdns は chaos 未対応で、tinydns は FORMERR を返すようだ(dnscache もたぶん同じだと思う)
- 10.x.x.x などのプライベートアドレス空間の逆引きには REFUSED を返す
- bind では、とくに設定しなければふつーに . から辿っていく(結果として blackhole-{1,2}.iana.org が返してきた NXDOMAIN が返る)。dnscache もたしか同じだったと思う
- unbound では、とくに設定しなければ unbound 自身が NXDOMAIN を返す
- 接続元ホストでアクセス制御して REFUSED を返すように設定できるキャッシュサーバは多いけど、問い合わせる名前によって REFUSED を返すように設定できるものは知らない
- 169.254/16 のリンクローカルアドレスも同様に REFUSED
- なのに fe80::/10 の v6 リンクローカルはなぜか . から辿って NXDOMAIN が返る
- localhost や 127.0.0.1、::1 を聞くと NXDOMAIN が返る
- authority section を見ると、ちゃんと . から辿っていってる模様
- unbound や dnscache では設定しなくても自分自身で 127.0.0.1 を返す
- bind では設定しなければ . から辿っていってその結果 NXDOMAIN が返るが、たとえキャッシュ専用サーバであってもたいていの場合は 127.0.0.1 を返すように localhost ゾーンを定義するのがふつー
- プライベートアドレスの問い合わせは蹴って localhost は外に聞きにいく、ってなんか一貫してないような
- なぜか、ごくふつーの名前でもたまに蹴られることがある(毎回ではない)
> dig @8.8.8.8 google.com any ; <<>> DiG 9.6.1-P1 <<>> @8.8.8.8 google.com any ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 11592 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;google.com. IN ANY ;; Query time: 41 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Fri Dec 4 16:31:33 2009 ;; MSG SIZE rcvd: 28
- 確認したのは ANY だけだが、ほかのタイプでも起きる?
- ってゆーか、これかなりマズいんじゃ…?
- ちゃんとラウンドロビンで応答する
- unbound、dnscache は一度キャッシュに入ったら TTL が切れるまで同じ順番で応答する
- 同じ名前を繰り返して問い合わせると、TTL が巻き戻ることがある
> dig @8.8.8.8 2ch.net ... 2ch.net. 43 IN A 206.223.154.230 ... > dig @8.8.8.8 2ch.net # 上から間をおかずにすぐに再実行 ... 2ch.net. 205 IN A 206.223.154.230 ...
- TTL 43 の問い合わせから1秒で2回目を実行すると、ふつーなら2回目の TTL は 42 になっているはず
- とゆーわけで、同じ IP アドレスで複数のホスト(IP anycast 的な意味ではなくロードバランサ的な意味で)が動いていて別々にキャッシュを管理しているのは確実
- が、この変化のパターンを観察すると、そんなに大量にあるわけでもなさそう(たぶん3つ)
- うちから ping を叩くと RTT は 38-42ms ぐらい
- google DNS がどんなにがんばってもこれより小さな時間で名前解決はできない
- サービスの思想からして同一 IP アドレスを anycast で広く分散配置してるのは確実だが、この RTT から推測するに日本国内ではなさそう
- シンガポールとか台湾とか?
- 130ms かかる OpenDNS に比べたらはるかに近いが、遠いことには変わりない
- キャッシュされててあたりまえなよく見る名前を問い合わせたときの応答は 40-45ms ぐらい
- ぶっちゃけ、 ものすごく遅い
- ping の RTT の分を引くと、キャッシュ済みの名前に対する DNS サーバ自体のレイテンシはせいぜい 2ms とかそんなもんなんでかなり頑張ってるといえるが…
- ちなみに Celeron M 900MHz な eeepc900 で動く unbound 1.3.4 にキャッシュ済みの名前を聞くと 1ms 以内で応答が返る
- うちから ISP のキャッシュ DNS に問い合わせた場合は 7-10ms ぐらい(ping の RTT は 6-8ms)
- 小さな個人サーバのようなそんなにメジャーでないところ(たとえばうちのところとか)の名前解決はかなりの確率で 200ms 以上の時間がかかる(キャッシュに入ってない)
- 実際のキャッシュヒット率がどれくらいだかわからんが、体感的にはそのへんの ISP のキャッシュ DNS と大差ないような…
- 少なくとも現状では使うメリットはなさげ
- なお、レイテンシは queryperf のようなちゃんとしたツールで測定したものではなく(他人のサーバにそれ使うのはイジメ)、dig の結果の末尾に表示された値を見ただけ
- 外に見せている IP アドレスは 8.8.8.8 と 8.8.4.4 だけど、外に聞きに行くときの src IP はまったく別
- とりあえず 72.14.202.94 (tx-out-f94.1e100.net) を確認 (ひとつだけ?)
_ 現時点でのまとめ。
- 既存の DNS サーバではなく独自実装っぽい
- google の DC は日本にないので速いはずがない、むしろ逆効果
- 近くに google DC がある地域で効果あるかどうかは、ほんとに google が宣伝しているとおりの高いキャッシュヒット率が得られるかどうかによる
- 日本から OpenDNS を使ってるような人ならば乗り換えると劇的に速くなるよっ!:-)
- すごいのは 8.8.8.8 だけじゃね?
_ 調べていないこと。
- negative cache の扱い
- SERVFAIL を cache してるか?
- lame の扱い
- DNSSEC まわり
- その他もろもろ
_ 今年も、前に勤めていた会社の忘年会のようなもの。組織としてはとっくの昔に消滅してるので、わしのように転職した人間でもありがたく呼んでもらえる。
_ いまや一部上場企業の社長をやってるおっさんをはじめとして、出世した人多いねぇ。わしゃ相変わらずだけど。今の会社ではすっかりおっさん的ポジションにいるけど、前の会社の人たちの間では永遠に下っ端なので、もっとおっさん達の間をお酌してまわるよ!
_ つーか、今の会社はおっさん成分が足りない。ゆとり乙。
_ 音が影響、物が動いて見える=脳科学実験で初実証−映画など応用期待・東北大など。聴覚が視覚に引き寄せられる腹話術効果とは反対に、視覚の方が聴覚に影響されることもありますよ、と。
_ こういうことを研究してるようなところってのはそんなに多くなくて、ってゆーか心当たりありまくりで、 調べてみたらやっぱりわしが学生のころにいた研究室がかかわってた。どうやら、メインでやってたわけでなくて共同研究の手伝い程度だったみたいだけど。まあ、相変わらずでなによりです。
_ djb が自作ツールの更新を放棄してからずいぶんたって、qmail やら djbdns やらはゆっくりと置き替えが進んでいるようだ。が、いまだに使い続けられているものもある。具体的には daemontools。いまだに daemontools を 使うネタが書かれているのを見て絶望した。代替物はほかにもあるのに。
_ runit。tai64nlocal 相当のものがないとか、欠けてるものがないではないけど、増えている機能も多い。ってゆーか、runit って init(8) すら置き替えできるレベルのものだし。
_ ライセンスは、フリーではなくしちめんどくさかった昔の djbware でもなく、PDS としてなにもかも放棄してしまった今の djbware でもなく、BSD ライセンスなので使いやすい。この業界の人なら誰でも知ってるとある商用ロードバランサ箱の中でこれが動いているのを見て、ああ、やっぱりあのライセンスじゃ商用製品で daemontools は使えないよね、とニヤリとしたのはもう何年前だろうか。そんなわけで、アヤしげなものではなく、ン百万円もする商用製品で長年にわたって運用されてきた実績もある。
_ なお、djbware はとっつきにくいけど djb 作じゃないなら、と期待すると泣きます。これを作った人も(たぶん) djb 信者なので、やっぱり djbware 的にとっつきにくいです。今まで daemontools を使ってきたけど djb に見捨てられちゃっていつまで使い続けられるのかな、乗り換える先ないし、という人向け。むしろいかに低コストで乗り換えできるか、を考えて作ったぽい感じ。というわけで、以下 daemontools をある程度知っていることが前提。
_ 使いかた。init を入れ替えたりしないのであれば、微妙な違いはあるけど daemontools とほぼ同じ。今てきとーにでっちあげた例。apache と echo サーバを動かす場合のディレクトリ構成。
このディレクトリを svscan に相当する runsvdirの引数に食わせて起動する。うん、daemontools といっしょだね。+ service + apache - run + env - 環境変数設定ファイル群 (envdir) + supervise - 管理用のファイルいろいろ + echo - run + inst - 接続制御設定ファイル群 + supervise + log - run + supervise + main - current_ こいつらに対する操作は、daemontools の svc に対して、runit では svを使う。上では apache を動かしてるけど、graceful restart するときは SIGUSR1 のシグナルを送らなければならない。が、daemontools では SIGHUP は送れても SIGUSR1 は送れない。こっちはかんたん。
でどーぞ。ほかにもいろんなシグナルを送れます。# sv 1 service/apache # SIGUSR1 # sv hup service/apache # SIGHUP_ run スクリプト。若干違うけど、やってることは daemontools のときと同じ。
chpstの -e は envdir、-u は setuidgid。上ではあえて chpst を使ってるけど、実はこいつは呼ばれる名前で動作を変えるので、envdir、setuidgid という名前で symlink を作っておけば daemontools のときのスクリプトそのままでも動く。ちなみに setlockは chpst -l (or -L) で。 svlogd(multilog) は symlink で置き替えというわけにはいかんけど、multilog の t を -t or -tt に書き換える程度でだいたい大丈夫。> find . -name run | xargs head ==> ./service/apache/run <== #!/bin/sh PATH=/usr/local/bin:/usr/bin:/bin httpd="/usr/local/sbin/httpd" exec env - PATH=$PATH /usr/local/sbin/chpst -e ./env $httpd -DNO_DETACH -DFOREGROUND ==> ./service/echo/run <== #!/bin/sh exec env - /usr/local/sbin/tcpsvd -v -i ./inst -p -u nobody 0 7 /bin/cat 2>&1 ==> ./service/echo/log/run <== #!/bin/sh exec env - /usr/local/sbin/chpst -u nobody /usr/local/sbin/svlogd -tt ./main_ 上の run スクリプトの中では tcpserver のかわりに tcpsvdというのを使ってる。runit とは別パッケージだけど作者は runit と同じ。たいていのオプションは tcpserver と同じ。上の例では見慣れないものとしては -i ./inst なんてのを使ってる。これは 接続制御設定。hosts.allow とか、tcpserver の -x file.cdb みたいなもの。inst ディレクトリにこんなファイルを作る。
127.0.0.1 からはアクセス許可、それ以外からは拒否。192.168.x.x からのアクセスを許可したければ、touch 192.168; chmod u+r 192.168 で完了。qmail で必要になる、192.168.x.x からのアクセスには RELAYCLINENT という環境変数を設定したい、という場合は---------- 1 root wheel 0 Dec 7 22:29 0 -rw-r--r-- 1 root wheel 0 Dec 7 22:29 127.0.0.1とする。TCPREMOTEIP とかの tcp-env な環境変数はとくに何もしなくても設定してくれる。ipsvd でも -x file.cdb は使えるけど、ipsvd はファイルから cdb に変換するのではなく、上のようなディレクトリ構造から cdb を作る(ファイルをパースしないという djb の思想を djb 自身よりも忠実に守っている)。けっきょくのところ、cdb を使う場合でもこのディレクトリは作らきゃいかんので、めんどくさいから cdb にしないでそのままにしておく。cdb にした方が速いと思うけどあんまり気にしない。# echo '+RELAYCLINENT=' > 192.168_ なぜ tcpserver ではなく tcpsvd を使うのか。tcpserver は全体の最大接続数は設定できるけど、同一クライアントからの最大接続数は制限できない。よって、1台のクライアントでその最大接続数いっぱいまで埋めてそのまま何もしないでぼーっと接続を維持する、というだけの単純なことでほかの人がアクセスできなくなって DoS が成立してしまう情けない仕様がある(バグじゃないし djb は穴と認めていない)。djb は、それよりもサーバのリソースが枯渇するまで無制限に接続を受け付けてしまう方がよくないと inetd を dis っている。tcpsvd は全体の接続数だけでなく、IP アドレスごとの最大接続数も制限できるので、どっちの DoS とも無縁。ちなみに今どきの inetd/xinetd もたいていはそのへんの制限はちゃんとできるので、djb が inetd を dis っているという理由で tcpserver を使ってる人は inetd/xinetd か tcpsvd に乗り換えましょう。tcpserver がいちばん脆弱です。
_ なお、ipsvd は ipv6 を喋れない。v6 を使いたい場合は、courier-imapd の中に入っている couriertcpdが、実は courier に限らずどんなものでもふつーに起動できて v6 を喋れて tcpserver とほぼ互換だったりする。もちろん、tcpserver が食らう DoS に耐性がある。
_ そんなわけで、わしのことを anti djb だと思っている一部の方々が飽きて燃料投下を望んでいるような声をだいぶ前にどっか(どこだか忘れた)で見かけたので、要望に答えて若干 djb を dis り気味に runit と ipsvd を解説してみました。わしゃ別に「いいものを使う」というだけで、djb が嫌いなわけでもなんでもないんだけどね。ちなみに、自分自身では好き嫌い以前に必要性を感じてないので使っておりませぬ(これ書くために何年かぶりにインストールした)。いいじゃん、ふつーのやりかたで。何が困るの?
_ 国境の長いトンネルを抜けると雪国であった。夜の底が白くなった。
_ うん、白かった。
_ サイズ変更以外の画像加工はしてないよ。Thunderbird3 が出たってゆーから入れ替えたら Thunderbird2 のときのメールも何もまったく見えなくなった。ひどいよ。
_ よくわからんが、なんか TB2 にしか対応してないアンチウィルスな何かが TB3 で誤動作したっぽい感じ。上書きアップグレードではなく、いったんアンインストールした上でさらにカスペルスキーが勝手に突っ込んだらしいファイルを消して、その後インストールしなおしたらなんとか復活した。
_ 「ミーティングやるからこの時間に集合!」というメールが届いて、いきなり何だよ聞いてねーよこっちの都合聞かずに勝手に決めんな、と思ってよくよく見たら、丸1年前のメールがなぜか未読に戻ってたとか、同じようにフォルダ内のメールのうち500通ぐらいがいきなり未読に戻ったとか、なんかおかしな挙動がいくつか。IMAP だから既読情報はサーバ側にあるはずなんだが…(TB の側でも独自に既読情報を管理してるのかもしれんが、オフラインで使ってるわけじゃないんだからサーバ側の情報と同期しないのはおかしい)。
_ あと、確認せずに勢いで入れ替えてしまったが keyconfig のアドオンがまだ TB3 に対応してなかった…。キーボードからの操作を間違いまくり。これアドオンじゃなくて標準機能にしてほしいんだけどなー。
_ ということで、やめときゃよかった、というのが使用1日目の感想。