Hitch 1.4とVarnish 5.2でHTTP/2なMagento環境を作る
この記事は公開から 1年以上が経過しています。現在の最新情報との整合性については弊社では一切の責任を負いかねます。
このエントリはMagento Advent Calendar 2017の1日目です。
Magento2系を稼働させる環境を作る際に、切っても切れない関係にあるものがVarnishです。
今回はこのVarnishのバージョン5.2系と、Varnish謹製のSSL/TLSフロントエンドのHitchを使って、HTTP/2に対応した環境を作ってみましょう。
なお、弊社では普段Ubuntu Linuxを使っています。CentOSやRedHat Enterprise Linuxをお使いの方は適当にここから先の内容を読み替えて進めてください。各種コマンドなどは全てUbuntu Linux 16.04 LTSで実行したものを記載しています。
今回作成する構成
今回作成する構成は次の図のような構成です。
サーバー1台の中に以下のプロセスを同居させる形なので、あまり低スペックでないほうが良いでしょう。
本格稼働させる環境の場合は、最低でもMySQLくらいは別サーバーに切り出したいところですが、今回はお試しなので良いことにします。
用意するのもの
最初に用意するものを確認しておきます。
少なくとも以下の2つは必要です。
- 適当なスペックのサーバー(グローバルIPを持っているものならなんでも)
- 適当なホスト名(DNSに設定済みであること)
それでは環境を作っていきましょう。
とりあえずMagentoが動く環境を作る
まず最初に、Magentoが動く環境を作ります。
これは以下の記事を参考にするとスムーズに行くでしょう。
Magentoを動かすだけであればVirtualBoxとVagrantで作っても構いませんが、今回のメインはその話ではないので割愛します。
HitchとVarnishをインストールする
Ubuntu LinuxにももちろんHitchやVarnishのパッケージは用意されているのですが、バージョンが少し古いものしか用意されていません。
今回はHTTP/2に対応したバージョンを使いたいので、Hitchは1.4系、Varnishは5.2系を使用します。
Varnishのインストールと設定
Varnishの公式リポジトリは、PackageCloudにあります。
Quick Installで指示されているとおり、
curl -s https://packagecloud.io/install/repositories/varnishcache/varnish5/script.deb.sh | sudo bash
を実行し、パッケージをインストールします。
設定ファイルをMagentoからダウンロードする
Varnishが無事にインストールできたら、次は設定を行います。
Varnishを動かす場合、Varnishそのものの設定ファイルを調整する必要があります。独自のシステムやVarnishを想定していないパッケージの場合、この設定ファイルを自力で作成する必要がありますが、現在のMagentoはVarnishの仕様を想定しているので、管理画面から簡単に設定ファイルをダウンロードできます。
設定ファイルのダウンロードは、Magentoの管理画面の「店舗>設定」でアクセスできるシステム設定画面の「システム」セクションにある「フルページキャッシュ」で行います。
標準状態では「内蔵キャッシュ」になっているところを「Varnish キャッシュ」に変更すると、「Varnish設定」という項目が出てきます。
ここでVarnishのバージョンに合わせた設定ファイルがダウンロードできます。
なおMagento2.1と2.2ではサポートするVarnishのバージョンが少し異なりますが、Varnish4系の設定ファイルをVarnish5系で使っても問題なく動作します。
設定ファイルを設置する
ダウンロードした設定ファイルをサーバーの以下の場所に配置します。
/etc/varnish/default.vcl
次に、プロセスを起動・停止・再起動などさせるスクリプトを用意します。
/etc/systemd/system/varnish.service
がある場合は、viエディタなどで開きます。もしファイルがない場合は、
/lib/systemd/system/varnish.service
からコピーして配置してください。
このファイルにはVarnishの起動設定が書いてあるのですが、以下の箇所を変更しておきます。
変更前:ExecStart=/usr/sbin/varnishd -a :6081 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,256m 変更後:ExecStart=/usr/sbin/varnishd -a :80 -a :81,PROXY -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,256m -p feature=+http2
この例では、Varnishを80番と81番ポートで待ち受けさせています。
81番の方はPROXY Protocolで待機させ、Hitchから流れてくるデータを処理します。
また、featureでhttp2を有効にしています。このオプションを付けることで、HTTP/2がVarnish上で有効になります。
変更できたら以下のコマンドを実行し、設定ファイルの内容をsystemdに認識させます。
sudo systemctl daemon-reload varnish
Apacheのポート番号を変える
Varnishを起動させる前に、Apacheのポート番号を変えておきます。
標準の設定ではApacheは80番ポートで起動しますが、Varnishが80番ポートを使うので、Apacheは8080番ポートで起動させます。
Ubuntu Linuxの場合は
/etc/apache2/ports.conf
に待ち受けポート番号が書いてあります。
さらに、
/etc/apache2/sites-enabled/<Magento用のconf>
にあるバーチャルホストの設定にもポート番号が書いてあります。この両方を8080に変えておきましょう。
変更できたらApacheを再起動し、続いてVarnishを起動させます。
設定に不備がなければApacheとVarnishが両方とも起動するはずです。
Hitchをインストールする
次はHitchをインストールします。記事執筆時点ではHitchのUbuntu Linux 16.04用のパッケージは
https://launchpad.net/~davividal-s/+archive/ubuntu/backports
でしか見つかりませんでした。ソースからコンパイルしてもいいのですが、今回は手軽に試したいので、このリポジトリのパッケージを利用します。
リポジトリの追加
リポジトリの追加はお作法通りです。
sudo add-apt-repository ppa:davividal-s/backports sudo apt-get update
と実行すれば基本的にはOKです。
Hitchのインストール
リポジトリが正しく追加できていれば、
sudo apt-get install hitch
でHitchがインストールできると思います。うまくインストールできたらHitchの設定を行います。
設定ファイルの調整
Hitchの設定ファイルは2つあります。
/etc/systemd/system/hitch.service /etc/hitch/hitch.conf
前者はVarnishと同じところに元ファイルがあるのでコピーします。
後者のファイルは以下のような記述にしておきます。
frontend = "[*]:443" ciphers = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA" tls-protos = TLSv1.0,TLSv1.1,TLSv1.2 prefer-server-ciphers = on sni-nomatch-abort = on backend = "[127.0.0.1]:81" write-proxy-v2 = on workers = 2 backlog = 1024 keepalive = 3600 syslog = on user = "nobody" pem-file = "/etc/letsencrypt/live/<ドメイン名>/hitch-bundle.pem" daemon = on alpn-protos = "h2, http/1.1”
ここで重要なのは、
alpn-protos= "h2, http/1.1"
というところです。
この記述を書かないと、HitchがHTTP/2で動作しません。Ubuntu Linuxで標準として使えるHitchはバージョン1.1で、この設定が利用できません。
そのため今回は1.4系を使用したわけです。
VarnishとApacheの設定変更
続いてHitchと連携できるようにVarnishとApacheの設定を変更します。
Varnishの設定ファイルに追記
Varnishの設定ファイルの52行目あたりに以下の追記を行います。
set req.http.x-forwarded-proto = "https";
Apacheの設定ファイルに追記
Magentoを動作させるApacheのバーチャルホスト設定
/etc/apache2/sites-enabled/<Magento用のconf>
に以下の内容を追記します。
SetEnvIf X-Forwarded-Proto https HTTPS=on SetEnv https HTTPS=on
追記できたらApacheを再起動しておきます。
この設定を行う意味
Hitchを通すとHTTPS通信は全てHTTP通信として暗号化が解除された状態でVarnishやApacheに流れます。
それ自体は望ましいのですが、Magentoと組み合わせる場合は少し具合の悪い点があります。
Magentoは流れてきたリクエストがHTTPなのかHTTPSなのかでベースURLのどちらを使うかを判断します。
この判断は以下のPHP上の変数を用いて行っています。
$_SERVER["HTTPS"]
この値が on であるとき、Magentoは通信がHTTPSで行われたものと認識します。たとえそれが443番ポートに来たものでなくとも、前段階でHTTPS通信が解除されたと認識してくれます。
反対に、この値が off である場合は、通信がHTTPSだったとしてもHTTPであるものとみなします。
MagentoのベースURLがすべて "https://" ではじまるURLになっていた場合、Magentoは正しいURLにブラウザを誘導しようとするため、自動的にリダイレクトが起きます。
ところがリダイレクト後でも同じことが繰り返されてしまうため、リダイレクトの無限ループが起きてしまい、サイトに全くアクセスできなくなります。
この問題を回避するために、先程の設定を行うわけです。常時HTTPS化が求められている現在においては、この内容で多少余分に書き過ぎであっても目的を果たすことができます。
また、今回の最終目的であるHTTP/2での通信は多くのブラウザでHTTPS通信が前提として実装されていることも見逃せないポイントです。
Let’s Encryptで証明書を取得する
仕上げにSSL証明書を取得します。
お試しなのでLet's Encryptを使います。
certbotのサイトに書いてあるチュートリアルに従ってcertbotをインストールします。
下記のコマンドを叩いていけばインストールできると思います。
sudo apt-get update sudo apt-get install software-properties-common sudo add-apt-repository ppa:certbot/certbot sudo apt-get update sudo apt-get install python-certbot-apache
Apacheだけであればこのままcertbotで取得できるのですが、Hitchは一工夫加える必要があります。
というのもHitchは前述の設定ファイルをみていただければ分かる通り、SSL証明書に関する設定は1行しかありません。
Apacheであれば、証明書と中間証明書、秘密鍵の3行がありますが、Hitchはこれらを1つにまとめたファイルを使用します。
Varnish公式のチュートリアルを参考にする
有難い事にVarnish公式サイトにはHitchとLet's Encryptを使うチュートリアルが公開されています。
CentOS7用ですが、パッケージのインストール以外はUbuntu Linuxでも使えるので、この内容を参考にしましょう。
Varnishの設定にcertbot用の記述を追加
最初にVarnishの設定ファイルを改造し、certbotに対応させます。
/etc/varnish/default.vcl
に次の内容を書き込みます。
backend certbot { .host = "127.0.0.1"; .port = "888"; } 〜中略〜 sub vcl_recv { 〜中略〜 if (req.url ~ "^/.well-known/acme-challenge/.*") { set req.backend_hint = certbot; return(pass); } 〜中略〜 }
sub vcl_recv のところは既に default.vcl にあるはずなので、単純に追記でOKです。
backend certbot は新しく書き込んでください。
書き込めたらvarnishを再起動しておきます。
Hitch用のフックスクリプトを用意
Let's Encryptの証明書をHitchが利用できるように1つのファイルに纏めるスクリプトを用意します。
/usr/local/bin/hitch-renew-hook
を作成し、次の内容を書き込みます。
#!/bin/bash # Full path to pre-generated Diffie Hellman Parameters file dhparams=/etc/hitch/dhparams.pem if [[ "${RENEWED_LINEAGE}" == "" ]]; then echo "Error: missing RENEWED_LINEAGE env variable." >&2 exit 1 fi umask 077 cat ${RENEWED_LINEAGE}/privkey.pem \ ${RENEWED_LINEAGE}/fullchain.pem \ ${dhparams} > ${RENEWED_LINEAGE}/hitch-bundle.pem
作成したら実行権を与えておきます。
sudo chmod a+x /usr/local/bin/hitch-renew-hook
このスクリプトは、 dhparams.pem というファイルを使用します。
次のコマンドで簡単に作成できるので、作成しておきましょう。
sudo openssl dhparam 2048 -out /etc/hitch/dhparam.pem
certbotで証明書を取得
さて、最後に certbot で証明書を取得しましょう。
certbot コマンドに幾つかパラメータを渡してやることで、証明書を取得できます。
sudo certbot certonly --standalone --preferred-challenges http \ --http-01-port 888 -d <取得したいホスト名> \ --renew-hook="/usr/local/bin/hitch-renew-hook" \ --post-hook="service hitch reload"
フックスクリプトが自動的に証明書や秘密鍵を1ファイルにまとめて配置し、Hitchをリロードします。
これでSSL証明書が手に入りました。
ブラウザでアクセスして、HTTP/2で通信していることを確認する
最後に動作チェックです。
ブラウザの開発者ツールでアクセスし、HTTP/2で通信していることを確認しましょう。
うまくHTTP/2で通信できているようです。
アンチウイルスソフトなどの関係でうまくHTTP/2にならないことがあるケースが報告されています。
もしうまくいかない場合は、一時的にアンチウイルスを止めてみると良いかもしれません(ずっと止めるのはダメですが)。
まとめ
Hitch1.4とVarnish5.2を使ってHTTP/2でコンテンツを配信できるMagento環境の構築手順をご紹介しました。
HTTP/2は従来のHTTP1.xよりも通信効率が良くなるように設計されているため、モバイル端末や常時HTTPSを意識する際には無視できない要素です。
さて、明日は2日目です。kzkick2ndさんによる、「Magento2開発環境構築2017冬」です。お楽しみに。