Skip to main content

CloudFlare 使用指南

在 cloudflare 上, 我们可以直接做域名购买,域名解析,SSL 加密、人机验证、WAF 和 DDOS防护。由于 其 CDN 节点分布全世界,具有告诉访问的优势。

Cloudflare 自动、免费、托管 浏览器侧证书(Universal SSL),以至于 你服务器可以不用公网证书

Cloudflare 是“域名级证书 + 反向代理 TLS 终止”,不是“服务器一个证书”。

(一)域名解析

如图,在 DNS - Records 中,我们可以添加记录

首先要添加根记录,即 从 3.132.25.89ordinis.dev,这是 A 记录,开启 proxy 即开启了 HTTPS

注意:这里开启 HTTPS 后,服务器上无需手动再次部署 HTTPS !原理在第二块会解释

image-20260109021339801

然后要添加具体记录,即 从 3.132.25.89www.ordinis.dev

image-20260109021447089

现在两个基本的 DNS 都已经做好了

image-20260109023248203

现在访问 https://www.ordinis.dev/https://ordinis.dev/,都会能看到:

image-20260109023721039

这成功说明解析已经生效。


(二)SSL 加密

在使用传统的DNS时,如果要使用 SSL 加密,我们一般都要手动把 HTTPS 证书部署在某一个环节上,例如

网页服务 

nginx 代理(在这里部署证书,做了加密)

阿里云 DNS 服务

用户浏览器

上面的例子中就是使用了 nginx 代理这一环节,部署 HTTPS 证书并做了加密。


但是使用 Cloudflare 时,只要在控制台做了域名解析 并点击开启了 SSL 加密,就可以无需手动部署 HTTPS 证书。

下图中的这个 Proxy status: Proxied(橙云) 就是开启 SSL 加密的标志。

image-20260109024043863

这是因为,Cloudeflare 把这个“部署证书的环节”搬到了全球边缘节点,

网页服务 

nginx 代理
↓ HTTPS(Origin Certificate)或 HTTP(你选择)
Cloudflare 边缘节点 Anycast IP(反向代理 / CDN)
↓ HTTPS(Cloudflare 证书)
CloudFlare DNS 服务 (自动 HTTPS)

用户浏览器

所以这个过程中,如果你开启了 Origin Certificate , 就实际上发生了两次 HTTPS,分别如下

  • 第一个连接:浏览器 ⇄ Cloudflare 边缘节点,使用 Cloudflare 的公网证书(Universal SSL)
  • 第二个连接:Cloudflare 边缘节点 ⇄ 你的服务器,使用 Cloudflare Origin Certificate

第二次 HTTPS (full 模式)是可选的,但是开启之后会更安全, HTTPS → HTTPS(双重 TLS)。

所以如果不选择 启用 full 模式 的话,就完全不需要手动部署证书了。以 ordinis.dev 为例,任何子域名 *.ordinis.dev 都能自动 变成 HTTPS,不用重新申请。并且该证书自动签发(Cloudflare CA),自动续期, 你什么都不用做。

关于第二次 HTTPS ,需要进一步说明。

在 Cloudflare 面板里,点击进入:SSL/TLSOverviewSSL/TLS encryptionConfigure

image-20260109024559484

你会看到 4 个选项,默认是 full,也就是两次 SSL 加密

image-20260109024733751

其含义如下

模式说明图示
Off不用image-20260109024851094
Flexible浏览器到 CF 是 HTTPS,但 CF 到服务器是 HTTP(不安全)image-20260109024840708
FullHTTPS → HTTPS,但不校验证书image-20260109024830897
Full (strict)HTTPS → HTTPS,且校验证书image-20260109024900713

为了安全起见,我们用:Full (strict)**

image-20260109025036038

在这种情况下,我们的服务器上也要部署一个 HTTPS 证书(Cloudflare Origin Certificate)。该证书只被 Cloudflare 信任,浏览器不信任!有效期可选 15 年,不需要域名所有权验证(因为你已经在 CF)。

这样一来,源站完全 HTTPS,服务器即使暴露 IP,也无法被普通浏览器访问,可以防止 中间人攻击

配置步骤如下:

步骤 1:生成 Origin Certificate

Cloudflare 控制台,点击进入:SSL/TLSOrigin ServerCreate Certificate

