「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
目次 †
概要 †
メール送信・受信処理について
仕組み †
全体像 †
┌────── (SMTP) ──────┐
│ │
Mail Box ← MDA ← MTA(内) ⇔ MTA(外) ⇔ MTA(外) ⇔ MTA(内) → MDA → Mail Box
↓ ↑ ↑ ↓
MRA MSA MSA MRA
↓ ↑ ↑ ↓
(POP) (SMTP) (SMTP) (POP)
↓ ↑ ↑ ↓
MUA ───────┘ └─────── MUA
アドレス †
- ヘッダとエンベロープ
仕組みとしては、BCCやML、大量配信時の運用等で利用されている。
しかし、送信元詐称などで悪用されることも多くなってしまっている。
コマンド †
- EHLO/HELOコマンド(通信開始)
- MAIL FROMコマンド(エンベロープFromを送る)
- RCPT TOコマンド(エンベロープToを送る)
- DATAコマンド(メールメッセージ送信開始)
- QUITコマンド(通信終了)
メールヘッダ †
# | 項目 | 概要 |
1 | Return-Path: メアド MAIL FROMコマンド値 | (送信元メアド) MAIL FROMコマンド値 ≒ エンベロープFrom値(詐称可能)。 メールを受信したMTAがエラーメールの返信先として記録。 なお、Errors-To: はRFCに定義されておらず方言的。 |
2 | Received: from MTA by MTA for メアド | 以下のように転送経路をスタックする Received: from MTA by MTA for メアド Received: from MTA by MTA for メアド Received: from MTA by MTA for メアド... |
2-1 | | from EHLO/HELOコマンド値 (逆引値 [xxx.xxx.xxx.xxx]) | メールを送信したMTAのアドレス ・EHLO/HELOコマンド値 ≒ ヘッダFrom値(詐称可能)。 ・逆引値(※ 詐称不可) |
2-2 | | by | メールを受信したMTAのアドレス |
2-3 | | for | 送信先メアド |
3 | From: メアド | (送信元メアド) EHLO/HELOコマンド値 ≒ ヘッダFrom値(詐称可能)。 |
4 | To: メアド | 送信先メアド |
機能 †
# | 略号 | 名称 | ソフトウェア |
1 | MUA | Mail User Agent. | OutlookなどのメーラーでMRA、MSAのクライアント |
2 | MTA | Mail Transfer Agent | Exchangeなどのメールサーバで、MDA、MRA、MSAを同梱 |
2-1 | | MDA | Mail Delivery Agent | 着信メールをユーザのMail Boxにファイルする機能 |
2-2 | | MRA | Mail Retrieval Agent | POPやIMAPのメール受信の機能 |
2-3 | | MSA | Message Submission Agent | SMTPのメール送信の機能 |
MUA †
メールの送受信を行う。
MTA †
- メールサーバ同士、SMTPでメールを転送する。
- 自身のMail Boxの場合、MDAへ引き渡す。
MDA †
着信メールをユーザのMail Boxにファイルする
MRA †
POPやIMAPで認証し、Mail Boxのメールを取り出す。
MSA †
MUAからメールを送信する際に、SMTP-AUTHを行う。
プロトコル †
電子メールで使われるプロトコル
SMTP †
- SMTP : Simple Mail Transfer Protocol
などもある。
- シーケンス
- クライアントからサーバのTCPポート25のコネクションを確立
- サーバがこれに応答する(SMTPのリプライコード220)。
- クライアントからサーバにEHLO/HELOコマンドで通信開始を宣言する。
- サーバがこれに応答する(...)。
- クライアントからサーバにMAIL FROMコマンドで返信先アドレス(エンベロープFrom)を送る。
- サーバがこれに応答する(SMTPのリプライコード250)。
- クライアントからサーバにRCPT TOコマンドで送信先アドレス(エンベロープTo)を送る。
- サーバがこれに応答する(SMTPのリプライコード250)。
- クライアントからサーバにDATAコマンドでメールメッセージ送信開始を宣言する。
- サーバがこれに応答する(SMTPのリプライコード354)。
- クライアントからサーバにメールメッセージを送る(終了まで)。
- サーバがこれに応答する(SMTPのリプライコード250)。
- クライアントからサーバにQUITコマンドを送信し、TCPコネクションを切断
- サーバがこれに応答する(SMTPのリプライコード221)。
POP †
- POP : Post Office Protocol
- ポート番号 : 110
- メール受信用プロトコル
- ユーザのMail Boxから自分のメールを取り出す時に使用
- 現在は、改良されたPOP3 (POP Version 3) が使用される。
などもある。
IMAP †
- IMAP : Internet Message Access Protocol
- ポート番号 : 143
- メール受信用プロトコル
- ユーザのMail Boxから自分のメールを取り出す時に使用
- 現在IMAPと呼ぶときにはIMAP4を指すことが通常
- POPとの最も大きな違いは、IMAPはMail Boxにメールを残すことが出来る。
などもある。
認証関連 †
クライアント認証 †
SMTP-AUTH †
サーバとクライアントの双方が対応してなければ利用できない拡張だが、
切り替えが進められ、近年では多くのサービスで必須となっている。
- SMTP-AUTH、SMTP Authentication、SMTP認証
- SMTP-AUTHを行うためのMSAをサブミッションポート(587)で実装した。
- SASL(Simple Authentication and Security Layer)機構を採用
# | コマンド | 説明 |
1 | AUTH LOGINコマンド | 平文 |
2 | AUTH PLAINコマンド | 平文(RFCに無いので実装が異なるケースがある) |
3 | AUTH CRAM-MD5コマンド | チャレンジ&レスポンス認証 |
4 | AUTH DIGEST-MD5コマンド | ダイジェスト認証 |
POP before SMTP †
- MUAはPOP3をサポートしていたためSMTP-AUTH普及前の認証機構として利用された。
- POP3の認証結果のIPアドレスを一定時間キャッシュしておき、認証済みIPアドレスからのメール送信を受け付けた。
Authenticated POP †
認証されたPOPという意味。
- チャレンジ・レスポンス
- POP3よりは安全性が高い。
- あまり普及してない(脆弱性)。
サーバー認証 †
送信(元)ドメイン認証とも言い、認証された場合に次の転送処理を継続する。
SPF(Sender Policy Framework) †
Sender ID(Sender ID Framework) †
SPFに加え、Resent-Sender, Resent-From, Sender, Fromなどの
メールアドレスPRA(Purported Responsible Address)の
ドメイン部分の正当性を、SPFと同じ仕組みで検証する。
DKIM(DomainKeys? Identified Mail) †
DomainKeys?とDKIMがある。
- DKIM
- ヘッダにユーザの公開鍵を添付する拡張でユーザ単位の認証も可能としている。
- 送信元のドメインを(、エンベロープFromではなく?)、DKIM-Signatureヘッダで示す。
DMARC(Domain-based Message Authentication, Reporting, and Conformance) †
over SSL †
サーバー認証+経路の暗号化(メール自体を暗号化しない)。
署名・暗号化 †
- 送信時、電子メールに署名と暗号化
- 受信時、電子メールの署名検証と復号化
鍵の交換 †
公開鍵を交換する必要がある。
- X.500などを使用できそうだが、標準化された仕様は無さそう。
- Microsoft製品の場合、ADに公開鍵をアップロードすることで、
ユーザによる個別鍵交換の手間を省くことができるらしい。
鍵の利用 †
署名 †
- 送信元の秘密鍵を使用して署名する。
- 送信先で送信元の公開鍵を使用して署名検証。
暗号化 †
- 送信先で共通鍵を生成する。
- 共通鍵でメールを暗号化
- 送信先の公開鍵を使用して共通鍵を暗号化
-メール中に暗号化された共通鍵を同梱-
- 送信先で送信先の秘密鍵を使用して共通鍵を復号化
- 復号化した共通鍵を使用してメールを復号化
プロトコル †
S/MIME †
- S/MIME : Secure/Multipurpose Internet Mail Extensions
- 鍵の交換
- 不特定多数とのやり取りで使用する。
- 証明書の公開鍵暗号基盤を使用する。
- 特徴
- MIMEを拡張したもので、添付ファイルなども暗号化が可能。
- 仕組 : 暗号化や署名には、PKCS #7を拡張したCMSを用いる。
- バージョン
- v2 : RSAを使用して鍵交換、暗号化自体には、3DESやRC2などを使用する。
- v3 : PKCSに従うためCA(認証局)が署名された公開鍵を発行することで、正当性を保証する。
PGP †
- PGP : Pretty Good Privacy
- 互いに公開鍵を署名しあう
「Web-of-trust(信用の輪)」の
インフラを使用して正当性を保証する。
- 加えて、公開鍵のフィンガープリントを確認する。
(フィンガープリントの交換か確認ができるインフラが必要)
STARTTLS †
- SMTPやPOPの経路のみの暗号化
- 上位層のプロトコルから見て透過的。
- TLSより上位のレイヤの設計と実装に委ねられている。
- ハンドシェイクをどう始めるか?
- 交換された電子証明書をどう解釈するか?
プログラム †
送信処理 †
メール送信処理は、.NETの標準的なAPIを使用して処理可能である。
SmtpClient? †
★ Obsoleteになっている。MailKitが後継。
// messageオブジェクトを生成
System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();
// 送信者を設定
message.From = new System.Net.Mail.MailAddress("xxxxx@yyyyy.co.jp", "西野 大介");
message.Sender = new System.Net.Mail.MailAddress("xxxxx@yyyyy.co.jp", "西野 大介");
// 件名を設定
message.SubjectEncoding = Encoding.GetEncoding("UTF-8");
message.Subject = "テスト メール";
// メッセージボディを設定
message.BodyEncoding = Encoding.GetEncoding("UTF-8");
message.Body = "本文\r\n本文\r\n本文\r\n本文\r\n本文\r\n本文\r\n本文\r\n本文\r\n本文\r\n本文\r\n本文\r\n";
// 添付ファイルを設定 --------------------------------------------------
message.Attachments.Add(
new System.Net.Mail.Attachment(@"C:\新規テキスト ドキュメント.txt",
new System.Net.Mime.ContentType("test/plain; charset=UTF-8")));
message.Attachments.Add(
new System.Net.Mail.Attachment(@"C:\新規Microsoft Word 文書.doc",
new System.Net.Mime.ContentType("test/plain; charset=UTF-8")));
message.Attachments.Add(
new System.Net.Mail.Attachment(@"C:\新規ビットマップ イメージ.bmp",
new System.Net.Mime.ContentType("test/plain; charset=UTF-8")));
// ---------------------------------------------------------------------
// addressコレクションオブジェクトを生成 -------------------------------
message.To.Add("xxxxx@yyyyy.co.jp");
message.CC.Add("xxxxx@yyyyy.co.jp");
message.Bcc.Add("xxxxx@yyyyy.co.jp");
// ---------------------------------------------------------------------
// その他、オプション --------------------------------------------------
// 優先度
message.Priority = System.Net.Mail.MailPriority.Normal;
// フォーマット
message.IsBodyHtml = false;
// 送信失敗時、レスを受信するかどうか
message.DeliveryNotificationOptions
= System.Net.Mail.DeliveryNotificationOptions.OnSuccess;
// ---------------------------------------------------------------------
// SmtpClientオブジェクトを作成
System.Net.Mail.SmtpClient client
= new System.Net.Mail.SmtpClient("xxx.xxx.xxx.xxx");
// ネットワーク経由
client.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
// タイムアウト値(ミリ秒))
client.Timeout = 5000;
// 認証(デフォルト)
client.UseDefaultCredentials = true;
//// 認証(カスタム)
//client.Credentials = new System.Net.NetworkCredential("username", "password");
// メッセージを送信
client.Send(message);
MailKit? †
SmtpClientの後継。
- 次の3つのメールクライアントAPIを提供している。
- SMTPクライアント
- POP3クライアント
- IMAP4クライアント
- 対応している主なプラットフォーム
- .NET Framework 4.5以降
- .NET Standard 1.3以降
- .NET Core 1.0以降
- UWP 10.0.12040以降
- Xamarin.Android/Xamarin.iOS
SendGrid? †
- クラウド型のメール配信サービス
- WebAPIでメール送信処理を実装可能。
- 大規模なメール配送を安全に行うには特別なノウハウがあり罠も多い。
辛い自前運用を、お金(サービス)で解決できる。
- 最大送信量に合わせたインフラの確保
- IPアドレスのウォームアップ(IPウォームアップ)が必要
- 開封率やクリック率の追いかけを効率化
- その他
Amazon SES、Mailchimp、Mandrill
受信処理 †
- メール受信処理は複雑なため、メール受信処理をシステム内に組み込まないようにするか、若しくは、専用の製品を使用して処理を実装する。
- ただし、Dynamicsなどの最近のパッケージでは、メール受信処理(メールボックスの監視サービスなど)も実装している。さすがという感じ。
POP3クライアントを実装するので受信処理も実装可能。
その他 †
携帯メールアドレス †
- 携帯向けにメール送信する場合は、携帯メールアドレス(RFCに準拠しないメールアドレス)に対応する必要があるか確認する。
- .NETでは、RFCに準拠しないメール アドレスをMailAddress?クラスに設定すると
例外となることがある(これを利用して、RFCに準拠しないメール アドレスをチェックできる)。
- この場合、MailMessage?クラスのToプロパティ(MailAddressCollection?クラス)にAddすると例外としないで処理できる。
- 必要であるなら、携帯メールアドレス対応のコンポーネントを導入する
- 当該アドレスにSMTPが対応していないケースもあるようである(Exchange 2000 Server、Server 2003)
IPウォームアップ †
- メルマガ配信などを行う、マーケティング領域のシステムなどで一般的な用語。
- メールが確実に届くように、IPアドレスのレピュテーションを上げること。
レピュテーション †
(IPアドレスの)レピュテーション
- メール配信の重要な評価指標、メール送信元の信頼度。
- ISPはメールの送信者の正当性を、レピュテーションで判断。
- レピュテーションが低い場合、送信したメールは
迷惑メールであると見なされ、受信拒否さ れる可能性が高くなる。
- 新しいIPアドレスにはレピュテーションがないので、
- 新しいIPアドレスからメールが配信されてもISPは、
メール送信元の正当性を判断できず、メールが確実に届かない恐れがある。
- メールを確実に届けるために、IPウォームアップで新しいIPアドレスのレピュテーションを上げる。
参考 †
参考 †
MailKit? †
SendGrid? †
IPウォームアップ †
Tags: :インフラストラクチャ, :通信技術