ClamAVのデーモン化

[前回](http://qiita.com/todaemon/items/8616a89d9fc9c408c081)の続きです。

今回はウイルス検知処理をデーモン化するのと、ウイルス定義ファイルの自動更新するところをまとめますね。

## 1. ウイルススキャン処理のデーモン化
デーモン化にはclamdというパッケージが必要です。yumでインストールします。

```shell-session
# yum install clamd
Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
 * epel: ftp.kddilabs.jp
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package clamd.x86_64 0:0.98.1-1.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

==============================================================================================================
 Package                 Arch                     Version                        Repository              Size
==============================================================================================================
Installing:
 clamd                   x86_64                   0.98.1-1.el6                   epel                   150 k

Transaction Summary
==============================================================================================================
Install       1 Package(s)

Total download size: 150 k
Installed size: 563 k
Is this ok [y/N]: y
Downloading Packages:
clamd-0.98.1-1.el6.x86_64.rpm                                                          | 150 kB     00:00
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : clamd-0.98.1-1.el6.x86_64                                                                  1/1
  Verifying  : clamd-0.98.1-1.el6.x86_64                                                                  1/1

Installed:
  clamd.x86_64 0:0.98.1-1.el6

Complete!
#
```

サクッとインストできました。

clamdはサービス起動スクリプトが用意されているので、serviceコマンドで起動しましょう。またchkconfigで自動起動するようにしておきます。

```shell-session
# /sbin/service clamd start
Starting Clam AntiVirus Daemon:                            [  OK  ]
# chkconfig clamd on
```

ウイルススキャンはclamdscanコマンドを使います。

```shell-session
# clamdscan /bin/
/bin/loadkeys: lstat() failed: Permission denied. ERROR
/bin/umount: lstat() failed: Permission denied. ERROR
/bin/ping: lstat() failed: Permission denied. ERROR
/bin/dmesg: lstat() failed: Permission denied. ERROR
/bin/rpm: lstat() failed: Permission denied. ERROR
/bin/ping6: lstat() failed: Permission denied. ERROR
/bin/login: lstat() failed: Permission denied. ERROR
/bin/hostname: lstat() failed: Permission denied. ERROR
/bin/tracepath6: lstat() failed: Permission denied. ERROR
/bin/tracepath: lstat() failed: Permission denied. ERROR
/bin/traceroute: lstat() failed: Permission denied. ERROR
/bin/dbus-daemon: lstat() failed: Permission denied. ERROR
/bin/alsaunmute: lstat() failed: Permission denied. ERROR
/bin/plymouth: lstat() failed: Permission denied. ERROR
/bin/mount: lstat() failed: Permission denied. ERROR
/bin/su: lstat() failed: Permission denied. ERROR

----------- SCAN SUMMARY -----------
Infected files: 0
Total errors: 16
Time: 0.034 sec (0 m 0 s)
#
```

(ﾟдﾟ)！おっと、権限の問題が発生です。
今回、clamdはclamユーザで起動しており、さらにSELinuxもEnforcingにしております。
/etc/clamd.conf を変更してclamdをrootユーザで起動してもいいのですが、ここはセキュリティのバランス加減でclamユーザのままにしておき、システム系のファイルもチェックしてもらうよう変更します。

/var/log/audit/audit.logを確認すると、clamdのアクセスがdeniedされているログがあるので、それをaudit2allowに食わせてみましょう。

```shell-session
# grep denied /var/log/audit/audit.log | grep clam | audit2allow

#============= antivirus_t ==============

#!!!! This avc can be allowed using the boolean 'antivirus_can_scan_system'
allow antivirus_t NetworkManager_var_lib_t:dir getattr;

#!!!! This avc can be allowed using the boolean 'antivirus_can_scan_system'
allow antivirus_t abrt_dump_oops_exec_t:file getattr;

#!!!! This avc can be allowed using the boolean 'antivirus_can_scan_system'
allow antivirus_t acct_exec_t:file getattr;
～省略～
#!!!! This avc can be allowed using the boolean 'antivirus_can_scan_system'
allow antivirus_t xdm_tmp_t:dir getattr;
```

すると多数のルールが出力されますが、よくよく見るとantivirus_can_scan_systemというBooleanを設定すればいけそうな雰囲気ですね。

念のためsesearchでantivirus_can_scan_systemをonにした時のルールを確認しときます。

```shell-session
# sesearch -b antivirus_can_scan_system -AC
Found 9 semantic av rules:
DT allow antivirus_domain device_node : chr_file getattr ; [ antivirus_can_scan_system ]
DT allow antivirus_domain device_node : blk_file getattr ; [ antivirus_can_scan_system ]
DT allow antivirus_domain file_type : dir { ioctl read getattr lock search open } ; [ antivirus_can_scan_system ]
DT allow antivirus_domain file_type : sock_file getattr ; [ antivirus_can_scan_system ]
DT allow antivirus_domain file_type : fifo_file getattr ; [ antivirus_can_scan_system ]
DT allow antivirus_domain device_t : dir { getattr search open } ; [ antivirus_can_scan_system ]
DT allow antivirus_domain non_security_file_type : file { ioctl read getattr lock open } ; [ antivirus_can_scan_system ]
DT allow antivirus_domain non_security_file_type : dir { ioctl read getattr lock search open } ; [ antivirus_can_scan_system ]
DT allow antivirus_domain non_security_file_type : lnk_file { read getattr } ; [ antivirus_can_scan_system ]
#
```

ではBooleanを設定します。

```shell-session
# setsebool -P antivirus_can_scan_system on
```

変更できたので再度/binをチェックしてみます。

```shell-session
]# clamdscan /bin/
/bin: OK

----------- SCAN SUMMARY -----------
Infected files: 0
Time: 0.051 sec (0 m 0 s)
#
```

成功です。
今回、clamユーザでのclamd起動とSELinuxがEnforcingという状態で動作させてます。
DACによる制御では、例えばrootのみ閲覧可能な/rootやログとかはチェックできませんし、またMACによる制御でもアクセスできないファイルがありますが、ClamAVとSELinux双方で守備するという考え方で、これでよしとしました。

まあ気になるファイルがある時は、rootユーザにてclamscanを手動で実行させましょう。


## 2. ウイルス定義ファイルの自動更新
freshclamのマニュアルを見ると、-dオプションと-cオプションを使うことでデーモン化して自動更新できるようです。

```shell-session
# man freshclam
freshclam(1)                    Clam AntiVirus                    freshclam(1)

NAME
       freshclam - update virus databases

SYNOPSIS
       freshclam [options]

DESCRIPTION
       freshclam is a virus database update tool for ClamAV.

OPTIONS
       Freshclam  reads its configuration from freshclam.conf. The settings can be overwritten with
       command line options.

～省略～
       -d, --daemon
              Run in a daemon mode. This option requires --checks.  -p FILE, --pid=FILE Write  dae-
              mon’s pid to FILE.

       --no-dns
              This option forces old non-DNS verification method (without a TTL delay).

       -c #n, --checks=#n
              Check #n times per day for a new database. #n must be between 1 and 50.
～後略～
```

1日1回の頻度でチェックするよう起動しておきました。

```shell-session
# freshclam -d -c 1
# ps -ef | grep fresh
clam     17534     1 64 09:28 ?        00:00:02 freshclam -d -c 1
root     17536 17327  0 09:28 pts/0    00:00:00 grep fresh
#
```

またOS再起動時にもfreshclamが起動するよう /etc/rc.local へ下記を追記してます。

```/etc/rc.local
/usr/bin/freshclam -d -c 1
```

あと順番が前後してしまうのですが、freshclamで定義ファイルを更新したら、clamdにそれをRELOADしてもらう必要があるので、連携が必要です。
freshclam.conf にその設定パラメータがあるので、clamdの設定ファイルを指定するよう変更しておきましょう。

```/etc/freshclam.conf
# Send the RELOAD command to clamd.
# Default: no
NotifyClamd /etc/clamd.conf
```

設定ファイルを変更したので再起動します。

```shell-session
# killall freshclam && freshclam -d -c1
```

※後で気付いたのですが、/etc/cron.daily/freshclamというファイルが配置されているので、1日1回のアップデートならcronに任せちゃうのがいいですね。なのでrc.localの自動起動も不要です。

## 3. 活用
とりあえず入れてみたという手順なので、運用めいたことは考えてないのですが、clamdでデーモン化しておくことで、メールのウイルスチェックをしたり、外部からSTREAMでデータを流してウイルスチェックしてもらうことができるようですね。

ClamAVのパッケージはマニュアルがしっかりしているので、clamdやclamd.confのmanを見て使えそうなプラクティスを探ってみます。

ではでは。