image-20260109025406593

设置如下:(全是默认)

image-20260109025523894

你会得到:一个公钥和一个私钥,分别复制并保存于本地文件 origin-cert.pemorigin-key.pem

image-20260109025838714

此时我们的 origin 证书就创建好了。

image-20260109030313490

步骤 2:安装 Nginx

我们先安装 nginx

sudo apt update
sudo apt install -y nginx
sudo systemctl enable nginx
sudo systemctl start nginx
systemctl status nginx

步骤 3:部署 Origin Certificate

现在证书路径保存在

  • /home/ubuntu/Keys/ordinis.dev/origin-cert.pem
  • /home/ubuntu/Keys/ordinis.dev/origin-key.pem

然后把证书移动到安全地方

sudo mkdir -p /etc/nginx/ssl/ordinis.dev
sudo cp ~/Keys/ordinis.dev/origin-cert.pem /etc/nginx/ssl/ordinis.dev/
sudo cp ~/Keys/ordinis.dev/origin-key.pem  /etc/nginx/ssl/ordinis.dev/

权限收紧(非常重要):

sudo chmod 600 /etc/nginx/ssl/ordinis.dev/origin-key.pem
sudo chmod 644 /etc/nginx/ssl/ordinis.dev/origin-cert.pem

步骤 4:创建并启动 Web 服务

~/test 下创建最小 Python HTTP 服务(8080),只处理 GET 请求并返回固定文本。它本身不提供任何“写文件”能力。

mkdir -p ~/test
tee ~/test/app.py > /dev/null <<'EOF'
from http.server import BaseHTTPRequestHandler, HTTPServer

class Handler(BaseHTTPRequestHandler):  # 定义一个请求处理器。
    def do_GET(self):  # 只要收到 任何 GET 请求(不管路径是什么) 
        body = b"Ordinis minimal Python service OK\n" # 构造固定返回体 
        self.send_response(200)  # 返回 200 OK
        self.send_header("Content-Type", "text/plain; charset=utf-8") # 输出这个固定文本
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

if __name__ == "__main__":
    HTTPServer(("127.0.0.1", 8080), Handler).serve_forever()
EOF

运行服务:

python3 ~/test/app.py

步骤 5:配置 Nginx(HTTP + HTTPS)

创建站点配置:

sudo tee /etc/nginx/sites-available/ordinis.dev > /dev/null <<'EOF'
# HTTP:统一跳转 HTTPS
server {
    listen 80;
    server_name ordinis.dev www.ordinis.dev;
    return 301 https://$host$request_uri;
}

