開封確認(受信確認)&配送確認

2008/09/03 未分類 spok

開封確認(受信確認)&配送確認

Qdmailでは、追加ヘッダーに設定することにより、開封確認(受信確認)&配送確認をすることができます。
しかし、作者としては配送確認はともかく、開封確認(受信確認)機能を利用していただくことには消極的です。

開封確認機能に消極的な理由

「相手がメールを読んだかどうか。」
送信した人にとっては、結構気になるものですが、受け取った側の人間にとっては煩わしいだけのもので、通常、よくないメールマナーとして紹介されていることが多いです。私自身も受け取りたくないです。
また、スパムメールが好んで使う場合もあり、これも非推奨の理由です。
しかしクローズドな関係での情報のやり取りなどで必要な場面というのも考えられなくはないので、ここに紹介する次第です。
Qdmailには開封確認についての便利な機能はあえて搭載していません。必要な方は、このページを参考に、ご自分でヘッダーを設定してください。

開封確認(受信確認)と配送確認の違い

開封確認(受信確認)は、受信者がメールを開いたかどうか(読んだかどうかではない)を確認するためのものです。
配送確認は、最後のサーバーまで届いたかどうかという点です。受信者が開封したかどうは関係ありません。配送確認は、開封確認の一歩手前の段階です。

開封確認(受信確認)

ヘッダー Disposition-Notification-To が開封確認のヘッダーです。X-Confirm-Reading-Toというヘッダーも同様の働きをしますが、過去のものであり、Disposition-Notification-Toだけで十分でしょう。

開封確認(受信確認)の設定の仕方

qd_send_mail方式の場合(テキストメール)
$add_header = array(
    'From'=>'return@example.com',
    'Disposition-Notification-To'=>'return@example.com',
);

qd_send_mail( 'text' , 'to@example.com' , '件名' , $add_header );
※FromとDisposition-Notification-Toに設定するアドレスは、別々に設定することができますが、一致していないと配送確認を返送しないメーラーもあるようです。
OOP or easyメソッドの場合
$mail にはQdmailのインスタンス(オブジェクト)が入っているものとします。
$mail -> addHeader('Disposition-Notification-To','return@example.com');

配送確認

配送確認の方法は2つあります。
名称配置備考
Return-Receipt-Toヘッダー古い仕様&RFC非準拠
NOTIFY=SUCCESS,FAILUREエンベロープSMTP通信でないとダメ(正しくはESMTP通信)
Return-Receipt-Toは、RFCで明確にされているものではなく、sendmailというインターネットでは代表的なメールサーバの独自拡張です。しかし、sendmailは途中からこのヘッダーをサポートしなくなり、現在のバージョンでは無視されます。もうReturn-Receipt-Toは過去のものと思って良いでしょう。
NOTIFY=SUCCESS,FAILUREは、逆に古いSMTPサーバーではサポートしていないため、送信、受信の両方が対応している必要があります。
現在では、NOTIFY=SUCCESS,FAILUREを設定するのが現実的です。
Qdsmtpでは、簡便的な方法で対応しています。0.1.7.a以降。

SMTP通信の場合
QdmailからQdsmtpを使用する場合は、Qdsmtpで配送確認のページの、SMTP初期設定時のパラメータで指定する方法がよりでしょう。
ただし、この方法は、どの宛先にも配送確認を付けてしまうので、留意が必要です。
また、返送先のアドレスは、ヘッダーのFromではなく、エンベロープのFrom(Return-Path)なので注意が必要です。

mail関数の場合
Qdmailでは、mail関数を利用している場合には、mtaOption()メソッドを利用します。
 -Nオプションで、Notifyの設定を行い、-f でreturn-pathの設定を行います。

配送確認の設定の仕方

Return-Receipt-Toは過去のものなので、ヘッダーだけご紹介しておきます。
Return-Receipt-To
設定は、受信確認を参考にしてください。

Qdsmtpを利用してSMTP送信している場合

NOTIFY=SUCCESS,FAILUREについては、いつかqdsmtpの配送確認のページをご参照下さい。

