让 Nginx 只允许 Cloudflare 反向代理流量以隐藏源站

Cloudflare 的传统用法是通过反向代理你的网站服务器起到防止 DDoS 和 CDN 加速的作用,这里假设 Cloudflare 是 D 不垮的,所以许多 DDoS 提供者的研究重心就放在了如何找出 Cloudflare 的源站上,比如子域名爆破,找回密码邮箱等等.

本文仅用来记录我是如何在 IP 层面上保护自己的源站地址的.

接入 Cloudflare 之前

假设我有一个网站:example.me,托管于:95.215.45.2. 在接入 Cloudflare 之前的 dig 结果会是:

1
2
;; ANSWER SECTION:
example.Me. 1799 IN A 95.215.45.2

这个时候我的服务器 IP 是直接暴露着的,假设我的安全措施没有做好,可能一波小流量的 DDoS 我的网站就挂了:(

接入 Cloudflare 之后

由于被 D 挂了一次,我决定把 example.me 迁到 Cloudflare 上提供保护,此时 dig 结果变成类似这样,显示的是 Cloudflare 的 IP,看上去很安全:

1
2
3
;; ANSWER SECTION:
example.Me. 600 IN A 104.24.111.123
example.Me. 600 IN A 104.24.110.123

此时作为攻击者有了之前的攻击经验可以直接猜测真实 IP 是 95.215.45.2,作为测试,只需要一条 cURL 语句,通过判断返回的是否是站点内容来判断是否继续攻击这个 IP:

1
curl -H "Host: example.me" example.me

可以猜到,我的服务器又会挂掉:(

所以,我们需要配置 Nginx 只接受来自反向代理 Cloudflare 为我们清洗过后的流量.

配置 Nginx

首先在 https://www.cloudflare.com/ips/ 找到 Cloudflare 提供的 IP 段,然后在 /etc/nginx 下创建一个文件,比如 cf.conf

内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# https://www.cloudflare.com/ips
# IPv4
allow 103.21.244.0/22;
allow 103.22.200.0/22;
allow 103.31.4.0/22;
allow 104.16.0.0/12;
allow 108.162.192.0/18;
allow 131.0.72.0/22;
allow 141.101.64.0/18;
allow 162.158.0.0/15;
allow 172.64.0.0/13;
allow 173.245.48.0/20;
allow 188.114.96.0/20;
allow 190.93.240.0/20;
allow 197.234.240.0/22;
allow 198.41.128.0/17;

# IPv6
allow 2400:cb00::/32;
allow 2405:8100::/32;
allow 2405:b500::/32;
allow 2606:4700::/32;
allow 2803:f800::/32;
allow 2c0f:f248::/32;
allow 2a06:98c0::/29;

然后在需要保护的网站 Server Block 中加上:

1
2
include /etc/nginx/cf.conf;
deny all;

大功告成,现在试一下 cURL:

1
2
3
4
5
6
7
8
➜ curl -H "Host: example.me" 95.215.45.2
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>

现在非 Cloudflare 的来源 IP 会显示 403,为了混淆起见,建议同时将直接 IP 访问的流量也给 403 掉.

1
2
3
4
5
6
server {
listen 80 default_server;
server_name _;
server_tokens off;
return 403;
}

我的博客使用了Disqus评论框,如果你看不到评论框,那么多半Disqus服务在你所在的地区被墙,请使用代理访问。