広告をつけていたと思ったら,いつの間にか使っていた

何を言って(略


これ.「桃色大戦ぱいろん」とかいう麻雀ゲー,のはず.
だって,会員登録ページの絵が,吉崎観音なんだもの…

Windows 7 の場合,インストールしても

  • スタートメニューに表示されない
  • デスクトップショートカットは自アカウントにしか表示されない

という,カユいところに手の届く仕様だった.
アップデートが多すぎてまだ起動しないので,やってみた感想はまたそのうち.
やってみた.
予想通り,必殺技系麻雀(命名:hadacchi)だった.
こんな要素はいらないのだ…
あと,人少ない.

social bookmark とか SNS とかのボタン

この weblog へ,WP Social Bookmarking Light とかいうのを入れてみた.
テーマをいじってボタンを表示させていると,テーマを変える毎にカスタマイズするの面倒だなぁ…と思っていたので,助かった.
これを入れてみると分かるが,web site の情報を共有するサービスって,腐るほどあるんだなぁ.
皆,何つかってるのか分からないので,テキトーに有名そうなのを残してみた.

中でも,evernote とか,google reader とか,atode とか,instapaper とか,後で読む系のサービスが目についた.
電車通勤でスマフォンとか使ってると,小型窓で読むのはめどい上に通信料かかるので,こういうの使いたいなぁ,とか思っていた頃が私にもありました…
子供できたら,家でPCなんて見てらんねー.
会社では web なんて読んでる暇ねー.
忙しい人こそ,目についたその時に記事を読まないと,二度と読む時間が見付からないんじゃないだろうか.

CPU 稼動率 in Win7

リソースモニタ
リソースモニタ

AMD のプロセッサを使っており,CPU ダウンクロックの状況を見たかったので,公式ソフトの AMD Power Monitor を探したのだが,どうも公式サイトから消えているらしい.
なぜだろうと考えてみると… Cool'n'Quiet ドライバが Vista 以降の OS 向けに出ていないのと同じ理由ではないか…,つまり OS が標準で類似の機能を搭載しているんじゃないかと考え,
タスクマネージャのパフォーマンスタブを開いてみると,「リソースモニター」とかいうそれっぽいボタンがあった.
当たりでした.

プロセスのトコにある「最大周波数」が,100%の状態で CPU がフル稼動らしい.
ためしに, Pixia で 5000x5000 のキャンパスを開いてお絵描きしてみたら,あっという間に 100% になってしまった.
CPU 使用率が 50% ちょいで止まっていたのは, Dual core だからだろう.

なお,起動オプションを調べてみたら,これで動くらしい.
C:\Windows\System32\prefmon.exe /res
または
C:\Windows\SysWOW64\prefmon.exe /res

もっと省エネを本当に考えるなら,core 毎にクロックダウンできた方がよさそうだ.
って,別チップやん,それじゃぁ.

FTPサーバでディレクトリ一覧を表示させない

ProFTPDの場合。
.ftpaccess を表示させたくないディレクトリへ作成。
ファイルの中身はこんな感じ。

<Limit DIRS>
    DenyAll
</Limit>

ただしこの設定を行なうと、親フォルダからそのディレクトリ自体を表示できなくなる。
Windows 標準の FTP クライアントの場合、
cd -- 不可
put -- 可能
具体的には、
put hogehoge.txt invisible_dir/hogehoge.txt
のように名前を直接指定して転送すれば、転送は可能。

公的SSL証明書は,お高い

会社から,よく PC の設定など自分のメモを見るために,自分の blog へアクセスすることがある.
メモを会社から投稿することもある.
でも,ちょっと情報セキュリティに気を使う会社なら投稿内容の監視くらいはしていそうなので,
SSL 通信で投稿内容を暗号化したいなーとか思ったのでした.

SSL の証明書って,たっけーのね…
最大手 VeriSign の場合,最安で 85,050 円とか,泣ける.
で,安いとこないかなーと探したら,こんなトコがありました → サイフにやさしいSSL証明書
2,880 円~ とか.びっみょー.
オレオレ証明書もいいけど,どうせなら第三者機関の証明書が欲しい…という人にとっては, 240円/月はお手頃なのだろうか.

spammer counter v3

IP アドレスでアクセスを禁止している spammer が,その後どれだけアクセスを続けているかをカウントする php コードを,今回は MySQL を使って実装した.
まず最初に注意点. ErrorDocument 403 で php ファイルへ飛ばす場合,その php ファイルへのアクセスは可能とすること.
さもなくば, 403 の転送で無限ループが発生する.
具体的には,.htaccess へ下記を追記.hogehoge.phpの部分は,設置したphpファイル名に変更すること.

<Files hogehoge.php>
allow from all
</Files>

spammer のアクセスが集中している時など,どうしても
spammer counter v2
では,ファイル書き込みに失敗するようだ.
その結果,度々ファイルがクリアされてしまっていた.

んで,よく考えたらこのサイトでは MySQL を使う blog が2つも動いていることを思い出したので,
DB で実装することにした.
とても楽チン.

そのコードは,こんな感じ.

<?php
header('HTTP/1.1 403 Forbidden');
header('Content-Type: text/html; charset=iso-8859-1');
?>
<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'>
<HTML><HEAD>
<TITLE>403 Forbidden</TITLE>
</HEAD><BODY>
<H1>Forbidden</H1>
<?php printf('You don't have permission to access %s\non this server.',
             htmlentities(strip_tags($_SERVER['REQUEST_URI']))); ?><P>
<HR>
<ADDRESS><?php
$e = explode(' ',$_SERVER['SERVER_SOFTWARE']);
printf('%s Server at %s Port %d',$e[0],$_ENV['SERVER_NAME'],$_ENV['SERVER_PORT']);
?></ADDRESS>
</BODY></HTML>
<?php
// MySQL
$mySqlHost = 'xxx.xxx.xxx';
$dbname    = 'database_name';
$user      = 'user_name';
$password  = 'password';
$table     = 'spammer_counter';

// connecting
$mobj = mysql_connect($mySqlHost,$user,$password);
if ($mobj == FALSE) { die('broken');}

// count IP addr
$addr = $_SERVER['REMOTE_ADDR'];

mysql_select_db($dbname,$mobj);
$done=mysql_query('insert into '.$table.' (ipaddr,number) values (''.$addr.'',1) '
                  .'on duplicate key update number=number+1;'); 
mysql_close($mobj);
if ($done == FALSE) { die('no response...');}
?>

欠点は,データを見るのに DB を叩く必要があること.  
それは嫌なので,viewer も作った.
</p>
<p class="pre">
<?xml version='1.0' encoding='Shift_JIS'?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'
    'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='ja' lang='ja'>
 <head><title>spammer viewer</title></head>
 </body>
 <h1>spammer viewer</h1>
 <table style='border: black solid 1px;'>
  <tr><th>IP addr</th><th># of access</th></tr>
<?php
// MySQL
$mySqlHost = 'xxx.xxx.xxx';
$dbname    = 'database_name';
$user      = 'user_name';
$password  = 'password';
$table     = 'spammer_counter';

// connecting
$mobj = mysql_connect($mySqlHost,$user,$password);
if ($mobj == FALSE) { die('broken');}

mysql_select_db($dbname,$mobj);

$done=mysql_query('select * from '.$table.';');
mysql_close($mobj);
if ($done == FALSE) { die('no response...');}

while ( $row = mysql_fetch_row($done)) {
  printf('  <tr><td>%s</td><td style=\'text-align:right;\'>%d</td></tr>\n',$row[0],$row[1]);
}

?>
 </table>
 </body>
</html>

spammer counter v2

spammer counter の記事で書いた,403 にかかった IP を保存するスクリプトを改造した.
まず最初に注意だが, ErrorDocument 403 で php ファイルへ飛ばす場合,その php ファイルへのアクセスは可能とすること.
さもなくば, 403 の転送で無限ループが発生する.
具体的には,.htaccess へ下記を追記.hogehoge.phpの部分は,設置したphpファイル名に変更すること.

<Files hogehoge.php>
allow from all
</Files>

もともとこのスクリプトを設置した理由は,弾いている IP を subnet mask でまとめるため,
subnet 毎のアクセスを把握したかったためなのだが,
先の記事のログではアクセス順に並ぶため, subnet 毎の状況を一見して把握できなかった.
そこで,アクセスがある毎に, 1 回だけ bubble sort を走らせることにした.

bubble sort で実装し行毎処理を行なっているのは,
全てメモリに読み込んで sort するのは,spammer のアドレスが想像以上に多いので,
ライン数が増えて処理に時間がかかるようになり,ファイルロックに邪魔されて
spammer のアクセスを拾えなくなるのではないかという懸念のため.
実際には,File I/O の方がボトルネックになっている気がするので,
fwrite 一発で書き込んだ方が処理は早いかも知れない…
もっと行数が増えたら,測定してみよう.

で,まぁコードはこんな感じ.

-- 追記
ごめん,バグがあった.
ループ前の1回の処理でbreak文を消してなかったので,バグってた.

-- 追記2
fgetcsv で取得した末尾の空白文字を取り除かないと \n が入ってしまうらしいことに,
後から気付いた.
全部 int キャストすることで,回避.

<?php
header('HTTP/1.1 403 Forbidden');
header('Content-Type: text/html; charset=iso-8859-1');
?>
<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'>
<HTML><HEAD>
<TITLE>403 Forbidden</TITLE>
</HEAD><BODY>
<H1>Forbidden</H1>
<?php printf('You don't have permission to access %s\non this server.',
             htmlentities(strip_tags($_SERVER['REQUEST_URI']))); ?><P>
<HR>
<ADDRESS><?php
$e = explode(' ',$_SERVER['SERVER_SOFTWARE']);
printf('%s Server at %s Port %d',$e[0],$_ENV['SERVER_NAME'],$_ENV['SERVER_PORT']);
?></ADDRESS>
</BODY></HTML>
<?php
// comparison 2 IP addresses
function aIsLargerThanB($a,$b) {
    // a and b are arrays of 4 integers, e.g. 127.0.0.1 is expressed as
    // array(127,0,0,1)
    if ($a[0]==$b[0])
        if ($a[1]==$b[1])
            if ($a[2]==$b[2]) return $a[3] > $b[3];
            else return $a[2] > $b[2];
        else return $a[1] > $b[1];
    else return $a[0] > $b[0];
}

// parse IP address to array of 4 integers.
function parseIpAddress($ip_addr){
    $return = array();
    foreach ( explode('.',$ip_addr) as $i) $return[] = (int)$i;
    return $return;
}

// count IP addr
$addr = $_SERVER['REMOTE_ADDR'];
$fobj = fopen('counter.dat','r');
if (flock($fobj, LOCK_EX)) {
  $oobj = fopen('counter.tmp','w');
  $flag=false;

  // 1st processing
  $s=fgetcsv($fobj);
  if (count($s)==2 and $s[0] === $addr) {
    $s[1]=(int)$s[1]+1;
    $flag=true;
  } else { $s[1] = (int)$s[1];}
  $prev = array($s[0],$s[1]);

  // process loop
  while (!feof($fobj))
    {
      $s=fgetcsv($fobj);
      $s[1] = rtrim($s[1]);
      if (count($s)<2) {
    fputcsv($oobj,$prev);
    break;
      } elseif (!$flag and $s[0] === $addr) {
    $s[1]=(int)$s[1]+1;
    $flag=true;
      } else { $s[1] = (int)$s[1];}

      $pips = parseIpAddress($prev[0]);
      $nips = parseIpAddress($s[0]);

      // bubble sort
      if (aIsLargerThanB($pips,$nips)) {
    fputcsv($oobj,$s);
      } else {
    fputcsv($oobj,$prev);
    $prev = array($s[0],$s[1]);
      }

    }

  fputcsv($oobj,$prev);
  if (!$flag) { fprintf($oobj,'%s,1\n',$addr);}
  flock($fobj,LOCK_UN);
  fclose($fobj);
  fclose($oobj);
  copy('counter.tmp','counter.dat');
} else {
    fclose($fobj);
}
?>

b-mobile fair を安く新規購入

今年の GW 頃に購入したb-mobile fairを使い切ってしまった.
クレカの登録が必要な代わりに8,350円で使える追加チャージか,9,800円の新規購入かで迷っていた.
そしたら,amazonで安く売ってた.

これなら,新規購入でも安いので,少しお得.
キャリアに個人情報を登録して足が着くのが嫌な人にオススメです.

spammer counter

アクセス禁止したスパマーが,その後どれだけアクセスしているかカウントする.

以前,スパム増加という記事でも触れたが,
本サイトではアクセス禁止リストにあるホストからのアクセスを禁止している.
ところが,似たようなIPからのアクセスが絶えず続いており,どんどんホストを追加している状態である.
このままではアクセス禁止リストが延々と伸びていってしまうので,特にアクセスの多いアドレス空間については,
適当なサブネットマスクでもってアク禁とすることにしたい.

ところが,一度アクセスを禁止してしまうと,その後はどの程度のアクセスがあるのか分からない.
アク禁リストのアップデートをするための情報として,アク禁を解除しないまま,アクセス数を把握する方法を考えた.

ずばり,403 エラードキュメントをphpにして,アクセス元をカウントアップする作戦である.
そして普通に誤った操作をした人に疑問を与えないよう,403を忠実に再現したい.
ということで,こんなコードを生成してみた.

<?php
header("HTTP/1.1 403 Forbidden");
header("Content-Type: text/html; charset=iso-8859-1");
?>
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>403 Forbidden</TITLE>
</HEAD><BODY>
<H1>Forbidden</H1>
<?php printf("You don't have permission to access %s\non this server.",
             htmlentities(strip_tags($_SERVER['REQUEST_URI']))); ?><P>
<HR>
<ADDRESS><?php
$e = explode(' ',$_SERVER['SERVER_SOFTWARE']);
printf("%s Server at %s Port %d",$e[0],$_ENV['SERVER_NAME'],$_ENV['SERVER_PORT']);
?></ADDRESS>
</BODY></HTML>
<?php
// count IP addr
$addr = $_SERVER['REMOTE_ADDR'];
$fobj = fopen("counter.dat","r");
if (flock($fobj, LOCK_EX)) {
    $oobj = fopen("counter.tmp","w");
    $flag=false;
    for(;!feof($fobj);)
    {
        if ($flag) { fwrite($oobj,fgets($fobj));}
        else {
            $s=fgetcsv($fobj);
            if (count($s)<2) { break;}
            if ($s[0] === $addr) {
                $s[1]=(int)$s[1]+1;
                $flag=true;
            }
            fputcsv($oobj,$s);
        }
    }
    if (!$flag) { fprintf($oobj,"%s,1\n",$addr);}
    fclose($fobj);
    fclose($oobj);
    copy("counter.tmp","counter.dat");
} else {
    fclose($fobj);
}
?>

ファイルロックなんて,何年か振りに実装した.
普通に php のオンラインドキュメントにあるようなファイルロックにしていないのは,
各行毎に読み込み/書き込みをしたかったから.
読み込み用ファイルを排他ロックして,読み込めた人だけ処理が進むようにしてみた.
そんな処理が問題になるほど膨大なログが溜まる頃には,レンタルサーバのスペースを
食い潰してアカウント消されていそうだけどね…

んで,アク禁で ErrorDocument 403 へ飛ばす場合の注意.
403 で飛ばす先の php ファイルへのアクセスは可能とすること.
さもなくば, 403 の転送で無限ループが発生する.

<Files hogehoge.php>
allow from all
</Files>

とかでOK.

余談だが, ErrorDocument で http://~~ と URI 指定すると,
別サーバへの転送と同様に処理されてしまうらしく,呼び出し元が引けなくなるので注意.