Category Archives: Unix

バージョン違いMySQLの同居

同じバージョンのMySQLを2台同じサーバーに入れたりというのは開発環境でやったことがあるのですが、双方とも自動起動してバージョン違いかつ文字コード違いという環境は初めて入れた。結論としては自動起動スクリプトがまるで複数導入を想定していないというのが分かったくらいかな。

やってみた構成はこんな感じ。
  • rpm版同士での複数インストール
    これは普通に競合するのでNG
  • 既存のMySQLクライアントとPHP-MySQLコネクタを残して、MySQL公式サイトのrpm最新版(Serverのみ)をインストール
    これも競合。MySQL公式サイトのものはServerとClientで2つに分けているが、RedHat公式のMySQLはServerとClientとその両方で使う無印パッケージの3つ分かれ、無印とMySQL公式のパッケージで競合を起こす。
  • 既存はrpm版で別途ソース版を入れる
    これは問題なし、自動起動スクリプトは改造が必要
  • 既存がソース版で別途インストールもソース版
    問題は無いがソース版同士なので全ての設定を別に分ける必要が出てくる。自動起動スクリプトは改造が必要。
自動起動スクリプトの改造が必要なのは、configureの設定内容を無視しているのでそのまま使えばデフォルトの構造でmy.cnfやpidファイル、sockファイルを探しに行くという恐ろしいワナがある。結局自動起動スクリプト上のmysql_safeコマンドの行に–defaults-file=[my.cnfのパス]で設定が必要。ちなみにこのオプションは最初に記述しないとエラーになります。他にはDBの初期化(mysql_install_db)をするときに既存のDBを破壊しないように念のためバックアップを取った上でオプションでdatadirやdefaults-fileを設定し回避すること。これは理由がわからないのですがスレーブ用に構築する予定のDBで初期化するときに最初からmy.cnfよりbin-logを抜いていたらエラーになった。これは初期化にはバイナリログが必要だったのか、中途半端なコメントがまずかったのかは不明。別に初期化の時にバイナリログが出されてもたいしたこと無いので別に良いのですけどね。
参考
またレプリケーションも本格的に負荷分散しようとしたら参照系で不要なDBやテーブルを持ってきたくないという事がありました。こちらの設定はスレーブ側のmy.cnfの[mysqld]内に
replicate-do-table=dbname.table
replicate-do-db=dbname
といった感じで追記するだけ。
また文字コードの設定で[mysqld]内に
default-character-set = utf8
だけでなく
skip-character-set-client-handshake
を設定するとPHPから接続したときにいちいち「SET NAMES」を設定しなくても良くなるし、他のセクションにdefault-character-setを入れなくても文字コードが統一される(status;やshow variablesで確認)。
[MySQL] 特定データベース、特定テーブルを指定したレプリケーション設定 | 半袖野郎 blog.hansode.org
あと大きなバッチを使うときに気になるのがメモリ使用量なのですが、折角1行ずつ取り出すのに一斉に配列に入れようとするのはセンス無さ過ぎで見つけ次第指導するレベルなのですが、また全件必要でないのにどうせ詮索スピード変わらないからという理由でLIMITを使わないのもメモリの事を考えてない証拠なのでこれもダメ、でもまさかmysql_query関数の結果が一旦全部メモリにキャッシュされるとは思わなかった。PHP上ではどう見てもメモリが溜まるような処理を書いてないのにメモリ不足になるのはこれのせいだった。そのときはmysql_unbuffered_queryを使いましょう。mysql_unbuffered_queryの制約としてはmysql_data_seekが使えないことや全ての行をフェッチする必要があるという事なので件数の絞込みはしっかりLIMITで設定しましょう。スピードは多分遅くなると思いますがバッチ等では消費メモリの上限を抑えられない方が問題なので。
PHP:SQLクエリのメモリ消費量を抑える:mysql_unbuffered_query

CentOS大丈夫か!?プロジェクトリーダが基金持ち逃げ!

本番環境でRHELを使う事が多いので実験サーバー等にCentOSを良く使ってたりしますが、今日こんな記事を見つけて愕然としています・・・。

