Shade 2016年08月22日 12:19   編集

メンテナンスフリー

一応ここのメインコンテンツの プラグイン・スクリプト検索CGI は、管理人がいなくても機能し続けるシステムを目指して、リンク切れ自動チェック機能を追加し、さらにリンク切れを検出して30日後に登録を抹消する機能も追加したが、思わぬ誤算が。
リンク切れが検出されて30日たった登録は確かにトップページのリンク切れ一覧から消え、抹消されたように見えるが、検索するとまだ登録に残っている。
どうもログファイル破損対策の自動リカバリー機能が誤動作しているようだ。
初期の頃頻繁にログファイルが壊れるというトラブルがあったため、急激にログファイルの容量が減ったら、自動的にバックアップファイルでリカバリーするという機能をつけていたのだ。
リンク切れ自動抹消機能は、リンク切れから30日以上経過した登録をまとめて削除することにしていたが、リンク切れが検出された日時が近い場合、一度に複数の登録が抹消される可能性がある。
そうするとログファイルの容量が急に減ったと判断されて、自動復旧が作動してしまう。
このため、登録を抹消するのは一回に1件のみにすることにした。(ver.4.092)

掲示板スパム対策

これで検索CGIの方はほとんどメンテナンスいらずになったと思うが、実は一番メンテナンスの手間がかかっているのは掲示板のスパム投稿。
プラグイン・スクリプト検索とWeb検索で5個の掲示板があって、それぞれスパム投稿対策をとっているが、やはり数か月ごとぐらいに投稿されてしまう。一度投稿されると似たようなタイプのスパム投稿が何度か続く。
スパム投稿と対策は常にイタチごっこの関係で、新たな対策をしてしばらくは効果があっても、そのうちその対策をかいくぐるような新手のスパムが出てくる。
現在ウチの掲示板で取っている対策は
  1. URL羅列拒否
  2. 日本語を含まない投稿拒否
  3. 投稿キー
    投稿フォームにランダムな数値の画像を表示し、それを入力しないと投稿できないという仕組み。
    ランダムに色やフォントを変えたり、ノイズを混入する改訂版の方が防止効果が高いようだが、ということは、画像ファイルをパターン認識しているのか。
  4. IPアドレス拒否モジュール
    ウチで公開しているモジュール。
    一時、いろいろなURLの書き込みスパムが集中して、URLを調べたところ、ドメイン名はいろいろだが、IPアドレスは一緒という書き込みが多かったので、スパム投稿のドメイン名からIPアドレスを抽出し、そのIPアドレスのドメインはすべて拒否してしまおうというものだ。
    しばらくは効果があったが、最近は短時間でIPアドレスを変えて投稿してくるケースもあるので、片っ端からIPアドレスを拒否してもきりがない。
最近のスパム拒否のテクニックとして自動投稿なので、フォームにアクセスして投稿するまでの時間が短いので、その時間を計測して短すぎるものははじくというのがあった。
counter:3,417
2016年08月22日 12:19   編集
基本的にテキスト装飾はhtmlのタグで直接記述します。管理者設定で許可されたタグが使用できます。

見出し

見出しはh1、... h4タグを使うことを想定しています。見た目の変更はbbs.cssで行うことになります。
<h1>h1タグによる見出し</h1>
<h2>h2タグによる見出し</h2>
<h3>h3タグによる見出し</h3>
<h4>h4タグによる見出し</h4>

h1タグによる見出し

h2タグによる見出し

h3タグによる見出し

h4タグによる見出し

タグ

許可されているタグはすべて有効になります。文字参照で記述しても有効になるので、ご注意ください。

<abc>ABC</abc>のように登録されていないタグは文字参照で表示されます。
preタグ内では許可されているタグを含めてすべてのタグが文字参照で表示されます。
<div style="color:red;">許可されているタグ</div>
<font style="color:blue;">許可されていないタグ</font>
<abc>許可されていないタグ</abc>
同じものをpreタグの外に出すと
許可されているタグ
<font style="color:blue;">許可されていないタグ</font>
<abc>許可されていないタグ</abc>

改行

