Apache HTTP 服务器是世界上最流行的 Web 服务器之一。它是一个开源且跨平台的 HTTP 服务器,为互联网上很大一部分网站提供支持。Apache 提供了许多强大的功能,可以通过额外的模块进行扩展。
如果您是网站所有者或系统管理员,您很可能经常与 Apache 打交道。您最常执行的任务之一可能是将 HTTP 流量重定向到您网站的安全 (HTTPS) 版本。
与以明文发送和返回请求与响应的 HTTP 不同,HTTPS 使用 TLS 来加密客户端与服务器之间的通信。
与 HTTP 相比,使用 HTTPS 有许多优势,例如:
- 所有数据在双向传输时都会被加密。因此,即使敏感信息被拦截也无法读取。
- 现代浏览器会为 HTTP 网站显示“不安全”警告。
- HTTPS 允许您使用 HTTP/2 协议,这能显著提升网站性能。
- Google 青睐 HTTPS 网站。如果通过 HTTPS 提供服务,您的网站排名会更好。
本指南介绍如何在 Apache 中将 HTTP 流量重定向到 HTTPS。
在设置重定向之前,您需要一个有效的 SSL/TLS 证书。Let’s Encrypt提供免费证书,是大多数网站最常用的选择。对于外部访问者无法访问的暂存站点或内部站点,自签名证书也同样适用。
在 Apache 中有多种重定向到 HTTPS 的方法。如果您对运行 Apache 的 Linux 服务器拥有 root 访问权限,首选方法是在域名的虚拟主机配置文件中设置重定向。否则,您可以在域名的 .htaccess 文件中设置重定向。某些控制面板(例如 cPanel)允许您通过点击几下鼠标来强制 HTTPS 重定向。
使用虚拟主机将 HTTP 重定向到 HTTPS
Apache 虚拟主机定义了服务器上托管的一个或多个域名的设置。在虚拟主机指令中,您可以指定站点文档根目录(包含网站文件的目录)、为每个站点创建单独的安全策略、使用不同的 SSL 证书、配置重定向等。
通常,当在某个域名上安装 SSL 证书后,该域名会有两个虚拟主机指令。第一个用于端口 80 上的 HTTP 版本站点,另一个用于端口 443 上的 HTTPS 版本。
在基于 Red Hat 的发行版(如 CentOS和 Fedora)中,虚拟主机文件存储在 /etc/httpd/conf.d 中。在 Debian 及其衍生版(如 Ubuntu)中,这些文件存储在 /etc/apache2/sites-available 目录中。
在添加重定向之前,请确保该域名拥有有效的 TLS 证书,并且 HTTPS 虚拟主机正常工作。
要将网站重定向到 HTTPS,请使用 Redirect 指令,如下例所示:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect permanent / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
Protocols h2 http/1.1
# SSL Configuration
# Other Apache Configuration
</VirtualHost>让我们解释一下这段代码。我们有两个虚拟主机指令,一个用于站点的 HTTP 版本,另一个用于 HTTPS 版本。
VirtualHost *:80- Apache 服务器监听指定域名在端口 80 (HTTP) 上的传入连接。VirtualHost *:443- Apache 服务器监听指定域名在端口 443 (HTTPS) 上的传入连接。
ServerName 和 ServerAlias 指令指定虚拟主机的域名。请确保将它们替换为您的域名。
高亮显示的行 Redirect permanent / https://example.com/ 位于 HTTP 虚拟主机内,用于将流量重定向到站点的 HTTPS 版本。
通常您还希望将站点的 HTTPS www 版本重定向到非 www 版本,或者反之。以下是一个示例配置:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect permanent / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
Protocols h2 http/1.1
<If "%{HTTP_HOST} == 'www.example.com'">
Redirect permanent / https://example.com/
</If>
# SSL Configuration
# Other Apache Configuration
</VirtualHost>HTTPS 虚拟主机内的代码(高亮显示的行)会检查请求头是否包含 www 域名,并重定向到非 www 版本。
如果 HTTPS 虚拟主机未配置或证书缺失,重定向可能会导致循环或浏览器错误。在强制实施重定向之前,请确保 HTTPS 正常工作。
每当您更改配置文件时,都需要重启或重新加载 Apache 服务以使更改生效:
Debian 和 Ubuntu:
sudo systemctl reload apache2CentOS 和 Fedora:
sudo systemctl reload httpd
使用 .htaccess 将 HTTP 重定向到 HTTPS
.htaccess 是 Apache Web 服务器基于每个目录的配置文件。此文件可用于定义 Apache 如何从放置该文件的目录中提供文件,以及开启或关闭附加功能。
通常,.htaccess 文件放置在域名根目录中,但您也可以在其他子目录中拥有其他 .htaccess 文件。
此方法要求 Apache 服务器上加载了 mod_rewrite 模块。大多数服务器默认加载此模块。如果可能,优先在虚拟主机中创建重定向,因为它更简单也更安全。
要将所有 HTTP 流量重定向到 HTTPS,请打开根目录中的 .htaccess 文件并向其中添加以下代码:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]以下是这段代码的含义:
RewriteEngine On- 启用重写功能。RewriteCond %{HTTPS} off- 检查是否为 HTTP 连接,如果条件满足,则执行下一行。RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]- 使用状态码 301(永久移动)将 HTTP 重定向到 HTTPS。请确保更改域名。
下面的示例有一个附加条件,用于检查请求是否以 www 开头。使用它可强制所有访问者使用 HTTPS 非 www 版本的站点:
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]编辑 .htaccess 文件时,您无需重启服务器,因为 Apache 会在每次请求时读取该文件。
重定向到单一规范主机
如果您想将所有流量强制到单一主机(www 或非 www),请在 HTTPS 虚拟主机上使用规范重定向。例如,要将所有流量重定向到非 www 版本:
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
<If "%{HTTP_HOST} == 'www.example.com'">
Redirect permanent / https://example.com/
</If>
# SSL Configuration
</VirtualHost>测试重定向
使用 curl 验证 HTTP 请求是否重定向到 HTTPS:
curl -I http://example.com您应该会看到一个 301 响应以及一个指向 HTTPS URL 的 Location 头:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/启用 HSTS(HTTP 严格传输安全)
HSTS 告诉浏览器在连接到您的站点时始终使用 HTTPS,即使用户在地址栏中输入 http://。这可以防止降级攻击并提高安全性。
将以下头添加到您的 HTTPS 虚拟主机中:
<VirtualHost *:443>
ServerName example.com
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
# SSL Configuration
</VirtualHost>max-age 值以秒为单位。上面的示例将其设置为一年(31536000 秒)。includeSubDomains 指令会将策略应用于所有子域名。
要使用 Header 指令,必须启用 mod_headers 模块。在 Debian/Ubuntu 上,运行:
sudo a2enmod headers
sudo systemctl reload apache2故障排除
重定向循环
如果您的浏览器显示“重定向过多”,请检查:
- HTTPS 虚拟主机已正确配置并监听端口 443
- SSL 证书有效且未过期
- 您没有在配置中将 HTTPS 重定向到 HTTPS
混合内容警告
启用 HTTPS 后,如果某些资源(图像、脚本、CSS)仍通过 HTTP 加载,您的站点可能会显示混合内容警告。请将所有内部链接更新为使用 HTTPS,或使用协议相对 URL(//example.com/path)。
更改未生效
如果对虚拟主机配置的更改没有生效,请确保已重新加载 Apache:
终端sudo systemctl reload apache2 # Debian/Ubuntu
sudo systemctl reload httpd # CentOS/Fedora对于 .htaccess 的更改,请确认虚拟主机配置中的 AllowOverride 已设置为 All。
快速参考
| 方法 | 使用场景 |
|---|---|
| 虚拟主机重定向 | 当您拥有服务器访问权限时的首选方法 |
.htaccess 重定向 | 当您无权访问虚拟主机配置时 |
| HSTS 头 | 在重定向正常工作后添加,以提高安全性 |