在网站前面放置 CDN 或反向代理可以吸收流量并隐藏服务器地址,但前提是真实 IP 始终不为人知。攻击者很少去攻破 CDN,他们会直接寻找源站。本指南列出源站泄露的各种途径,以及如何让源站拒绝除代理之外的一切请求。
源站是如何被找到的
- DNS 历史记录:一些服务会保留旧记录,因此你在接入 CDN 之前使用过的 IP 仍然留有记录。
- 子域名:直接指向服务器的
mail.、ftp.或dev.记录。 - 邮件头:同一主机发出的邮件会在邮件头中暴露其 IP。
- 证书透明度和互联网扫描:扫描器会把证书与所有提供该证书的 IP 对应起来。
- 应用行为:Webhook、图片抓取器和“检查此 URL”之类的功能会从源站向外发起连接。
第 1 步:从干净的状态开始
如果服务器已经暴露,最稳妥的办法是更换 IP,或者换一台新服务器并迁移。想隐藏一个已经公开的地址是行不通的。请参考零停机迁移指南来规划迁移。
第 2 步:只接受来自代理的流量
只允许代理公布的地址段访问 Web 端口,其余一律拒绝。使用 UFW 时,做法如下,请使用你的服务商公布的地址段。
sudo ufw default deny incoming
sudo ufw allow OpenSSH
for ip in $(cat proxy-ranges.txt); do sudo ufw allow from "$ip" to any port 443 proto tcp; done
sudo ufw enable
由于地址段会变化,请定期刷新该列表。为了获得更强的保障,可使用经过认证的源站拉取(双向 TLS),让 Nginx 拒绝任何没有代理证书的客户端。
第 3 步:隔离一切可能泄露的内容
- 通过另一台主机或中继发送邮件,绝不要从源站发送。
- 不要让非 Web 子域名指向源站 IP。
- 让应用的出站请求经过代理或单独的 worker。
- 配置一个默认的 Nginx server 块,对未知的
Host返回空响应,这样扫描裸 IP 时什么也看不到。
server {
listen 443 ssl default_server;
ssl_reject_handshake on;
}
第 4 步:像攻击者一样测试
在 DNS 历史工具中搜索你的域名,扫描你自己的 IP 段以查找该证书,并通过测试邮件检查邮件头。只要其中任何一项暴露了源站,就更换 IP 并重复上述步骤。
请记住它能做什么、不能做什么:它保护的是地址的可用性和隐私,并不会隐藏账户的所有者是谁。关于这一点,请阅读匿名托管到底有多匿名;至于能绕过网络层的攻击,请参阅 第 7 层防御。