japan.internet.com The Internet & IT Network


RSSニュース検索
カテゴリ
> トップページ
> Webビジネス
> Eコマース
> Webファイナンス
> Webマーケティング
> パブリック
> Webテクノロジー
> 携帯・ワイヤレス
> Linux Today
> Linux Tutorial
> J.I.C.ブログ
キャリア
> 転職ならen
> 派遣ならen
> アルバイトならen
> IT求人情報
ヘッドライン
> 今日のヘッドライン
> 週間ヘッドライン
Special Link
> フォトコミュニティ
> ストックフォト
> クリップアート
> イラスト
> フェリカ
> Web2.0
> 写真
イベント&セミナー
> イベントカレンダー
> 書評「IT の耳」
> 出張・接待検索
> ニュースガジェット 注目
無料ニュースメール
> 新規登録
> 変更・解除
> オプトインメールの登録・変更・解除
インフォメーション
> パートナーサイト
転職ならエン
就職ならen
求人ならen
履歴書ならen
アルバイトならエン
CRM/SFAならオラクル
> 会社概要地図
> グループ会社
株式会社アエリア
(株)サンゼロミニッツ
株式会社エアネット
> お問い合わせ
> 広告掲載について
> リンクについて
> 著作権について
> その他お問い合わせ
> 利用規約
> 個人情報保護方針
デベロッパー 2008年3月14日 10:00
デベロッパー・バックナンバー
JEEアプリケーションでのファイルのウイルススキャンの実装

著者: Vlad Kofman  オリジナル版を読む プリンター用 記事を転送
2008年3月14日 10:00 付の記事
海外internet.com発の記事
このエントリーを含むはてなブックマーク この記事をクリップ! Buzzurlにブックマーク Yahoo!ブックマークに登録 newsing it!

はじめに

 この記事では、Java(JEEアプリケーション)でファイルのアンチウイルススキャンを実装する方法の一例を紹介します。現在のコンピュータ環境、特にWindowsオペレーティングシステムでは、ウイルスやトロイの木馬をはじめとするさまざまなマルウェアやスパイウェアが大きな問題となっています。

 Javaで開発するアプリケーションに、外部からファイルをアップロードできるようにするという要件がある場合、セキュリティリスクが生じる可能性があります。ここで言うアップロードとは、HTTPプロトコルなり他の方法なりを使って、何らかの形で企業のファイアウォール内に外部のファイルを送れるようにすることを指します。こうした要件はエンタープライズアプリケーションでは非常によくあるもので、しかもJavaは最も広く使われているWeb開発プラットフォームの1つです。にもかかわらず、このように大きく口を開けたセキュリティリスクが往々にして見過ごされているのは、残念なことです。

 Java Development Kit(JDK)には、アンチウイルススキャンのための機能は標準装備されていません。その理由として大きいのは、Javaはプログラム言語であり、ウイルススキャンのパッケージを備えていないということです。しかも、アンチウイルスソフトウェアはSunの専門外ですし、同社のビジネスモデルにも含まれていません。ウイルス対策のソフトウェア(あるいはJavaパッケージ)を開発することや、さらに重要な、維持やメンテナンスを続けていくことは、Sunにとってかなりの重荷です。ウイルスは常に進化を続けていくので、ウイルス定義を最新の状態に維持していくのは骨の折れる作業です。ウイルスの検出と対処を行うための製品は、McAfee、Symantec、Zone Labsなどの大企業が開発し、多大なリソースを投入してそのメンテナンスにあたっています。

