Apache运行ThinkPHP必须将DocumentRoot设为public目录、启用mod_rewrite并配置AllowOverride All、显式拒绝runtime/app/config等敏感目录访问,否则将导致404、源码泄露等安全问题。

public 目录被强制暴露、runtime 或 app 目录被下载源码等真实问题。
为什么 ThinkPHP 的 public 目录必须是 DocumentRoot
ThinkPHP 6+ 强制采用「入口隔离」设计:public 是唯一合法 Web 可访问路径,其余如 app、runtime、config 等目录绝不能被 HTTP 直接访问。如果 Apache 的 DocumentRoot 指向项目根目录(比如 /var/www/myapp),那么用户访问 https://example.com/runtime/log/202605.log 就可能直接下载日志文件——这是严重安全风险。
-
DocumentRoot必须设为/var/www/myapp/public(Linux)或C:/xampp/htdocs/myapp/public(Windows) - 不能靠
Alias或Redirect补救;必须从根上限制可访问范围 - 若用虚拟主机,
<virtualhost></virtualhost>块内必须单独设置该DocumentRoot,不能复用全局配置
mod_rewrite 必须启用且 .htaccess 生效
ThinkPHP 路由依赖 Apache 的 URL 重写能力。即使你写了 public/.htaccess,若 Apache 未允许该文件生效,所有带参数的 URL(如 /index/user/profile)都会 404。
- 确认模块已加载:
a2enmod rewrite(Debian/Ubuntu)或检查httpd -M | grep rewrite(RHEL/CentOS) - 在对应
<directory></directory>块中必须包含:AllowOverride All(Apache 2.4+);Require all granted也必不可少 - 别信“默认开启”——很多最小化安装或容器镜像里
AllowOverride默认是None -
.htaccess文件权限需为 644,且 Apache 进程用户(如www-data)有读取权
必须屏蔽 runtime / app / config 等敏感目录的直接访问
即便 DocumentRoot 正确指向 public,攻击者仍可能通过构造路径尝试越权访问(例如利用符号链接、路径遍历漏洞或配置疏漏)。最稳妥的做法是在 Apache 配置中主动拒绝这些路径。
- 在
<virtualhost></virtualhost>或主配置中添加:<Directory "/var/www/myapp/runtime"> Require all denied </Directory> <Directory "/var/www/myapp/app"> Require all denied </Directory> <Directory "/var/www/myapp/config"> Require all denied </Directory> - 注意路径必须是**绝对路径**,且与实际磁盘路径完全一致(区分大小写、结尾斜杠不影响)
- 不要只依赖
.htaccess放在各目录下——Apache 主配置优先级更高,更可靠 - 若使用宝塔、AMH 等面板,请手动检查其生成的配置是否包含上述
<Directory>块
AllowOverride All 和敏感目录的显式拒绝——这两项不落实,哪怕路由跑通了,安全水位也极低。



















