Apache HTTP Serverでの常時HTTPS化の設定

web/server

GNU socialを始めとした分散SNSをApache HTTP Serverで動作させる際の常時HTTPS化の設定を記します。

概要

Webサイト全体を常にHTTPSで表示することを常時HTTPS化と呼んでいます。

インターネットでWebサイトを表示する際はHTTPのプロトコルがベースになっています。しかし、HTTP自体は暗号化通信をしていないため、外部から盗聴可能などセキュリティー面で問題がありました。これを改善するため、HTTPをTLSで暗号化したHTTPSという通信プロトコルが誕生しました。

2010年頃まではHTTP通信が主流でしたが、2014-08-07にGoogleがHTTPSを検索ランキングに考慮しだしてから、HTTPSに対応するための無料のサーバー証明書を発行するLet’s Encryptの設立など、インターネット上でHTTPSの普及が一気に広がっていきました。

近年ではHTTPSでWebサイト全体を表示することが常識的になってきています。ただし、常時HTTPS化を行うには、HTTPからHTTPSへのリダイレクトなどいくつか必要な手順があります。

管理人の知る限り、ほとんどのレンタルサーバー・共用サーバーで採用されているWebサーバーはApache HTTP Server (httpd) です。そこで、Apacheでの常時HTTPS化の設定を記します。

結論としては、公開ディレクトリー直下の.htaccessに以下の内容を追記すればOKです。

常時HTTPS化の.htaccess
## Always HTTPS
<If "%{HTTPS} == 'on'">
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</If>
<ElseIf "%{REQUEST_URI} !~ m#^/\.well-known#">
    RewriteEngine On
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI}?%{QUERY_STRING} [L,R=301]
</ElseIf>

方針

サーバー側で証明書は取得済みなどで、サーバーがHTTPS自体に対応していることを前提とします。ほとんどのレンタルサーバーでは、HTTPSに対応していますので、通常は問題ありません。VPSなどで自分でサーバーを設置する場合は自分で用意しておきます。

この前提の下で、以下の3点を施して、常時HTTPS化を実現します。

Apacheでの常時HTTPS化の基本方針
  1. HTTPからHTTPSへのリダイレクト
  2. HSTSの対応
  3. プリロードHSTSへの登録

3のみ内容が多くなるため別の記事で説明します。

設定にあたっては以下の情報源を参考にしました。

情報源
  1. HSTS (HTTP Strict Transport Security) の導入 – Qiita
  2. TLS暗号設定ガイドライン~安全なウェブサイトのために(暗号設定対策編)~:IPA 独立行政法人 情報処理推進機構: TLS暗号設定 サーバー設定編 p. 12 5.1 Apacheの場合

HTTPからHTTPSへのダイレクト

まず、HTTPへのアクセスをHTTPSへのアクセスにリダイレクトします。Apacheでの設定 (httpd.conf) は以下となります。

LoadModule rewrite_module modules/mod_rewrite.so

<If "%{HTTPS} == 'off' && %{REQUEST_URI} !~ m#^/\.well-known#"> RewriteEngine On RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI}?%{QUERY_STRING} [L,R=301] </If>

Let’s Encryptによる証明書を使っている場合,証明書の更新時に.well-knownへのHTTPでのアクセスが必要になります。そのため,<If>指令で%{HTTPS}のチェックの後に,.well-knownへのアクセスのチェックをしています。

これでリダイレクトの設定は完了となります。

HTTP Strict Transport Security (HSTS)

HTTPのページにアクセスした場合にHTTPSのページにリダイレクトさせたとしても,リダイレクト前にHTTPのページにアクセスされることに変わりはありません。そのため,HTTPのページへのアクセス時に平文通信が発生し,中間攻撃を許してしまいます。

これを防ぐために,RFC 6797で規定されているHTTP Strict Transport Security (HSTS) があります。

