HSTS 和 Wordpress 重定向到 www 和非 www 和 https - 避免多次重定向?

HSTS 和 Wordpress 重定向到 www 和非 www 和 https - 避免多次重定向?

我正在尝试在我的 Wordpress 网站上实施 HSTS(HTTP 严格传输安全),但没有任何成功。首先,我设法将我的网站从非 www 重定向到 www ,并包括 https:// ,但我收到了消息https://hstspreload.org/它应该首先重定向到 www。

我尝试使用 VirtualHosts 配置文件,但没有成功。所以我在谷歌上搜索了一下,发现此链接这看起来像是使用 htaccess 的解决方案,但我仍然遇到问题。如果有人知道如何通过 VirtualHost / Apache 配置文件实现这一点,那就太好了。

错误:HTTP 首先重定向到 www http://inter.net(HTTP) 应立即重定向到https://inter.net(HTTPS),然后再添加 www 子域。目前,第一个重定向是 https://www.inter.net/。需要额外的重定向以确保任何支持 HSTS 的浏览器都会记录顶级域的 HSTS 条目,而不仅仅是子域。

我的 htaccess 如下:

# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

#### This is what I added : From https://www.danielmorell.com/guides/htaccess-seo/redirects/https-www-and-trailing-slash 
#### Force HTTPS://WWW and remove trailing / from files ####
## Turn on rewrite engine
RewriteEngine on

# Remove trailing slash from non-filepath urls
RewriteCond %{REQUEST_URI} /(.+)/$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ https://www.inter.net/%1 [R=301,L]

# Include trailing slash on directory 
RewriteCond %{REQUEST_URI} !(.+)/$
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+)$ https://www.inter.net/$1/ [R=301,L]

# Force HTTPS and WWW 
RewriteCond %{HTTP_HOST} !^www\.(.*)$ [OR,NC]
RewriteCond %{https} off  
RewriteRule ^(.*)$ https://www.inter.net/$1 [R=301,L]

# Yoast SEO - XML Sitemap Rewrite Fix
RewriteEngine On
RewriteBase /
RewriteRule ^sitemap_index.xml$ /index.php?sitemap=1 [L]
RewriteRule ^locations.kml$ /index.php?sitemap=wpseo_local_kml [L]
RewriteRule ^geo_sitemap.xml$ /index.php?sitemap=geo [L]
RewriteRule ^([^/]+?)-sitemap([0-9]+)?.xml$ /index.php?sitemap=$1&sitemap_n=$2 [L]
RewriteRule ^([a-z]+)?-?sitemap.xsl$ /index.php?yoast-sitemap-xsl=$1 [L]
# END Yoast SEO - XML Sitemap Rewrite Fix

ps-inter.net url 仅作为示例。

编辑 - 我已编辑 example.com.conf 文件以添加下面答案中给出的 MrWhite 提供的额外规则 - 看起来很准确。运行命令 apachectl configtestSyntaw 后一切正常。运行service apache2 reload以使更改生效,并让所有浏览器都说页面未正确重定向:(**ERR_TOO_MANY_REDIRECTS**每次针对不同的浏览器清除缓存)。

我仅将 htaccess 恢复为原始 Wordpress 和 Yoast SEO 规则。

我当前在 apache 上这个 VirtualHost 的配置文件可能有问题,但是 apachectl configtest 没有语法错误:https://paste.ofcode.org/vr25hFkPEt2vYjpM5sAUxK

我尝试使用 Firefox 开发者模块 (F12) 来查看是否能理解任何其他信息,问题似乎是 301 重定向循环https://www.example.com

编辑 2:感谢 @MrWhite ,我明白了ServerAlias细节是不必要的,也是循环的原因。问题解决了,并从中吸取了教训。

答案1

