WordPress の wp-config.php を安全に公開ディレクトリ外に配置する方法【PCI DSS準拠】

2025年4月からクレジットカードセキュリティガイドラインというものが実施され、WordPressのサイトにおいて、日本国内のレンタルサーバーにおいて「データディレクトリの露見に伴う設定不備への対策」がうまく出来ないと考えていたのですが、ふと閃きまして、完全に対応ができる方法を見つけました。

はじめに

この記事では、クレジットカード決済を扱うECサイトなどで求められる「PCI DSS セキュリティ基準」や「クレジットセキュリティーガイドライン」に対応するため、WordPress の重要な設定ファイル(wp-config.php)を公開ディレクトリ外に安全に配置する方法を解説します。

⚠️ 重要な注意事項

  • この記事の内容は技術的な実装方法を紹介するものであり、動作を保証するものではありません
  • 実装は自己責任でお願いします
  • サイトに不具合が生じた場合、復旧できるようバックアップを必ず取得してください
  • 実装サポートが必要な場合は、ページ下部の「サポート依頼」をご覧ください

動作確認環境

  • レンタルサーバー: Xserver
  • PHP: 8.0以上
  • WordPress: 6.0以上

他のサーバー環境では動作が異なる可能性があります。


なぜこの対策が必要なのか?

クレジットセキュリティーガイドラインの要求事項

日本のクレジットカード業界では「クレジットセキュリティーガイドライン」において、以下の対策が求められています:

データディレクトリの露見に伴う設定不備への対策

  • 公開ディレクトリには、重要なファイルを配置しない
  • 特定のディレクトリを非公開にする
  • 公開ディレクトリ以外に重要なファイルを配置する

従来のWordPressの問題点

通常、WordPress の設定ファイル(wp-config.php)は公開ディレクトリ(public_html)内に配置されています:

/home/username/
└── public_html/
    ├── wp-config.php  ← データベース情報が記載された重要ファイル
    ├── wp-content/
    ├── wp-includes/
    └── index.php

この配置では、Web サーバーの設定ミスやプラグインの脆弱性により、wp-config.php の内容が漏洩するリスクがあります。


解決策:セキュアローダー方式

本記事では、以下の構成でセキュリティを強化します:

/home/username/
├── wp-configs/              ← 非公開ディレクトリ(新規作成)
│   └── site1-wp-config.php  ← 実際の設定ファイル
└── public_html/
    └── site1/
        ├── wp-config.php    ← セキュアローダー(軽量版)
        ├── wp-content/
        └── index.php

この方式のメリット

セキュリティ

  • 設定ファイルが公開ディレクトリ外に配置される
  • 複数の検証レイヤーで攻撃を防御
  • PCI DSS要件に準拠

パフォーマンス

  • 追加オーバーヘッド: わずか0.3ms
  • OPcache使用時はほぼゼロ
  • 体感速度に影響なし

保守性

  • 既存の wp-config.php をほぼそのまま使用可能
  • 複数サイト管理が容易
  • 標準的な WordPress 構造を維持

実装手順

ステップ1: バックアップの取得

必ず最初にバックアップを取得してください。

# 既存の wp-config.php をバックアップ
cp /home/username/public_html/site1/wp-config.php /home/username/wp-config.php.backup

ステップ2: 非公開ディレクトリの作成

SSH またはファイルマネージャーで、公開ディレクトリの外に設定ファイル用ディレクトリを作成します。

# 非公開ディレクトリ作成
mkdir -p /home/username/wp-configs
chmod 500 /home/username/wp-configs

Xserver のファイルマネージャーを使用する場合:

  1. ファイルマネージャーにログイン
  2. /home/username/ に移動 注: ドメインが設定されている場合は[/home/username/domain/]となる
  3. 「フォルダ作成」で wp-configs を作成

ステップ3: 設定ファイルの移動と編集

3-1. 既存の wp-config.php をコピー

cp /home/username/public_html/site1/wp-config.php /home/username/wp-configs/site1-wp-config.php

3-2. セキュリティトークン検証を追加

/home/username/wp-configs/site1-wp-config.php をテキストエディタで開き、ファイルの先頭(<?phpの直後)に以下を追加します:

<?php
// ===============================================
// セキュリティトークン検証(LFI対策)
// ===============================================
if ( ! defined( 'SECURE_CONFIG_LOADER' ) || SECURE_CONFIG_LOADER !== true ) {
    http_response_code( 403 );
    header( 'HTTP/1.0 403 Forbidden' );
    die( 'Direct access not allowed.' );
}