高密度小池 / CentOS プロジェクトが瓦解
記事の翻訳によると、プロジェクトリーダー兼金庫番がCentOSの基金を持ち出して失跡したようです。しかもドメイン管理まで任せていたのでcentos.orgの失効も危ぶまれているらしい。ちなみに期限を調べたら今年の12月4日、あと4ヶ月ちょっとしかない・・・。
CentOSが無くなるのは非常に困るのでなんとか解決して欲しいです。
続報:
Kenichi Maehashi’s Blog
centos.orgのドメインについてはCentOS Projectに名義変更されましたね。
(最終更新 2009/09/01 02:57:51 UTC)
とりあえず引継ぎは行われるという事で一安心です。

ipf.logが大きくなってきた

ipf.logはFreeBSDで使っているIPフィルタのログファイル名ですが、特になにも気にせず放置してたら500MB超えていました。折角/var/log内に置いているファイルだしシステムでローテーションしようと方法を検索。

下記のページがヒットしました。なるほどnewsyslog.confで設定するんですね。

NetBSD3.0 i386 の /etc/newsyslog.conf について
http://rabbit-kernel.hp.infoseek.co.jp/it/newsyslog/

とりあえず次の一行を追加
/var/log/ipf.log             600  5     *    $D0   Z

/var/log/ipf.logを「権限600」で「5世代」、「サイズ制限なし」で「毎日0時」だと思います。最後のZはなんでしょう?また日付が変わったらちゃんとローテーションできたか様子見です。

 

Xen入れてみました

Windows上のVirtualPCではXen入れるとクラッシュしてましたが、DELLの新品PC(Vostro 220s)にやってみたら64bit版はダメでしたが32bit版のCentOS5.3をインストールできました。(でもGUIインストールは何故か失敗したのでテキストモードでインストール)

そしてゲストOSに同じCentOS5.3 32bit版を入れたのですが、苦労したのがパッケージの置き場所の選択。

# virt-install –nographics
What is the name of your virtual machine? vps1
How much RAM should be allocated (in megabytes)? 512
What would you like to use as the disk (file path)? /var/lib/xen/images/vps1.img
How large would you like the disk (/var/lib/xen/images/vps1.img) to be (in gigabytes)? 50
What is the install location? /var/tmp/CentOS-5.3-i386-bin-DVD.iso

ホストOSから上記のようにコマンド打ってインストーラー起動までは行きましたが、今度はゲスト側からイメージが読み込めないんですね。だからといってインターネット経由でのインストールはだるいので、DVDの中身をWindowsPCからWinSCPでホストOSのドキュメントルート以下にコピーして、ホストOSでApache起動。ゲストOSからはHTTPインストールでホストOSのIPアドレス指定でクリアしました。

ちょっとだけ面倒だったかな。でもこれで開発用専用サーバーの増設コストが下がりました。

参考にしたサイト:
ゲストOSインストール(CentOS5編) – CentOSで自宅サーバー構築
http://centossrv.com/xen-domu-centos5.shtml

サイトメンテ時には503

これは目からウロコ。よくやるのが200 OKのまま文面は「ただいまメンテナンスを行っております。しばらくしてから再度ごアクセスください。」って出している。auのEZwebだとApacheエラーは画面表示させてくれないのでユーザビリティ上しかたないとか(得に404に関してはレギュレーションで指定されているし)あるのでつい200 OKのままなんですよね。それだと検索エンジンのクロールでキャッシュされてしまう危険を伴う。403/404出していると次回からクロール来なくなる可能性があるし500は論外。でも下記URLの記事によれば503の場合は検索エンジンも次回のクロールの機会が来るまで待ってくれるみたいなので大丈夫だそうです。

サイトメンテナンス時には、HTTP 503エラーを使う » 海外SEO情報ブログ・メルマガ
http://www.suzukikenichi.com/blog/using-503-error-at-site-maintenance/

元記事ではドキュメントルートからメンテする場合の設定で困っているそうですが、とりあえず動作した設定をここで公開しておきます。

Alias /maintenance/ “/home/www/maintenance/”
ErrorDocument 503 /maintenance/503.html
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/maintenance/503.html$
RewriteRule ^.*$ – [R=503,L]
<Directory “/home/www/maintenance/”>
Options FollowSymLinks ExecCGI
AllowOverride All
Order allow,deny
Allow from all
</Directory>

ドキュメントルート以下にメンテ用ファイルを置きたくなかったのでAliasにしましたが、R=503としたのでRewriteRule の飛び先はこの場合何書いても同じだったので – にしました。あと必ず ErrorDocument 503 を定義しておくことです。