mail関数を利用している場合

mail関数の第5引数は、MTAに渡すオプションです。お使いのサーバーがsendmailまたはsendmailラッパーであれば、以下の設定をしてみてください。

qd_send_mail($option .....)の場合
$option = array(
    'type' => 'text',
    'option'=>array(
	'mtaOption'=>'-N success,failure -f return_address@example.com'
    ),
);
return_address@example.comには、貴方が返事をもらうためのアドレスを指定してください。
 -f はreturn-pathを設定するためのオプションです。

OOPまたはeasy...メソッドの場合
$mail -> mtaOption( '-N success,failure -f retun_address@example.com' );

その他

この確認の確実性

多くの人は、開封確認(受信確認)について無効に設定しているかと思います。開封確認を付けたからといって、必ず相手が開封したかどうかがわかるわけではありません。
また、配送確認も上記のとおり、確実なものではありません。
配送確認を確実にしたい場合は、SMTPにて相手のサーバーに直接送り届けることでしょう。

参考にさせていただいたサイト

開封確認-中の技術日誌ブログ
開封確認付きメールをどう思いますか。-人力検索はてな
メーラ機能比較報告書-西村宏之のホームページです
becky-ml:01166 開封確認
sendmail システム管理 (151K) -日本ネットワークインフォメーションセンター
SMTP拡張サービス
RFC1891日本語参考訳

電子署名の使用法

2008/09/02 未分類 spok

サンプルコード qd_send_mail型

Qdmailでは、S/MIME署名することができるのは、SMTP送信の場合のみです。
$param には、smtpの設定データが入っているものとします。
なお、サンプルのためパスワードをスクリプトに直接入れる形になっていますが、このパスワードは秘密鍵を守る重要なものです。ユーザーの責任において、厳重に管理する必要があります。

pfx形式

$option = array(
	'type'=>'text',
	'option'=>array(
		'sign'=>'s/mime',
		'certificateFilePath'=>'/usr/local/username/cert',
		'certificateTempPath'=>'/usr/local/username/cert/temp',
		'certificateFile'=>'cert_spok.pfx',
		'certificatePass'=>'your_password',
	),
	'smtp'=>$param,
);

$to = array('address@example.com','宛先日本語');
$body = <<<EOF
S/MIMEのテストです。
S/MIMEはメール全体を包んで、ハッシュ値(SHA1)を取り、それを秘密鍵で暗号化し、
さらに公開鍵といっしょにして送信するものです。
受け取ったメーラーは、独自に内容のハッシュ値を取り、公開鍵で解読したハッシュ値と比較します。
これが一致していれば、メールの内容は改ざんされていないことになります。

EOF;

$from = array('from@example','スポック');

qd_send_mail($option , $to , 'S/MIMEテスト' , $body ,  $from , 'test.jpg' );
certificateFilePath
certificateFilePathは、署名ファイルが置いてあるディレクトリです。
デフォルト(指定しない場合)では、windows環境の時(PHP_OSがWINの時)は、c:¥cert 、ウィンドウズ以外の時は、/user/local/cert となります。最後に、スラッシュ、バックスラッシュは付けないでください。
certificateTempPath
certificateTempPathは、署名ルーチンが使用するtempディレクトリです。
デフォルト(指定しない場合)では、windows環境の時(PHP_OSがWINの時)は、c:¥temp 、ウィンドウズ以外の時は、/tmp となります。最後に、スラッシュ、バックスラッシュは付けないでください。
注意点
相対パス指定にすると、apacheからみたルートディレクトリがカレントディレクトリとされて、意図と違うディレクトリを参照することになりますので、絶対パスで指定するのが無難です。

Tips!
例えば開発環境winと運用環境unixで、署名ディレクトリが異なる場合があるかと思います。その場合は、ソースコードの、$certificate_file_path_win と $certificate_file_path_unix の定義部分をそれぞれの環境に合わせて書き換えておけば、アプリケーションでパスを切り替える必要がありません。

