翻訳者からのお願い: このドキュメントはセキュリティに関する設定説明です。できるだけ間違いのないように注意して翻訳していますが、正確を期する必要があります。セキュリティに詳しい方の査読を強く希望します。このドキュメントを参考にDokuWikiのセキュリティ設定を行う場合、翻訳内容に疑義があるときは必ず原文を参照するようにしてください。
Webアプリケーションのセキュリティについての一般的な情報は、Security Discussionを参照してください。
DokuWikiのセキュリティに関する問題の情報を得るには、freshmeat.net/projects/dokuwiki/でDokuWikiプロジェクトを購読してください(購読時のオプションで「Permit the owners of the project to include me in subscriber emails」をチェックしてください)。購読するにはFreshMeatのアカウントが必要です。 現在はバグトラッキングシステムですべてのセキュリティに関する情報を得られます。
DokuWikiに関するセキュリティ問題を発見した場合は、まず個人的にメンテナにご連絡ください。
bugで報告される場合は、公開スペースであることをよく考慮してください。
DokuWikiデフォルト設定では、誰でもWikiに対するアクセスと変更が許可されています。DokuWikiがインストール されたら、すぐに誰かがアクセスできる状態になります。初期設定を行っている間は、外部からのアクセスを 拒否すべきです。
Apache Webサーバを利用している場合は、DokuWikiのインストールディレクトリに置かれた.htaccessファイル の先頭に以下の記述をすることで、外部からのアクセスを拒否できます。
Deny from all Allow from 192.168.1.1
“192.168.1.1”の部分は、ご自身のIPアドレスに置き換えてください。IPアドレスはhttp://www.whatsmyip.org/で調べることができます。
eth0を介してインターネットに接続しているLiuxターミナルで、コマンドifconfig eth0を打ち込めばIPアドレスがわかります。 ただし、ルータはコンピュータとは異なるIPを持っている場合がありますので注意してください。
IPアドレスを他人と共有している場合、同じIPを共有している人もDokuWikiにアクセスできます。
プロキシや無線ルータの内側(職場、学校、AOLなどのISPなど)から接続している場合にこの状態が生じます。
Wikiを正式公開するときには、.htaccessに追加した拒否設定を削除するのを忘れないようにしてください。
fmode/dmodeはファイル/ディレクトリを作成する際のモードです。この値はできるだけ厳しく制限するように設定してください。 この設定はDokuWikiをセキュアにする上で非常に大切です。詳細はpermissionsを参照してください。
必須 - デバッグ出力には公開によって潜在的な危険性が生じる情報が多く含まれています。
DokuWikiのconfigディレクトリに配置されているconf/local.phpファイルを編集し、以下の行を追加してください。
$conf['allowdebug'] = 0;
permissionsのページのとおりにパーミッションを設定した場合、conf/local.phpファイルの所有者はApacheのユーザになっているはずです。この場合、あなたがroot権限を持っていないなら少し問題が生じます。DokuWikiを自分のホームディレクトリのどこかにインストールしているとしましょう。すべてのディレクトリの所有者はあなた自身です。DokuWikiが動作するようにするためのパーミッション設定は、confディレクトリのグループを変更しグループに書き込み権限を与えることです。Apacheによってlocal.phpが作成されたときのデフォルト状態では、あなたはこのファイルの読み取りと削除が可能ですが、変更はできません。これを解決するには、まずlocal.phpをエディタで開いてテキストを切り取ってどこかに一時的に保存します。次にlocal.phpを削除し、先ほどのテキストを貼り付けたlocal.phpを作成します。最後にlocal.phpのグループをApacheユーザのグループに変更し、グループに対して書き込み権限を与えます2)。
DokuWikiは、Wikiページからリンクされている外部画像などをlib/exe/fetch.phpスクリプトによりローカルWebサーバ上にコピーします。これによって、一定したパフォーマンスの提供、およびリモート画像のリサイズが可能になります。リモートソースからダウンロードするファイルのサイズを制限したい場合は、$conf['fetchsize']オプション(単位はバイト)を設定するとよいでしょう。0を指定すると外部ソースのキャッシュが無効になります。
mod_rewriteを使うことでログイン時にHTTPSを強制することができます。この設定を行うことで平文のパスワードがネットワーク上に流れることを防止できます。
この設定を行うには、Apache設定ファイルに以下の行を追加します。
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteCond %{QUERY_STRING} do=log
RewriteRule ^(.*) https://%{HTTP_HOST}/$1 [R,QSA,L]
サーバ名とSSL証明書のホスト名を一致させるために${HTTP_HOST}を${SERVER_NAME}変更する必要があるかもしれません。
Posted by Travis Sidelinger: travis [at] ilive4code [dot] net - 2006Oct01
「ログアウト」をクリックしたときにもログインページが送られます。したがって、do=loginをdo=log(in|out)に置き換えると少し改善になるでしょう。
— Gerard Neil 2007-01-27 04:01
質問: mod_rewriteの機能でログイン後非SSLに戻すことはできますか? — Alex Popov 2007-10-31 14:03
いろいろ試した結果、どうにかできました。ログイン/ログアウト以外のすべてのページで非SSLを使うには、上記の設定の後に以下の行を挿入します。
RewriteCond %{HTTPS} on
RewriteCond %{QUERY_STRING} !do=log
RewriteCond %{REQUEST_METHOD} GET
RewriteRule ^(.*) http://%{HTTP_HOST}/$1 [R,QSA,L]
GETをテストしている行に注意。これがないとログインページがエラーになり、メインページに戻されます(doku.phpにPOSTしないとリダイレクトのときにパラメータが失われるため)。
— wirehead [at] notapattern [dot] net 2007-Jan-04 23:00
クッキーが失われる問題の修正
私の場合、HTTPとHTTPSが切り替わるときにログイン時にセットされたクッキーが失われるという問題が発生しました。対象は2007-06-26b(およびおそらくそれ以前の)リリースです。この問題について説明します。上記のコードを使ってログイン/ログアウトのURLをSSL暗号化ページのものに書き換え、ログイン後セキュアでないHTTPページにリダイレクトするようにしたのですが、このときクッキーが失われてしまうのです。相対URLではなく絶対URLでクッキーがセットされていたことが原因でした。このため、クッキーはHTTPSのサイトのみに結び付けられていたのです。だからHTTPに戻ったときに「まったくログインしていない」状態になってしまっていたわけです。デフォルトの$conf['canonical'] = 0が適用されている状態で発生したことを付記しておきます。
これを修正するには、inc/init.phpを次のように修正します。
- if (!defined('DOKU_COOKIE')) define('DOKU_COOKIE', 'DW'.md5(DOKU_URL));
+ if (!defined('DOKU_COOKIE')) define('DOKU_COOKIE', 'DW'.md5(DOKU_BASE));
また、パスワードの変更ができる「ユーザー情報の更新」のページと「ユーザー管理」などがある「管理」ページも暗号化するために、以下のような書き換え条件/ルールをお勧めします。
2008-03-28更新: RewriteRuleを少し変更しました。以前のものは、サーバルートのサブフォルダにWikiを配置している場合に正しく動作しませんでした。新しいコードは、Webサーバのサブディレクトリに複数のDokuWikiをインストールしている場合でも正しく動作するはずです。
# We want to encrypt all pages over which passwords might be sent
# Includes: login, logout, profile (password change), admin menu (user manager)
RewriteCond %{HTTPS} !on
RewriteCond %{QUERY_STRING} do=(log|profile|admin)
RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,QSA,L]
# Change back to non-secure for all other pages
RewriteCond %{HTTPS} on
RewriteCond %{QUERY_STRING} !do=(log|profile|admin)
RewriteCond %{REQUEST_METHOD} GET
RewriteRule ^(.*) http://%{HTTP_HOST}%{REQUEST_URI} [R,QSA,L]
この解決策を見つけるまでしばらく苦労しました(分かってしまえば簡単なんですが)。これがほかの方の時間の節約とイライラ解消に役立てばと思います。ググレカス3)してもこのページしかヒットしなくて大変だったので…
— poonh [at] mcmaster [dot] ca 2008-Jan-23 18:25 EST
poonhさん、解決策の投稿ありがとうございます。とても助かりました
。ただ、Firefoxで「セキュリティ警告: 暗号化されていない情報を含んでいます」という警告が出てしまいます。js.phpやss.phpに対するリクエストが非セキュアなHTTPのURIにリダイレクトされてしまうためです。そこで次のような「センドバック」用のコードを追加してはどうでしょう。
# Change back to non-secure for all other pages
RewriteCond %{HTTPS} on
RewriteCond %{QUERY_STRING} !do=(log|profile|admin)
RewriteCond %{REQUEST_URI} !\/css.php
RewriteCond %{REQUEST_URI} !\/js.php
RewriteCond %{REQUEST_METHOD} GET
RewriteRule ^(.*) http://%{HTTP_HOST}/$1 [R,QSA,L]
この方法でセキュリティ上の問題はありますか?なにかセキュリティ上の問題が残ってないでしょうか?あれこれ考えるのが好きなもので。 — Andy Turner 2008-Mar-25 13:48 GMT
理論的には、一部のファイルが暗号化されない接続で取得されても問題(セキュリティ的に)ないと思います。なぜなら、それらには機密情報が含まれているわけじゃないですから。個人的には、パスワードの伝送路が確実に暗号化されていれば十分だと思います。さらにあなたが提案された上記のコードは、問題を完全に解決しているわけではありません(あなたがおっしゃっているとおり、「センドバック」してるだけですから)。最初のリダイレクトでHTTPS/HTTP混在でコンテンツが取得される問題は解消してません。
最初のリダイレクトで混在での取得って起きますか?よくわかりません。どなたか説明してくださるとうれしいのですが。私はこんな風に考えています。まず、ログインページをHTTPでリクエストする、次にサーバがリクエストをHTTPSページにリダイレクトする。この流れになるのは、リクエストすべきJSやCSSがわかっている場合だけです。だからJSやCSSのリンクが現在のページからの相対URLで指定されていれば、ブラウザは同じサーバ(つまりHTTPS)にリクエストを投げるはずです。私が提案したコードを入れない場合はこれらのJSなどへのリクエストはHTTPサーバにリダイレクトされてしまいますが、このコードを追加することでHTTPS経由で返されるようになるはずです。だからあなたがおっしゃる混在リクエストがいつ起きるのかわかりません。 — Andy Turner 2008-Mar-28 17:45 GMT
さらに検討してみました。たくさんのJavaScriptやCSSのインクルードファイルなどのページコンテンツは、平文で取得されます。このため、ブラウザがHTTPSとHTTPの混在を警告するわけです。あなたがおっしゃる相対URLのことは分かりました。問題は提案のコードのRwriteCondに含まれている例外処理は十分でないということです。Wiresharkなどのパケットキャプチャツールを使えば、ブラウザが大量のセキュアでないHTTP GETリクエストを発行しているのが観察できると思います。JPG、PNG、ICO、GIF、そのほかたくさんの例外処理が必要なんです。エレガントに処理できる方法があると思うのですが、今のところ思いつきません。
— poonh [at] mcmaster [dot] ca 2008-Apr-01 02:23 EDT
How can I make some pages non-writable?を参照してください。
上記以外にセキュリティ/プライバシーに関係のある設定項目を以下に示します。すべてを網羅したリストというわけではありませんので注意してください。
「任意」の項目も含めて以下の設定を行うことを強く推奨します。面倒な作業ですが手間をかける価値があるはずです。
ここで説明する設定の目的は、どうしてもドキュメントルート4)配下に置く必要があるスクリプト以外のファイルをできる限りドキュメントルートの外に配置することです。
この項で提案する方法のアウトラインは次のようになります。一般的なUnixベースの共有ホストを利用し、ホームディレクトリが/home/yourname、ドキュメントルートディレクトリが/home/yourname/wwwであるとします。ここで/home/yourname/dokuwikiというディレクトリ(ドキュメントルートの外側)を作成し、DokuWikiのパーツをこのディレクトリ配下に配置します。それでは詳しく説明していきましょう。
IISをご利用の場合:
ダイアログやチェックボックスの名前は、ドイツ語版IISのUIからの翻訳です。英語版IISの正しいUI名とは違っているかもしれません(訳注: 日本語のUI名がわかる方!修正をお願いします。)
(必須 - たとえ.htaccessで保護していても、このディレクトリは絶対に公開領域に置いたままにすべきではありません)
binディレクトリをドキュメントルートの外に移動するか、完全に削除します。このディレクトリに収納されているのは、コマンドラインからのみ利用するスクリプトであり、公開領域においたままにすべきではありません。
シェルを使えない環境をご利用の場合、このスクリプトを利用することはないはずです。残しておいても無意味なので、単純にディレクトリごと削除してください。削除してしまってもDokuWikiの動作には問題ありません(これらのスクリプトはDokuWikiの動作に必須ではない)。
(任意 - ディレクトリを.htaccessで保護していても、つねに安全というわけではありません)
dataディレクトリとその配下のmedia、atticディレクトリをドキュメントルートの外に移動します。
手順は次のとおりです。
dataディレクトリとその中身をドキュメントルートの外に移動するdataの位置を指すように設定する
たとえば、dataディレクトリを/home/yourname/dataに移動した場合は、conf/local.phpを次のように編集します。
$conf['savedir'] = '/home/yourname/data';
mediaおよびatticディレクトリはdataのサブディレクトリですので、上記の手順でこれらのディレクトリのセキュリティ設定も完了です。
(任意 - ディレクトリを.htaccessで保護していても、つねに安全というわけではありません)
configサブディレクトリをドキュメントルートの外に移動します。これは現行バージョンのDokuWikiではすこし面倒です。今のところもっとも容易なアプローチは、PHPのini設定のauto-prepend-fileを使う方法でしょう。auto-prepend-fileを設定して、新しいconfigディレクトリの位置を指す定数を定義する簡単なPHPファイルを読み込ませます。
一般的な共有ホストでは、まず、以下の内容で/home/yourname/dokuwiki/prepend.phpを作成します。
<?php define('DOKU_CONF','/home/yourname/dokuwiki/conf/');
(意図的にPHP処理命令を閉じていません。最終行に「?>」を追加しないようにしてください。)
次にconfディレクトリを/home/yourname/dokuwiki/に移動して、/home/yourname/dokuwiki/confを作成します。
最後にドキュメントルートの.htaccessファイル(/home/yourname/www/.htaccess)を編集して、次の行を追加します。
php_value auto_prepend_file "/home/yourname/dokuwiki/prepend.php"
この行は、ほかのスクリプトの前にprepend.phpを実行するようPHPに指示します。ここで定数を定義することで、DokuWikiのinc/init.phpで後から設定される値を上書きすることができます。
(任意 - ディレクトリを.htaccessで保護していても、つねに安全というわけではありません)
理論的には特に危険なことはないのですが、やはりこのコードを公開領域に置く理由もありません。後悔するよりは安全を追求しましょう。最初に断っておきますが、このステップではシェルからサーバにアクセスすることが必要です。ここまでのステップではすべてFTPクライアントから操作できたのに比べると、少し敷居が高くなります。
前のステップでconfigディレクトリをドキュメントルートの外に移動しているはずですので、最初の手順は既存のprepend.phpに次に示すとおりに更新します。
<?php define('DOKU_CONF','/home/yourname/dokuwiki/conf/'); define('DOKU_INC','/home/yourname/dokuwiki/');
次にincディレクトリを/home/yourname/dokuwikiに移動して/home/yourname/dokuwiki/incを作成します。さらにlibディレクトリを移動して、ドキュメントルートにシンボリックリンクを張る作業が必要です。次のコマンドを実行してください。
$ mv /home/yourname/www/dokuwiki/lib /home/yourname/dokuwiki $ ln -s /home/yourname/dokuwiki/lib /home/yourname/www/dokuwiki/lib
上のコマンドを実行すると、ドキュメントルートにlibのシンボリックリンクが作成され、なおかつDOKU_INCが正しく解決できる状態を作ることができます。
この項はwiki:config:phpにマージして、ここにリンクした方がよいのではないでしょうか。
以下に示すのは一般的な「グッドプラクティス」です。PHPのセキュリティ強化策一般についての参考資料としては、Apache Securityの第3章(ここからPDF形式で入手可)をお勧めします。
自由にコントロールできるサーバでDokuWiki/PHPを運用している場合、chroot jail環境を検討されているかもしれません。ネット上にはさまざまな情報があふれていますが、もっとも完全、正確、かつ効果的な情報はおそらくApache + Chroot + FastCGI + PHP FAQでしょう。
以下の設定には、/home/yourname/www/.htaccessの.htaccessを編集する必要があります。
IISの場合:
(任意 これはよいアイディアです - 与える情報が多いほどアタックは容易になります)
公開ドキュメントルートディレクトリの.htaccess(/home/yourname/www/.htaccess - httpリクエストに対して公開されているindex.phpやdoku.phpが格納されているディレクトリ)に以下の行を追加します。
# Disable display of public PHP error messages php_flag display_errors "off" # Log all PHP errors to a file in private directory ( and not in the Dokuwiki data dir either! ) # here you'd need to create the directory and the file then make sure the file has world write # permissions php_flag error_log "/home/yourname/logs/errors.log" # Don't keep reporting the same error again and again (keep log file smaller) php_flag ignore_repeated_errors On # Dokuwiki generates a lot of notices... best prevent reporting them # in .htaccess files E_ALL, E_NOTICE have no effect, you must use the # values from http://www.php.net/manual/en/function.error-reporting.php # E_ALL & ~E_NOTICE => 2047 - 8 => 2039 (Note: E_ALL is different for 5.2.x and above, see # http://www.php.net/manual/en/ref.errorfunc.php#errorfunc.constants.errorlevels.e-all) php_flag error_reporting 2039
上記の設定で指定されているディレクトリとログファイルを作成するために、次のコマンドをシェルから実行します。
$ mkdir ~/logs $ touch ~/logs/errors.log $ chmod 662 ~/logs/errors.log
PHPがファイルを見つけられなかった場合、自動的に作成されることはありません。その結果、エラーメッセージは捨てられることになります。また、ログファイルのサイズが大きくなりすぎないように対策する必要があります。サイズを抑制する簡単な方法を以下に示します。
$ tail -100 ~/logs/errors.log > ~/logs/errors.log
このスクリプトは、ログファイルの最新の100行を確保して元のログを上書きします。このスクリプトを週1回程度cronで実行するとよいでしょう。
Linux/Unix上のApacheで稼動しているDokuWiki用の手順です。CentOS 4.4で検証しています
PHPのセキュリティ設定では次の2つのオプションが非常に重要です5)。
まず、以下の行をhttpd.confまたは/wiki/.htaccessに追加します。
# dokuwiki is installed in : /var/www/html/wiki/
# your php pear packages are in : /usr/share/pear/
# php is installed in : /usr/lib/php4/
# use a new tmp directory in : /var/www/html/wiki/tmp/
<Directory /var/www/html/wiki>
php_admin_flag safe_mode On
php_admin_value safe_mode_exec_dir "/usr/lib/php4"
php_admin_value safe_mode_include_dir "/usr/share/pear/"
php_admin_value open_basedir "/var/www/html/wiki/:/var/www/wiki/:/usr/share/pear/"
php_admin_value upload_tmp_dir "/var/www/html/wiki/tmp/"
</Directory>
次に、Linux/Unixの次のコマンドでwikiディレクトリのパーミッションを設定します。
# chown apache:apache -R /var/www/html/wiki/
ホスティングプロバイダにシェルアカウントを持っていない場合、またはDokuWikiのアップロードにftpだけを使っている場合はパーミッションは自動的に設定されているはずです。chownを実行する必要はありません。
上の行で言っているのはtelnetとかのことでしょうか?私の今のプロバイダではコマンドラインは使えません。ざっと説明すると、私はまずこのページを見て.binディレクトリを削除し、./dataディレクトリを移動しました。ところが、Filezillaで古い方の./dataディレクトリを削除できないんです。”ディレクトリが空じゃない”と怒られたので、ファイルがあるサブディレクトリに移動したんですが、削除しようとしてもPWDコマンドしかできないみたいなんです。どうにもならない状態です。このページに書いてあることは私のところではできないんでしょうか?それとも何かバカな間違いをしているんでしょうか。初心者にわかるように説明していただけないでしょうか。初心者が大多数だと思うので。。。
chownコマンドのようにオーナーやグループを変更できるftpクライアントがあるかどうかは知りませんが、あなたのプロバイダはファイルのオーナーやグループ属性を変更する権限を与えてないんでしょう。だから「あなたの」ファイルを削除できないのでしょう(きっと所有者があなたじゃないんです)。fmode/dmodeを厳しく(8進値で666/777より小さい値にしているとか。特に3番目の数字)設定しているとしたら、書き込まれたファイルを自分では削除できないはずです。なぜなら、それらのファイル(DokuWikiが作成したファイル)の所有者がWebサーバになっているから。permissions、fmode、hostedあたりを参考にしてください。/Leif
上記はWebサーバがApacheでユーザapacheの権限で動作していると仮定しています。この設定が必要になるのは、PHPスクリプトが.phpファイルの所有者のユーザ権限で実行されるためです。
DokuWikiではユーザーの貢献によるたくさんのプラグインが利用できます。こうしたプラグインはDokuWikiとは別に思い思いの方法で配布されています。そのため、DokuWikiのコードベースと同じような十分な管理やレビューがなされているわけではありません。プラグインを利用する際に留意すべき点をいくつか挙げておきます。
libディレクトリ配下にインストールされるが、このディレクトリはドキュメントルート配下に公開しなければならない。したがって、プラグインにどのようなコードが含まれているか慎重にレビューする必要がある。さらに.htaccessで適切に制限をかける必要がある
なぜわかりました。noteプラグインのように自分のディレクトリの中のファイルにリンクしているプラグインもあるからですね。 / Viktor
prepend.phpの中でほかの定数と一緒にDOKU_PLUGINを定義して、プラグインをドキュメントルートの外に置くことはできないんですか?
質問: DokuWikiでもMizillaのhttps://addons.mozilla.orgみたいなことはできないんでしょうか。
MozillaのサイトにはMozillaプロジェクト(Firefox、Thunderbirdなど)のためのレビュー済みのプラグインがたくさん置いてあります。安定していてセキュアなプラグインだけがサイトに置いてもらえます。プラグインをあそこからインストールする限り、よく分からないサードパーティーと違って比較的安心だと思います。
これからDokuWikiが有名になるにつれて、プラグインの脆弱性へのセーフガードが重要になってくるんじゃないでしょうか。
charlieMOGUL 07-12-2006 10:00 GMT +01:00
University
このページはSecurityの2008/06/12 03:09に更新されたリビジョンを元に翻訳しています。オリジナル文書の新しい更新に気づいた方は、差分を参照してアップデートしてください。
Original English revision: Security –2008/06/12 03:09
Please update this translation, if you notice the change in original English version.
翻訳を更新したら以下に日付つきの署名を追加してください。
Add your signature here if you created, translated or modified whole or part of this page.
マニュアル翻訳の品質向上のために査読(翻訳チェック)にご協力ください。誤字、脱字、訳抜け、わかりにくい訳語などの修正、技術的な観点からのブラッシュアップなど、お気づきの点がありましたらどんどん修正してください。査読を完了したら以下に日付つきの署名を追加してください。
To improve the quality of manual translation, please check this translation. Add your signature here if you improved this translation.