Postfixのメールをリアルタイムにウイルスチェックします
2015年現在、メールに添付するタイプのウイルスが再び猛威を振るっています。根本的な解決策としてWindowsへメールを渡す前に、サーバ上でウイルスを削除できれば安心です。
そこでCentOS6系でPostfixのメールを自動でウイルスチェックし、ウイルス発見時に削除する設定を解説します。
一般的にClamAVとの連携はSpamAssassinやamavisd-newを導入する解説が多いですが、この記事では高速に動作するClamSMTPというウイルスフィルターを利用します。
またClamdはバージョンによって実行権限が異なっていたり、ClamSMTPにも種類があり、設定ファイルも異なっているなど、わかりにくい部分もあるので補足で解説します。
ClamAVのインストール
一連の流れで解説するためにClamAVのインストール方法から解説します。
細かな設定については触れないので、使い方を知りたい方は「無料で使えるLinuxのアンチウイルスソフト『Clam AntiVirus』の導入と設定の解説」をご覧ください。
またPostfixは設定済みの前提で進めます。
これも過去に解説しているので良かったらご覧ください。
「Postfixによる、セキュリティに配慮したメールサーバの構築方法」
「メールサーバ構築のためOpenSSL、Postfix、Dovecotのインストールと設定」
過去このサイトの解説ではrpmforgeを利用してインストールしていましたが、epelだと最新のものがインストールできます。
# yum update clamav --enablerepo=epel (省略) Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Updating: clamav x86_64 0.98.7-1.el6 epel 1.3 M Updating for dependencies: clamav-db x86_64 0.98.7-1.el6 epel 95 M clamd x86_64 0.98.7-1.el6 epel 161 k Transaction Summary ================================================================================ Upgrade 3 Package(s) (省略)
ClamAVの設定
# cd /etc # cp clamd.conf clamd.conf.org ←オリジナルの設定ファイルのバックアップ # vi /etc/clamd.conf
rootで起動するため権限の変更
User clam ←これは前のバージョンではclamavとなっていた。 ↓ #User clam
壊れたファイルを検出してくれるオプションですが、誤検出が多いため無効
DetectBrokenExecutables yes
↓
#DetectBrokenExecutables yes
TCPソケットを利用したウイルススキャンを停止(外部サーバのスキャンサーバとして使う場合はそのまま)
TCPSocket 3310
TCPAddr 127.0.0.1
↓
#TCPSocket 3310
#TCPAddr 127.0.0.1
これで一旦保存。
ウイルス定義をスクリプトを使って更新
# sh /etc/cron.daily/freshclam
以下のようなエラーが出る場合があります。
ERROR: Can't create temporary directory /var/lib/clamav/clamav-6505bfbc05c499549901860d5a3dc649.tmp
freshclamのログを見てみます。
# cat /var/log/clamav/freshclam.log (省略) ERROR: Can't create temporary directory /var/lib/clamav/clamav-270ac084898ed0437abdb0cef1af19a5.tmp Hint: The database directory must be writable for UID 495 or GID 493
「/var/lib/clamav」のUIDとGIDが違って書き込めないとのこと。
テンポラリディレクトリの権限を変更
# chown 495:493 /var/lib/clamav
ネット上の多くの解説でユーザー名はclamavとされていますが、最新版はデフォルトのユーザー名がclamに変更されたようです。 そのためインストール時に作成されるディレクトリやlogファイルの権限はclamで作成されています。古い解説に合わせる場合はclamavへ変更してください。(今回はroot権限で実行するため変更しなくても問題はありません)
これで無事にアップデートできるはずです。
このスクリプトが通常に実行できるということは、cronで毎日ウイルス定義ファイルを更新できるということです。
ClamSMTPのインストール
ClamSMTPは動作が軽快で、一旦設定してしまえば特別なメンテナンスもいらないという特徴を持っています。
それではClamSMTPをインストールします。
# yum install clamsmtp --enablerepo=epel (省略) Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: clamsmtp x86_64 1.10-6.el6 epel 42 k Transaction Summary ================================================================================ Install 1 Package(s) (省略)
ClamSMTPの設定
# cp /etc/clamsmtpd.conf /etc/clamsmtpd.conf.org # vi /etc/clamsmtpd.conf
スキャンしたメールを送信するためのポートを確認(10026以外なら直す)
OutAddress: 10026
続いてメールを待ち受けるポートを設定
#Listen: 0.0.0.0:10025
↓
Listen: 127.0.0.1:10025
他にもログファイルの設定等は「/etc/clamd.d/clamsmtp.conf」で行います。少し関係がわかりにくいですが、この設定ファイルはClamSMTP用にClamdAVの動作を制御する設定ファイルという位置付けのようです。
転送用のポートを開放
設定したらiptablesでポートを開放します。(同一サーバ内で転送している場合は不要)
サーバ内部で転送すればいいのでローカルネットワーク限定で開放します。
# iptables -A INPUT -p tcp -s 192.168.0.0/24 -m tcp --dport 10025 -j ACCEPT # iptables -A INPUT -p tcp -s 192.168.0.0/24 -m tcp --dport 10026 -j ACCEPT
postfixの「main.cf」を変更する
# vi /etc/postfix/main.cf
content_filterでClamSMTPで待ち受けるポートへ転送。
receive_override_optionsでコンテンツフィルタリングの前にアドレスを操作できないようにします。
content_filter = scan:127.0.0.1:10025 receive_override_options = no_address_mappings
postfixの「master.cf」を変更する
# vi /etc/postfix/master.cf
最終行に追加する。(行頭のスペースが重要なので注意)
# AV scan filter (used by content_filter) scan unix - - n - 16 smtp -o smtp_send_xforward_command=yes # For injecting mail back into postfix from the filter 127.0.0.1:10026 inet n - n - 16 smtpd -o content_filter= -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks -o smtpd_helo_restrictions= -o smtpd_client_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o mynetworks_style=host -o smtpd_authorized_xforward_hosts=127.0.0.0/8
それぞれの意味を解説すると以下のとおり。
AV scan filterの方は、フィルターの並列プロセス数が16。
xforwardはコンテンツフィルター前の情報をロギングするための設定。詳しくは「公式のドキュメント」を参照してください。
For injecting mailはコンテンツフィルターを通した後にポストフィックスに戻す設定です。
127.0.0.1のポート10026で、同じように並列プロセス数が16。
receive_override_optionsでmain.cfの設定を上書き。
no_unknown_recipient_checksは知らない受信者を拒否しない。要は一先ず全部フィルターに通すという設定。
no_header_body_checksはheader/body_checksを無効にする。要は上と同じように全部フィルターに通す設定。
smtpd_recipient_restrictionsはアクセス制限についての設定。
permit_mynetworksは$mynetworksにリストアップされたネットワークを許可。ようはローカルネットワークのメールは許可という設定。
rejectはデフォルトのポリシーで上のネットワーク以外のメールは要求を拒否します。
mynetworks_styleはリレーアクセス制御などのための信頼されたネットワークのリスト。
hostはローカルのみ信頼という設定。
smtpd_authorized_xforward_hostsはxforwardを使うことを許可する対象。
127.0.0.0/8はいわゆるローカルでのみ許可という意味。
これで全ての設定は完了です。
全てのデーモンを新しい設定で起動します。
# /etc/init.d/clamd restart # /etc/init.d/clamsmtpd restart # /etc/init.d/postfix restart # /etc/init.d/dovecot restart
EPELでインストールすると以下のファイルも入るようです。 しかし上のclamsmtpdでウイルスメールのチェックは可能です。再現はできませんでしたが、clamsmtp-clamdでないと動作しない環境もあるようなので、動かない場合は試してみてください。 clamsmtpdとはコマンドも異なるので注意してください。 clamsmtp-clamdの設定ファイルの解説で詳しい設定が解説されています。必要な方は参照してください。
# /etc/init.d/clamsmtp-clamd restart
自動起動の設定
正しく起動することがわかったら自動起動を有効にします。
# chkconfig --list clamd # chkconfig --list clamsmtpd
2と5が無効の場合、有効にしておいてください。
# chkconfig clamd on # chkconfig clamsmtpd on
テストウイルスで正しく動作するかテスト
テストウイルスをダウンロードして自分のメールアドレス宛に添付して送信します。Googleでテストウイルスと検索すれば出てきます。
トレンドマイクロのテストウイルスのページはこちら
正しく動作していれば「/var/log/maillog」に以下のようにログが流れます。
Nov 15 15:11:56 hoge clamsmtpd: 10000D: from=huga@example.com, to=hoge@example.com, status=VIRUS:Eicar-Test-Signature
ウイルスが発見されると「status=VIRUS」の後にウイルス名が記載されています。
通常時は「status=CLEAN」となります。
clamdの方のlogには以下のように表示されます。
Sun Nov 15 15:11:56 2015 -> /var/lib/clamd.clamsmtp/clamsmtpd.tM4EC4: Eicar-Test-Signature FOUND
うまくいかない場合はclamsmtpd.confにあるClamAddressの「/var/run/clamd.clamsmtp/clamd.sock」とclamd.confの「LocalSocket」が一致しているか、ファイルが存在するかなど確認してみてください。
また、clamsmtpd.confでキャッシュ用のディレクトリを指定するTempDirectoryの「/var/lib/clamd.clamsmtp/」が存在するか、User:で設定したユーザーで権限が正しく指定されているか調べてみてください。
定時スキャンの設定
せっかくclamdを常駐させてPostfixを監視しているので、リアルタイムスキャンも利用したいところです。
しかしClamAVのリアルタイムスキャンはLinux 2.6.36以降で標準搭載されているfanotifyを利用します。それ以前のカーネルではDazukoなどを導入せねばならず、はっきり言って安定しない地雷機能です。
CentOS7なら、SELINUXを無効にして、「/etc/clamd.conf」でScanOnAccessをyesに変更、スキャンフォルダをOnAccessIncludePathで指定すればリアルタイムスキャンが有効になります。
今回はCentOS6系なので、すっぱり諦めて、自動で1週間に1度サーバ全体をウイルススキャンします。
これは以前の投稿で紹介した方法です。
除外項目の設定
# vi /etc/clamd.conf
除外項目を設定します。登録したディレクトリは再帰的に無効になります。
#ExcludePath ^/proc/
#ExcludePath ^/sys/
↓
#ExcludePath ^/proc/
#ExcludePath ^/sys/
ExcludePath ^/boot/
ExcludePath ^/proc/
ExcludePath ^/sys/
ExcludePath ^/var/
ExcludePath ^/etc/
cronで実行するスクリプトの作成
# cd ← rootディレクトリで作業 # vi clamd.sh
メールアドレスの項目は環境に合わせて変更してください。
#!/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin #ウイルスに関するメッセージを入れる変数を作成 #mktempは「/tmp」以下にユニークなファイルを作成するコマンド CLAMSCANTMP=`mktemp` #clamdscanを全体に実行。ウイルスが見つかった場合削除して、メッセージをmktempで作成したファイルに代入 clamdscan / --remove > $CLAMSCANTMP 2>&1 # $CLAMSCANTMPにウイルス発見の際に出力される「FOUND」があるか調べ、ある場合に内容をメールする。(見つからなかった場合もメールするようにした) [ ! -z "$(grep FOUND$ $CLAMSCANTMP)" ] && \ grep FOUND$ $CLAMSCANTMP | mail -s "Virus Found" info@example.com [ -z "$(grep FOUND$ $CLAMSCANTMP)" ] && \ echo "clamdscan normal end" | mail -s "Virus Not Found" info@example.com rm -f $CLAMSCANTMP
1週間に1度でもやれば上等なので以下に保存。
# mv clamd.sh /etc/cron.weekly
ちゃんと動作するかテストしてみてください。
ちなみに除外項目以外は全て(一部例外あり)のファイルを検査するため数時間かかることがあります。実行する際は注意してください。
# sh /etc/cron.weekly/clamd.sh
時間がかかると言ってもclamdscanはclamscanに比べ半分以下のスピードで実行できます。更に1度検査したファイルはスキップするので2回めからさらに高速になります。
また、今回設定したClamSMTPも大量のメールも高速に検査することができます。
ただ、ウイルス定義のデータベース等をRAMに展開するため、最低でも150MB程度のメモリを消費します。メモリ量の少ないサーバの場合はOOM Killerに注意してください。
メモリの潤沢な環境でリアルタイムスキャンを有効にするとclamdだけで350MB程度使うようです。