介绍
TLS 或“传输层安全性”——及其前身 SSL——是用于将正常流量包装在受保护的加密包装器中的协议。 使用这项技术,服务器可以安全地向其客户端发送信息,而不会被外部方截获或读取它们的消息。
在本指南中,我们将向您展示如何在 Ubuntu 20.04 上的 Apache Web 服务器上创建和使用自签名 SSL 证书。
注意: 自签名证书将加密您的服务器和任何客户端之间的通信。 但是,由于它没有由 Web 浏览器和操作系统中包含的任何受信任的证书颁发机构签名,因此用户无法使用该证书自动验证您的服务器的身份。 因此,您的用户在访问您的网站时会看到安全错误。
由于此限制,自签名证书不适用于为公众服务的生产环境。 它们通常用于测试或保护由单个用户或一小组用户使用的非关键服务,这些用户可以通过备用通信渠道建立对证书有效性的信任。
如需更适合生产的证书解决方案,请查看免费证书颁发机构 Let's Encrypt。 您可以在我们的 How To Secure Apache with Let's Encrypt on Ubuntu 20.04 教程中了解如何下载和配置 Let's Encrypt 证书。
先决条件
在开始本教程之前,您需要以下内容:
使用非 root、启用 sudo 的用户访问 Ubuntu 20.04 服务器。 我们的 Initial Server Setup with Ubuntu 20.04 指南可以向您展示如何创建此帐户。
您还需要安装 Apache。 您可以使用
apt
安装 Apache。 首先,更新本地包索引以反映最新的上游更改:sudo apt update
然后,安装
apache2
包:sudo apt install apache2
最后,如果您设置了
ufw
防火墙,请打开http
和https
端口:sudo ufw allow "Apache Full"
完成这些步骤后,请确保您以非 root 用户身份登录并继续学习本教程。
第 1 步 - 启用 mod_ssl
在我们可以使用 any 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 -x509
:这指定我们要使用 X.509 证书签名请求 (CSR) 管理。 X.509 是 SSL 和 TLS 遵守的用于密钥和证书管理的公钥基础设施标准。-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
下的相应子目录中。
接下来我们将更新我们的 Apache 配置以使用新的证书和密钥。
第 3 步 - 将 Apache 配置为使用 SSL
现在我们有了可用的自签名证书和密钥,我们需要更新我们的 Apache 配置以使用它们。 在 Ubuntu 上,您可以将新的 Apache 配置文件(它们必须以 .conf
结尾)放入 /etc/apache2/sites-available/
,它们将在下次重新加载或重新启动 Apache 进程时加载。
对于本教程,我们将创建一个新的最小配置文件。 (如果您已经设置了 Apache <Virtualhost>
并且只需要添加 SSL,您可能需要复制以 SSL
开头的配置行,并切换 VirtualHost
端口从 80
到 443
。 我们将在下一步处理端口 80
。)
在 /etc/apache2/sites-available 目录中打开一个新文件:
sudo nano /etc/apache2/sites-available/your_domain_or_ip.conf
粘贴以下最小 VirtualHost 配置:
/etc/apache2/sites-available/your_domain_or_ip.conf
<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
将以下内容粘贴到空白文件中:
/var/www/your_domain_or_ip/index.html
<h1>it worked!</h1>
当然,这不是一个完整的 HTML 文件,但浏览器很宽松,足以验证我们的配置。
保存并关闭文件接下来,我们需要使用a2ensite
工具启用配置文件:
sudo a2ensite your_domain_or_ip.conf
接下来,让我们测试一下配置错误:
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
。 确保包含尾部斜杠:
/etc/apache2/sites-available/your_domain_or_ip.conf
<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 20.04 上使用 Let's Encrypt 保护 Apache 教程。