-
Notifications
You must be signed in to change notification settings - Fork 0
MS_Mail
-
TOP > インフラストラクチャ > 通信技術
- メール
- VPN
- ネットワーク機器一覧
※ Open棟梁側にも「メール」ページがあるため、ファイル名は MS_Mail.md とした。
メール送信・受信処理について
┌────── (SMTP) ──────┐
│ │
Mail Box ← MDA ← MTA(内) ⇔ MTA(外) ⇔ MTA(外) ⇔ MTA(内) → MDA → Mail Box
↓ ↑ ↑ ↓
MRA MSA MSA MRA
↓ ↑ ↑ ↓
(POP) (SMTP) (SMTP) (POP)
↓ ↑ ↑ ↓
MUA ─────────┘ └───────────── MUA
- ヘッダとエンベロープ
仕組みとしては、BCCやML、大量配信時の運用等で利用されている。
しかし、送信元詐称などで悪用されることも多くなってしまっている。- ヘッダ → 表記上
- エンベロープ → SMTP上
- 送信元・送信先アドレス
- 送信元アドレス:ヘッダFrom / エンベロープFrom
- 送信先アドレス:ヘッダTo / エンベロープTo
- = SMTPプロトコルのコマンド
- EHLO/HELOコマンド(通信開始)
- MAIL FROMコマンド(エンベロープFromを送る)
- RCPT TOコマンド(エンベロープToを送る)
- DATAコマンド(メールメッセージ送信開始)
- QUITコマンド(通信終了)
- = POPプロトコルのコマンド
| # | 項目 | 概要 |
|---|---|---|
| 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コマンド値 = 送信側MTAが名乗るホスト名(詐称可能)。 ・逆引値(※ 詐称不可) |
| 2-2 | by | メールを受信したMTAのアドレス |
| 2-3 | for | 送信先メアド |
| 3 | From: メアド | (送信元メアド)= ヘッダFrom値(詐称可能)。 |
| 4 | To: メアド | 送信先メアド |
移行メモ(正誤): 原文は「EHLO/HELOコマンド値 ≒ ヘッダFrom値」としていたが、 EHLO/HELO は送信側 MTA が名乗るホスト名であって、ヘッダ From(メールアドレス)とは別物。 上表ではその旨に改めた。 なお「MAIL FROM ≒ エンベロープFrom」は原文どおり正しい。
| # | 略号 | 名称 | ソフトウェア |
|---|---|---|---|
| 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 — メールの送受信を行う。送信 : SMTP / 受信 : POP、IMAP
- MTA — メールサーバ同士、SMTPでメールを転送する。自身のMail Boxの場合、MDAへ引き渡す。
- MDA — 着信メールをユーザのMail Boxにファイルする。
- MRA — POPやIMAPで認証し、Mail Boxのメールを取り出す。
- MSA — MUAからメールを送信する際に、SMTP-AUTHを行う。
電子メールで使われるプロトコル
-
SMTP : Simple Mail Transfer Protocol
-
ポート番号
- 通常ポート番号 : 25(サーバ間の転送に使用)
- サブミッションポート番号 : 587(利用者からの送信の受付に使用)
-
メール送信用プロトコル
-
- SMTP over SSL : ポート465
- SMTP over SSH
などもある。
-
SMTPプロトコルの
- コマンド
- シーケンス
- クライアントからサーバのTCPポート25のコネクションを確立
- サーバがこれに応答する(SMTPのリプライコード220)。
- クライアントからサーバにEHLO/HELOコマンドで通信開始を宣言する。
- サーバがこれに応答する(SMTPのリプライコード250)。
- クライアントからサーバにMAIL FROMコマンドで返信先アドレス(エンベロープFrom)を送る。
- サーバがこれに応答する(SMTPのリプライコード250)。
- クライアントからサーバにRCPT TOコマンドで送信先アドレス(エンベロープTo)を送る。
- サーバがこれに応答する(SMTPのリプライコード250)。
- クライアントからサーバにDATAコマンドでメールメッセージ送信開始を宣言する。
- サーバがこれに応答する(SMTPのリプライコード354)。
- クライアントからサーバにメールメッセージを送る(終了まで)。
- サーバがこれに応答する(SMTPのリプライコード250)。
- クライアントからサーバにQUITコマンドを送信し、TCPコネクションを切断
- サーバがこれに応答する(SMTPのリプライコード221)。
補足: SMTP over SSL(465/tcp)は一度非推奨とされたが、 RFC 8314 により Implicit TLS のサブミッション(Submissions, 465/tcp) として復権している。 現在は 587 + STARTTLS か 465 + Implicit TLS のどちらかを使うのが標準。
- POP : Post Office Protocol
- ポート番号 : 110
- メール受信用プロトコル
- ユーザのMail Boxから自分のメールを取り出す時に使用
- 現在は、改良されたPOP3 (POP Version 3) が使用される。
- また、セキュリティが強化された、 POP over SSL : ポート995 などもある。
- IMAP : Internet Message Access Protocol
- ポート番号 : 143
- メール受信用プロトコル
- ユーザのMail Boxから自分のメールを取り出す時に使用
- 現在IMAPと呼ぶときにはIMAP4を指すことが通常
- POPとの最も大きな違いは、IMAPはMail Boxにメールを残すことが出来る。
- また、セキュリティが強化された、 IMAP over SSL : ポート993 などもある。
サーバとクライアントの双方が対応してなければ利用できない拡張だが、
切り替えが進められ、近年では多くのサービスで必須となっている。
- 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コマンド | チャレンジ&レスポンス認証(認証基盤: AuthenticationInfrastructure.md) |
| 4 | AUTH DIGEST-MD5コマンド | ダイジェスト認証(認証基盤: AuthenticationInfrastructure.md) |
補足(最新化): CRAM-MD5 / DIGEST-MD5 は MD5 の弱化に伴い非推奨。 現在は TLS 上での AUTH PLAIN、もしくは OAuth 2.0 ベースの XOAUTH2(Microsoft 365 / Gmail は基本認証を廃止済み)が主流。
- MUAはPOP3をサポートしていたためSMTP-AUTH普及前の認証機構として利用された。
- POP3の認証結果のIPアドレスを一定時間キャッシュしておき、認証済みIPアドレスからのメール送信を受け付けた。
認証されたPOPという意味。
- チャレンジ・レスポンス
- POP3よりは安全性が高い。
- あまり普及してない(脆弱性)。
- メール本文は暗号化されない。
送信(元)ドメイン認証とも言い、認証された場合に次の転送処理を継続する。
- 送信元のSMTPサーバの正当性をDNSのレコード(DNSサーバ)を使用して検証する。
- SMTPサーバへの設定も必要になる(ソフトウェアの設定で有効化)。
- エンベロープFromのドメインのTXTレコードにIPアドレスの記載がある。
SPFに加え、Resent-Sender, Resent-From, Sender, Fromなどの
メールアドレスPRA(Purported Responsible Address)の
ドメイン部分の正当性を、SPFと同じ仕組みで検証する。
補足(最新化): Sender ID は事実上使われていない(RFC 4406 は Historic に降格)。 現在は SPF + DKIM + DMARC の組み合わせが標準。
DomainKeysとDKIMがある。
- DomainKeys
- DKIM
- ヘッダにユーザの公開鍵を添付する拡張でユーザ単位の認証も可能としている。
- 送信元のドメインを、DKIM-Signatureヘッダ(
d=タグ)で示す。
移行メモ(補足): 原文が「(エンベロープFromで?)」と留保していた点について。 DKIM はエンベロープ From を使わない。 検証者は DKIM-Signature ヘッダの
d=(署名ドメイン)とs=(セレクタ)から<s>._domainkey.<d>の TXT レコードを引いて公開鍵を得る。 エンベロープ From を使うのは SPF のほう。 また DomainKeys(RFC 4870)は DKIM(RFC 6376)に置き換えられ廃止済み。
補足(最新化): DMARC は SPF / DKIM の結果に加えて ヘッダ From ドメインとの一致(alignment) を要求する点が要。 2024年以降、Google / Yahoo は一括送信者に DMARC 設定を必須化している。
サーバー認証+経路の暗号化(メール自体を暗号化しない)。
- 送信時、電子メールに署名と暗号化
- 受信時、電子メールの署名検証と復号化
公開鍵を交換する必要がある。
- X.500などを使用できそうだが、標準化された仕様は無さそう。
- Microsoft製品の場合、ADに公開鍵をアップロードすることで、
ユーザによる個別鍵交換の手間を省くことができるらしい。
- 送信元の秘密鍵を使用して署名する。
- 送信先で送信元の公開鍵を使用して署名検証。
-
送信元で共通鍵を生成する。
-
共通鍵でメールを暗号化
-
送信先の公開鍵を使用して共通鍵を暗号化
-メール中に暗号化された共通鍵を同梱-
-
送信先で送信先の秘密鍵を使用して共通鍵を復号化
-
復号化した共通鍵を使用してメールを復号化
移行メモ(正誤): 原文は最初の行が「送信先で共通鍵を生成する」となっていたが、 以降の手順(共通鍵でメールを暗号化 → 送信先の公開鍵で共通鍵を暗号化 → メールに同梱)と矛盾する。 共通鍵を生成するのは送信元が正しいので改めた。
- S/MIME : Secure/Multipurpose Internet Mail Extensions
- 鍵の交換
- 不特定多数とのやり取りで使用する。
- 証明書の公開鍵暗号基盤を使用する。
- 特徴
- MIMEを拡張したもので、添付ファイルなども暗号化が可能。
- 仕組 : 暗号化や署名には、PKCS #7(
PKCS.md)を拡張したCMSを用いる。 - バージョン
- v2 : RSAを使用して鍵交換、暗号化自体には、3DESやRC2などを使用する。
- v3 : PKCS(
PKCS.md)に従うためCA(認証局)が署名された公開鍵を発行することで、正当性を保証する。
- PGP : Pretty Good Privacy
- 鍵の交換
- 小規模なコミュニティで使用する。
- 仕組
- 互いに公開鍵を署名しあう「Web-of-trust(信用の輪)」のインフラを使用して正当性を保証する。
- 加えて、公開鍵のフィンガープリントを確認する。
(フィンガープリントの交換か確認ができるインフラが必要)
メール送信処理は、.NETの標準的なAPIを使用して処理可能である。
★ 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";
// 添付ファイルを設定 --------------------------------------------------
message.Attachments.Add(
new System.Net.Mail.Attachment(@"C:\新規テキスト ドキュメント.txt",
new System.Net.Mime.ContentType("text/plain; charset=UTF-8")));
message.Attachments.Add(
new System.Net.Mail.Attachment(@"C:\新規Microsoft Word 文書.doc",
new System.Net.Mime.ContentType("application/msword")));
message.Attachments.Add(
new System.Net.Mail.Attachment(@"C:\新規ビットマップ イメージ.bmp",
new System.Net.Mime.ContentType("image/bmp")));
// ---------------------------------------------------------------------
// 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);移行メモ(正誤): 原文のサンプルは、3つの添付すべてに
new ContentType("test/plain; charset=UTF-8")を指定していた。
test/plainはtext/plainのタイプミス。- また、Word / ビットマップに
text/plainは不適切なので、 それぞれapplication/msword/image/bmpに直した。
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
- クラウド型のメール配信サービス
- WebAPIでメール送信処理を実装可能。
- 大規模なメール配送を安全に行うには特別なノウハウがあり罠も多い。
辛い自前運用を、お金(サービス)で解決できる。- 最大送信量に合わせたインフラの確保
- IPアドレスのウォームアップ(IPウォームアップ)が必要
- 開封率やクリック率の追いかけを効率化
- その他:Amazon SES、Mailchimp、Mandrill
- メール受信処理は複雑なため、メール受信処理をシステム内に組み込まないようにするか、
若しくは、専用の製品を使用して処理を実装する。 - ただし、Dynamicsなどの最近のパッケージでは、
メール受信処理(メールボックスの監視サービスなど)(CRMEmailManagement.md)も実装している。さすがという感じ。 - MailKit は POP3 / IMAP4 クライアントを実装するので受信処理も実装可能。
- 携帯向けにメール送信する場合は、携帯メールアドレス(RFCに準拠しないメールアドレス)に
対応する必要があるか確認する。 - .NETでは、RFCに準拠しないメール アドレスをMailAddressクラスに設定すると
例外となることがある(これを利用して、RFCに準拠しないメール アドレスをチェックできる)。 - この場合、MailMessageクラスのToプロパティ(MailAddressCollectionクラス)にAddすると
例外としないで処理できる。 - 必要であるなら、携帯メールアドレス対応のコンポーネントを導入する。
- 当該アドレスにSMTPが対応していないケースもあるようである(Exchange 2000 Server、Server 2003)。
補足(最新化): いわゆる「キャリアメール」の RFC 非準拠アドレス (
@の直前にピリオド、連続ピリオド等)は、 各キャリアが 2009 年前後に新規取得を停止しており、 現在は既存アドレスの残存への配慮という位置付け。
- メルマガ配信などを行う、マーケティング領域のシステムなどで一般的な用語。
- メールが確実に届くように、IPアドレスのレピュテーションを上げること。
(IPアドレスの)レピュテーション
- メール配信の重要な評価指標、メール送信元の信頼度。
- ISPはメールの送信者の正当性を、レピュテーションで判断。
- レピュテーションが低い場合、送信したメールは
迷惑メールであると見なされ、受信拒否される可能性が高くなる。 - 新しいIPアドレスにはレピュテーションがないので、
- 新しいIPアドレスからメールが配信されてもISPは、
メール送信元の正当性を判断できず、メールが確実に届かない恐れがある。 - メールを確実に届けるために、IPウォームアップで新しいIPアドレスのレピュテーションを上げる。
- 新しいIPアドレスからメールが配信されてもISPは、
- SmtpClient Class (System.Net.Mail)
- メール運用がロストテクノロジーになっていく話 - Qiita
- MailKit が公式に .NET の SmtpClient を置き換える - InfoQ
- 電子メールを送信するには?(MailKit編)- @IT
- SendGridとは
- SendGridでメール配送を始めるためのまとめ - Qiita
- IPウォームアップを行う - SendGrid ドキュメント
Tags: インフラストラクチャ, 通信技術
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。