努力
加油

CentOS 8.2如何设置防火墙和SELinux以便运行WordPress?

在 CentOS 8.2 上部署 WordPress,核心难点不在于安装软件本身,而在于理清 Firewalld(防火墙)和 SELinux 这两个安全模块的工作逻辑。很多新手踩坑都是因为只关了 SELinux 或者没开放正确的端口,导致页面打不开或后台无限重定向。

以下是基于生产环境最佳实践的配置方案,分为“最小权限原则”和“快速测试模式”两种场景。推荐优先使用第一种,既安全又稳定。

一、 前置条件确认

假设你已经完成了 LAMP 或 LNMP 环境的搭建:

  • Web 服务器:Apache (httpd) 或 Nginx
  • 数据库:MySQL/MariaDB
  • PHP:7.4+
  • WordPress 文件已解压到 /var/www/html 或自定义目录

二、 Firewalld 配置(网络层)

CentOS 8 默认使用 firewalld,而不是传统的 iptables。WordPress 主要需要 HTTP (80) 和 HTTPS (443) 端口。

1. 检查当前状态

systemctl status firewalld
# 如果未运行,启动并设为开机自启
systemctl start firewalld
systemctl enable firewalld

2. 开放必要端口

不要直接关闭防火墙!只需允许 Web 流量通过。

# 永久开放 http 和 https 服务
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https

# 重载配置使生效
firewall-cmd --reload

注意:如果你使用了非标准端口(例如 SSH 改了 2222),也需要手动添加端口规则,但 WordPress 本身通常只需要 80/443。

3. 验证端口是否开放

firewall-cmd --list-services
# 输出应包含: dhcpv6-client http https ssh

此时,外部浏览器应该已经可以访问你的 WordPress 首页了。如果还无法访问,问题大概率出在 SELinux 或应用配置上。


三、 SELinux 配置(内核安全层)

这是最容易出错的地方。SELinux 会阻止 Apache/Nginx 读取不在其默认上下文中的文件,或阻止其连接数据库。

强烈建议:不要直接禁用 SELinux (setenforce 0)。 在生产环境中禁用 SELinux 会带来严重的安全风险。我们应该通过调整策略来让 WordPress 正常运行。

1. 确认 SELinux 状态

getenforce
# 正常应为 Enforcing

2. 设置 Web 服务器上下文

WordPress 的文件必须被标记为正确的 SELinux 类型,否则 Apache 将无法读取它们。

情况 A:WordPress 安装在默认路径 /var/www/html
CentOS 8 的 httpd 包通常已经预置了正确的策略。你只需要确保 Apache 有权限执行 CGI 脚本(如果使用 PHP-FPM 则不需要此步,但为了保险起见):

# 允许 httpd 执行 cgi 脚本(部分旧版配置可能需要)
setsebool -P httpd_enable_cgi on

# 如果使用了 PHP-FPM,确保 httpd 可以连接到 php-fpm socket
setsebool -P httpd_can_network_connect_fpm on

情况 B:WordPress 安装在自定义路径(如 /data/wordpress)
你需要将新目录的上下文改为 httpd_sys_content_t:

# 修改目录及子文件的上下文
chcon -Rt httpd_sys_content_t /data/wordpress

# 如果要持久化(重启后不丢失),需要使用 semanage
# 先安装 policycoreutils-python-utils
yum install policycoreutils-python-utils -y

# 添加新的内容类型关联
semanage fcontext -a -t httpd_sys_content_t "/data/wordpress(/.*)?"

# 恢复上下文
restorecon -Rv /data/wordpress

3. 允许 Web 服务器连接数据库

Apache/Nginx 需要通过 localhost 连接 MySQL/MariaDB。SELinux 默认可能阻止这种网络连接。

# 允许 httpd 通过网络连接数据库(MySQL/MariaDB 默认端口 3306)
setsebool -P httpd_can_network_connect_db on

关键点:-P 参数表示持久化,重启后依然有效。

4. 处理上传目录权限问题

WordPress 上传图片、插件、主题时,可能会因为 SELinux 拒绝写入而失败。

方法一:给 www-data 用户(或 apache 用户)赋予写权限(推荐)

# 假设 wordpress 根目录是 /var/www/html
chown -R apache:apache /var/www/html
chmod -R 755 /var/www/html

# 特别地,wp-content 目录需要可写
chmod -R 775 /var/www/html/wp-content

方法二:如果仍报错,检查具体 AVC 日志
当出现 "Permission denied" 时,查看审计日志:

ausearch -m avc -ts recent

根据日志提示,使用 audit2allow 生成临时策略,但这属于高级调试手段,一般上述步骤已足够。


四、 WordPress 自身配置检查

即使系统层面配置正确,WordPress 内部也可能因配置错误导致白屏或循环重定向。

  1. 配置文件 wp-config.php
    确保以下常量设置正确:

    define('DB_NAME', 'your_database');
    define('DB_USER', 'your_user');
    define('DB_PASSWORD', 'your_password');
    define('DB_HOST', 'localhost'); // 注意:如果是 MySQL Socket 连接,可能需要改为 unix_socket 路径
  2. 站点地址设置
    登录 WP Admin -> 设置 -> 常规,确保“WordPress 地址”和“站点地址”与你实际访问的 URL 一致(包括 http/https)。

  3. 伪静态规则(Rewrite Rules)

    • Apache: 确保 .htaccess 文件存在且有写入权限,且 httpd.conf 中开启了 mod_rewrite 模块。
      <Directory /var/www/html>
       AllowOverride All
      </Directory>
    • Nginx: 需要在 nginx 配置文件中添加 location 块:
      location / {
       try_files $uri $uri/ /index.php?$args;
      }

五、 常见问题排查清单

现象 可能原因 解决方案
403 Forbidden SELinux 阻止访问 检查 chcon 或 semanage fcontext 是否正确设置
500 Internal Server Error PHP 错误或权限不足 查看 /var/log/httpd/error_log 或 /var/log/php-fpm/www-error.log
无法上传图片/插件 目录权限不足 检查 wp-content 属主是否为 apache,权限是否为 755/775
数据库连接失败 SELinux 阻止网络 执行 setsebool -P httpd_can_network_connect_db on
页面样式丢失 资源路径错误 检查 wp-config.php 中的 WP_SITEURL 和 WP_HOME

六、 总结

在 CentOS 8.2 上运行 WordPress,不要走捷径去关闭 SELinux。正确的做法是:

  1. Firewalld:只开放 http 和 https 服务。
  2. SELinux:
    • 使用 setsebool -P httpd_can_network_connect_db on 允许连库。
    • 使用 chcon 或 semanage fcontext 确保 Web 文件上下文正确。
    • 确保 wp-content 目录对 apache 用户可写。
  3. 应用层:检查 wp-config.php 和伪静态规则。

这样配置出来的系统,既符合国内云服务器的安全规范,又能稳定运行 WordPress,避免因安全策略过于宽松而被攻击的风险。