メール送受信の仕組みを全ッッ然理解していなかった話

スマホからメールすることはほとんどないなぁ

おまとめ三行

僕がどれだけ勘違い上等デコ助野郎だったか
そっちのSPFじゃないよねっ(*≧▽≦*)
ほんっとーに迷惑な奴だよ、迷惑メールは

全然理解していなかったと過去形で書いていますけど、実際のところは現在進行形で理解していないっていうお話です。

先日、仕事で開発しているウェブサービスで、メールがやたらと届かなくなるという不具合が発生してしまいました。お客さんから「メールが全然飛ばねえぞ。どうなってんだゴルァ! さっさと原因を解決して飛ぶようにしやがらねーと、テメーの首を飛ばすぞああん!?」的なクレームが来ました。

それまで、これと言って大きな問題もなくメールは飛ばせていたし、クレームが来た時も、正常に飛んでいる人もたくさんいたもんだから、どうせ受信側の問題だろとか思ってたんですよ。「うっせー。外部の人間に俺の首を飛ばす権利があんのかぁ! 大口叩いてツバを飛ばしてくんじゃねえぞこらぁ!」と開き直ってたんです。でもどうやらそうじゃないことが分かったので、こりゃあ首と胴体が離れる前にどげんかせんといかんということで、いろいろと調べておったんです。

メールが届かない原因ってのは、結構いろんなパターンがある。これ一つだけやっときゃオールオッケーってわけには、なかなか行かないみたいです。

最初にも言った通り、僕はその仕組みをほとんど理解できていないので、ここでその全てを話すことはできません。でも、少なくとも今回はこんなパターンを知ったってのを、少しお話しさせていただこうかと。そんな次第です。



メールサーバーの設定

パターンの前に、僕がどれだけ勘違い上等デコ助野郎だったかってことを、ちょいとだけ。

メールの送受信を行うには、メールサーバーの設定が必要になります。ここではAWSのEC2を使う場合の話をします。

AWSのEC2を使う場合、サーバーを起動すると、デフォルトでsendmailというソフト(MTAとか言うのかな?)が動いています。なので、ぶっちゃけ何も設定しなくても、メールは送信できます。

受信する場合は、もう少し設定が必要です。sendmailに関しては、以前にこんな記事も書いたことがあるので、ここでは省略します。もし参考になれば。

sendmail転送設定を(なるべく簡潔に)完結させる



実を言うと、僕はすでにここからよく分かってなかったんですね。

例えば、norm-nois.comというドメインで、メールを使いたい場合。sendmailの設定以外に、通常はDNSのレコード設定ってのも行うことになります。

norm-nois.com A xxx.xxx.xxx.xxx
norm-nois.com MX 10 norm-nois.com

DNSレコードって何のこっちゃって人はすみません、ググってください。今回は説明は省略。

とにかく、MXっていうレコードでドメインを指定することで「@norm-nois.com」のメールアドレスでメールを受け取れるようになるわけです。

僕はこのMXレコードを設定するだけで「@norm-nois.com」のメールアドレスに関する送受信は、全てAレコードで設定したIPアドレスのサーバーから行えるもんだと思ってたんですよ。でもそうじゃなかった。

受信に関しては、確かにAレコードで設定したサーバーで受け取れます。sendmailで転送設定を行っていれば、サーバーで受け取ったメールをgmailとかに転送もできる。ここまでは良かった。

でも、送信に関しては、localhostから送信されることになっちゃうんですね。



んーと、何を言ってるかってーと……例えば、メールサーバーと、メールの送信を行うウェブサービスがあるサーバーが、別々の場合。

norm-nois.com A 111.111.111.111
mail.norm-nois.com A 222.222.222.222
norm-nois.com MX 10 mail.norm-nois.com

ここでは、IPアドレスが111.111.111.111のサーバーで、norm-nois.comというドメインのサービスが動いてて、IPアドレスが222.222.222.222のサーバーが、メールサーバーに設定されているとします。メールサーバーの方には、mail.norm-nois.comというサブドメインが当ててある。

ここで今、「akatsuki@norm-nois.com」宛にメールが飛んできた場合。この場合は、メールサーバーの方でメールを受信します。でも、norm-nois.com(111.111.111.111)からメールを送信する場合は、そのままnorm-nois.comのサーバーから、直接メールが送信される。localhostってのはそういう意味です。

僕はこれを、勝手にmail.norm-nois.comの方から送信されてるもんだと思い込んでました。MXレコードでそっちを指定してるんだから、あとは自動的にそっちを経由してくれると思ってました。そうではないんですね。経由させるには、ちゃんと自分で、メール送信に使う接続先のサーバーを指定しないといけない。データベースの接続を設定するのと同じような感じ。

