Table of Contents

文字化け Edit

最近は余り見かけないので,却って,文字コードを強制的に切り替える機能(現在表示しているページの文字コードを,ヘッダー情報を無視して任意に選択する)がブラウザからなくなっているようだ。手元のChrome (Windows)とEdge (Windows)にはない。まだIE (Windows 10)では切り替え可能。2018年 3月

アクセス制限 Edit

自宅サーバーを立てるだけなら固定IPは不要で,ダイナミックDNSでもよい。しかし外部にあるサーバーの認証に自宅IPを使う場合は,ダイナミックIPだとちょっと不便だ。逆引きできないからである。(.htaccessに,ダイナミックDNSのホスト名を書いてもworkしない。Cf. HostnameLookups。ちなみに、Apache ver 2.4.19から逆引きできないホスト名(ダイナミックDNSなど)でアクセス制限できる。Require forward-dns記法。mod_authz_host - Apache HTTP Server Version 2.4

幾つかの対処策はあるが,一つ,ホスト名とクッキーを併用して認証するのは割と簡単だ。

まず,クッキーを発行するCGIを用意する。次に,アクセス制限したいディレクトリの.htaccessで条件を記述する。

  • クッキー発行CGI (Perl)。このURLは人に知られてはいけないし,アクセスに制限を付ける。
    my $expires;
    {
    	local $expire_delta_hour = 24*7;
    	local(@t, @m, @w);
    	@t = gmtime(time() + $expire_delta_hour*60*60);
    	@m = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
    	@w = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
    	$expires = sprintf(" expires=%s, %02d-%s-%04d %02d:%02d:%02d GMT;",$w[$t[6]], $t[3], $m[$t[4]], $t[5]+1900, $t[2], $t[1], $t[0]);
    }
    print <<END;
    Set-Cookie: xxx=xxxxxxxxxxxx; $expires; path=/;
    Content-type: text/html;charset=UTF-8
    
    <HTML>
    
  • .htaccess
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
    Allow from .ap.plala.or.jp
    
    RewriteEngine on
    RewriteCond %{HTTP_COOKIE} !xxx=xxxxxxxxxxxx
    RewriteRule ^ - [R=404,L]
    

アクセス監視(自動化) Edit

直接どこからもリンクされていないページを見られていたことに偶然気付いた。アクセス制限(認証等)をする内容ではない。さて、ログを随時確認(監視)する、というようなことは自動化すべきなので、特定のディレクトリ(あるいはその他条件)に合致するアクセスがあったらメールで通知が来るように設定した。やりかたは色々あるだろうけど、対象ファイルに、それ自体を加工できないものも含まれているので、ファイル側を一切いじらなくても済む方法として、Apacheのパイプ経由のログ機能で外部プログラムを呼ぶことにした。

パイプ経由のログ機能はログを加工するために用意されたのだろうけど、今回の用途にも特に問題なく使える。本来のログへの影響はApacheの仕様を参照。

  • httpd.confやvhost.conf
    SetEnvIf Request_URI "^/hoge/" mail
    CustomLog "|/スクリプトpath" combined env=mail
    
  • スクリプト
    #!/usr/bin/perl
    $| = 1;
    while (<STDIN>) {
    	my $sendmail = "/usr/sbin/sendmail -t admin";
    	my $headers = <<'END';
    To: admin
    Subject: 適切なもの(ascii文字で)
    END
    	my $body = $_;
    	open (SENDMAIL, "| $sendmail");
    	print SENDMAIL $headers;
    	print SENDMAIL "\n";
    	print SENDMAIL $body;
    	close(SENDMAIL);
    }
    

この例だと、通常のApacheログ一行分(combined書式)が$bodyに入る。command injectionに注意。

fail2ban Edit

fail2banは定番で、Sakura VPSの標準セットでは設定済というくらいらしい。私はウェブ(http,https)に対して使っているが、難儀したのは、Apacheログファイルにホスト名で出力(逆引き済、HostnameLookups On)していると、どうやらうまく動かなかった点。(いずれにせよ、fail2banは、ログにホスト名で書かれているとIPに戻して動作するので、Apacheの苦労が無駄になる。)ApacheをHostnameLookups Onで使うのは邪道だろうけど、私のホストはそんなに人気がないので利便性を採る。そこで、本命のログとは別に、fail2ban用のログを平行して出力している。LogFormat %hを%aに替えるだけであり、特に難しくない。

HostnameLookups Offにしても、.htaccess等で、ホスト名でアクセス制御しているとOn (double)の動作になるので、Offにしていても同じ問題は出るはず。

NHKのウェブページで文字化け Edit

問題の所在 Edit

NHKのウェブページをWeb::Scraperで取得して加工することがよくある。一つ難があり,文字化けすることがある。原因は,NHKはページの文字コードを「Shift_JIS」と名乗っているのに,実際には,Shift_JISから外れた「Windows機種依存文字」を偶に(必要に応じて?)使っているため。例えば「山﨑努」。固有名詞という理由(大義名分)だろうか。

  • 気付いたのは,明日(執筆は2010年7月25日)の衛星映画劇場「地の涯に生きるもの」。昨日の朝日新聞土曜版「サザエさんをさがして 知床旅情」にこの映画のことが出ている。

こうした文字はShift_JISではなく「cp932」等と呼ばれる文字コードなら(一応)許される。しかし,ページが名乗っている文字コード名をそのまま受け入れるソフトウェア(Web::Scraperもその一つ)は,Shift_JISにない機種依存文字であり,未定義文字だと理解して,1バイト目を「置換文字」(U+FFFD)に変換してしまう。(2バイト目は半角カナなどに変換される。)そのため,人間にとっては文字化けする。

  • U+FFFDが画面上どのように見えるかは状況次第。?と表示されることもあれば,\x{fffd}と表示されることもある。

対処 Edit

Web::Scraperを呼び出す前に,

use Encode::Alias;
define_alias( qr/shift.*jis$/i  => '"cp932"' );

を加える。

補足 Edit

\x{fffd}という文字列に変換されるのは,画面等への出力時(encode時)。Web::Scraperは「﨑」をU+FFFDとU+FF71の2文字へ成功裏に変換する。その後,Encode:encodeやbinmodeなどがShift_JISまたはcp932に変換する際に\x{fffd}に変換する。

  • Web::ScraperやLWP::Simpleなどのお任せツールは,自動的に内部表現(Unicode)にdecodeしてくれる。

Web::Scraperの挙動は正しい仕様であり,おかしなことをしているのはあくまでもNHKである。しかし現実問題として情報が失われている。世の多くのブラウザーは「Shift_JIS」と「cp932」を厳密に区別しない*1。善し悪しはいわゆる波ダッシュ問題としても議論されている。さて,波ダッシュ問題は意味的に別の文字になってしまう,だが一定の法則があるので元の文字を推測できる*2。これに対し,今回の問題は元の文字が何だか分からなくなってしまう。より深刻と言えば深刻。

波ダッシュ Edit

ただ,なんでもcp932にすればよいわけではない。というのも,「cp932はshift_jisに機種依存文字を加えたもの」ではないからだ。(そうだったら話は簡単だったのに。)この典型が波ダッシュ問題。波ダッシュ(~)の書かれたページの設定が,Shift_JISのときとcp932のときとでは,その後の運命が違う。議論があるが,簡単に言えば,cp932のときは(Web::Scraperなどで取得されると)別の文字(見た目はよく似ているが)になってしまう。そして,NHKのページには波ダッシュが多用されている。

もっとも先述のように,この問題はたいていの場合元に戻すことができるし,全文検索などでも対処可能なので,それほど大きな問題ではない。

外字まで Edit

NHKのウェブページには「外字」(Windowsの利用者定義文字)が使われていることもある。例えば,「長崎県女クラスメイト」という記述を今日(2010年 8月 7日)見つけた。「女ク」の間の文字がどのように表示されるかは読み手が使っているソフトウェア(ブラウザー等)次第であり,例えばIE 8 on Windows 7やGoogle Chrome 6.0では「□」のように表示され,FF 3.6ではもっと直截に「普通じゃない文字」であることが分かるように表示される。NHK社内で使っている特別な文字・記号(業界の記号か何か?)がそのまま公開ページに出てきてしまったと推測される。NHK社内ではどのような文字を当てているのだろうか?(実際の放送を見ると,単なる空白になっていた。意味的にも空白となるべき場所。空白であることが見た目明確に分かるようにするための記号が当てられているのかも。)

Research Artisan Lite Edit

Research Artisan Liteを使用している。

PHP 5.6, 7.0 Edit

PHP 5.5から一部の機能に異常が出る。7.0では全然動かない。幸い、同一のApacheで複数のPHPを混在させるのは非常に簡単なので、Research ArtisanのディレクトリだけPHP 5.4で動かせば全ての問題が解決する。CentOS 7.4, Apache 2.4.29, PHP 7.0(本体)にて。2018年 4月14日

PHPは標準ではApacheに組み込まれて動く。モジュール版。しかし、普通のコマンドとしてPHPを動かすこともできる。CGI版と呼ばれるが、単に普通のコマンドとしてインストールし、普通のコマンドとしてApacheから呼び出すだけの話だ。.phpという拡張子に対しどのパスのコマンドを呼ぶかをApacheは柔軟に設定できる(ディレクトリ内の.htaccessで)ので、運用は非常に簡単だ。インストールだけは少し知識が要る。普通にyumでインストールするとモジュール版になるので、自分でソースからインストールする必要がある。

前月のログを自動削除 Edit

cronで毎月下旬に次のスクリプトを呼んでいる。GDPRを意識した。

#!/usr/bin/perl
use Time::Piece;
use Time::Seconds;
my $t = localtime;
$t -= ONE_MONTH;
my $lastmonth = sprintf "%04d%02d", $t->year,$t->mon;
print qx(mysql -h localhost -u root -pPSWD accesslog -e "DROP TABLE ra_log_$lastmonth;");

*1 正確には,波ダッシュ問題に見るように,首尾一貫しない解釈をする。
*2 この限りでは首尾一貫している。

添付ファイル: filehatena_help_cookie.png 151件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-04-26 (木) 12:30:48 (82d)