速读#
把一个自建服务链接发到公开社区,等于请很多人同时从不同角度检查它。有人看页面,有人查 DNS,有人扫开放端口,还有人直接读前端 JavaScript。
真正危险的通常不是某个“高手技巧”,而是几件小事连在一起:截图露出域名,历史记录指向源站,容器端口绑定了公网,管理密码又写在前端常量里。单独看都容易忽略,连起来就是一条完整的暴露链。
公开域名之后,扫描很快就会来#
公网服务从来不是“只有拿到链接的人能看”。域名会进入 DNS、证书透明度日志、搜索引擎和各种扫描数据库;IP 上的开放端口也会被持续探测。
因此安全判断不能建立在这些假设上:
- 链接只发在一个小圈子里,外面的人不会知道。
- 管理页面没有放按钮,别人找不到路径。
- 服务用了高端口,扫描器不会扫到。
- 前端代码压缩过,里面的常量没人看得懂。
它们都只是降低偶然发现的概率,不是访问控制。
第一层:截图和页面先泄露了什么#
发布演示图前,我会先看四个位置:地址栏、页面正文、开发者工具和终端输出。这里经常出现真实域名、源站 IP、内网地址、用户名、目录路径、请求头或 token。
最容易犯的错是只给敏感文字打码,却忘了同一张图里还有二维码、浏览器状态栏、网络请求地址或 DNS 查询结果。更稳妥的办法不是后期打码,而是使用专门的演示环境和演示账号,让截图里本来就没有生产秘密。
已经公开过的秘密不能靠删图恢复安全。只要 token、密码或私钥出现在公开页面,就应该按已泄露处理:立即吊销、轮换,再查访问日志确认影响范围。
第二层:Cloudflare 代理不等于源站永远隐藏#
域名开了 Cloudflare 代理,正常解析会返回 Cloudflare 边缘地址,但源站仍可能从其他地方被找到:
- 以前的 DNS 记录曾直接指向源站。
- 某个子域没有走代理,仍和主站共用同一 IP。
- 源站还开放着 80、443 或应用高端口,拿到 IP 后可以绕过边缘直连。
- 邮件、监控、错误页或仓库配置里留下了源站线索。
所以“橙云已开”只完成了入口代理,源站还要拒绝不该来的直连。我的站点使用 Tunnel 后,Web 服务只接受本机或容器网络访问,公网不再开放 Web 入站;这比单纯隐藏 DNS 记录更彻底。
检查时先看真实监听,而不是只看防火墙界面:
sudo ss -lntupdocker ps --format 'table {{.Names}}\t{{.Ports}}'sudo ufw status numbered如果服务只供 Nginx 使用,端口绑定到 127.0.0.1;如果只供同一 Compose 网络使用,用 expose,不要发布到宿主机。攻击面应在监听层就收住。
第三层:前端里没有秘密#
浏览器要执行的 HTML、CSS 和 JavaScript,访问者都能下载。把管理密码写成:
const ADMIN_PASSWORD = '...';无论变量名怎么改、代码是否压缩、输入框是否隐藏,它都已经公开。前端校验只能改善交互,不能证明用户身份,因为访问者可以直接修改请求或绕过页面调用接口。
真正的认证必须发生在服务端:
- 服务端保存密码哈希或使用成熟身份提供方。
- 登录成功后签发有过期时间的会话。
- 每个管理接口都重新校验会话和权限。
- 对登录和高风险操作做限速、日志与必要的二次确认。
个人站如果已经使用 GitHub OAuth,就继续复用它;管理入口再放进 Cloudflare Access,可以把未授权请求挡在源站之外。没有必要自己发明一套前端口令系统。
第四层:管理入口要和公开页面分开#
“没有在导航里展示 /admin”不是保护。路径可以从前端 bundle、网络请求、robots 文件、仓库或常见字典里找到。
管理面应该有独立边界:
| 层 | 处理方式 |
|---|---|
| 边缘 | Cloudflare Access 或同类身份门禁 |
| 应用 | 服务端会话与权限校验 |
| 接口 | 限速、CSRF 防护、输入校验 |
| 记录 | 登录失败和管理操作日志 |
全站人机挑战不适合作为主防线。它会让普通读者先受阻,也挡不住已经拿到接口和凭据的人;把挑战或 Access 只放在管理路径,边界更准确。
第五层:504 不等于“被攻破”#
公开链接后突然出现 504 Gateway Time-out,只能说明网关在期限内没等到上游响应。原因可能是请求量上升、应用进程卡死、连接池耗尽、内存不足或反向代理超时,也可能只是服务正在重启。
判断要靠证据:
systemctl status <service>journalctl -u <service> --since '15 minutes ago'docker stats --no-streamfree -hdf -h同时对照 Nginx、应用和 Cloudflare 的时间线。没有日志和资源数据时,把 504 直接解释成 DDoS 或入侵都太早。
服务端至少应该有进程自启、资源限制、请求超时和健康检查。它们不能阻止攻击,但能避免一次流量波动把故障拖成只能手工登录重启。
不要把公开服务器当压测靶场#
社区里一句“帮我测测”很容易变成无上限并发。未经授权对别人的服务施压不合适,对自己的生产站直接压测也不专业:真实用户、日志和资源都混在一起,结果无法解释。
要验证容量,应该先写清边界:目标环境、起止时间、最大并发、最大请求率、监控指标和停止条件。先在测试环境逐级升压,看到错误率、延迟或资源达到阈值就停。压测是受控实验,不是看服务器什么时候倒。
我会在公开前走一遍的清单#
- 截图和页面中没有 token、密码、源站 IP、内网地址或个人信息。
- 仓库与构建产物中没有前端硬编码秘密。
ss和容器端口列表里只有明确需要的公网监听。- Web 源站只能经预定入口到达,不能用源站 IP 绕过边缘。
- 管理路径有边缘门禁和服务端认证,不靠隐藏 URL。
- 登录与管理接口有限速、日志和会话过期。
- 服务有自启、资源限制、健康检查和可执行的回滚路径。
- 若曾公开秘密,已经轮换并检查日志,不把删帖当补救。
这份检查没有高级技巧,价值就在于把零散的小洞按攻击者实际走的顺序连起来。公开服务不可避免会被看见;能控制的是,别人看见域名之后,还能不能继续走到源站、管理接口和真正的权限。