「改行を<br />に変換する」
をチェックしていると、フォーム中の改行を
<br />
に変換して記事の改行に反映させます。ただし、行の最後が閉じタグ ">" あるいはプラグインの記述に使う "]]" の場合は変換されません。
<table>
<tr><td>テーブル</td></tr>
</table>

<table><br />
<tr><td>テーブル</td></tr><br />
</table><br />
のようになると変だからです。

添付ファイル

画像などの添付ファイルは記事ごとにアップロードします。
「投稿」ボタンを押してファイルをアップロードすると、ファイルのサムネールの上にそのファイルの埋め込みタグが表示されるので、それをコピーして貼り付けます。
画像ファイルの場合、imgタグにwidth属性を指定しますが、オリジナルの画像の幅となっています。大きすぎてはみ出すような場合は、適当な数値に変更してください。

添付ファイルは記事ごとに管理されますが、埋め込みタグは記事に関連づけられたディレクトリへ保存されたファイルのパスを指定しているだけなので、他の記事に埋め込んでもそのまま使えます。
counter:4,486
PHP 2016年08月22日 12:19   編集
ローカル環境で、PHPで表示したHTMLからPDFを出力するためにmpdfモジュールを使用しているが、「﨑」、「髙」など特定の文字が文字化けしてしまう。
それを回避するためのメモ。

まずhttp://www.mpdf1.com/mpdf/index.php?page=Downloadから最新版のmpdfをダウンロード。
xamppにPHPのモジュールとしてインストールすることも出来るが、webサーバーにはmpdfがインストールされてない場合もあるので、
そういう場合でも使用できるよう、ほかのPHPファイルなどと同様にhtdocs内に保存した。
mpdfを使用するPHPで使用する前にmpdfをインクルードして使用することになる。

たとえば、実行するPHPファイルと同じディレクトリ内に./includeディレクトリを作り、その中にmpdfを入れた場合、以下のような関数でmpdfが利用できる。

function mpdf_preview($url,$file) {
require_once('./include/mpdf/mpdf.php'); // ①mpdf.phpを読み込む
$html = file_get_contents($url); // ②URLが$urlのhtmlの内容を取得する。
$html = mb_convert_encoding($html,"SJIS-win","EUC-JP");
// ③なぜかEUC-JPからUTF-8に直接変換すると「﨑」などが文字化けするので、いったんSJIS-winに変換する。
$html = mb_convert_encoding($html,"UTF-8","SJIS-win");
// ④mpdfを使う前にUTF-8に変換しておかないとエラーが出る場合があるので、UTF-8に変換する。
$mpdf = new mpdf('ja+aCJK');
$mpdf->WriteHTML($html);
if ($file) {
$mpdf->Output($file,'F'); // ⑦ファイル名$fileを指定してPDFファイルを保存する。
} else {
$mpdf->Output(); // ⑧$fileを指定しない場合は、ブラウザに表示するのみ
}
}

となる。
  1. まず、①でmpdfが使えるように mpdf.php を読み込む。
  2. file_get_contents($url) で、$url(フルパス)で表示されるhtmlの文字列を取得して$htmlに保存する。
  3. その文字列$htmlをmpdfに渡してPDFに変換するわけだが、そのまま渡すとエラーになる場合があるので、$htmlはUTF-8に変換する必要がある。
    mb_convert_encodingで文字コードを変換する。
    PHPをEUC-JPで書いている場合、
    $html = mb_convert_encoding($html,"UTF-8","EUC-JP");
    としたくなるが、こうすると例の「﨑」とか「髙」が文字化けする。
    PHPをSJISで書いている場合は
    $html = mb_convert_encoding($html,"UTF-8","SJIS");
    としたくなるが、これも﨑」、「髙」が文字化けする。
    これは
    $html = mb_convert_encoding($html,"UTF-8","SJIS-win");
    としなければならないらしい。EUC-JPも文字化けしない指定名があればいいのだが、わからなかったので、EUC-JPの場合は、
    $html = mb_convert_encoding($html,"SJIS-win","EUC-JP");
    $html = mb_convert_encoding($html,"UTF-8","SJIS-win");
    のように、いったんSJIS-winに変換して2段階でUTF-8に変換すると、文字化けを解消できた。
