CAPTCHAによるBBSスパム対策


BBSに対するスパム対策がイタチゴッコになってきたので、文字画像に記載された文字を投稿時に確認キーとして入力してもらうことにより自動入力を遮断することにしました。文字画像作成にはImageMagickを使いました。
これにより、現時点でOCR機能を持った高度なツールは無いようなので自動入力による書込み(主に海外からの書込み)は100%遮断できています。但し、日本語の書込みの中にはご丁寧に人間系でやっている例がまれにあるため、本対策だけで完全遮断できるわけではありません。従って、他の対策も併用する必要があり、おやじは追加でかなりの対策(非公開)を行っています。

■ImageMagick のインストール

WindowsXP、SuSE9.3/10.2、CentOS4.4でのImageMagickのインストール方法を示します。なお、WWWサーバでCGIの掲示板が動作していることが前提です。

◆WindowsXP へのインストール

WindowsXPにImageMagickをインストールするには、バイナリパッケージをダウンロードしてインストールするだけです。
  1. Windows用のバイナリパッケージを下記からダウンロードしてくる。NTベースならNT4〜Vistaまで対応してる。いくつか種類があるので注意が必要である。

    ・ImageMagickのサイト: http://www.imagemagick.net/script/binary-releases.php#windows

    ・パッケージ: ImageMagick-6.3.3-10-Q16-windows-dll.exe (Win32 dynamic at 16 bits-per-pixel)

  2. インストールは、ダウンロードしてきたファイルを実行し、指示に従って、というより全てデフォルトのまま作業を実行していけば良いだけである。
    但し、下記のインストールする内容の選択のところでは、「Install PerlMagick for ActiveState Perl v5.8.8 build xxx」を追加で選択すること。



◆SuSE9.3/10.2 へのインストール

SuSE には、ImageMagick の RPM があるので、YaST でインストールするだけです。

  1. YaST コントロールセンタを起動し、「ソフトウェア」の「ソフトウェアのインストール/削除」を起動する。
  2. 「フィルタ」 を 「検索」 とし検索欄に 「imagemagick」 と入力し 「検索」 ボタンを押す。
  3. 右側に該当するパッケージが出てくるので、その中の以下のものにチェックマークを入れて 「了解」 を押しておしまい。
    C++インタフェースはとりあえずは不要ですが、コマンドでいろいろできるので入れておくといいと思います。
    • ImageMagick
    • perl-PerlMagick perlインタフェース
    • ImageMagick-Magick++ C++インタフェース


◆CentOS4.4 へのインストール

CentOSにはImageMagick の RPM があるので、yum でインストールするだけです。C++インタフェース(ImageMagick-c++)はとりあえずは不要ですが、コマンドでいろいろできるので入れておくといいと思います。

# yum install ImageMagick ImageMagick-perl ImageMagick-c++



■掲示板CGIの改造

掲示板CGIはいろいろあるので、ここではおやじが使用しているKENT WEBさんの「Web Forum」を例に改造例を示します。なお、最新版の「Web Forum」では類似の画像による対策がされており、数字限定ですが処理が軽いのでそのまま利用すれば良いと思います。おやじは改造しまくっているので、簡単に乗り換えられませんが・・。

◆ImageMagickを利用した画像表示スクリプトのインストール

