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

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
スマホからメールすることはほとんどないなぁ

この記事を三行にまとめると

僕がどれだけ勘違い上等デコ助野郎だったか
そっちの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に切り替えた途端「おお神よ! 無事にメールが届くようになりました。あなた様の首を飛ばさずに済みましたことを感謝いたします。アーメン」と、手のひらを返してきましたからね。だから僕も「なーにがアーメンだよ。こっちは一日対応に追われて、朝飯も昼飯も食えなかったんだよこんちきしょう! ようやく飯にありつけるぜ! ずぞぞぞ〜」と、ラーメンの汁を飛ばしながら見届けてやりました。
 もしかしたら何か関連しているかも? 
 みんなからのコメント 
2018年04月14日 12:39:56
ff
気になった点を一つ。

% dig norm-nois.com mx
...
...
;; ANSWER SECTION:
norm-nois.com. 86370 IN MX 0 norm-nois.com.

...

MX の優先度が 0 (ゼロ)だけど、普通は10, 20 とかにしといて、
サーバー移転とかの時に優先度あげたメールサーバー(MX)を上げて、
そっちにメールが行くようにしたりします。
0 (ゼロ)だと、それ以上優先度の高いメールサーバーをあげられないので...。

また、本当にちゃんとメールサーバーを運用したいのなら、メールサーバー複数あげて(DNSにMXを複数設定して)、

mx1.norm-nois.com IN 111.111.111.111
mx2.norm-nois.com IN 222.222.22.222

norm-nois.com. IN MX 10 mx1.norm-nois.com
norm-nois.com. IN MX 20 mx2.norm-nois.com

片方のメールサーバーがメンテしてても(or 死んでても)、
メールは受け取って、ロストしないようにした方がいいとはおもいます
(ロードバランスで一つのIPのうらに複数メールサーバーある場合もあるけど)。
まあ、ITの会社のくせに、ちゃんとやってない会社わりとあるけどね
(そういう会社の製品は買わない...(笑))。

メールサーバーをちゃんと運用するのは、相手側もあるので、Webサーバーなんかよりメンドクサイです。
2018年04月14日 23:10:09
まっち~(管理人)
なるほど。優先度が0だとそうなるというのは知りませんでした。勉強になります。
ただ、このブログはレンタルサーバーで動いてるので、メールサーバーの運用とかも自分ではやってないんですよ。
仕事でメールサーバーを運用する必要があるときはそこも気をつけたいと思います。ありがとうございます。
2019年05月12日 22:38:53
[…] このあたりのことは以下のサイトを参考にしています。 https://www.kagoya.jp/howto/network/nameresolution/ https://japanrock-pg.hatenablog.com/entry/20090602/1243942825 https://go-journey.club/archives/10118 https://sendgrid.kke.co.jp/blog/?p=4494 https://norm-nois.com/blog/archives/3636 […]