Let's Encryptで常時SSL化してみた話(HTTP/2対応編)
いよいよゴールだよ
HTTP/2 (Hypertext Transfer Protocol version 2) は Webアクセスで用いられている HTTPプロトコルの最新バージョン。現在主に用いられているのは HTTP/1.1だが、これと互換性を維持したまま非同期接続、多重化、パイプライン化などで高速な通信が可能になっているとのことだ。
SSL化すると暗号化のため今までよりWebサーバに負荷がかかり、ホームページの表示速度が低下する可能性があるが、HTTP/2を導入すれば速度低下を防ぐことができる、あるいは今までより高速化されるかもしれない(実際にはそれほど効果がなく、SSL化すれば遅くなるのが普通らしいが。ウチも若干遅くなったような気がする)。
主要な Webブラウザは既に対応済みなので、あとは Webサーバ側が対応すれば良い。
9.1 Nghttp2のインストール
Apache2 で HTTP/2 に対応するには HTTP/2 を有効にしてビルドする必要があるのだが、その際に Nghttp2ライブラリが使用されるので、先ず Nghttp2 をインストールする。
1) Nghttp2をダウンロードして解凍
Nghttp2公式ホームページ:https://nghttp2.org/
現時点での最新版は Nghttp2 v1.36.0
$ xzcat nghttp2-1.36.0.tar.xz | tar xf -
$ cd nghttp2-1.36.0
|
2) ビルド方法("build.sh"スクリプト作成)
SSLライブラリは "/usr/local/ssl" にインストールされている OpenSSLの方を使用する。
#!/usr/local/bin/bash -x
export MACOSX_DEPLOYMENT_TARGET=10.4
export GCC="/usr/local"
export SSL="/usr/local/ssl"
export PATH="${GCC}/bin:$PATH"
export DYLD_LIBRARY_PATH="${GCC}/lib:${DYLD_LIBRARY_PATH}"
export PKG_CONFIG_PATH="${SSL}/lib/pkgconfig:${PKG_CONFIG_PATH}"
./configure \
CPP="${GCC}/bin/cpp" \
CC="${GCC}/bin/gcc" \
CXX="${GCC}/bin/g++" \
CFLAGS="-O2 -mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET}" \
CXXFLAGS="-O2 -mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET}" \
OPENSSL_CFLAGS="-I${SSL}/include" \
OPENSSL_LIBS="-L${SSL}/lib -lssl -lcrypto" \
CPPFLAGS="-I${SSL}/include -I/usr/local/include -I/usr/include" \
LDFLAGS="-L${SSL}/lib -L/usr/local/lib -L/usr/lib"
make
注)「¥」は実際には半角の「\」(バックスラッシュ)
3) ビルドしてインストール
$ chmod +x ./build.sh
$ ./build.sh
$ sudo make install
$ ls -l /usr/local/lib/libnghttp2*
-rwxr-xr-x 1 root admin 140900 1 21 14:37 /usr/local/lib/libnghttp2.14.dylib
-rw-r--r-- 1 root admin 219016 1 21 14:37 /usr/local/lib/libnghttp2.a
lrwxr-xr-x 1 root admin 19 1 21 14:37 /usr/local/lib/libnghttp2.dylib -> libnghttp2.14.dylib
-rwxr-xr-x 1 root admin 995 1 21 14:37 /usr/local/lib/libnghttp2.la
|
9.2 Apache2 を HTTP/2対応にする
Apache公式ホームページ:https://httpd.apache.org/
Apache2 を HTTP/2を有効にしてビルド(configure)する。現時点での最新版は httpd-2.4.38
ビルド方法("build.sh"スクリプト)は以下。configure に --enable-http2 を指定することで mod_http2モジュールが作られるようになる。SSLライブラリは OpenSSL の方を使用している。
#!/usr/local/bin/bash -x
export MACOSX_DEPLOYMENT_TARGET=10.4
export GCC="/usr/local"
export SSL="/usr/local/ssl"
export PATH="${GCC}/bin:$PATH"
export DYLD_LIBRARY_PATH="${GCC}/lib:${DYLD_LIBRARY_PATH}"
export PKG_CONFIG_PATH="${SSL}/lib/pkgconfig:${PKG_CONFIG_PATH}"
export PREFIX="/usr/local/apache2"
export APR="/usr/local/apache2"
./configure \
--prefix=${PREFIX} \
--enable-dav \
--enable-so \
--enable-ssl \
--enable-http2 \
--enable-mods-shared=most \
--with-apr=${APR} \
--with-apr-util=${APR} \
--with-ssl=${SSL} \
--with-z=/usr/local \
CC="${GCC}/bin/gcc" \
CPP="${GCC}/bin/cpp" \
CFLAGS="-O2 -mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET}" \
CPPFLAGS="-I${SSL}/include -I/usr/local/include -I/usr/include" \
LDFLAGS="-L${SSL}/lib -L/usr/local/lib -L/usr/lib"
make
注)「¥」は実際には半角の「\」(バックスラッシュ)
上記でビルドしてインストールする。
$ chmod +x ./build.sh
$ ./build.sh
$ sudo make install
|
9.3 Apache2 の設定
1) "/usr/local/apache2/conf/httpd.conf"
http2_module を有効化する。以下の行の先頭に #がある場合は #を削除し、行そのものが無い場合は追加する。
LoadModule http2_module modules/mod_http2.so
|
2) "/usr/local/apache2/conf/extra/httpd-ssl.conf"
SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4
↓
SSLCipherSuite TLSv1.3 "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:
TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256"
SSLCipherSuite 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:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK
〜
# 暗号化方式の決定をサーバ側で行う
SSLHonorCipherOrder on
# HTTPヘッダの漏洩を防ぐためHTTP圧縮しない
SSLCompression off
〜
SSLProtocol all -SSLv2 -SSLv3
↓
# TLSv1には攻撃方法が見つかっているので使用しない
SSLProtocol -All +TLSv1.1 +TLSv1.2 +TLSv1.3
〜
<VirtualHost _default_:443>
ServerName y-naito.ddo.jp:443
SSLEngine on
SSLCertificateFile "/etc/letsencrypt/live/y-naito.ddo.jp/fullchain.pem"
SSLCertificateKeyFile "/etc/letsencrypt/live/y-naito.ddo.jp/privkey.pem"
<IfModule http2_module> # ←追加
ProtocolsHonorOrder On # ←追加 プロトコル合意順序の有効化
Protocols h2 http/1.1 # ←追加 HTTP/2 と HTTP/1.1をサポート
</IfModule> # ←追加
〜略〜
</VirtualHost>
|
注1)
SSLCipherSuite TLSv1.3 で TLSv1.3 の暗号スイートを記述し、従来の SSLCipherSuite には TLSv1.2 までの暗号スイートを記述する。
注2)
SSLCipherSuite の暗号スイートの記述は長いため、表示の都合で折り返してインデントしているが、実際には改行も空白文字もない連続した文字列であることに注意。
注3)
上ではTLSv1を使わない設定にしているが、この場合、古いAndoroid端末、IE 8以前やSafari 6以前のブラウザからは接続できなくなる。実は TLSv1.1 にも脆弱性が見つかっているので使用しない方が良いそうで、時代は TLSv1.2, TLSv1.3 へと移行している(主要ブラウザは2020年にTLSv1.1のサポートを打ち切るみたいだ)。この辺りは、どこまでの古いブラウザをサポートするか?(いつ古い環境のユーザを切り捨てるか?)とのトレードオフになってくる。
HTTP/2には暗号化しないhttp接続に対応したプロトコル h2c もあるようだが、httpでのアクセスは httpsにリダイレクトしているので、http接続の設定は変更しなくても良いだろう。
3) 設定の変更を反映
$ sudo /usr/local/apache2/bin/apachectl configtest
Syntax OK
$ sudo /usr/local/apache2/bin/apachectl restart
$
|
9.4 確認
ウチのWebサーバにはPHPが入っているので、phpinfo()で各種設定情報を表示させて確認してみた。
Apache の環境変数や HTTPヘッダ情報を見ると、HTTP/2で通信されていることが分かる。
暗号化についてもFirefoxの開発ツールで確認したところ、
TLSv1.3で行われていることが確認できた。作業のシメとして、Qualys SSL Labsでセキュリティランクを診断してもらった。結果は、
以上で新年の目標「ホームページの常時SSL化」は一応完了だ(誰か御褒美をください)。残りはホームページ内に httpコンテンツが混在していないかチェック、修正して行くだけだが、こちらはボチボチとやっていく事にしよう。
|