本教程的作者选择了 电子前沿基金会 作为 Write for DOnations 计划的捐款对象。

引言

Cloudflare 是一个位于访问者和网站服务器之间的服务,作为网站的反向代理。Cloudflare 提供了内容交付网络(CDN)、DDoS 攻击缓解和分布式域名服务等功能。

Nginx 是一款广受欢迎的网页服务器软件,负责托管世界上一些访问量最大的网站。使用 Nginx 托管网站并结合 Cloudflare 作为 CDN 和 DNS 提供者是一种常见做法。

在这篇教程中,你将学会如何利用 Cloudflare 提供的 Origin CA certificate 来保护你的 Nginx 托管网站,随后配置 Nginx 以使用认证的拉取请求。采用这种配置的好处包括能够利用 Cloudflare 的 CDN 和快速的 DNS 解析服务,同时确保所有的连接都必须经过 Cloudflare,有效防止恶意请求直接到达你的服务器。

前提条件

完成本教程需要满足以下条件:

第 1 步 — 生成 Origin CA TLS Certificate

Cloudflare Origin CA 允许你生成一个免费的 TLS 证书,由 Cloudflare 签名,用于安装在你的 Nginx 服务器上。通过使用 Cloudflare 生成的 TLS 证书,你可以确保 Cloudflare 的服务器与你的 Nginx 服务器之间的连接是安全的。

首先,登录你的 Cloudflare 账户,选择你想要保护的域名,然后前往 Cloudflare 仪表盘的 SSL/TLS 部分。接下来,转到 Origin Server 标签页,并点击 Create Certificate 按钮:

保持默认选项 Generate private key and CSR with Cloudflare 选中。

点击 下一步 后,你会看到一个包含 Origin CertificatePrivate Key 的对话框。你需要把 Cloudflare Origin Certificate 和 Private Key 从 Cloudflare 复制到你的服务器。出于安全原因, Private Key 信息不会再次显示,因此在点击 确定 之前,请确保已经复制了密钥到你的服务器。

你将在服务器上的 /etc/ssl 目录下保存 Origin Certificate 和 Private Key 文件。该目录在服务器上已预先存在。

首先,复制浏览器中对话框显示的 Origin Certificate 内容。

然后,在服务器上,使用你偏好的文本编辑器打开 /etc/ssl/cert.pem 文件:

1
        sudo nano /etc/ssl/cert.pem

将证书内容粘贴进文件,然后保存并退出编辑器。如果你使用的是 ~nano~,请按 ~Ctrl+X~,随后按 ~Y~,然后按回车键。

接着返回浏览器,复制 Private Key 的内容。打开文件 /etc/ssl/key.pem 进行编辑:

1
        sudo nano /etc/ssl/key.pem

将 Private Key 内容粘贴进文件,保存并退出编辑器。

注意: 有时,从 Cloudflare 仪表板复制证书和密钥到服务器文件时,可能会插入空白行。Nginx 会将这种带有空白行的证书和密钥视为无效,因此请确保你的文件中没有空白行。

警告: Cloudflare 的 Origin CA certificate 只被 Cloudflare 信任,因此只应用于与 Cloudflare 保持活动连接的原始服务器。如果你在任何时候停用 Cloudflare,你的 Origin CA certificate 会出现不受信任的证书错误。

将密钥和证书文件复制到服务器后,你需要更新 Nginx 配置以使用它们。

第 2 步 — 在 Nginx 中安装 Origin CA certificate

在上一节中,你已经使用 Cloudflare 的仪表板生成并保存了 Origin Certificate 和 Private Key 到你的服务器。现在,你将更新你的站点的 Nginx 配置,以使用 Origin Certificate 和 Private Key 来保护 Cloudflare 的服务器与你的服务器之间的连接。

首先,确保 UFW 允许 HTTPS 流量。启用 Nginx Full 配置,这将打开端口 80 (HTTP) 和 443 (HTTPS):

1
        sudo ufw allow 'Nginx Full'

现在重新加载 UFW:

1
        sudo ufw reload

最后,确认你的新规则被允许并且 UFW 处于活动状态:

1
        sudo ufw status

你会看到如下输出:

1
2
3
4
5
6
7
8
OutputStatus: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx Full                 ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Nginx Full (v6)            ALLOW       Anywhere (v6)

现在你可以调整你的 Nginx 服务器配置了。Nginx 在安装时会创建一个默认的服务器配置。如果它还存在,请将其删除,因为你已经为你的域配置了一个自定义的服务器配置:

1
        sudo rm /etc/nginx/sites-enabled/default

接下来,打开你域的 Nginx 配置文件:

1
        sudo nano /etc/nginx/sites-available/your_domain

该文件看起来应该像这样:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# /etc/nginx/sites-available/your_domain
# ======================================
server {
        listen 80;
        listen [::]:80;

        root /var/www/your_domain/html;
        index index.html index.htm index.nginx-debian.html;

        server_name your_domain www.your_domain;

        location / {
                try_files $uri $uri/ =404;
        }
}