まずこれが、今回のメール不達騒動を引き起こす要因の一つだったのかなと思われます。



ブラックリストについて

ほんじゃあ、具体的にメールが届かない原因について、探っていきやしょう。

一番よくあるパターン……かどうかは分からないですが、とにかくメールが届かなくなった時に、真っ先に疑えるのは、自分とこのメールサーバーが、ブラックリストに載っちゃってる場合です。詳しい仕組みは分かりませんが、やたらとスパムメールを飛ばしまくってたり、そうでなくても、メール送信に使うサーバーの設定などが適切に行われていないと「このサーバーから飛ぶメールは怪しいぞ」と判定されて、ブラックリストに載ってしまうことがあります。

ブラックリストに載ってるかチェックできるサイトはいっぱいあります。「メール ブラックリスト チェック」とかで検索すると、すぐ出てくる。

例えばこんなサイト。
http://www.blacklistalert.org

ただし、ブラックリストに載ったサーバーからのメールを拒否するどうかは、受信サーバーの設定によります。なので、ブラックリストに載っていたとしても、何事もなくメールが届くこともあります。

この辺、ちょっと厄介ですよね。僕もそうだったんですが、最初に「メールが届かないんですけど」って問い合わせが来たとき、それ以外のほとんどの人には正常に飛んでたから、ブラックリストに載ってるなんて、夢にも思ってなかったんですね。っていうか、この時点ではブラックリストなんて概念すら存じ上げていなかった。

じゃあ適切な設定って何よってことなんですが、これもいろいろあるんで、とりあえず今回は、以下の二つについて見て行きます。

・SPF設定
・DNSの逆引き設定

僕の場合、SPFの設定はしてありました。まあ、先ほど言った大いなる勘違いによって、間違った設定をしてしまってはいたんですけど。でも最初にメールが届かないって問い合わせが来た時は、DNS逆引き設定をしてなかったことで、ブラックリストに載ってしまっていました。



SPFの設定

SPFってのは、サンプロテクションファクター(Sun Protection Factor)の略で、紫外線をカットする強さを表す数値です。SPF値が強い日焼け止めほど、紫外線から身を守ってくれるということになります。

……って、そっちのSPFじゃないよねっ(*≧▽≦*)

SPFというのは、Sender Policy Frameworkの略で、簡単に言えば、メールの送信元のドメインやらIPアドレスが、信頼に値するものかどうかを証明するような仕組みです。メールサーバーの設定を行う際、このSPFの設定をきちんと行っていないと「お宅が飛ばしてるメール、スパムじゃね?」って思われてしまうことがあります。

SPFは、DNSレコードのTXTレコードというもので設定します。

norm-nois.com A 111.111.111.111
mail.norm-nois.com A 222.222.222.222
norm-nois.com MX 10 mail.norm-nois.com
norm-nois.com TXT "v=spf1 +a +mx +ip4:111.111.111.111 -all"

本当はSPFについても詳しく説明した方が良いと思うんですけど、それをここで書いちゃうと今日の記事がマジパねえ長さになっちゃいそうなんで、今日はざっと触りだけ。

上記のSPFレコードは、norm-nois.comのメールがどこから送信されるのを許可するか、みたいなものを設定しています。「v=spf1」ってのは、SPFのバージョンです。この場合はバージョン1ですね。

「+a」は、Aレコードで設定したIPアドレスから送信されるメールならOK、みたいな意味です。「+mx」も同様に、MXレコードで設定したサーバー(mail.norm-nois.com)から送信されるメールなら許可します、みたいなことです。「+ip4:111.111.111.111」は、このIPアドレスのサーバーから送信されるメールは問題ないってことですね。今回の場合だと、Aレコードで111.111.111.111と設定していますので、「+a」と「+ip4:111.111.111.111」は、同じ意味を持つものになります。だからどっちか片方だけ書いときゃ良いんですが、説明の意味も込めて、あえて両方書いてます。同じ意味のものを重複して書いたからと言って、エラーになることはないようです。

「-all」っていうのは、今設定した以外のサーバー(+a、+mx、+ip4:111.111.111.111以外)から送信されるメールは、認証を許可しないという内容です。

認証には「+」「-」「~」「?」の四種類あります。「+」は、認証を許可するという意味です。「+a」とか「+mx」は、AレコードやMXレコードからの送信を許可するってなるわけですね。反対に「-」は、認証を許可しないという意味になります。「-a」と書けば、Aレコードからのメール送信は認証しないという意味になります。「~」は、+の-の中間みたいな、あいまいな感じ。認証が通ることもあるし、通らないこともある。「?」は、そもそも認証の許可するしない自体を設定しません的なこと……かな?

