位置:首页 > PHP > Ubuntu 上的 PHP 安全加固清单:从系统更新到代码审计

Ubuntu 上的 PHP 安全加固清单:从系统更新到代码审计

时间:2026-08-23  |  作者:怪兽小助手  |  阅读:0

目录

  1. 先把系统和 PHP 版本保持在可维护状态
  2. 重点检查 php.ini 里的高风险配置
  3. Web 服务器要和 PHP 一起收紧
  4. 用系统安全模块和权限控制补上隔离层
  5. 把传输、入口和监控补齐
  6. 代码层面的防护和后续维护不能省

前言

把 PHP 跑在 Ubuntu 上并不难,难的是上线后还能把风险控制在可接受范围内。本文按系统更新、php.ini 配置、Apache/Nginx 加固、权限隔离、HTTPS 与审计,再到代码层防护逐层拆开,既保留可直接照做的命令和配置,也说明每一步主要在防什么,方便你判断哪些该优先落地。

把 PHP 服务部署到 Ubuntu 上,很多人先关注的是能不能跑起来,真正上线后才发现安全问题更难补。与其零散地加几个模块,不如按“系统更新、PHP 配置、Web 服务器、权限与审计、代码实践”这几层来检查,这样更容易判断哪些措施是基础项,哪些属于针对业务场景的强化项。

下面这份清单保留了常用命令、配置项和目录示例,适合直接对照现有环境逐项核查。即使你暂时不一次性全部启用,也可以先把最容易落地、收益最高的部分补齐,尽快降低暴露面。

先把系统和 PHP 版本保持在可维护状态

PHP 安全的第一道防线,通常不是某个高级扩展,而是及时更新系统和运行时。大量攻击利用的都是已经公开、也已经修复的旧漏洞。

Ubuntu 环境中,建议定期执行以下命令更新系统组件:

sudo apt update && sudo apt upgrade

同时也要同步更新 PHP 本体和常用扩展,避免核心解释器与扩展库长期落后:

sudo apt install php php-cli php-fpm php-mysql php-curl php-xml php-zip

这一步的意义很直接:先把已知漏洞窗口缩到最小,再谈后面的细粒度加固。

重点检查 php.ini 里的高风险配置

很多 PHP 安全问题并不是代码写坏了,而是默认配置过宽。上线前,至少要把下面几类设置过一遍。

展示 php.ini 中与 PHP 安全加固直接相关的关键配置项,包括报错控制、危险函数、上传限制和远程资源访问开关。
php.ini 安全配置检查图把 php.ini 中最常被忽略、但最容易直接影响暴露面的配置集中梳理出来,适合上线前逐项核对。

不要把报错信息直接暴露给用户

生产环境里,错误细节不应该直接回显到页面。否则路径、变量名、SQL 结构甚至扩展状态都可能被外部拿去分析。

display_errors = Off
log_errors = On
error_log = /var/log/php_errors.log

这样做的好处是把调试信息留在服务器内,既方便排查,也减少敏感信息泄露。

按业务情况禁用危险函数

如果应用并不依赖系统命令调用,就应该尽量收紧高风险函数。像 evalexecsystempassthrushell_execcurl_exec 一旦被利用,往往会把问题从应用层直接带到系统层。

可以通过 disable_functions 统一禁用。这类限制尤其适合常规 CMS、后台系统、内容站和接口服务。

上传能力要同时限制大小和访问范围

文件上传不是简单地限制一个大小参数,更关键的是限制脚本可访问目录,避免上传点成为落地入口。

upload_max_filesize = 2M
post_max_size = 8M
open_basedir = /var/www/html/:/tmp/

upload_max_filesize = 2Mpost_max_size = 8M 用来控制上传体积,open_basedir 则限制 PHP 只能访问指定路径,例如 /var/www/html//tmp/。即使有恶意文件进入上传目录,活动范围也会被压缩。

关闭远程资源包含能力

远程文件包含攻击(RFI)之所以危险,就在于攻击者可以借助 URL 让脚本加载外部恶意代码。生产环境通常不需要保留这类能力。

allow_url_fopen = Off
allow_url_include = Off

这两项关闭后,PHP 通过 URL 直接加载远程资源的空间会明显变小。

OPcache 不只是性能优化

启用 OPcache 的常见理由是减少重复编译、提升响应速度,但它对运行稳定性也有帮助。脚本不必频繁重复解析,运行面会更收敛。

opcache.enable=1

它不是替代安全配置的手段,但适合作为生产环境的基础项保留。

Web 服务器要和 PHP 一起收紧

PHP 本身配得再严,如果 Apache 或 Nginx 暴露过多信息、脚本执行边界不清,整体风险依然很高。

对比 Apache 与 Nginx 在 PHP 安全加固中的重点措施,包括模块启用、响应头隐藏和上传目录脚本阻断。
Apache 与 Nginx 加固重点对比同样是跑 PHP,Apache 和 Nginx 的加固重点并不一样:前者偏模块与信息隐藏。

Apache 环境重点看模块与信息暴露

Apache 场景下,常见的加固项包括启用 Web 应用防护模块、限制异常请求,以及减少响应头泄露的信息量。

sudo a2enmod security2
sudo a2enmod evasive20

mod_security 可以拦截 SQL 注入、XSS 等常见攻击流量,mod_evasive 适合对暴力请求和部分 DDoS 行为做基础缓解。

ServerTokens Prod
Header unset X-Powered-By

隐藏 Apache 版本信息、移除 X-Powered-By 响应头,虽然不直接修复漏洞,但能减少被动暴露。

Nginx 环境重点收紧脚本执行路径

Nginx 的核心思路是:只有明确允许的 PHP 入口才能交给 PHP-FPM 处理,其他位置即使出现脚本文件也不能执行。