你需要修改 Nginx 配置文件以实现以下目的:

  • 在端口 80 上监听并将所有请求重定向到 https
  • 在端口 443 上监听并使用前一节中添加的 Origin Certificate 和 Private Key。

修改文件,使其看起来像下面这样:

 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
# /etc/nginx/sites-available/your_domain
# ======================================
server {
    listen 80;
    listen [::]:80;
    server_name your_domain www.your_domain;
    return 302 https://$server_name$request_uri;
}

server {

    # SSL configuration

    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ssl_certificate         /etc/ssl/cert.pem;
    ssl_certificate_key     /etc/ssl/key.pem;

    server_name your_domain www.your_domain;

    root /var/www/your_domain/html;
    index index.html index.htm index.nginx-debian.html;


    location / {
            try_files $uri $uri/ =404;
    }
}

保存文件并退出编辑器。

接下来,测试确保你的 Nginx 配置文件中没有语法错误:

1
        sudo nginx -t

如果没有发现问题,重启 Nginx 以应用你的更改:

1
        sudo systemctl restart nginx

现在转到 Cloudflare 仪表板的 SSL/TLS 部分,转到 概览 标签页,将 SSL/TLS encryption mode 更改为 Full(strict) 。这告诉 Cloudflare 始终加密 Cloudflare 与你的原始 Nginx 服务器之间的连接。

现在访问 https://your_domain 以确认你的网站已正确设置。你会看到你的首页,并且浏览器会显示该网站是安全的。

在下一节中,你将配置 Authenticated Origin Pulls,以验证你的原始服务器确实在与 Cloudflare 通信。通过这种方式,Nginx 将被配置为仅接受使用 Cloudflare 的有效客户端证书的请求;所有未通过 Cloudflare 的请求都将被拒绝。

第 3 步 — 配置 Authenticated Origin Pulls

Origin CA certificate 帮助 Cloudflare 验证它是否正在与正确的原始服务器通信。这一步将使用 TLS Client Authentication 来验证你的原始 Nginx 服务器是否正在与 Cloudflare 通信。

在 Client Authenticated TLS 握手过程中,双方都提供证书进行验证。原始服务器被配置为仅接受使用 Cloudflare 的有效客户端证书的请求。没有通过 Cloudflare 的请求将被拒绝,因为它们不具备 Cloudflare 的证书。这意味着攻击者不能绕过 Cloudflare 的安全措施,直接连接到你的 Nginx 服务器。

Cloudflare 提供由 CA 签名的证书如下所示:

 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
-----BEGIN CERTIFICATE-----
MIIGCjCCA/KgAwIBAgIIV5G6lVbCLmEwDQYJKoZIhvcNAQENBQAwgZAxCzAJBgNV
BAYTAlVTMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMRQwEgYDVQQLEwtPcmln
aW4gUHVsbDEWMBQGA1UEBxMNU2Fu IEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv
cm5pYTEjMCEGA1UEAxMab3JpZ2luLXB1bGwuY2xvdWRmbGFyZS5uZXQwHhcNMTkx
MDEwMTg0NTAwWhcNMjkxMTAxMTcwMDAwWjCBkDELMAkGA1UEBhMCVVMxGTAXBgNV
BAoTEENsb3VkRmxhcmUsIEluYy4xFDASBgNVBAsTC09yaWdpbiBQdWxsMRYwFAYD
VQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMSMwIQYDVQQD
ExpvcmlnaW4tcHVsbC5jbG91ZGZsYXJlLm5ldDCCAiIwDQYJKoZIhvcNAQEBBQAD
ggIPADCCAgoCggIBAN2y2zojYfl0bKfhp0AJBFeV+jQqbCw3sHmvEPwLmqDLqynI
42tZXR5y914ZB9ZrwbL/K5O46exd/LujJnV2b3dzcx5rtiQzso0xzljqbnbQT20e
ihx/WrF4OkZKydZzsdaJsWAPuplDH5P7J82q3re88jQdgE5hqjqFZ3clCG7lxoBw
hLaazm3NJJlUfzdk97ouRvnFGAuXd5cQVx8jYOOeU60sWqmMe4QHdOvpqB91bJoY
QSKVFjUgHeTpN8tNpKJfb9LIn3pun3bC9NKNHtRKMNX3Kl/sAPq7q/AlndvA2Kw3
Dkum2mHQUGdzVHqcOgea9BGjLK2h7SuX93zTWL02u799dr6Xkrad/WShHchfjjRn
aL35niJUDr02YJtPgxWObsrfOU63B8juLUphW/4BOjjJyAG5l9j1//aUGEi/sEe5
lqVv0P78QrxoxR+MMXiJwQab5FB8TG/ac6mRHgF9CmkX90uaRh+OC07XjTdfSKGR
PpM9hB2ZhLol/nf8qmoLdoD5HvODZuKu2+muKeVHXgw2/A6wM7OwrinxZiyBk5Hh
CvaADH7PZpU6z/zv5NU5HSvXiKtCzFuDu4/Zfi34RfHXeCUfHAb4KfNRXJwMsxUa
+4ZpSAX2G6RnGU5meuXpU5/V+DQJp/e69XyyY6RXDoMywaEFlIlXBqjRRA2pAgMB
AAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgECMB0GA1Ud
DgQWBBRDWUsraYuA4REzalfNVzjann3F6zAfBgNVHSMEGDAWgBRDWUsraYuA4REz
alfNVzjann3F6zANBgkqhkiG9w0BAQ0FAAOCAgEAkQ+T9nqcSlAuW/90DeYmQOW1
QhqOor5psBEGvxbNGV2hdLJY8h6QUq48BCevcMChg/L1CkznBNI40i3/6heDn3IS
zVEwXKf34pPFCACWVMZxbQjkNRTiH8iRur9EsaNQ5oXCPJkhwg2+IFyoPAAYURoX
VcI9SCDUa45clmYHJ/XYwV1icGVI8/9b2JUqklnOTa5tugwIUi5sTfipNcJXHhgz
6BKYDl0/UP0lLKbsUETXeTGDiDpxZYIgbcFrRDDkHC6BSvdWVEiH5b9mH2BON60z
0O0j8EEKTwi9jnafVtZQXP/D8yoVowdFDjXcKkOPF/1gIh9qrFR6GdoPVgB3SkLc
5ulBqZaCHm563jsvWb/kXJnlFx