他には外部サーバや内部でバーチャルホストを作ってそこにスクリプトを置き、リバースプロキシで転送という方法も思いつきましたがリソースの無駄遣いなので伏せておきます。(本当の理由は自宅サーバにProxy入れて無かった・・・)

Cookieを使ったSQLインジェクション

最近Cookieを使ったSQLインジェクションが発見されたということでその手法の詳細記事がありました。前置きが長すぎてもっと簡潔にして欲しかったのですが問題点は以下のようになります。

  • メジャーな侵入検知システムはPOST/GETの検査を行うがCookieを見逃していた。
  • スクリプト側でPOST/GET等メソッドを明示的に区別してデータ取得していない。
  • スクリプト側で入力データの検査が出来ていない。

元記事には

ここまで聞くと、「うちのサイトではクッキーにデータベースに関連するような情報は格納していないから関係ない」と、早合点する人もいるかもしれない。それは間違いなので、もう少しお付き合いいただきたい。

なんて書いてるからよくよく読んでみましたがCookie使う以前の問題で仕事でウェブプログラミングしているならその会社のスキルを疑って良いレベルです。PGのスキル不足は常にあると仮定してもレビューせずに素通りかPLが無能。PMが放置主義って言ってる様なもので会社でレベルで恥かいてるぞ。私ならこんな杜撰なコード組む会社に2度目の外注はしない。

まずコードの品質を上げる前に侵入検知システム等に頼るのは気が進まないし費用のムダ。これの方法の恐いのは侵入検知システム自体に穴がある場合だけでなく、サーバー移設等環境が変わった場合にミスが起きやすい。ニュースで「サーバーの設定ミスで情報漏えい」というケースがこれ。

次にデータ取得においてメソッドを区別していないのはCookie以前の問題でGETしか想定していないスクリプトでPOSTで渡されてもスクリプトのみでは同じ問題が起きるので注意すること。昔Perlで外部ライブラリなしでコーディングしているときは非常に面倒だと思いつつもどうやってデータがウェブサーバに送られてくるのか勉強になりました。今時よく利用されるASPやPHPはその辺の面倒な処理を自動的にやってくれて組込関数グローバル変数から読み込めますがRequest系の実装は気持ち悪くて使えない。未だにRequestについてGET/POSTを気にせずどっちでも使えるから便利とか発言するPGを見かけるが変数名が重複したときの対処方法を考えていないのが大半。セキュリティはともかくバグの元になる事を想定できていない。そういう人に限ってデバッガ未経験だったりする。

あとニュース記事には書かれていませんがPHPの場合、Requestでなくても$_POSTや$_GETのみで変数を上書きできるから注意ですね。通常リスト構造のデータを受け取るときは配列型にしたほうが便利ですが、それをせず同じ変数名で並べて送ってくるフォームがありそれにも$_POSTや$_GETは対応できないのでPerlの時のように素の入力データから抽出しています。それと同じ方法で本来の変数を上書きされても発見できない場合がありますので注意です。

最後に入力されたデータを検査していないのは論外、今回のセキュリティホールもPOST/GETを想定した変数だとしてもスクリプト側で検査していれば問題になっていない。メソッドを明示していればCookie経由で上書きしようとした変数はその場でイジェクトできるし、Request受けていてもそのデータを検査できていれば良いのである。とは言っても現実はApacheエラーログを見ずに組む人が多い、サニタイズどころかValidateやisset検査すらせずにエラーログを汚しまくる奴もいる。指摘するとErrorじゃなくてWarningだから大丈夫だろうとか言葉を理解できていない人やErrorじゃ無いんだからサーバー側でログ出力止めろよ!と逆ギレする民度の低いPGも少なからず存在する。そういうのに限ってこれまたPHPはPerlと違ってセッション実装できているから凄いとか内部処理を知らずに自慢(それもPHP作った本人じゃないのに)していたことがあって呆れたこともあります。

以上で愚痴込みのまとめは終わりますが、元記事を見てハッと気付いた脅威が一つありました。
最低限の作業として送られてくるデータは特定して検査するように書いているつもりですが、セッション変数はサーバーに保存されているデータなのでそこまでは強制的に検査していませんでした。(ヒマがあればするけれど他人にまで強制していない)