ちなみにHTMLで表示する場合は、文字コードを変換した場合、charsetなどを変換した文字コードに変更してやる必要があるが、PDFにする場合、そのままでUTF-8に変換しても問題ないようだ。このへんはどうなっているのかよくわからない。
counter:4,483
2016年08月22日 12:19   編集
インストールされているプラグインの一覧です。

[A]
access
アクセスの多い順にページ名を一覧表示
[B]
bbs
掲示板を作成する

bbs

掲示板を作成する
■ファイルアップロード
■返信
■過去ログ生成
■隠しパラメータ送信によるスパム投稿対策
■スライドロックによるスパム投稿対策
オプションは[[bbs('lock=1|max_log=100|item=thread')]]のように指定

指定できるオプション

form
form=up(フォームを上に表示) form=down(フォームを下に表示)
item
デフォルトの記事表示順を指定
item=time(投稿順) item=thread(スレッドごとに表示)
max_log
現行ログの保存数。これを超えると過去ログに移動。
例 max_log=50
max_past
過去ログに保存する記事数。これを超えると過去ログファイルを新たに作成。
例 max_past=100
page_line
1ページに表示する記事数。これを超えると次のページに表示
例 page_line=10
lock
スライダで投稿ボタンをロックする lock=1で表示する
例 lock=1
perm_tag
許可するタグ。複数ある場合は;(セミコロン)で区切る。
有効になるのはタグ名だけを<>で囲った場合とその閉じタグだけ。styleなどは指定できない。
例 perm_tag=pre;h1
nameless
投稿者名未入力で投稿した場合、表示される名前を指定。'id'にすると、日付とIPアドレスを元にしたIDを表示
例 nameless=id
titleless
タイトル未入力で投稿した場合、表示されるタイトルを指定。
例 titleless=タイトルなし
hide_bbs
デフォルトでフォームと投稿内容を隠す hide_bbs=1で隠す
例 hide_bbs=1
show_text
添付したtextファイルの内容を表示する show_text=txt;phpのように表示するテキストファイルの拡張子を指定する。複数ある場合は;(セミコロン)で区切る
例 show_text=txt;log

使用例

[[bbs('lock=1|nameless=id')]]
タイトル
投稿者
編集パスワード
コメント
添付

bbs_count
bbsプラグインの最新投稿をチェックして、投稿数をカウント
[C]
calendar
カレンダーを表示し、予定などを保存します。
categories
カテゴリーの一覧を表示する
comment
1行コメントフォームを表示
comment2
commentプラグインに記事の再編集機能を追加
comment3
comment2プラグインにファイル添付機能を追加
[D]
debug
デバッグ用情報を出力
diff
差分表示
[E]
edit
編集リンクを表示する
[F]
files
記事のファイル情報を表示する
footnote
脚注を表示する
[G]
get_id
記事のIDを取得
[H]
help
記事の入力ルールを簡単に説明します
history
更新履歴を表示する
[L]
listup
記事の一覧を表示する
[N]
navi
同じカテゴリーまたは同じタイトルの前後の記事のリンクを表示する
next_link
同じカテゴリーの前後の記事のリンクを表示する
[P]
plugins
プラグインの一覧と説明、使用例を表示する。
[R]
readmore
「続きを読む」を表示する
recent
最近更新された記事の一覧を表示する
[S]
sample
ここにプラグインの説明を記述
search
検索フォームを表示して検索する
search_image
記事に添付された画像のサムネールを一覧表示する
show_new
ファイルが更新されたらnew!表示する。
counter:6,150
CGI 2016年08月22日 10:57   編集

ベーシック認証

ユーザー専用ディレクトリに直接アクセスされるのを防ぐため、オプションで.htaccessによるベーシック認証機能を追加できるようにしました。.htaccessに対応しているサーバーでのみ使用可能です。
ブラウザから直接専用ディレクトリにアクセスしてファイルをダウンロードする必要はなくなったので、すべてのユーザーからのアクセスを拒否するように変更してもよかったのですが、登録ユーザー名とパスワードでアクセスできるという仕様はそのままです。しかし、まず使う必要はないし、普段は特に意識する必要はありません。