W+1bsO9BDD6DweBcGdNurgmH625wBXksSdD7y/
fakk8DagjbjKShYlPEFOAqEcliwjF45eabL0t27MJV61O/jHzHL3dknXeE4BDa2j
bA+JbyJeUMtU7KMsxvx82RmhqBEJJDBCJ3scVptvhDMRrtqDBW5JShxoAOcpFQGm
iYWicn46nPDjgTU0bX1ZPpTpryXbvciVL5RkVBuyX2ntcOLDPlZWgxZCBp96x07F
AnOzKgZk4RzZPNAxCXERVxajn/FLcOhglVAKo5H0ac+AitlQ0ip55D2/mf8o72tM
fVQ6VpyjEXdiIXWUq/o=
-----END CERTIFICATE-----

你也可以从 Cloudflare 的官方文档 中直接下载这个证书。

复制这个证书。

然后,在服务器上创建 /etc/ssl/cloudflare.crt 文件来存放 Cloudflare 的证书:

1
        sudo nano /etc/ssl/cloudflare.crt

将证书内容加入文件中,保存并退出编辑器。

现在,更新你的 Nginx 配置以启用 TLS Authenticated Origin Pulls。打开你域名的配置文件:

1
        sudo nano /etc/nginx/sites-available/your_domain

按照以下示例添加 ssl_client_certificatessl_verify_client 指令: /etc/nginx/sites-available/your_domain

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# /etc/nginx/sites-available/your_domain
# ======================================
. . .

server {

    # SSL configuration

    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ssl_certificate         /etc/ssl/cert.pem;
    ssl_certificate_key     /etc/ssl/key.pem;
    ssl_client_certificate /etc/ssl/cloudflare.crt;
    ssl_verify_client on;

    . . .

保存文件并退出编辑器。

接下来,测试 Nginx 确保你的 Nginx 配置中没有语法错误:

1
        sudo nginx -t

如果没有发现问题,重启 Nginx 来应用你的更改:

1
        sudo systemctl restart nginx

最后,为了启用 Authenticated Pulls,请转到 Cloudflare 仪表板的 SSL/TLS 部分,导航到 Origin Server 标签页并切换 Authenticated Origin Pulls 选项。

现在访问 https://your_domain 以确认一切都已正确设置。和之前一样,你的首页会被显示出来。

为了验证你的服务器仅接受由 Cloudflare CA 签名的请求,请切换 Authenticated Origin Pulls 选项以禁用它,然后重新加载你的网站。你应该会看到如下的错误消息:

如果 Cloudflare 的 CA 没有对请求进行签名,你的原始服务器将报错。

注意: 大多数浏览器会缓存请求,因此要查看上述变化,你可能需要使用浏览器的隐私/无痕浏览模式。为了防止 Cloudflare 在你设置网站时缓存请求,可以在 Cloudflare 仪表板的 概览 部分切换 开发模式

现在你已经确认一切都设置正确了,返回到 Cloudflare 仪表板的 SSL/TLS 部分,导航到 Origin Server 标签页,并再次切换 Authenticated Origin Pulls 选项以启用它。

结语

通过本教程,你已经学会了如何通过在 Cloudflare 和 Nginx 服务器之间加密流量,使用 Cloudflare 提供的 Origin CA certificate 来保护你的 Nginx 驱动的网站。此外,你还设置了 Authenticated Origin Pulls ,确保你的服务器只接受来自 Cloudflare 服务器的请求,阻止任何其他尝试直接连接到你的 Nginx 服务器的行为。

原文在此: How To Host a Website Using Cloudflare and Nginx on Ubuntu 20.04 | DigitalOcean