// タイムアウト検証(リプレイ攻撃対策)
if ( defined( 'CONFIG_LOAD_TIME' ) && ( microtime( true ) - CONFIG_LOAD_TIME ) > 1.0 ) {
    die( 'Configuration load timeout.' );
}

// 以下、既存のwp-config.phpの内容

ポイント:

  • この2つのチェックを追加するだけで、既存の wp-config.php の内容はそのまま使えます
  • データベース情報などの設定はすべてそのまま残します

3-3. パーミッション設定

chmod 400 /home/username/wp-configs/site1-wp-config.php

ステップ4: セキュアローダーの配置

/home/username/public_html/site1/wp-config.php を以下の内容に完全に置き換えます:

<?php
/**
 * WordPress 軽量セキュアローダー
 * PCI DSS / クレジットセキュリティーガイドライン準拠
 * 
 * @version 1.0.0
 * @description パフォーマンス最適化版
 */

// ===============================================
// エラーハンドリング設定
// ===============================================
ini_set( 'display_errors', 0 );
error_reporting( 0 );

// ===============================================
// 基本定義
// ===============================================
if ( ! defined( 'ABSPATH' ) ) {
    define( 'ABSPATH', __DIR__ . '/' );
}

// セキュリティトークン
define( 'SECURE_CONFIG_LOADER', true );
define( 'CONFIG_LOAD_TIME', microtime( true ) );

// ===============================================
// 最小限のセキュリティ検証
// ===============================================
$raw_dir_name = basename( __DIR__ );

// 致命的な攻撃のみ防止
if ( strpos( $raw_dir_name, "\0" ) !== false ||
     strpos( $raw_dir_name, '..' ) !== false ||
     ! preg_match( '/^[a-z0-9_-]+$/i', $raw_dir_name ) ) {
    http_response_code( 500 );
    die( 'Invalid configuration.' );
}

$site_id = $raw_dir_name;
$config_dir = dirname( ABSPATH, 2 ) . '/wp-configs';
$config_file = $config_dir . '/' . $site_id . '-wp-config.php';

// ファイル存在確認
if ( ! file_exists( $config_file ) || ! is_file( $config_file ) ) {
    http_response_code( 500 );
    die( 'Configuration file not found.' );
}

// パストラバーサル防止
$real_config = realpath( $config_file );
$real_config_dir = realpath( $config_dir );

if ( ! $real_config || strpos( $real_config, $real_config_dir . '/' ) !== 0 ) {
    http_response_code( 500 );
    die( 'Security violation.' );
}

// ===============================================
// 設定ファイル読み込み
// ===============================================
require_once $real_config;

重要な注意:

  • $site_id = $raw_dir_name; の行で、現在のディレクトリ名(例: site1)を自動取得します
  • この名前と設定ファイル名(例: site1-wp-config.php)が一致している必要があります

ステップ5: 動作確認

  1. ブラウザでサイトにアクセス
  2. 正常に表示されることを確認
  3. 管理画面にログインできることを確認

エラーが出た場合:

  • エラーメッセージをメモする
  • バックアップから元の wp-config.php に戻す
  • ページ下部の「サポート依頼」を参照

セキュリティ設定の強化

.htaccess でのアクセス制限

/home/username/wp-configs/.htaccess を作成し、以下を記述:

# すべてのファイルへのWebアクセスを拒否
<FilesMatch ".*">
    Require all denied
</FilesMatch>

ログディレクトリの作成(オプション)

mkdir -p /home/username/logs
chmod 700 /home/username/logs

エラーログを記録したい場合は、ローダーファイルに以下を追加できます:

set_error_handler( function( $errno, $errstr, $errfile, $errline ) {
    error_log( sprintf(
        '[%s] Config Error: %s in %s:%d',
        date( 'Y-m-d H:i:s' ),
        $errstr,
        basename( $errfile ),
        $errline
    ), 3, '/home/username/logs/config-errors.log' );
    
    http_response_code( 500 );
    die( 'Configuration error occurred.' );
    return true;
} );

パフォーマンス最適化

OPcacheの有効化

Xserverではデフォルトで有効ですが、確認方法:

php.iniまたは.user.iniに以下を追加:

opcache.enable=1
opcache.memory_consumption=128
opcache.validate_timestamps=0

本番環境での推奨設定:

opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
```

### パフォーマンス測定結果
```
標準的なwp-config.php              : 0.5ms
セキュアローダー(軽量版)         : 0.8ms (+0.3ms)
セキュアローダー(OPcache有効)    : 0.55ms (+0.05ms)

通常のページ全体の読み込み時間     : 100-1000ms
```

**結論: 0.3msの追加は体感できません(0.03%の影響)**

---

## 複数サイトへの対応

この方式は複数のWordPressサイトを管理する場合にも便利です:
```
/home/username/
├── wp-configs/
│   ├── site1-wp-config.php
│   ├── site2-wp-config.php
│   └── blog-wp-config.php
└── public_html/
    ├── site1/
    │   └── wp-config.php  ← すべて同じローダー
    ├── site2/
    │   └── wp-config.php  ← すべて同じローダー
    └── blog/
        └── wp-config.php  ← すべて同じローダー

ポイント:

  • すべてのサイトで同じローダーファイルを使用
  • ディレクトリ名と設定ファイル名を一致させる(例: blog ディレクトリ → blog-wp-config.php
  • 各サイトの設定ファイルは個別に管理

トラブルシューティング

よくあるエラーと対処法

「Configuration file not found.」と表示される

原因:

  • 設定ファイルのファイル名とディレクトリ名が一致していない
  • 設定ファイルが存在しない

対処:

# ファイル名を確認
ls -la /home/username/wp-configs/

# ディレクトリ名を確認
basename /home/username/public_html/site1

ディレクトリ名が site1 なら、設定ファイルは site1-wp-config.php でなければなりません。

「Direct access not allowed.」と表示される

原因:

  • セキュリティトークン検証のコードが設定ファイルに追加されていない

対処: 設定ファイル(/home/username/wp-configs/site1-wp-config.php)の先頭にセキュリティトークン検証コードを追加してください。

サイトが真っ白になる

原因:

  • PHP のシンタックスエラー
  • ファイルのパーミッション問題

対処:

  1. バックアップから元の wp-config.php に戻す
  2. エラーログを確認(/home/username/logs/config-errors.log
  3. パーミッションを確認
chmod 400 /home/username/wp-configs/site1-wp-config.php
chmod 444 /home/username/public_html/site1/wp-config.php

セキュリティチェックリスト

実装後、以下を確認してください:

  • 設定ファイルが公開ディレクトリ外に配置されている
  • 設定ファイルのパーミッションが400になっている
  • wp-configs/.htaccess で Webアクセス が拒否されている
  • サイトが正常に表示される
  • 管理画面にログインできる
  • プラグインが正常に動作する
  • バックアップが取得されている

まとめ

この実装により、以下が実現できます:

セキュリティ面

  • ✅ PCI DSS 要件に準拠
  • ✅ クレジットセキュリティーガイドラインに対応
  • ✅ 設定ファイルの漏洩リスクを大幅に低減

パフォーマンス面

  • ✅ わずか 0.3ms の追加オーバーヘッド
  • ✅ OPcache 使用時はほぼゼロ影響
  • ✅ ユーザー体験への影響なし

保守面

  • ✅ 標準的な WordPress 構造を維持
  • ✅ 既存サイトからの移行が容易
  • ✅ 複数サイト管理が効率化

免責事項

  • この記事で紹介した方法は、特定の環境(Xserver)での動作確認に基づいています
  • 他のサーバー環境では動作が異なる可能性があります
  • 実装により発生した問題について、当方は一切の責任を負いません
  • 必ず事前にバックアップを取得し、自己責任で実装してください
  • 本番環境での実装前に、テスト環境での動作確認を強く推奨します

サポートのご案内

実装サポート

この実装方法について、以下のサポートを有償で提供しています:

  • 設定代行: お客様のサーバー環境に合わせて実装を代行
  • トラブルシューティング: エラー発生時の原因調査と解決
  • カスタマイズ: 特殊な環境への対応や追加機能の実装
  • セキュリティ監査: 実装後のセキュリティ検証

お問い合わせ

実装サポートをご希望の方は、以下の情報を添えてお問い合わせください:

  1. サーバー環境(レンタルサーバー名、PHP バージョンなど)
  2. WordPress のバージョン
  3. サイト数
  4. 現在発生している問題(トラブルシューティングの場合)