Webサーバー兼SMTPサーバーでやらかした話 〜そして外部メール運用を導入するまで〜

この記事は [CPaaS Now Advent Calendar 2024](https://qiita.com/advent-calendar/2024/cpaas-now) の最終日投稿としてお届けします。  

本アドベントカレンダーを盛り上げるスポンサーである **CPaaS NOW** さんに感謝を込めて、実運用で起きた「メールまわりのやらかし」を共有してみようかと思います。


## はじめに
みなさん、Webサイトの問い合わせフォームや予約システムなどからメールを送信する際、どのようなSMTP運用をしていますか？  

わたしがかつて運用していたプロジェクトでは、**Webサーバー兼SMTPサーバーを同じマシンで運用**していたことがあります。Webホスティングしているサイトはコーポレートサイトでした。そんな環境で、致命的なやらかしをしてしまった経験があります。

この記事では、そのやらかし事例を掘り下げつつ、外部のSMTPを利用してスマートに運用する方法をご紹介します。  


## やらかしの概要

### シナリオ
1. **Webサーバー** と **SMTPサーバー** を同居させて運用。  
1. Webサーバーではコーポレートサイトをホスティング
1. Webサーバーのホスト名はコーポレートドメインを指定
1. メールサーバーは別環境で運用
1. お問い合わせフォームの通知はコーポレートのメールアドレス（`info@example.com` など）へ行う設計。  
1. ところが実際には、**Webサーバー内にローカル配送されてしまい、メールが外部に飛ばない** という問題が発生。

### どうして起きたのか？
- Webサーバー内のSMTP（Postfix等）のデフォルト設定では、**「同一ドメイン宛のメールはローカルに配送する」** となっていることが多いです。  
- そのため、「`example.com` 宛のメールは全部自分あて」と判断し、外部のメールサーバーではなく、Webサーバー内に滞留してしまいました。

この結果、担当者は問い合わせメールが届いていることに気づかず、ユーザーの問い合わせに返事ができないという事態に……。  


## なぜ外部SMTPサーバーが重要なのか
今回のやらかしは、Webサーバー内のSMTPサーバーを利用したため発生しました。可能であれば外部のSMTPサーバーを利用したほうが様々な面でよいことがあります。

### 1. ローカル配送の回避
外部SMTPサーバーを利用することで、**必ず外部経由でメールを送信**するようにできます。  
同一ドメイン宛のメールでも、自社サーバーではなく外部のルーティングを通るため、ローカル配送されるリスクがなくなります。

### 2. 送達率向上
企業向けのSMTPサービスでは、送達率を高めるための取り組み（SPFやDKIMなどの認証設定、IPレピュテーション管理）がしっかり行われています。  
これらを利用することで、**「迷惑メール判定」を受けにくくなり、確実に届くメール運用**が期待できます。

### 3. スケーラビリティ確保
自前サーバーで大量メールを捌くには、**サーバーリソースの確保**や**送信制限の対策**が必要です。一方、外部のSMTPサービスは大規模送信にも対応しているケースが多く、**急なメール送信需要にも柔軟に対応**できます。


### 外部SMTPサーバーとして、CPaaS NOW のようなCPaaSを活用するメリット
今回のアドベントカレンダーのスポンサーである **CPaaS NOW** のようなCPaaS（Communications Platform as a Service）を導入すれば、単にSMTP運用の改善にとどまらず、**メール・SMS・音声通話など複数のチャネルを一元管理**できそうです。（ユーザーではないので想像が混じっていますｍｍ　詳細は[サービスページ](https://smslink.nexway.co.jp/cpaas/lp?utm_source=qiita&utm_medium=referral&utm_campaign=advent-calendar-2024)をご覧ください。）

- **メール送信だけでなく、SMSでリマインド通知**をするなど、エンドユーザーの利便性を高める施策が取りやすい  
- **API連携が充実**しており、開発者が使いやすい形で統合できる  
- 専用の管理コンソールやレポーティング機能で、**メールの到達率やエラーの内訳**を容易に可視化可能

こうしたサービスを積極的に活用することで、**やらかしのリスクを大幅に削減**できるだけでなく、**サービス全体のユーザー体験を向上**させることが期待できるのではないでしょうか。


## 実際の対策例
そうはいっても、なかなか難しい場合は、サーバー上の設定等で対応する必要があります。

### １．ローカル配送を無効にする
Postfixでは、ローカル配送先を指定する **mydestination** パラメータを変更することで、ローカル配送を無効化できます。

以下に、Postfix を使った設定例を示します。外部SMTPを利用して送信することで、同一ドメイン宛メールのローカル配送を回避できます。  

**設定例**
/etc/postfix/main.cf に以下の設定を確認・編集します。
```bash
# /etc/postfix/main.cf

# mydestinationにローカル配送を避けたいドメインを追加しない
mydestination =
```
上記のように、**mydestination** を空にするか、ローカル配送を避けたいドメイン (example.com) を含めないようにします。

デフォルトでは、mydestination にサーバーのホスト名やローカルドメインが設定されていることが多くあります。この場合、同じドメイン宛のメールがローカルに配送されるので確認してみましょう。

### ２．外部SMTPサーバーを利用する

```bash
# /etc/postfix/main.cf

# == SMTPリレー先 (外部SMTP) の設定 ==
relayhost = [smtp.example.com]:587

# == SMTP認証に必要な設定 ==
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_tls_security_options = noanonymous
smtp_use_tls = yes

```

smtp_sasl_password_maps には、外部SMTPサーバーの認証情報を設定します。

たとえば /etc/postfix/sasl_passwd に smtp.example.com:587 username:password の形式で書き、postmap コマンドでハッシュ化（postmap /etc/postfix/sasl_passwd）して使います。ハッシュファイルの権限変更も忘れずに（chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db）行いましょう。

※CPaaSを利用する場合は、API連携となるので、Postfixの設定は不要かと思います

## おわりに
今回のやらかし事例では、WebサーバーとSMTPサーバーを同じマシン・同じドメインで運用した結果、ローカル配送が原因で問い合わせメールが届かなかったという苦い経験を紹介しました。

しかし、外部SMTPサーバーを利用することで、送達率の向上や複数チャネルの一元管理が実現できます。

## まとめのポイント
* Webとメールで別環境、同一ドメインを使用するとローカル配送される恐れがある
* 外部SMTPサーバーやCPaaS利用で、確実なメール送信を実現

最終日の投稿となりますが、この記事をきっかけに、読者の皆さまがより堅牢でスケーラブルなメール運用ができるきっかけとなれば幸いです。