---
id: cloudflare-free-tier
title: 给一台小服务器套上 Cloudflare：免费版的边界在哪
date: 2026-11-02
updated: 2026-11-05
category: 建站
tags: Cloudflare, nginx, WAF
minutes: 12
---

很多人说的"套个 Cloudflare"，其实只是把橙色云朵点亮。它确实能挡掉一部分东西，但免费版的额度比想象中紧，而且最容易出事的地方通常不在 Cloudflare，而在源站。

这篇按我自己那台机器的顺序写：先讲清楚防护发生在哪一层，再说免费版到底给了什么，最后是源站必须配合的两件事。

## 一、防护发生在哪一层

请求进到你的服务器之前，会先落在 Cloudflare 的边缘节点。能被拦在那里的部分越多，源站就越轻松。

| 层 | 在做什么 | 免费版 |
|---|---|---|
| DNS | 对外只暴露 Cloudflare 的地址 | 有 |
| 边缘 DDoS | L3/L4/L7 清洗，不计费 | 有 |
| WAF | 托管规则 + 自定义规则 | 自定义 5 条 |
| 速率限制 | 按 IP 和路径限速 | 只有 1 条 |
| 源站 | 限速、只放行回源、纯静态 | 自己配 |

最后一行经常被忽略。边缘再强，只要源站 IP 能被直接访问，前面配的东西都可以绕过去。

## 二、迁 DNS 之前先备份

Cloudflare 的 CDN 能力建立在它接管解析上。换 NS 是整体换掉解析服务商，漏一条记录就掉一个服务。先把现有记录导出来：

```
# 按你自己的子域列表补全
for n in @ www mail blog; do
  echo "== $n"
  dig +short A "$n.example.com"
done | tee dns-backup.txt
```

特别留意三类：MX 和 TXT（邮件验证，最容易漏）、泛解析 `*`（Cloudflare 不会自动建）、以及那些"不是 80/443 用途"的子域。

:::注意
橙色云朵不是全开就好。只有 HTTP/HTTPS 网站该开代理；SSH、面板、代理节点这类必须保持灰云，否则会直接连不上。
:::

## 三、回源模式选 Full (strict)

四种模式的区别值得记住，因为它直接决定源站流量在公网上是不是明文：

```
Flexible      Cloudflare → 源站 走 HTTP，明文回源，最危险
Full          走 HTTPS，但不验证证书，可被中间人
Full(strict)  走 HTTPS 且验证证书 —— 选这个
```

Strict 的前提是源站有一张被信任的证书。可以用 Cloudflare 的 Origin CA（15 年、不写入证书透明度日志），也可以用 Let's Encrypt（通用，但签发记录会公开）。

## 四、让 nginx 认得真实访客

开了代理之后，`$remote_addr` 全是 Cloudflare 的机房地址。日志和限速都对着同一批 IP 生效，等于失效。

```
set_real_ip_from 173.245.48.0/20;
# … 其余 14 段 IPv4 和 7 段 IPv6，用脚本生成，别手抄
real_ip_header    CF-Connecting-IP;
real_ip_recursive on;
```

只有列在 `set_real_ip_from` 里的网段发来的这个头才被采信，所以伪造它没有用。

## 五、源站只接受回源

这一步才是真正"藏源站"。做法是判断连接的对端地址是不是 Cloudflare，不是就拒绝。注意别拿 `CF-Connecting-IP` 判断——那个头可以伪造。

```
set $allow_direct 0;
set $deny_direct 0;
if ($is_cf_edge = "0")   { set $deny_direct 1; }
if ($allow_direct = "1") { set $deny_direct 0; }
if ($deny_direct = "1")  { return 403; }
```

之所以拆成三条，是因为 nginx 的 `if` 不支持变量拼接，`if ($a$b = "00")` 会报 unknown variable。

:::坑
切到 0 之前务必确认 Cloudflare 链路是通的。改完如果打不开，本地和 CDN 都被挡，只能 SSH 上去改回来。
:::

## 六、验证

配置完跑这几条，缺一条都说明没生效：

```
# 1. 是否经过边缘
curl -sI https://blog.example.com | grep -i cf-ray

# 2. 直连源站是否被拒（期望 403）
curl -s -o /dev/null -w '%{http_code}\n' \
  --resolve blog.example.com:443:源站IP https://blog.example.com/

# 3. 限速是否生效（20 并发）
seq 1 60 | xargs -P20 -I{} curl -s -o /dev/null -w '%{http_code}\n' \
  https://blog.example.com/ | sort | uniq -c
```

第三条会同时看到 200 和 429，那就对了。

## 七、真被打的时候

顺序大概是这样：先看 Security Events 里哪条规则在拦、哪条没拦住；然后把 Security Level 提到 High；有明确特征（固定 UA 或路径）就加一条自定义规则，这比封 IP 有效得多；实在扛不住再开 Under Attack，那里是全站 JS 挑战，SEO 会受影响，攻击一停要记得关。

别急着换源站 IP。只要藏源站还在生效，清洗都在边缘完成，换 IP 只是暴露新线索。

:::边界
免费版挡不住"直接打 IP"的流量。如果同机的其他域名还留着灰云 A 记录，任何人都能 dig 出源站地址，然后绕开这一整套。真要解决，得让源站不再暴露公网端口。
:::