总而言之,HSTS 的主要要求是:

  1. 从 HTTP 重定向到 HTTPS在同一主机上. 即http://example.com.https://example.com http://www.example.comhttps://www.example.com

  2. 仅在 HTTPS 上重定向到规范主机名(www 或非 www)。(即上面的 #1 之后)

  3. 仅在 HTTPS 上发送Strict-Transport-Security(STS) HTTP 响应标头。包括在规范重定向上(上面的 #2)。

    (尽管有多个消息来源称 STS 标头应该仅有的通过 HTTPS 发送,甚至通过纯 HTTP 发送也完全无效,但我不相信情况如此。规格规定当通过 HTTP 发送时,UA 应该忽略此标头,因此通过 HTTP 发送此标头也不是“问题”。但是,仅通过 HTTPS 发送此标头的工作量并不大,这就是我下面实现此标头的方式。)

这意味着您不能在单个重定向中规范化请求(HTTP / HTTPS / www / non-www),因为这可能违反上面的#1。

您似乎也没有在发布的代码中设置 STS 标头。如果您在 Apache(服务器配置或.htaccess)中实现重定向,则无法使用 WordPress 设置此标头 - 如果您正在这样做?

我进行了一些谷歌搜索,发现这个链接看起来像是使用 htaccess 的解决方案

该“解决方案”不是实施 HSTS。该文章的唯一目的是在单个重定向中规范化请求。该文章顶部的“警告”明确告诉您它违反了 HSTS。

你还把指令的顺序搞错了。这些“重定向”指令需要删除WordPress 前端控制器,否则它根本就不会被 WordPress 处理虚拟的URL。

我假设您的规范主机名是www.example.com。(虽然您在问题标题中提到重定向到非 www,但您在问题的其余部分都重定向到 www?)

我尝试使用 VirtualHosts 配置文件,但没有成功。

尽管可以说在服务器配置中实现这一点(使用单独的虚拟主机)更简单、更不容易出错且效率更高。

例如(省略“其他”必要指令):

<VirtualHost *:80>
    ServerName example.com
    # Redirect to HTTPS - same host
    Redirect 301 / https://example.com/
</VirtualHost>

<VirtualHost *:80>
    ServerName www.example.com
    # Redirect to HTTPS - same host
    Redirect 301 / https://www.example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName example.com
    # Redirect to canonical host (HTTPS only)
    Redirect 301 / https://www.example.com/

    # SSL directives...

    # Set STS header on the HTTPS redirect ("always" argument is required for this)
    Header always set Strict-Transport-Security "max-age=2592000; includeSubDomains"
</VirtualHost>

<VirtualHost *:443>
    # Canonical host
    ServerName www.example.com

    # SSL directives...
    # etc.    

    # Set STS header on the HTTPS response
    Header always set Strict-Transport-Security "max-age=2592000; includeSubDomains"
</VirtualHost>

请注意,上面的 STS 标头仅设置了max-age为期 1 个月的参数,并不包含该preload参数。如果这是您的意图,请务必遵循 HSTS 预加载列表的“部署要求”中给出的说明。https://hstspreload.org/#deployment-recommendations

或者,以实现这一点.htaccess

(注意:我没有实现“尾随斜杠”重定向,因为您没有在要求中提到这一点,它只是从外部文章中复制的代码的一部分。)

# Set HSTS env var only if HTTPS
RewriteCond %{HTTPS} on
RewriteRule ^ - [E=HSTS:1]

# Redirect HTTP to HTTPS on the same host
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# Redirect non-www to www (HTTPS only)
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# Set HSTS header conditionally if request is over HTTPS only (based on HSTS env var)
Header always set Strict-Transport-Security "max-age=2592000; includeSubDomains" env=HSTS

# Yoast SEO - XML Sitemap Rewrite Fix
# : (directives go here...)
# END Yoast SEO - XML Sitemap Rewrite Fix

# BEGIN WordPress
# : (directives go here...)
# END WordPress

always指令上需要条件,Header因此标头设置在非 200 OK 响应上。即,它需要在非 www 到 www HTTPS 301 重定向上设置。

也可以看看我的答案关于 CodeReview SE 中 HSTS 实施的以下问题.htaccess

相关内容