@example.comなどの一定のドメインから受信したメールだけ、件名にマークをつけたり署名を自動でつけたい、という要望にあたったため、試行錯誤しました。
Postfixのコンテンツフィルター、PHPで実装することにしました。そのメモを残します。
環境
- OS
- Centos 7.2
- ミドルウェア
-
- Postfix 2.10
- Apache 2.4
- PHP 7.2
設定ファイルのパスやコマンドのパスなどが異なる場合は、それぞれの環境のものと置き換えてください。
Postfixのコンテンツフィルター準備
コンテンツフィルターの実行用アカウント作成
セキュリティを考え、シェルへログインできないアカウントを作成してください。
useradd -s /sbin/nologin filter
passwd filter
一時ファイル保存用ディレクトリ作成
コンテンツフィルターで受け取ったメール(標準入力)を一時的にファイルへ保存します。そのファイルをを保存するディレクトリを作成します。
mkdir -p /var/spool/filter/
chown -R filter.filter /var/spool/filter
コンテンツフィルターで処理するスクリプトを作成
シェルで作成しても良いですし、PHPで作成しても良いです。コンテンツフィルターから照準入力で受け取った後に行う処理を記述します。フィルター用ユーザーで作成してください。
PHPの簡単なサンプルです。
vi /home/filter/filter.php
#!/usr/local/bin/php
<?php
require_once 'Mail/mimeDecode.php';
date_default_timezone_set( 'Asia/Tokyo' );
mb_language( "ja" );
mb_internal_encoding( "UTF-8" );
$to_array = get_all_to( $argv );
$email = '';
$fd = fopen( "php://stdin", "r" );
while ( ! feof( $fd ) ) {
$line = fread( $fd, 1024 );
$email .= $line;
}
fclose( $fd );
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
$params['input'] = $email;
$params['crlf'] = "\r\n";
$structure = Mail_mimeDecode::decode( $params ); // 件名(Subjectをrenameしたりする際に使用)
$temp_seq = time() . '-' . rand( 0, 99999 ) . '-' . rand( 0, 99999 );
$INSPECT_DIR = '/var/spool/filter/';
$SENDMAIL = "/usr/sbin/sendmail -G -i";
$save_file_path = $INSPECT_DIR . $temp_seq;
$EX_TEMPFAIL = 75;
$EX_UNAVAILABLE = 69;
// ここで何らかの処理
save_message( $save_file_path, $email );
foreach( $to_array as $i_key => $to_address ) {
$sendmail_cmd = $SENDMAIL . ' "' . $to_address . '" <' . $save_file_path;
$i_status = exec( $sendmail_cmd, $status );
}
delete_file( $save_file_path );
function save_message($save_file_path, $email){
$file = fopen( $save_file_path, "a" );
fwrite( $file, $email );
fclose( $file );
}
function get_all_to($email_stdin){
$st_emails = $email_stdin;
unset( $st_emails[0] );
unset( $st_emails[1] );
unset( $st_emails[2] );
unset( $st_emails[3] );
unset( $st_emails[4] );
asort( $st_emails );
return $st_emails;
}
function delete_file($file_path){
unlink( $file_path );
}
?>
権限追加
chmod 700 /home/filter/filter.php
Postfixのコンテンツフィルター設定
コンテンツフィルターの処理が完成したら、実際にPostfixからパイプでコンテンツフィルターに渡す設定を行います。
vi /etc/postfix/master.cf
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (yes) (never) (100)
# ==========================================================================
smtp inet n - n - - smtpd
-o content_filter=filter:dummy
最下部に、下記を追加
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (yes) (never) (100)
# ==========================================================================
filter unix - n n - 10 pipe
flags=Rq user=filter argv=/home/filter/filter.php -f ${sender} -- ${size} ${recipient}
systemctl reload postfix
コメント