日本以外からのPOSTを弾くフィルタpreload
gusagiです。
今日は、日本以外からのPOSTを弾くフィルタpreloadを書いてみようと思います。
トラックバックスパムやコメントスパムなどで困っている方は結構いると思います。
簡単な対応方法は、protectorモジュールを入れて対応することなのですが、
日本以外からPOSTされた場合は全て弾きたい、などという場合もあります。
その場合、PEARのNET_GeoIPを利用することで実現が可能になります。
Net_GeoIPでは、MaxMind社が配布しているGeoLite Countryのデータを利用します。
利用するデータは、こちらのファイルで、無料で利用可能です。
このファイルと、前述のPEARパッケージを、サーバの適当なディレクトリにアップロードして下さい。
※下記のコードでは、PEARパッケージを{XOOPS_TRUST_PATH}/PEAR、GeoLite Countryのデータを
{XOOPS_TRUST_PATH}//PEAR/GeoIP/GeoIP.datとしています。
<?php
if( ! defined( 'XOOPS_ROOT_PATH' ) ) exit ;
if ( ! class_exists('DenySpam') ) {
class DenySpam extends XCube_ActionFilter
{
function preBlockFilter()
{
// 特定のIPアドレスなら、フィルタを適用しない
$ip = getenv( 'REMOTE_ADDR' );
$allowIps = array( '192.168.', '111.222.333.444' );
foreach ( $allowIps as $key => $allowIp ) {
if ( strstr($ip, $allowIp) !== false ) {
return;
}
}
// リクエストメソッドがPOSTの場合だけ、チェックを行う
$method = getenv( 'REQUEST_METHOD' );
if ( strtolower($method) === 'post' ) {
// PEARパッケージのために一時的にinclude_pathを書き換えるので、
// 元のinclude_pathを待避してから、include_pathを変更する
$includePath = get_include_path();
set_include_path( $includePath . PATH_SEPARATOR . XOOPS_TRUST_PATH . '/PEAR' );
// Net_GeoIPを読み込む
require_once XOOPS_TRUST_PATH . '/PEAR/Net/GeoIP.php';
// GeoLite Countryのデータを元にインスタンスを取得
$geoIp = Net_GeoIP::getInstance( XOOPS_TRUST_PATH . '/PEAR/GeoIP/GeoIP.dat' );
// アクセス元の国コードを取得
$countryCode = strtolower( $geoIp->lookupCountryCode($ip) );
//
// ログにPOST内容を記録(#1)
//
$dateTime = date( 'Y-m-d H:i:s' );
@error_log( $dateTime . ' ' . $ip . ' ' . $countryCode . ' ' . serialize($_POST) . "n",
3, XOOPS_TRUST_PATH . '/log/post.log' );
// アクセス元の国が日本じゃない場合、include_pathを元に戻して、XOOPS_URLにリダイレクト
if ( $countryCode !== 'jp' ) {
set_include_path( $includePath );
$xcRoot = & XCube_Root::getSingleton();
$xcRoot->mController->executeForward( XOOPS_URL );
}
// アクセス元の国が日本の場合、include_pathを元に戻して終了
set_include_path( $includePath );
}
}
}
}
上記のようなコードを、{XOOPS_ROOT_PATH}/preload/DenySpam.class.phpとして保存すると、
日本以外からのPOSTを弾くフィルタの出来上がりとなります。
(PEARのパスや、GeoLite Countryのデータファイルのパスは、適宜読み替えて下さい)
なお、途中の行にあるログ記述部分は、必須という訳ではありませんが、POST内容を保存しておくと
良い場合もあるので、サンプルとして記述しています。
最初に書いたように、protectorモジュールで解決できているなら、このようなフィルタは
不要だと思いますが、protector以外にこんな方法もあるということで書いて見ました。
参考になれば幸いです。
RSS feed for comments on this post.
ƤˤϡޤȤդƤޤ
Ȥ
ʤߥȤդ뤳ȤϽޤ