アプリケーション環境

 Javaでファイルのウイルススキャンを実装するには、サードパーティ製のパッケージを利用する必要があります。この記事では、Java APIを備えたSymantec Scan Engine(SSE)パッケージを使うことにします。このパッケージは、TCP/IPサーバーとして動作するアプリケーションです。プログラミングインターフェイスが用意されており、コンテンツのスキャン技術をJavaアプリケーションに組み込むことができます。この記事ではSymantec Scan Engine 5.1を使用します。この製品には、UNIX版とWindows版の両方があります。

 他社製のアンチウイルスパッケージを使用する場合は、どんなAPIが用意されているかは各自で調べてください。もっとも、基本的なアプローチは似ているはずです。また、ここで紹介する実装方法は、使用するJEEテクノロジは問わず、最近のMVCフレームワーク(StrutsやSpringなど)に対応しています。

 アーキテクチャは次のようになります。まず、SSEを常時稼動するサーバーマシンが必要です。アプリケーションサーバーをホストするマシンと同じにすることもできますが、エンタープライズ環境の場合は、別のマシンにすることをお勧めします。また、ファイアウォールでデフォルトポートを開けておき、スキャンエンジンと通信できるようにしておく必要があります。ファイルスキャンを行う必要があるすべてのJEEアプリケーションは、デフォルトポートを通じてSSEサーバーマシンと通信できます。なお、別々のアプリケーションサーバーで稼動している複数のアプリケーションが同じスキャンサーバーを共用することもできます。詳細については、SymantecのWebサイトにある、Symantec Scan Engine(SSE)のインストールガイドを参照してください。

 スキャンが必要な外部ファイルを、プログラミングインターフェイス(デフォルトポートを使用するJava API)を使用してSSEに送信すると、そのファイルに対する他の操作を行う前に、SSEから結果コードが戻ります。たとえば、Webメール型のアプリケーションで、外部ユーザーが添付ファイルとしてファイルをアップロードしたとします。この場合、アプリケーションは、SSEのAPIを呼び出し、OKかNGかを示すリターンコードに基づいて、アップロードの結果を判断し、その電子メールを実際に送信してよいかどうかを決定します。Yahooメールのアカウントをお持ちの方なら、Norton Antivirusですべての添付ファイルがスキャンされるのを見たことがあるかもしれません(Javaを使った実装ではありませんが)。

図1 Yahooのスクリーンショット
図1 Yahooのスクリーンショット

 サーバーへのScan Engineのインストールの詳細については、Symantecのサイトにある、Symantec Scan Engine(SSE)実装ガイドを参照してください。

 SSEについて頭に入れておくべきポイントを以下にまとめます。

  • SSEをインストールする前に、サーバーにJava 2 SE Runtime(JRE)5.0 Update 6.0以降をインストールする必要があります。
  • インストール後に、Symantec Scan Engineデーモンが稼動していることを確認してください。UNIX版の場合、UNIXのコマンドプロンプトで次のコマンドを入力します。
  • ps -ea | grep sym.
    
    次のようなプロセスのリストが表示されます。
    • 5358 ? 0:00 symscan
    • 5359 ? 0:00 symscan
    何も表示されない場合、SSEプロセスは起動していません。
    SSEプロセスが起動しなかった場合、次のコマンドを入力してSSEを再起動します。
    /etc/init.d/symscan restart
    
  • 常に最新のウイルス定義を適用しておくことが最も重要な責務です。最新のデータがインストールされていないと、スキャン全体の実効性がなくなります。Symantec製品では、LiveUpdate機能によって、最新のファイル定義が自動的にダウンロードされます。ホストサーバーがSymantecの更新サービスに接続できるようにファイアウォールのルールを設定しておいてください。

プロジェクトのセットアップ

 この記事のために、Symantec SSE APIのラッパーとなる「av.jar」を用意しました。SymantecのJava APIを使用し、SSEサーバーのクライアントとして機能して、サーバーとのすべての通信を担います。「av.jar」は、本稿の冒頭のリンクからダウンロードできます。SSEに対して「av.jar」を使用するには、これをJava CLASSPATHに含める必要があります。このjarにはAVClientというクラスが含まれています。これは、SSEに対してバイト列でファイルを送信し、結果を返すという処理そのものを行うクラスです。

 私のプロジェクト設定では、System.getPropertyを通じてアクセスする3つの変数を追加しています。次のような変数です。

