Perl CGIからメールが送られなくなる。

以前、PQI AirFlash AirWiFiへ接続が成功したら、IPアドレスをメールで報告させる仕組みを構築していました。

gentoolinux.hatenablog.com

しかし、サーバーを再起動してからというもの、WiFiの接続は成功している(写真がGoogle Photosにアップロードされている)のに、メールが一向に届かないという現象が発生しました。

サーバーのプロセスを見ていると、

apache    20001   9636   0 0:0 ?        00:00:00 /home/www/xxx/mail.cgi
apache    20011  20001  0 0:0 ?        00:00:00 /usr/sbin/sendmail

というプロセスがずっと残っていました。
これはCGIが古くて、動作しなくなったのかと思い、いろいろとCGIを組み直しましたが、一向に直りません。

そこで、apaheのエラーログを見ることにしました。

tail -f /var/log/apache2/error_log
[Sun Oct 20 22:42:01.108468 2019] [cgi:error] [pid 9639:tid 140420415723264] [client 192.168.0.6:37054] AH01215: postdrop: warning: mail_queue_enter: create file maildrop/108046.28992: Permission denied: /home/www/xxx/test.cgi

なんだか、maildropにファイルが作成できないエラーが出ています。
MTAはpostfixなので、まずは設定をチェック。

postfix check
postfix: Postfix is running with backwards-compatible default settings
postfix: See http://www.postfix.org/COMPATIBILITY_README.html for details
postfix: To disable backwards compatibility use "postconf compatibility_level=2" and "postfix reload"
postfix/postfix-script: warning: not owned by group postdrop: /usr/sbin/postqueue
postfix/postfix-script: warning: not owned by group postdrop: /usr/sbin/postdrop
postfix/postfix-script: warning: not set-gid or not owner+group+world executable: /usr/sbin/postqueue
postfix/postfix-script: warning: not set-gid or not owner+group+world executable: /usr/sbin/postdrop

あ、mail.cfの設定を古いまま使っているのがバレていますね。
で、いくつかグループオーナーが間違っていたり、実行設定が間違っているようです。

ここにある対処法を参考に、各パーミッション等を変更します。
linux.m2osw.com

chgrp postdrop /var/spool/postfix/maildrop
chgrp postdrop /usr/sbin/postqueue
chmod g+s /usr/sbin/postqueue
chmod g+s /usr/sbin/postdrop
chmod 3730 /var/spool/postfix/maildrop
chmod 2730 /var/spool/postfix/public

こうすると、/var/spool/postfix配下のls -al結果は次のようになりました。

# ls -al /var/spool/postfix/
合計 64
drwxr-xr-x 16 root    root     4096  34  2019 .
drwxr-xr-x  5 root    root     4096  323  2015 ..
-rw-r--r--  1 root    root        0  34  2019 .keep_mail-mta_postfix-0
drwx------  2 postfix root     4096 1020 23:00 active
drwx------  2 postfix root     4096  720  2017 bounce
drwx------  2 postfix root     4096  711  2011 corrupt
drwx------ 15 postfix root     4096  42  2017 defer
drwx------ 18 postfix root     4096  229  2012 deferred
drwx------  2 postfix root     4096  711  2011 flush
drwx------  2 postfix root     4096  711  2011 hold
drwx------  2 postfix root     4096 1020 23:00 incoming
drwx-ws--T  2 postfix postdrop 4096 1020 23:00 maildrop
drwxr-xr-x  2 root    root     4096  67  2014 pid
drwx------  2 postfix root     4096 1019 04:26 private
drwx-ws---  2 postfix postdrop 4096 1019 04:26 public
drwx------  2 postfix root     4096  711  2011 saved
drwx------  2 postfix root     4096  711  2011 trace

今動いているmail.cgisendmailはkill -9で強制終了する必要がありますが、その後に動作させたmail.cgiは、しっかりと標準入力の内容をメール本文に送ってくれました。

ちなみに、新しいmail.cgiは、CPANのモジュールを使って動作させています。

#!/usr/bin/perl

use URI::Escape;
use Email::Sender::Simple qw(sendmail);
use Email::Simple;
use Email::Simple::Creator;

read (STDIN, $inputescaped, $ENV{'CONTENT_LENGTH'});
$input = uri_unescape($inputescaped);

$subject = 'PQIAirCard'; # メールの件名

$input =~ s/  //g; # 空白2文字分を削除

$email = Email::Simple->create(
  header => [
    To      => '<to_user@to_mail_host.com>',
    From    => '<from_user@from_host.com>',
    Subject => "$subject",
  ],
  body => "$input",
);

sendmail($email);

print "OK";
exit;

だいぶシンプルになりました。