2026年8月9日

2026年8月9日

WordPressのMySQLのセキュリティ設定

はじめに

WordPressのデータベース(MySQL/MariaDB)はサイトの全データを保管する重要なコンポーネントです。デフォルト設定のままでは権限過剰・リモートアクセス開放・不要なユーザーが残るなど、深刻なセキュリティリスクが存在します。

症状・原因

  • WordPressのDBユーザーにALL PRIVILEGESが付与されている
  • MySQLが0.0.0.0でリスニングしてインターネットからアクセス可能
  • rootユーザーにパスワードが設定されていない
  • 不要な匿名ユーザーやテストデータベースが残っている

解決手順

ステップ1:現在のMySQL設定を診断する

# MySQL のバージョン確認
mysql --version

# リスニングアドレスを確認(0.0.0.0 は危険)
sudo ss -tnlp | grep :3306

# MySQL に接続して状態を確認
mysql -u root -p

# 接続後に実行
SHOW VARIABLES LIKE 'bind_address';
SELECT user, host, plugin FROM mysql.user;
SHOW DATABASES;
-- 不審なユーザーを確認
SELECT user, host, password_expired, account_locked
FROM mysql.user
ORDER BY user;

-- WordPress ユーザーの権限を確認
SHOW GRANTS FOR 'wordpress_user'@'localhost';

ステップ2:MySQL の初期セキュリティ設定を実行する

# mysql_secure_installation を実行(初回セットアップ)
sudo mysql_secure_installation

# 対話式で以下を設定:
# - root パスワードの設定: Yes(強力なパスワードを設定)
# - 匿名ユーザーの削除: Yes
# - root のリモートログイン禁止: Yes
# - test データベースの削除: Yes
# - 権限テーブルのリロード: Yes
-- 手動で匿名ユーザーを削除
DELETE FROM mysql.user WHERE User = '';
DELETE FROM mysql.user WHERE User = 'root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');

-- test データベースを削除
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db = 'test' OR Db = 'test\\_%';

-- 変更を反映
FLUSH PRIVILEGES;

ステップ3:WordPress 専用ユーザーを最小権限で作成する

-- WordPress 専用データベースを作成
CREATE DATABASE wordpress_db
    CHARACTER SET utf8mb4
    COLLATE utf8mb4_unicode_ci;

-- WordPress に必要な最小権限のみ付与したユーザーを作成
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'StrongPassword123!';

-- WordPress の通常操作に必要な権限のみ付与
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER
    ON wordpress_db.*
    TO 'wp_user'@'localhost';

-- 権限を確認
SHOW GRANTS FOR 'wp_user'@'localhost';

-- 変更を反映
FLUSH PRIVILEGES;
# wp-config.php に DB 設定を反映
wp config set DB_NAME wordpress_db
wp config set DB_USER wp_user
wp config set DB_PASSWORD 'StrongPassword123!'
wp config set DB_HOST localhost

ステップ4:MySQL のネットワーク設定を強化する

# /etc/mysql/mysql.conf.d/mysqld.cnf

[mysqld]
# ローカルのみアクセスを許可(リモートアクセスを無効化)
bind-address = 127.0.0.1

# LOAD DATA LOCAL INFILE を無効化(データ漏洩リスク)
local-infile = 0

# シンボリックリンクを無効化
symbolic-links = 0

# 一般クエリログを無効化(本番環境)
general_log = 0

# エラーログのみ有効化
log_error = /var/log/mysql/error.log

# パスワードポリシーを設定(MySQL 8.0以降)
validate_password.policy = MEDIUM
validate_password.length = 12
validate_password.mixed_case_count = 1
validate_password.number_count = 1
validate_password.special_char_count = 1

# 最大接続数
max_connections = 100

# クエリキャッシュを無効化(MySQL 8.0では削除済み)
# query_cache_type = 0
# 設定を反映
sudo systemctl restart mysql

# リスニングアドレスを再確認
sudo ss -tnlp | grep :3306
# 127.0.0.1:3306 のみ表示されれば OK

ステップ5:定期的なデータベース監査を設定する

#!/bin/bash
# /usr/local/bin/mysql-security-audit.sh

DB_USER="root"
DB_PASS="root-password"
LOG_FILE="/var/log/mysql-security-audit.log"
DATE=$(date +%Y-%m-%d)

echo "=== MySQL セキュリティ監査: ${DATE} ===" >> $LOG_FILE

# パスワードのないユーザーを確認
mysql -u$DB_USER -p$DB_PASS -e "
    SELECT user, host FROM mysql.user
    WHERE authentication_string = '' OR authentication_string IS NULL;
" 2>/dev/null >> $LOG_FILE

# ALL PRIVILEGES を持つユーザーを確認
mysql -u$DB_USER -p$DB_PASS -e "
    SELECT GRANTEE, PRIVILEGE_TYPE FROM information_schema.USER_PRIVILEGES
    WHERE PRIVILEGE_TYPE = 'ALL';
" 2>/dev/null >> $LOG_FILE

# 最近作成されたユーザーを確認
mysql -u$DB_USER -p$DB_PASS -e "
    SELECT user, host, password_last_changed
    FROM mysql.user
    ORDER BY password_last_changed DESC LIMIT 10;
" 2>/dev/null >> $LOG_FILE

echo "=== 監査完了 ===" >> $LOG_FILE
// functions.php: DB エラーを本番環境で非表示にする

// データベース接続エラーを非表示
add_filter('allow_dev_auto_core_updates', '__return_false');

// カスタムDBエラーページを設定
// /var/www/html/wp-content/db-error.php を作成
<?php
// wp-content/db-error.php: カスタムDBエラーページ
http_response_code(503);
header('Retry-After: 300');
?>
<!DOCTYPE html>
<html lang="ja">
<head><title>一時的なエラー</title></head>
<body>
<h1>メンテナンス中</h1>
<p>しばらく時間をおいてから再度アクセスしてください。</p>
</body>
</html>

注意事項

  • wp-config.phpに記載するDBパスワードは推測困難な文字列(16文字以上・英数記号混合)を使用してください。パスワード管理ツールで生成することをお勧めします
  • MySQLを外部に公開する必要がある場合(マルチサーバー構成等)は、bind-addressの変更と合わせてファイアウォールで特定IPのみ許可してください
  • mysql_secure_installationは既存の本番データベースで実行しても安全ですが、testデータベース削除前に同名のデータベースが存在しないか確認してください

まとめ

MySQLのセキュリティ設定は①mysql_secure_installationで匿名ユーザー削除・test DB削除・root遠隔ログイン禁止、②WordPress専用ユーザーにSELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTERの最小権限のみ付与、③bind-address = 127.0.0.1でリモートアクセスを無効化・local-infile = 0で外部ファイル読込を禁止、④validate_password.policy = MEDIUMでパスワードポリシーを強制、⑤月次cronでパスワード無しユーザー・ALL PRIVILEGES保有ユーザーを監査します。

お気軽にご相談ください

お見積りへ お問い合わせへ