相信使用 Cloudflare 建站的同学,其目的都是为了隐藏服务器 IP,但是有些无良爬虫可通过 HTTP/HTTPS 访问扫描全网 IP 绕过 CDN,暴露证书、同时暴露你的域名。
就比如下面 Nginx 常规 HTTPS 跳转配置就会轻易暴露你的 IP:
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
return 301 https://$server_name$request_uri;
}
}
如果你 Nginx 上有这种配置,运行下面命令就可以获取你的域名了(假设你的IP是 1.2.3.4)
curl -v -k http://1.2.3.4
或者直接浏览器输入 http://1.2.3.4 也会跳转到你的域名。解决办法是,直接删除上面 80 端口配置,只保留 443 端口配置。也就是将 HTTPS 作为唯一的回源协议。
Nginx 上开启的端口越少,暴露的风险也就越低,这是显而易见的,就比如 Cloudflare 建站的用户,只需要开启 443 端口就够了。这里又有人问了,443 端口也可以用类似命令扫描呀!对,下面一条命令不止暴露域名,连证书都可以暴露:
curl -v -k https://1.2.3.4
开启 ssl_reject_handshake 插件
可以看见,证书和域名都暴露了。解决方法也很简单,nignx 开启 ssl_reject_handshake 插件就能防止 443 端口被扫,下面讲讲使用方法。
Nginx 版本高于等于 1.19.4,才可以使用 ssl_reject_handshake 特性来防止 SNI 信息泄露。如果 Nginx 版本太低,可以自编译 Nginx.
Nginx 里面新添加一个 server 块,即可开启 ssl_reject_handshake,如下:
注,上面插件只适用于 443 端口不适用其它端口。重启 Nginx 后,再运行上面命令,看看还会不会暴露域名。
IP 白名单
实际上还有更直接的方法,那就是配置 Cloudflare IP 白名单,服务端只允许 Cloudflare IP 的请求,其它丢弃掉。下面是利用 iptables 来设置 CF IP 白名单的方法。
有人问,为什么不用 Nginx 内置的 access module 来配置白名单?
因为使用 HTTPS 作为回源协议,爬虫依旧能通过探测证书 SNI 信息来找到你的源站服务器,所以才用 iptables 来配置白名单。
添加cloudflare ips-v4 iptables 白名单的命令:
添加cloudflare ips-v6 iptables 白名单的命令:
丢弃白名单以外的 ipv4 80,443 tcp 包:
丢弃白名单以外的 ipv6 80,443 tcp 包:
第三种假设
其实应该还有第三种方法,俺来假设一下,现在爬虫的 HTTP 版本基本都是 1.1,指定 HTTP 版本号来屏蔽爬虫,理应能达到同样效果。
Nginx 里 server 模块中引入下面规则文件:
还可以引入以下规则,来抵御 CC 攻击,下面规则比较暴力,非 Cloudflare 用户可以酌情引用。
结语
对于爬虫爬取你的真实 IP,上面三种方法,可以三选一。(第三种假设没经过测试,不确保可用性)
俺以前有一点误区,以为在 Cloudflare 上配置相应规则能屏蔽这些爬虫,其实这是不对的,因为它们压根不搭理你域名,只是扫全网IP,探测证书 SNI 信息,所以在 CF 上折腾相关规则完全是无用功。