如何在 Ubuntu 16.04 中为 Apache 创建自签名 SSL 证书
介绍
TLS 或传输层安全性及其前身 SSL(代表安全套接字层)是用于将正常流量包装在受保护的加密包装器中的 Web 协议。
使用此技术,服务器可以在服务器和客户端之间安全地发送流量,而不会被外界截获消息。证书系统还帮助用户验证他们正在连接的站点的身份。
在本指南中,您将学习如何设置自签名 SSL 证书,以便在 Ubuntu 16.04 服务器上与 Apache Web 服务器一起使用。
注意:自签名证书将加密您的服务器和任何客户端之间的通信。但是,由于它未由 Web 浏览器和操作系统中包含的任何受信任的证书颁发机构签名,因此用户无法使用该证书自动验证您的服务器的身份。因此,您的用户在访问您的网站时会看到安全错误。
由于此限制,自签名证书不适用于为公众服务的生产环境。它们通常用于测试或保护单个用户或一小群用户使用的非关键服务,这些用户可以通过备用通信渠道建立对证书有效性的信任。
如需更适合生产的证书解决方案,请查看如何在 Ubuntu 16.04 上使用 Let's Encrypt 保护 Apache 教程。
先决条件
在开始本教程之前,您需要具备以下条件:
-
Access to a Ubuntu 16.04 server with a non-root, sudo-enabled user. Our Initial Server Setup with Ubuntu 16.04 guide can show you how to create this account.
-
You will also need to have Apache installed. You can install Apache using
apt
. First, update the local package index to reflect the latest upstream changes:- sudo apt update
Then, install the
apache2
package:- sudo apt install apache2
And finally, if you have a
ufw
firewall set up, open up thehttp
andhttps
ports:- sudo ufw allow "Apache Full"
完成这些步骤后,请确保您以非 root 用户身份登录并继续本教程。
第 1 步 — 启用 mod_ssl
在我们可以使用 任何 SSL 证书之前,我们首先必须启用 mod_ssl
,这是一个提供 SSL 加密支持的 Apache 模块。
使用 a2enmod
命令启用 mod_ssl
:
- sudo a2enmod ssl
重新启动 Apache 以激活模块:
- sudo systemctl restart apache2
mod_ssl
模块现已启用并可供使用。
第 2 步 — 创建 SSL 证书
现在 Apache 已准备好使用加密,我们可以继续生成新的 SSL 证书。该证书将存储有关您网站的一些基本信息,并附有一个密钥文件,使服务器能够安全地处理加密数据。
我们可以使用 openssl
命令创建 SSL 密钥和证书文件:
- sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt
输入命令后,系统会提示您输入有关网站的信息。在我们讨论之前,让我们看一下我们发出的命令中发生了什么:
- openssl:这是用于创建和管理 OpenSSL 证书、密钥和其他文件的基本命令行工具。
- req:此子命令指定我们要使用 X.509 证书签名请求 (CSR) 管理。 \X.509 是 SSL 和 TLS 遵守其密钥和证书管理的公钥基础设施标准。我们想要创建一个新的 X.509 证书,因此我们正在使用此子命令。
- -x509:这进一步修改了之前的子命令,它告诉实用程序我们想要创建一个自签名证书,而不是像通常发生的那样生成证书签名请求。
- -nodes:这告诉 OpenSSL 跳过使用密码保护我们的证书的选项。当服务器启动时,我们需要 Apache 能够在没有用户干预的情况下读取文件。密码短语可以防止这种情况发生,因为我们必须在每次重启后输入它。
- -days 365:此选项设置证书将被视为有效的时间长度。我们在这里设定为一年。
- -newkey rsa:2048:这指定我们要同时生成新证书和新密钥。我们没有在上一步中创建签署证书所需的密钥,因此我们需要将其与证书一起创建。
rsa:2048
部分告诉它生成一个 2048 位长的 RSA 密钥。 - -keyout:这一行告诉 OpenSSL 在哪里放置我们正在创建的生成的私钥文件。
- -out:这告诉 OpenSSL 在哪里放置我们正在创建的证书。
如上所述,这些选项将创建密钥文件和证书。我们将被问到一些关于我们服务器的问题,以便将信息正确地嵌入到证书中。
适当填写提示。最重要的一行是请求 Common Name
的那一行。您需要输入用于访问服务器的主机名或服务器的公共 IP。重要的是,此字段必须与您在浏览器地址栏中输入的任何内容相匹配以访问该站点,因为不匹配会导致更多安全错误。
整个提示看起来像这样:
Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:Example
Locality Name (eg, city) [Default City]:Example
Organization Name (eg, company) [Default Company Ltd]:Example Inc
Organizational Unit Name (eg, section) []:Example Dept
Common Name (eg, your name or your server's hostname) []:your_domain_or_ip
Email Address []:webmaster@example.com
您创建的两个文件都将放置在 /etc/ssl
目录的相应子目录中。
第 3 步 — 配置 Apache 以使用 SSL
现在我们有了可用的自签名证书和密钥,我们需要更新 Apache 配置以使用它们。在 Ubuntu 上,您可以将新的 Apache 配置文件(它们必须以 .conf
结尾)放入 /etc/apache2/sites-available/
,它们将在下次加载Apache 进程被重新加载或重新启动。
对于本教程,我们将创建一个新的最小配置文件。 (如果您已经设置了 Apache
并且只需要向其添加 SSL,您可能需要复制以 SSL
开头的配置行,并将 VirtualHost
端口从 80
切换到 443
。我们将在下一步处理端口 80
。 )
在 /etc/apache2/sites-available 目录中打开一个新文件:
- sudo nano /etc/apache2/sites-available/your_domain_or_ip.conf
粘贴以下最小 VirtualHost 配置:
<VirtualHost *:443>
ServerName your_domain_or_ip
DocumentRoot /var/www/your_domain_or_ip
SSLEngine on
SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key
</VirtualHost>
请务必将 ServerName
行更新为您打算对服务器进行寻址的方式。这可以是主机名、完整域名或 IP 地址。确保您选择的任何内容与制作证书时选择的 Common Name
匹配。
其余行指定一个 DocumentRoot
目录来提供文件,以及将 Apache 指向我们新创建的证书和密钥所需的 SSL 选项。
现在让我们创建我们的 DocumentRoot
并将一个 HTML 文件放入其中,仅用于测试目的:
- sudo mkdir /var/www/your_domain_or_ip
使用文本编辑器打开一个新的 index.html
文件:
- sudo nano /var/www/your_domain_or_ip/index.html
将以下内容粘贴到空白文件中:
<h1>it worked!</h1>
当然,这不是一个完整的 HTML 文件,但是浏览器很宽松,足以验证我们的配置。
保存并关闭文件
- sudo a2ensite your_domain_or_ip.conf
它将提示您重新启动 Apache 以激活配置,但首先,让我们测试配置错误:
- sudo apache2ctl configtest
如果一切顺利,您将得到如下所示的结果:
OutputAH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
Syntax OK
第一行是一条消息,告诉您 ServerName
指令未全局设置。如果您想摆脱该消息,可以在 /etc/apache2/apache2.conf
中将 ServerName
设置为服务器的域名或 IP 地址。这是可选的,因为消息不会造成任何伤害。
如果您的输出中有 Syntax OK
,则您的配置文件没有语法错误。我们可以安全地重新加载 Apache 来实现我们的更改:
- sudo systemctl reload apache2
现在在浏览器中加载您的站点,确保在开头使用 https://
。
你应该看到一个错误。这对于自签名证书来说是正常的!浏览器警告您它无法验证服务器的身份,因为我们的证书未由任何已知的证书颁发机构签名。出于测试目的和个人使用,这可能没问题。您应该能够点击进入高级或更多信息并选择继续。
执行此操作后,您的浏览器将加载 it worked!
消息。
注意:如果您的浏览器根本没有连接到服务器,请确保您的连接没有被防火墙阻止。如果您使用的是 ufw
,则以下命令将打开端口 80
和 443
:
- sudo ufw allow "Apache Full"
接下来,我们将在我们的配置中添加另一个 VirtualHost
部分,以处理纯 HTTP 请求并将它们重定向到 HTTPS。
第 4 步 — 将 HTTP 重定向到 HTTPS
目前,我们的配置只会响应端口 443
上的 HTTPS 请求。最好在端口 80
上也做出响应,即使您想要强制对所有流量进行加密也是如此。让我们设置一个 VirtualHost
来响应这些未加密的请求并将它们重定向到 HTTPS。
打开我们在前面步骤中启动的相同 Apache 配置文件:
- sudo nano /etc/apache2/sites-available/your_domain_or_ip.conf
在底部,创建另一个 VirtualHost
块以匹配端口 80
上的请求。使用 ServerName
指令再次匹配您的域名或 IP 地址。然后,使用 Redirect
匹配任何请求并将它们发送到 SSL VirtualHost
。确保包括尾部斜杠:
<VirtualHost *:80>
ServerName your_domain_or_ip
Redirect / https://your_domain_or_ip/
</VirtualHost>
完成后保存并关闭此文件,然后再次测试配置语法,并重新加载 Apache:
- sudo apachectl configtest
- sudo systemctl reload apache2
您可以通过在地址前面加上纯 http://
来访问您的站点,从而测试新的重定向功能。您应该会自动重定向到 https://
。
结论
您现在已将 Apache 配置为使用自签名 SSL 证书处理加密请求,并将未加密的 HTTP 请求重定向到 HTTPS。
如果您计划在公共网站上使用 SSL,您应该考虑购买域名并使用广泛支持的证书颁发机构,例如 Let's Encrypt。
有关使用 Apache Let's Encrypt 的更多信息,请阅读我们的如何在 Ubuntu 16.04 上使用 Let's Encrypt 保护 Apache 教程。