LoginSignup
1
0

More than 5 years have passed since last update.

kusanagi 共用サーバーで WordPress 同士を独立させる

Last updated at Posted at 2018-07-17

複数の WordPress を共用サーバーでホストするリスクを軽減する

動作環境

概要

hhvm の機能で共用サーバーの複数サイトの WordPress(または PHP のフレームワーク)でお互いのディレクトリを見えなくします。 URL 毎に vsftp の chroot のような設定をする感じ。

共用サーバーで複数サイトを動かすことのリスク

kusanagi を入れれば非力のサーバーでも WordPress がそれなりの速さが出るようになる。同じサーバーでもういっちょサイト作ってみようかとなるわけです。しかし同一サーバーだとどれか一つでも WordPress の脆弱性を抱えているとそこを起点としてパッチがきちんと当たっている他のサイトも書き換えが可能なわけです。apache とか nginx は単一ユーザーで動かしていますからね。

WordPress の安全性を高める でも触れられています。

サーバーの脆弱性
共用サーバー (同じサーバー上に他の人のサイトがホスティングされている環境) で誰かのサイトが感染すると、たとえこのガイドに従っていた場合でもあなたのサイトも感染してしまう可能性があります。使用している[用語集#Hosting_provider Web ホスト] がどのようなセキュリティ対策を行っているか確かめておいてください。

hhvm の設定で共用サイトのリスクを低減する

共用サーバーで誰かのサイトから影響を受けないようにするためには、よくある答えはそもそも別のサーバーにしろ(AWS あるし)、なのですが、低コスト運用を目指したいのにサーバーの乱立は避けたいところです。そこで、hhvm が持っている vsftp でいう chroot のような機能を使い、サイトをまたいでファイルが見えないようにします(ただし下記で実験しますが OS コマンドインジェクションには効果がありません )。
今回の例での 5 つのサイトについて、サイト毎にどこのディレクトリで動いているかを /etc/hhvm/php.ini足します:

/etc/hhvm/php.ini(追加)
hhvm.server.safe_file_access = true
hhvm.server.allowed_directories[] = /usr/share/pear
hhvm.server.allowed_directories[] = /tmp
hhvm.server.allowed_directories[] = /usr/bin
hhvm.virtual_host[jpvlad][prefix] = jpvlad.com
hhvm.virtual_host[jpvlad][overwrite][server][allowed_directories][] = /var/www/jpvlad/geeklog
hhvm.virtual_host[tft][prefix] = tft-japan.com
hhvm.virtual_host[tft][overwrite][server][allowed_directories][] = /home/kusanagi/tftjapan/DocumentRoot
hhvm.virtual_host[onsa][prefix] = japan-onsa.org
hhvm.virtual_host[onsa][overwrite][server][allowed_directories][] = /home/kusanagi/japan-onsa/DocumentRoot
hhvm.virtual_host[beauty][prefix] = beautyonsa.com
hhvm.virtual_host[beauty][overwrite][server][allowed_directories][] = /home/kusanagi/beautyonsa/DocumentRoot
hhvm.virtual_host[heartbeat][prefix] = heartbeat.selfnavi.com
hhvm.virtual_host[heartbeat][overwrite][server][allowed_directories][] = /home/kusanagi/heartbeat/DocumentRoot

足し終わったら:

# service hhvm restart

説明です

  1. 最初の

    hhvm.server.safe_file_access = true
    

    true でないと、chroot のような機能は動きません。忘れないようにします。

  2. 次に、全サイト共用のディレクトリを設定します。

    hhvm.server.allowed_directories[] = 共用ディレクトリ名
    
  3. 共用ディレクトリの設定の後は各サイト毎設定です。ここでは http(s)://beautyonsa.com については hhvm 内の名前を beauty としています。ご自身の現状とあわせ自由に設定してください。

    hhvm.virtual_host[beauty][prefix] = beautyonsa.com
    
  4. 次に beauty がどこのディレクトリを使うのかを指定します。複数あるときは hhvm.virtual_host[beauty][overwrite][server][allowed_directories][] = の行を足してきます。

    hhvm.virtual_host[beauty][overwrite][server][allowed_directories][] = /home/kusanagi/beautyonsa/DocumentRoot
    
  5. (hhvm のリスタート後)http(s)://beautyonsa.com アクセス時は /usr/share/pear, /tmp, /usr/bin, /home/kusanagi/beautyonsa/DocumentRoot 以外の PHP プログラムを実行しようとしても全部 404 (not found) 扱いとなります。

  6. 3, 4 を繰り返しホストしてるサイト分ほど加えます。 hhvm 内の名前は変更してください。

サイト毎で設定できるのはディレクトリだけではないです。設定できる項目は This is an example of the ini format for hhvm.virtual_hosts をご覧ください。

auto_prepend_file の扱い

PHP では、php.ini

auto_prepend_file =

で PHP 実行毎フックをいれることができます。私の場合ですと php.inimemory_limit 設定に目星をつけるために auto_prepend_file の PHP プログラムで一定以上のメモリーを食う PHP ファイル名をログにだすようにしています(hook.php)。こういうときも共用ディレクトリとして auto_prepend_file = のディレクトリを加えておかないとなりません、例えば、次のように共用ディレクトリ扱いとします( 実行毎フックがなければ追加の必要はありません ):

/etc/hhvm/php.ini(追加)
auto_prepend_file = /home/kusanagi/auto_prepend/hook.php
hhvm.server.allowed_directories[] = /home/kusanagi/auto_prepend

すっかり忘れていると 404 エラーで嵌ることになります。

hhvm.server.safe_file_access = true でどこまで chroot のような効果を出せるのか

hhvm の生死判定をするサイト heartbeat.selfnavi.com でテストしてみます(作り方は 生死判定をするサイトの設置 を参照)。hhvm の設定と共用している各サイトのディレクトリ構成は /etc/hhvm/php.ini にあります。共用サーバーの別のサイトのファイルにアクセスできるかどうか調べるために test.php を置きます。

/home/kusanagi/heartbeat/DocumentRoot/test.php
<?php
    print "*** cat ***\n";
    system('/bin/cat /home/kusanagi/beautyonsa/DocumentRoot/index.php', $result);
    print "*** fopen ***\n";
    $fp = fopen("/home/kusanagi/beautyonsa/DocumentRoot/index.php", "r");
    if (!($fp === false)) {
        while( ! feof( $fp ) ) {
            echo fgets( $fp, 9182 );
        }
        fclose($fp);
    }

次の行で、unix のコマンドから共用サーバーの別のサイトにアクセスできるかどうかを調べます:

system('/bin/cat /home/kusanagi/beautyonsa/DocumentRoot/index.php', $result);

次の行で、php で共用サーバーの別のサイトにアクセスできるかどうかを調べます:

$fp = fopen("/home/kusanagi/beautyonsa/DocumentRoot/index.php", "r");

hhvm.server.safe_file_access = false で動かしてみます

  • cat, fopen とも成功します。普通の動きです
$ wget -qO- http://heartbeat.selfnavi.com/test.php
*** cat ***
<?php
/**
 * Front to the WordPress application. This file doesn't do anything, but loads
 * wp-blog-header.php which does and tells WordPress to load the theme.
 *
 * @package WordPress
 */

/**
 * Tells WordPress to load the WordPress theme and output it.
 *
 * @var bool
 */
define('WP_USE_THEMES', true);

/** Loads the WordPress Environment and Template */
require( dirname( __FILE__ ) . '/wp-blog-header.php' );
*** fopen ***
<?php
/**
 * Front to the WordPress application. This file doesn't do anything, but loads
 * wp-blog-header.php which does and tells WordPress to load the theme.
 *
 * @package WordPress
 */

/**
 * Tells WordPress to load the WordPress theme and output it.
 *
 * @var bool
 */
define('WP_USE_THEMES', true);

/** Loads the WordPress Environment and Template */
require( dirname( __FILE__ ) . '/wp-blog-header.php' );

hhvm.server.safe_file_access = true で動かしてみます

wget -qO- http://heartbeat.selfnavi.com/test.php
*** cat ***
<?php
/**
 * Front to the WordPress application. This file doesn't do anything, but loads
 * wp-blog-header.php which does and tells WordPress to load the theme.
 *
 * @package WordPress
 */

/**
 * Tells WordPress to load the WordPress theme and output it.
 *
 * @var bool
 */
define('WP_USE_THEMES', true);

/** Loads the WordPress Environment and Template */
require( dirname( __FILE__ ) . '/wp-blog-header.php' );
*** fopen ***
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0