よかろうもん!

アプリからインフラまで幅広くこなすいまどきのクラウドエンジニアが記す技術ブログ

RailsアプリケーションにてClamAVを利用してリアルタイムにウィルス・スキャンを実現する方法

ファイルのアップロード機能を有するアプリケーションを運用している場合は、ウィルスに感染したファイルがアップロードされることを考慮する必要があります。

もし何も対策していない場合、ウィルスに感染しているファイルがアップロードされ、そのファイルをファイル所有者以外がダウンロードすることで、2次被害が発生してしまうかもしれません。

そのような事態を避けるためにも、ファイルがアップロードされた時点でウィルス・スキャンを実施し、感染ファイルにはなるべくアクセスできないようにすべき構成にすることが望ましいです。

では、ファイルがアップロードされた際にリアルタイムにスキャンするにはどうしたらよいでしょうか?
アプライアンス製品や有償のツールを使うことで簡単に実現可能ではありますが、今回は、オープンソース・ソフトウェアのClamAVを利用して、リアルタイム・ウィルス・スキャンを実現する方法を紹介します。

はじめにClamAVって何?どうやってインストールすればいいの?という方は、以下をを読むと大体のことはわかるかと思います。

まずはRubyからClamAVを利用するための方法を紹介します。
解説する内容を応用することで、Railsアプリケーションでファイルがアップロードされた時にリアルタイムにウィルス・スキャンが可能となりますので、ぜひ試してみてください。

では、早速ClamAVRubyから操作できるようにするためのツールを紹介します。

その名の通り、"clamav"という gem がこちらで提供されており、この gem がRubyClamAVをつなげるruby bindingです。

"clamav"を導入する際の注意点として、このgemが動作するために必要となる環境は、以下のようになっています。

clamav >= 0.95.3, libclamav6, libclamav-dev
clamav >= 0.96 is recommended

インストールしてるClamAVのバージョンが上記以下の場合は、自身でsourceをダウンロードしてインストールする必要があります。

ClamAVがインストールされている場合、以下のコマンドでバージョン情報を確認することができます。

$ clamav-config --version
0.96.1

※参考情報として、ubuntu 10.04 (Lucid Lynx)のパッケージ・リポジトリでは、VERSION=0.96.1のClamAVが提供されています。

それでは、導入方法を解説します。

インストールする方法はいつものように以下のコマンドを発行します。

$ sudo gem install clamav

このとき、libclamav-devに該当するパッケージがインストールされていないと、インストール時にエラーとなります。

これで環境が整いました。
では、Rubyの式を標準入力から簡単に入力/実行するためのツールである irb で使い方を解説します。

interu@ubuntu:~$ irb
irb(main):001:0> require 'clamav' #clamavライブラリ(gem)をロード
=> true
irb(main):002:0> clam = ClamAV.instance #clamavインスタンスオブジェクトを生成
=> #
irb(main):003:0> clam.version #clamavのバージョン確認
=> "0.96.1"
irb(main):004:0> clam.loaddb #clamavのウィルス定義をロード
=> false

irb(main):005:0> clam.scanfile("/home/interu/sample_file.pdf")
=> 0
irb(main):006:0> clam.scanfile("/home/interu/eicar.com")
=> "Eicar-Test-Signature"
irb(main):007:0> clam.scanfile("/home/interu/non_exist_file_path.txt")
=> 8

scanfileメソッドで3つのファイルをスキャンしていますが、スキャンの結果は以下のようになっています。

  • ウィルスを含まないファイル : 戻り値は "0"
  • ウィルスを含んでいるファイル: 戻り値は "検出されたウィルスの名称"
  • ファイルパスが間違っている : 戻り値は "8"

※擬似ウィルスファイル(eicar.com)は、${GEM_INSTALL_PATH}/clamav-0.4.1/spec/clamav-testfiles 以下に含まれています。

Railsアプリケーション上でファイルが何らかのファイルがアップロードされたら、上記で示した手順で該当のファイルをスキャンすることでリアルタイム・スキャンを行うことができるようになります。

ちなみに、ファイルアップロードプラグインとして paperclip を利用している場合は、こちらに解説されているように before_post_process や after_post_process でウィルス・スキャンを行うようなメソッドを定義し、ウィルスを検出した場合は、 self.my_attribute = "x" のようにフラグを立てるようにしたらよいでしょう。

今回は、ClamAVを利用する方法を紹介しましたが、他のアンチウィルス・ソフトウェアであっても、Rubyから操作できるような仕組みが提供されているのであれば、オンライン・スキャンは実現可能ですので。