# HTTPS:TLS 终止 + 反向代理
server {
    listen 443 ssl http2;
    server_name ordinis.dev www.ordinis.dev;

    ssl_certificate     /etc/nginx/ssl/ordinis.dev/origin-cert.pem;
    ssl_certificate_key /etc/nginx/ssl/ordinis.dev/origin-key.pem;

    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
EOF

启用站点:

sudo ln -sf /etc/nginx/sites-available/ordinis.dev /etc/nginx/sites-enabled/ordinis.dev
sudo rm -f /etc/nginx/sites-enabled/default

测试并重载:

sudo nginx -t && sudo systemctl reload nginx

此时访问 https://ordinis.dev 应看到:

image-20260109035047438

说明整个流程已经跑通。

此外,还可以测试:

  • 从服务器本机(验证 Origin Cert)
curl -k https://127.0.0.1

能返回 HTML 即成功(-k 忽略浏览器不信任是正常的)。

  • 绕过 Cloudflare(安全检查)
curl https://3.132.25.89

应失败或证书错误(这是正确的)。

curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the webpage mentioned above.
(base) heihe@heihedeMacBook-Pro-4 ~ %

此外,只要 DNS 在 Cloudflare 且 橙云开启(Proxied),自动生效的包括:L3/L4 DDoS 防护,基础 WAF 规则,HTTPS 强制,HTTP/2 / HTTP/3,全球 CDN

你可以稍后再开的:Bot Fight Mode,Rate Limiting(API 防刷),Firewall Rules(封 IP / 国家)



(三)源 IP 保护

在传统 DNS 架构下,别人是可以直接访问原来的服务器 IP 的。但是在当前 Cloudflare 架构下,DNS 把域名指向的不是 我们自己服务器的源 IP,而是 Cloudflare 的边缘节点的 IP。因此,别人追查不到我们的服务器源 IP。

1️⃣ 强制 HTTPS + 自动重定向

SSL/TLS → Edge Certificates → Always Use HTTPS

2️⃣ 锁死源站

  • 防火墙只允许 Cloudflare IP 段访问 80/443,也就是只有边缘节点才能访问 原始 IP
  • 防止绕过 CF 直接打你服务器


(四)WebSocket 的 Bug

传统 WebSocket 直连:

Browser  ───(TCP + TLS + WS)───>  Origin

Cloudflare 代理:

Browser ⇄ CloudflareCloudflare ⇄ Origin 两条独立的连接,由 Cloudflare 做中继转发(类似 L7 proxy)。

Browser  ──(TCP+TLS+WS)──>  Cloudflare Edge  ──(TCP+TLS+WS or HTTP)──>  Origin(Nginx→App)

因此 websocket 可能会出现以下问题:代理层的升级握手、超时、缓冲、头部转发、路由/粘性等细节没配对。


A. Nginx 没有正确转发 Upgrade 头

如果你 Nginx 只是 proxy_pass,没有加 WebSocket 必需头,会导致握手失败或退化成普通 HTTP。

你需要(在 location 里):

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

更稳的写法(避免非 WS 请求也强制 upgrade):

map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

然后:

proxy_set_header Connection $connection_upgrade;

C. 超时/心跳机制

WebSocket 本质上需要 keepalive/heartbeat。 Cloudflare/中间网络可能在“长时间无数据”时断开连接。

解决方案:应用层每 20–50 秒发一次 ping/pong(或一条轻量心跳消息)。 这不是 Cloudflare 特有,代理链更长时更需要。

D. 源站可用性与多实例“粘性”

如果你后面做多实例或滚动更新,WS 连接会断;要靠:

  • 客户端自动重连(指数退避)
  • 服务端支持断线恢复(基于 session/room 状态)
  • 如果你做了负载均衡,要考虑粘性(但 Cloudflare 到单源站时通常不是问题)

E. HTTP/2 / gRPC / 反代混用导致的问题

你源站 Nginx 到应用要用 HTTP/1.1 转发 WS(因为 Upgrade 属于 HTTP/1.1 机制),这也是为什么必须 proxy_http_version 1.1;

你现在的架构下,最小正确配置(直接可用)

你目前是:Cloudflare → Nginx(443) → Python(8080)。 如果你未来 WebSocket 路径是 /ws,推荐这样改 Nginx:

map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
listen 443 ssl http2;
server_name ordinis.dev www.ordinis.dev;

ssl_certificate /etc/nginx/ssl/ordinis.dev/origin-cert.pem;
ssl_certificate_key /etc/nginx/ssl/ordinis.dev/origin-key.pem;

# 普通 HTTP API/页面
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

# WebSocket
location /ws {
proxy_pass http://127.0.0.1:8080; # 你的 WS 服务端口(可与 HTTP 同端口)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_read_timeout 3600;
proxy_send_timeout 3600;
}
}

关键点:Upgrade/Connection + proxy_http_version 1.1 + 合理的 proxy_read_timeout



(五)邮件服务器

如果这个域名 @ordinis.dev 还要用来收发邮件的话,还需要补充一条 MX 记录。

MX 记录会告诉全世界:发给 @ordinis.dev 的邮件,应该投递到邮件服务器 mx.ordinis.dev

这样就可以用 admin@ordinis.dev support@ordinis.dev 等做邮箱体系了

image-20260109022325215

然后还要配置 SPF / DKIM / DMARC,否则邮件会进垃圾箱 或被拒收。

image-20260109022909202

如果 这个域名不用于发/收邮件,也需要用 SPF / DKIM / DMARC 把它锁死,防止被伪造发信。

  • 不配置 MX(或配置 Null MX) → “这个域名不接收邮件”

  • 配置 严格 SPF / DMARC → 告诉收件服务器:“任何声称来自 @ordinis.dev 的邮件,都是伪造的,请直接拒绝”

常见配置是:

  • SPFordinis.dev. TXT "v=spf1 -all"

  • **DMARC **: _dmarc.ordinis.dev. TXT "v=DMARC1; p=reject; adkim=s; aspf=s;"