mk-mode BLOG

このブログは自作の自宅サーバに構築した Debian GNU/Linux で運用しています。
PC・サーバ構築等の話題を中心に公開しております。(クローンサイト: GitHub Pages

ブログ開設日2009-01-05
サーバ連続稼働時間
Reading...
Page View 合計
Reading...
今日
Reading...
昨日
Reading...

Ruby - UNIX MBOX メールヘッダ・Received属性の検証!

[ プログラミング ] [ Mail, Ruby ]

こんばんは。

今日は Ruby で UNIX MBOX メールデータ中で一番肝のメールヘッダ「Received」属性を検証してみました。 以下の過去記事も参照。

「Received」属性の検証と言っても、RFC 5321, 5322 に準拠しているか、どんな構成になっているを分類しているだけです。 今回は不正な中継をしていないか等の検証は行っていません。

「Received」属性とは RFC 5321, 5322 でルール化されているもので、経由したメールサーバの情報が記録されています。基本的に複数のサーバを経由していれば複数記録されています。

RFC 5321, 5322 によれば、「Received」は以下のような書式になっていないといけません。

1
2
Received: from xxxx by xxxx via xxxx with xxxx id xxxx for xxxx;
 Tue, 1 Mar 2011 12:23:38 +0900

現在の基準である RFC 5321, 5322 では “from” と “by” は必須ですが、以前の基準では設定されていなくてもよかったようです。 そして、日時は曜日部分・秒部分はなくてもよいです。

RFC 5321, 5322 については以下等も参照。

以下に、当方の UNIX MBOX メールデータ(61,665件)を検証した結果を掲載します。 ※だから何?と言われそうですが、自分の近い将来のための記録として掲載していますので、ご承知おきください。

Ruby スクリプトは今までの検証で使用してきたものを流用しています。(しかし、今回はかなり修正しました)

使用した正規表現

多数のデータの中には様々な書式のものが存在するため、単純な正規表現では解析不可能です。 今回は多数の正規表現を使用しました。 参考までにそのうちの1つを紹介します。 (個人的には今一しっくりしていませんが・・・)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
REG_EXP_DATE = /(?:\s*;\s*)
              (?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s*)?
              (\d{1,2})\s+
              (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+
              (\d{4}|\d{2})\s+
              (\d{2}):(\d{2})(?::(\d{2}))?\s+
              (UT|GMT|[ECMP][SD]T|[ZAMNY]|[+-]\d{4})
              (?:\s*(.*?))?/x
REG_EXP_FROM_1 = /^(?:\s*from\s+((?:(?!\sfrom\s).)*?))?
              (?:\s+by\s+((?:(?!\sby\s).)*?))?
              (?:\s+via\s+((?:(?!\svia\s).)*?))?
              (?:\s+with\s+((?:(?!\swith\s).)*?))?
              (?:\s+id\s+((?:(?!\sid\s).)*?))?
              (?:\s+for\s+((?:(?!\sfor\s).)*?))?
              #{REG_EXP_DATE}$/x

何回も使用する日時部分の正規表現を別にしています。 そして、単に正規表現にマッチすることだけを考えず、マッチした際の値を取得することを考えて丸括弧で括っています。 また、特徴として、

1
Received: from xxx ( xxxx with xxxx ) by xxxx with .....

のように、本来のキーワードがコメントとして使用されているケース(この場合は “with")があるため、否定先読みを使用しています。

1メール当たりのReceivedの件数

1メール当たりのReceivedの件数を集計しました。 「Received」が設定されていないものも結構存在しました。

0件 9,109
1件 1,156
2件 447
3件 17,558
4件 15,557
5件 7,654
6件 4,625
7件 2,430
8件 2,165
9件 602
10件 260
11件 61
12件 27
13件 10
14件 3
19件 1
合 計 226,506

RFCに準拠しているか検証

現行の RFC 5321, 5322 では “from” と “by” は必須ですが、以前の基準のものも存在するので、"from" と “by” のどちらかが非設定でもアンマッチとはしませんでした。

マッチしたもの 209,762
 from の件数 171,541
 by の件数 209,740
 via の件数 122
 with の件数 168,567
 id の件数 177,608
 for の件数 125,419
 from が非設定 3,8221
 by が非設定 22
 from も by も非設定 0
マッチしなかったもの 16,744
 (msmtp ...) というもの 1,506
 (qmail ...) というもの 14,528
 (smtpmc ...) というもの 137
 (nullmailer ...) というもの 1
 (melon ...) というもの 1
 日時書式が不正なもの 546
 その他の不正なもの 25
  • “from"も"by"も非設定のものはありませんでした。
  • “("と”)“で囲まれたものが結構ありました。
  • 日時書式では、タイムゾーンの設定が不正なものが殆どでした。 ( “+0900 (JST)” とすべきところが、選択肢に存在しない"JST"のみで設定されている )
  • その他の不正なものは、すべて"from"が同レベルで2回設定されているもの。

元々、将来的に UNIX MBOX データをデータベースに保存する事が目的ですので、今回はどのような書式のものがどれくらい存在するかを検証しました。 本来なら、この「Received」を精査してスパムメール・迷惑メール対策に役立てるのでしょう。 (実際、検証中それらしいものが多数見受けられました。)

今回で、メールヘッダの主だった属性の検証は一応終了とします。

これからは、メールボディ部分の検証をしてみたいと考えています。 単純にテキストデータのみだけでなく、色んなデータ形式があるし、Multipart(1つのメールが分割)になっていたり、色んなタイプの添付ファイルがあったり、とかなり手ごわそう 少し調査に時間がかかりそう。

以上。

Comments