.htaccessが使えないサーバーでは、せめてディレクトリの中身の一覧が見られないように、ディレクトリ作成時に中にindex.htmlを作成する $make_index を1にしておいた方がいいでしょう。
ユーザー登録で作成される専用ディレクトリ名がランダムな文字列で生成されるのも、外部から直接専用ディレクトリにアクセスされにくくするためです。

.htaccessと.htpasswd

ベーシック認証に必要な.htaccessと.htpasswd はユーザー登録、修正時にCGIが自動的に作成するので、通常は特に意識する必要はありませんが、簡単に仕組みを説明しておきます。
.htaccess をおいたディレクトリと、その下層ディレクトリにベーシック認証が有効になります。
.htaccess 内には、このディレクトリにはベーシック認証が必要ですということと、認証に照合するパスワードを書いたファイルへのパスが書かれています。

たとえば、ユーザー1の設定ディレクトリ(ユーザー1がアクセスできる最上層のディレクトリ。以下ルートディレクトリと呼ぶ)が./upload/dir1だとすると、このディレクトリ内に.htaccessに置きます。
.htaccess内には、ユーザー1のパスワードの保存先を記入することになります。
パスワードの保存先は専用のディレクトリ内にします。外から存在がわからないように名前をランダムな文字列にします。このディレクトリ内はアップロード用ディレクトリ内と同じディレクトリ構成にして、該当ディレクトリ内に.htpasswdを作成します。
.htpasswdにはユーザーIDとパスワードを書き込みます。
multiupload/ multiupload.cgi
|
+--- upload / (ユーザー2のルートディレクトリ)
| |
| +--- .htaccess (パスワードファイルへのパス
| | jhf5S30j78vc/upload/.htpasswd)
| |
| +--- dir1 / (ユーザー1のルートディレクトリ)
| |
| +--- .htaccess (パスワードファイルへのパス
| jhf5S30j78vc/upload/dir1/.htpasswd)
+--- jhf5S30j78vc /
|
+--- upload /
|
+--- .htpasswd (ユーザー2のパスワード保存)
|
+--- dir1 /
|
+--- .htpasswd (ユーザー1のパスワード保存)
このユーザー1のルートディレクトリより、上層のディレクトリをルートディレクトリに設定されたユーザー(たとえば./uploadをルートディレクトリにするユーザー2)にとっては、ユーザー1のルートディレクトリ(./upload/dir1)はサブディレクトリに相当します。

下層ディレクトリには、認証無しでアクセスできるようにしたいのですが、下層の.htaccessの設定が優先されるらしいので、./uploadに.htaccess を置いて、jhf5S30j78vc/uploadに.htpasswdを置くだけではアクセスできません。

このため、ユーザー設定時にルートディレクトリの下層に他のユーザーのルートディレクトリがある場合は、その下層ディレクトリに相当する.htpasswd にもパスワードを保存することにしました。
逆に設定したユーザーのルートディレクトリの上層のディレクトリをルートディレクトリとするユーザーがいたら、そのパスワードも.htpasswd に保存する必要があります。
multiupload/ multiupload.cgi
|
+--- upload / (ユーザー2のルートディレクトリ)
| |
| +--- .htaccess (パスワードファイルへのパス
| | jhf5S30j78vc/upload/.htpasswd)
| |
| +--- dir1 / (ユーザー1のルートディレクトリ)
| |
| +--- .htaccess (パスワードファイルへのパス
| jhf5S30j78vc/upload/dir1/.htpasswd)
+--- jhf5S30j78vc /
|
+--- upload /
|
+--- .htpasswd (ユーザー2のパスワード保存)
|
+--- dir1 /
|
+--- .htpasswd (ユーザー1とユーザー2のパスワード保存)
.htpasswd に保存するパスワードですが、ローカルサーバで実験したときはcryptしたパスワードでは照合できず、生のパスワードでないとダメでした。
このため、わざわざ別に生のパスワードを保存する処理を追加していたのですが、その後Web上でテストしてみると、cryptしたパスワードで大丈夫なことがわかりました。
結局生のパスワードは保存しないですむことになりました。
.htpasswdも直接見られる心配はないのかもしれませんが、パスワード保存ディレクトリは、管理者パスワード生成時に自動的にランダムな文字列のディレクトリ名を作成するようにしています。
counter:3,897
CGI 2016年08月16日 15:04   編集

