/wp-content/uploads/ を作れない

新規のブロクを使いたいユーザから
「/wp-content/uploads/2007/12 ディレクトリを作成できませんでした。」
という警告がでて、画像がアップロードできないと 噛み付かれた。原因はブラウザ経由ではDirectoryが作れなかったからだ。取りあえず/wp-content/uploads/を作ったけど...
他の正しく動いているblog をみるとuploads のowner は www となっているので wwwとした。これでいいのだろうか?このままだとapache/php経由でだれでもファイルをアップロードできてしまう?。
んでもってphpのセーフモードについての解説を見つけた。わかりやすい。
http://hiromasa.zone.ne.jp/blog/archives/657/ だ。
で原因が分かってきた。
WordPress Japan にあるエラー回避方法があるが、これはWordpressME2.0 のものだ。現在は2.2.3 だ。そのまま適用されるかどうかはわからん。
WordPress ME 2.0 – Docs から
対処方法
その1。あらかじめftpでdirectoryを作っておく
アップロード機能を試す前に、予め手動でディレクトリを作成して書き込み権限を与えるとセーフモードの制限を回避できます。具体的には wp-content 配下に uploads/yyyy/mm を作成してすべてのディレクトリに書き込み権限を与えます。とりあえずは2か月分作成してお試しください。


その2

セーフモード下でどうしてもこの機能を使いたい場合は、wp-admin/inline-uploading.php を CGI として動作させます。アップロード機能を試す前に inline-uploading.php を開き、ファイルの先頭行に以下の記述を追加します。
#!/usr/local/bin/php4php4となっているところはphp5であったりphpであったりします。それぞれのサーバー環境に合わせて記述してください。続けて .htaccess を作成します。拡張子を変更しなくても CGI として動作させるためです。.htaccess は wp-admin ディレクトリに置いてください。
<files inline-uploading.php> AddHandler cgi-script .php </files>後は、inline-uploading.php が実行可能なようにパーミッションを変更します。[700-755]



2006/8/12 Saturday の記事から

セーフモードの束縛 このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加

日記 – 曇時々晴 ひろまさ @ 13:18

WordPress ユーザの間ではおなじみ「セーフモードの束縛」。 WP のプラグインを動かすと、

Warning: fopen() [function.fopen]: SAFE MODE Restriction in effect. The script whose uid is 10358 is not allowed to access cache-phase2.php on line 79

