Linux Install Memo

サーバー管理者によるLinux関連ソフトのインストールメモ

Home » □Postfix + amavisd-new でウィルススキャン

□Postfix + amavisd-new でウィルススキャン

参考URL:
http://www.ijs.si/software/amavisd/

最近 www.amavis.org にアクセスできないぁと思っていたら、postfix-ML
で聞いたら、もう本家のプロジェクトは止まってて、派生プロジェクトが
いくつかあるとのこと。で、その中でもよさげっぽいので amavisd-new を
入れてみたいと思います。

tar xvzf package/amavisd-new-2.6.1.tar.gz
cd amavisd-new-2.6.1/

として、INSTALL を見てみると、まず Perl モジュールとして下記のもの
がいるとのこと。CPAN 使ってしこしこインストールしましょう。

Archive::Tar?? (Archive-Tar-x.xx)
Archive::Zip?? (Archive-Zip-x.xx) (1.14 or later should be used!)
Compress::Zlib (Compress-Zlib-x.xx)
Convert::TNEF? (Convert-TNEF-x.xx)
Convert::UUlib (Convert-UUlib-x.xxx) (1.05 or later, stick to new versions!)
MIME::Base64?? (MIME-Base64-x.xx)
MIME::Parser?? (MIME-Tools-x.xxxx) (latest version from CPAN – currently 5.417)
Mail::Internet (MailTools-1.58 or later have workarounds for Perl 5.8.0 bugs)
Net::Server??? (Net-Server-x.xx) (version 0.88 finally does setuid right)
Net::SMTP????? (libnet-x.xx, ports/net/p5-Net) (>= libnet-1.16 for performance)
Digest::MD5??? (Digest-MD5-x.xx) (2.22 or later)
IO::Stringy??? (IO-stringy-x.xxx)
Time::HiRes??? (Time-HiRes-x.xx) (use 1.49 or later, older can cause problems)
Unix::Syslog?? (Unix-Syslog-x.xxx)
BerkeleyDB???? with bdb library 3.2 or later (4.2 or later preferred)

順番としては

Archive::Tar??
Compress::Zlib
Archive::Zip?? (Zlibが必須なため)
MIME::Base64??
MIME::Parser??
Convert::TNEF? (MIME::Bodyが必須なため)
Convert::UUlib
Mail::Internet
Net::Server???
Net::SMTP?????
Digest::MD5???
IO::Stringy???
Time::HiRes???
Unix::Syslog??

でいれること。

他にも

> optional Perl modules:
>?? Mail::SpamAssassin????????? for doing spam scanning (recomm. 2.64 or 3.0.2)
>?? DBI with appropriate DBD::* if using SQL lookups
>?? Net::LDAP?????????????????? if using LDAP lookups
>?? Authen::SASL????????? if authenticating on mail forwarding and DSN
>?? Mail::ClamAV????????? Perl module interface to ClamAV library
>?? SAVI????????????????? Perl module interface to Sophos library (0.30 or later)