AV_SERVER_HOST=192.168.1.150
AV_SERVER_PORT=''1344''
AV_SERVER_MODE=SCAN

 AV_SERVER_HOSTはScan Engineがインストールされているマシンのホスト名またはIPです。

 AV_SERVER_PORTはScan Engineが受け取るファイルをリッスンするポートです。

 AV_SERVER_MODEはスキャンモードで、次のいずれかです。

  • NOSCAN ― スキャンを行いません(先頭が"SCAN"以外のどのキーワードを指定しても、Scan Engineの呼び出しは無視され、ファイルの転送とスキャンは行われません)。
  • SCAN ― ファイルまたはバイトストリームをスキャンしますが、感染の修復は行いません。
  • SCANREPAIR ― ファイルをスキャンし、感染の修復を試みますが、それ以外の処理は行いません。
  • SCANREPAIRDELETE ― ファイルをスキャンし、感染の修復を試みます。修復できないファイルは削除します。
 ファイルストリーム(バイト列)のスキャンの場合、有効な値はSCANとNOSCANのみです。

SSEでスキャンを行うJava APIの使用

 スキャンを行うクラスでは、「av.jar」内のAVClientオブジェクトに備わっているスキャンAPIを呼び出します。AVClientオブジェクトはScan Engineサーバーへの接続を確立し、以下のAPIを含みます。

図2 Scan Engineサーバーと通信するための主なAPI
図2 Scan Engineサーバーと通信するための主なAPI

 スキャンの対象がファイルシステム上のファイルで、SCANモード(スキャンのみのモード)を使用する場合は、パラメータとしてファイル名のみを受け取るメソッドを呼び出します。

 スキャンの対象がファイルシステム上のファイルで、SCANREPAIRモードまたはSCANREPAIRDELETEモードを使用する場合は、入力ファイル名と出力ファイル名を受け取るメソッドを呼び出します。

 スキャンの対象がメモリ内のファイル(バイト列)の場合は、バイト列を受け取るメソッドを呼び出します。

 サンプルコードを以下に示します。

import com.av.*;

 設定パラメータを初期化します。

static String avMode =
   (System.getProperty("AV_SERVER_MODE") != null)
   ? (String) System.getProperty("AV_SERVER_MODE") : "NOSCAN";

static boolean scan = avMode.startsWith("SCAN");

static String avServer =
   (String) System.getProperty("AV_SERVER_HOST");

static int avPort =
   Integer.parseInt( (String) System.getProperty("AV_SERVER_PORT"));

 メモリ内ファイルのバイト列をスキャンしてチェックする例です。

