毎秒1000リクエスト を捌く超高速CMS「adiary」
2009/11/30(月)CORESERVER、メールの凶悪仕様(Gmailとの不具合の理由)
訳あってレンタルサーバのCORESERVER.JP(Value Domain)の利用を検討していたのですが、メールがらみでひどい素敵仕様を発見したので記録しておきます。GmailとCORE SERVERの相性が悪いという話がネットであちこち書かれていますが、おそらくこれが原因ではないかと思います。
メールの仕組みについて
問題について述べる前にメールサーバについて簡単におさらいしておきます。そんなの分かってるという人は飛ばしてください。
いわゆるメールサーバというのは、SMTPというプロトコルによってメールをサーバからサーバへ転送するサービスをしています。このSMTPというのは元々サーバも受信者も送信者もなにも区別がないプロトコルで、「SMTPサーバからSMTPサーバへどんどんタライまわしをしているといずれ受信サーバにたどりつく」というSPAMなんて存在しない、インターネットが限られた利用者が使用する紳士的な世界だった頃に作られました。その名残から、今もって
- メール送信時にメールクライアントソフト(メーラー)が自分のメール送信用サーバに対してメールのデータを送るSMTP
- メールサーバ間でメールのデータをやりとりするときに使われるSMTP
2つには何の差も存在しません。こんな仕様だから、メール設定のいわゆるSMTPサーバ(送信サーバ)として使用するサーバには何かしら制限を加えておかないと、世界中からそのサーバを中継(経由)してSPAMを送り放題になってしまいます。このように「本来想定している人以外からのメールを送ること」を第三者中継といいます*1。第三者中継をしないために通常は次のような制限を加えておきます(いずれかもしくは複数)。
- 特定のIPからしか送信できないようにする。プロバイダのSMTPサーバが、そのプロバイダの利用者IPのみに中継を許可する。
- SMTP-AUTH等の認証をする。ID/パスワードを確認するので、正規のID/パスワードを持つ利用者のみに中継を許可できる。
- POP before SMTPという特殊な方法を利用する。メール送信前に1度メールを受信させることで、そのIP利用者に短時間だけ(1~5分程度)中継を許可する。
最初の方法だけで済めばよいのですが、どうしてもホテルやモバイルパソコンからメールを送信したいとなったときに必ずしも同じプロバイダを利用できるとは限らないので他の方法が必要になります。SMTP-AUTHがまだそんなに普及していなかった頃*2、過渡的な措置としてPOP before SMTPというものが考えられました。
以上はあくまで送る側の話で、SMTPサーバは送るためのサーバであると同時に受信サーバでもあることが多くあります*3。このままだと何処から送られてくるかわからない自分宛のメールを受け取れなくなってしまうので、自分宛のメールは無条件で受け取るという設定をします。例えば、xxx@foo.com ならば foo.com は自分宛ですよと登録しておきます。
CORESERVERのおさらい
- CORESERVERは送信メールサーバ=受信メールサーバ
- CORESERVERはPOP before SMTPのみ対応(SMTP-AUTH未対応)
CORESERVERの血迷っ…素敵過ぎる仕様
CORESERVERで普通にメールサーバを設定して、設定したサーバ宛にメールを送ろうとしたらこんなエラーメールが帰ってきました。
<test@s1xx.coresv.jp>: host s1xx.coresv.jp[202.172.28.1xx] said: 552 sorry, your domain isn't in my list of allowed senderhosts (#5.7.1) (in reply to MAIL FROM command)
要するに「あなたのドメインは送信元ドメイン許可リストに入っていません」と言っている。にも関わらず、他のぜんぜん関係ないメールサーバ(メールアカウント)からメールを送るとちゃんと受け取る。さっぱり意味不明。検索すると同じようにハマっている人多数。
色々調べてみたところ、原因がはっきりしました。
- POP before SMTPの設定時間(タイムアウト)が3時間以上!
- POP before SMTPで「リレー許可リスト」に登録されると、そのIPからのSMTP接続はすべて外部への中継(リレー)として扱われる
どちらの仕様もバカ素敵すぎて言葉もない。
つまり、
- SMTPサーバでもあるIPで、CORESERVERからメールを受信する。
- CORESERVER側で「リレー許可リスト」に登録される。
- 手元のSMTPサーバからCORESERVER宛にメールを送信する。
- CORESERVERは「リレー許可リスト」に登録さているという理由だけで、外部から自分宛のメール送信を強制的に内部(CORESERVER)から外部へのメール送信と見なす。
- CORESERVERは外部へのメール送信のとき、予め登録された自ドメイン(senderhosts)にSMTPのFROM*4ドメインが含まれないためメールを拒否する。
- CORESERVERは自分宛のメールを552のエラーとして受取拒否する。
ということです。
そしておそらく「リレー許可リスト」はサーバごとに全ユーザ共有だと思われるので(未確認)、たとえ自分でPOPしていなくても時々メールが送れないサーバが出てくる……と。
Gmailには
Gmailには、Gmailに統合してあるアカウント名義でメールを送信する目的で外部SMTPサーバを使用してメールを送信する機能がありまして、それを使うとバッチリメールが送れなくなるわけです。
これをしないと、GmailではFromの代理送信表示がされてしまいます。
総評
VALUE DOMAINのDNS設定も、何行か書くとすぐバグるし(行を入れ替えないとダメとか)、いまいちツメが甘い印象がぬぐえない。所詮、安かろうなんたらでしょうか。サーバスペックはいいんだけど、障害対応も遅いみたいだしねぇ。今回は安定性重視なのでCORESERVERは却下の方向。
どこか、もちょっとマトモなレンタルサーバ知りませんか?(苦笑)
追記
なんかググってたらこの記事のほぼコピペのブログが。せめてリンクぐらいしようや……。*5
2009/07/01(水)メールの添付ファイル名とMIME文字コードと色々メモ
メールの添付ファイルやMIMEに関するメモ。実装サンプルは adiary を落として lib/Satsuki/Base/Mail.pm でも開いてみてください。
関連記事:2行に渡るメールヘッダの正しい処理
2009/06/02(火)IE8のメモ+バグメモ
adiaryをIE8(IE8モードの標準準拠時)に対応させたときのメモ。
IEモードスイッチを標準準拠にする
DOCTYPEレンダリングモード以外に、IE6/7互換設定を一切無視して*1IE8以降の標準でレンダリングさせる。
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
HTTP_USER_AGENT
IE8ならば本来、
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
となるはずですが、IE8側で例のIE7互換性設定がされていると(厄介なことにイントラネットでは標準でオン)、
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0)
となる。仕方が無いので「Trident/4.0」を見てIE8と判別する。
CSSの@charset宣言
CSSの @charset宣言 は必ず1行目に書く必要がありますが、IE8の@charsetは仕様に厳格でないといけないようです。
@charset "EUC-JP"
このとき「@charset」と「"EUC-JP"」の間は半角スペース1個でないとIE8は認識しません。TABや半角スペース2個以上では認識しません。
ちなみにこのIE8の実装が正しい動作のようです。
input type="file"で直接入力できない
Firefox等では以前より直接入力できなかったのですが、IE8でもこれができなくなりました。テキストボックスがグレーアウトします。
歴史的に見て、HTML の ファイル アップロード コントロール (input type=file) はかなりの数の公開された脆弱性の温床であり続けました。この問題を解決するため、このコントロールの動作について二つの変更を加えました。
ユーザーの入力するローカルのファイル パスをキーストロークの監視によって盗む攻撃を防ぐため、ファイル パスの編集ボックスを読み取り専用としました。ファイルをアップロードする場合、ファイルの参照ダイアログを利用して、ファイルを指定する必要があります。
ついでにファイルのパスを送る病(これは設定できる)も変更されたようです。
フォームのtextareaが勝手にスクロールする
IE8において大きめの textarea の挙動がおかしい。
- 右のスクロールバーが中間(一番上や一番下以外)の位置にある。
- スクロールバー付近か行をまたがって入力されるなど、文字が多めに入力されている状態である。
そのとき、特定の行で文字を入力すると、未確定状態・確定状態に関わらず文字を入力するごとにスクロールバーが勝手に移動するという謎のバグがあります。
さらに、スタイルでline-heightが100%より大きく指定されていると、1文字入力するごとに、スクロールバーがガクガク上下に移動し、大変に使いにくくなります。
回避策は不明(CSSをoffにしても発生します)間違え。詳しい情報が分かりましたら、コメントでもTBでもお知らせ願えると助かります。
追記
position:absolute
にしてあげると問題はおきない模様。どうも1文字入力するごとにオブジェクトの位置計算ルーチンか何かが走っているらしく、その辺の計算が重くなってくるとバグる模様。position:absolute ってわけにもいかないしなあ。
さらに追記。
position:absolute で回避する技が(アップデートで)いつの間にか使えなくなってました。IEがabsoluteを正しく解釈して、absoluteでレンダリングされるのでほかの表示が崩れる。
substr(-1)の結果が正しくない
IE8では、"abcd".substr(-1)をすると"abcd"が返ってきます。(正しくは"d"です)
文字列の最後の文字を判定する際によく使う方法なので、かなり厄介なバグです。