なーんてでちゃって、げんなりという例のアレです。 有名なサーバでは XREA さんがこの PHP のセーフモードに対応しています。
これってなにがセーフなのか、いれてないと何がやばいのか、あほな言葉で解説しているサイトもあまりなさそうなので、おばかな hiromasa.zone でそっと書いてみます。 :-)
セーフモードを説明をするには、まずはファイルパーミッション (FTP で777 とか 666 とかするあれ)のことを書かねばなりません。
時は戻り、インターネット・アンダーグラウンド全盛期。(←戻ってばっか
2000 年より前のインターネット。 「ホームページ」全盛期で、Perl / CGI なんかつかって掲示板とか自前でもっているとちょっとおしゃれな時。 CGI プログラマもレンタルサーバ会社も手探り状態、試行錯誤。 CGI が動く無料サーバを探して一生懸命作った掲示板システムを設置。 パーミッション?よぉくわからないから、とりあえず 777 でいーやみたいな。  動くし。

次の日みたら、何者かの連続投稿で埋め尽くされ、その次の日みたさっぱりした感じに全部消えていた orz

懐かしいね。 連続投稿はともかく、なぁんでログが消え去ったのでしょう? これ、あらかたは同一サーバにいる悪意のユーザに消されたのが原因です。
PHP のセーフモードの存在意義は、上のログ削除のような「共有サーバ上で同じサーバの他人のファイルを勝手に書き換える」ことを防ぐことにあります。 そうです、セーフがはいっていなくて、ある条件がそろうとこれができてしまうのです。
なぜそんなことが起こせるのか。 これには UNIX のパーミッションと PHP の動作が深く関わってきます。
まずは、設置した「ホームページ(html) /CGI/ PHP」がどうやって、ブラウザに表示されているかということろから。
Web で公開されるファイルは一般的に UNIX というオペレーティングシステム上に置かれます。 パーミッションという考え方は UNIX のファイル管理の考え方です。
UNIX 上のファイルを見るには、必ずそのオペレーティングシステムにログインする必要があります。 え、ブラウザでアクセスするとき UNIX にログインなんかしてないじゃん…。 もうその通りで、実際のところは間に Web サーバというソフトウェアが UNIX サーバで動作していて、Web サーバソフトが「UNIXログインの仲介」をしてくれます。 このWeb サーバソフトで一番有名なのが、よくきく Apache というソフトです。
Apache は、ブラウザからのアクセスをうけると、指定された URI (アドレスね) に従って UNIX サーバ上のファイルを抽出し、ブラウザに返してくれます。 Apache が UNIX に常にログインしていて、ブラウザとの間を受け持つイメージです。
次に、パーミッションのお話。
UNIX のパーミッションは、「自分」「グループ」「他人」という3つの登場人物に対して、「読み込み」「書き込み」「実行」という権限を組み合わせてつけること ができます。 FTP で数字が3つ並んでいるのは、左から「自分」「グループ」「他人」に対して、「読み込み」「書き込み」「実行」の組み合わせた数字です。 この辺はみなさ んご存じでしょう。
また、ファイルには所有者の考え方があり、誰のファイルであるか、どこのグループのファイルであるか。 という情報が付与されます。
FTP でファイルをアップロードするということは、自分のユーザID で UNIX にログインしてファイルを作成していることになりますので、そのファイルの所有者にはそのユーザID(自分)が付与されます。(FFFTP などでみることができるでしょう)
適切にファイルのパーミッションを設定することで、他の人から見えないファイルやグループで共有したいファイルを設定することができ、さらに読み込み、書 き込み、実行、の権限をつけることができるわけです。 UNIX はひとつのマシンをみんなで使おうという、マルチユーザ OS ですのでこういった制御が必要になります。
しかしここで話がややこしくなるのが、Apache を介してアクセスしてくる不特定多数の”ユーザ”。
このユーザが誰になるのかってーと、Apache が UNIX 上で動作するのに使っているユーザになります。 詳しくはあれですが、よくあるのは apache とか www って名前のユーザ。 ブラウザからの閲覧者はこの apache とか www とかって名前のユーザに全員なります。(もちろんサイトマスターも、ブラウザでアクセスした場合は apache さんになります)
FTP でアップロードしたファイルの視点からみると、apache とか www ユーザへのアクセス制限は三桁数字一番右の「他人」が適応されます。
そしてもっと話がややこしいのが、 .php などの「動作するファイル」の場合。 ブラウザからアクセスされたとき、だれがプログラムを動作させたことになるのかって話ですが、これも apache さんになります。
たとえば、動作させた PHP の中でプログラムが自動的にディレクトリを作った場合、この所有者は apache さんになります。 動作させた人が、apache さんなのでそうなってしまうのです。
ここまでは、セーフモードとは関係なく、Apache(mod_php) と UNIX の仕様です。
さぁ、PHP セーフモードの束縛の原因がなんとなく分かってきました(?)。
ここで PHP のセーフモードの仕様を読んでみます。 たとえば、ファイル読み書きに使われる fopen 関数。

処理を行うディレクトリが実行するスクリプトと同じ UID を有しているかどうかを確認します。

UID というのは所有者だと思ってください。
FTP で作成した PHP ファイルの UID は、まぎれもなく「あなた」です。 しかしながら、PHP の中で自動的に作られたディレクトリは apache さんになります。 この自動的につくられたディレクトリの中で「あなたがアップロードした」プログラムがファイル操作をしようとすると、これはセーフモー ドの制約にかかってしまうのです。 ファイルをアップロードした人と、アクセス先のディレクトリの所有者が違うからです。
この所有者のミスマッチこそがセーフモードの”束縛”です。
「あなた」と apache の関係だけみると、これはとても都合が悪いのです。 しかし、共有サーバにはいろいろなひとがいっしょにはいっています。「あなた」と「同じ共有サーバの他のユーザ」の関係もあります。
例えば他の人のファイル/ディレクトリ(当然FTP ログインアカウントが違うので UID もちがう)へのアクセスの場合はいい方向(セーフモードの存在意義通り)に”制約”が働き、共有サーバ内どうしのユーザでファイルを書き換えたり(改ざ ん)することを防ぐことができます。 これがセーフモードの役割です。
よくセーフモードの制約を回避するために、apache 所有者でできちゃったディレクトリを削除して、FTP で作り直すのは、PHP とディレクトリの所有者を合わせるためにあります。
さて、セーフが入っていないサーバで、なぜ「改ざん」ができてしまうかというと、データファイルにはファイルパーミッションの「他人」に書き込み権限をつける必要があるからです。 なぜならば、PHP の動作ユーザは apache さんになるから。 しかし「他人」に権限をつけた瞬間、共有サーバの「他のユーザのプログラム」(これも同じく apache さん)からも、同じように(時には悪意の)書き込みできてしまうことになります。
まぁ実際のところ改ざんをするには、URI ではなく “UNIX 的な”ファイルのありか(フルパス)を知る必要があったり、そのフルパスを調べる行為に別のセキュリティがかかっていたりしますので、そうそう簡単にはで きなくはなっています。(みれちゃうサーバもいまだあるみたいだけど…) ただ、エラーメッセージにはフルパスがでてしまうので、この点は注意が必要で す。 エラーログを掲示板などにはるときは、フルパスは隠したほうが良いでしょう。 たとえばこんなのね。

/home/******/public_html

****** にはユーザID とかはいるので、これは隠し通してください。 :-)
全ては、PHP(mod_php) の動作ユーザが全て apache になってしまう仕様に起因していて、これをなんとかしようとしたのが PHP のセーフモードです。 PHP のマニュアルにも、

PHP のセーフモードは、共有サーバでのセキュリティの問題を解決するための試みです。 この問題を PHP のレベルで解決しようとするのはアーキテクチャ上正しくありません。 しかし、Web サーバや OS レベルでの代替策はあまり現実的ではないため、 多くのユーザ、特に ISP ではセーフモードが現在使用されています。

と書かれていて、また PHP 6.0 では削除される予定とのことです。
Perl のCGI 動作などでは、suExec と呼ばれる Apche ラッパーにより、スクリプト所有者 = スクリプト動作ユーザにするという理想的な環境をつくることができます。 もちろん、PHP でも CGI 動作できるサーバではこの方式を使うことが出来ます。 この場合、パーミッションを「700」とかに設定できますので、「他人」からのアクセスは一切出来なくなり、セキュリティ的には一番高くなるでしょう。
2000 年より前くらいのホスティングサーバ(主に無料)は、この suExec もはいっていないところが多く、同一サーバ間で書き換え戦争していて笑っちゃった時期もありました。 で、日本で suExec が入っている数少ないサーバがここだったのです。 なのでみんな使っていたんですね。 :-) まぁPHP は関係ない話ですが。
最近はこの手のはやりもなくなって、やるひともいなくなった、、と思いきやアジア圏ではいまだこの手のお遊びが流行っているようです。 というわけでみなさん、セキュリティには気をつけましょう。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です