Postfixのコンテンツフィルターで、タイトルや本文を変更して送信する

@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

参考リンク

スポンサーリンク
スポンサーリンク




シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
スポンサーリンク