跳到正文
把自建服务发到公网之前:域名、源码和管理入口会泄露什么
把自建服务发到公网之前:域名、源码和管理入口会泄露什么

把自建服务发到公网之前:域名、源码和管理入口会泄露什么

公开一个链接后,别人看到的不只是页面。域名、历史 DNS、源站端口、前端代码和管理入口会连成一条暴露链,发布前应逐层检查。

速读#

把一个自建服务链接发到公开社区,等于请很多人同时从不同角度检查它。有人看页面,有人查 DNS,有人扫开放端口,还有人直接读前端 JavaScript。

真正危险的通常不是某个“高手技巧”,而是几件小事连在一起:截图露出域名,历史记录指向源站,容器端口绑定了公网,管理密码又写在前端常量里。单独看都容易忽略,连起来就是一条完整的暴露链。

公开域名之后,扫描很快就会来#

公网服务从来不是“只有拿到链接的人能看”。域名会进入 DNS、证书透明度日志、搜索引擎和各种扫描数据库;IP 上的开放端口也会被持续探测。

因此安全判断不能建立在这些假设上:

  • 链接只发在一个小圈子里,外面的人不会知道。
  • 管理页面没有放按钮,别人找不到路径。
  • 服务用了高端口,扫描器不会扫到。
  • 前端代码压缩过,里面的常量没人看得懂。

它们都只是降低偶然发现的概率,不是访问控制。

第一层:截图和页面先泄露了什么#

发布演示图前,我会先看四个位置:地址栏、页面正文、开发者工具和终端输出。这里经常出现真实域名、源站 IP、内网地址、用户名、目录路径、请求头或 token。

最容易犯的错是只给敏感文字打码,却忘了同一张图里还有二维码、浏览器状态栏、网络请求地址或 DNS 查询结果。更稳妥的办法不是后期打码,而是使用专门的演示环境和演示账号,让截图里本来就没有生产秘密。

已经公开过的秘密不能靠删图恢复安全。只要 token、密码或私钥出现在公开页面,就应该按已泄露处理:立即吊销、轮换,再查访问日志确认影响范围。

第二层:Cloudflare 代理不等于源站永远隐藏#

域名开了 Cloudflare 代理,正常解析会返回 Cloudflare 边缘地址,但源站仍可能从其他地方被找到:

  • 以前的 DNS 记录曾直接指向源站。
  • 某个子域没有走代理,仍和主站共用同一 IP。
  • 源站还开放着 80、443 或应用高端口,拿到 IP 后可以绕过边缘直连。
  • 邮件、监控、错误页或仓库配置里留下了源站线索。

所以“橙云已开”只完成了入口代理,源站还要拒绝不该来的直连。我的站点使用 Tunnel 后,Web 服务只接受本机或容器网络访问,公网不再开放 Web 入站;这比单纯隐藏 DNS 记录更彻底。

检查时先看真实监听,而不是只看防火墙界面:

Terminal window
sudo ss -lntup
docker ps --format 'table {{.Names}}\t{{.Ports}}'
sudo ufw status numbered

如果服务只供 Nginx 使用,端口绑定到 127.0.0.1;如果只供同一 Compose 网络使用,用 expose,不要发布到宿主机。攻击面应在监听层就收住。

第三层:前端里没有秘密#

浏览器要执行的 HTML、CSS 和 JavaScript,访问者都能下载。把管理密码写成:

const ADMIN_PASSWORD = '...';

无论变量名怎么改、代码是否压缩、输入框是否隐藏,它都已经公开。前端校验只能改善交互,不能证明用户身份,因为访问者可以直接修改请求或绕过页面调用接口。

真正的认证必须发生在服务端:

  1. 服务端保存密码哈希或使用成熟身份提供方。
  2. 登录成功后签发有过期时间的会话。
  3. 每个管理接口都重新校验会话和权限。
  4. 对登录和高风险操作做限速、日志与必要的二次确认。

个人站如果已经使用 GitHub OAuth,就继续复用它;管理入口再放进 Cloudflare Access,可以把未授权请求挡在源站之外。没有必要自己发明一套前端口令系统。

第四层:管理入口要和公开页面分开#

“没有在导航里展示 /admin”不是保护。路径可以从前端 bundle、网络请求、robots 文件、仓库或常见字典里找到。

管理面应该有独立边界:

处理方式
边缘Cloudflare Access 或同类身份门禁
应用服务端会话与权限校验
接口限速、CSRF 防护、输入校验
记录登录失败和管理操作日志

全站人机挑战不适合作为主防线。它会让普通读者先受阻,也挡不住已经拿到接口和凭据的人;把挑战或 Access 只放在管理路径,边界更准确。

第五层:504 不等于“被攻破”#

公开链接后突然出现 504 Gateway Time-out,只能说明网关在期限内没等到上游响应。原因可能是请求量上升、应用进程卡死、连接池耗尽、内存不足或反向代理超时,也可能只是服务正在重启。

判断要靠证据:

Terminal window
systemctl status <service>
journalctl -u <service> --since '15 minutes ago'
docker stats --no-stream
free -h
df -h

同时对照 Nginx、应用和 Cloudflare 的时间线。没有日志和资源数据时,把 504 直接解释成 DDoS 或入侵都太早。

服务端至少应该有进程自启、资源限制、请求超时和健康检查。它们不能阻止攻击,但能避免一次流量波动把故障拖成只能手工登录重启。

不要把公开服务器当压测靶场#

社区里一句“帮我测测”很容易变成无上限并发。未经授权对别人的服务施压不合适,对自己的生产站直接压测也不专业:真实用户、日志和资源都混在一起,结果无法解释。

要验证容量,应该先写清边界:目标环境、起止时间、最大并发、最大请求率、监控指标和停止条件。先在测试环境逐级升压,看到错误率、延迟或资源达到阈值就停。压测是受控实验,不是看服务器什么时候倒。

我会在公开前走一遍的清单#

  1. 截图和页面中没有 token、密码、源站 IP、内网地址或个人信息。
  2. 仓库与构建产物中没有前端硬编码秘密。
  3. ss 和容器端口列表里只有明确需要的公网监听。
  4. Web 源站只能经预定入口到达,不能用源站 IP 绕过边缘。
  5. 管理路径有边缘门禁和服务端认证,不靠隐藏 URL。
  6. 登录与管理接口有限速、日志和会话过期。
  7. 服务有自启、资源限制、健康检查和可执行的回滚路径。
  8. 若曾公开秘密,已经轮换并检查日志,不把删帖当补救。

这份检查没有高级技巧,价值就在于把零散的小洞按攻击者实际走的顺序连起来。公开服务不可避免会被看见;能控制的是,别人看见域名之后,还能不能继续走到源站、管理接口和真正的权限。

版权许可

CC BY-NC-SA 4.0 本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

相关文章

s1oopX

登录 s1oopX