WebサーバーのHTTPS応答に以下のHTTP応答ヘッダーを含めることで,次回以降,HTTPでアクセスせずに,HTTPSでアクセスするようにWebブラウザーに指示できます。

Strict-Transport-Security:max-age=有効期間秒数;includeSubDomains

これにより,2回目以降はHTTPへのアクセス自体を回避できます。

Apacheでの設定 (httpd.conf) は以下の通りとなります。

LoadModule headers_module modules/mod_headers.so

<If "%{HTTPS} == 'on'"> Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" </If>

この設定では,サブドメインも含めて365日が指示の有効期間となります。なお,後述するプリロードHSTSの設定 (preload) も便宜上ここでは一緒に設定しています。

.htaccessでの設定

ここまでのリダイレクトとHSTSの設定をまとめると,以下のhttpd.confとなります。

LoadModule headers_module modules/mod_headers.so
LoadModule rewrite_module modules/mod_rewrite.so

## Always HTTPS <If "%{HTTPS} == 'on'"> Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" </If> <ElseIf "%{REQUEST_URI} !~ m#^/\.well-known#"> RewriteEngine On RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI}?%{QUERY_STRING} [L,R=301] </ElseIf>

設定はLoadModule指令以外は.htaccessでも通用するものとなっています。httpd.confはサーバー全体の設定であるため、レンタルサーバーでは、.htaccessで制御します。念のため,.htaccessでの設定例は以下となります。

## `httpd.conf` で以下の3指令を指定しておく。
# LoadModule headers_module modules/mod_headers.so # LoadModule rewrite_module modules/mod_rewrite.so # AllowOverride FileInfo
## Always HTTPS <If "%{HTTPS} == 'on'"> Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" </If> <ElseIf "%{REQUEST_URI} !~ m#^/\.well-known#"> RewriteEngine On RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI}?%{QUERY_STRING} [L,R=301] </ElseIf>

.htaccessを使う場合,httpd.confLoadModulemod_headers.somod_rewrite.soを読み込む他,AllowOverride FileInfoを指定しておく必要があります。ほとんどのレンタルサーバーでは、最初からこれらが有効になっていますので、あまり気にする必要はありません。

IPAのサーバーの設定例は,<VirtualHost>指令を使ったもので,httpd.confでの設定しか考慮しておらず,.htaccessでの設定が考慮されていませんでした。そのため,どちらも共通で通用する設定を考えて記しました。

プリロードHSTS (Preload HSTS)

ここまでで、HTTP→HTTPSのリダイレクト、HSTSによる2回目以降HTTPSへのアクセス指示で、ほとんどHTTPS化ができています。残っているのは初回のHTTPアクセスのみです。

HSTSにより次回以降のHTTPアクセスを回避できますが,どうしても初回のHTTPアクセスを回避できません。HSTSは,一度HTTPSのページにアクセスして,HSTSヘッダーを受け取ってから初めて機能するからです。

この初回のHTTPアクセスを回避するための仕組みとして,プリロードHSTS (Preload HSTS) が存在します。このプリロードHSTSを設定することで常時HTTPS化が完成となります。

ここまで設定できていれば、プリロードHSTSの設定はフォームから申請するだけですので簡単です。ただし、画像付きで説明すると分量が多くなるため、別の記事「プリロードHSTS (Preload HSTS) の設定 | GNU social JP」にしています。

結論

Apache HTTP Serverでの常時HTTPS化の設定方法を記しました。

GNU socialやNextcloud Socialなどの、レンタルサーバーで稼働する分散SNSのソフトのインストール時に共通でほぼ必須の設定となります。

意味を理解して自分で設定を用意すると時間がかかりますが、結局は.htaccessに数行のコードを追加するだけで完了します。こちらの設定をそのまま適用して常時HTTPS化を実現してみましょう。

コメント

  1. […] 前回の「Apache HTTP Serverでの常時HTTPS化の設定 | GNU social JP」で残したプリロードHSTSの設定方法を記します。 […]

Copied title and URL