さくらのレンタルサーバについて、いくつか独特のクセに遭遇したのでメモしておきます。
.html 拡張子で PHPスクリプト を実行したい
経緯
SEOやセキュリティの観点からか、拡張子は .html
としてあたかも静的サイトであるように見せかけ、実際は内部で PHP が動いている……というケースですかね。
通常のサーバであれば .htaccess
に次のような行(サーバによってパラメータは細かく調整する必要はあり)を追記すれば要求は満たせます。
AddHandler php5-script .php .html
しかし、さくらのレンタルサーバの場合は一筋縄では行かない、というお話。
さくらのレンタルサーバの PHP はモジュール版ではなくCGI版だからでしょうか。
対処
用意するファイルは php.cgi
と .htaccess
の2つ。
php.cgi
#!/bin/sh
exec /usr/local/bin/php-cgi
.htaccess
Action myphp-script /php.cgi
AddHandler myphp-script .php .html
ちなみに両方とも文字コード「EUC-JP」、改行コード「LF」としておきます。 php.cgi
はともかく、 .htaccess
は大丈夫そうな気はするのですが。
参考記事の一つに指示があったのでアップロード時はバイナリモードとします。
また、仮にこの設定をサブディレクトリのみで適用したい場合は2つのファイルをサブディレクトリに置いて
Action myphp-script /SUBDIRECTORY/php.cgi
AddHandler myphp-script .php .html
という形にします。もしパスが間違えている場合は
AH02811: script not found or unable to stat: /home/USERNAME/www/php.cgi
というようなエラーログが記録されます。
仮にサブディレクトリに設置するならば、次のような配置イメージになります。
└ /home/USERNAME/ # ユーザルート
└ www/
└ www/ # ドキュメントルート
└ SUBDIRECTORY/
├ .htaccess # .html拡張子でもPHPスクリプトを動作させるため。 php.cgi とセット
└ php.cgi # .html拡張子でもPHPスクリプトを動作させるため。 .htaccess とセット
$_SERVER[‘DOCUMENT_ROOT’]
2つ目は PHP の $_SERVER['DOCUMENT_ROOT']
の値について。
現象
本体サイトとは別にサブドメインでもサイトを運用する等をするために、ドキュメントルートをコントロールパネルで変更している場合にこの事例に遭遇します。
└ /home/USERNAME/ # ユーザルート
└ www/ # デフォルトのドキュメントルート
├ www/ # 変更したドキュメントルート
│ └ 本体サイト
│
└ SUBDOMAIN/ # サブドメインのドキュメントルート
└ サブドメインの別サイト
例えばこんなディレクトリとドキュメントルートの設定になっているとします。
ここで、 /home/USERNAME/www/www/
に PHP を設置して $_SERVER['DOCUMENT_ROOT']
に代入される値を見てみると……。
想定ではコントロールパネルで変更した /home/USERNAME/www/www/
になっていると思いがちですが、実際は /home/USERNAME/www/
、つまり変更する前のデフォルトのドキュメントルートになります。
これを知らないで PHP で $_SERVER['DOCUMENT_ROOT']
を使って require
や include
をすると、階層がずれるため読み込みに失敗してしまいます。
対処
用意するファイルは path.php
(任意の名前) と .user.ini
の2つ。
path.php
<?php
$_SERVER['DOCUMENT_ROOT'] = $_SERVER['DOCUMENT_ROOT'] . '/www/';
.user.ini
auto_prepend_file = ${DOCUMENT_ROOT}/../php_path_replacer/path.php
文字コードや改行コードは UTF-8, LF で大丈夫です。
これを、 path.php
は /home/USERNAME/php_path_replacer/
(任意ですがユーザから実行されないようにドキュメントルートより上の階層にしておきます) に、 .user.ini
は $_SERVER['DOCUMENT_ROOT']
の値を置換したいPHPの階層にアップロードします。
すると、次のような配置イメージになります。
└ /home/USERNAME/ # ユーザルート
├ php_path_replacer/
│ └ path.php # $_SERVER['DOCUMENT_ROOT'] が狂うのを防ぐため。 .user.ini とセット
│
└ www/
└ www/ # ドキュメントルート
└ SUBDIRECTORY/
└ .user.ini # $_SERVER['DOCUMENT_ROOT'] が狂うのを防ぐため。 path.php とセット
設置のディレクトリ階層のイメージはこのような形。
ディレクトリごとにFTPユーザの権限を設定する
自前の vsftpd ならば
/etc/vsftpd/vsftpd.conf
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
userlist_deny=NO
user_config_dir=/etc/vsftpd/user_conf
/etc/vsftpd/chroot_list
## 空
/etc/vsftpd/user_conf/FTPUSER
local_root=/var/www/example/
とかしてユーザごとのルートディレクトリを決めてしまうのですが、さくらのレンタルサーバではそういったFTPユーザごとにディレクトリを指定することはできません (できるのはドメインごとのルートディレクトリまでで、「同じドメイン内で異なるディレクトリをルートとする」のようなことは不可)。
代わりに .ftpaccess
を使用して一応の権限を設定します。
ルートディレクトリの .ftpaccess
<Limit ALL>
AllowUser rootdir_user@example.com
DenyUser subdir_user@example.com
</Limit>
<Limit CWD CDUP LIST>
AllowUser subdir_user@example.com
</Limit>
Limit ALL
セクション: ルートディレクトリ以下を編集できるユーザに権限を与えますAllowUser
ディレクティブ で全てのコマンドを許可するユーザを指定DenyUser
ディレクティブ コマンドを許可しないユーザを指定
Limit CWD CDUP LIST
セクション: サブディレクトリ用のユーザはログイン時はどうしてもルートディレクトリに来てしまうので、ディレクトリ移動と一覧取得の権限がないとサブディレクトリに入れないため、そこだけ権限を付与しますCWD
,CDUP
,LIST
の3つのコマンドのみ許可するユーザをAllowUser
ディレクティブ で指定
サブディレクトリの .ftpaccess
<Limit ALL>
AllowUser OR rootdir_user@example.com,subdir_user@example.com
</Limit>
.ftpaccess
は .htaccess
と同様、設置したディレクトリ下の全てのディレクトリに影響を及ぼすので、サブディレクトリ用ユーザが編集できるディレクトリには上述の設定を打ち消すように Limit ALL
セクション に追加します。
以上を踏まえると、次のような配置イメージになります。
└ /home/USERNAME/ # ユーザルート
└ www/
└ www/ # ドキュメントルート
├ .ftpaccess # ドキュメントルート用
└ SUBDIRECTORY/
└ .ftpaccess # サブディレクトリ用
余談
仮に全てを組み合わせると次のような配置イメージになります。
└ /home/USERNAME/ # ユーザルート
├ php_path_replacer/
│ └ path.php # $_SERVER['DOCUMENT_ROOT'] が狂うのを防ぐため。 .user.ini とセット
│
└ www/ # デフォルトのドキュメントルート
├ www/ # 変更したドキュメントルート
│ ├ 本体サイト
│ │
│ ├ .ftpaccess # ドキュメントルート用FTPユーザ権限設定
│ └ SUBDIRECTORY/
│ ├ .ftpaccess # サブディレクトリ用FTPユーザ権限設定
│ ├ .user.ini # $_SERVER['DOCUMENT_ROOT'] が狂うのを防ぐため。 path.php とセット
│ ├ .htaccess # .html拡張子でもPHPスクリプトを動作させるため。 php.cgi とセット
│ └ php.cgi # .html拡張子でもPHPスクリプトを動作させるため。 .htaccess とセット
│
└ subdomain/ # サブドメインのドキュメントルート
└ サブドメインの別サイト
流石にカオスですね……。
参考
拡張子 .html で PHP を動かす
- 拡張子.htmlでphpを動作させる | さくらインターネットのVPS設定マニュアル
- さくらのレンタルサーバで.htmlをphpで動作させたい – Qiita
- さくらインターネットのhtml内でphpを実行する方法とエラー対応 | おもてうら倉庫
- さくらサーバー html上でPHPを動かす
$_SERVER[‘DOCUMENT_ROOT’]
- 【公開日:2018年3月14日】レンタルサーバの仕様変更について(2018年3月) – さくらのサポート情報
- $_SERVER[‘DOCUMENT_ROOT’]がおかしい?|BLOG|株式会社エムハンド
- [PHP]$_SERVER[‘DOCUMENT_ROOT’]で値が異なる場合の対処法
- さくらインターネットの「DOCUMENT_ROOT」 | なんかやってみる
- さくらのレンタルサーバーでマルチドメイン利用時のDOCUMENT_ROOT – Scrapdiary
.ftpaccess
概要
ディレクティブ一覧
- ProFTPD module mod_core
Context:
に.ftpaccess
が記載されていれば使えるはず
AllowUserディレクティブ, DenyUserディレクティブ
Limitセクション
Directoryセクション
.ftpaccess
では Directory
セクション は使用できないため、今回は各々のディレクトリに .ftpaccess
を置くことにしました。