Web应用程序根目录

把网站文件丢进服务器,应用程浏览器敲个域名就能跑起来——这事看着简单,序根背后有个东西一直在默默干活:Web应用程序根目录。目录它不是应用程一个文件夹那么简单,更像是序根一道边界线,决定了哪些文件能被外面访问,目录哪些必须烂在里头。应用程

我最早接触这个概念是序根在一台共享主机上。当时把数据库配置文件跟index.php放在同一层,目录结果某天随手访问 /config.php,应用程浏览器直接把数据库账号密码吐了出来。序根那台服务器没有做任何额外防护,目录根目录就是应用程站点根目录,所有文件天然可读。序根后来我才明白,目录Web根目录的本质是HTTP请求的解析起点。Apache或Nginx收到一个URL,会把它映射到根目录下的某个路径。映射规则由服务器配置决定,但根目录是这条链路的锚点。

根目录不等于项目目录

很多人刚上手时会把整个项目文件夹直接设为根目录。代码、日志、备份、.env文件全在里面。这相当于把家门钥匙插在锁上还贴了张纸条写“欢迎光临”。

一个更稳妥的做法是让项目目录和Web根目录分离。比如Laravel的public/、Django的static/与media/、Rails的public/,框架作者早就替你想好了。根目录只放必须暴露的东西:入口文件、静态资源、上传目录。应用逻辑、配置、依赖包统统放在根目录之外。服务器配置里把DocumentRoot指向public/,请求就进不来其他目录了。

我见过一个电商站点,根目录下有个backup.sql,大小2.3GB。搜索引擎爬虫没放过它,索引之后任何人都能下载。这就是根目录边界失守的典型后果。

路径穿越与符号链接

根目录的边界有时候会被路径穿越攻击绕过。比如/../../etc/passwd这种请求,老版本服务器没做好过滤就直接读系统文件了。现代服务器默认会规范化路径,但如果你自己写路由解析,就得格外小心。

符号链接也是个坑。假设根目录下有个uploads软链接指向/var/data,而/var/data里恰好有敏感文件,那根目录的隔离就形同虚设。Nginx有个disable_symlinks指令可以管住这事,Apache也有Options -FollowSymLinks。默认配置不一定安全,得自己确认。

多站点与子目录

一台服务器跑多个站点时,根目录的规划更考验人。有人喜欢用子目录:/var/www/site-a、/var/www/site-b,每个子目录是一个独立根。也有人用子域名加独立根目录。两种都行,关键是别让一个站点的漏洞波及另一个。

我偏向给每个站点独立的系统用户和独立的根目录,权限设成750,属主是站点用户,组是Web服务器组。这样即使某个站点被上传了WebShell,攻击者也读不到隔壁站点的文件。共享主机时代那种“所有站点同属一个www-data”的做法,现在看简直是在裸奔。

根目录里的默认文件

根目录下通常会有默认索引文件:index.html、index.php、index.htm。服务器按配置顺序查找,找到哪个就返回哪个。这个顺序可以改,但别乱改。有人把index.html放在index.php前面,结果PHP入口永远不执行,页面显示的是静态占位符。排查半天才发现是目录索引顺序的问题。

还有.htaccess(Apache)或web.config(IIS),它们也住在根目录里,控制着URL重写、访问限制、缓存策略。这些文件一旦写错,轻则404,重则500。改之前备份,改之后立刻测试,这是基本纪律。

根目录是Web应用的玄关。你让谁进来、让谁看见什么、不让谁碰什么,全在这道边界上决定。把它当回事,别等出了事再回头翻日志。