不能靠chattr锁定Web根目录防非法上传,因其会阻止所有写入导致网站瘫痪,且无法区分合法与恶意上传;应采用禁用脚本解析、移除执行权限、存至Web根外、强制重命名+白名单+内容校验等组合策略。

不能靠 chattr 锁定 Web 根目录来防非法上传。
chattr 的作用范围有限
chattr +i 确实能让文件或目录「不可修改、不可删除、不可重命名」,但它的前提是:Web 服务进程(如 Apache 或 Nginx)必须没有 root 权限——而现实中,绝大多数生产环境的 Web 服务是以非 root 用户(如 www-data、nginx)运行的。一旦你对 /var/www/html/ 这类目录执行 chattr +i,连这个普通用户都无法写入,结果是:正常上传、日志写入、缓存生成全部失败,网站直接瘫痪。
更关键的是:chattr 是文件系统级锁定,它不区分「谁在写」,只认「是否加锁」。它无法判断「这个请求是合法用户上传头像」还是「攻击者上传 shell.php」——它只会一视同仁地拒绝所有写操作。
真正该用的权限控制手段
防非法上传的核心不是「锁死整个目录」,而是「让恶意文件即使传上去也无法被执行或访问」。推荐组合使用以下方式:
-
上传目录禁用脚本解析:Apache 中配置
php_flag engine off或 Nginx 中用location ~ \.php$ { return 403; },确保/uploads/下的 .php 文件不会被当成代码执行 -
目录权限设为 755,文件权限设为 644:用
chmod -x /var/www/html/uploads/显式移除执行位,即使上传了 .php,服务器也只返回源码或下载,不执行 -
把真实文件存到 Web 根目录外:例如存到
/var/www/app-data/uploads/,前端只暴露路由如/download?id=abc123,由 PHP 脚本做权限校验后再读取并输出文件内容 -
强制重命名 + 白名单 + 内容校验:不信任扩展名和 MIME,上传后用
finfo_file()或exif_imagetype()检查真实类型,再保存为随机名(如a7f3b9e2.png)
chattr 的合理使用场景
chattr 更适合保护极少数关键静态资产,比如:
- 配置文件(
/etc/nginx/nginx.conf)防止被恶意覆盖 - 证书文件(
/etc/ssl/private/my.key)防止被篡改或删除 - 日志轮转前的归档文件(
/var/log/apache2/access.log.1)防止被清除痕迹
这些文件本身就不该被 Web 进程写入,加 +i 是加固;而上传目录恰恰是设计为「要被 Web 进程持续写入」的地方,强行加锁等于自废武功。

















