Important
2024年2月2日の時点でこのリポジトリのデフォルトブランチは5-stable
(Sisimai 5)になりました。 もし古いバージョンを使いたい場合は4-stable1
ブランチを見てください。またmain
やmaster
ブランチはもうこのリポジトリでは使用していません。
Caution
Sisimai 4.25.14p11およびそれ以前のバージョンには 正規表現に関する脆弱性 ReDoS: CVE-2022-4891があります。 該当するバージョンをお使いの場合はv4.25.14p12以降へアップグレードしてください。
Warning
Sisimai 5はPerl 5.26以上が必要です。インストール/アップグレードを実行する前にperl -v
コマンドで
システムに入っているPerlのバージョンを確認してください。
Note
SisimaiはPerlモジュールまたはRuby Gemですが、PHPやPython、GoやRustなどJSONを読める言語であれば どのような環境においても解析結果を得ることでバウンスの発生状況を捉えるのにとても有用です。
- README(English)
- シシマイ? | What is Sisimai
- シシマイを使う準備 | Setting Up Sisimai
- 使い方 | Usage
- Sisimai 4とSisimai 5の違い
- Contributing
- その他の情報 | Other Information
- 作者 | Author
- 著作権 | Copyright
- ライセンス | License
Sisimai(シシマイ)は複雑で多種多様なバウンスメールを解析してバウンスした理由や宛先メールアドレスなど 配信が失敗した結果を構造化データで出力するライブラリでJSONでの出力も可能です
- バウンスメールを構造化したデータに変換
- 以下24項目の情報を含むデータ構造2
- 基本的情報:
timestamp
,origin
- 発信者情報:
addresser
,senderdomain
, - 受信者情報:
recipient
,destination
,alias
- 配信の情報:
action
,replycode
,action
,replycode
,deliverystatus
- エラー情報:
reason
,diagnosticcode
,diagnostictype
,feedbacktype
,hardbounce
- メール情報:
subject
,messageid
,listid
, - その他情報:
smtpagent
,timezoneoffset
,lhost
,rhost
,token
,catch
- 基本的情報:
- 出力可能な形式
- Perl (Hash, Array)
- JSON (
JSON
モジュールを使用) - YAML (
YAML
モジュールまたはYAML::Syck
モジュールが必要)
- 以下24項目の情報を含むデータ構造2
- インストールも使用も簡単
cpan
,cpanm
,cpm install
git clone & make
- 高い解析精度
- 73種類のMTAs/MDAs/ESPsに対応
- Feedback Loop(ARF)にも対応
- 34種類のバウンス理由を検出
次の画像のように、Perl版シシマイ(p5-sisimai)はコマンドラインから簡単にバウンスメールを解析すること ができます。
シシマイの動作環境についての詳細はSisimai | シシマイを使ってみる をご覧ください。
$ cpanm --sudo Sisimai
--> Working on Sisimai
Fetching http://www.cpan.org/authors/id/A/AK/AKXLIX/Sisimai-4.25.16.tar.gz ... OK
...
1 distribution installed
$ perldoc -l Sisimai
/usr/local/lib/perl5/site_perl/5.30.0/Sisimai.pm
Warning
Sisimai 5はPerl 5.26以上が必要です。インストール/アップグレードを実行する前にperl -v
コマンドで
システムに入っているPerlバージョンを確認してください。
$ perl -v
This is perl 5, version 30, subversion 0 (v5.30.0) built for darwin-2level
Copyright 1987-2019, Larry Wall
...
$ cd /usr/local/src
$ git clone https://github.com/sisimai/p5-sisimai.git
$ cd ./p5-sisimai
$ make install-from-local
./cpanm --sudo . || ( make cpm && ./cpm install --sudo -v . )
--> Working on .
Configuring Sisimai-v5.1.0 ... OK
Building and testing Sisimai-v5.1.0 ... Password: <sudo password here>
OK
Successfully installed Sisimai-v5.1.0
1 distribution installed
$ perl -MSisimai -lE 'print Sisimai->version'
5.1.0
下記のようにSisimaiのrise()
メソッドをmboxかMaildir/のPATHを引数にして実行すると解析結果が配列
リファレンスで返ってきます。v4.25.6から元データとなった電子メールファイルへのPATHを保持するorigin
が利用できます。
#! /usr/bin/env perl
use Sisimai;
my $v = Sisimai->rise('/path/to/mbox'); # またはMaildir/へのPATH
# v4.23.0からSisimaiクラスのrise()メソッドとdump()メソッドはPATH以外にもバウンスメール全体を文字列
# として読めるようになりました
use IO::File;
my $r = '';
my $f = IO::File->new('/path/to/mbox'); # またはMaildir/へのPATH
{ local $/ = undef; $r = <$f>; $f->close }
my $v = Sisimai->rise(\$r);
# もし"delivered"(配信成功)となる解析結果も必要な場合は以下に示すとおりrise()メソッドに"delivered"
# オプションを指定してください
my $v = Sisimai->rise('/path/to/mbox', 'delivered' => 1);
# v5.0.0からSisimaiはバウンス理由が"vacation"となる解析結果をデフォルトで返さなくなりました。もし
# "vacation"となる解析結果も必要な場合は次のコードで示すようにrise()メソッドに"vacation"オプション
# を指定してください。
my $v = Sisimai->rise('/path/to/mbox', 'vacation' => 1);
if( defined $v ) {
for my $e ( @$v ) {
print ref $e; # Sisimai::Fact
print ref $e->recipient; # Sisimai::Address
print ref $e->timestamp; # Sisimai::Time
print $e->addresser->address; # "michitsuna@example.org" # From
print $e->recipient->address; # "kijitora@example.jp" # To
print $e->recipient->host; # "example.jp"
print $e->deliverystatus; # "5.1.1"
print $e->replycode; # "550"
print $e->reason; # "userunknown"
print $e->origin; # "/var/spool/bounce/new/1740074341.eml"
print $e->hardbounce; # 0
my $h = $e->damn(); # Hashリファレンスに変換
my $j = $e->dump('json'); # JSON(文字列)に変換
print $e->dump('json'); # JSON化したバウンスメールの解析結果を表示
}
}
下記のようにSisimaiのdump()
メソッドをmboxかMaildir/のPATHを引数にして実行すると解析結果が文字列
(JSON)で返ってきます。
# メールボックスまたはMaildir/から解析した結果をJSONにする
my $j = Sisimai->dump('/path/to/mbox'); # またはMaildir/へのPATH
# dump()メソッドはv4.1.27で追加されました
print $j; # JSON化した解析結果を表示
# dump()メソッドは"delivered"オプションや"vacation"オプションも指定可能
my $j = Sisimai->dump('/path/to/mbox', 'delivered' => 1, 'vacation' => 1);
Sisimai->rise
とSisimai->dump
のc___
引数(c
と_
が三個/魚用の釣り針に見える)はコールバック機能
で呼び出されるコードリファンレンスを保持する配列リファレンスです。
c___
の1番目の要素にはSisimai::Message->sift
で呼び出されるコードリファレンスでメールヘッダと本文
に対して行う処理を、2番目の要素には、解析対象のメールファイルに対して行う処理をそれぞれ入れます。
各コードリファレンスで処理した結果はSisimai::Fact->catch
を通して得られます。
c___
に渡す配列リファレンスの最初の要素に入れたコードリファレンスはSisimai::Message->sift()
で
呼び出されます。
#! /usr/bin/env perl
use Sisimai;
my $code = sub {
my $args = shift; # (*Hash)
my $head = $args->{'headers'}; # (*Hash) メールヘッダー
my $body = $args->{'message'}; # (String) メールの本文
my $adds = { 'x-mailer' => '', 'queue-id' => '' };
if( $body =~ m/^X-Postfix-Queue-ID:\s*(.+)$/m ) {
$adds->{'queue-id'} = $1;
}
$adds->{'x-mailer'} = $head->{'x-mailer'} || '';
return $adds;
};
my $data = Sisimai->rise('/path/to/mbox', 'c___' => [$code, undef]);
my $json = Sisimai->dump('/path/to/mbox', 'c___' => [$code, undef]);
print $data->[0]->catch->{'x-mailer'}; # "Apple Mail (2.1283)"
print $data->[0]->catch->{'queue-id'}; # "43f4KX6WR7z1xcMG"
Sisimai->rise()
とSisimai->dump()
の両メソッドに渡せる引数c___
(配列リファレンス)の2番目に入れた
コードリファレンスは解析したメールのファイルごとに呼び出されます。
my $path = '/path/to/maildir';
my $code = sub {
my $args = shift; # (*Hash)
my $kind = $args->{'kind'}; # (String) Sisimai::Mail->kind
my $mail = $args->{'mail'}; # (*String) Entire email message
my $path = $args->{'path'}; # (String) Sisimai::Mail->path
my $fact = $args->{'fact'}; # (*Array) List of Sisimai::Fact
for my $e ( @$fact ) {
# "catch"アクセサの中に独自の情報を保存する
$e->{'catch'} ||= {};
$e->{'catch'}->{'size'} = length $$mail;
$e->{'catch'}->{'kind'} = ucfirst $kind;
if( $$mail =~ /^Return-Path: (.+)$/m ) {
# Return-Path: <MAILER-DAEMON>
$e->{'catch'}->{'return-path'} = $1;
}
# "X-Sisimai-Parsed:"ヘッダーを追加して別のPATHに元メールを保存する
my $a = sprintf("X-Sisimai-Parsed: %d\n", scalar @$fact);
my $p = sprintf("/path/to/another/directory/sisimai-%s.eml", $e->token);
my $f = IO::File->new($p, 'w');
my $v = $$mail; $v =~ s/^(From:.+)$/$a$1/m;
print $f $v; $f->close;
}
# 解析が終わったらMaildir/にあるファイルを削除する
unlink $path if $kind eq 'maildir';
# 特に何か値をReturnする必要はない
};
my $list = Sisimai->rise($path, 'c___' => [undef, $code]);
print $list->[0]->{'catch'}->{'size'}; # 2202
print $list->[0]->{'catch'}->{'kind'}; # "Maildir"
print $list->[0]->{'catch'}->{'return-path'}; # "<MAILER-DAEMON>"
コールバック機能のより詳細な使い方は Sisimai | 解析方法 - コールバック機能をご覧ください。
Sisimai 4.1.27から登場したdump()
メソッドを使うとワンライナーでJSON化した解析結果が得られます。
$ perl -MSisimai -lE 'print Sisimai->dump(shift)' /path/to/mbox
[
{
"destination": "google.example.com",
"lhost": "gmail-smtp-in.l.google.com",
"hardbounce": 0,
"reason": "authfailure",
"catch": null,
"addresser": "michitsuna@example.jp",
"alias": "nekochan@example.co.jp",
"smtpagent": "Postfix",
"smtpcommand": "DATA",
"senderdomain": "example.jp",
"listid": "",
"action": "failed",
"feedbacktype": "",
"messageid": "hwK7pzjzJtz0RF9Y@relay3.example.com",
"origin": "./gmail-5.7.26.eml",
"recipient": "kijitora@google.example.com",
"rhost": "gmail-smtp-in.l.google.com",
"subject": "Nyaan",
"timezoneoffset": "+0900",
"replycode": 550,
"token": "84656774898baa90660be3e12fe0526e108d4473",
"diagnostictype": "SMTP",
"timestamp": 1650119685,
"diagnosticcode": "host gmail-smtp-in.l.google.com[64.233.187.27] said: This mail has been blocked because the sender is unauthenticated. Gmail requires all senders to authenticate with either SPF or DKIM. Authentication results: DKIM = did not pass SPF [relay3.example.com] with ip: [192.0.2.22] = did not pass For instructions on setting up authentication, go to https://support.google.com/mail/answer/81126#authentication c2-202200202020202020222222cat.127 - gsmtp (in reply to end of DATA command)",
"deliverystatus": "5.7.26"
}
]
Sisimai 4.25.16p1と Sisimai 5には下記のような違いがあります。 それぞれの詳細はSisimai | 違いの一覧を参照してください。
Sisimai 5.0.0からPerl 5.26.0以上が必要になります。
機能 | Sisimai 4 | Sisimai 5 |
---|---|---|
動作環境(Perl) | 5.10 - 5.38 | 5.26 - 5.38 |
元メールファイルを操作可能なコールバック機能 | なし | あり3 |
解析エンジン(MTA/ESPモジュール)の数 | 68 | 73 |
検出可能なバウンス理由の数 | 29 | 34 |
依存もジュール数(Perlのコアモジュールを除く) | 2 モジュール | 2 モジュール |
ソースコードの行数 | 10,800 行 | 11,800 行 |
テスト件数(t/とxt/ディレクトリ) | 270,000 件 | 335,000 件 |
1秒間に解析できるバウンスメール数4 | 541 通 | 660 通 |
ライセンス | 2条項BSD | 2条項BSD |
開発会社による商用サポート | 提供中 | 提供中 |
いくつかの解析メソッド名、クラス名、パラメーター名がSisimai 5で変更になっています。解析済みデータの 各項目はLIBSISIMAI.ORG/JA/DATAを参照してください。
解析用メソッド周辺の変更箇所 | Sisimai 4 | Sisimai 5 |
---|---|---|
解析メソッド名 | Sisimai->make |
Sisimai->rise |
出力メソッド名 | Sisimai->dump |
Sisimai->dump |
解析メソッドが返すオブジェクトのクラス | Sisimai::Data |
Sisimai::Fact |
コールバック用のパラメーター名 | hook |
c___ 5 |
ハードバウンスかソフトバウンスかを識別するメソッド名 | softbounce |
hardbounce |
"vacation"をデフォルトで検出するかどうか | 検出する | 検出しない |
Sisimai::Messageがオブジェクトを返すかどうか | 返す | 返さない |
MIME解析用クラスの名前 | Sisimai::MIME |
Sisimai::RFC2045 |
SMTPセッションの解析をするかどうか | しない | する6 |
Sisimai 5で3個のESPモジュール名(解析エンジン)が変更になりました。詳細はMTA/ESPモジュールの一覧/ LIBSISIMAI.ORG/JA/ENGINEを参照してください。
Sisimai:: |
Sisimai 4 | Sisimai 5 |
---|---|---|
Apple iCloud Mail (added at v5.1.0) | なし | Rhost::Apple |
Microsoft Exchange Online | Rhost::ExchangeOnline |
Rhost::Microsoft |
Google Workspace | Rhost::GoogleApps |
Rhost::Google |
Tencent | Rhost::TencentQQ |
Rhost::Tencent |
Yahoo Mail (added at v5.1.0) | なし | Rhost::YahooInc |
DragonFly Mail Agent (added at v5.1.0) | なし | Lhost::DragonFly |
Sisimai 5では新たに5個のバウンス理由が増えました。検出可能なバウンス理由の一覧は LIBSISIMAI.ORG/JA/REASONを参照してください。
バウンスした理由 | Sisimai 4 | Sisimai 5 |
---|---|---|
ドメイン認証によるもの(SPF,DKIM,DMARC) | SecurityError |
AuthFailure |
送信者のドメイン・IPアドレスの低いレピュテーション | Blocked |
BadReputation |
PTRレコードが未設定または無効なPTRレコード | Blocked |
RequirePTR |
RFCに準拠していないメール7 | SecurityError |
NotCompliantRFC |
単位時間の流量制限・送信速度が速すぎる | SecurityError |
Speeding |
もしもSisimaiにバグを発見した場合はIssuesにて連絡を いただけると助かります。
Sisimaiで解析できないバウンスメールは set-of-emails/to-be-debugged-because/sisimai-cannot-parse-yetリポジトリに追加してPull-Requestを送ってください。
- @libsisimai | Sisimai on Twitter (@libsisimai)
- LIBSISIMAI.ORG | SISIMAI | MAIL ANALYZING INTERFACE | DECODING BOUNCES, BETTER AND FASTER.
- Sisimai Blog | blog.libsisimai.org
- Facebook Page | facebook.com/libsisimai
- GitHub | github.com/sisimai/p5-sisimai
- CPAN | Sisimai - Mail Analyzing Interface for bounce mails. - metacpan.org
- CPAN Testers Reports | CPAN Testers Reports: Reports for Sisimai
- Ruby verson | Ruby version of Sisimai
- Fixtures | set-of-emails - Sample emails for "make test"
- README.md - README.md in English
- RFC3463 - Enhanced Mail System Status Codes
- RFC3464 - An Extensible Message Format for Delivery Status Notifications
- RFC3834 - Recommendations for Automatic Responses to Electronic Mail
- RFC5321 - Simple Mail Transfer Protocol
- RFC5322 - Internet Message Format
Copyright (C) 2014-2024 azumakuniyuki, All Rights Reserved.
This software is distributed under The BSD 2-Clause License.
Footnotes
-
4系を
clone
する場合はgit clone -b 4-stable https://github.com/sisimai/p5-sisimai.git
↩ -
コールバック機能を使用すると
catch
アクセサの下に独自のデータを追加できます ↩ -
Sisimai->rise
メソッドで指定するc___
パラメーター第二引数で指定可能 ↩ -
macOS Monterey/1.6GHz Dual-Core Intel Core i5/16GB-RAM/Perl 5.30 ↩
-
c___
は漁港で使う釣り針に見える ↩ -
Sisimai::SMTP::Transcript->rise
メソッドによる ↩ -
RFC5322など ↩