認証が通っているかどうかは、メールのソースを見れば分かります。ソースの中にこんなような記述があれば、認証は無事に通っています。

Received-SPF: pass

「pass」となっていれば、認証成功です。認証が通らない場合は「fail」とか「softfail」とかって表示されます。



じゃあここで今、新しく「blog.norm-nois.com」というサーバーを立ち上げたとしましょう。

norm-nois.com A 111.111.111.111
mail.norm-nois.com A 222.222.222.222
blog.norm-nois.com A 255.255.255.255
norm-nois.com MX 10 mail.norm-nois.com
norm-nois.com TXT "v=spf1 +a +mx +ip4:111.111.111.111 -all"

この時、blog.norm-nois.comに関するSPF設定は存在しません。「-all」の中に含まれることになる。つまり、blog.norm-nois.comのサーバーからメールを送信した場合は、認証が通らないので「fail」となり、相手にメールが届かないことがあります。

ここも、僕が勘違いしてたとこなんですね。

先ほども言ったように、僕はnorm-nois.comに関して、AレコードとMXレコードを設定した時点で設定はバッチリだと思ってたんで、まさにこんなような書き方になってたんですよ。つまりblog.norm-nois.comから飛ばすメールも、passになるだろうと。この先どれだけサーバーを増やそうと、norm-nois.com関連のメールは、何も問題ないはずだと。でもそうじゃないんですね。blog.norm-nois.comからもpassさせたいんなら、それもSPFに書かなきゃいけなかった。

norm-nois.com A 111.111.111.111
mail.norm-nois.com A 222.222.222.222
blog.norm-nois.com A 255.255.255.255
norm-nois.com MX 10 mail.norm-nois.com
norm-nois.com TXT "v=spf1 +a +mx +ip4:255.255.255.255 -all"

たぶんこのせいで、スパム扱いされてたメールも、多々あったかもしれません。



それと、もう一つ大きな勘違いがあった。

「-all」とか「~all」っていうのは、norm-nois.com以外のドメインに関する設定だと思ってたんですよ。

えーっとつまり、norm-nois.comのサーバーで、送信者が「akatsuki@norm-nois.com」と「info@hogehoge.jp」という二つのメールアドレスを使っていたとする。norm-nois.comはうちで管理してるドメインだけど、hogehoge.jpの方は、全然別の人が管理しているドメインだと思って下さい。

この時、akatsuki@norm-nois.comの方は「+a」という設定で認証が行われ、info@hogehoge.jpの方は「-all」あるいは「~all」で認証が判定されると、そんな風に思ってたんです。

仕事で使ってるウェブサービスの方で、実際にお客さんから、送信元を自分たちのメールアドレスにしてくれっていう要望が多数あったんですよ。だけど彼らのドメインを管理しているわけじゃない。大丈夫なのかなとも思ったんですけど、「-all」を止めて「+all」とか「~all」にすれば、普通に使えるようになるんじゃないかと、自分の中ではそう設定していたつもりだったんです。そうじゃないのよね。あくまでもこの設定は、norm-nois.comというドメインに関する設定のみ。まあ、よくよく考えりゃその通りだわな。勝手に他人のドメインの設定なぞできるかっつー話よ。

この勘違いはでかかった。デコ助野郎のデコが禿げ上がってどこまでがデコなのか分からないくらいでかかったわ。

この勘違いに気づくまで、実に二年近くも放ったらかしてしまいました。二年間もずっと、お客さんのメールアドレスを送信元にしていた。きっとこれも、今回の件につながる大きな要因だったんでしょう。「おたくらが管理してないドメインのメールをやたらいっぱい飛ばしてるけど、てめーんとこのサーバーは本当に安全か?」って。



DNSの逆引き設定

DNSの逆引きとは、えーと何て説明すれば良いんだ……? まあようは、特定のIPアドレスとドメインが結びついているかどうか、みたいなことです。

例えば、今僕が、111.111.111.111というIPアドレスを持つサーバーを使っているとして、そのサーバーでnorm-nois.comというドメインを使用していた場合に、この二つがちゃんと結びつけられているか。DNSの設定がちゃんとできているか。それを確かめようってことです。

ちゃんと設定できているか逆引きするには、nslookupとかdigというコマンドを使います。

# nslookup 111.111.111.111

//実行結果(の一部)
Non-authoritative answer:
111.111.111.111.in-addr.arpa name = norm-nois.com.

nslookupを実行した時に、設定したドメインが返ってくれば、逆引き設定ができている証拠です。

