URL 書き換えルール
このプログラムの入口は index.php ひとつだけで、すべてのページはそこを経由して振り分けられます。URL 書き換えを設定しないと、トップページ以外は何も開けません。
Docker でインストールした場合、この設定は不要です(イメージに組み込み済み)。
以下の 3 つのルールは意味的に同じものです。書き換えを行うと同時に、公開すべきでないファイル(ログ、データベースダンプ、設定、
.env、composer.jsonなど)へのアクセスも遮断します。最後のlocation /だけを写すのではなく、ブロックごとコピーしてください。
Nginx
宝塔:サイト → 対象サイト → 疑似静的 に貼り付けて保存します。
# 唯一の入口 index.php だけを許可し、それ以外の .php は実行しない
if ($uri ~* "^/(?!index\.php(/|$)).*\.php(/|$)") { return 404; }
location ~* ^/(runtime|kernel|config|vendor)/ { return 404; }
location ~ /\.(?!well-known) { return 404; }
location ~* \.(log|sql|sqlite|db|db-wal|db-shm|bak|old|save|orig|swp|swo|tmp|ini|lock)$ { return 404; }
location ~* (~|composer\.(json|lock)|package(-lock)?\.json)$ { return 404; }
location / {
try_files $uri $uri/ /index.php?s=$uri&$args;
}最初のルールが location ではなく if である理由:宝塔の設定テンプレートでは include enable-php-XX.conf が疑似静的の include より先に置かれており、nginx の正規表現 location は記述順に評価されて最初に一致したところで止まります。そのためここに location ~ \.php$ と書いても永久に到達せず、何も起きないまま無効になります。if はより早い rewrite フェーズで動くので、順序の影響を受けません。
Apache
設定不要です。 プロジェクトルートの .htaccess が対応済みなので、アップロード時に漏れていないかだけ確認してください。
Apache 側で mod_rewrite が有効になっていること、サイトの AllowOverride が None でないことを確認します。
IIS
Windows + IIS では URL Rewrite 2.0 モジュールが必要です。サイトルートの web.config に以下を記述します(宝塔 Windows 版では疑似静的の欄に貼り付けます)。
<rules>
<!-- ① プログラムのディレクトリ -->
<rule name="acg_deny_dir" stopProcessing="true">
<match url="^(runtime|kernel|config|vendor)(/|$)"/>
<action type="CustomResponse" statusCode="404" subStatusCode="0" statusReason="Not Found" statusDescription="Not Found"/>
</rule>
<!-- ② ドットファイル/ドットディレクトリ(ACME 認証は許可) -->
<rule name="acg_deny_dotfile" stopProcessing="true">
<match url="(^|/)\.(?!well-known)"/>
<action type="CustomResponse" statusCode="404" subStatusCode="0" statusReason="Not Found" statusDescription="Not Found"/>
</rule>
<!-- ③ 機微な拡張子 -->
<rule name="acg_deny_ext" stopProcessing="true">
<match url="\.(log|sql|sqlite|db|db-wal|db-shm|bak|old|save|orig|swp|swo|tmp|ini|lock)$"/>
<action type="CustomResponse" statusCode="404" subStatusCode="0" statusReason="Not Found" statusDescription="Not Found"/>
</rule>
<!-- ④ バックアップと依存関係ファイル -->
<rule name="acg_deny_file" stopProcessing="true">
<match url="(~|composer\.(json|lock)|package(-lock)?\.json)$"/>
<action type="CustomResponse" statusCode="404" subStatusCode="0" statusReason="Not Found" statusDescription="Not Found"/>
</rule>
<!-- ⑤ 唯一の入口 index.php のみ許可 -->
<rule name="acg_deny_php" stopProcessing="true">
<match url="^(?!index\.php(/|$)).*\.php(/|$)"/>
<action type="CustomResponse" statusCode="404" subStatusCode="0" statusReason="Not Found" statusDescription="Not Found"/>
</rule>
<!-- ⑥ 書き換え本体 -->
<rule name="acg_rewrite" stopProcessing="true">
<match url="^(.*)$"/>
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
</conditions>
<action type="Rewrite" url="index.php?s={R:1}" appendQueryString="true"/>
</rule>
</rules>URL Rewrite 1.x は
CustomResponseに対応していません。<action type="AbortRequest"/>に置き換えてください(レスポンスボディが空になります)。
requestFilteringのhiddenSegmentsで代用しないでください。 あれはパスのどの階層にも一致するため、管理画面の/admin/config/...や、プラグイン同梱のassets/vendor/・assets/.../config/といった静的リソースまで 404 になります。
サイトルートに他の PHP を置いている場合
上記 3 つのルールはいずれも index.php 以外の実行を許可しません。phpMyAdmin や adminer などをサイトルートに置いている場合は一緒に遮断されるので、そうしたツールは別サイトへ移してください。
設定できたかの確認
次のアドレスにアクセスし、すべて 404 になれば正解です。
あなたのドメイン/composer.json
あなたのドメイン/runtime.log
あなたのドメイン/config/database.phpそのうえで任意の商品ページが正常に開けば、書き換えは効いています。