お知らせ

ユーザーがトレンドマイクロのセキュリティソフトを使用している場合、アクセス制限ページのログイン情報が外部に漏れる恐れがあります。対策を施したver.1.12に更新をお願いします。

需要がどれくらいあるかわかりませんが、ファイルの更新時間を変更するCGIを公開しました。
私の場合は、掲示板などのログファイルの更新時間を変更するのに使っています。
なぜ、ログファイルの更新時間を変更する必要があるかというと、スパム投稿対策のためです。ウチの検索サイトでは、掲示板などのログファイルの更新時間をチェックして、何日以内の更新だったら new! 表示したりしています。当然ながらスパム投稿の場合でもログファイルが更新されると new! 表示されます。
スパムを削除してもログファイルの更新時間は元には戻りません。(スパムを削除した時間にさらに更新されるだけです。)
そうすると、スパムを削除してログの中身は元の状態に戻っているのに new! 表示だけが残ってしまうことになります。
これはやはり具合が悪いので、こういう場合は更新時間変更CGIでログファイルの更新時間を、スパムが投稿される元の時間に戻すようにしています。

また、最近はWEB上ではなく、パソコン内のファイルの更新時間を変更したいというケースもあるので、ローカル環境でも使いやすいよう改修したものを公開することにしました。テキストボックスに入力したディレクトリに移動できるようになっています。日本語のフォルダやファイルにもアクセスできるようです。(すべて大丈夫かわかりませんが)

web上での使用も考えて、簡単なアクセス制限機能もつけています。このCGIはファイルの更新時間を変更することしかできませんが、使い方によっては見えてはいけないファイルも見えてしまうという危険があるからです。WEB上に設置する場合、極力わかりにくいパスワードを設定してください。
ver.1.12 2013/03/14
ログイン後の認証を一時ファイルによる認証に変更。
ver.1.1 2011/06/17
秒単位まで編集できるようにしました。
パスワードは「guest」です。サンプルなので、ディレクトリの移動に制限をかけています。

設置

ダウンロードしたファイルを解凍したら、time_stamp.cgi1行目の
#!/usr/local/bin/perl
をサーバーに合わせて変更してください。

パスワード制御するなら(24行目がmy $use_pass = 1;なら)
25行目の
my $pass = '';
にパスワードを入れてください。
修正は以上です。あとはサーバーにアップロードしてtime_stamp.cgiのパーミッションを適当に設定してください。

使い方

  • 更新時間を変更したいファイル名をクリックすると、変更フォームが現れます。「指定した時間に変更する」を選んで、日時を変更し、「タイムスタンプ修正実行」ボタンを押すと更新時間が変更されます。
    「現在に変更する」を選んだ場合は、現在の時間に更新されます。

  • ディレクトリ名をクリックするとそのディレクトリに移動します。ディレクトリ名クリックはそのディレクトリへの移動に割り当てているので、ディレクトリの更新時間変更はとりあえずできません。

  • ファイル名、ファイルのサイズ、最終更新時間でソートできます。たとえば、名前をクリックするとファイル名を昇順でソートします。もう一度名前をクリックすると降順でソートします。
    サイズ、最終更新時間のソートも同じように2度続けてソートすると表示順を逆にします。
  • フォルダとファイルは分けて表示しますが、フォルダを先に表示したり、ファイルを先に表示したりすることができます。
存在しない日付や時間への変更はできませんが、存在してもUNIX元年(1970年1月1日)より前や、2038年1月19日以降の日付には変更できません。
・・・と思っていたら、いつの間にか1970年以前や2038年以降への変更もできるようです。PHPと同様にサーバーのPerlも64bit化されているのかもしれません。
counter:4,083
Shade 2012年12月16日 20:13   編集
投稿者
コメント
counter:3,078