これらを入れておくと(っていうか、spamスキャナは必須か)幸せになるらしい
です。…だけど、今回はとりあえず入れません。(^^;

一通りモジュールを入れたら amavisd-new 用のアカウントを用意します。
今までのウィルスチェックを試していたならば vscan というアカウント
があるでしょうが、せっかちでいきなりここに来た人は作ってください。

とりあえず amavisd:amavisd というアカウントを作っておきます。
ホームディレクトリは /var/amavis/ にしておきます。

mkdir /var/amavis
chown amavisd:amavisd /var/amavis
chmod 750 /var/amavis

そしたら展開した中から出てきた amavisd 他をコピーします。

cp amavisd /usr/local/sbin/
chown root /usr/local/sbin/amavisd
chmod 755 /usr/local/sbin/amavisd

cp amavisd.conf /etc/
chown root /etc/amavisd.conf
chmod 644 /etc/amavisd.conf

mkdir /var/virusmails
chown amavisd:amavisd /var/virusmails
chmod 750 /var/virusmails

で、あとは /etc/amavisd.conf をいじります。

以下のパラメーターを書き直します。

> $mydomain = ‘example.com
> $daemon_user = ‘vscan’;
> $daemon_group = ‘sweep’;

また、Postfix を使用しているので以下のコメントアウトをはずします。

> $forward_method = ‘smtp:127.0.0.1:10025’;
> $notify_method = $forward_method;

こうすると、amavisd-new に振られてウィルス(等)のチェックが完了した
メールを10025番ポートを通じてローカルマシンの Postfix に返す、という
意味です。通知も同じように、ということですね。

ちなみに

> $inet_socket_port = 10024; # accept SMTP on this local TCP port

amavisd-new 自体は10024番ポートで待ちますが、これが嫌なら他に替えること。

それと、

> @local_domains_acl

このパラメーターにドメインを追記していくとローカル配信ということなのかな?

また、管理者への通知は

> $virus_admin = “virusalert\@$mydomain”;

ここで決まります。

そんなんで、/etc/amavisd.conf は一通り目を通すようにしてください。

で、つづいて postfix の設定です。

AMaViS の時には

—> Postfix —(10025)—> AMaViS —(10026)—> Postfix —>

という流れでしたが、amavisd-new の場合には

—> Postfix —(10024)—> amavisd-new —(10025)—> Postfix —>

という流れみたいですね。

では早速動かしてみましょう。え?ウィルスチェック用ソフトが無い?
大丈夫、とりあえず試すことはできます。

まずウィルスチェックも何もしないなら /etc/amavisd.conf の

> # @bypass_virus_checks_acl = qw( . ); # uncomment to DISABLE anti-virus code
> # @bypass_spam_checks_acl = qw( . ); # uncomment to DISABLE anti-spam code

上記の2つのパラメーターを両方ともコメントアウトをやめて

> @bypass_virus_checks_acl = qw( . ); # uncomment to DISABLE anti-virus code
> @bypass_spam_checks_acl = qw( . ); # uncomment to DISABLE anti-spam code

というようにしてください。

で、

su – amavisd
/usr/local/sbin/amavisd debug &

とすると動きます。

後のテスト方法は詳しくは ./README_FILES/README.postfix に書いてある
ので、これをよくみてみましょう。デバッグの方法から書いてあります。

簡単にいうと、/etc/postfix/main.cf の最後にでも

> content_filter = smtp:[127.0.0.1]:10024
> default_process_limit = 100

として、/etc/postfix/master.cf の最後に

> 127.0.0.1:10025 inet n – n – 100 smtpd
> -o content_filter= -o myhostname=dummy.domain.name

とでも追加すればOK。ちなみに

> 127.0.0.1:10025 inet n – n – 100 smtpd
> -o content_filter=

とすると、ウィルスチェック専用サーバーとしてさらに他のサーバーに
リレーできるようになります。

リレーの設定は Postfix 次第なのですが、ポイントは

> #relay_domains = $mydestination

です。ここを

> relay_domains = /etc/postfix/relay_domains

こんな風にして、/etc/postfix/relay_domains に

> #
> # relay_domains
> #
> fwnet.jp
> fwnet.or.jp

のようにすると、リレーするドメインが決まります。

★ポイント… 通知メッセージの日本語化

通知メッセージを日本語で送る場合には、色々といじらないといけません。

> # $notify_sender_templ = read_text(‘/var/amavis/notify_sender.txt’);
> # $notify_virus_sender_templ= read_text(‘/var/amavis/notify_virus_sender.txt’);
> # $notify_virus_admin_templ = read_text(‘/var/amavis/notify_virus_admin.txt’);
> # $notify_virus_recips_templ= read_text(‘/var/amavis/notify_virus_recips.txt’);
> # $notify_spam_sender_templ = read_text(‘/var/amavis/notify_spam_sender.txt’);
> # $notify_spam_admin_templ = read_text(‘/var/amavis/notify_spam_admin.txt’);

一見すると /etc/amavisd.conf の設定でこれらファイルを用意すればいい
のかな?と思いますが、それは通知メッセージを英語で書く場合です。

日本語で通知するにはエンコーディングしないといけませんが、
そのためにはこのパラメーターの下の

> # read_l10n_templates(‘/etc/amavis/en_US’);

というパラメーターを有効にして、日本語化した通知メッセージを()内の
ディレクトリにおいて、「charset」と言うファイルで文字コードを指定して
あげないといけません。注意しなければいけない点として、charset は通知
用ファイルの文字コードを書くのであって、通知するメールそのもののエン
コードは amavisd.conf にその設定を書かないといけません。

ここでは

> read_l10n_templates(‘/etc/amavis/’);

として、この中に「iso-2022-jp」で書いたファイルを置くことにします。

mkdir /etc/amavis

としてディレクトリを作って、charset に文字コードを書いておきます。

cat > /etc/amavis/charset
iso-2022-jp

ちなみにメールを送信するかしないかは

> # Notify virus sender?
> #$warnvirussender = 1; # (defaults to false (undef))
>
> # Notify spam sender?
> #$warnspamsender = 1; # (defaults to false (undef))
>
> # Notify sender of banned files?
> #$warnbannedsender = 1; # (defaults to false (undef))
>
> # Notify sender of syntactically invalid header containing non-ASCII characters?
> #$warnbadhsender = 1; # (defaults to false (undef))
>
> # Notify virus (or banned files) RECIPIENT?
> # (not very useful, but some policies demand it)
> #$warnvirusrecip = 1; # (defaults to false (undef))
> #$warnbannedrecip = 1; # (defaults to false (undef))
>
> # Notify also non-local virus/banned recipients if $warn*recip is true?
> # (including those not matching local_domains*)
> #$warn_offsite = 1; # (defaults to false (undef), i.e. only notify locals)

このパラメータで決まります。

最近は送信元の詐称は当たり前なので sender に通知しても意味が無いと
思われます。なので、RECIPIENT (送信先)に通知をすれば十分でしょう。
ただ、いっぱいウィルスメールが来ると、今度は「検知しました」メール
がspamメールになるので、それはそれで注意しましょう。

複数のドメインをチェックする場合には、Postfix でもリレー設定をして
いるはずなので、/etc/amavisd.conf の設定を下記のようにして通知可能
な送信先ドメインを設定しておかないと、管理者にしか通知が来ません。

> read_hash(\%local_domains, ‘/etc/postfix/relay_domains’);

逆を言うと、ここに書かないと送信元に通知ができないけど、世の中全部
のドメインを書くわけにも行かないので、通知先のドメイン名は限定しま
しょう、ってことですね。

以下の方法で通知メッセージを日本語化すると、下記のすべてのファイルが
必要になります。

> template-dsn.txt
> template-virus-sender.txt
> template-virus-admin.txt
> template-virus-recipient.txt
> template-spam-sender.txt
> template-spam-admin.txt

まぁとりあえず touch しておけばいいでしょう。(通知しないしね)

touch /etc/amavis/template-dsn.txt
touch /etc/amavis/template-virus-sender.txt
touch /etc/amavis/template-virus-admin.txt
touch /etc/amavis/template-virus-recipient.txt
touch /etc/amavis/template-spam-sender.txt
touch /etc/amavis/template-spam-admin.txt

で、管理者向けの「見つけたぞ」メールの内容を作りましょう。

/usr/local/sbin/amavisd を見てみると、最後の方に通常時のメッセージ
が「# This is a template for… 」という書き出しでかいてあるので、
ここからコピペします。

> # =============================================================================
> # This is a template for VIRUS ADMINISTRATOR NOTIFICATIONS.
> # For syntax and customization instructions see README.customize.
> # Note that only valid header fields are allowed; non-standard header
> # field heads must begin with “X-” .
> #
> Date: %d
> From: %f
> Subject: [? %#V |[? %#F |[? %#X ||INVALID HEADER]|BANNED NAME (%F)]|VIRUS (%V)]#
> FROM[?%l|| LOCAL] [?%o|(?)|<%o>]
> To: [? %#T |undisclosed-recipients: ;|[<%T>|, ]]
> [? %#C |#|Cc: [<%C>|, ]]
> Message-ID: <VA%n@%h>
>
> ウィルスを見つけました!どうします?
> OK?
>
> [? %#X |#|[%X\n]]
> [? %#V |No viruses were found.
> |A virus (%V) was found.
> |Two viruses (%V) were found.
> |%#V viruses were found.
> ]
> [? %#F
> |#|A banned name (%F) was found.
> |Two banned names (%F) were found.
> |%#F banned names were found.
> ]
> [? %#W |#
> |Scanner detecting a virus: %W
> |Scanners detecting a virus: %W
> ]
> The mail originated from: <%o>
>
> [? %t |#|According to the ‘Received:’ trace, the message originated at:
> %t
> ]
> [? %#S |Notification to sender will not be mailed.
>
> ]#
> [? %#D |#|The message WILL BE delivered to:[
> %D]
> ]
> [? %#N |#|The message WAS NOT delivered to:[
> %N]
> ]
> [? %#V |#|[? %#v |#|Virus scanner output:[
> %v]
> ]]
> [? %q |Not quarantined.|The message has been quarantined as:
> %q
> ]
> ————————- BEGIN HEADERS —————————–
> [%H
> ]\
> ————————– END HEADERS ——————————

まんまベタベタですが、まぁ取り合えず日本語化したいわけですから、
とりあえず確認用に日本語メッセージを入れておきましょう。

実際にカスタマイズするには、./README_FILES/README.customize に各変数
の意味が書いてあるので、それを見てください。

で、amavisd を起動してみると…

> Error in config file /etc/amavisd.conf: Insecure dependency in eval while running with -T switch at /usr/local/lib/perl5/5.8.0/PerlIO.pm line 22.
> BEGIN failed–compilation aborted.

ありゃ、怒られてしまいました。
うーん、見てみると確かに PerlIO モジュールで eval していますから
このままだと怒られますね。

・・・と、いろいろ調べてみたのですが、どうも Perl-5.8 のマルチ
バイト処理が今ひとつきちんとコーディングされていないようです?

少なくとも通知用メッセージを読み込むときには UTF8 に変換して読み
込んで、メールとして出力するときには ISO-2022-JP にしないといけま
せん。

なので、/usr/local/sbin/amavisd そのものをいじらないといけないの
で、下記の修正ポイントを参照して各自の責任で直して試してください。

まずは perldoc Encode::JP として、Encode 処理をどのように使用した
らいいのかを確認してみました。スーパーユーザーでは見れませんので、
一般ユーザーレベルになってください。

ふむふむほうほう、というわけでやることは、

1./usr/local/sbin/amavisd の中でコメントアウトされている

> # use Encode; # Perl 5.8 UTF-8 support

を解除します。

2.出力部分:safe_encode を下記のように修正

> sub safe_encode($$;$) {
>???? if (!$unicode_aware) { $_[1] }? # just return the second argument
>???? else {
>???????? my($encoding, $str, $check) = @_;
>???????? $check = 0? if !defined($check);
>???????? my($taint) = substr($str,0,0);??????? # taintedness of the string
>???????? $str =~ /^(.*)$(?!\n)/s;? $str = $1;? # untaint
> #
> # T.Kabu 2003.07.28
> #
> #?????? $taint . Encode::encode($encoding, $str, $check); # retain taintedness
>???????? $taint .= encode($encoding, $str); # retain taintedness
>???????? $taint;
>???? }
> }

3.入力部分:read_text を下記のように修正

> sub read_text($;$) {
>???? my($filename,$encoding) = @_;
>???? my($inp) = IO::File->new;
>???? $inp->open($filename,’r’)
>???????? or die “Can’t open file $filename for reading: $!”;
> #
> # T.Kabu 2003.07.28
> #
> #??? if ($unicode_aware && $encoding ne ”) {
> #?????? binmode($inp,”:encoding($encoding)”)
> #?????????? or die “Can’t set :encoding($encoding) on file $filename: $!”;
> #??? }
>???? my($str) = ”;? # must not be undef, work around a Perl UTF8 bug
>???? if ($unicode_aware && $encoding ne ”) {
>???????? while(<$inp>) { $str .= decode($encoding, $_); }
>???? }
>???? else {
>???????? while(<$inp>) { $str .= $_; }
>???? }
>???? $inp->close or die “Can’t close file $filename: $!”;
>???? $str;
> }

4.ヘッダー部分:string_to_mime_entity を下記のように修正

> sub string_to_mime_entity($) {
>???? my($mail_as_string_ref) = @_;
>???? my($entity); my($m_hdr,$m_body);
>???? my($taint) = substr($$mail_as_string_ref,0,0);
>???? ($m_hdr,$m_body) = ($1.$taint, $3.$taint)
>???????? if $$mail_as_string_ref =~ /^(.*?\r?\n)(\r?\n|$(?!\n))(.*)$(?!\n)/s;
>???? $m_body = safe_encode($bdy_encoding, $m_body);
>???? # make sure _our_ source line number is reported in case of failure
>???? eval {$entity = MIME::Entity->build(
>???????? Type => ‘text/plain’, Encoding => ‘-SUGGEST’, Charset => $bdy_encoding,
>???????? (defined $notify_xmailer_header && $notify_xmailer_header eq ”
>???????????? ? ()? # leave the MIME::Entity default
>???????????? : (‘X-Mailer’ => $notify_xmailer_header) ), # X-Mailer hdr or undef
>???????? Data => $m_body); 1}? or do {chomp($@); die $@};
>???? my($head) = $entity->head;
>???? # insert header fields from template into MIME::Head entity
>???? $m_hdr =~ s/\r?\n([ \t])/$1/g;? # unfold template header
>???? for my $hdr_line (split(/\r?\n/,$m_hdr)) {
>???????? if ($hdr_line =~ /^([^:]*):\s*(.*)$(?!\n)/s) {
>???????????? my($fhead,$fbody) = ($1.$taint, $2.$taint);
>???????????? # encode according to RFC 2047 if necessary
>???????????? if ($fhead =~ /^(X-.*|Subject|Comments)$(?!\n)/si &&
>???????????????? $fbody =~ /[^\011\012\040-\176]/ # nonprint. except TAB and LF?
>???????????? ) { # encode according to RFC 2047
>???????????????? my($fbody_octets) = $fbody;? # non- UTF-8 -aware
> #
> # T.Kabu 2003.07.29
> #
>???????????????? $fbody_octets = safe_encode($hdr_encoding, $fbody);
> #
>???????????????? if ($unicode_aware && Encode::is_utf8($fbody)) {
>???????????????????? $fbody_octets = safe_encode($hdr_encoding, $fbody);
>???????????????????? do_log(5,”string_to_mime_entity UTF-8 body:? $fbody”);
>???????????????????? do_log(5,”string_to_mime_entity body octets: $fbody_octets”);
>???????????????? }
>???????????????? $fbody = MIME::Words::encode_mimeword($fbody_octets,
>?????????????????????????????????????????????????????? ‘Q’, $hdr_encoding);
>???????????? } else {? # supposed to be in plain ASCII, let’s make sure it is
>???????????????? $fbody = safe_encode(‘ascii’, $fbody);
>???????????? }
>???????????? $fhead = safe_encode(‘ascii’, $fhead);
>???????????? do_log(5, sprintf(“string_to_mime_entity %s: %s”, $fhead,$fbody));
>???????????? # make sure _our_ source line number is reported in case of failure
>???????????? eval {$head->replace($fhead,$fbody); 1} or do {chomp($@); die $@};
>???????? }
>???? }
>???? $entity;? # return the built MIME::Entity
> }

とするといけます。

特に3番目は、binmode でエンコードできそうなものですが、-T オプション
がついているのでエラーで怒られますのでこうしました。何か他にいい方法が
あったら教えてください。

★ポイント… mail.hogehoge.com にもMXを適用する場合

> mail IN A 210.197.75.225
> IN MX 10 relay.hogehoge.com.

DNS情報に上記のように、mail の下にもMXレコードを書かないといけないです。

で、肝心のウィルスチェック用ソフトについてですが、amavisd-new は
色々と対応していますが、個人が使う上では色々と制約があります。
調べられたのだけ書いていきますと..

> http://www.vanja.com/tools/sophie/
> http://www.csupomona.edu/~henson/www/projects/SAVI-Perl/
> http://clamav.elektrapro.com/ <— 使えませんでした
> http://www.openantivirus.org/ <— 使えませんでした
> http://www.vanja.com/tools/trophie/
> http://www.f-prot.com/ <— コマンドライン版なら試せますが…
> http://www.hbedv.com/ or http://www.centralcommand.com/
> http://www.commandsoftware.com/ <— お試し版は.DEFが無いといわれる。
> http://www.symantec.com/ <— お試しできません
> http://drweb.imshop.de/ <— 使えました
> http://www.f-secure.com/products/anti-virus/ <— 使えました
> http://www.nod32.com/
> http://www.nod32.com/
> http://www.norman.com/products_nvc.shtml
> http://www.pandasoftware.com/
> http://www.nai.com/ <— 使えませんでした
> http://www.virusbuster.hu/en/
> http://www.cyber.com/
> http://www.ikarus-software.com/
> http://www.bitdefender.com/ <— 使えませんでした

と、こんな感じです。

どれがよいというのは無いんですが、個人使用だと無料な場合もあります
ので、一通り見た方がいいでしょう。

Name of author

Name: admin

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です