署名ファイルディレクトリ省略型
署名ファイルディレクトリが初期設定のままでいい場合は下記のように省略できます。
$option = array(
	'type'=>'text',
	'option'=>array(
		'sign'=>'s/mime',
		'certificateFile'=>'cert_spok.pfx',
		'certificatePass'=>'your_password',
	),
	'smtp'=>$param,
);

ファイル.pem形式

署名が.pfx形式ではなく、.pem方式の場合は以下のように指定します。
.pem方式は、秘密鍵が平分で保存されています。.pemファイル自体の管理を十分に気をつけて下さい。

$option = array(
	'type'=>'text',
	'option'=>array(
		'sign'=>'s/mime',
		'certificateFilePath'=>'/usr/local/username/cert',
		'certificateTempPath'=>'/usr/local/username/cert/temp',
		'certificateFile'=>'cert_spok.pem',
		'privateKeyFile'=>'private_spok.pem',
	),
	'smtp'=>$param,
);
なお、デフォルトは、pem形式であり、何も指定しない場合は、 cert.pem , private.pem がデフォルトファイル名になります。

注意!

証明書ファイルから抽出される秘密鍵は、外部に漏らしてはいけないものです。抽出時のパスワードは必ず設定してください。また、pem形式の場合は、パスワード保護がきかない場合もあるので、certificateFilePathは、外部からアクセスできないディレクトリを指定することを強く推奨します。
また、tempディレクトリも外部からアクセスできないディレクトリを指定してください。

電子署名(S/MIME)

2008/09/02 未分類 spok
Qdmail 1.0.9bからは、電子署名ができます。これにより、よりセキュアなメールをQdmailから送信することができます。(なお、これは暗号化ではなく、署名です。)
1.0.9b現在は、S/MIME方式のみをサポートしています。

なお、この機能を使用するには、OpenSSLモジュールがPHPに組み込まれている必要があります。
また、現状では、SMTP送信でないと正しく送信できません。

電子署名でできること

  • メール本文が経路途中で改ざんされていないことを保証する(本文のみです。ヘッダーは対象外。)
  • 「あなたが」署名したメールであると証明できる(ただし、オレオレ証明書でないことが条件です。)
  • テキストメールだけでなく、HTMLメール、添付ファイルがあっても、その改ざんがないことを保証でききる
例)
三井住友銀行、東京三菱銀行などは、顧客に送るメールすべてにS/MIME方式による電子署名をしています。これにより、フィッシング詐欺などのリスクを減らしています。

条件

貴方(貴社)が、権威ある認証機関から正当な公開鍵証明書をもらっている必要があります。
といっても、制限付きながら私が無料でもらえるぐらいですから、理解さえすればそんなにハードルは高くありません。
商用で使う場合は、ベリサインなどの会社から有償で証明書を購入するのがよいでしょう。

SMTP送信について

2008/08/30 未分類 spok
SMTPサーバー送信は、実装としては2種類あるかと思います。ここではその解説です。

基礎知識

メールは一般的には以下のような配送ルートで送られます。

一般論
クライアント(Qdmail) → 配送元SMTPサーバー(A) → 配送先AMTPサーバー(B) → 相手のPC
最後の(B)→相手のPCはPOPプロトコルであり、その他はすべてSMTPプロトコルで配送されます。
ここでQdmailは、クライアントとなります。
PHPのmail関数を利用した場合は、以下のようなルートです。
クライアント(Qdmail) → mail関数 → sendmail・配送元SMTPサーバー(A) → 配送先AMTPサーバー(B) → 相手のPC
sendmailは、PostFixであったりQmailであることもあります。QmailとQdmailは違いますので、ご留意下さい。
sendmailというのは、ひとつのプログラムで、送信サーバー、中継サーバー、受信サーバーの1台3役のサーバーなので、よく理解がごっちゃになりやすいので気をつけて下さい。

mail関数とSMTP送信の違い

mail関数の方がSMTP送信の段取りをやってくれるため、PHPプログラムは簡単になります。一方で、mail関数そのものが、ちょっと改行コードの取り扱い等に難点があり、文字化けの原因になったりします。

