介绍
TLS 或传输层安全性及其前身 SSL 代表安全套接字层,是用于将正常流量包装在受保护的加密包装器中的 Web 协议。
使用这项技术,服务器可以在服务器和客户端之间安全地发送流量,而不会被外界截获消息。 证书系统还帮助用户验证他们正在连接的站点的身份。
在本指南中,我们将向您展示如何设置自签名 SSL 证书以在 Ubuntu 18.04 服务器上与 Nginx Web 服务器一起使用。
注意: 自签名证书将加密您的服务器和任何客户端之间的通信。 但是,由于它没有由 Web 浏览器中包含的任何受信任的证书颁发机构 (CA) 签名,因此用户无法使用该证书自动验证您的服务器的身份。
如果您没有与您的服务器关联的域名,并且在加密的 Web 界面不是面向用户的情况下,自签名证书可能是合适的。 如果你 do 有一个域名,在很多情况下最好使用 CA 签名的证书。 您可以在此处 的 Let's Encrypt 项目 中了解如何设置免费的可信证书。
先决条件
要遵循本教程,您将需要:
- 一台 Ubuntu 18.04 服务器设置有非 root 用户,配置有
sudo
权限和防火墙。 您可以按照我们的 Ubuntu 18.04 初始服务器设置来了解如何设置此类用户帐户。 - 您还需要安装 Nginx Web 服务器。 如果您想在您的服务器上安装整个 LEMP(Linux、Nginx、MySQL、PHP)堆栈,您可以按照我们关于 在 Ubuntu 18.04 上设置 LEMP 的指南进行操作。
- 如果您只想要 Nginx Web 服务器,您可以按照我们的指南在 在 Ubuntu 18.04 上安装 Nginx。
完成先决条件后,继续执行第一步。
第 1 步 — 创建 SSL 证书
TLS/SSL 通过使用公共证书和私钥的组合来工作。 SSL 密钥在服务器上是保密的。 它用于加密发送给客户端的内容。 SSL 证书与任何请求内容的人公开共享。 它可用于解密由相关 SSL 密钥签名的内容。
您可以在单个命令中使用 OpenSSL 创建自签名密钥和证书对:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
以下是该命令各部分功能的细分:
sudo
:sudo
命令允许sudo
组的成员临时将他们的权限提升到另一个用户(超级用户,或 root 用户,默认情况下)。 在这种情况下这是必要的,因为我们在/etc/
目录下创建证书和密钥对,只能由 root 用户或其他特权帐户访问。openssl
:这是用于创建和管理 OpenSSL 证书、密钥和其他文件的基本命令行工具。req
:此子命令指定我们要使用 X.509 证书签名请求 (CSR) 管理。 X.509 是 SSL 和 TLS 为其密钥和证书管理所遵循的公钥基础设施标准。 我们想创建一个新的 X.509 证书,所以我们使用这个子命令。-x509
:这进一步修改了前面的子命令,告诉实用程序我们要制作自签名证书,而不是像通常发生的那样生成证书签名请求。-nodes
:这告诉 OpenSSL 跳过使用密码保护我们的证书的选项。 当服务器启动时,我们需要 Nginx 能够读取文件,而无需用户干预。 密码可以防止这种情况发生,因为我们必须在每次重启后输入它。-days 365
:此选项设置证书将被视为有效的时间长度。 我们在这里设置了一年。-newkey rsa:2048
:这指定我们要同时生成一个新证书和一个新密钥。 我们没有在上一步中创建签署证书所需的密钥,因此我们需要将其与证书一起创建。rsa:2048
部分告诉它生成一个 2048 位长的 RSA 密钥。-keyout
:这一行告诉 OpenSSL 将我们正在创建的生成的私钥文件放在哪里。-out
:这告诉 OpenSSL 在哪里放置我们正在创建的证书。
如前所述,这些选项将创建密钥文件和证书。 运行此命令后,系统会询问您一些有关服务器的问题,以便将信息正确嵌入证书中。
适当地填写提示。 最重要的一行是请求通用名称的行(例如 服务器 FQDN 或您的姓名)。 您需要输入与您的服务器关联的域名,或者更有可能是您的服务器的公共 IP 地址。
整个提示将如下所示:
OutputCountry Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:New York Locality Name (eg, city) []:New York City Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bouncy Castles, Inc. Organizational Unit Name (eg, section) []:Ministry of Water Slides Common Name (e.g. server FQDN or YOUR name) []:server_IP_address Email Address []:admin@your_domain.com
您创建的两个文件都将放置在 /etc/ssl
目录的相应子目录中。
在使用 OpenSSL 时,您还应该创建一个强大的 Diffie-Hellman 组,用于与客户端协商 Perfect Forward Secrecy。
您可以通过运行以下命令来做到这一点:
sudo openssl dhparam -out /etc/nginx/dhparam.pem 4096
这需要一段时间,但完成后,您将在 /etc/nginx/dhparam.pem
处拥有一个强大的 DH 组,将在配置期间使用。
第 2 步 — 配置 Nginx 以使用 SSL
现在您已经创建了 /etc/ssl
目录下的密钥和证书文件,您需要修改 Nginx 配置以利用它们。
首先,您将创建一个配置片段,其中包含有关 SSL 密钥和证书文件位置的信息。 然后,您将创建一个具有强大 SSL 设置的配置片段,该设置可以在未来与任何证书一起使用。 最后,您将使用您创建的两个配置片段调整您的 Nginx 服务器块,以便正确处理 SSL 请求。
这种配置 Nginx 的方法将允许您保持干净的服务器块并将常见的配置段放入可重用的模块中。
创建指向 SSL 密钥和证书的配置片段
首先,使用您喜欢的文本编辑器在 /etc/nginx/snippets
目录中创建一个新的 Nginx 配置片段。 以下示例使用 nano
:
为了正确区分此文件的用途,将其命名为 self-signed.conf
:
sudo nano /etc/nginx/snippets/self-signed.conf
在此文件中,将 ssl_certificate
指令设置为您的证书文件,将 ssl_certificate_key
设置为关联的密钥。 这将如下所示:
/etc/nginx/snippets/self-signed.conf
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt; ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
添加这些行后,保存文件并退出编辑器。 如果您使用 nano
,您可以按 CTRL + X
,然后按 Y
和 ENTER
来执行此操作。
创建具有强加密设置的配置片段
接下来,您将创建另一个片段来定义一些 SSL 设置。 这将为 Nginx 设置一个强大的 SSL 密码套件,并启用一些有助于保持服务器安全的高级功能。
您设置的参数可以在未来的 Nginx 配置中重复使用,因此您可以给文件一个通用名称:
sudo nano /etc/nginx/snippets/ssl-params.conf
为了安全地设置 Nginx SSL,我们将调整来自 Cipherlist.eu 的建议。 Cipherlist.eu 是一个有用且易于理解的资源,用于了解用于流行软件的加密设置。
注意: Cipherlist.eu 中的建议设置提供了强大的安全性。 有时,这是以更高的客户端兼容性为代价的。 如果您需要支持旧客户端,可以通过单击页面上标有“是的,给我一个适用于旧版/旧版软件的密码套件”的链接访问一个替代列表。 如果需要,您可以将该列表替换为下一个示例代码块的内容。
选择使用哪种配置很大程度上取决于您需要支持什么。 它们都将提供极大的安全性。
出于我们的目的,请完整复制提供的设置,但首先,您需要进行一些小的修改。
首先,为上游请求添加首选 DNS 解析器。 我们将在本指南中使用 Google 的(8.8.8.8
和 8.8.4.4
)。
其次,注释掉设置严格传输安全标头的行。 在取消注释此行之前,您应该花点时间阅读 HTTP Strict Transport Security 或 HSTS,特别是有关 “预加载”功能 。 预加载 HSTS 可提高安全性,但如果意外启用或启用不正确,也会产生深远的负面影响。
将以下内容添加到您的 ssl-params.conf
片段文件中:
/etc/nginx/snippets/ssl-params.conf
ssl_protocols TLSv1.3; ssl_prefer_server_ciphers on; ssl_dhparam /etc/nginx/dhparam.pem; ssl_ciphers EECDH+AESGCM:EDH+AESGCM; ssl_ecdh_curve secp384r1; ssl_session_timeout 10m; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; # Disable strict transport security for now. You can uncomment the following # line if you understand the implications. #add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block";
因为您使用的是自签名证书,所以不会使用 SSL 装订。 Nginx 将输出警告,禁用您的自签名证书的装订,但随后将继续正常运行。
完成后保存并关闭文件。
调整 Nginx 配置以使用 SSL
现在您已经有了代码片段,您可以调整 Nginx 配置以启用 SSL。
我们将在本指南中假设您正在使用 /etc/nginx/sites-available
目录中的自定义服务器块配置文件。 本指南还遵循先决条件 Nginx 教程中的约定,并在此示例中使用 /etc/nginx/sites-available/your_domain
。 根据需要替换您的配置文件名。
在继续之前,请备份您当前的配置文件:
sudo cp /etc/nginx/sites-available/your_domain /etc/nginx/sites-available/your_domain.bak
现在,打开配置文件进行调整:
sudo nano /etc/nginx/sites-available/your_domain
在内部,您的服务器块可能开始类似于以下内容:
/etc/nginx/sites-available/your_domain.com
server { listen 80; listen [::]:80; server_name your_domain www.your_domain.com; root /var/www/your_domain.com/html; index index.html index.htm index.nginx-debian.html; . . . }
您的文件可能有不同的顺序,而不是 root
和 index
指令,您可能有一些 location
、proxy_pass
或其他自定义配置陈述。 这很好,因为您只需要更新 listen
指令并包含您的 SSL 片段。 然后修改这个现有的服务器块以在端口 443
上提供 SSL 流量,并创建一个新的服务器块以响应端口 80
并自动将流量重定向到端口 443
。
注意: 使用 302 重定向,直到您确认一切正常。 之后,您将其更改为永久 301 重定向。
在您现有的配置文件中,更新两个 listen
语句以使用端口 443
和 ssl
,然后包含我们在前面步骤中创建的两个片段文件:
/etc/nginx/sites-available/your_domain.com
server { listen 443 ssl; listen [::]:443 ssl; include snippets/self-signed.conf; include snippets/ssl-params.conf; server_name your_domain.com www.your_domain.com; root /var/www/your_domain.com/html; index index.html index.htm index.nginx-debian.html; . . . }
接下来,在第一个块的右括号 (}
) 之后将第二个服务器块添加到配置文件中:
/etc/nginx/sites-available/your_domain.com
. . . server { listen 80; listen [::]:80; server_name your_domain.com www.your_domain.com; return 302 https://$server_name$request_uri; }
这是一个简单的配置,侦听端口 80
并执行到 HTTPS 的重定向。 完成编辑后保存并关闭文件。
第 3 步 — 调整防火墙
如果按照先决条件指南的建议启用了 ufw
防火墙,则需要调整设置以允许 SSL 流量。 幸运的是,Nginx 在安装时使用 ufw
注册了一些配置文件。
您可以通过运行以下命令查看可用的配置文件:
sudo ufw app list
输出中将出现如下列表:
OutputAvailable applications: Nginx Full Nginx HTTP Nginx HTTPS OpenSSH
您还可以通过键入 sudo ufw status
来检查当前设置:
sudo ufw status
它可能会生成以下输出,这意味着 Web 服务器只允许 HTTP 流量:
OutputStatus: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx HTTP ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx HTTP (v6) ALLOW Anywhere (v6)
要允许 HTTPS 流量,您可以更新“Nginx Full”配置文件的权限:
sudo ufw allow 'Nginx Full'
然后,删除多余的“Nginx HTTP”配置文件:
sudo ufw delete allow 'Nginx HTTP'
运行 sudo ufw status
后,您应该会收到以下输出:
sudo ufw status
OutputStatus: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx Full ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx Full (v6) ALLOW Anywhere (v6)
此输出确认对防火墙的调整已成功,并且您已准备好在 Nginx 中启用更改。
第 4 步 — 启用 Nginx 中的更改
完成对防火墙的更改和调整后,您可以重新启动 Nginx 以实施新的更改。
首先,检查我们的文件中是否存在语法错误。 您可以通过运行 sudo nginx -t
来做到这一点:
sudo nginx -t
如果一切顺利,您将获得如下内容的结果:
Outputnginx: [warn] "ssl_stapling" ignored, issuer certificate not found for certificate "/etc/ssl/certs/nginx-selfsigned.crt" nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
注意开头的警告。 如前所述,此特定设置会生成警告,因为您的自签名证书无法使用 SSL 装订。 这是意料之中的,您的服务器仍然可以正确加密连接。
如果您的输出与我们的示例匹配,那么您的配置文件应该没有语法错误。 如果是这种情况,那么您可以安全地重新启动 Nginx 以实施更改:
sudo systemctl restart nginx
现在系统已使用新更改重新启动,您可以继续进行测试。
第 5 步 — 测试加密
现在,您已准备好测试您的 SSL 服务器。
打开您的网络浏览器并在地址栏中输入 https://
,然后是您的服务器的域名或 IP:
https://server_domain_or_IP
根据您的浏览器,您可能会收到一条警告,因为您创建的证书未由浏览器的受信任证书颁发机构之一签名:
此警告是预期的和正常的。 我们只对我们证书的加密方面感兴趣,而不是对我们主机真实性的第三方验证。 单击“ADVANCED”,然后单击提供的链接以转到您的主机:
此时,您应该被带到您的站点。 在我们的示例中,浏览器地址栏显示一个带有“x”的锁,这意味着无法验证证书。 它仍在加密您的连接。 请注意,此图标可能会有所不同,具体取决于您的浏览器。
如果你为 Nginx 配置了两个服务器块,自动将 HTTP 内容重定向到 HTTPS,你还可以检查重定向功能是否正确:
http://server_domain_or_IP
如果这导致相同的图标,这意味着您的重定向工作正常。
第 6 步 — 更改为永久重定向
如果您的重定向工作正常并且您确定只允许加密流量,您应该修改 Nginx 配置以使重定向永久化。
再次打开您的服务器块配置文件:
sudo nano /etc/nginx/sites-available/your_domain.com
找到 return 302
并将其更改为 return 301
:
/etc/nginx/sites-available/your_domain.com
return 301 https://$server_name$request_uri;
保存并关闭文件。
检查您的配置是否有语法错误:
sudo nginx -t
准备好后,重新启动 Nginx 以使重定向永久化:
sudo systemctl restart nginx
重新启动后,更改将被实施,您的重定向现在是永久的。
结论
您已将 Nginx 服务器配置为对客户端连接使用强加密。 这将使您能够安全地处理请求,并防止外部各方读取您的流量。 或者,您可以选择使用可以从 Let's Encrypt 获得的自签名 SSL 证书,这是一个安装免费 TLS/SSL 证书并在 Web 服务器上启用加密 HTTPS 的证书颁发机构。 从我们关于 如何在 Ubuntu 18.04 上使用 Let's Encrypt 保护 Nginx 的教程中了解更多信息。