public void scanFile(byte[] fileBytes, String fileName)
   throws IOException, Exception {

   if (scan) {
      AVClient avc = new AVClient(avServer, avPort, avMode);
      if (avc.scanfile(fileName, fileBytes) == -1) {
         throw new VirusException("WARNING: A virus was detected in
            your attachment: " + fileName + "<br>Please scan
            your system with the latest antivirus software with
            updated virus definitions and try again.");
      }
   }
}

 MVCハンドラ内でこのコードを使用する場合は、カスタムのVirusExceptionをスローでき、呼び出し側のメソッドでこれをチェックして必要なクリーンアップ処理を実行できます。このクラスも「av.jar」に含まれています。

 使用例を次に示します。

catch (Exception ex) {
   logger.error(ex);
   if (ex instanceof VirusException) {
      // do something here
   }
   else {
      // there was some other error - handle it
   }
}

 Scan EngineのクライアントAPIの詳細については、Symantec Scan Engineソフトウェア開発者ガイドを参照してください。

SSEの応答コードと通知オプション

 SSEに接続できなかった場合や、SSEライセンスが無効になったり有効期限が切れたりした場合に備えて、Javaコードには、システムサポート担当者に送信する通知や電子メールを自動生成するためのフックが必要です。こうした通知を生成する機能を使用するためには、アンチウイルスのクライアントコードをアプリケーションに組み込むときに、javamailやその他の電子メールパッケージを使用することが必要な場合があります。AVClientオブジェクトのconnect (String host) API、およびヘルパークラスAVRespondのrequest(String server_response)メソッドを参照してください。

 コードの一覧を以下に示します。

  • private String one = "ICAP/1.0 100";
  • private String two = "ICAP/1.0 200";
  • private String three = "ICAP/1.0 201";
  • private String four = "ICAP/1.0 204";
  • private String five = "ICAP/1.0 400";
  • private String six = "ICAP/1.0 403";
  • private String seven = "ICAP/1.0 404";
  • private String eight = "ICAP/1.0 405";
  • private String nine = "ICAP/1.0 408";
  • private String ten = "ICAP/1.0 500";
  • private String eleven = "ICAP/1.0 503";
  • private String twelve = "ICAP/1.0 505";
  • private String thirteen = "ICAP/1.0 533";
  • private String fourteen = "ICAP/1.0 539";
  • private String fifteen = "ICAP/1.0 551";
  • private String sixteen = "ICAP/1.0 558";

 私は、SSEサーバーからの応答文字列に、ライセンスの有効期限切れに対応する文字列「ICAP/1.0 558」を追加しました。対応が必要な主なコードには、ウイルスを示すtwoとthree、およびファイルが異常なしであることを示すfourがあります。

 応答コードの定義の一覧については、Symantec Scan Engineソフトウェア開発者ガイド(表3-4の状態コード)を参照してください。

 ライセンスが無効の場合に管理者に電子メールを送信するには、次のようにします。

if (server_response.equals(fourteen) ||
   server_response.equals(sixteen)) {
   // license is bad
   // if you want to let files through without actually scanning
   the_return = "''clean''";
   // send email - this must be working if option is "clean"
   String body = "Note the license for Symantec Scan Engine is
                 invalid or has expired!¥n¥rPlease see - class
                 AVRespond for more info.¥n¥rThis email is sent
                 every time a client uploads an un-scanned file";
   try {
      sendMail("symantec_scan_engine@mycompany.com",
               "YOU@mycompany.com", "Invalid or expired license for
               Symantec Scan Engine", body);

   }
   catch (Exception ex) {
      logger.error("AV client could not send email notification¥nMake
                    sure properties has ¥"mail.smtp.host¥" entry in
                    it ¥n " + ex);
   }
}

まとめ

 この記事では、JEEアプリケーションにファイルのアンチウイルススキャン機能を組み込む方法について説明しました。驚いたことに、このしくみについて知っている開発者はあまり多くありません。外部ファイルをスキャンせずにおくことはセキュリティリスクとなり得るにもかかわらずです。

 現在のところ、スキャン処理の実装はサードパーティベンダごとに固有で、独自のJava APIを備えた製品を利用することになります。Java開発者としては、スキャンAPIの標準プロトコルをSunが策定して、各ベンダに準拠してもらう形になった方がうれしいと思います。ちょうど、Java Messaging Service(JMS)プロトコルの場合と同じようにです。エンタープライズ分野におけるスキャン処理は、JMSほどの存在感はないにせよ、一部のエンタープライズアプリケーションにとって重要な側面であることは間違いありません。

関連情報

著者紹介

Vlad Kofman(Vlad Kofman)
ウォールストリート有数の企業でエンタープライズレベルのプロジェクトに携わる。また、米国政府の防衛関連の仕事も手がけている。特に関心を寄せているのは、オブジェクト指向プログラミング方法論、UI、デザインパターン。
★最新トップニュース
国内 Adobe Flash Player 10 パブリックベータ版を公開(Webテクノロジー 5月16日 18:10)
米国 Adobe Systems は、2008年5月15日、「Adobe Flash Player 10」(コードネーム:Astro)のパブリックベータ版を Adobe Labs で公開したことを発表した。
国内 【今週の Web ミミズク】CBS の高価な買い物、グリッドは地球を救えるか、四川州地震のネット募金(Webファイナンス 5月16日 18:00)
今週のビッグニュースは、なんといっても、CBS による CNET の買収だ。買収総額は18億ドル、だそうだが、この金額は高いか、安いか。
国内 TI、WUXGA 対応の「.95 WUXGA DLP チップ」を発表、対応 DLP プロジェクタ製品も登場(Webテクノロジー 5月16日 17:50)
Texas Instruments(TI)は、2008年5月13日、同社初となる1,920×1,200ピクセルの解像度を持つ WUXGA プロジェクタ向けの「.95 WUXGA DLP チップ」を発表した。
国内 社会保険庁の国民年金保険料クレジットカード収納業務を GMO-PG が受託(パブリック - ニュース 5月16日 17:30)
非対面クレジットカード決済事業を展開する、GMO ペイメントゲートウェイ株式会社(GMO-PG)は、2008年8月1日から2009年3月31日まで、社会保険庁の国民年金保険料のクレジットカード収納に係るカード番号管理等の業務を受託すると発表した。
海外 【中国】中国移動、中国 TD 規格を5月末に 3.5G 規格にアップグレード(携帯・ワイヤレス 5月16日 17:00)
5月15日、中国国内メディアの報道によれば、中国移動(チャイナ・モバイル)は5月末に TD 規格(TD-SCDMA:中国独自の 3G 通信規格)を3.5G 規格(TD-HSDPA)にアップグレードさせることを明らかにしたという。
トピックス
> オススメのIT系求人情報【毎週月曜日更新】
footer_301.gif


リサーチ
> デイリーリサーチDLサイト
> OnlineResearchPortal (リサーチデータバンク)
> モバイルリサーチ with goo
footer_301.gif
キーワード
> Youtube > BlackBerry
> CGM > SaaS
> アクセス解析 > LPO
> テーマ一覧はこちら
footer_301.gif
セミナー情報
> 第1回インターネットコムマーケティングセミナー「新規クライアントを効率的に獲得する Web マーケティング手法とは」(3月26日)多数のご参加ありがとうございました
footer_301.gif
デベロッパー
> DevX
> CodeGuru
> developer.com
footer_301.gif
j.i.c.ブログ
ブログ一覧
Graphic Design Forum 【Graphic Design Forum】
経済の混乱とフリーランス (5月16日)
データメーション 【データメーション】
IT 業界の女性について:(ハッと息をのむ)ある少女の観点(5月16日)
ジュピターメディア創設者がITを斬る 【ジュピターメディア創設者がITを斬る】
CNET が CBS に買収(5月16日)
ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」 【ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」】
「微生物、たんぱく質に隠された無限の可能性に挑戦!!」/株式会社サティス製薬(5月16日)
japan.internet.com テクノログ 【japan.internet.com テクノログ】
5月4日(日)〜5月10日(土)(5月13日)
最新テクノロジーの意外な処方箋 【最新テクノロジーの意外な処方箋】
アクセンチュア・テクノロジー・ラボプロジェクト:REST(Reducing Effort in Script-based Testingスクリプトテストの負荷軽減)(5月12日)
footer_301.gif
最新コラム一覧
IT マネジメント IT マネジメント

Steve Ballmer 氏が辞任すべき理由(5月16日)
15 seconds 15 seconds

AJAX SlideShowおよびTreeViewコントロールを使用してスライドショーを作成する(5月16日)
最新アフィリエイト事例にみる成功の法則 最新アフィリエイト事例にみる成功の法則

アフィリエイト市場動向(5月16日)
最新ハイテク講座 最新ハイテク講座

全自動からオゾンの力まで!ハイテク洗濯機の最新事情(5月16日)
百式のネットビジネス研究 百式のネットビジネス研究

手書き入力で中国語を検索できる辞書サイト「nciku」(5月16日)
週刊-サイト別アクセス状況データ 週刊-サイト別アクセス状況データ

ビデオリサーチインタラクティブ調査(月間インターネットオーディエンスデータ)(5月15日)
「IT の耳」 「IT の耳」

【書評】『ウェブを変える10の破壊的トレンド』(5月15日)
検索エンジンマーケティング 検索エンジンマーケティング

中国検索エンジン市場シェアを巡る攻防(5月15日)
気になるオープンソースソフトウェア 気になるオープンソースソフトウェア

オープンソースのアプリケーションサーバー Apache Geronimo(5月15日)
気になるトレンド用語 気になるトレンド用語

ネットの危機?自由が奪われる「青少年インターネット規制法案」(5月14日)
footer_301.gif
専門チャンネル
> セキュリティチャネル > テレコムチャネル
> サーチエンジンウォッチ
footer_301.gif
海外のインターネットコム アメリカ韓国ドイツトルコ
関連企業のサイト:ストックフォト イラスト ネットストリート ホテル予約サイト タウン情報 出張 事業継承 シミュレーション トランクルーム 優待映画チケット 田舎暮らしガイド オリジナルTシャツ ニタコエ
Copyright 2008 Jupitermedia Corporation All Rights Reserved. http://www.internet.com/
space.gif space.gif