宛先不明判定が厳しいメールサーバへの並行配送を制限する

3000人程度の利用者に対するメールシステムを、かれこれ12年間、オンプレミスで運用してきたのですけれど、ついに G Suite に移転することになりました。その間に得たノウハウを、このままロストテクノロジーにするのも惜しいので、過去の作業ログの中から、ある程度汎用性がありそうなトピックを取り出して、公開しようと思います。

某月某日。2000人の学生宛に同報メールを送信すると115件が拒否されて返ってきたと、某センターから報告。さて何が起こっているのか?
拒否されている時のログは、以下の通り。

```
Jul  8 11:57:46 mails0 postfix/smtp[7338]: 91A03E01BE: to=<alice-mobile@docomo.ne.jp>, orig_to=<alice@example.jp>, relay=mfsmax.docomo.ne.jp[203.138.181.240]:25, delay=0.73, delays=0.05/0.02/0.07/0.59, dsn=5.0.0, status=bounced (host mfsmax.docomo.ne.jp[203.138.181.240] said: 550 Unknown user bob-mobile@docomo.ne.jp charie-mobile@docomo.ne.jp (in reply to end of DATA command))
```

しかし、同じユーザの転送状況を見ると、成功しているときもあるので、単純な転送先設定の誤りではない。

```
Jul  3 09:36:26 mails0 postfix/smtp[11334]: 9B1C9E02FA: to=<alice-mobile@docomo.ne.jp>, orig_to=<alice@example.jp>, relay=mfsmax.docomo.ne.jp[203.138.180.240]:25, delay=0.25, delays=0/0/0.07/0.18, dsn=2.0.0, status=sent (250 Requested mail action okay, completed)
Jul  3 18:15:58 mails0 postfix/scan/smtp[18846]: 60D46E03A7: to=<alice-mobile@docomo.ne.jp>, orig_to=<alice@example.jp>, relay=avasgw.example.jp[133.15.2.65]:25, delay=16, delays=16/0/0.01/0.21, dsn=2.6.0, status=sent (250 2.6.0 <20140703T181558+0900-548-0002> Queued mail for delivery)
Jul  7 17:36:12 mails0 postfix/smtp[13251]: D80BFE01C0: to=<alice-mobile@docomo.ne.jp>, orig_to=<alice@example.jp>, relay=mfsmax.docomo.ne.jp[203.138.180.240]:25, delay=0.66, delays=0.05/0.01/0.07/0.54, dsn=2.0.0, status=sent (250 Requested mail action okay, completed)
```

調べてみると、以下の情報に行き当たった。

* https://www.nttdocomo.co.jp/service/communication/imode_mail/notice/mass_send/
* http://d.hatena.ne.jp/ts_asano/20120822/1345594575 

つまり、docomo / AU / Softbank などの携帯キャリアの MTA は、1つの smtp セッションで複数の宛先にメールを配送する場合、そのセッションに含まれる1つの宛先でも user unknown があると、そのメールを mass mailing と判定して拒否するようになっているらしい。

そのため、このような設定を行っている MTA に対しては、並列配送しないように設定する必要がある。具体的には、`/etc/postfix/master.cf` に以下のような記述を追加して、並列度1の配送先 mobilesmtp を設置する。

```conf:/etc/postfix/master.cf
mobilesmtp      unix    -       -       n       -       -       smtp
  -o syslog_name=postfix/mobile
  -o smtp_destination_concurrency_limit=1
  -o smtp_destination_recipient_limit=1
```

次に、対象となるドメインを列挙したファイル `/etc/postfix/mobilephone_transport` を用意する。

```conf:/etc/postfix/mobilephone_transport
# docomo
docomo.ne.jp	mobilesmtp:
mopera.net	mobilesmtp:
# au
ezweb.ne.jp	mobilesmtp:
biz.ezweb.ne.jp	mobilesmtp:
augps.ezweb.ne.jp	mobilesmtp:
ido.ne.jp	mobilesmtp:
# softbank
softbank.ne.jp	mobilesmtp:
i.softbank.jp	mobilesmtp:
.vodafone.ne.jp	mobilesmtp:
disney.ne.jp	mobilesmtp:
# emobile
emnet.ne.jp	mobilesmtp:
emobile.ne.jp	mobilesmtp:
emobile-s.ne.jp	mobilesmtp:
# willcom
pdx.ne.jp	mobilesmtp:
willcom.com	mobilesmtp:
wcm.ne.jp	mobilesmtp:
```

このファイルは、postfix から参照できるデータベースに変換しておく。

```shell-session
$ sudo postmap hash:/etc/postfix/mobilephone_transport
```

最後に、これらの対象ドメイン向けのメールは mobilesmtp に配送するように `/etc/postfix/main.cf` に設定する．

```conf:/etc/postfix/main.cf
transport_maps = hash:/etc/postfix/mobilephone_transport
```

これで、携帯向けのメールは並列配送しないようになったので、ある学生1人が転送失敗しても、他の学生宛メールが巻き添えになることはなくなったはず。

なお、その後もメール転送についてはトラブルが頻発したので、2019年時点の知見としては、利用者によって申告された転送先メールアドレスをそのまま設定してはいけない。必ず、そのメールアドレスが有効であることを確認してから設定する必要がある。