此配置的主要用途是确保没有人可以绕过Cloudflare或其他安全反向代理提供商对网站发起拒绝服务攻击(DoS)。类似功能可以通过real_ip和其他插件实现,但本文的重点是简化设置,不需要安装插件。
需要注意的是,Cloudflare的IP范围并非静态的,尽管变化频率非常低,仍需要手动更新。有人仍然可以通过Cloudflare Workers作为第三方在Cloudflare IP范围内发起请求,不过要使用这种方式进行大规模拒绝服务攻击难度较大。
首先我们创建一个Shell脚本,该脚本将Cloudflare的IPv4/IPv6地址输出为Caddyfile所需的格式:
cloudflare-ip-list.sh:
1
2
3
4
5
6
7
8
9
10
|
#!/bin/sh
#
# 输出最新的Cloudflare IP列表。
#
# 注意:即使阻止这些范围的流量,第三方的Cloudflare Workers仍然可以访问您的网站。
#
for i in `curl -s https://www.cloudflare.com/ips-v4`; do echo -n "$i "; done
for i in `curl -s https://www.cloudflare.com/ips-v6`; do echo -n "$i "; done
echo
|
以下是一个针对多个子域配置的Caddyfile示例,每个子域使用相同的规则阻止非Cloudflare的流量。
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
#
# Caddy配置示例,阻止非Cloudflare的流量
#
{
admin off
email [email protected]
log {
output file /var/log/caddy/access.log
format json
}
}
#
# Caddy代码片段:用于阻止所有非Cloudflare来源的流量。
#
# 此配置旨在阻止恶意扫描和IP侦查的机器人流量。
#
# 生成remote_ip列表可通过cloudflare-ip-list.sh脚本
#
# 了解更多关于Caddy代码片段的信息:
# - https://caddyserver.com/docs/caddyfile/concepts#snippets
# - https://caddy.community/t/caddy-v2-reusable-snippets/6744
#
(cloudflare-only) {
# 使用shell脚本输出的IP地址更新此处
@blocked not remote_ip 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32
respond @blocked "<h1>仅允许通过Cloudflare访问HTTP/HTTPS</h1>" 403
}
# 指定只能通过Cloudflare反向代理访问的子域
#
# 手动测试直接IP是否被阻止:
#
# curl --header "Host: mysite.example.com" http://1.2.3.4
#
http://mysite.example.com {
handle {
import cloudflare-only
# 网站处理逻辑
reverse_proxy 127.0.0.1:8080
}
}
:80 {
respond "<h1>未指定站点域名的HTTP请求</h1>" 403
}
:443 {
respond "<h1>未指定站点域名的HTTPS请求</h1>" 403
}
|
使用以下命令测试直接IP访问是否被成功阻止:
1
|
curl --header "Host: mysite.example.com" http://1.2.3.4
|
成功阻止时,应该返回:
1
|
<h1>仅允许通过Cloudflare访问HTTP/HTTPS</h1>
|