2019年03月07日

cronはどうやってMTAの有無を確認しているのか

後輩が、あるサーバー上でだけメール送信スクリプトが動かない問題にぶち当たった。スパムフォルダ見ろとかiptablesの設定済ませたかとか様々なレベルの助言が飛び交ったが(こういうしょぼい問題ほど周りに集まってガヤガヤ言いたがる傾向)、ボスの一言「postfix入ってる?」であっさりと解決したようだった。

そういえばcron実行中に出力があったにもかかわらず、MTAがインストールされていないとsyslogに警告が出ることを思い出した。

No MTA installed, discarding output

これってどうやって判別してるんだろう?MTAと一口に言っても様々だし、ポートか何かチェックしてるのだろうか。

Debianパッケージのソース を落として確認してみる。 do_command.c 533行目付近 でメッセージの出力箇所が見つかった。

  /* Don't send mail if MAILCMD is not available */
  if ((statret = stat(MAILCMD, &mcsb)) != 0) {
          Debug(DPROC|DEXT, ("%s not found, not sending mail\n", MAILCMD))
          if (pos > 0) {
                  log_it("CRON", getpid(), "info", "No MTA installed, discarding output");
          }
          goto mail_finished;
  } else {
          Debug(DPROC|DEXT, ("%s found, will send mail\n", MAILCMD))
  }

MAILCMD_PATH_SENDMAIL が定義されていればそれが、そうでないなら /usr/lib/sendmail がセットされる。 statでこのパスをチェックしてこれが実在していない場合はログにその旨が記録される、という仕組み。 手元の Lubuntu は Exim4 をインストール済みだが、_PATH_SENDMAIL/usr/include/paths.h/usr/sbin/sendmail と定義され、これは exim4 へのシンボリックリンクになっていた。

ということはこの MTA 検知の仕組みを真似するなら「パスの通った位置に sendmail という名の実行ファイルがあるか」でよさそう。他のMTAであってもsendmail互換のものをパッケージ管理でインストールしたのであれば、このようにシンボリックリンクが自動で作られるはずなので個別にチェックする必要はない。

_PATH_SENDMAILconfig.h で定義されており、他のMTAにも対応できるようコメントが残されていた。
/bin/mail はいいとして /usr/mmdf/bin/submit はまったく知らない上に馴染みがない(FHSぽくない)置き方なので調べてみると1970年代に開発されたMTAらしい→英語版ウィキペディア:MMDF
しかしcronの原型も1970年代でみんながいま使っているvixiecronも1987年に初公開。ずっと残ってるんだろうなぁ。

ちなみにこのメッセージは Debian のパッチが当てられた結果で、オリジナルではメール送信コマンドの実行に失敗したことしかわからないようだ。(コマンドがこけたときもいっしょくた)

posted by かぷらす at 06:53| Comment(0) | 調査 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
コチラをクリックしてください