これの何が原因かというと、一度送られたフォームデータ(特にショッピングカート等)は途中ページでの改ざんを防ぐ為にセッション変数として保持することがありますが、保存したセッション変数からデータを再取得するときに検査をしていない場合がありました。近年はCookieに値セットして使うことが無いので完全な見逃しですが、Cookieを改ざんされた時に$_SESSIONが自動的に汚染されないか確認したことが無かった・・・。これは週明け直ぐにでもチェックしてみます。

他にDBとの入出力に対しての検査も、最初はそこまでする必要あるのかな?と思っていましたが仕事で使う内に必須だと思うようになりました。セキュリティ的には外部と接触する部分で一斉検査すれば大体良いのですが、開発途中でDBのデータがいい加減に入力されているとか仕様外の構成になっていたりするとが多く、というかほぼ100%でデバッグの障害になってたりもします。これでPGとDBエンジニアが鶏が先か卵が先かみたいなケンカもします。そこでスクリプト側としてはDBとの入出力にも開発効率を上げるために検査を入れておいたほうが良いと思います。あとApache管理者の意見として、大量のUndefined indexでログを汚すなというのもあります。

またまた進化したSQLインジェクションの脅威 クッキーを悪用 セキュリティー-最新ニュース:IT-PLUS
http://it.nikkei.co.jp/security/news/index.aspx?n=MMIT2g000028102008&cp=1

mod_ktaiに画像変換モジュールを追加

最近登場した携帯サイト用Apacheモジュールのmod_ktaiに画像変換モジュールが追加され、端末の仕様に合わせて自動変換を行うようです。確かにGDやImageMagickで毎回変換すると大量アクセス時に重くなるし、だからといってファイルに変換して置くのも移設とか面倒になるし、Keitai Pictureはバージョンアップするごとに検索リスエストがスパム化して返って激重になるし・・・。ということでApacheモジュール大賛成です。負荷試験で効果の比較したのち本格導入検討しようかな。

ゆめみ、Apacheモジュール「mod_ktai」シリーズに画像変換モジュールを追加 – ITmedia +D モバイル
http://plusd.itmedia.co.jp/mobile/articles/0810/30/news130.html

telnetでBASIC認証対応http接続

例えば http://example.com/index.htmlに接続すると仮定してtelnetを用いると

> telnet example.com 80

とコマンドを打ち続いて

GET /index.html HTTP/1.1
User-Agent: Telnet [ja] (Windows)
Host: example.com

と入力してエンター2回押すのですがBASIC認証だとこのままでは弾かれてしまいます。確かサーバーのログを見た感じではリクエストの際にユーザ名とパスワードを同時に送っているっぽいのでググって見たらAuthorizationヘッダで実現しているサンプルがありました。

Authorization: Basic aG9nZTpmdWdh

といった感じでAuthorization: +認証種別+BASE64エンコードされた文字列のようです。(今まで素で送っているものと思ってた。。。盗聴されれば本当のユーザ・パス知るまでもないのですが)

BASE64のコードを生成するには私の環境ではopensslを用いる方法を取ってみました。

> echo -n ‘hoge:fuga’ | openssl enc -e -base64
aG9nZTpmdWdh

いい加減、自由にヘッダの設定できるカスタムブラウザ作らないとな…。(携帯3キャリ全機種のプロファイルを登録できるような形で)

HTTP クライアントを作ってみよう(5) – Basic 認証編 –
http://x68000.q-e-d.net/~68user/net/http-auth-1.html

Linuxコマンドの有効活用

ちょっとしたTipsですがこれは便利ですね。意外とコマンドのオプションって実装が違ったり、バージョンアップで増えていても気がつかなかったりするので定期的に見直してみるのも良いかもです。

$_

直前に打ったコマンドの最後の引数。
これはシェル組んでいると結構使ってますね。

watch -d ls -l

活用方法がわからなかったのですが、そういう使い道があったんですね。

cd –

直前にいたディレクトリへジャンプ。この方法の存在は知っていましたが、一回忘れてしまってからずっと思い出せないままでした。

mkdir -p

これは絶対使う。特にインストーラーやシェルバッチで!

あなたが知らないかもしれないLinuxのコマンドいろいろ  IDEAIDEA
http://www.ideaxidea.com/archives/2008/06/linux.html