先日メールのチェックをしているとサーバが「451 Local Error」というエラーを返すようになりました。
具体的には以下のようなエラーメッセージです。
This is the mail system at host mail.sukegra.com. I'm sorry to have to inform you that your message could not be delivered to one or more recipients. It's attached below. For further assistance, please send mail to postmaster. If you do so, please include this problem report. You can delete your own text from the attached returned message. The mail system <hogehoge@example.com>: host 127.0.0.1[127.0.0.1] said: 451 Local Error (in reply to end of DATA command)
エラーコードを元に原因を特定するべく検索すると、どうやらウイルス対策で利用しているClam AntiVirusが原因のようです。
当サイトではメールのリアルタイムチェックにclamdとClamSMTPを組み合わせて利用していたのですが、何らかの理由でclamdが停止することで「451 Local Error」が発生していました。
まずはclamdが生きているか調べます。
# ps aux | grep clamd clamsmtp 1253 0.0 0.0 844088 1212 ? Ss 2018 1:31 /usr/sbin/clamsmtpd -f /etc/clamsmtpd.conf -p /var/run/clamd.clamsmtp/clamsmtpd.pid
clamsmtpは動いていますが、あるはずのclamdがありません。
clamdは何らかの原因で突然落ちることがあります。(主にメモリ不足。設定にOOMKiller時に自動で停止する設定もあります)
とりあえず再起動をかけてみます。
# /etc/init.d/clamd restart
Stopping Clam AntiVirus Daemon: [FAILED]
Starting Clam AntiVirus Daemon: [ OK ]
やはり落ちていたようです。
これで終わってはまた自動で停止する可能性があるので原因を探ってみます。
まずは困ったときの更新作業。とりあえずウイルスのデータベースを更新します。
[root@sukegra ~]# freshclam
ClamAV update process started at Sat Mar 2 10:37:46 2019
WARNING: Your ClamAV installation is OUTDATED!
WARNING: Local version: 0.99 Recommended version: 0.101.1
DON'T PANIC! Read http://www.clamav.net/support/faq
main.cld is up to date (version: 58, sigs: 4566249, f-level: 60, builder: sigmgr)
daily.cvd is up to date (version: 25374, sigs: 2264251, f-level: 63, builder: raynman)
bytecode.cld is up to date (version: 328, sigs: 94, f-level: 63, builder: neo)
「Your ClamAV installation is OUTDATED!」と出ています。バージョンが古いのでアップデートしろとのこと。
EPELリポジトリを有効にしてアップデートします。
# yum --enablerepo=epel update clamav
Dependencies Resolved
=================================================================================================================
Package Arch Version Repository Size
=================================================================================================================
Updating:
clamav x86_64 0.100.2-1.el6 epel 1.3 M
Installing for dependencies:
json-c x86_64 0.11-13.el6 base 27 k
Updating for dependencies:
clamav-db x86_64 0.100.2-1.el6 epel 161 M
clamd x86_64 0.100.2-1.el6 epel 243 k
Transaction Summary
=================================================================================================================
Install 1 Package(s)
Upgrade 3 Package(s)
Total download size: 163 M
Is this ok [y/N]: y ←yキーを入力してエンター
「0.100.2-1.el6」というのが最新のものらしいです。インストール後に再起動します。
# /etc/init.d/clamd restart
Stopping Clam AntiVirus Daemon: [FAILED]
Starting Clam AntiVirus Daemon: WARNING: Ignoring deprecated option AllowSupplementaryGroups at line 204
LibClamAV Warning: Detected duplicate databases /var/lib/clamav/main.cvd and /var/lib/clamav/main.cld, please manually remove one of them
LibClamAV Warning: Detected duplicate databases /var/lib/clamav/bytecode.cvd and /var/lib/clamav/bytecode.cld. The /var/lib/clamav/bytecode.cvd database is older and will not be loaded, you should manually remove it from the database directory.
[ OK ]
なにやら警告がわさわさと出ています。
バージョンが変わったので設定も変わったのだと思います。とりあえず上から順番に直します。
1行目の警告の対処
1行目は設定ファイルの204行目にあるAllowSupplementaryGroupsをコメントアウトしろとのこと。
ちなみに設定ファイルは「/etc/clamd.conf」です。公式サイトのチュートリアルに「/etc/clamd.d/clamsmtp.conf」とあったのでそちらを編集しましたが、反映されませんでした。「/etc/clamd.d/clamsmtp.conf」を使うのはLinux 7からで、Linux 6では「/etc/clamd.conf」のようです。
# vi /etc/clamd.conf
# Initialize supplementary group access (clamd must be started by root).
# Default: no
AllowSupplementaryGroups yes
以下のように変更
# Initialize supplementary group access (clamd must be started by root). # Default: no # AllowSupplementaryGroups yes
2行目の警告の対処
次は「/var/lib/clamav/main.cvd」と「/var/lib/clamav/main.cld」というデータベースが重複しているとのこと。データベースの形式も変わったようです。どちらかを削除するべきか…。
# cd /var/lib/clamav/ # ls -al drwxr-xr-x 2 clam clam 4096 Oct 24 03:19 . drwxr-xr-x 29 root root 4096 Mar 2 03:43 .. -rw-r--r-- 1 clamav clamav 1013248 Jan 3 03:40 bytecode.cld -rw-r--r-- 1 clam clam 187426 Oct 4 14:57 bytecode.cvd -rw-r--r-- 1 clamav clamav 168627200 Mar 1 03:27 daily.cld -rw-r--r-- 1 clam clam 51005708 Oct 4 14:57 daily.cvd -rw-r--r-- 1 clamav clamav 307499008 Jun 9 2017 main.cld -rw-r--r-- 1 clam clam 117892267 Jan 9 2018 main.cvd
どうやら拡張子がcldのものが古く、cvdのものが新しいようです。
ウイルス定義ファイルなら新しい方が良かろうということで「main.cld」を削除します。
# rm main.cld
3行目の警告の対処
「/var/lib/clamav/bytecode.cvd」が古いのでロードできない。手動で削除しろとのこと。
# rm bytecode.cvd
さて、これで警告の修正が終わったので早速起動してみます。
# /etc/init.d/clamd start
Starting Clam AntiVirus Daemon: [FAILED]
あれ、起動しなくなりました。悪化しとるがなw
ひとまず、ログでも見てみます。
# vi /var/log/clamav/clamd.log
Sat Mar 2 14:34:21 2019 -> +++ Started at Sat Mar 2 14:34:21 2019
Sat Mar 2 14:34:21 2019 -> Received 0 file descriptor(s) from systemd.
Sat Mar 2 14:34:21 2019 -> clamd daemon 0.100.2 (OS: linux-gnu, ARCH: x86_64, CPU: x86_64)
Sat Mar 2 14:34:21 2019 -> Log file size limited to 4294967295 bytes.
Sat Mar 2 14:34:21 2019 -> Reading databases from /var/lib/clamav
Sat Mar 2 14:34:21 2019 -> Not loading PUA signatures.
Sat Mar 2 14:34:21 2019 -> Bytecode: Security mode set to "TrustSigned".
Sat Mar 2 14:34:41 2019 -> Loaded 6823116 signatures.
Sat Mar 2 14:34:43 2019 -> LOCAL: Unix socket file /var/run/clamav/clamd.sock
Sat Mar 2 14:34:43 2019 -> LOCAL: Setting connection queue length to 30
Sat Mar 2 14:34:43 2019 -> ERROR: daemonize() failed: Cannot allocate memory
Sat Mar 2 14:34:43 2019 -> Socket file removed.
気になるのはPUA signaturesが読み込めないという部分。PUAとはPotentially Unwanted Applicationのことで一般的に言えば「悪意あるソフトを検出するための定義ファイル」といったところでしょうか。
そして具体的なエラーの内容は「ERROR: daemonize() failed: Cannot allocate memory」つまりメモリが足りないよとのこと。
ClamAVのリアルタイムチェックにclamdを走らせるとメモリ食いなことで知られていますが、それでも使用メモリは300MB程度です。当サーバではGMO VPSの2GBプランで、メモリに余裕を持たせているため、たかが300MBでメモリ不足になることは考えられません。
どうしたものかと調べていると有益な情報がstack overflowに。
どうやら起動時に限りPUA signaturesを読み込んだあとコピーするという作業が発生するとのこと。(個人的に検証はしていません)その際に最大で500MB×2つまり1GB程度のメモリを消費するとのこと。これならメモリ不足になったことも理解できます。
通常こういった一時的に多くのメモリを消費する作業には仮想メモリを利用します。Linuxでいうスワップですね。
ということでClamAVが起動するに十分な量のスワップ領域を作成します。
ひとまず構成を確認
# vi /etc/fstab
/dev/vda1 / ext3 defaults 1 1
/dev/vdb swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
「/dev/vdb」にswapがあります。どうやらこれでは足りなかったようです。「/swapfile」というスワップファイルを追加するべく最後の行に以下を追加。
/swapfile swap swap defaults 0 0
ddコマンドでスワップファイル「/swapfile」を作成
# dd if=/dev/zero of=/swapfile bs=1024K count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 62.7715 s, 17.1 MB/s
ざっくり解説するとifの内容をofに書き込んでいます。ちなみに/dev/zeroは0でファイルを埋めています。サイズはbsかけるcountで、1024Kのファイルを1024カウント分、つまり合計1073741824 bytesです。
権限変更
$ chmod 600 /swapfile
スワップ領域を作成
$ mkswap -f /swapfile
スワップ領域を有効にする
$ swapon /swapfile
スワップが正しく設定できたか確認
$ swapon -s
Filename Type Size Used Priority
/dev/vdb partition 1048572 490288 -1
/swapfile file 1048572 0 -2
無事「/swapfile」が作成されています。priorityとあるので、「/dev/vdb」がいっぱいになったら「/swapfile」を使う感じですね。
メモリサイズを確認
$ free
total used free shared buffers cached
Mem: 1920268 1794016 126252 139928 61836 525804
-/+ buffers/cache: 1206376 713892
Swap: 2097144 490288 1606856
無事Swapの項目が合計の2GBになってます。
clamdが起動できるかテストします。
# /etc/init.d/clamd start
Starting Clam AntiVirus Daemon: [ OK ]
これで無事にclamdが起動しました。
アップデート後にfreshclamを実行するとエラー
万事解決と思いきやfreshclam時にもエラーが出るようです。
ERROR: Can't create temporary directory /var/lib/clamav/clamav-ad7315d02d042720ae5290a4c7a2f8a6.tmp
これは以前も直した経験のあるテンポラリーディレクトリの所有権の問題です。
# chown 495:493 /var/lib/clamav
所有権がclamavとなっているところをclamにするという設定です。(所有権は実行者や設定に合わせて適宜変更してください。)
clamAVのややこしいところは、このへんの所有権をバージョンアップごとに変更することです。作者にも思惑があるのかもしれませんが、定義ファイルの更新は普通cron等で自動実行しているため、書き換えが面倒ですね。
以上、ClamAVがメモリ不足で自動停止する問題と、バージョンアップ時の諸問題の解決方法でした。