SMTP送信は文字化けについては、mail関数より信頼性が高いものの、SMTPプロトコルでの送信をPHPプログラムが面倒見無ければならないので、面倒です。Qdsmtpは、その面倒さを引き受けて、ユーザーの負担を軽くするものです。

SMTP送信の種類

SMTP送信の中にも大きく2種類があります。

その1(中継サーバーに配送を委託する方法)---Qdsmtpはこの実装。
クライアント(Qdmail) → 配送元SMTPサーバー(A) → 配送先AMTPサーバー(B) → 相手のPC
                       (認証が必要)       (認証不要)

その2(直接相手先のSMTPサーバーに配送してしまう方法)
クライアント(Qdmail) → 配送先AMTPサーバー(B) → 相手のPC
             (認証不要)
一般的にSMTP送信と言った時にどちらを指すのはかは、私の経験不足でわかりません。どなたか、知っていたら教えて下さい。

認証について

過去のインターネットの世界では、SMTPは認証不要でした。しかし、それがスパムメールに悪用されるようになり、POP Before SMTPという疑似認証方式が多くで採用され、現在では、SMTP AUTHというIDとパスワードでの認証が必要になっています。
ただし、認証が必要なのは、他のSMTPサーバーに送信する中継サーバーだけです。
なぜなら、配信先のSMTPサーバー(B)は、どこのサーバーから接続されるのがわからないから、それを認証必須にしてしまうと、特定の相手先からしかメールを受け取れないことになっています。
したがって、多くのSMTPサーバーは、以下のような設定になっています。
自分が管理するメールボックス宛であれば、認証必要なく接続を許可し、他のサーバーへの中継要求は認証があれば許可するが、認証がなければ拒否する。
だから、配信元サーバーは通常認証が必要になります。そうでないとスパムの踏み台にされてしまうからです。もし、現状で認証の必要のない配信元サーバーを公開しているのであれば、即刻サーバー停止すべきものです。

2つの方法の違い

その1(中継サーバーに配送を委託する方法)
認証ありで第三者中継を許すサーバーにで接続し、各到達地点のSMTPサーバーに中継してもらう。

この方法の利点
  • 到達地点のSMTPサーバーになんらかの理由で接続できなかった場合でも、最初のSMTPサーバーが、メールを留保し、後で、送り直しをしてくれるため、到達確立が安心できるレベルにある
  • いつも同じSMTPサーバーに接続するだけでよいので、面倒がない
  • 安定した配送元SMTPサーバーであれば、しっかり配送してくれる
その代わりに、そのSMTPサーバーに自分がアカウントを持っていなければなりません。例えば、私はレンタルサーバーのSMTPサーバーやso-netのアカウントも持っていますので、たまにso-netのSMTPサーバーに認証ありで、中継してもらっています。

その2(直接、配送先のSMTPサーバーに接続する方法)
送り先のメールアドレスに合わせて、その都度異なる(当該メールを管理する)SMTPサーバーに認証なしで接続して送信することになります。

例えば、ドコモユーザー(***@docomo.ne.jp)に送信する場合には、mfsmax.docomo.ne.jpというSMTPサーバーをdocomo.ne.jpという情報からインターネット上で逆引きして探しだし、そこへ接続します。
gmailユーザー(***@gmail.com)であれば、gmail.comの受信サーバーたるASPMX.L.GOOGLE.COMを探しだし、そこへ接続します。

認証なしサーバーは第三者中継は行わないものの、そのSMTPサーバーが管理するドメイン(サブドメイン)のメールボックス宛であれば、認証なしで受け入れます。

この方法の利点
  • 直接接続なので認証がいらない
という点です。

一方で、欠点もあります。
  • 送り先のメールアドレスから、IPアドレスなり、SMTPサーバーなりを逆引きしなければならず、また、接続エラーの場合の処理を自前で実装しなければならない
  • エラー処理は、PHPだけでは完結が難しく、必ず、サーバーの設定等も必要になることが多いので、可搬性のよくない(万人向けではない)ソフトになってしまう
  • そのPHPプログラムが動作するIPアドレスによっては、配送元から接続拒否をされる場合がある

