在 CentOS 8.2 上部署 WordPress,防火墙和 SELinux 的配置是确保服务安全且可访问的关键环节。很多新手容易在这两步卡住,要么为了省事直接 systemctl stop firewalld 和 setenforce 0(这是大忌),要么配置错误导致数据库连不上或页面空白。
下面我以生产环境的标准实践来梳理这两部分的配置逻辑。CentOS 8 系列默认使用 firewalld 作为动态防火墙管理器,以及 SELinux 作为强制访问控制机制。我们的目标是:只开放必要的端口,保持 SELinux 处于 Enforcing 模式但正确标注上下文。
一、防火墙配置 (Firewalld)
CentOS 8 默认启用 firewalld。WordPress 主要依赖 HTTP (80) 和 HTTPS (443) 端口对外提供服务。如果服务器内部运行 MySQL/MariaDB,通常监听 localhost,因此不需要对公网开放 3306 端口。
1. 检查当前状态
首先确认防火墙是否正在运行:
sudo systemctl status firewalld
如果是 inactive,启动它并设置开机自启:
sudo systemctl start firewalld
sudo systemctl enable firewalld
2. 开放 Web 服务端口
我们不需要手动指定端口号,直接使用 firewalld 提供的服务名称更规范,也便于后续管理。
永久开放 HTTP 服务:
sudo firewall-cmd --permanent --add-service=http
永久开放 HTTPS 服务(如果你计划安装 SSL 证书,这一步必做):
sudo firewall-cmd --permanent --add-service=https
重载配置使生效:
sudo firewall-cmd --reload
3. 验证规则
查看当前活跃的区域和服务:
sudo firewall-cmd --list-services
你应该能看到 http https 出现在列表中。
注意:如果你的服务器位于阿里云、腾讯云等云厂商后台,记得去云控制台的“安全组”里同样放行 80 和 443 端口。本地 firewalld 配好了,云安全组没开也是白搭。
二、SELinux 配置
很多教程建议关闭 SELinux,但在企业级环境中,保持 SELinux 开启能极大提升系统安全性。WordPress 涉及 Apache/Nginx 读取文件、PHP-FPM 执行脚本、以及可能的数据库连接。我们需要做的是调整策略上下文,而不是关闭保护。
1. 确认 SELinux 状态
getenforce
如果返回 Enforcing,说明已开启。如果返回 Permissive,建议改为 Enforcing 以符合最佳实践:
sudo setenforce 1
# 修改配置文件使其重启后生效
sudo sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
2. 针对 Apache/Nginx 的策略调整
假设你使用的是 Apache (httpd),这是 CentOS 环境下最常见的搭配。
允许 HTTPD 网络请求(如调用外部 API 或重定向):
sudo setsebool -P httpd_can_network_connect 1
如果 WordPress 需要访问外部资源(较少见,但某些插件可能需要),或者服务器本身作为XX:
sudo setsebool -P httpd_can_network_relay 1
关键步骤:确保网站根目录权限正确
WordPress 通常安装在 /var/www/html 或自定义目录。Apache 进程用户是 apache。如果 SELinux 阻止了 Apache 读取新上传的文件或写入 wp-content/uploads,通常是上下文不对。
标准情况下,Web 内容应该被标记为 httpd_sys_content_t。如果你将 WordPress 解压到了 /var/www/html,默认上下文通常是对的。但如果你的网站目录在其他位置(比如 /data/wordpress),你需要手动标注:
# 假设你的网站放在 /data/wordpress
sudo semanage fcontext -a -t httpd_sys_content_t "/data/wordpress(/.*)?"
sudo restorecon -Rv /data/wordpress
允许 Apache 写入特定目录(如 uploads, themes, plugins)
虽然大多数情况下 Apache 有写权限,但 SELinux 可能会拦截。确保你的网站目录及其子目录拥有正确的写入上下文标签。通常只要文件属主是 apache:apache 且类型是 httpd_sys_rw_content_t 即可。
你可以尝试以下命令让 Apache 能够写入所有 web 内容(谨慎操作,仅限测试环境或信任的站点):
sudo setsebool -P httpd_unified_write 1
更推荐的做法是精确设置目录权限:
# 将 wp-content 目录标记为允许写入
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/wp-content(/.*)?"
sudo restorecon -Rv /var/www/html/wp-content
3. 针对 Nginx + PHP-FPM 的情况
如果你用的是 Nginx,策略略有不同:
# 允许 Nginx 网络连接
sudo setsebool -P httpd_can_network_connect 1
# 确保 Nginx 可以读写网站文件
sudo semanage fcontext -a -t httpd_sys_content_t "/path/to/wordpress(/.*)?"
sudo restorecon -Rv /path/to/wordpress
4. 排查 SELinux 拒绝日志
如果配置后出现 500 错误或无法上传图片,第一时间看日志:
sudo tail -f /var/log/audit/audit.log | grep denied
或者使用工具 sealert(需安装 setroubleshoot-server):
sudo sealert -a /var/log/audit/audit.log
它会给出非常具体的修复建议,比如“是否需要开启某个 bool 值”。
三、常见坑点与调试技巧
-
数据库连接失败?
WordPress 报错 “Error establishing a database connection” 时,先排除密码错误。如果密码正确,检查 SELinux 是否阻止了 Apache/Nginx 连接本地 MySQL。虽然 MySQL 监听 localhost,但在某些高安全策略下,SELinux 可能拦截 socket 通信。确保mysqld服务正常运行,且 SELinux 没有禁止httpd连接mysqld。通常只需确保两者在同一主机且端口正确即可,一般无需额外 bool 值,除非你使用了非标准配置。 -
图片上传失败?
90% 是因为wp-content/uploads目录权限问题。确保该目录及子目录的所有者是apache(Apache)或nginx(Nginx),组也是对应的。sudo chown -R apache:apache /var/www/html/wp-content sudo chmod -R 755 /var/www/html/wp-content同时,确保 SELinux 上下文允许写入(参考上文
httpd_sys_rw_content_t)。 -
为什么不用 iptables?
CentOS 8 已经弃用 iptables 作为默认前端,转而使用 nftables。firewalld 是基于 nftables 的动态管理器。手动操作 iptables 命令可能会导致与 firewalld 冲突,引发不可预知的行为。请坚持使用firewall-cmd。 -
临时关闭 SELinux 测试?
如果你在调试过程中实在搞不定 SELinux 策略,可以临时设为 Permissive 模式来验证是否是 SELinux 的问题:sudo setenforce 0如果此时 WordPress 正常工作,那基本确定是 SELinux 上下文或 Bool 值的问题。排错完成后,务必改回
setenforce 1。
总结
在 CentOS 8.2 上部署 WordPress:
- 防火墙:通过
firewall-cmd --permanent --add-service={http,https}开放 80/443 端口,并 reload。 - SELinux:保持 Enforcing 模式。重点处理网站目录的上下文标签(
httpd_sys_content_t或httpd_sys_rw_content_t),并根据需要开启httpd_can_network_connect等布尔值。 - 原则:最小权限原则。不要盲目关闭安全模块,而是通过精细化的策略配置来适应应用需求。
这样配置后的系统,既满足了 WordPress 的运行需求,又保持了较高的安全基线,符合国内主流云服务器的合规要求。
云技术博客