6
8

More than 5 years have passed since last update.

ProxSMTPによる"超"単機能コンテンツフィルタの実装

Last updated at Posted at 2014-04-23

SMTPメールを出力するサーバからメールを受け取り、「本文中にAaaとBbbという文字があればrelay、でなければreject」を実装する必要が出てきた

ただし、以下の条件がある

  1. SMTPメールを出力するサーバへのログインはできない

結論:

ProxSMTP(+スクリプト)を搭載したサーバを別途用意、そこにSMTPメールを中継させて判定を行うようにした

$ sudo apt-get -y install proxsmtp
$ sudo service postfix stop
$ sudo update-rc.d -f postfix remove

※Postfixが入るのはご愛嬌

/etc/proxsmtp/proxsmtpd.conf
Listen: 0.0.0.0:25
OutAddress: upper-mx.example.local:25
FilterCommand: /opt/bin/filter.rb
/opt/bin/filter.rb
#!/usr/bin/env ruby

require "mail"

module Postfix
  module Filter
    def self.run(input)
      mail = Mail.new(input)
      return true if (mail.body =~ /Aaa/ and mail.body =~ /Bbb/)
      false
    end
  end
end

if __FILE__ == $0
  if Postfix::Filter.run(msg = STDIN.read)
    STDOUT.puts msg
    exit 0
  else
    STDERR.puts "550 Content Rejected: could not relay."
    exit 255
  end
end

今回得られた知見:

一般的なSMTPサーバというものは「原則relay」(= default allow)に則って設計/実装されている。
よって「特定条件のみrelay」 (= default reject)を実現するのが、極めて大変。

postfix / exim4 / sendmail / Courier-MTA について、default rejectが可能なのか調査した。

Postfix

ビルトインヘッダ・本体検査(header_checks / body_checks)による検査

# passという文字がbodyに見つかったらDUNNO(=OK)、そうでない場合はREJECTとしたい
/pass/ DUNNO
/.*/ REJECT

ルータ等のfilterを書いている人なら「これでOKじゃね?」と思うが、残念。
header_checks/body_checksでは、DUNNO(OK)で判定が止まらないため、REJECT行まで行ってしまう。(バグではなく仕様)

単純なcontent_filterによる検査

シェルスクリプト等へSTDIN/STDOUTを使ったフィルタ実装は、content_filterに来た時点で既にqueueに入っているため、スクリプト内ではdeferもしくはbounceのみ選択可能。rejectはできない。

高度なcontent_filterによる検査

inetもしくはunix domainソケットを使った、他プロセスと通信してcontent_filterする場合は、単純な場合と違い、他プロセスの結果に応じてrejectを発生させる事は可能。

※ただし、今回の用途で考えると、このためだけに2つもプロセスを起動するのはシステムがデカすぎるため、不採用としました

exim4

system_filterで実装可能...と思われましたが、設定ファイルがデカすぎ&わかりづらく、system_filterを適用できませんでした。

たぶんこれで行けると思うんですけど。

/etc/exim4/system.filter
# Exim filter
if $message_body contains "Aaa" and $message_body contains "Bbb"
then
  seen finish
else
  fail "cannot relay."
endif

※一行目に# Exim filterって書かなきゃいけないところが、もうダメ。むり。

sendmail / Courier-MTA

もう、力つきて、調べてない。

あとがき

もう、こんな仕事、やりたくない。。。
Qiitaの中でProxSMTPネタって、Qiitaの中では初じゃないでしょうか?

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8