配送元が接続拒否をする場合とは?

その2(配送先サーバーに直接送信)の場合によく問題となるのが、例えばdocomoユーザーへのメールが届かない、という問題です。参考<Radish3(Docomo対策編)>-パソコンおやじ
ドコモでは、スパム対策のために、「怪しいとドコモが判断した送信元サーバー」からは、接続を受け付けないか、極端に待たせるか、優先順位を下げるなどの設定にしているようです。
ここではドコモを取り上げましたが、このように送信元サーバーの制限をするプロバイダは他にもあるそうです(詳しくは調べていません。)
何を持って「怪しい」と判断するかは、そのサーバーの管理者のポリシーなのでなんともいえませんが、いわゆる「プロバイダ事業者」が管理するサーバーは特段の問題はないものの、ダイナミックDNSなどでIPアドレスが頻繁に変更となるサーバーや、これまでに大量送信が確認されたサーバー、もしくは見慣れない?サーバーなどは問題となることが多いようです。
これは、私たちが、PHPを使って直接配信先に接続しようとした時、配信先のサーバ-に、審査されることを意味します。
例えば、会社のテストサーバーから繋ぐと、「怪しい」と判断されるかも知れませんし、それを運用環境にもっていってIPアドレス等が変更になれば、「怪しくない」と判断されるかも知れません。その逆もあるかも知れません。このように、開発環境と運用環境で、接続確立がかわるため、開発は面倒です。

この問題は、配信先のサーバーの問題であるため、その1(中継サーバーに中継してもらう)方法でも、起こりえます。しかし、通常、その1の方法の場合は、かなり信頼性のあるプロバイダやレンタルサーバー事業者のSMTPサーバーを利用することが多いので、問題が表面化することは少ないといえます。
逆に、その1の方法でも、自社で立てたテストサーバーのようなものであれば、同様の問題がでてくる可能性はあります(あくまでも可能性)。

Qdsmtpの対処と今後

現状

現状では、その1の方法だけなので、いろんな所にメールを送りたければ、サーバー認証またはPOP Before SMTPにて、信頼性のあるSMTPサーバーをご利用ください。
ご自分でSMTPサーバーを構築する場合には、「配信先サーバーによる審査」という問題にご留意下さい。

今後

いずれは、Qdsmtpも、その2 の方法もサポートしたいとは思いますが。。。。時間があれば。
その時には、その2の方法を接続を試みて、接続負荷だった場合には、その1の中継サーバーにお願いする、というような方法になるでしょう。

重要度を設定する

2008/08/28 未分類 spok
Qdmailでは、メールの重要度を設定することができます(3段階)。Qdmail 1.0.8b以降の機能です。

重要度設定方法

パラメータの意味は以下のとおりです。
high重要
normal普通
low低い

qd_send_mail() 方式の場合(テキストメールの例)

$option = array(
    'type'=>'text',
    'option'=>array('priority'=>'high'),
);

qd_send_mail($option , $to , $subject ,$body );

OOP , easy~メソッド 方式の場合

$mailにはQdmailのインスタンス(オブジェクト)が入っているものとします。
$mail -> priority('high');
重要度をキャンセルするには
$mail -> priority('');
現在の重要度の設定を取得するには
$return_value = $mail -> priority( null );

予備知識

メールの重要度は、各メーラーなどが独自に実装している面があり、ひとつのヘッダーを設定すればそれでOKとはいきません。Qdmailでは、4つのヘッダーを設定しています。たぶんこれでほとんどのメーラーは大丈夫だと思います。
設定しているヘッダー
X-Priority135
Priorityurgentnormalnon-urgent
X-MsMail-PriotiryHighNormalLow
ImportanceHighNormalLow
priorityメソッドは addHeader()メソッドを利用して、これら4つのヘッダーを設定しているだけです。

参考URL

メールの重要度を設定する-Shin x blog