使用 nftables 配置 Web 服务器仅允许 Cloudflare IP 访问
✨ 文章记录了如何使用 nftables(Linux 中现代化的防火墙框架)配置防火墙规则实现仅允许来源自 Cloudflare IP 源地址的访问,确保所有流量都通过 Cloudflare 处理。
将网站接入 Cloudflare CDN 是提高其性能和安全性的常用方法。然而,如果您的源服务器仍然可以直接通过其 IP 地址访问,那么 Cloudflare 带来的许多安全优势(如 DDoS 防护、WAF)可能会被绕过。
为了确保仅接收来自 Cloudflare 代理的流量,一是可以通过建立 Cloudflare Tunnel 之类的隧道来排除其他流量,再一个就是配置 Linux 自身的网络防火墙仅允许 Cloudflare 的 源 IP 访问服务器。
下面是修改 nftables 配置文件的记录
获取 Cloudflare IP 地址范围
我们可以从 Cloudflare 官方文档中找到这些列表:
第二步:修改 nftables 配置
nftables 的配置文件通常位于 /etc/nftables.conf
sudo vim /etc/nftables.conf在配置文件中,我们将定义一个 inet (IPv4/IPv6) 类型的 filter 表,并在 input 链(处理进入服务器的数据包)中添加规则。
以下是一个配置示例,可以将其内容整合到您现有的 nftables.conf 文件中,或者如果文件为空,则直接使用它。
记得将示例中的 IP 地址列表替换为您在第一步中获取的 最新 Cloudflare IP 范围。
#!/usr/sbin/nft -f
# 完全清除现有规则集,确保配置从干净状态开始
flush ruleset
# 定义 Cloudflare IPv4 地址集合
define cloudflare_ipv4 = {
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
}
# 定义 Cloudflare IPv6 地址集合
define cloudflare_ipv6 = {
2400:cb00::/32, 2606:4700::/32, 2803:f800::/32,
2405:b500::/32, 2405:8100::/32, 2a06:98c0::/29,
2c0f:f248::/32
}
# 定义 HTTP/HTTPS 端口
define http_ports = { 80, 443 }
table inet filter {
# 输入链处理进入系统的数据包
chain input {
type filter hook input priority 0;
# 使用明确的默认策略:拒绝所有流量,仅允许特定规则
policy drop;
# 允许本地回环接口流量
iif lo accept comment "允许本地回环流量"
# 允许已建立和相关的连接
ct state established,related accept comment "允许已建立和相关连接"
# 允许来自 Cloudflare 的 HTTP/HTTPS 流量
ip saddr $cloudflare_ipv4 tcp dport $http_ports accept comment "允许 Cloudflare IPv4 HTTP/HTTPS 流量"
ip6 saddr $cloudflare_ipv6 tcp dport $http_ports accept comment "允许 Cloudflare IPv6 HTTP/HTTPS 流量"
# 允许 ICMP 流量用于网络诊断
ip protocol icmp accept comment "允许 ICMPv4 流量"
ip6 nexthdr ipv6-icmp accept comment "允许 ICMPv6 流量"
# SSH 访问控制(默认注释掉,建议仅在需要时启用并限制源 IP)
# tcp dport 22 ip saddr { 192.168.1.0/24, 10.0.0.0/8 } accept comment "仅允许特定 IP 范围的 SSH 访问"
# 记录被拒绝的 HTTP/HTTPS 请求(可选,用于调试)
# tcp dport $http_ports counter log prefix "BLOCKED HTTP/HTTPS: " drop comment "记录并阻止非 Cloudflare HTTP/HTTPS 访问"
# 记录所有其他被拒绝的请求(可选,用于调试)
# counter log prefix "BLOCKED OTHER: " comment "记录所有其他被拒绝的请求"
}
# 转发链处理通过系统转发的数据包
chain forward {
type filter hook forward priority 0;
policy drop;
# 如需添加转发规则,请在此处添加
}
# 输出链处理从系统发出的数据包
chain output {
type filter hook output priority 0;
policy accept;
# 默认允许所有出站流量
# 如需限制出站流量,请在此处添加规则
}
}配置说明(如下解释均由 AI 生成):
table inet filter { ... }: 定义一个用于 IPv4 和 IPv6 的过滤表。chain input { ... }: 定义处理入站流量的链。type filter hook input priority 0;: 指定这是一个过滤链,挂载到input钩子上,优先级为 0。policy accept;: 默认策略是接受所有流量。我们稍后会添加特定的drop规则。或者,您可以将此设置为policy drop;并仅显式accept您需要的流量(更安全的默认设置)。iif "lo" accept: 允许本地回环接口(localhost)的通信。非常重要,否则本地服务可能无法通信。ct state established,related accept: 允许属于已建立连接或与现有连接相关的包通过。这通常是必要的,以允许双向通信正常工作。ip saddr { ... } tcp dport { 80, 443 } accept: 允许源 IP 地址 (saddr) 在指定列表中的 IPv4 流量访问 TCP 目标端口 (dport) 80 或 443。ip6 saddr { ... } tcp dport { 80, 443 } accept: 同上,但针对 IPv6 地址。ip protocol tcp tcp dport { 80, 443 } drop: 拒绝所有 其他 访问 TCP 端口 80 或 443 的 IPv4 流量。ip6 nexthdr tcp tcp dport { 80, 443 } drop: 同上,但针对 IPv6 流量。comment "...": 为规则添加注释,便于理解。
应用 nftables 配置
保存对 /etc/nftables.conf 文件的更改后,需要加载这些新规则。使用以下命令:
sudo nft -f /etc/nftables.conf这条命令会检查配置文件的语法,如果无误,则原子性地应用新规则集。
或者我们可以使用 systemd 服务来管理 nftables,从而使得配置在重启后也能持久化(通常需要先启用服务 sudo systemctl enable nftables),可以使用:
sudo systemctl restart nftables注意: 在应用防火墙规则之前,请确保有其他访问服务器的方式(例如,控制台访问、允许 SSH 的规则),以防配置错误导致网络连接中断。
验证 nftables 配置
应用配置后,验证规则是否已按预期加载至关重要。使用以下命令查看当前的完整规则集:
sudo nft list ruleset检查输出,确保在 inet filter 表的 input 链中能看到刚刚添加的允许 Cloudflare IP 和拒绝其他 HTTP/HTTPS 访问的规则。
此时我们还可以尝试从 非 Cloudflare 的 IP 地址访问您的网站(端口 80 或 443)。这些连接应该被阻止(例如,超时或连接被拒绝)。同时,通过 Cloudflare 访问网站应能正常工作。