location = /xmlrpc.php { deny all; }

这类规则适合直接封掉不需要的脚本入口。

location ~ .php$

需要确保只有这个 PHP 处理块把请求交给 PHP-FPM,而不是让任意目录里的脚本都有执行机会。

location ~ ^/(uploads|assets)/.*.(php|php5|jsp)$ { deny all; }

上传目录和静态资源目录通常只该存放文件,不该成为脚本执行点。这条规则就是为了防止“上传成功后直接执行”。

用系统安全模块和权限控制补上隔离层

到这一步,目标已经不只是“减少攻击入口”,还包括“即使某处被利用,影响范围也尽量受限”。

AppArmor 或 SELinux 用来限制 PHP 进程边界

AppArmor 和 SELinux 的价值在于进程级隔离。哪怕 PHP 服务被入侵,也不代表它能自由读取系统关键目录。

sudo aa-enforce /etc/apparmor.d/usr.sbin.php-fpm

通过 AppArmor 强制启用配置后,PHP-FPM 的访问范围会受到限制,不再能随意触达 /etc/root 这类敏感位置。

setenforce 1

如果环境使用 SELinux,开启强制模式同样可以提高隔离强度。

Suhosin 适合作为额外防护层

Suhosin 常被视作 PHP 的补充安全扩展,适合在需要更严运行限制的环境中作为附加层使用。

sudo apt install php-suhosin

安装后,它可以提供缓冲区溢出防护、格式化串攻击防御等额外保护,用来补足 PHP 原生机制的空白。

文件与目录权限不要图省事

权限管理的原则很简单:只给必要权限,不给“万能权限”。

sudo chown -R www-data:www-data /path/to/php/project

先确保项目文件归属正确,避免不同用户混用造成越权写入。

sudo chmod -R ug+rwx storage bootstrap/cache

storagebootstrap/cache 这类需要写入的目录,可以按需授予读写权限;而 chmod 777 这种做法应当避免,它会把控制面直接放大。

把传输、入口和监控补齐

很多环境前面的配置都做了,但在 HTTPS、防火墙和日志审计上留了空白,结果问题出现后既拦不住,也追不清。

概括 Ubuntu 上 PHP 服务的外围防护层,包括 HTTPS、UFW、防 SSH 暴力破解和 auditd 审计。
外围防护与审计闭环外围防护的重点不是单点配置,而是把传输加密、入口收敛和异常发现三件事一起补齐。

HTTPS 是默认项,不是可选项

客户端与服务器之间如果没有 TLS 保护,中间人攻击、会话窃听和敏感数据泄露都会变得容易。

sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d yourdomain.com

使用 Let's Encrypt 可以较低成本启用 SSL/TLS 证书,把站点流量切到 HTTPS。

只开放必要端口,并收紧 SSH 登录方式

服务器不该把所有入口都暴露在公网。对大多数 PHP 网站来说,通常只需要开放 80 和 443。

sudo ufw allow 'Nginx Full'
sudo ufw enable

配合 UFW,可以先把 Web 服务放行,再关闭其他不必要端口。

此外,建议修改 /etc/ssh/sshd_config,将 PermitRootLogin no 写入配置,并尽量使用密钥认证替代密码登录,降低 SSH 被撞库或暴力破解的概率。

日志和审计的作用是尽快发现异常

安全体系不能只有“防”,还必须有“看见问题”的能力。PHP 错误日志、Web 访问日志和文件变更审计,是最基础也最实用的三类信号。

tail -f /var/log/php_errors.log

这个命令适合实时观察异常输出,快速定位是否出现集中报错或异常请求触发。

sudo apt install auditd
sudo auditctl -w /path/to/php/files -p wa -k php-files

安装 auditd 后,可以对 PHP 文件的写入和修改行为做跟踪。一旦出现可疑落地文件、批量篡改或异常更新,定位会快很多。

代码层面的防护和后续维护不能省

系统和服务器可以缩小攻击面,但最终能不能守住,还是要看业务代码本身是否遵守基本的安全规则。

所有外部输入都要校验与转义

不要默认相信用户提交的数据。邮箱、URL 等格式可以先用 filter_var() 验证;输出到页面前,再根据场景使用 htmlspecialchars()strip_tags() 做处理。

这属于防 XSS 的基本动作,越早统一到框架层或公共函数层,后续越不容易漏。

数据库访问必须使用预处理语句

SQL 注入防护最稳妥的方式,仍然是 PDO 或 MySQLi 的预处理语句,而不是手工拼接字符串。

$stmt = $mysqli->prepare("SELECT * FROM users WHERE id = ?"); $stmt->bind_param("i", $id);

这段示例的重点不在语法,而在边界:参数与 SQL 结构分离,数据库不会把输入直接当作语句的一部分执行。

密码存储使用 PHP 内置哈希 API

密码不要自行设计加密方案,直接使用 PHP 提供的密码哈希接口即可。

$hashed_password = password_hash('user_password', PASSWORD_DEFAULT);

校验时配合 password_verify() 使用,既省掉自实现风险,也更容易跟随 PHP 默认策略升级。

定期审计和备份,才能应对长期运行风险

安全加固不是做完一次配置就结束。代码会变、依赖会变、暴露面也会变,因此需要定期检查漏洞、保留回滚手段。

可以使用 PHPSA(PHP Security Advisories Checker)等工具扫描潜在安全问题,比如未过滤输入、过时函数或已知风险依赖。

备份也应纳入固定流程:

sudo rsync -a vz /var/www/html /path/to/backup
mysqldump -u username -p database_name > database_backup.sql

前者用于备份站点文件,后者用于备份数据库。真正遇到文件被篡改、版本回退或数据库异常时,恢复能力往往比单点防御更关键。

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多