简介
TLS,即传输层安全性,及其前身 SSL,即安全套接字层,是用于将普通流量包装在受保护的加密包装中的网络协议。
使用这项技术,服务器可以在服务器和客户端之间安全地发送流量,而不会被外部方拦截。证书系统还帮助用户验证他们正在连接的站点的身份。
在本指南中,我们将向您展示如何为 Ubuntu 18.04 服务器上的 Nginx Web 服务器设置自签名 SSL 证书。
先决条件
要按照本教程操作,您需要:
- 一个已设置了非root用户并配置了
sudo
权限和防火墙的 Ubuntu 18.04 服务器。您可以按照我们的 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 地址。
提示的全部内容如下:
Country 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 组,用于与客户端协商完美前向保密。
您可以通过运行以下命令来执行此操作:
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
设置为相关的密钥。看起来会像这样:
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 是一个有用且易于理解的资源,用于了解流行软件使用的加密设置。
对于我们的目的,完整地复制提供的设置,但首先你需要做一些小的修改。
首先,添加你喜欢的上游请求的 DNS 解析器。在本指南中,我们将使用 Google 的(8.8.8.8
和 8.8.4.4
)。
其次,注释掉设置严格传输安全头的行。在取消注释之前,你应该花一点时间了解 HTTP 严格传输安全(HSTS),特别是关于“preload”功能。预加载 HSTS 提供了增强的安全性,但如果意外启用或错误启用,可能会产生深远的负面后果。
将以下内容添加到你的 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;
# 暂时禁用严格传输安全。如果你理解其含义,可以取消注释以下行。
#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 stapling 将不会被使用。Nginx 将输出警告,为你的自签名证书禁用 stapling,但然后会继续正确运行。
编辑完成后保存并关闭文件。
调整 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
在文件中,你的服务器块可能类似于以下内容:
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;. . .
}
你的文件可能顺序不同,而且你可能有一些 location
、proxy_pass
或其他自定义配置语句,而不是 root
和 index
指令。这没关系,因为你只需要更新 listen
指令并包含你的 SSL 片段。然后修改现有的服务器块以在端口 443
上提供 SSL 交通,并创建一个新的服务器块以在端口 80
上响应并自动重定向交通到端口 443
。
在你的现有配置文件中,更新两个 listen
语句以使用端口 443
和 ssl
,然后包含我们在前面步骤中创建的两个片段文件:
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;. . .
}
接下来,在第一个块的结束大括号 (}
) 后,在配置文件中添加第二个服务器块:
. . .
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
输出将会显示如下列表:
Available applications:Nginx FullNginx HTTPNginx HTTPSOpenSSH
你也可以通过输入 sudo ufw status
来检查当前设置:
sudo ufw status
它可能会生成以下输出,意味着只有 HTTP 流量被允许访问 web 服务器:
Status: activeTo 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
Status: activeTo 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
如果一切顺利,你将会得到以下结果:
nginx: [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 stapling,这个特定设置会生成一个警告。这是正常的,你的服务器仍然可以正确加密连接。
如果你的输出与我们的示例匹配,那么你的配置文件应该没有语法错误。如果是这种情况,你可以安全地重新启动 Nginx 来实施更改:
sudo systemctl restart nginx
现在系统已经使用新的更改重新启动,你可以继续进行测试。
步骤 5 — 测试加密
现在,你已经准备好测试你的 SSL 服务器。
打开你的网络浏览器,然后在地址栏中输入 https://
,后面跟上你的服务器域名或 IP:
https://server_domain_or_IP
根据你的浏览器,你可能会收到一个警告,因为你创建的证书没有被你的浏览器信任的证书机构签名:
!Nginx self-signed cert warning
这个警告是正常的。我们只关心证书的加密方面,而不是主机真实性的第三方验证。点击 “高级”,然后点击提供的链接以继续访问你的主机:
!Nginx self-signed override
此时,你应该会被带到你的网站。在我们的示例中,浏览器地址栏显示一个带有 “x” 的锁,这意味着证书无法验证。但它仍然在加密你的连接。请注意,这个图标可能会因浏览器而异。
如果你在 Nginx 中配置了两个服务器块,自动将 HTTP 内容重定向到 HTTPS,你也可以检查重定向是否正常工作:
http://server_domain_or_IP
如果结果显示相同的图标,这意味着你的重定向工作正常。
步骤 6 — 更改为永久重定向
如果你的重定向工作正常,并且你确定只想允许加密流量,你应该修改 Nginx 配置以使重定向变为永久性的。
再次打开你的服务器块配置文件:
sudo nano /etc/nginx/sites-available/your_domain.com
找到 return 302
并将其更改为 return 301
:
return 301 https://$server_name$request_uri;
保存并关闭文件。
检查你的配置是否有语法错误:
sudo nginx -t
当你准备好后,重新启动 Nginx 以使重定向变为永久性:
sudo systemctl restart nginx
重新启动后,更改将会生效,你的重定向现在是永久性的。
结论
您已经配置了 Nginx 服务器以在客户端连接中使用强加密。这将使您能够安全地提供请求,并防止外部方读取您的流量。或者,您可以选择使用自签名的 SSL 证书,该证书可以从 Let’s Encrypt 获得,Let’s Encrypt 是一个安装免费 TLS/SSL 证书并在 Web 服务器上启用加密 HTTPS 的证书颁发机构。您可以从我们的教程《如何在 Ubuntu 18.04 上使用 Let’s Encrypt 安全配置 Nginx》中了解更多信息。