Apache-2.2

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

  • January 13, 2021

我正在嘗試在我的 Wordpress 網站上實施 HSTS(HTTP 嚴格傳輸安全),但沒有取得任何成功。首先,我設法將我的網站從非 www 重定向到 www ,包括 https:// ,但我在https://hstspreload.org/上收到消息,它應該首先重定向到 www。

我試圖使用 VirtualHosts 配置文件,沒有運氣。所以我做了一些Google搜尋,發現這個連結看起來像是 htaccess 的解決方案,但我仍然遇到問題。如果有人知道如何通過 VirtualHost / Apache 配置文件來實現這一點,那就太好了。

錯誤:HTTP 首先重定向到 www http://inter.net (HTTP) 應在添加 www 子域之前立即重定向到https://inter.net(HTTPS)。現在,第一個重定向是 to 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 網址僅作為範例。

編輯 - 我已經編輯了我的 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 Developer 模組(F12)來查看是否可以理解任何其他資訊,問題似乎是 301 重定向循環https://www.example.com

編輯2:感謝@MrWhite,我明白ServerAlias細節是不必要的,是循環的原因。問題解決了,從中吸取了教訓。

總之,HSTS的主要要求是:

  1. 在同一主機上從 HTTP 重定向到 HTTPS 。IE。http://example.comhttps://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 發送,但我不認為是這種情況。規範指出,UA 應該在以下情況下簡單地忽略此標頭通過 HTTP 發送,因此通過 HTTP 發送也不是“問題”。但是,僅通過 HTTPS 發送它並沒有太多工作,這就是我在下面實現的方式。)

因此,這意味著您不必在單個重定向中規範化請求(HTTP / HTTPS / www / non-www),因為這可能違反上面的#1。

您似乎也沒有在您發布的程式碼中設置 STS 標頭。如果您在 Apache(伺服器配置或.htaccess)中實現重定向,那麼您無法使用 WordPress 設置此標頭 - 如果您正在這樣做?

我做了一些Google搜尋,發現這個連結看起來像是 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 header只設置了max-age1個月的參數,不包含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 響應。IE。它需要在非 www 上設置為 www HTTPS 301 重定向。

另請參閱對 CodeReview SE 上有關 HSTS 實施的以下問題的回答.htaccess

引用自:https://serverfault.com/questions/1044319