起因
前几天给博客加了后台管理功能,新增了 SQLite 数据库目录 Mdata 和缓存目录 Mcache。功能跑通之后,一个念头突然冒出来:
如果我直接访问 https://域名/Mdata/content.db,会发生什么?试了一下,浏览器开始下载一个文件——数据库文件被完整暴露了。里面装着所有文章内容、用户密码哈希、翻译缓存,一旦被爬虫或路人下载走,整个站就成了透明玻璃房。
这篇文章记录一下排查和修复的过程,也给后来者一个参考。
一、先确认到底暴没暴露
不要凭直觉,先测。用 curl 或浏览器逐个访问:
curl -I https://你的域名/Mdata/content.db curl -I https://你的域名/Mcache/_config.php curl -I https://你的域名/Mdata/views.log curl -I https://你的域名/Mdata/content.db-wal
看返回的 HTTP 状态码:
返回码 含义 200 OK 危险,文件被公开下载 403 Forbidden 被拒绝,但暴露了路径存在 404 Not Found 理想结果,跟不存在一样 如果是 200,事情就得处理了。
二、为什么宝塔默认挡不住
宝塔面板的默认 Nginx 配置里,PHP 处理规则长这样:
location ~ \.php$ {
fastcgi_pass unix:/tmp/php-cgi-74.sock;
include fastcgi.conf;
}
它只管 .php 文件,其他扩展名(.db、.log、.lock)会走静态文件规则,直接被 Nginx 当普通文件吐给用户。所以 content.db 就这样裸奔了。
有人会想:那把 .db 加到 PHP 规则里不就行了?不行,那会让 Nginx 试图用 PHP 解析二进制文件,结果是乱码或 500。
正确做法是用一个独立的前缀匹配规则,把整个目录掐掉。
三、核心配置
打开宝塔面板 → 网站 → 点击站点 → 配置文件,找到 server {} 块,在里面加入:
# 屏蔽数据与缓存目录
location ^~ /Mdata/ {
return 404;
}
location ^~ /Mcache/ {
return 404;
}
保存,Nginx 会自动 reload。再测一遍那四个 URL,应该全部返回 404。
就这两条,问题解决了。
四、加固:扩展到全站
挡掉两个目录只是起点。顺手加上几条通用规则,覆盖更多场景:
# ============ 安全加固 ============
# 屏蔽隐藏文件(放行 .well-known 给证书验证用)
location ~ /\.(?!well-known) {
return 404;
}
# 屏蔽数据与缓存目录
location ^~ /Mdata/ {
return 404;
}
location ^~ /Mcache/ {
return 404;
}
# 屏蔽后台密钥 / 会话文件
location ~ ^/admin/_(key_.*|auth)\.php$ {
return 404;
}
# 兜底:禁止访问任何数据库文件
location ~* \.(db|sqlite|sqlite3|db-wal|db-shm)$ {
return 404;
}
# 禁止访问日志 / 锁文件
location ~* \.(log|lock)$ {
return 404;
}
# 禁止访问备份 / 临时 / 配置文件
location ~* \.(bak|old|orig|save|swp|swo|tmp|inc|ini|conf)$ {
return 404;
}
逐条解释:
- 隐藏文件规则:挡住
.git、.env、.htaccess这类文件。(?!well-known)是负向先行断言,避免误伤.well-known(Let's Encrypt 签发证书用)。 - 目录屏蔽:Mdata / Mcache 两个核心目录。
- 后台文件屏蔽:
Madmin/_key_*.php里存着登录密钥、_auth.php里存着会话 token。虽然内容被注释包裹不会泄露,但多一层是一层。 - 扩展名兜底:万一哪天你把
Mdata改名成Data、或者有别的目录里也有.db,这条规则依然拦得住。 - 日志/锁文件:
views.log、views.lock、php_error.log这类文件,内容可能包含 IP、UA、错误堆栈。 - 备份/临时文件:编辑器(vim / VSCode / PHPStorm)会生成
.swp、~、.orig之类,开发者改代码时忘记删掉,就会暴露源码。
六、关于 403 和 404 的哲学
安全圈有一句老话:
不要告诉攻击者你做错了什么。
一个 403 Forbidden 的响应,等价于对扫描器广播:"这里有东西,只是我现在不给你。" 攻击者下一步的动作就是尝试绕过、猜路径、找漏洞。
而 404 Not Found 是沉默——"你看到的和我看到的没什么不同"。
对自用的小站来说,攻击者本来也没那么"精准打击",大多是自动化扫描。给个 404,扫描器一般就略过了。