設定の仕方はいくつかあると思いますが、AWSのEC2の場合は、以下のページから申請が必要です。
https://aws.amazon.com/forms/ec2-email-limit-rdns-request

ここで逆引き設定したいIPアドレスとドメインを入力すれば、数日くらいで逆引きができるようになります。僕が申請した時は、設定が反映された直後にブラックリストからも消えました。ブラックリストから削除する方法は他にもあると思うんですが、リストのチェックはリアルタイムで行われているっぽいので、逆引きができたり、とにかくちゃんと設定されていることが確認されれば、自然と削除されるんじゃないかと思います。



レピュテーション

僕が上記のDNS逆引き設定をしたのは、一年くらい前のことでした。当時もメールが飛ばないってクレームが来て、それでいろいろと調べたところ、ブラックリストに載っているのが分かったので、逆引き設定して、リストからも除外されました。

そして今回、また同じクレームが来たのですが、でもブラックリストには載ってなかったんですよ。逆引き設定も反映されたままだし、だから余計に、こっちの責任ではないって判断してしまったんですね。首なんて飛ばさせるかコノヤローって、激を飛ばしてたんですね。

でも実は、ブラックリストにさえ載っていなければOKかと言われると、そんなことはないようです。

メールには、レピューテションと呼ばれるものが存在します。これは文字通りに、メールの送信に対する評価、みたいなものです。やたらとスパムばっかり飛ばしているようなサーバーは、このレピュテーションが低くなります。

ブラックリストに載っていなくても、レピュテーションが低いと受信を拒否する設定をしているサーバーも、中にはあるようです。今回僕がクレームを受けたところもそうでした。

レピュテーションもブラックリストと同様に、SPFの設定などをきちんと行っておくことで、低下を防げるようです。僕の場合、前述の通り、送信元のサーバーをSPFレコードに書いてなかったことや、他のお客さんのドメインを送信元に使っていたことが、レピュテーションの低下につながったんじゃないかと思います。SPFの設定がちゃんと設定できているようで、実はできていなかったってことですね。

レピュテーションを調べるサイトもいくつもあるようなので、検索すればすぐに見つかると思います。

僕はここ使いました。
http://www.senderbase.org

レピュテーションは、サーバーに問題なければ自然と高くなって行くそうです。「低くなってしまい、メールが届かなくなった。だけど今すぐに回復させたい! 何とかしてよレピュエモーン!」みたいなことは、僕が調べた限りでは、できないっぽい気がします。だから今回の僕みたいに「三日も待てるか。40秒で解決しな! さもないとセリヌンティウスの命はないよ!」みたいな状況では、もうとにかく謝り倒すしかないかもしれない。






ふー。相も変わらず長々と説明してしまいましたね。でも、冒頭でも言ったように、僕は今もってなお、メールの仕組みを理解しきれていません。だからこれだけ書いても、氷山の一角に過ぎないと思います。もっと他の要因で、メールが届かないことはある。ケータイなんかだと、PCからの受信を拒否してたりもするしね。

それらを全て解決するのは、専門家じゃないと難しいでしょう。僕のように、フロントエンドの開発しかしてないような奴には、厳しい領域です。

そもそも迷惑メールなんてものがこの世に存在しなければ、受信側もフィルタリングする必要なんてないのよね。そうなれば僕たち送信側も、こんなに悩まなくて済むのにね。ほんっとーに迷惑な奴だよ、迷惑メールは。飛ばなくても迷惑だ。



というわけで結論!

メールサーバーについてきちんと理解している人がいないなら、外部のメール配信サービスなどに頼った方が良いかもしれない。

僕も今回の騒動を受けて、結局自前で全部カバーするのは無理だって結論に達したので、SendGridっていうサービスに切り替えました。猶予がなかったってのも、ありますけどね。早急に何とかしなきゃいけない状況だったんで、レピュテーションの回復を待ってられなかった。

まだ使い始めたばかりなので何とも言えませんが、少なくとも僕が自分でメールサーバーを管理するよりは、ずっと安心だと思います。届かないってクレーム寄越した人たちも、SendGridに切り替えた途端「おお神よ! 無事にメールが届くようになりました。あなた様の首を飛ばさずに済みましたことを感謝いたします。アーメン」と、手のひらを返してきましたからね。だから僕も「なーにがアーメンだよ。こっちは一日対応に追われて、朝飯も昼飯も食えなかったんだよこんちきしょう! ようやく飯にありつけるぜ! ずぞぞぞ〜」と、ラーメンの汁を飛ばしながら見届けてやりました。

まだコメントはいただけてないみたい……
もしかしたら何か関連しているかも?