#author("2018-02-01T23:18:27+09:00","default:nowsky","nowsky")
*AMaViS [#o146649b]
clamavと連携させる事で、メールのウイルス検査を実現するソフトウェア。
単体でリレーMTAとして動作させる事も可能だが、
sendmailやPostfixとかの他MTAで一度受けた後にAMaViSに転送する方が、
セキュリティ的に望ましい。
sendmailやPostfixとかの他MTAで一度受けた後にAMaViSに転送する方がセキュリティ的に望ましい。

- 参考情報
[[amavisd-newの設定の巻:+http://www.sea-bird.org/pukiwiki/index.php?amavisd-new%A4%CE%C0%DF%C4%EA%A4%CE%B4%AC]]
~
*構築環境 [#lf44aa5d]
今回検証した環境はこちら
-debian 8.1 x86_64
-openSUSE 13.1 x86_64
-CentOS 7.2 x86_64
-openSUSE 42.2 x86_64
 ※CentOS 6.x等の非Systemd環境で構築する場合には、各スクリプトをinit用に書き換える必要がある。
~
他には下の内容で構築メモを作成
-amavisは"127.0.0.1:TCP/10026"で待ち受ける
-検査完了したメールには"X-Virus-Scanned:"のヘッダーを付与する
-ウイルスメール以外(スパムとか)は、とりあえず次のMTAへ転送する
-Clamavは事前にインストールしておく
-コンフィグディレクトリ構成は、apt-getやzypperした結果のデフォルトをそのまま使う
~
ドメイン構成などは
-メール鯖のドメイン:hoge.org
-メール鯖のFQDN:mail.hoge.org
-メール鯖のIPアドレス:10.0.0.1
-メール鯖管理者のメールアドレス:admin☆mail.hoge.org
~
*構築(Debian環境) [#v6c5c48f]
*構築(Debian) [#v6c5c48f]
&size(16){&font(b){1. インストール};};
amavisの一部コマンドがnon-freeリポジトリを使っている為、
リポジトリを追加する事でインストール出来るようにする必要がある。
 # vi /etc/apt/sources.list.d/jessie.non-free.list
 ==================================================
 deb http://ftp.jp.debian.org/debian/ jessie non-free
 deb http://ftp.jp.debian.org/debian/ jessie-updates non-free
 deb http://ftp.jp.debian.org/debian/ jessie-backports non-free
 
 # apt-get install amavisd-new spamassassin clamav-daemon
 # apt-get install pyzor razor libnet-dns-perl libmail-spf-perl
 # apt-get install arj bzip2 cabextract cpio file gzip lha nomarch pax rar unrar unzip unzoo zip zoo
~

&size(16){&font(b){2. 設定};};
debian環境の場合は、amavisの設定ファイルが細切れになっている。
概ね、機能毎に纏まっているが一部の設定は全く違うファイルにあったりするので、
該当するコンフィグが見つからない場合は、
概ね機能毎に纏まっているが一部の設定は全く違うファイルにあったりするので、
該当するコンフィグが見つからない場合は、都度grepコマンドで探し出す。
 # grep -r "検索文字列" ./*
で探し出すのが良い。
~
#region(&color(#ff0000){設定内容};)
&size(14){&font(b){そのまま使う設定ファイル};};
 /etc/amavis/conf.d/01-debian
 /etc/amavis/conf.d/30-template_localization
 /etc/amavis/conf.d/50-user
~
&size(14){&font(b){/etc/amavis/conf.d/05-domain_id};};
 < chomp($mydomain = `head -n 1 /etc/mailname`);
 ---
 > chomp($mydomain = "hoge.org");
~
&size(14){&font(b){/etc/amavis/conf.d/05-node_id};};
 < chomp($myhostname = `hostname --fqdn`);
 ---
 > chomp($myhostname = "mail.hoge.org");
~
&size(14){&font(b){/etc/amavis/conf.d/15-av_scanners};};
 ! ['ClamAV-clamd',
 !   \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd.ctl"],
 !   qr/\bOK$/m, qr/\bFOUND$/m,
 !   qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ],
 ---
 &ask_daemonの第2引数をclamavのソケットと合わせる
~
&size(14){&font(b){/etc/amavis/conf.d/15-content_filter_mode};};
 < @bypass_spam_checks_maps = (
 <   \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);
 ---
 > @bypass_spam_checks_maps = (1);
~
&size(14){&font(b){/etc/amavis/conf.d/20-debian_defaults};};
 < $QUARANTINEDIR = "$MYHOME/virusmails";
 < $quarantine_subdir_levels = 1; # enable quarantine dir hashing
 ---
 > ###$QUARANTINEDIR = "$MYHOME/virusmails";
 > ###$quarantine_subdir_levels = 1; # enable quarantine dir hashing
 ==================================================
 < @keep_decoded_original_maps = (new_RE(
 <   qr'^MAIL$',
 <   qr'^MAIL-UNDECIPHERABLE$',
 <   qr'^(ASCII(?! cpio)|text|uuencoded|xxencoded|binhex)'i,
 <   qr'^Zip archive data',
 < ));
 ---
 > @keep_decoded_original_maps = (new_RE(
 >   qr'^MAIL$',
 >   qr'^MAIL-UNDECIPHERABLE$',
 >   qr'^(ASCII(?! cpio)|text|uuencoded|xxencoded|binhex)'i,
 > ###qr'^Zip archive data',
 > ));
 ==================================================
 ! [1] $inet_socket_bind = '127.0.0.1';
 ! [2] $inet_socket_port = 10026;
 ! [3] $forward_method = 'smtp:[127.0.0.1]:10025';
 ! [4] $X_HEADER_TAG = 'X-Virus-Scanned';
 ! [5] $X_HEADER_LINE = "$myproduct_name at $mydomain";
 ! [6] $virus_admin = 'admin@mail.hoge.org';
 ! [7] $spam_admin = 'admin@mail.hoge.org';
 ---
 [1] amavisの待ち受けるIPアドレス
 [2] amavisの待ち受けるTCPポート番号
 [3] ウイルス検査完了メールの転送先。例だとIP:127.0.0.1-TCP/10025に投げる
 [4] ウイルス検査完了メールに付与するヘッダ
 [5] ウイルス検査完了メールに付与するヘッダパラメータ
 [6] ウイルスメールの転送先アドレス。ドメイン部を$mydomainに置き換え可能
 [7] スパムメールの転送先アドレス。ドメイン部を$mydomainに置き換え可能
 ==================================================
 $banned_filename_re = new_RE(
   # [1] Block certain double extensions anywhere in the base name
   qr'\.[^./]*\.(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)\.?$'i,
 
   # [2] Windows Class ID CLSID, strict
   qr'\{[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}\}?$'i,
 
   # [3] Block these MIME types
   qr'^application/x-msdownload$'i,
   qr'^application/x-msdos-program$'i,
   qr'^application/hta$'i,
 
   # [4] Block these file extension
   qr'^(?!cid:).*\.[^./]*[A-Za-z][^./]*\.\s*(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)[.\s]*$'i,
   qr'.\.(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)$'i,
   qr'^\.(exe-ms|dll)$',
 );
 ---
 [1] 二重拡張子の添付ファイルを遮断
 [2] OSのCLSIDパラメータを遮断
 [3] 添付ファイルのMIMEタイプで遮断
 [4] 添付ファイルの拡張子で遮断
~
&size(14){&font(b){/etc/amavis/conf.d/25-amavis_helpers};};
 < @mynetworks = qw( 127.0.0.1/32 );
 ---
 > @mynetworks = qw( 127.0.0.1/32 10.0.0.1/32 );
 ---
 @mynetworksはCIDR形式で記入する
#endregion
~

&size(16){&font(b){3. 設定反映};};
書き換えた設定をAMaViSに反映させる為にプロセスの再起動を行う。
 # systemctl restart amavis.service
 # netstat -an | egrep -i "tcp.*10026.*LISTEN"
~
*構築(CentOS) [#l9b626fe]
&size(16){&font(b){1. インストール};};
コアとなるclamavと関連ライブラリはEPELリポジトリを使っている為、
事前にEPELリポジトリを追加しておく必要がある。
 # yum install amavisd-new spamassassin
 # yum install clamav clamav-data clamav-filesystem clamav-lib clamav-scanner-sysvinit clamav-scanner
 # yum install clamav-server-systemd clamav-server-sysvinit clamav-server clamav-update
~

&size(16){&font(b){2. 設定};};
CentOSの場合amavisの設定ファイルは、/etc/amavisd/amavisd.confの一つに集約されている。
/etc/clamd.d/amavisd.confにも設定があるが、こちらは使わないので放置する。
~
*構築(OpenSUSE版) [#fa11b2ab]
#region(&color(#ff0000){設定内容};)
&size(14){&font(b){/etc/amavisd/amavisd.conf};};
 ! [1] @bypass_virus_checks_maps = (0);
 ! [2] @bypass_spam_checks_maps  = (1);
 ---
 [1] ウイルスチェックを必ず実行する
 [2] スパムメールチェックは行わない
 ==================================================
 ! [3] $lock_file = "/var/run/amavisd/amavisd.lock";
 ! [4] $pid_file  = "/var/run/amavisd/amavisd.pid";
 ---
 [3] amavisd起動時のロックファイル
 [4] amavisdのプロセス番号ファイル
 ==================================================
 ! [5] $log_level = 1;
 ! [6] $do_syslog = 1;
 ! [7] $syslog_facility = 'mail';
 ---
 [5] amavisdのウイルスチェックログを記録
 [6] amavisdのログをsyslogに出力
 [7] syslogのfacilityを設定する
 ==================================================
 <     \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamd.amavisd/clamd.sock"],
 ---
 >     \&ask_daemon, ["CONTSCAN {}\n", "【clamavのソケットと同じにする】"],
 ==================================================
 < $mydomain   = 'example.com';
 ---
 > $mydomain   = 'hoge.org';
 > $myhostname = 'mail.hoge.org';
  
 < $QUARANTINEDIR   = undef;
 ---
 > # $QUARANTINEDIR = undef;
  
 < $db_home   = "$MYHOME/db";
 ---
 > # $db_home = "$MYHOME/db";
  
 < @mynetworks = qw( 127.0.0.0/8 [::1] [FE80::]/10 [FEC0::]/10 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 );
 ---
 > @mynetworks = qw( 127.0.0.1/32 10.0.0.1/32 );
  
 < $inet_socket_port = 10024;
 ---
 > $inet_socket_bind = '127.0.0.1';
 > $inet_socket_port = 10026;
  
 < $virus_admin               = undef;
 ---
 > $virus_admin               = 'admin@mail.hoge.org';
 > $spam_admin                = 'admin@mail.hoge.org';
  
 < $mailfrom_notify_admin     = undef;
 < $mailfrom_notify_recip     = undef;
 < $mailfrom_notify_spamadmin = undef;
 ---
 > $mailfrom_notify_admin     = "virusalert\@$mydomain";
 > $mailfrom_notify_recip     = "virusalert\@$mydomain";
 > $mailfrom_notify_spamadmin = "spam.police\@$mydomain";
  
 < # $notify_method  = 'smtp:[127.0.0.1]:10025';
 ---
 > $forward_method   = 'smtp:[127.0.0.1]:10025';
 > $notify_method    = '$forward_method';
  
 < $X_HEADER_TAG  = 'X-Virus-Scanned';
 < $X_HEADER_LINE = "$myproduct_name at $mydomain";
  
 > $banned_filename_re = new_RE(
 >   qr'\.[^./]*\.(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)\.?$'i,
 >   qr'\{[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}\}?$'i,
 >   qr'^application/x-msdownload$'i,
 >   qr'^application/x-msdos-program$'i,
 >   qr'^application/hta$'i,
 >   qr'^(?!cid:).*\.[^./]*[A-Za-z][^./]*\.\s*(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)[.\s]*$'i,
 >   qr'.\.(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)$'i,
 >   qr'^\.(exe-ms|dll)$',
 > );
#endregion
~

&size(16){&font(b){3. スクリプト書き換え};};
デフォルト設定だと、&font(b){amavisd};と&font(b){clamd};が&font(b){それぞれamavisプロセスを起動};してしまい、メモリを2倍消費する。
clamavと連携する時は、clamdからのみプロセスを実行出来れば良いので、起動スクリプトを修正して二重起動を防止する。
また、スクリプト修正に併せてtmpfiles内のユーザ・グループ設定を、amavisd・clamdの実行ユーザにそれぞれ変更する。
~
#region(&color(#ff0000){設定内容};)
&size(14){&font(b){起動スクリプト調整};};
 # vi /usr/lib/systemd/system/amavisd.service
 ---
 [Unit]
 Description=Amavisd-new is an interface between MTA and content checkers.
 Documentation=http://www.ijs.si/software/amavisd/#doc
 # After=network.target
 # Wants=clamd@amavisd.service
 # Wants=postfix.service
 After=clamd@scan.service network.target
 Wants=clamd@scan.service
 Before=postfix.service
 
&size(14){&font(b){2重起動防止};};
 # rm /etc/clamd.d/amavisd.conf
 
&size(14){&font(b){テンポラリ設定の変更};}; 
 # vi /usr/lib/tmpfiles.d/amavisd-new.conf
 ---
 d /var/run/amavisd 755 vscan vscan -
 
 # vi /usr/lib/tmpfiles.d/clamd.scan.conf
 ---
 d /var/run/clamd.scan 0710 clamd clamd
#endregion
~

&size(16){&font(b){4. 設定反映};};
amavisdを一つだけにする為、関連するプログラムを再起動する
設定を間違えてamavisdが二重起動しようとしている場合や、systemdによるサービス自動再起動が動作し、
プログラムが上手く再起動出来ない(1つだけにならない)場合は下記ログがmessagesに出力される
 systemd: Starting clamd scanner (amavisd) daemon...
 clamd:   ERROR: Can't open/parse the config file /etc/clamd.d/amavisd.conf
 systemd: clamd@amavisd.service: main process exited, code=exited, status=1/FAILURE
 systemd: Unit clamd@amavisd.service entered failed state.
 systemd: clamd@amavisd.service failed.
 systemd: clamd@amavisd.service holdoff time over, scheduling restart.
 systemd: start request repeated too quickly for clamd@amavisd.service
 systemd: Started clamd scanner (amavisd) daemon.
 
 ※再起動順序
 amavisdがforeground引数を付けた状態で起動していたら、clamd経由でamavisが起動している(二重起動状態)
 ---
 # systemctl restart clamd
 # systemctl restart amavisd
 # netstat -an | egrep -i "tcp.*10026.*LISTEN"
 # ps -ef | grep amavis
~
*構築(openSUSE) [#z4b7a91b]
&size(16){&font(b){1. インストール};};
openSUSEでは標準リポジトリでamavisパッケージを導入する事が出来る筈だが、
エラーが出てしまった場合はソースRPMリポジトリとセキュリティリポジトリを追加する。
 # zypper addrepo http://download.opensuse.org/distribution/leap/42.2/repo/oss/ opensuse-repo-oss
 # zypper addrepo http://download.opensuse.org/repositories/security/openSUSE_Leap_42.2/security.repo opensuse-security
 # zypper refresh
 # zypper install clamav amavisd-new
~

&size(16){&font(b){2. 設定};};
openSUSEのamavisd.confは一つのファイルに固まった形になっている。
設定内容はCentOS版と殆ど同じだが、バイパス設定が少しだけ違うので注意する。
~
#region(&color(#ff0000){設定内容};)
&size(14){&font(b){/etc/amavisd.conf};};
 ! [1] # @bypass_virus_checks_maps = (1);
 ! [2] @bypass_spam_checks_maps    = (1);
 ! [3] # $bypass_decode_parts      = 1;
 ---
 [1] コメントアウトか"0"をセットするとウイルスチェックを実行する
 [2] スパムチェックは行わない
 [3] コメントアウトするとファイルデコーダ・アーカイバが動作するようになる
 ==================================================
 ! [4] $MYHOME    = '/var/spool/amavis';
 ! [5] $lock_file = "$MYHOME/var/amavisd.lock";
 ! [6] $pid_file  = "$MYHOME/var/amavisd.pid";
 ---
 [4] amavisが生成するファイルのディレクトリ指定
 [5] amavis起動時のロックファイル
 [6] amavisのプロセス番号ファイル
 ==================================================
 ! [7] $log_level = 1;
 ! [8] $do_syslog = 1;
 ! [9] $syslog_facility = 'mail';
 ---
 [7] amavisのウイルスチェックログを記録
 [8] amavisのログをsyslogに出力
 [9] syslogのfacilityを設定する
 ==================================================
 <     \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamd.amavisd/clamd.sock"],
 ---
 >     \&ask_daemon, ["CONTSCAN {}\n", "【clamavのソケットと同じにする】"],
 ==================================================
 < $mydomain   = 'example.com';
 ---
 > $mydomain   = 'hoge.org';
 > $myhostname = 'mail.hoge.org';
  
 < $QUARANTINEDIR   = undef;
 ---
 > # $QUARANTINEDIR = undef;
  
 < $db_home   = "$MYHOME/db";
 ---
 > # $db_home = "$MYHOME/db";
  
 < @mynetworks = qw( 127.0.0.0/8 [::1] [FE80::]/10 [FEC0::]/10 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 );
 ---
 > @mynetworks = qw( 127.0.0.1/32 10.0.0.1/32 );
  
 < $inet_socket_port = 10024;
 ---
 > $inet_socket_bind = '127.0.0.1';
 > $inet_socket_port = 10026;
  
 < $virus_admin               = undef;
 ---
 > $virus_admin               = 'admin@mail.hoge.org';
 > $spam_admin                = 'admin@mail.hoge.org';
  
 < $mailfrom_notify_admin     = undef;
 < $mailfrom_notify_recip     = undef;
 < $mailfrom_notify_spamadmin = undef;
 ---
 > $mailfrom_notify_admin     = "virusalert\@$mydomain";
 > $mailfrom_notify_recip     = "virusalert\@$mydomain";
 > $mailfrom_notify_spamadmin = "spam.police\@$mydomain";
  
 < # $notify_method  = 'smtp:[127.0.0.1]:10025';
 ---
 > $forward_method   = 'smtp:[127.0.0.1]:10025';
 > $notify_method    = '$forward_method';
  
 < $X_HEADER_TAG  = 'X-Virus-Scanned';
 < $X_HEADER_LINE = "$myproduct_name at $mydomain";
  
 > $banned_filename_re = new_RE(
 >   qr'\.[^./]*\.(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)\.?$'i,
 >   qr'\{[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}\}?$'i,
 >   qr'^application/x-msdownload$'i,
 >   qr'^application/x-msdos-program$'i,
 >   qr'^application/hta$'i,
 >   qr'^(?!cid:).*\.[^./]*[A-Za-z][^./]*\.\s*(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)[.\s]*$'i,
 >   qr'.\.(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)$'i,
 >   qr'^\.(exe-ms|dll)$',
 > );
#endregion
~

&size(16){&font(b){3. 設定反映};};
書き換えた設定をプロセスに反映させる為に再起動を行う。
また、デフォルトでは自動起動がOFFになっている為、自動起動をONに変更する。
 # systemctl enable  amavis.service
 # systemctl restart amavis.service
 # netstat -an | egrep -i "tcp.*10026.*LISTEN"