在CentOS或Ubuntu系统上如何隔离两个WordPress站点?

在 CentOS 或 Ubuntu 系统上隔离两个 WordPress 站点,核心目标是防止资源争抢、安全隔离以及故障隔离。所谓“隔离”,通常指从文件系统权限、进程运行环境、网络端口/反向X_X路由以及数据库资源四个维度进行分离。

以下是基于主流技术栈(Nginx + PHP-FPM + MySQL/MariaDB)的标准实践方案,分为轻量级隔离和重度隔离两种场景。


一、 基础架构原则:多站点 vs 独立实例

首先明确:不建议在同一 WordPress 安装目录下通过 wp-config.php 配置多站点(Multisite),除非你有极强的内部管理能力。对于生产环境,尤其是面向公众的两个网站点,最佳实践是部署为两个完全独立的 WordPress 实例。


二、 隔离层级详解

1. 文件系统与用户权限隔离(最基础且关键)

每个 WordPress 站点应拥有独立的目录结构和独立的操作用户。

  • 目录结构:
    /var/www/site1.com   # 站点1代码
    /var/www/site2.com   # 站点2代码
  • 用户与组:
    创建独立的用户(如 wp_user1, wp_user2),或使用统一的应用用户但严格限制文件所有权。

    sudo useradd -m -s /bin/bash wp_user1
    sudo useradd -m -s /bin/bash wp_user2
    sudo chown -R wp_user1:www-data /var/www/site1.com
    sudo chown -R wp_user2:www-data /var/www/site2.com
  • 权限控制:
    • 代码目录对 Web 服务器用户(www-data)仅读执行。
    • wp-content/uploads 和 wp-content/cache 需可写,但建议通过 PHP-FPM 池的 umask 设置最小化权限。
    • 使用 ACL(访问控制列表)精细控制特定目录权限:
      setfacl -R -m u:www-data:rX /var/www/site1.com/wp-content/uploads

2. PHP-FPM 进程隔离(推荐:独立 Pool)

不要共用同一个 PHP-FPM 主进程池。不同站点应使用不同的 PHP-FPM 监听 socket 或端口,并分配独立的资源限制。

  • 配置独立 Pool:
    在 /etc/php/8.1/fpm/pool.d/(Ubuntu)或 /etc/php-fpm.d/(CentOS)中创建两个配置文件:

    ; site1.conf
    [site1]
    user = wp_user1
    group = www-data
    listen = /run/php/php8.1-fpm-site1.sock
    pm = dynamic
    pm.max_children = 50
    pm.start_servers = 5
    ; 其他安全设置
    php_admin_value[open_basedir] = /var/www/site1.com:/tmp
    ; site2.conf
    [site2]
    user = wp_user2
    group = www-data
    listen = /run/php/php8.1-fpm-site2.sock
    pm = dynamic
    pm.max_children = 50
    php_admin_value[open_basedir] = /var/www/site2.com:/tmp
  • 优势:

    • 一个站点因内存泄漏导致 PHP-FPM 崩溃,不影响另一个站点。
    • 可通过 open_basedir 强制限制 PHP 脚本只能访问自身目录,提升安全性。

3. Nginx 反向X_X与虚拟主机隔离

每个站点使用独立的 Server Block,绑定不同的域名或子域名,指向各自的 PHP-FPM socket。

# site1.conf
server {
    listen 80;
    server_name site1.com www.site1.com;
    root /var/www/site1.com/public_html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.1-fpm-site1.sock; # 指向独立 socket
    }
}

# site2.conf
server {
    listen 80;
    server_name site2.com www.site2.com;
    root /var/www/site2.com/public_html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.1-fpm-site2.sock; # 指向独立 socket
    }
}

注意:若两个站点共享同一 IP,确保防火墙只开放必要端口(80/443)。若使用 HTTPS,需分别为每个域名申请 SSL 证书(Let’s Encrypt 支持通配符或多域名证书)。

4. 数据库隔离

虽然 MySQL/MariaDB 可以共用实例,但必须严格隔离数据库和用户权限。

  • 创建独立数据库和用户:

    CREATE DATABASE site1_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    CREATE USER 'site1_user'@'localhost' IDENTIFIED BY 'strong_password_1';
    GRANT ALL PRIVILEGES ON site1_db.* TO 'site1_user'@'localhost';
    FLUSH PRIVILEGES;
    
    -- 同理为 site2 创建
  • 连接配置:
    在每个站点的 wp-config.php 中使用对应的数据库凭据。
  • 高级隔离(可选):
    若担心 SQL 注入横向移动,可在 MySQL 层面启用 read_only 或更细粒度的权限控制,但通常应用层隔离已足够。

