从 DNS 到 Tunnel:一次把 Cloudflare 配明白的实战记录
Cloudflare 实战案例分享|附完整命令
在现代网站架构中,Cloudflare 已经不只是一个“免费 CDN”工具,而是一个集 DNS 管理、CDN 加速、HTTPS 证书、DDoS 防护、WAF 防火墙、Zero Trust、对象存储、边缘计算 等能力于一体的综合平台。对于个人开发者、中小企业、独立站站长以及运维工程师来说,合理使用 Cloudflare,可以显著提升网站访问速度、安全性和稳定性。
本文将通过一个完整实战案例,演示如何将一个普通网站接入 Cloudflare,并结合常见运维场景,给出可直接复制使用的命令示例。文章内容包括:域名接入、DNS 配置、源站 Nginx 配置、HTTPS 设置、防盗链、防火墙规则、缓存优化、真实 IP 获取、Cloudflare Tunnel 内网穿透以及常见问题排查。
一、实战背景说明
假设我们有一个网站:
域名:www.example.com
源站服务器:Ubuntu 22.04
Web 服务:Nginx
网站目录:/var/www/example.com
源站 IP:1.2.3.4
我们的目标是:
- 将域名接入 Cloudflare;
- 使用 Cloudflare 托管 DNS;
- 开启 HTTPS;
- 配置 Nginx 适配 Cloudflare;
- 获取访客真实 IP;
- 开启缓存与安全防护;
- 使用 Cloudflare Tunnel 暴露本地服务;
- 给出完整命令,方便直接实操。
注意:文中的
example.com、1.2.3.4请替换为你自己的域名和服务器 IP。
二、将域名接入 Cloudflare
1. 注册并添加站点
首先登录 Cloudflare 官网:
https://dash.cloudflare.com/
注册账号后,点击:
Add a website
输入你的域名,例如:
example.com
Cloudflare 会自动扫描当前域名已有 DNS 记录。扫描完成后,你需要确认 DNS 记录是否正确。
常见记录如下:
A example.com 1.2.3.4
A www 1.2.3.4
CNAME cdn example.com
MX example.com mail.example.com
其中,网站相关的记录可以开启 Cloudflare 代理,也就是橙色云朵。
Proxied:经过 Cloudflare CDN 和安全防护
DNS only:只做 DNS 解析,不经过 Cloudflare
对于网站访问,一般建议:
example.com Proxied
www.example.com Proxied
对于邮件服务,例如 MX、mail、smtp 等,通常建议保持:
DNS only
因为邮件协议不适合直接走 Cloudflare 普通 CDN 代理。
三、修改域名 NS 服务器
Cloudflare 添加站点后,会分配两个 Nameserver,例如:
abby.ns.cloudflare.com
walt.ns.cloudflare.com
你需要到域名注册商后台,将原来的 DNS 服务器修改为 Cloudflare 提供的 NS。
例如原来是:
ns1.registrar.com
ns2.registrar.com
修改为:
abby.ns.cloudflare.com
walt.ns.cloudflare.com
修改完成后,等待 DNS 生效。一般几分钟到数小时,最长可能 24 到 48 小时。
可以使用以下命令检查 NS 是否已经切换成功。
Linux / macOS 查询 NS
dig NS example.com
示例输出:
example.com. 86400 IN NS abby.ns.cloudflare.com.
example.com. 86400 IN NS walt.ns.cloudflare.com.
使用公共 DNS 查询
dig @8.8.8.8 NS example.com
dig @1.1.1.1 NS example.com
如果返回的是 Cloudflare 的 NS,说明已经生效。
四、源站服务器基础环境准备
下面以 Ubuntu 22.04 为例。
1. 更新系统
sudo apt update
sudo apt upgrade -y
2. 安装 Nginx
sudo apt install nginx -y
3. 启动并设置开机自启
sudo systemctl start nginx
sudo systemctl enable nginx
查看状态:
sudo systemctl status nginx
4. 创建网站目录
sudo mkdir -p /var/www/example.com
创建测试首页:
sudo tee /var/www/example.com/index.html > /dev/null <<'EOF'
Cloudflare 实战案例
Hello Cloudflare
这是一个接入 Cloudflare 的测试站点。
EOF
设置权限:
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com
五、配置 Nginx 虚拟主机
创建 Nginx 配置文件:
sudo nano /etc/nginx/sites-available/example.com
写入以下内容:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html index.htm;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
try_files $uri $uri/ =404;
}
}
创建软链接启用站点:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
测试 Nginx 配置:
sudo nginx -t
重新加载 Nginx:
sudo systemctl reload nginx
如果你想删除默认站点,可以执行:
sudo rm -f /etc/nginx/sites-enabled/default
sudo systemctl reload nginx
本地测试源站是否正常:
curl -I http://127.0.0.1
指定 Host 测试:
curl -I -H "Host: example.com" http://127.0.0.1
如果返回 HTTP/1.1 200 OK,说明源站配置正常。
六、Cloudflare SSL/TLS 模式选择
进入 Cloudflare 后台:
SSL/TLS -> Overview
常见模式有:
Off
Flexible
Full
Full strict
建议优先使用:
Full strict
原因是它要求 Cloudflare 到源站之间也必须使用有效证书,安全性最高。
如果你的源站暂时没有 HTTPS 证书,可以先使用:
Full
不建议长期使用:
Flexible
因为 Flexible 模式下,用户到 Cloudflare 是 HTTPS,但 Cloudflare 到源站是 HTTP,容易引发重定向循环或安全问题。
七、为源站申请 Cloudflare Origin Certificate
Cloudflare 提供 Origin Certificate,可以部署在源站,仅用于 Cloudflare 与源站之间的 HTTPS 通信。
操作路径:
SSL/TLS -> Origin Server -> Create Certificate
选择:
Generate private key and CSR with Cloudflare
主机名可以填写:
example.com
*.example.com
证书有效期可以选择 15 年。
生成后,你会得到:
- Origin Certificate;
- Private Key。
在服务器上创建目录:
sudo mkdir -p /etc/nginx/ssl/example.com
保存证书:
sudo nano /etc/nginx/ssl/example.com/origin.crt
粘贴 Cloudflare 提供的 Certificate 内容。
保存私钥:
sudo nano /etc/nginx/ssl/example.com/origin.key
粘贴 Cloudflare 提供的 Private Key 内容。
设置权限:
sudo chmod 600 /etc/nginx/ssl/example.com/origin.key
sudo chmod 644 /etc/nginx/ssl/example.com/origin.crt
八、配置 Nginx HTTPS
修改 Nginx 站点配置:
sudo nano /etc/nginx/sites-available/example.com
完整配置如下:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html index.htm;
ssl_certificate /etc/nginx/ssl/example.com/origin.crt;
ssl_certificate_key /etc/nginx/ssl/example.com/origin.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
try_files $uri $uri/ =404;
}
}
测试配置:
sudo nginx -t
重载服务:
sudo systemctl reload nginx
用 curl 测试 HTTPS:
curl -I https://example.com
如果 DNS 已经接入 Cloudflare,返回可能类似:
HTTP/2 200
server: cloudflare
说明请求已经经过 Cloudflare。
九、获取访客真实 IP
接入 Cloudflare 后,Nginx 日志中默认看到的客户端 IP 通常是 Cloudflare 的节点 IP,而不是用户真实 IP。为了记录真实访客 IP,需要配置 Nginx 的 real_ip 模块。
1. 创建 Cloudflare IP 配置文件
sudo nano /etc/nginx/conf.d/cloudflare-real-ip.conf
写入以下内容:
real_ip_header CF-Connecting-IP;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
测试并重载 Nginx:
sudo nginx -t
sudo systemctl reload nginx
查看访问日志:
sudo tail -f /var/log/nginx/example.com.access.log
这时日志中的 IP 应该会显示真实访客 IP。
2. 自动更新 Cloudflare IP
Cloudflare IP 段可能会变动,可以写一个脚本自动更新。
创建脚本:
sudo nano /usr/local/bin/update-cloudflare-real-ip.sh
写入:
#!/bin/bash
set -e
CONF_PATH="/etc/nginx/conf.d/cloudflare-real-ip.conf"
echo "real_ip_header CF-Connecting-IP;" > "$CONF_PATH"
echo "" >> "$CONF_PATH"
curl -s https://www.cloudflare.com/ips-v4 | while read ip; do
echo "set_real_ip_from $ip;" >> "$CONF_PATH"
done
curl -s https://www.cloudflare.com/ips-v6 | while read ip; do
echo "set_real_ip_from $ip;" >> "$CONF_PATH"
done
nginx -t
systemctl reload nginx
echo "Cloudflare real IP list updated."
赋予执行权限:
sudo chmod +x /usr/local/bin/update-cloudflare-real-ip.sh
手动执行一次:
sudo /usr/local/bin/update-cloudflare-real-ip.sh
添加定时任务:
sudo crontab -e
加入:
0 3 * * 1 /usr/local/bin/update-cloudflare-real-ip.sh >/var/log/update-cloudflare-real-ip.log 2>&1
表示每周一凌晨 3 点自动更新。
十、只允许 Cloudflare 访问源站
为了防止攻击者绕过 Cloudflare 直接攻击源站 IP,可以在服务器防火墙中只允许 Cloudflare IP 访问 80 和 443 端口。
注意:执行此类操作前,请确保 SSH 端口不会被误封。建议先放行自己的 SSH IP。
1. 安装 UFW
sudo apt install ufw -y
2. 放行 SSH
如果你的 SSH 端口是 22:
sudo ufw allow 22/tcp
如果你使用自定义端口,比如 2222:
sudo ufw allow 2222/tcp
3. 放行 Cloudflare IP 访问 HTTP/HTTPS
创建脚本:
sudo nano /usr/local/bin/allow-cloudflare-ufw.sh
写入:
#!/bin/bash
set -e
ufw --force reset
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
ufw allow from $ip to any port 80 proto tcp
ufw allow from $ip to any port 443 proto tcp
done
for ip in $(curl -s https://www.cloudflare.com/ips-v6); do
ufw allow from $ip to any port 80 proto tcp
ufw allow from $ip to any port 443 proto tcp
done
ufw --force enable
ufw status verbose
赋予权限:
sudo chmod +x /usr/local/bin/allow-cloudflare-ufw.sh
执行:
sudo /usr/local/bin/allow-cloudflare-ufw.sh
查看状态:
sudo ufw status numbered
如果你不确定自己的 SSH 是否安全,建议先不要执行 ufw --force reset,可以手动添加规则后再启用。
十一、Cloudflare 缓存优化实战
Cloudflare 默认会缓存静态资源,例如:
图片、CSS、JS、字体、部分视频文件
但默认不会缓存 HTML 页面。如果你的网站是静态站点、博客、文档站,可以通过 Cache Rules 缓存 HTML,从而大幅提升访问速度。
1. 推荐缓存规则
进入:
Rules -> Cache Rules -> Create rule
规则名称:
Cache Everything for Static Site
匹配条件:
Hostname equals example.com
或者:
URI Path starts with /
设置:
Cache eligibility: Eligible for cache
Edge TTL: 1 month
Browser TTL: 4 hours
如果后台路径不想缓存,例如 WordPress 后台,可以排除:
URI Path starts with /wp-admin
URI Path starts with /wp-login.php
2. Nginx 添加静态资源缓存头
location ~* \.(jpg|jpeg|png|gif|ico|css|js|webp|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
完整示例:
server {
listen 443 ssl http2;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html index.htm;
ssl_certificate /etc/nginx/ssl/example.com/origin.crt;
ssl_certificate_key /etc/nginx/ssl/example.com/origin.key;
location / {
try_files $uri $uri/ =404;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js|webp|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
}
重载:
sudo nginx -t
sudo systemctl reload nginx
3. 清理 Cloudflare 缓存
如果修改了前端资源但用户看不到更新,可以在 Cloudflare 后台执行:
Caching -> Configuration -> Purge Cache
选择:
Purge Everything
也可以只清理指定 URL。
十二、使用 Cloudflare API 清理缓存
如果你有自动化部署需求,可以通过 Cloudflare API 清理缓存。
1. 准备变量
你需要获取:
API Token
Zone ID
建议使用 API Token,而不是 Global API Key。
设置环境变量:
export CF_API_TOKEN="你的_API_Token"
export CF_ZONE_ID="你的_Zone_ID"
2. 清理全部缓存
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'
3. 清理指定 URL
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"files": [
"https://example.com/index.html",
"https://example.com/assets/app.css"
]
}'
4. 部署脚本示例
#!/bin/bash
set -e
SITE_DIR="/var/www/example.com"
CF_API_TOKEN="你的_API_Token"
CF_ZONE_ID="你的_Zone_ID"
cd "$SITE_DIR"
git pull
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'
echo "Deploy completed and Cloudflare cache purged."
保存为:
sudo nano /usr/local/bin/deploy-example.sh
赋予权限:
sudo chmod +x /usr/local/bin/deploy-example.sh
执行:
sudo /usr/local/bin/deploy-example.sh
十三、防盗链配置
如果你的网站图片被其他网站大量引用,会增加带宽压力。可以结合 Nginx 和 Cloudflare 做防盗链。
1. Nginx 防盗链
location ~* \.(jpg|jpeg|png|gif|webp)$ {
valid_referers none blocked example.com *.example.com;
if ($invalid_referer) {
return 403;
}
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
测试并重载:
sudo nginx -t
sudo systemctl reload nginx
2. Cloudflare WAF 规则防盗链
进入:
Security -> WAF -> Custom rules -> Create rule
规则名称:
Block image hotlinking
表达式示例:
(http.request.uri.path matches "\.(jpg|jpeg|png|gif|webp)$" and http.referer ne "" and not http.referer contains "example.com")
动作:
Block
这样可以在边缘节点直接拦截盗链请求,减少源站压力。
十四、基础 WAF 安全规则示例
Cloudflare 免费版也可以配置一些基础防护规则。
1. 拦截敏感路径扫描
常见恶意扫描路径:
/.env
/.git
/config.php
/phpinfo.php
/backup.zip
WAF 表达式:
http.request.uri.path contains ".env"
or http.request.uri.path contains ".git"
or http.request.uri.path contains "phpinfo.php"
or http.request.uri.path contains "backup"
动作:
Block
2. 限制后台只允许指定国家或 IP
例如 WordPress 后台路径:
/wp-admin
/wp-login.php
只允许自己的 IP 访问:
(http.request.uri.path starts with "/wp-admin" or http.request.uri.path eq "/wp-login.php") and ip.src ne 你的IP
动作:
Block
如果你的 IP 是:
8.8.8.8
表达式:
(http.request.uri.path starts with "/wp-admin" or http.request.uri.path eq "/wp-login.php") and ip.src ne 8.8.8.8
十五、开启 Cloudflare Brotli 和 HTTP/3
进入:
Speed -> Optimization
建议开启:
Brotli: On
HTTP/3: On
0-RTT Connection Resumption: 按需开启
Brotli 可以压缩文本资源,例如 HTML、CSS、JS。HTTP/3 可以改善弱网和跨国访问体验。
源站 Nginx 也可以开启 gzip:
sudo nano /etc/nginx/nginx.conf
在 http 块中加入或确认:
gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types
text/plain
text/css
application/json
application/javascript
application/xml
application/xml+rss
image/svg+xml;
测试重载:
sudo nginx -t
sudo systemctl reload nginx
十六、Cloudflare Tunnel 实战:无需公网 IP 暴露内网服务
Cloudflare Tunnel 是非常实用的功能。它可以让你的内网服务通过 Cloudflare 安全暴露到公网,不需要公网 IP,也不需要开放路由器端口。
假设你本地有一个服务:
本地地址:http://localhost:8080
希望访问:https://app.example.com
1. 安装 cloudflared
Ubuntu / Debian:
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb
sudo dpkg -i cloudflared.deb
查看版本:
cloudflared --version
2. 登录 Cloudflare
cloudflared tunnel login
执行后会打开浏览器,选择你的域名授权。
3. 创建 Tunnel
cloudflared tunnel create my-app-tunnel
查看 Tunnel 列表:
cloudflared tunnel list
4. 创建配置文件
sudo mkdir -p /etc/cloudflared
sudo nano /etc/cloudflared/config.yml
写入:
tunnel: my-app-tunnel
credentials-file: /root/.cloudflared/你的隧道ID.json
ingress:
- hostname: app.example.com
service: http://localhost:8080
- service: http_status:404
注意将 credentials-file 替换为实际路径。一般创建 Tunnel 后,会生成类似:
/root/.cloudflared/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.json
5. 创建 DNS 记录
cloudflared tunnel route dns my-app-tunnel app.example.com
6. 运行测试
cloudflared tunnel run my-app-tunnel
访问:
https://app.example.com
如果可以打开本地服务,说明配置成功。
7. 安装为系统服务
sudo cloudflared service install
启动:
sudo systemctl start cloudflared
设置开机自启:
sudo systemctl enable cloudflared
查看状态:
sudo systemctl status cloudflared
查看日志:
journalctl -u cloudflared -f
十七、常见问题排查
1. 出现 521 Web Server Is Down
原因通常是 Cloudflare 无法连接源站。
检查 Nginx 是否运行:
sudo systemctl status nginx
检查端口监听:
sudo ss -tulnp | grep nginx
检查防火墙:
sudo ufw status
测试源站:
curl -I http://1.2.3.4
如果源站只允许 Cloudflare IP 访问,用普通 IP 测试失败是正常的。
2. 出现 522 Connection Timed Out
通常是源站网络不通、防火墙阻断或服务器负载过高。
查看服务器负载:
uptime
top
查看 Nginx 错误日志:
sudo tail -100 /var/log/nginx/error.log
查看系统日志:
sudo journalctl -xe
3. 出现 525 SSL Handshake Failed
原因通常是 Cloudflare 到源站 HTTPS 握手失败。
检查证书文件:
sudo ls -l /etc/nginx/ssl/example.com/
检查 Nginx 配置:
sudo nginx -t
检查 443 端口:
sudo ss -tulnp | grep 443
4. 出现重定向循环
如果浏览器一直跳转,常见原因是 Cloudflare 设置了 Flexible SSL,同时源站又强制 HTTPS。
建议改为:
SSL/TLS -> Overview -> Full 或 Full strict
并保持源站 HTTPS 正常。
5. 如何确认请求经过 Cloudflare
使用 curl:
curl -I https://example.com
如果响应头中出现:
server: cloudflare
cf-cache-status: HIT
cf-ray: xxxxx
说明请求经过了 Cloudflare。
查看 DNS 解析:
dig example.com
如果返回的是 Cloudflare IP,而不是你的源站 IP,说明代理已经生效。
十八、推荐生产环境配置清单
对于正式上线的网站,建议至少完成以下配置:
| 项目 | 建议 |
|---|---|
| DNS | 网站记录开启 Proxied |
| SSL/TLS | 使用 Full strict |
| 源站证书 | 使用 Cloudflare Origin Certificate 或 Let’s Encrypt |
| HTTP 跳转 | 源站或 Cloudflare 统一跳转 HTTPS |
| 真实 IP | Nginx 配置 CF-Connecting-IP |
| 防火墙 | 只允许 Cloudflare IP 访问 80/443 |
| 缓存 | 静态资源设置合理 TTL |
| WAF | 拦截敏感路径和恶意扫描 |
| API Token | 使用最小权限原则 |
| 日志 | 定期查看 Nginx 与 Cloudflare Analytics |
| Tunnel | 内网服务优先使用 Cloudflare Tunnel |
| 备份 | 配置前备份 Nginx 与防火墙规则 |
十九、一键备份关键配置
在修改 Nginx、SSL、防火墙前,建议先备份。
sudo mkdir -p /backup/cloudflare-demo
sudo cp -r /etc/nginx /backup/cloudflare-demo/nginx-$(date +%F)
sudo ufw status verbose > /backup/cloudflare-demo/ufw-status-$(date +%F).txt
查看备份:
ls -lh /backup/cloudflare-demo
恢复 Nginx 配置示例:
sudo cp -r /backup/cloudflare-demo/nginx-2025-01-01/* /etc/nginx/
sudo nginx -t
sudo systemctl reload nginx
二十、总结
通过本文的实战案例,我们完成了一个网站接入 Cloudflare 的完整流程:从 DNS 托管、Nginx 源站配置、HTTPS 证书部署,到真实 IP 获取、防火墙限制、缓存优化、WAF 规则以及 Cloudflare Tunnel 内网服务发布。
对于个人站点来说,Cloudflare 可以快速解决 HTTPS、CDN、基础防护和全球访问加速问题;对于企业站点来说,Cloudflare 还可以进一步结合 Zero Trust、Access、Workers、R2、Load Balancing 等功能构建更完整的边缘网络架构。
最后给出一个简洁的实战建议:
能用 Full strict 就不要用 Flexible;
能隐藏源站 IP 就不要暴露源站;
能在 Cloudflare 边缘拦截的请求,就不要放到源站处理;
能自动化的操作,就尽量通过脚本和 API 实现。
Cloudflare 的核心价值不只是“加速”,更是把安全、性能和可用性尽可能前置到边缘节点。只要配置得当,它可以成为网站架构中非常可靠的一道防线。