作者选择了Electronic Frontier Foundation作为Write for Donations计划的捐赠对象。
介绍
Cloudflare是一项服务,位于访问者和网站所有者服务器之间,充当网站的反向代理。Cloudflare提供内容交付网络(CDN),以及DDoS防护和分布式域名服务器服务。
Nginx是一种流行的Web服务器,负责托管互联网上一些最大和流量最高的站点。组织通常使用Nginx提供网站,并使用Cloudflare作为CDN和DNS提供商。
在本教程中,您将使用来自Cloudflare的Origin CA证书为由Nginx提供的网站安全,并配置Nginx以使用身份验证的拉取请求。使用此设置的优点是,您可以从Cloudflare的CDN和快速DNS解析中受益,同时确保所有连接都通过Cloudflare。这可以防止任何恶意请求到达您的服务器。
先决条件
要完成本教程,您需要以下内容:
- 一台Ubuntu 22.04服务器,按照Ubuntu 22.04初始服务器设置指南进行设置,包括一个
sudo
非root用户和一个防火墙。 - 在您的服务器上安装了Nginx。您可以按照我们在Ubuntu 22.04上安装Nginx的指南进行操作。
- A Cloudflare account.
- A registered domain added to your Cloudflare account that points to your Nginx server. Our guide on how to mitigate DDoS attacks against your website with Cloudflare can help you set this up. Our introduction to DNS terminology, components, and concepts can also provide assistance.
- 为您的域名配置了一个Nginx服务器块,您可以按照如何在Ubuntu 22.04上安装Nginx的第5步进行操作。
步骤1 — 生成一个Origin CA TLS证书
Cloudflare Origin CA允许您生成由Cloudflare签名的免费TLS证书,以安装在您的Nginx服务器上。通过使用Cloudflare生成的TLS证书,您可以加密Cloudflare服务器与您的Nginx服务器之间的连接。
要使用Origin CA生成证书,请在Web浏览器中登录您的Cloudflare帐户。选择要保护的域并导航到Cloudflare仪表板的SSL/TLS部分。从那里,导航到Origin Server选项卡,然后单击创建证书按钮:
保留默认选项“使用Cloudflare生成私钥和CSR”选中。
点击创建,您将看到一个对话框,显示Origin证书和私钥。出于安全原因,私钥信息将不会再次显示,所以在单击“确定”之前,请将密钥复制到您的服务器上。
您将使用服务器上的/etc/ssl目录来保存Origin证书和私钥文件。该文件夹已经存在于服务器上。
首先,在浏览器对话框中显示的Origin证书中复制内容。
然后,在您的服务器上,使用您喜欢的文本编辑器打开/etc/ssl/cert.pem:
将证书内容粘贴到文件中。然后保存并退出编辑器。如果您使用nano,请按Ctrl+X,然后在提示时按Y,然后按Enter。
然后返回到浏览器并复制私钥的内容。打开文件/etc/ssl/key.pem进行编辑:
将私钥粘贴到文件中,保存文件并退出编辑器。
注意:有时,当您从Cloudflare仪表板复制证书和密钥并粘贴到服务器上的相关文件时,会插入空行。Nginx会将这些证书和密钥视为无效,请确保您的文件中没有空行。
警告:Cloudflare的源CA证书仅受Cloudflare信任,因此只应由与Cloudflare活动连接的源服务器使用。如果您暂停或禁用Cloudflare,您的源CA证书将引发不受信任的证书错误。
现在您已经将密钥和证书文件复制到服务器上,您需要更新Nginx配置以使用它们。
步骤2 — 在Nginx中安装源CA证书
在前一节中,您使用Cloudflare的仪表板生成了源证书和私钥,并将文件保存到了服务器上。现在,您将更新站点的Nginx配置,以使用源证书和私钥来加密Cloudflare服务器和您的服务器之间的连接。
首先,请确保UFW允许HTTPS流量。启用 Nginx Full
,这将打开端口 80
(HTTP)和端口 443
(HTTPS):
现在重新加载UFW:
最后,检查您的新规则是否允许,并且UFW是否处于活动状态:
你会看到这样的输出:
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在安装过程中会创建一个默认的服务器块。如果仍然存在,请删除它,因为您已经为您的域配置了自定义服务器块:
接下来,打开您域名的Nginx配置文件:
文件应该看起来像这样:
您将修改Nginx配置文件以执行以下操作:
- 监听端口
80
并将所有请求重定向到使用https
。 - 监听端口
443
并使用前一部分添加的原始证书和私钥。
修改文件使其看起来像以下内容:
保存文件并退出编辑器。
接下来,测试以确保您的Nginx配置文件中没有语法错误:
如果您没有发现问题,请重新启动Nginx以启用更改:
现在转到Cloudflare仪表板的SSL/TLS部分,导航到概述选项卡,并将SSL/TLS加密模式更改为完全(严格)。这样可以通知Cloudflare始终加密Cloudflare与您源Nginx服务器之间的连接。
现在访问您的网站:https://your_domain
,以验证它是否设置正确。您将看到您的首页显示,并且浏览器将报告该站点是安全的。
要查看证书的详细信息,请访问您浏览器的开发者工具,选择安全选项卡,然后查看证书。
注意:您可能会注意到您的证书未将Cloudflare列为颁发者。这是因为Cloudflare可能使用其他证书颁发机构,例如 Let’s Encrypt。要获取完整列表,请查阅Cloudflare 的产品文档以了解证书颁发机构。
接下来,您将设置身份验证源拉取,以验证您的源服务器确实与Cloudflare通信,而不是其他服务器。通过这样做,Nginx 将配置为仅接受使用来自Cloudflare的有效客户端证书的请求;所有未经Cloudflare传递的请求都将被丢弃。
步骤 3 — 设置身份验证源拉取
Origin CA 证书将帮助Cloudflare验证它是否正在与正确的源服务器通信。这一步将使用 TLS 客户端身份验证来验证您的源 Nginx 服务器是否正在与Cloudflare通信。
在客户端身份验证的TLS握手中,双方都提供要验证的证书。源服务器配置为仅接受使用来自Cloudflare的有效客户端证书的请求。未经Cloudflare的请求将被丢弃,因为它们没有Cloudflare的证书。这意味着攻击者无法规避Cloudflare的安全措施直接连接到您的Nginx服务器。
Cloudflare提供了由以下证书签名的CA证书:
-----BEGIN CERTIFICATE-----
MIIGCjCCA/KgAwIBAgIIV5G6lVbCLmEwDQYJKoZIhvcNAQENBQAwgZAxCzAJBgNV
BAYTAlVTMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMRQwEgYDVQQLEwtPcmln
aW4gUHVsbDEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv
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/kXJnlFxW+1bsO9BDD6DweBcGdNurgmH625wBXksSdD7y/
fakk8DagjbjKShYlPEFOAqEcliwjF45eabL0t27MJV61O/jHzHL3dknXeE4BDa2j
bA+JbyJeUMtU7KMsxvx82RmhqBEJJDBCJ3scVptvhDMRrtqDBW5JShxoAOcpFQGm
iYWicn46nPDjgTU0bX1ZPpTpryXbvciVL5RkVBuyX2ntcOLDPlZWgxZCBp96x07F
AnOzKgZk4RzZPNAxCXERVxajn/FLcOhglVAKo5H0ac+AitlQ0ip55D2/mf8o72tM
fVQ6VpyjEXdiIXWUq/o=
-----END CERTIFICATE-----
您也可以直接从Cloudflare的文档下载证书。
复制此证书。
然后创建文件/etc/ssl/cloudflare.crt
以保存Cloudflare的证书:
将证书添加到文件中。然后保存文件并退出编辑器。
现在更新您的Nginx配置以使用TLS认证的源站拉取。打开您域名的配置文件:
按照以下示例添加ssl_client_certificate
和ssl_verify_client
指令:
保存文件并退出编辑器。
接下来,测试Nginx确保您的Nginx配置中没有语法错误:
如果未发现问题,请重新启动Nginx以启用您的更改:
最后,要启用验证拉取,请在Cloudflare仪表板中打开SSL/TLS部分,转到源服务器选项卡,并切换已验证的源拉取选项。
现在访问您的网站:https://your_domain
以验证是否设置正确。与以前一样,您将看到您的主页。
要验证您的服务器是否仅接受由Cloudflare的CA签名的请求,请切换已验证的源拉取选项以禁用它,然后重新加载您的网站。您应该会收到以下错误消息:
如果Cloudflare的CA未签署请求,则您的源服务器会引发错误。
注意:大多数浏览器会缓存请求,因此要查看上述更改,您可以在浏览器中使用无痕/私密浏览模式。为了防止Cloudflare在设置网站时缓存请求,请转到Cloudflare仪表板中的概述并切换开发模式。
现在您知道它正常工作了,请返回Cloudflare仪表板中的SSL/TLS部分,转到源服务器选项卡,并再次切换已验证的源拉取选项以启用它。
结论
在本教程中,您通过使用来自Cloudflare的Origin CA证书对Cloudflare和Nginx服务器之间的流量进行加密,保护了您的Nginx-powered网站。然后,您在Nginx服务器上设置了身份验证的Origin Pulls,以确保它仅接受来自Cloudflare服务器的请求,防止其他任何人直接连接到Nginx服务器。