5. 缓存与静态资源隔离

  • 对象缓存(Redis/Memcached):
    建议使用独立的 Redis 实例或至少使用不同的 DB 编号(redis-cli SELECT 0 对应 site1, SELECT 1 对应 site2),避免缓存污染。

    // wp-config.php 中
    define('WP_REDIS_HOST', '127.0.0.1');
    define('WP_REDIS_PORT', 6379);
    define('WP_REDIS_DATABASE', 0); // site1 用 0, site2 用 1
  • 页面缓存(Varnish/Nginx FastCGI Cache):
    为每个站点配置独立的缓存路径:

    fastcgi_cache_path /var/cache/nginx/site1 levels=1:2 keys_zone=SITE1:10m max_size=1g;
    fastcgi_cache_path /var/cache/nginx/site2 levels=1:2 keys_zone=SITE2:10m max_size=1g;

三、 进阶隔离:容器化方案(Docker)

如果希望实现更强的隔离性(进程、网络、文件系统完全隔离),推荐使用 Docker Compose 为每个站点部署独立容器。

示例:docker-compose.yml for Site1

version: '3.8'
services:
  nginx:
    image: nginx:alpine
    ports: ["8081:80"]
    volumes:
      - ./site1/html:/var/www/html
      - ./site1/conf.d:/etc/nginx/conf.d
    depends_on:
      - php
      - mysql

  php:
    image: php:8.1-fpm
    volumes:
      - ./site1/html:/var/www/html
    environment:
      - WORDPRESS_DB_HOST=mysql
      - WORDPRESS_DB_NAME=site1_db
      - WORDPRESS_DB_USER=site1_user
      - WORDPRESS_DB_PASSWORD=pass1

  mysql:
    image: mariadb:10.5
    volumes:
      - site1_data:/var/lib/mysql
    environment:
      MYSQL_DATABASE: site1_db
      MYSQL_USER: site1_user
      MYSQL_PASSWORD: pass1
      MYSQL_ROOT_PASSWORD: rootpass1

volumes:
  site1_data:

优点:

  • 每个站点有独立的 MySQL 数据卷,互不干扰。
  • 网络隔离:各服务间通过 Docker 内部网络通信,外部仅暴露 Nginx 端口。
  • 易于迁移和备份。

四、 安全加固建议

  1. 禁用目录浏览:在 Nginx 配置中添加 autoindex off;。
  2. 隐藏版本号:
    server_tokens off;
    fastcgi_param SERVER_SOFTWARE nginx; # 隐藏 PHP-FPM 版本
  3. 定期更新:保持 OS、Nginx、PHP、MySQL 和 WordPress 核心插件的安全补丁更新。
  4. WAF 防护:可使用 ModSecurity 或云厂商提供的 WAF 规则,针对常见 WP 攻击(如 XML-RPC 暴力破解)进行拦截。
  5. 日志监控:为每个站点配置独立的 Nginx access/error log,便于排查问题。

五、 总结

隔离维度 轻量级方案(同服务器) 重度隔离方案(Docker/KVM)
文件系统 独立目录 + 独立用户 独立容器/虚拟机
PHP 处理 独立 PHP-FPM Pool 独立容器内 PHP
Web 服务器 独立 Nginx Server Block 独立容器内 Nginx
数据库 独立 DB + 独立用户 独立 DB 实例或容器
缓存 独立 Redis DB / Nginx Cache Zone 独立容器
适用场景 中小型站点,资源有限 高可用、高安全要求、多租户

最终建议:
对于大多数中小规模业务,采用 “独立目录 + 独立 PHP-FPM Pool + 独立 Nginx Server Block + 独立 MySQL 用户” 的组合即可实现有效隔离,兼顾性能与管理复杂度。若对稳定性要求极高或站点数量较多,建议迁移至 Docker 或 Kubernetes 编排环境。

未经允许不得转载:CLOUD云枢 » 在CentOS或Ubuntu系统上如何隔离两个WordPress站点?