本文约 2,637 字,预计阅读 7 分钟。文中命令与配置均经过实测,可直接参考执行。
引言
试着在浏览器里输入 https://你的域名/wp-content/uploads/ 或者 https://你的域名/wp-includes/,如果页面直接列出一个个文件名、大小和修改时间,说明你的服务器开启了目录列表(Directory Listing)。这在攻击者眼里是一份现成的「藏宝图」:他能一眼看到你上传了哪些敏感文件、有没有备份、用的什么主题插件和版本,甚至能找到没做保护的配置文件。目录列表本身不是漏洞,但它把「需要猜」的信息直接给了对手,属于典型的信息泄露,会让后续的针对性攻击事半功倍。本篇文章教你用最少的改动,把 Apache 和 Nginx 两种环境下的目录列表关掉,并验证是否真的生效。
故障原因分析
- 服务器默认开启了目录索引。Apache 的
Options Indexes或 Nginx 的autoindex on是很多环境(尤其是一些一键环境包)的默认状态,导致没有默认首页的目录会直接列文件。
- 目录里缺少 index 文件。服务器在找不到
index.php、index.html时,如果允许索引就会退而列出目录内容。
- 上传目录权限过开放。
wp-content/uploads常被设成可写,一旦目录列表开着,攻击者能直接看清你上传的所有文件,包括可能的备份、导出数据。
- 备份文件与日志外露。很多人习惯把
.sql、.zip备份丢在网站目录里,配合目录列表等于把数据库直接公开。
- 攻击者靠它做侦察。扫描器会试探常见目录能否被遍历,一旦发现可列目录,就会顺藤摸瓜寻找可利用的插件、旧版本文件和敏感配置。
分步解决方案
方法一:先用命令确认哪些目录能遍历
在服务器上直接请求目录看返回码,200 且内容是文件清单就是开着:
# 看上传目录、包含目录、插件目录是否可列
for d in wp-content/uploads/ wp-includes/ wp-content/plugins/ wp-content/themes/; do
code=$(curl -s -o /dev/null -w "%{http_code}" "https://你的域名/$d")
echo "$d -> $code"
done
如果返回 200 并能看到文件清单,就需要处理。返回 403 或 404 的目录一般是安全的。
方法二:用 .htaccess 全局关闭目录列表(Apache)
在网站根目录 .htaccess 里加入:
# 关闭目录索引,禁止列出目录内容
Options -Indexes
这样整个站点的目录列表都会被关掉。若你只想针对某个敏感目录处理,可以在该目录下单独放一个 .htaccess:
# 放在 wp-content/uploads/.htaccess
Options -Indexes
方法三:给关键目录补上 index 文件
即使 Options -Indexes 生效,给目录放一个空白的 index 文件是更保险的双保险做法。在 wp-content/uploads/ 下新建 index.html,内容留空即可(WordPress 会自动生成一个 index.php 用于目录保护,但有些环境没生成)。
# 在常用目录里补一个空白 index.html
touch /www/wwwroot/yoursite.com/wp-content/uploads/index.html
touch /www/wwwroot/yoursite.com/wp-content/themes/index.html
这样即便服务器规则被改动,访问目录也只会打开一个空白页,不会列文件。
方法四:Nginx 环境用 autoindex off
Nginx 用户要修改站点配置文件(宝塔用户可在「网站 → 设置 → 配置文件」里改),在 server 段或对应 location 里加:
server {
# 关闭目录列表
autoindex off;
location /wp-content/uploads/ {
autoindex off;
try_files $uri $uri/ =404;
}
}
改完执行 nginx -t 检测语法,再 nginx -s reload 重载。宝塔面板也有图形开关:网站设置里找「目录浏览」相关选项关闭即可。
方法五:顺手处理外露的备份与敏感文件
关闭目录列表只是第一步,还要主动清理「能被列出来」的东西。把 wp-config.php 的备份、.sql 导出、.zip 整站包从网站目录移走,别放在能被 URL 访问的位置。同时给 wp-config.php 和 xmlrpc.php 加访问限制(可参考站内相关文章)。最后再跑一遍方法一的命令,确认全部目录都返回 403 或 404。
常见踩坑点
.htaccess里写成了Options +Indexes。加号是开启,减号才是关闭,写反了等于帮倒忙,务必用-Indexes。
- 只改根目录忽略子目录。子目录若有自己的
.htaccess覆盖了根目录设置,仍可能被遍历,需要逐层确认。
- Nginx 改了不重载。改完配置不
reload,改动不生效,还容易因为语法错误导致站点 500,改前先备份。
- 关闭后误伤功能。极少数依赖目录读取的功能可能受影响,改动后测一遍上传图片、前台页面是否正常。
- 只关目录列表不清备份文件。备份文件还躺在网站目录里,一旦被别的漏洞泄露就是大事故。
- 以为 403 就绝对安全。目录列表关了,但若文件本身能被猜中路径直接下载(比如
backup.sql),照样危险,敏感文件该移走就移走。
总结
目录列表把网站的文件结构赤裸裸地展示出来,虽然不算高危漏洞,却是攻击者最爱的侦察入口。关闭方法很简单:Apache 用 Options -Indexes,Nginx 用 autoindex off,再给敏感目录补上空白 index 文件做双保险。改完后一定用 curl 逐个目录复测,确认都返回 403 或 404。同时别忘了清理放在网站目录里的数据库备份和压缩包,它们配合目录列表才是真正致命。把 WordPress 目录列表禁用到位,你的站就少了一张递给攻击者的地图。