前提条件として、「Web Forum」は既にインストールされ稼動確認ができているものとします。
  1. おやじが作成したスクリプト類のアーカイブをダウンロードして解凍し、「Web Forum」のディレクトリにコピーする。下記のNo.1と2は確認キーのバックグラウンドで使用するランダムノイズのキャンバス及びそれを作成するためのスクリプトなので使用しないのならコピー不要。
    スクリプト類のアーカイブは、lzh形式tar.gz形式があるので、適宜ダウンロードする。

    No. ファイル名 概 要
    1 bg.gif 文字画像用のバック用のランダムドット画像(70×22)
    2 bg_gen.cgi 上記画像を作成するスクリプト(オンラインでは未使用)
    3 image_gen.cgi 確認キーの画像を表示するスクリプト
    4 keyinit.pl ランダムキー関係のモジュールと各種設定
    ゆいさんの簡易暗号化サブルーチン
    ( http://www.cup.com/yui/ )

  2. bg_gen,cgi(必要時)とimage_gen.cgiのperlのパスを環境に併せて変更する。

  3. 続けて「Web Forum」を改造するが、「Web Forum v5.02」の場合、改造するのは「init.cgi」と「regist.cgi」である。
    *:行番号は改造前の番号を示す。

    [init.cgiの改造]

    1. 61行目の次に下記(ライブラリファイルのパス)を追加する。他のライブラリと同様に「lib」ディレクトリ配下に設置する場合は、関連する「image_gen.cgi」も変更が必要になる。

      # ライブラリファイル【サーバパス】
      $jcodepl = './lib/jcode.pl';
      $foldpl = './lib/fold.pl';
      $regkeypl = './lib/registkey.pl';
      $keyinitpl = './keyinit.pl';

         (snip)


    2. 「Web Forum v5.02」のスパム対策を停止するため、198行目にある「$regist_key = 1;」を「$regist_key = 0;」に変更する。

    3. 548行目の次に下記(確認キーの入力表示)を追加する。

      </tr>
      EOM

         # 確認キー
         require "$keyinitpl";
         $ciphertext = &en_key;

         print <<EOM;
      <tr valign="top">
         <td><b>確認キー</b><br><img src="./image_gen.cgi?$ciphertext" alt="確認キー"></td>
         <td><font color="red">投稿時、左に表\示されている$len文字($charset[$chr])を入力してください。</font><br>
         <input type=text name=chk size=8 value="" maxlength=8> (確認キーは表\示後<font color="red">$ef_time分間のみ有効</font>です。)</td>
         <input type=hidden name=ciphertext value="$ciphertext">
         </tr>
      EOM


         # 投稿キー
         if ($regist_key) {

    [regist.cgiの改造]

    1. 14行目の次に下記(ライブラリファイルのパス)を追加する。

      # 外部ファイル取り込み
      require './init.cgi';
      require $jcodepl;
      require $foldpl;
      require $keyinitpl;

         (snip)


    2. 33行目の次に下記(確認キーのチェック処理)を追加する。

         # 入力チェック
         &chk_form;

         # 確認キーチェック
         &key_chk($in{'chk'},$in{ciphertext});


         # 投稿キーチェック
         if ($regist_key) {

    3. 232行目の次にも同様に下記(確認キーのチェック処理)を追加する。

         # 入力チェック
         &chk_form;

         # 確認キーチェック
         &key_chk($in{'chk'},$in{ciphertext});


         # 投稿キーチェック
         if ($regist_key) {

    4. 274行目の次に下記(確認キーと暗号化キー)を追加する。

      <input type="hidden" name="wrap" value="$in{'wrap'}">
      <input type="hidden" name="message" value="$in{'message'}">
      <input type="hidden" name="chk" value="$in{'chk'}">
      <input type="hidden" name="ciphertext" value="$in{ciphertext}">

      EOM

      # 投稿キー
      if ($regist_key) {

■チューニング

取り敢えずはデフォルトのままで、動作させて見てください。想定どおりならそのままでよいですが、イメージと異なる場合はチューニングしてください。

◆ランダム画像の生成の仕組み

どうやって、ランダム画像の生成される過程が不明だとチューニングできないと思いますので、主に「image_gen.cgi」の動作(設定は「keyinit.pl」)について簡単に示します。但し、どうやって表示しているかは説明しませんので、必要ならCGIを読んでください。
  1. 「image_gen.cgi」では、外部からコールされるとクエリ(CGIの?以降)で渡された暗号化された確認キーをデコードし、その文字を画像化します。

  2. まず、バックグラウンドとなるキャンバスを作成する。キャンバスは単色のものを自動生成するか、バックグラウンド画像を取り込むことができる。画像サイズは波型加工することを想定し、高さ方向は最終的な画像+α(20程度。字の大きさや波型加工の振幅による)の高さとすること。

  3. キャンバスに文字データを書き込む。書き込み位置は、波型加工することを想定し中央になるようにしてある。

  4. 必要なら波型加工する。振幅とピッチを画像を見ながら調整する。波型加工する場合、太めのフォントでないと文字がかすれる。

  5. 画像を最終的なサイズにトリミングし、画像サイズを変更する。切り出す位置を適宜調整する。

  6. でき上がった画像を標準出力に書き出す。

     

◆各種パラメータ

「keyinit.pl」で設定する各種パラメータの概要を示しますが、実際の画像を見ながらのチューニングするしかありません。
No. パラメータ 概 要
1 $debug = 0; [デバックモード]
デバックモードonの場合、画像生成の各過程の画像をファイルに書き出す。
負荷がかかるので、デバック時以外使用不可。
0:off(デフォルト) 1:on
2 $imgfile = 'bbs.gif'; [画像ファイル名]
デバックモード時に書き出す画像ファイル名を指定する。
・char-bbs.gif: ベースとなる文字画像ファイル
・wave-bbs.gif: 波型加工した文字画像ファイル
・bbs.gif : 指定サイズにトリミングした表示用文字画像ファイル
3 $ef_time = '30'; [確認キー有効時間]
確認キーの有効時間を分単位で指定する。
4 $crypt_key = '1234ABCD'; [暗号化キー]
暗号化用のキーを英大小文字+数字(4〜8桁)で指定する。
5 $len = '3'; [確認キー桁数]
6 $chr = 0; [確認キー文字種別]
確認キーで使用する文字種別を指定する。種別を混在させると誤判別しやすくなるので '3' は使用しないこと。
0=英大文字, 1=英小文字, 2=数字, 3=英大小文字+数字

@charset = ('英大文字','英小文字','数字','英大小文字+数字')は、文字種別の画面表示データなので修正不可。
7 $W = '60';
$H = '22';
[文字画像の幅と高さ]
文字画像の幅($W)と高さ($H)をピクセルで指定する。
8 $bgfile = '#ffffff';
#$bgfile = 'bg.gif';
[バックグラウンド画像]
単一色のキャンバスを自動生成する(色指定)か、予め用意された画像(xxx.gif/jpg)を指定する。
画像(gif/jpg形式のみ)を利用する場合は、文字画像の高さ+20ピクセル程度の画像を用意すること。
9 $font = 'full path'; [画像生成に使用するフォントのパス]
truetypeフォントを絶対パスで指定すること。
波型加工する場合は、文字を選ばないと判読不能になる。
なお、CentOSはtruetypeフォントはほとんど入っていないので、別途、RHELのSRPMをリビルドしてインストールすると良い。
・SuSE9.3
 $font = '/usr/X11R6/lib/X11/fonts/truetype/luxirb.ttf';
・SuSE10.2
 $font = '/usr/share/fonts/truetype/luxirb.ttf';
・CentOS4.4
 $font = '/usr/X11R6/lib/X11/fonts/TTF/luxirb.ttf';
・WindowsXP
 font = 'C:\WINDOWS\Fonts\TIMESBD.TTF';
10 $font_color = '#ee0000'; [フォント色]
文字画像のフォントの色を指定する。
11 $font_size = '20'; [フォントサイズ]
文字画像のフォントサイズを指定(point)する。
12 $space = '0'; [文字間調整]
特に波型加工時に、文字が詰まって文字画像が見難い場合、文字間を調整する。
0:なし  1:あり(スペース挿入)
13 $vert = '0'; [文字の高さ方向の調整]
キャンバス上の文字の高さ方向の微調整をピクセル指定で行う。
デフォルト:0 であるが、負数(ex. '-2') も利用可能。
14 $amp = '1';
$pitch = '10';
[文字画像の波状加工の振幅とピッチ]
文字画像を波状加工する場合、振幅($amp)とピッチ($pitch)を指定する。
波状加工しない場合は両方とも0にすること

■バックグラウンド画像の作成

OCR対策として、添付の bg_gen.cgi を使用して確認キー画像のバックグラウンド画像用にランダムノイズを描画した画像を生成できます。 以下を設定してブラウザでアクセスするだけです。パラメータの説明を見てもらえれば設定方法はわかると思います。

  1. bg_gen.cgi を掲示板CGIの同じディレクトリに設置し、perlのパスを環境に合わせて変更する。

  2. 不正起動防止用パスワードを適宜変更してください。


Topページへ