如何配置使用 HTTP 嚴格傳輸安全(HSTS)

linux.cn發表於2015-04-15

HTTP 嚴格傳輸安全(HSTS)是一種安全功能,web 伺服器通過它來告訴瀏覽器僅用 HTTPS 來與之通訊,而不是使用 HTTP。本文會說明如何在 Apache2、Nginx 和 Lighttpd 上如何啟用 HSTS。在主流的 web 伺服器上測試通過: Nginx 1.1.19、 Lighttpd 1.4.28 和 Apache 2.2.22 ,環境為 Ubuntu 12.04、 Debian 6 & 7 和 CentOS 6,只需要調整部分引數就可以工作在其它的發行版上。

如何配置使用 HTTP 嚴格傳輸安全(HSTS)

什麼是 HTTP 嚴格傳輸安全?

引用自 Mozilla Developer Network

如果一個 web 伺服器支援 HTTP 訪問,並將其重定向到 HTTPS 訪問的話,那麼訪問者在重定向前的初始會話是非加密的。舉個例子,比如訪問者輸入 http://www.foo.com/ 或直接輸入 foo.com 時。

這就給了中間人攻擊的一個機會,重定向會可能會被破壞,從而定向到一個惡意站點而不是應該訪問的加密頁面。

HTTP 嚴格傳輸安全(HSTS)功能使 Web 伺服器告知瀏覽器絕不使用 HTTP 訪問,在瀏覽器端自動將所有到該站點的 HTTP 訪問替換為 HTTPS 訪問。

以下引自維基百科

HSTS 可以用來抵禦 SSL 剝離攻擊。SSL 剝離攻擊是中間人攻擊的一種,由 Moxie Marlinspike 於2009年發明。他在當年的黑帽大會上發表的題為 “New Tricks For Defeating SSL In Practice” 的演講中將這種攻擊方式公開。SSL剝離的實施方法是阻止瀏覽器與伺服器建立HTTPS連線。它的前提是使用者很少直接在位址列輸入https://,使用者總是通過點選連結或3xx重定向,從HTTP頁面進入HTTPS頁面。所以攻擊者可以在使用者訪問HTTP頁面時替換所有https://開頭的連結為http://,達到阻止HTTPS的目的。

HSTS可以很大程度上解決SSL剝離攻擊,因為只要瀏覽器曾經與伺服器建立過一次安全連線,之後瀏覽器會強制使用HTTPS,即使連結被換成了HTTP。

另外,如果中間人使用自己的自簽名證書來進行攻擊,瀏覽器會給出警告,但是許多使用者會忽略警告。HSTS解決了這一問題,一旦伺服器傳送了HSTS欄位,使用者將不再允許忽略警告。

場景舉例:

當你通過一個無線路由器的免費 WiFi 訪問你的網銀時,很不幸的,這個免費 WiFi 也許就是由黑客的筆記本所提供的,他們會劫持你的原始請求,並將其重定向到克隆的網銀站點,然後,你的所有的隱私資料都曝光在黑客眼下。

嚴格傳輸安全可以解決這個問題。如果你之前使用 HTTPS 訪問過你的網銀,而且網銀的站點支援 HSTS,那麼你的瀏覽器就知道應該只使用 HTTPS,無論你是否輸入了 HTTPS。這樣就防範了中間人劫持攻擊。

注意,如果你之前沒有使用 HTTPS 訪問過該站點,那麼 HSTS 是不奏效的。網站需要通過 HTTPS 協議告訴你的瀏覽器它支援 HSTS。

伺服器開啟 HSTS 的方法是,當客戶端通過HTTPS發出請求時,在伺服器返回的 HTTP 響應頭中包含 Strict-Transport-Security 欄位。非加密傳輸時設定的HSTS欄位無效。

在 Apache2 中設定 HSTS

編輯你的 apache 配置檔案(如 /etc/apache2/sites-enabled/website.conf 和 /etc/apache2/httpd.conf ),並加以下行到你的 HTTPS VirtualHost:

# Optionally load the headers module:
LoadModule headers_module modules/mod_headers.so

<VirtualHost 67.89.123.45:443>
    Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
</VirtualHost>

現在你的 web 站點在每次訪問時都會傳送該請求頭,失效時間是兩年(秒數)。這個失效時間每次都會設定為兩年後,所以,明天你訪問時,它會設定為明天的兩年後。

你只能在 HTTPS 虛擬機器中設定這個頭,而不能設定在 HTTP 虛擬機器中。

要將你的訪問者重定向到對應 HTTPS 站點,可使用如下設定:

<VirtualHost *:80>
  [...]
  ServerName example.com
  Redirect permanent / https://example.com/
</VirtualHost>

如果僅僅是做重定向的話,甚至不需要設定 DocumentRoot。

你也可以使用 mod_rewrite 來做重定向,但是上述的方式更簡單更安全。不過,mod_rewrite 可以重定向頁面到對應的 HTTPS 頁面,而上述配置則只重定向到“/”:

<VirtualHost *:80>
  [...]
  <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
  </IfModule>
</VirtualHost>

不要忘記重啟 Apache。

Lighttpd

對於 lighttpd 來說很簡單,將下述配置增加到你的 Lighttpd 配置檔案(例如:/etc/lighttpd/lighttpd.conf):

server.modules += ( "mod_setenv" )
$HTTP["scheme"] == "https" {
    setenv.add-response-header  = ( "Strict-Transport-Security" => "max-age=63072000; includeSubdomains; preload")
}

重啟 Lighttpd。失效時間也是兩年。

Nginx

Nginx 甚至更簡單,將下述行新增到你的 HTTPS 配置的 server 塊中:

add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";

不要忘記重啟 Nginx。

相關文章